First public contribution.
1 // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
20 #include <graphics/fbsdefs.h>
22 #include "apgrfxfacade.h"
23 #include "TGraphicsHarness.h"
24 #include "GraphicsTestUtilsServer.h"
26 _LIT(KGraphicsTestFrameworkPanic, "Graphics Test Framework");
27 const TInt KTestCleanupStack = 0x40;
29 const TDisplayMode testDisplayModes[] =
46 The test code manager, provides functions to set active object
47 with lowest priority for running tests in auto mode.
49 class CTestManager : public CActive
51 friend class CTGraphicsBase;
53 static CTestManager* NewL(MTestCases* aAutoTestApp);
55 void FinishAllTestCases();
56 void StartTest(); //initialize an active object and set it status as active
57 void SetSelfDrive(TBool aSelfDrive);
60 CTestManager(MTestCases* aAutoTestApp);
65 TInt RunError(TInt aError);
67 MTestCases* iTestCase;
68 TInt iCurTestCaseNumber; //a current test case, every time when function RunTestCaseL is called this member inc by one
73 /** Construct an active object with the lowest priority */
74 CTestManager::CTestManager(MTestCases* aTestCases) :
75 CActive(EPriorityIdle), iTestCase(aTestCases), iSelfDrive(EFalse)
78 CTestManager::~CTestManager()
83 CTestManager* CTestManager::NewL(MTestCases* aTestCases)
85 CTestManager *theTestManager=new (ELeave) CTestManager(aTestCases);
86 CActiveScheduler::Add(theTestManager);
87 return theTestManager;
90 void CTestManager::RunL()
92 __ASSERT_ALWAYS(iTestCase, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
98 // debug statement to indicate progress of test suite by
99 // printing the sub-test that is currently active
101 timeStamp.HomeTime();
103 _LIT(KDateString3,"%-B%:0%J%:1%T%:2%S%:3.%Cms");
104 timeStamp.FormatL(dateStr, KDateString3);
105 ++iCurTestCaseNumber;
106 RDebug::Print(_L("%S - Test Case Number: %d"), &dateStr, iCurTestCaseNumber);
108 iTestCase->RunTestCaseL(iCurTestCaseNumber);
111 _LIT(KFinished,"Finished test case %d and test completed");
112 RDebug::Print(KFinished,iCurTestCaseNumber);
118 _LIT(KStarted,"Started test case %d");
119 RDebug::Print(KStarted,iCurTestCaseNumber);
128 void CTestManager::DoCancel()
131 iTestCompleted = ETrue;
134 TInt CTestManager::RunError(TInt aError)
137 timeStamp.HomeTime();
139 _LIT(KDateString3,"%-B%:0%J%:1%T%:2%S%:3 %Cms");
140 timeStamp.FormatL(dateStr, KDateString3);
141 _LIT(KTestLeft,"RunTestCaseL left of %S - Test Case Number: %d");
142 RDebug::Print(KTestLeft, &dateStr, iCurTestCaseNumber);
144 aError = iTestCase->RunTestCaseLeft(aError);
145 FinishAllTestCases();
150 Initialize an active object and set it as active
152 void CTestManager::StartTest()
154 TRequestStatus *pS= (&iStatus);
155 User::RequestComplete(pS, 0);
160 Time to move on to the next test step
162 void CTestManager::NextTest()
164 _LIT(KFinished,"Finished test case %d");
165 RDebug::Print(KFinished,iCurTestCaseNumber);
170 Stop active scheduler, and quit a test step
172 void CTestManager::FinishAllTestCases()
174 iTestCompleted = ETrue;
175 CActiveScheduler::Stop();
179 Controls wether the manager calls RunTestCaseL whenever the system is otherwise idol
181 void CTestManager::SetSelfDrive(TBool aSelfDrive)
183 if (iSelfDrive!=aSelfDrive)
185 iSelfDrive = aSelfDrive;
193 if (!IsActive() && !iTestCompleted)
200 Tells the manager this case is finished so you can call RunTestCaseL again
202 void CTestManager::CaseComplete()
204 __ASSERT_DEBUG(!IsActive(), User::Panic(KGraphicsTestFrameworkPanic, ETestPanicAlreadyActive));
205 if (iSelfDrive && !iTestCompleted)
212 EXPORT_C const TDesC& CTGraphicsBase::ColorModeName(TDisplayMode aMode)
215 _LIT(KGray2,"Grey2");
216 _LIT(KGray4,"Grey4");
217 _LIT(KGray16,"Grey16");
218 _LIT(KGray256,"Grey256");
219 _LIT(KColor16,"Color16");
220 _LIT(KColor256,"Color256");
221 _LIT(KColor4K,"Color4K");
222 _LIT(KColor64K,"Color64K");
223 _LIT(KColor16M,"Color16M");
224 _LIT(KColor16MU,"Color16MU");
225 _LIT(KColor16MA,"Color16MA");
226 _LIT(KColor16MAP,"Color16MAP");
228 _LIT(KUnknown,"Unknown");
264 EXPORT_C const TDesC& CTGraphicsBase::RotationName(CFbsBitGc::TGraphicsOrientation aOrientation)
267 _LIT(K90,"Rotated90");
268 _LIT(K180,"Rotated180");
269 _LIT(K270,"Rotated270");
270 _LIT(KUnknown,"Unknown");
273 case CFbsBitGc::EGraphicsOrientationNormal:
275 case CFbsBitGc::EGraphicsOrientationRotated90:
277 case CFbsBitGc::EGraphicsOrientationRotated180:
279 case CFbsBitGc::EGraphicsOrientationRotated270:
286 EXPORT_C void CTGraphicsBase::SaveScreenShotL(CFbsScreenDevice* aScdv)
289 _LIT(KBitmapDrive, "c:");
291 _LIT(KBitmapDrive, "e:");
293 _LIT(KBitmapPath, "\\screenshot.mbm");
294 TDisplayMode dispMode = aScdv->DisplayMode();
295 TSize scrSize = aScdv->SizeInPixels();
296 CFbsBitmap* dstBmp = new(ELeave) CFbsBitmap;
297 CleanupStack::PushL(dstBmp);
298 User::LeaveIfError(dstBmp->Create(scrSize, dispMode));
299 HBufC8* row = HBufC8::NewLC(scrSize.iWidth*4);
300 TPtr8 prow = row->Des();
301 for (TInt ii = 0; ii < scrSize.iHeight; ++ii)
303 aScdv->GetScanLine(prow, TPoint(0, ii), scrSize.iWidth, dispMode);
304 dstBmp->SetScanLine(prow,ii);
306 CleanupStack::PopAndDestroy(row);
308 mbmFile.Append(KBitmapDrive);
309 mbmFile.Append(KBitmapPath);
310 User::LeaveIfError(dstBmp->Save(mbmFile));
311 CleanupStack::PopAndDestroy(dstBmp);
314 EXPORT_C CTGraphicsBase::CTGraphicsBase(CTestStep* aStep) :
318 EXPORT_C CTGraphicsBase::~CTGraphicsBase()
322 iTestManager -> Cancel();
327 void CTGraphicsBase::InitializeL()
329 __ASSERT_DEBUG(iStep, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
330 iTestManager = CTestManager::NewL(this);
334 The function must be called after all test cases completed
336 EXPORT_C void CTGraphicsBase::TestComplete()
340 iTestManager -> FinishAllTestCases();
344 EXPORT_C void CTGraphicsBase::SetSelfDrive(TBool aSelfDrive)
347 iTestManager->SetSelfDrive(aSelfDrive);
350 EXPORT_C void CTGraphicsBase::CaseComplete()
353 iTestManager->CaseComplete();
356 EXPORT_C TInt CTGraphicsBase::RunTestCaseLeft(TInt aError)
358 _LIT(KRunTestCaseLLeft,"The RunTestCaseL left with %d");
359 ERR_PRINTF2(KRunTestCaseLLeft,aError);
360 iStep->SetTestStepResult(EFail);
364 /** Start a test cases loop */
365 void CTGraphicsBase::Execute()
367 __ASSERT_DEBUG(iTestManager, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
368 __ASSERT_DEBUG(CActiveScheduler::Current(), User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
370 iTestManager -> StartTest();
371 CActiveScheduler::Start();
374 Reset test cases counter to a new value. Can be used for running the same consequence of test
375 cases with different initial parameters.
376 aNewCurrentTestCase cannot be negative.
378 EXPORT_C void CTGraphicsBase::ResetCounter(TInt aNewCurrentTestCase )
380 __ASSERT_DEBUG(aNewCurrentTestCase >= 0, User::Panic(KGraphicsTestFrameworkPanic, KErrArgument));
381 iTestManager->iCurTestCaseNumber = aNewCurrentTestCase;
384 //---------------------
386 Initialise the cleanup stack.
388 void CTGraphicsStep::SetupCleanup(CTrapCleanup*& tc)
390 tc = CTrapCleanup::New();
393 User::Panic(_L("Out of memory"), KErrNoMemory);
398 for ( TInt ii = KTestCleanupStack; ii > 0; ii-- )
399 CleanupStack::PushL( (TAny*)1 );
400 TEST( r == KErrNone );
401 CleanupStack::Pop( KTestCleanupStack );
405 void CTGraphicsStep::LogHeapInfo(RWsSession& aWs, TBool aStart)
407 _LIT(KInfoStart,"Start");
408 _LIT(KInfoEnd,"End");
409 _LIT(KInfoCheckPassed,"WsHeap leak check passed");
410 _LIT(KInfoCheckFailed,"Memory leak detected. Number of orphaned cells=%d.");
411 _LIT(KInfoCheckFailed2,"See epocwindout for the address of the first orphaned cell.");
412 _LIT(KInfoHeapSummary," WsHeap - Count=%d,Total=%d,Free=%d,Max free=%d");
413 _LIT(KInfoDisabled,"Memory leak testing has not been enabled.");
415 TPckgBuf<TWsDebugHeapInfo> heapInfo;
416 aWs.DebugInfo(EWsDebugInfoHeap,heapInfo);
420 infoBuf.Append(KInfoStart);
424 infoBuf.Append(KInfoEnd);
425 TInt heapFailCount=aWs.DebugInfo(EWsDebugFetchCheckHeapResult);
426 if (heapFailCount==KErrNone)
428 INFO_PRINTF1(KInfoCheckPassed);
430 else if (heapFailCount>0) // Negative error should be ignored as it means the check has not been enabled
433 ERR_PRINTF2(KInfoCheckFailed,heapFailCount);
434 ERR_PRINTF1(KInfoCheckFailed2);
438 WARN_PRINTF1(KInfoDisabled);
441 infoBuf.AppendFormat(KInfoHeapSummary,heapInfo().iCount,heapInfo().iTotal,heapInfo().iAvailable,heapInfo().iLargestAvailable);
442 INFO_PRINTF1(infoBuf);
446 Main entry point from CTestStep class.
447 Creates cleanup stack, background window and launches a test
449 EXPORT_C TVerdict CTGraphicsStep::doTestStepL()
452 HAL::Get(HALData::EMemoryRAMFree, memFree);
453 INFO_PRINTF2(_L("Test started - RAM free: %d"), memFree);
456 CTrapCleanup* tc = NULL;
459 TInt err = RFbsSession::Connect();
463 err = RFbsSession::Connect();
467 User::Panic(_L("Font bitmap session connect"), err);
472 if (iLogHeapInfo && err==KErrNone)
474 ws.DebugInfo(EWsDebugSetCheckHeapOnDisconnectClient);
475 LogHeapInfo(ws,ETrue);
479 RWindowGroup winGroup = RWindowGroup(ws);
480 RWindow theWindow(ws);
483 const TUint32 ENullWsHandle = 0xFFFFFFFF; // Events delivered to this handle are thrown away
484 //creat background window with the size of the screen
485 //it is particulary important for tests which draw on the screen, read screen buffer
486 //and compare result. By default top TEF window is concole and blinking cursor can interfere
487 //with the work of the tests
488 TSize size(640, 240); //some default value
489 //retrieve screen size
490 err = GetScreenSize(size);
493 WARN_PRINTF2(_L("Can't retrieve size from screen driver err = %d"), err);
496 winGroup.Construct(ENullWsHandle);
497 winGroup.AutoForeground(ETrue);
498 theId1 = winGroup.Identifier();
500 theWindow.Construct(winGroup, ENullWsHandle);
501 theWindow.SetExtent(TPoint(0, 0), size);
502 theWindow.SetVisible(ETrue);
503 theWindow.Activate();
505 //the following trick we need to put the window on the top
506 TApaTaskListFacade taskList(ws);
507 TApaTaskFacade task = taskList.FindByPos(1);
508 task.BringToForeground();
509 TApaTaskFacade task1(ws);
510 task1.SetWgId(theId1);
511 task1.BringToForeground();
516 CloseAllPanicWindows(theId1, ws);
519 // initialize the test and kick off the test cases loop
520 TRAP(err, TestSetupL(); // initialize a test step
521 ExecuteL()); // run active scheduler, in order to complete test execution
522 // CTGraphicsStep::TestComplete function needs to be called
526 SetTestStepResult(EFail);
529 TestClose(); // free all allocated resources here
533 CloseAllPanicWindows(theId1, ws);
540 // Prev close will trigger Wserv dummy shutdown and heap check
541 // We then re-connect to get the result of the shutdown.
544 TInt MaxNumberOfAttempt=10;
545 TInt currentAttempt=0;
548 errConnection=ws2.Connect();
549 if (errConnection==KErrNone)
551 LogHeapInfo(ws2,EFalse);
556 RDebug::Printf("Connection Error with Wserv... %i",errConnection);
560 }while( (errConnection!=KErrNone) && (currentAttempt<MaxNumberOfAttempt) );
562 RFbsSession::Disconnect();
568 return TestStepResult();
571 void CTGraphicsStep::CloseAllPanicWindows(TInt aId, RWsSession& ws) const
573 TInt idFocus = ws.GetFocusWindowGroup();
575 event.SetType(EEventKey); //EEventKeyDown
576 TKeyEvent *keyEvent = event.Key();
577 keyEvent->iCode = EKeyEscape;
578 keyEvent->iScanCode = EStdKeyEscape;
579 keyEvent->iModifiers = 0;
581 while(idFocus != aId && (theLimit-- > 0))
583 ws.SendEventToAllWindowGroups(event);
584 idFocus = ws.GetFocusWindowGroup();
588 TInt CTGraphicsStep::GetScreenSize(TSize& aSize) const
590 CFbsScreenDevice* dev = NULL;
593 TInt sizeOfDisplayMode = sizeof (testDisplayModes) / sizeof(testDisplayModes[0]);
595 for(TInt theScreenModeIndex = sizeOfDisplayMode - 1; theScreenModeIndex ; theScreenModeIndex--)
597 TDisplayMode disp = testDisplayModes[theScreenModeIndex];
598 TRAP(err, dev = CFbsScreenDevice::NewL(_L(""), disp)); //scdv
601 aSize = dev->SizeInPixels();
612 /** Installs an active scheduler and launches a test*/
613 void CTGraphicsStep::ExecuteL()
615 CActiveScheduler* theAs = new (ELeave) CActiveScheduler;
616 CleanupStack::PushL(theAs);
617 CActiveScheduler::Install(theAs);
619 CTGraphicsBase* autoTest = CreateTestL();
620 User::LeaveIfNull(autoTest);
621 CleanupStack::PushL(autoTest);
623 autoTest -> InitializeL();
624 autoTest -> ConstructL();
625 autoTest -> Execute();
627 CleanupStack::PopAndDestroy(2, theAs);