os/graphics/graphicstest/graphicstestharness/src/TGraphicsHarness.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 
    17 #include <hal.h>
    18 #include <w32debug.h>
    19 #include <e32std.h> 
    20 #include <graphics/fbsdefs.h>
    21 
    22 #include "apgrfxfacade.h"
    23 #include "TGraphicsHarness.h"
    24 #include "GraphicsTestUtilsServer.h"
    25 
    26 _LIT(KGraphicsTestFrameworkPanic, "Graphics Test Framework");
    27 const TInt KTestCleanupStack = 0x40;
    28 
    29 const TDisplayMode testDisplayModes[] =	
    30 	{
    31 	EGray2,
    32 	EGray4,
    33 	EGray16,
    34 	EGray256,
    35 	EColor16,
    36 	EColor256,
    37 	EColor64K,
    38 	EColor16M,
    39 	EColor4K,
    40 	EColor16MU,
    41 	EColor16MA,
    42 	EColor16MAP,
    43 	};
    44 
    45 /**
    46   The test code manager, provides functions to set active object 
    47   with lowest priority for running tests in auto mode.
    48  */
    49 class CTestManager : public CActive
    50 	{
    51 friend class CTGraphicsBase;
    52 protected:
    53 	static CTestManager* NewL(MTestCases* aAutoTestApp);
    54 	~CTestManager();
    55 	void FinishAllTestCases();
    56 	void StartTest(); //initialize an active object and set it status as active
    57 	void SetSelfDrive(TBool aSelfDrive);
    58 	void CaseComplete();
    59 private:
    60 	CTestManager(MTestCases* aAutoTestApp);
    61 	void NextTest();
    62 	// from CActive
    63 	void RunL();
    64 	void DoCancel();
    65 	TInt RunError(TInt aError);
    66 private:
    67 	MTestCases* iTestCase;
    68 	TInt iCurTestCaseNumber; //a current test case, every time when function RunTestCaseL is called this member inc by one
    69 	TBool iTestCompleted;
    70 	TBool iSelfDrive;
    71 	};
    72 
    73 /** Construct an active object with the lowest priority */
    74 CTestManager::CTestManager(MTestCases* aTestCases) :
    75 		CActive(EPriorityIdle), iTestCase(aTestCases), iSelfDrive(EFalse)
    76 	{}
    77 
    78 CTestManager::~CTestManager()
    79 	{
    80 	Cancel();
    81 	}
    82 
    83 CTestManager* CTestManager::NewL(MTestCases* aTestCases)
    84 	{
    85      CTestManager *theTestManager=new (ELeave) CTestManager(aTestCases);
    86      CActiveScheduler::Add(theTestManager);
    87 	 return theTestManager;
    88 	}
    89 
    90 void CTestManager::RunL()
    91 	{
    92 	__ASSERT_ALWAYS(iTestCase, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
    93 	if(	iTestCompleted)
    94 		{
    95 		return;
    96 		}
    97 	
    98 	// debug statement to indicate progress of test suite by
    99 	// printing the sub-test that is currently active
   100 	TTime timeStamp;
   101 	timeStamp.HomeTime();
   102 	TBuf<50> dateStr;
   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);
   107 
   108 	iTestCase->RunTestCaseL(iCurTestCaseNumber);
   109 	if (iTestCompleted)
   110 		{
   111 		_LIT(KFinished,"Finished test case %d and test completed");
   112 		RDebug::Print(KFinished,iCurTestCaseNumber);
   113 		}
   114 	else
   115 		{
   116 		if (iSelfDrive)
   117 			{
   118 			_LIT(KStarted,"Started test case %d");
   119 			RDebug::Print(KStarted,iCurTestCaseNumber);
   120 			}
   121 		else
   122 			{
   123 			NextTest();
   124 			}
   125 		}
   126 	}
   127 
   128 void CTestManager::DoCancel()
   129 	{
   130 	if (!iSelfDrive)
   131 		iTestCompleted = ETrue;
   132 	}
   133 
   134 TInt CTestManager::RunError(TInt aError)
   135 	{
   136 	TTime timeStamp;
   137 	timeStamp.HomeTime();
   138 	TBuf<50> dateStr;
   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);
   143 	
   144 	aError = iTestCase->RunTestCaseLeft(aError);
   145 	FinishAllTestCases();
   146 	return aError;
   147 	}
   148 
   149 /**
   150  	Initialize an active object and set it as active
   151  */
   152 void CTestManager::StartTest()
   153 	{
   154 	TRequestStatus *pS= (&iStatus);
   155 	User::RequestComplete(pS, 0);
   156 	SetActive();
   157 	}
   158 
   159 /**
   160  Time to move on to the next test step
   161  */
   162 void CTestManager::NextTest()
   163 	{
   164 	_LIT(KFinished,"Finished test case %d");
   165 	RDebug::Print(KFinished,iCurTestCaseNumber);
   166 	StartTest();
   167 	}
   168 
   169 /**
   170  Stop active scheduler, and quit a test step
   171  */
   172 void CTestManager::FinishAllTestCases()
   173 	{
   174 	iTestCompleted = ETrue;
   175 	CActiveScheduler::Stop();
   176 	}
   177 
   178 /**
   179  Controls wether the manager calls RunTestCaseL whenever the system is otherwise idol
   180  */
   181 void CTestManager::SetSelfDrive(TBool aSelfDrive)
   182 	{
   183 	if (iSelfDrive!=aSelfDrive)
   184 		{
   185 		iSelfDrive = aSelfDrive;
   186 		if (aSelfDrive)
   187 			{
   188 			if (IsActive())
   189 				Cancel();
   190 			}
   191 		else
   192 			{
   193 			if (!IsActive() && !iTestCompleted)
   194 				NextTest();
   195 			}
   196 		}
   197 	}
   198 
   199 /**
   200  Tells the manager this case is finished so you can call RunTestCaseL again
   201  */
   202 void CTestManager::CaseComplete()
   203 	{
   204 	__ASSERT_DEBUG(!IsActive(), User::Panic(KGraphicsTestFrameworkPanic, ETestPanicAlreadyActive));
   205 	if (iSelfDrive && !iTestCompleted)
   206 		NextTest();
   207 	}
   208 
   209 
   210 //-------------
   211 
   212 EXPORT_C const TDesC& CTGraphicsBase::ColorModeName(TDisplayMode aMode)
   213 	{
   214 	_LIT(KNone,"None");
   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");
   227 	_LIT(KRgb,"RGB");
   228 	_LIT(KUnknown,"Unknown");
   229 	switch(aMode)
   230 		{
   231 	case ENone:
   232 		return KNone;
   233 	case EGray2:
   234 		return KGray2;
   235 	case EGray4:
   236 		return KGray4;
   237 	case EGray16:
   238 		return KGray16;
   239 	case EGray256:
   240 		return KGray256;
   241 	case EColor16:
   242 		return KColor16;
   243 	case EColor256:
   244 		return KColor256;
   245 	case EColor64K:
   246 		return KColor64K;
   247 	case EColor16M:
   248 		return KColor16M;
   249 	case ERgb:
   250 		return KRgb;
   251 	case EColor4K:
   252 		return KColor4K;
   253 	case EColor16MU:
   254 		return KColor16MU;
   255 	case EColor16MA:
   256 		return KColor16MA;
   257 	case EColor16MAP:
   258 		return KColor16MAP;
   259 	default:
   260 		return KUnknown;
   261 		}
   262 	}
   263 
   264 EXPORT_C const TDesC& CTGraphicsBase::RotationName(CFbsBitGc::TGraphicsOrientation aOrientation)
   265 	{
   266 	_LIT(K0,"Normal");
   267 	_LIT(K90,"Rotated90");
   268 	_LIT(K180,"Rotated180");
   269 	_LIT(K270,"Rotated270");
   270 	_LIT(KUnknown,"Unknown");
   271 	switch(aOrientation)
   272 		{
   273 	case CFbsBitGc::EGraphicsOrientationNormal:
   274 		return K0;
   275 	case CFbsBitGc::EGraphicsOrientationRotated90:
   276 		return K90;
   277 	case CFbsBitGc::EGraphicsOrientationRotated180:
   278 		return K180;
   279 	case CFbsBitGc::EGraphicsOrientationRotated270:
   280 		return K270;
   281 	default:
   282 		return KUnknown;
   283 		}
   284 	}
   285 
   286 EXPORT_C void CTGraphicsBase::SaveScreenShotL(CFbsScreenDevice* aScdv)
   287 	{
   288 #ifdef __WINS__
   289 	_LIT(KBitmapDrive, "c:");
   290 #else
   291 	_LIT(KBitmapDrive, "e:");
   292 #endif
   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)
   302 		{
   303 		aScdv->GetScanLine(prow, TPoint(0, ii), scrSize.iWidth, dispMode);
   304 		dstBmp->SetScanLine(prow,ii);
   305 		}
   306 	CleanupStack::PopAndDestroy(row);
   307 	TFileName mbmFile;
   308 	mbmFile.Append(KBitmapDrive);
   309 	mbmFile.Append(KBitmapPath);	
   310 	User::LeaveIfError(dstBmp->Save(mbmFile));
   311 	CleanupStack::PopAndDestroy(dstBmp);
   312 	}
   313 
   314 EXPORT_C CTGraphicsBase::CTGraphicsBase(CTestStep* aStep) :
   315 			iStep(aStep)
   316 	{}
   317 
   318 EXPORT_C CTGraphicsBase::~CTGraphicsBase()
   319 	{
   320 	if(iTestManager)
   321 		{
   322 		iTestManager -> Cancel();
   323 		}
   324 	delete iTestManager;
   325 	}
   326 
   327 void CTGraphicsBase::InitializeL()
   328 	{
   329 	__ASSERT_DEBUG(iStep, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
   330 	iTestManager = CTestManager::NewL(this);
   331 	}
   332 	
   333 /**
   334  	The function must be called after all test cases completed 
   335  */	
   336 EXPORT_C void CTGraphicsBase::TestComplete()
   337 	{
   338 	if(iTestManager)
   339 		{
   340 		iTestManager -> FinishAllTestCases();
   341 		}
   342 	}
   343 
   344 EXPORT_C void CTGraphicsBase::SetSelfDrive(TBool aSelfDrive)
   345 	{
   346 	if (iTestManager)
   347 		iTestManager->SetSelfDrive(aSelfDrive);
   348 	}
   349 
   350 EXPORT_C void CTGraphicsBase::CaseComplete()
   351 	{
   352 	if (iTestManager)
   353 		iTestManager->CaseComplete();
   354 	}
   355 
   356 EXPORT_C TInt CTGraphicsBase::RunTestCaseLeft(TInt aError)
   357 	{
   358 	_LIT(KRunTestCaseLLeft,"The RunTestCaseL left with %d");
   359 	ERR_PRINTF2(KRunTestCaseLLeft,aError);
   360 	iStep->SetTestStepResult(EFail);
   361 	return KErrNone;
   362 	}
   363 
   364 /** Start a test cases loop */
   365 void CTGraphicsBase::Execute()
   366 	{
   367 	__ASSERT_DEBUG(iTestManager, User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
   368 	__ASSERT_DEBUG(CActiveScheduler::Current(), User::Panic(KGraphicsTestFrameworkPanic, KErrBadHandle));
   369 
   370 	iTestManager -> StartTest();
   371 	CActiveScheduler::Start();
   372 	}
   373 /**
   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.
   377 */
   378 EXPORT_C void CTGraphicsBase::ResetCounter(TInt aNewCurrentTestCase )
   379 	{
   380 	__ASSERT_DEBUG(aNewCurrentTestCase >= 0, User::Panic(KGraphicsTestFrameworkPanic, KErrArgument));
   381 	iTestManager->iCurTestCaseNumber = aNewCurrentTestCase;
   382 	}
   383 
   384 //---------------------
   385 /**
   386  Initialise the cleanup stack.
   387 */
   388 void CTGraphicsStep::SetupCleanup(CTrapCleanup*& tc)
   389     {
   390 	tc = CTrapCleanup::New();
   391 	if (!tc)
   392 		{
   393 		User::Panic(_L("Out of memory"), KErrNoMemory);
   394 		}
   395 
   396 	TRAPD(r, 
   397 		{
   398 		for ( TInt ii = KTestCleanupStack; ii > 0; ii-- )
   399 			CleanupStack::PushL( (TAny*)1 );
   400 		TEST( r == KErrNone );
   401 		CleanupStack::Pop( KTestCleanupStack );
   402 		} );
   403 	}
   404 
   405 void CTGraphicsStep::LogHeapInfo(RWsSession& aWs, TBool aStart)
   406 	{
   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.");
   414 
   415 	TPckgBuf<TWsDebugHeapInfo> heapInfo;
   416 	aWs.DebugInfo(EWsDebugInfoHeap,heapInfo);
   417 	TBuf<256> infoBuf;
   418 	if (aStart)
   419 		{
   420 		infoBuf.Append(KInfoStart);
   421 		}
   422 	else
   423 		{
   424 		infoBuf.Append(KInfoEnd);
   425 		TInt heapFailCount=aWs.DebugInfo(EWsDebugFetchCheckHeapResult);
   426 		if (heapFailCount==KErrNone)
   427 			{
   428 			INFO_PRINTF1(KInfoCheckPassed);
   429 			}
   430 		else if (heapFailCount>0) // Negative error should be ignored as it means the check has not been enabled
   431 			{
   432 			TEST(0);
   433 			ERR_PRINTF2(KInfoCheckFailed,heapFailCount);
   434 			ERR_PRINTF1(KInfoCheckFailed2);
   435 			}
   436 		else
   437 		    {
   438 		    WARN_PRINTF1(KInfoDisabled);
   439 		    }
   440 		}
   441 	infoBuf.AppendFormat(KInfoHeapSummary,heapInfo().iCount,heapInfo().iTotal,heapInfo().iAvailable,heapInfo().iLargestAvailable);
   442 	INFO_PRINTF1(infoBuf);
   443 	}
   444 
   445 /**
   446  Main entry point from CTestStep class. 
   447  Creates cleanup stack, background window and launches a test
   448 */
   449 EXPORT_C TVerdict CTGraphicsStep::doTestStepL()
   450 	{
   451 	TInt memFree;
   452 	HAL::Get(HALData::EMemoryRAMFree, memFree);
   453 	INFO_PRINTF2(_L("Test started - RAM free: %d"), memFree);	
   454 	
   455 	__UHEAP_MARK;
   456 	CTrapCleanup* tc = NULL;
   457 	SetupCleanup(tc);
   458 	
   459 	TInt err = RFbsSession::Connect();
   460 	if(err != KErrNone)
   461 		{
   462 		FbsStartup();
   463 		err = RFbsSession::Connect();
   464 
   465 		if(err != KErrNone) 
   466 			{
   467 			User::Panic(_L("Font bitmap session connect"), err);
   468 			}
   469 		}
   470 	RWsSession ws;
   471 	err = ws.Connect();
   472 	if (iLogHeapInfo && err==KErrNone)
   473 		{
   474 		ws.DebugInfo(EWsDebugSetCheckHeapOnDisconnectClient);
   475 		LogHeapInfo(ws,ETrue);
   476 		}
   477 	TInt theId1 = NULL;
   478 #ifdef __WINS__
   479 	RWindowGroup winGroup = RWindowGroup(ws);
   480 	RWindow theWindow(ws);
   481 	if (err==KErrNone)
   482 		{
   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);
   491 		if(err)
   492 			{
   493 			WARN_PRINTF2(_L("Can't retrieve size from screen driver err = %d"), err);
   494 			}
   495 
   496 		winGroup.Construct(ENullWsHandle);
   497 		winGroup.AutoForeground(ETrue);
   498 		theId1 = winGroup.Identifier();
   499 	
   500 		theWindow.Construct(winGroup, ENullWsHandle);
   501 		theWindow.SetExtent(TPoint(0, 0), size);
   502 		theWindow.SetVisible(ETrue);
   503 		theWindow.Activate();
   504 	
   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();
   512 		}
   513 #endif
   514 	if (err==KErrNone)
   515 		{
   516 		CloseAllPanicWindows(theId1, ws);
   517 		}
   518 
   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
   523 
   524 	if (err)
   525 		{
   526 		SetTestStepResult(EFail);
   527 		}
   528 		
   529 	TestClose(); // free all allocated resources here
   530 	
   531 	if (ws.Handle())
   532 		{
   533 		CloseAllPanicWindows(theId1, ws);
   534 #ifdef __WINS__	
   535 		theWindow.Close();
   536 		winGroup.Close();
   537 #endif
   538 		ws.Close();
   539 		User::After(50000);	
   540 		// Prev close will trigger Wserv dummy shutdown and heap check
   541 		// We then re-connect to get the result of the shutdown.
   542 		RWsSession ws2;
   543 		TInt errConnection;
   544 		TInt MaxNumberOfAttempt=10;
   545 		TInt currentAttempt=0;		
   546 		do
   547 			{
   548 			errConnection=ws2.Connect();		
   549 			if (errConnection==KErrNone)
   550 				{
   551 				LogHeapInfo(ws2,EFalse);
   552 				ws2.Close();
   553 				}
   554 			else
   555 				{
   556 				RDebug::Printf("Connection Error with Wserv... %i",errConnection);
   557 				User::After(50000);		
   558 				}
   559 			currentAttempt++;
   560 			}while( (errConnection!=KErrNone) && (currentAttempt<MaxNumberOfAttempt) );
   561 		}
   562 	RFbsSession::Disconnect();	
   563 
   564 	delete tc;
   565 
   566 	__UHEAP_MARKEND;
   567 	
   568 	return TestStepResult();
   569 	}
   570 
   571 void CTGraphicsStep::CloseAllPanicWindows(TInt aId, RWsSession& ws) const
   572 	{
   573 	TInt idFocus = ws.GetFocusWindowGroup();
   574 	TWsEvent event;
   575 	event.SetType(EEventKey); //EEventKeyDown
   576 	TKeyEvent *keyEvent = event.Key();
   577 	keyEvent->iCode = EKeyEscape;
   578 	keyEvent->iScanCode = EStdKeyEscape;
   579 	keyEvent->iModifiers = 0;
   580 	TInt theLimit = 50;
   581 	while(idFocus != aId && (theLimit-- > 0))
   582 		{
   583 		ws.SendEventToAllWindowGroups(event);
   584 		idFocus = ws.GetFocusWindowGroup();
   585 		}
   586 	}
   587 	
   588 TInt CTGraphicsStep::GetScreenSize(TSize& aSize) const
   589 	{
   590 	CFbsScreenDevice* dev = NULL;
   591 	
   592 	TInt err = KErrNone;
   593 	TInt sizeOfDisplayMode = sizeof (testDisplayModes) / sizeof(testDisplayModes[0]);
   594 	 
   595 	for(TInt theScreenModeIndex = sizeOfDisplayMode - 1; theScreenModeIndex ; theScreenModeIndex--)
   596 		{
   597 		TDisplayMode disp = testDisplayModes[theScreenModeIndex];
   598 		TRAP(err, dev = CFbsScreenDevice::NewL(_L(""), disp)); //scdv
   599 		if(err == KErrNone)
   600 			{
   601 			aSize = dev->SizeInPixels();
   602 			delete dev;
   603 			return KErrNone;
   604 			}
   605 		delete dev;
   606 		dev = NULL;		
   607 		}
   608 	
   609 	return err;		
   610 	}
   611 
   612 /** Installs an active scheduler and launches a test*/
   613 void CTGraphicsStep::ExecuteL()
   614 	{
   615 	CActiveScheduler* theAs = new (ELeave) CActiveScheduler;
   616 	CleanupStack::PushL(theAs);
   617 	CActiveScheduler::Install(theAs);
   618 
   619 	CTGraphicsBase*	autoTest = CreateTestL();
   620 	User::LeaveIfNull(autoTest);
   621 	CleanupStack::PushL(autoTest);
   622 
   623 	autoTest -> InitializeL();
   624 	autoTest -> ConstructL();
   625 	autoTest -> Execute();
   626 
   627 	CleanupStack::PopAndDestroy(2, theAs);
   628 	}
   629 
   630 TInt  E32Dll( )
   631 	{
   632 	return 0;
   633 	}
   634