sl@0: // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "apgrfxfacade.h" sl@0: #include "TGraphicsHarness.h" sl@0: #include "GraphicsTestUtilsServer.h" sl@0: sl@0: _LIT(KGraphicsTestFrameworkPanic, "Graphics Test Framework"); sl@0: const TInt KTestCleanupStack = 0x40; sl@0: sl@0: const TDisplayMode testDisplayModes[] = sl@0: { sl@0: EGray2, sl@0: EGray4, sl@0: EGray16, sl@0: EGray256, sl@0: EColor16, sl@0: EColor256, sl@0: EColor64K, sl@0: EColor16M, sl@0: EColor4K, sl@0: EColor16MU, sl@0: EColor16MA, sl@0: EColor16MAP, sl@0: }; sl@0: sl@0: /** sl@0: The test code manager, provides functions to set active object sl@0: with lowest priority for running tests in auto mode. sl@0: */ sl@0: class CTestManager : public CActive sl@0: { sl@0: friend class CTGraphicsBase; sl@0: protected: sl@0: static CTestManager* NewL(MTestCases* aAutoTestApp); sl@0: ~CTestManager(); sl@0: void FinishAllTestCases(); sl@0: void StartTest(); //initialize an active object and set it status as active sl@0: void SetSelfDrive(TBool aSelfDrive); sl@0: void CaseComplete(); sl@0: private: sl@0: CTestManager(MTestCases* aAutoTestApp); sl@0: void NextTest(); sl@0: // from CActive sl@0: void RunL(); sl@0: void DoCancel(); sl@0: TInt RunError(TInt aError); sl@0: private: sl@0: MTestCases* iTestCase; sl@0: TInt iCurTestCaseNumber; //a current test case, every time when function RunTestCaseL is called this member inc by one sl@0: TBool iTestCompleted; sl@0: TBool iSelfDrive; sl@0: }; sl@0: sl@0: /** Construct an active object with the lowest priority */ sl@0: CTestManager::CTestManager(MTestCases* aTestCases) : sl@0: CActive(EPriorityIdle), iTestCase(aTestCases), iSelfDrive(EFalse) sl@0: {} sl@0: sl@0: CTestManager::~CTestManager() sl@0: { sl@0: Cancel(); sl@0: } sl@0: sl@0: CTestManager* CTestManager::NewL(MTestCases* aTestCases) sl@0: { sl@0: CTestManager *theTestManager=new (ELeave) CTestManager(aTestCases); sl@0: CActiveScheduler::Add(theTestManager); sl@0: return theTestManager; sl@0: } sl@0: sl@0: void CTestManager::RunL() sl@0: { sl@0: __ASSERT_ALWAYS(iTestCase, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle)); sl@0: if( iTestCompleted) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: // debug statement to indicate progress of test suite by sl@0: // printing the sub-test that is currently active sl@0: TTime timeStamp; sl@0: timeStamp.HomeTime(); sl@0: TBuf<50> dateStr; sl@0: _LIT(KDateString3,"%-B%:0%J%:1%T%:2%S%:3.%Cms"); sl@0: timeStamp.FormatL(dateStr, KDateString3); sl@0: ++iCurTestCaseNumber; sl@0: RDebug::Print(_L("%S - Test Case Number: %d"), &dateStr, iCurTestCaseNumber); sl@0: sl@0: iTestCase->RunTestCaseL(iCurTestCaseNumber); sl@0: if (iTestCompleted) sl@0: { sl@0: _LIT(KFinished,"Finished test case %d and test completed"); sl@0: RDebug::Print(KFinished,iCurTestCaseNumber); sl@0: } sl@0: else sl@0: { sl@0: if (iSelfDrive) sl@0: { sl@0: _LIT(KStarted,"Started test case %d"); sl@0: RDebug::Print(KStarted,iCurTestCaseNumber); sl@0: } sl@0: else sl@0: { sl@0: NextTest(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CTestManager::DoCancel() sl@0: { sl@0: if (!iSelfDrive) sl@0: iTestCompleted = ETrue; sl@0: } sl@0: sl@0: TInt CTestManager::RunError(TInt aError) sl@0: { sl@0: TTime timeStamp; sl@0: timeStamp.HomeTime(); sl@0: TBuf<50> dateStr; sl@0: _LIT(KDateString3,"%-B%:0%J%:1%T%:2%S%:3 %Cms"); sl@0: timeStamp.FormatL(dateStr, KDateString3); sl@0: _LIT(KTestLeft,"RunTestCaseL left of %S - Test Case Number: %d"); sl@0: RDebug::Print(KTestLeft, &dateStr, iCurTestCaseNumber); sl@0: sl@0: aError = iTestCase->RunTestCaseLeft(aError); sl@0: FinishAllTestCases(); sl@0: return aError; sl@0: } sl@0: sl@0: /** sl@0: Initialize an active object and set it as active sl@0: */ sl@0: void CTestManager::StartTest() sl@0: { sl@0: TRequestStatus *pS= (&iStatus); sl@0: User::RequestComplete(pS, 0); sl@0: SetActive(); sl@0: } sl@0: sl@0: /** sl@0: Time to move on to the next test step sl@0: */ sl@0: void CTestManager::NextTest() sl@0: { sl@0: _LIT(KFinished,"Finished test case %d"); sl@0: RDebug::Print(KFinished,iCurTestCaseNumber); sl@0: StartTest(); sl@0: } sl@0: sl@0: /** sl@0: Stop active scheduler, and quit a test step sl@0: */ sl@0: void CTestManager::FinishAllTestCases() sl@0: { sl@0: iTestCompleted = ETrue; sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: sl@0: /** sl@0: Controls wether the manager calls RunTestCaseL whenever the system is otherwise idol sl@0: */ sl@0: void CTestManager::SetSelfDrive(TBool aSelfDrive) sl@0: { sl@0: if (iSelfDrive!=aSelfDrive) sl@0: { sl@0: iSelfDrive = aSelfDrive; sl@0: if (aSelfDrive) sl@0: { sl@0: if (IsActive()) sl@0: Cancel(); sl@0: } sl@0: else sl@0: { sl@0: if (!IsActive() && !iTestCompleted) sl@0: NextTest(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Tells the manager this case is finished so you can call RunTestCaseL again sl@0: */ sl@0: void CTestManager::CaseComplete() sl@0: { sl@0: __ASSERT_DEBUG(!IsActive(), User::Panic(KGraphicsTestFrameworkPanic, ETestPanicAlreadyActive)); sl@0: if (iSelfDrive && !iTestCompleted) sl@0: NextTest(); sl@0: } sl@0: sl@0: sl@0: //------------- sl@0: sl@0: EXPORT_C const TDesC& CTGraphicsBase::ColorModeName(TDisplayMode aMode) sl@0: { sl@0: _LIT(KNone,"None"); sl@0: _LIT(KGray2,"Grey2"); sl@0: _LIT(KGray4,"Grey4"); sl@0: _LIT(KGray16,"Grey16"); sl@0: _LIT(KGray256,"Grey256"); sl@0: _LIT(KColor16,"Color16"); sl@0: _LIT(KColor256,"Color256"); sl@0: _LIT(KColor4K,"Color4K"); sl@0: _LIT(KColor64K,"Color64K"); sl@0: _LIT(KColor16M,"Color16M"); sl@0: _LIT(KColor16MU,"Color16MU"); sl@0: _LIT(KColor16MA,"Color16MA"); sl@0: _LIT(KColor16MAP,"Color16MAP"); sl@0: _LIT(KRgb,"RGB"); sl@0: _LIT(KUnknown,"Unknown"); sl@0: switch(aMode) sl@0: { sl@0: case ENone: sl@0: return KNone; sl@0: case EGray2: sl@0: return KGray2; sl@0: case EGray4: sl@0: return KGray4; sl@0: case EGray16: sl@0: return KGray16; sl@0: case EGray256: sl@0: return KGray256; sl@0: case EColor16: sl@0: return KColor16; sl@0: case EColor256: sl@0: return KColor256; sl@0: case EColor64K: sl@0: return KColor64K; sl@0: case EColor16M: sl@0: return KColor16M; sl@0: case ERgb: sl@0: return KRgb; sl@0: case EColor4K: sl@0: return KColor4K; sl@0: case EColor16MU: sl@0: return KColor16MU; sl@0: case EColor16MA: sl@0: return KColor16MA; sl@0: case EColor16MAP: sl@0: return KColor16MAP; sl@0: default: sl@0: return KUnknown; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C const TDesC& CTGraphicsBase::RotationName(CFbsBitGc::TGraphicsOrientation aOrientation) sl@0: { sl@0: _LIT(K0,"Normal"); sl@0: _LIT(K90,"Rotated90"); sl@0: _LIT(K180,"Rotated180"); sl@0: _LIT(K270,"Rotated270"); sl@0: _LIT(KUnknown,"Unknown"); sl@0: switch(aOrientation) sl@0: { sl@0: case CFbsBitGc::EGraphicsOrientationNormal: sl@0: return K0; sl@0: case CFbsBitGc::EGraphicsOrientationRotated90: sl@0: return K90; sl@0: case CFbsBitGc::EGraphicsOrientationRotated180: sl@0: return K180; sl@0: case CFbsBitGc::EGraphicsOrientationRotated270: sl@0: return K270; sl@0: default: sl@0: return KUnknown; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CTGraphicsBase::SaveScreenShotL(CFbsScreenDevice* aScdv) sl@0: { sl@0: #ifdef __WINS__ sl@0: _LIT(KBitmapDrive, "c:"); sl@0: #else sl@0: _LIT(KBitmapDrive, "e:"); sl@0: #endif sl@0: _LIT(KBitmapPath, "\\screenshot.mbm"); sl@0: TDisplayMode dispMode = aScdv->DisplayMode(); sl@0: TSize scrSize = aScdv->SizeInPixels(); sl@0: CFbsBitmap* dstBmp = new(ELeave) CFbsBitmap; sl@0: CleanupStack::PushL(dstBmp); sl@0: User::LeaveIfError(dstBmp->Create(scrSize, dispMode)); sl@0: HBufC8* row = HBufC8::NewLC(scrSize.iWidth*4); sl@0: TPtr8 prow = row->Des(); sl@0: for (TInt ii = 0; ii < scrSize.iHeight; ++ii) sl@0: { sl@0: aScdv->GetScanLine(prow, TPoint(0, ii), scrSize.iWidth, dispMode); sl@0: dstBmp->SetScanLine(prow,ii); sl@0: } sl@0: CleanupStack::PopAndDestroy(row); sl@0: TFileName mbmFile; sl@0: mbmFile.Append(KBitmapDrive); sl@0: mbmFile.Append(KBitmapPath); sl@0: User::LeaveIfError(dstBmp->Save(mbmFile)); sl@0: CleanupStack::PopAndDestroy(dstBmp); sl@0: } sl@0: sl@0: EXPORT_C CTGraphicsBase::CTGraphicsBase(CTestStep* aStep) : sl@0: iStep(aStep) sl@0: {} sl@0: sl@0: EXPORT_C CTGraphicsBase::~CTGraphicsBase() sl@0: { sl@0: if(iTestManager) sl@0: { sl@0: iTestManager -> Cancel(); sl@0: } sl@0: delete iTestManager; sl@0: } sl@0: sl@0: void CTGraphicsBase::InitializeL() sl@0: { sl@0: __ASSERT_DEBUG(iStep, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle)); sl@0: iTestManager = CTestManager::NewL(this); sl@0: } sl@0: sl@0: /** sl@0: The function must be called after all test cases completed sl@0: */ sl@0: EXPORT_C void CTGraphicsBase::TestComplete() sl@0: { sl@0: if(iTestManager) sl@0: { sl@0: iTestManager -> FinishAllTestCases(); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CTGraphicsBase::SetSelfDrive(TBool aSelfDrive) sl@0: { sl@0: if (iTestManager) sl@0: iTestManager->SetSelfDrive(aSelfDrive); sl@0: } sl@0: sl@0: EXPORT_C void CTGraphicsBase::CaseComplete() sl@0: { sl@0: if (iTestManager) sl@0: iTestManager->CaseComplete(); sl@0: } sl@0: sl@0: EXPORT_C TInt CTGraphicsBase::RunTestCaseLeft(TInt aError) sl@0: { sl@0: _LIT(KRunTestCaseLLeft,"The RunTestCaseL left with %d"); sl@0: ERR_PRINTF2(KRunTestCaseLLeft,aError); sl@0: iStep->SetTestStepResult(EFail); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** Start a test cases loop */ sl@0: void CTGraphicsBase::Execute() sl@0: { sl@0: __ASSERT_DEBUG(iTestManager, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle)); sl@0: __ASSERT_DEBUG(CActiveScheduler::Current(), User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle)); sl@0: sl@0: iTestManager -> StartTest(); sl@0: CActiveScheduler::Start(); sl@0: } sl@0: /** sl@0: Reset test cases counter to a new value. Can be used for running the same consequence of test sl@0: cases with different initial parameters. sl@0: aNewCurrentTestCase cannot be negative. sl@0: */ sl@0: EXPORT_C void CTGraphicsBase::ResetCounter(TInt aNewCurrentTestCase ) sl@0: { sl@0: __ASSERT_DEBUG(aNewCurrentTestCase >= 0, User::Panic(KGraphicsTestFrameworkPanic, KErrArgument)); sl@0: iTestManager->iCurTestCaseNumber = aNewCurrentTestCase; sl@0: } sl@0: sl@0: //--------------------- sl@0: /** sl@0: Initialise the cleanup stack. sl@0: */ sl@0: void CTGraphicsStep::SetupCleanup(CTrapCleanup*& tc) sl@0: { sl@0: tc = CTrapCleanup::New(); sl@0: if (!tc) sl@0: { sl@0: User::Panic(_L("Out of memory"), KErrNoMemory); sl@0: } sl@0: sl@0: TRAPD(r, sl@0: { sl@0: for ( TInt ii = KTestCleanupStack; ii > 0; ii-- ) sl@0: CleanupStack::PushL( (TAny*)1 ); sl@0: TEST( r == KErrNone ); sl@0: CleanupStack::Pop( KTestCleanupStack ); sl@0: } ); sl@0: } sl@0: sl@0: void CTGraphicsStep::LogHeapInfo(RWsSession& aWs, TBool aStart) sl@0: { sl@0: _LIT(KInfoStart,"Start"); sl@0: _LIT(KInfoEnd,"End"); sl@0: _LIT(KInfoCheckPassed,"WsHeap leak check passed"); sl@0: _LIT(KInfoCheckFailed,"Memory leak detected. Number of orphaned cells=%d."); sl@0: _LIT(KInfoCheckFailed2,"See epocwindout for the address of the first orphaned cell."); sl@0: _LIT(KInfoHeapSummary," WsHeap - Count=%d,Total=%d,Free=%d,Max free=%d"); sl@0: _LIT(KInfoDisabled,"Memory leak testing has not been enabled."); sl@0: sl@0: TPckgBuf heapInfo; sl@0: aWs.DebugInfo(EWsDebugInfoHeap,heapInfo); sl@0: TBuf<256> infoBuf; sl@0: if (aStart) sl@0: { sl@0: infoBuf.Append(KInfoStart); sl@0: } sl@0: else sl@0: { sl@0: infoBuf.Append(KInfoEnd); sl@0: TInt heapFailCount=aWs.DebugInfo(EWsDebugFetchCheckHeapResult); sl@0: if (heapFailCount==KErrNone) sl@0: { sl@0: INFO_PRINTF1(KInfoCheckPassed); sl@0: } sl@0: else if (heapFailCount>0) // Negative error should be ignored as it means the check has not been enabled sl@0: { sl@0: TEST(0); sl@0: ERR_PRINTF2(KInfoCheckFailed,heapFailCount); sl@0: ERR_PRINTF1(KInfoCheckFailed2); sl@0: } sl@0: else sl@0: { sl@0: WARN_PRINTF1(KInfoDisabled); sl@0: } sl@0: } sl@0: infoBuf.AppendFormat(KInfoHeapSummary,heapInfo().iCount,heapInfo().iTotal,heapInfo().iAvailable,heapInfo().iLargestAvailable); sl@0: INFO_PRINTF1(infoBuf); sl@0: } sl@0: sl@0: /** sl@0: Main entry point from CTestStep class. sl@0: Creates cleanup stack, background window and launches a test sl@0: */ sl@0: EXPORT_C TVerdict CTGraphicsStep::doTestStepL() sl@0: { sl@0: TInt memFree; sl@0: HAL::Get(HALData::EMemoryRAMFree, memFree); sl@0: INFO_PRINTF2(_L("Test started - RAM free: %d"), memFree); sl@0: sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* tc = NULL; sl@0: SetupCleanup(tc); sl@0: sl@0: TInt err = RFbsSession::Connect(); sl@0: if(err != KErrNone) sl@0: { sl@0: FbsStartup(); sl@0: err = RFbsSession::Connect(); sl@0: sl@0: if(err != KErrNone) sl@0: { sl@0: User::Panic(_L("Font bitmap session connect"), err); sl@0: } sl@0: } sl@0: RWsSession ws; sl@0: err = ws.Connect(); sl@0: if (iLogHeapInfo && err==KErrNone) sl@0: { sl@0: ws.DebugInfo(EWsDebugSetCheckHeapOnDisconnectClient); sl@0: LogHeapInfo(ws,ETrue); sl@0: } sl@0: TInt theId1 = NULL; sl@0: #ifdef __WINS__ sl@0: RWindowGroup winGroup = RWindowGroup(ws); sl@0: RWindow theWindow(ws); sl@0: if (err==KErrNone) sl@0: { sl@0: const TUint32 ENullWsHandle = 0xFFFFFFFF; // Events delivered to this handle are thrown away sl@0: //creat background window with the size of the screen sl@0: //it is particulary important for tests which draw on the screen, read screen buffer sl@0: //and compare result. By default top TEF window is concole and blinking cursor can interfere sl@0: //with the work of the tests sl@0: TSize size(640, 240); //some default value sl@0: //retrieve screen size sl@0: err = GetScreenSize(size); sl@0: if(err) sl@0: { sl@0: WARN_PRINTF2(_L("Can't retrieve size from screen driver err = %d"), err); sl@0: } sl@0: sl@0: winGroup.Construct(ENullWsHandle); sl@0: winGroup.AutoForeground(ETrue); sl@0: theId1 = winGroup.Identifier(); sl@0: sl@0: theWindow.Construct(winGroup, ENullWsHandle); sl@0: theWindow.SetExtent(TPoint(0, 0), size); sl@0: theWindow.SetVisible(ETrue); sl@0: theWindow.Activate(); sl@0: sl@0: //the following trick we need to put the window on the top sl@0: TApaTaskListFacade taskList(ws); sl@0: TApaTaskFacade task = taskList.FindByPos(1); sl@0: task.BringToForeground(); sl@0: TApaTaskFacade task1(ws); sl@0: task1.SetWgId(theId1); sl@0: task1.BringToForeground(); sl@0: } sl@0: #endif sl@0: if (err==KErrNone) sl@0: { sl@0: CloseAllPanicWindows(theId1, ws); sl@0: } sl@0: sl@0: // initialize the test and kick off the test cases loop sl@0: TRAP(err, TestSetupL(); // initialize a test step sl@0: ExecuteL()); // run active scheduler, in order to complete test execution sl@0: // CTGraphicsStep::TestComplete function needs to be called sl@0: sl@0: if (err) sl@0: { sl@0: SetTestStepResult(EFail); sl@0: } sl@0: sl@0: TestClose(); // free all allocated resources here sl@0: sl@0: if (ws.Handle()) sl@0: { sl@0: CloseAllPanicWindows(theId1, ws); sl@0: #ifdef __WINS__ sl@0: theWindow.Close(); sl@0: winGroup.Close(); sl@0: #endif sl@0: ws.Close(); sl@0: User::After(50000); sl@0: // Prev close will trigger Wserv dummy shutdown and heap check sl@0: // We then re-connect to get the result of the shutdown. sl@0: RWsSession ws2; sl@0: TInt errConnection; sl@0: TInt MaxNumberOfAttempt=10; sl@0: TInt currentAttempt=0; sl@0: do sl@0: { sl@0: errConnection=ws2.Connect(); sl@0: if (errConnection==KErrNone) sl@0: { sl@0: LogHeapInfo(ws2,EFalse); sl@0: ws2.Close(); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Printf("Connection Error with Wserv... %i",errConnection); sl@0: User::After(50000); sl@0: } sl@0: currentAttempt++; sl@0: }while( (errConnection!=KErrNone) && (currentAttemptiCode = EKeyEscape; sl@0: keyEvent->iScanCode = EStdKeyEscape; sl@0: keyEvent->iModifiers = 0; sl@0: TInt theLimit = 50; sl@0: while(idFocus != aId && (theLimit-- > 0)) sl@0: { sl@0: ws.SendEventToAllWindowGroups(event); sl@0: idFocus = ws.GetFocusWindowGroup(); sl@0: } sl@0: } sl@0: sl@0: TInt CTGraphicsStep::GetScreenSize(TSize& aSize) const sl@0: { sl@0: CFbsScreenDevice* dev = NULL; sl@0: sl@0: TInt err = KErrNone; sl@0: TInt sizeOfDisplayMode = sizeof (testDisplayModes) / sizeof(testDisplayModes[0]); sl@0: sl@0: for(TInt theScreenModeIndex = sizeOfDisplayMode - 1; theScreenModeIndex ; theScreenModeIndex--) sl@0: { sl@0: TDisplayMode disp = testDisplayModes[theScreenModeIndex]; sl@0: TRAP(err, dev = CFbsScreenDevice::NewL(_L(""), disp)); //scdv sl@0: if(err == KErrNone) sl@0: { sl@0: aSize = dev->SizeInPixels(); sl@0: delete dev; sl@0: return KErrNone; sl@0: } sl@0: delete dev; sl@0: dev = NULL; sl@0: } sl@0: sl@0: return err; sl@0: } sl@0: sl@0: /** Installs an active scheduler and launches a test*/ sl@0: void CTGraphicsStep::ExecuteL() sl@0: { sl@0: CActiveScheduler* theAs = new (ELeave) CActiveScheduler; sl@0: CleanupStack::PushL(theAs); sl@0: CActiveScheduler::Install(theAs); sl@0: sl@0: CTGraphicsBase* autoTest = CreateTestL(); sl@0: User::LeaveIfNull(autoTest); sl@0: CleanupStack::PushL(autoTest); sl@0: sl@0: autoTest -> InitializeL(); sl@0: autoTest -> ConstructL(); sl@0: autoTest -> Execute(); sl@0: sl@0: CleanupStack::PopAndDestroy(2, theAs); sl@0: } sl@0: sl@0: TInt E32Dll( ) sl@0: { sl@0: return 0; sl@0: } sl@0: