kerneltest/e32test/dispchan/t_dispchan.cpp
changeset 0 a41df078684a
child 4 56f325a607ea
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2008-2009 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 the License "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 // This test should not depend on any external data files and should work with
       
    15 // the default (empty) epoc.ini file.
       
    16 // The test should be run without the Graphics GCE enabled but with the Base GCE
       
    17 // driver enabled. On the emulator this can be done by launcing with -Dtextshell --
       
    18 // and on the H4 build a textshell ROM with -DSYMBIAN_BASE_USE_GCE but NOT 
       
    19 // -DSYMBIAN_GRAPHICS_USE_GCE
       
    20 // In the visual tests some flickering may occur due to updates to the console. On
       
    21 // the emulator it is possible to configure a second screen so that the console updates
       
    22 // will only happen on one screen. The test automatically runs on every screen available.
       
    23 // 
       
    24 //
       
    25 
       
    26 #define __E32TEST_EXTENSION__
       
    27 
       
    28 #include <dispchannel.h>
       
    29 #include <e32std.h>
       
    30 #include <e32std_private.h>
       
    31 #include <e32svr.h>
       
    32 #include <e32test.h>
       
    33 #include <pixelformats.h>
       
    34 #include <hal.h>
       
    35 
       
    36 RTest test(_L("Display Channel device driver unit tests"));
       
    37 
       
    38 /** Maximum probable pixel resolution width or height */
       
    39 static const TInt KMaxExpectedPixelRes = 10000;
       
    40 
       
    41 /** Unlikely to ever have a > 1000 Hz refresh rate */
       
    42 static const TInt KMaxExpectedRefreshRate = 1000;
       
    43 
       
    44 /** Time (in microseconds) for each visual test */
       
    45 static const TInt KDrawWaitTime = 1000000;
       
    46 
       
    47 /** Array of supported rotations */
       
    48 static const RDisplayChannel::TDisplayRotation KRotations[] = {
       
    49 		RDisplayChannel::ERotationNormal, 
       
    50 		RDisplayChannel::ERotation90CW,
       
    51 		RDisplayChannel::ERotation180,
       
    52 		RDisplayChannel::ERotation270CW};
       
    53 static const TInt KNumRotations = sizeof(KRotations) / sizeof(RDisplayChannel::TDisplayRotation);
       
    54 
       
    55 /** Array of pixel formats to try for visual test */
       
    56 static const RDisplayChannel::TPixelFormat KPixelFormats[] = {
       
    57 	EUidPixelFormatYUV_422Interleaved16bit,	// not supported on emulator but should not be a fatal error
       
    58 	EUidPixelFormatXRGB_4444,	
       
    59 	EUidPixelFormatARGB_4444,
       
    60 	EUidPixelFormatRGB_565,
       
    61 	EUidPixelFormatXRGB_8888,
       
    62 	EUidPixelFormatARGB_8888,
       
    63 	EUidPixelFormatARGB_8888_PRE	
       
    64 };
       
    65 static const TInt KNumPixelFormats = sizeof(KPixelFormats) / sizeof(RDisplayChannel::TPixelFormat);
       
    66 
       
    67 /**
       
    68 Encapsulates display related HAL information. 
       
    69 */
       
    70 class THalDisplayInfo 
       
    71 	{
       
    72 public:
       
    73 	TBool iIsMono;
       
    74 	TBool iIsPalettized;
       
    75 	TInt iBitsPerPixel;
       
    76 	TInt iMemoryAddress;
       
    77 	TInt iMemoryHandle;
       
    78 	TInt iState;
       
    79 	TInt iColors;
       
    80 	TInt iXPixels;
       
    81 	TInt iYPixels;
       
    82 	TInt iXTwips;
       
    83 	TInt iYTwips;
       
    84 	TInt iNumModes;	
       
    85 	TInt iMode;
       
    86 	TInt iOffsetBetweenLines;
       
    87 	TInt iOffsetToFirstPixel;
       
    88 	TBool iIsPixelOrderRGB;
       
    89 	TBool iIsPixelOrderLandscape;
       
    90 	};
       
    91 
       
    92 /**
       
    93 Helper class that waits for RDisplayChannel asynchronous requests and
       
    94 can cancel them if necessary. The purpose of this class is so that the main 
       
    95 test class can create an asynchronous request and also simulate the completion
       
    96 of that request e.g. faking a display change event.
       
    97 */
       
    98 class CAsyncHelper : public CActive
       
    99 	{
       
   100 public:
       
   101 	inline CAsyncHelper(RDisplayChannel& aDisp);
       
   102 	inline ~CAsyncHelper();
       
   103 	inline TRequestStatus& Status();
       
   104 	void WaitForOperation(TInt* aResult);
       
   105 private:
       
   106 	// From CActive
       
   107 	inline void DoCancel();
       
   108 	inline void RunL();	
       
   109 private:
       
   110 	RDisplayChannel& iDisp;
       
   111 	TInt* iResult;
       
   112 	};
       
   113 
       
   114 inline CAsyncHelper::CAsyncHelper(RDisplayChannel& aDisp) : CActive(EPriorityHigh), iDisp(aDisp) {CActiveScheduler::Add(this);}
       
   115 inline CAsyncHelper::~CAsyncHelper() {Deque();}
       
   116 inline TRequestStatus& CAsyncHelper::Status() {return iStatus;}
       
   117 // Writes the iStatus.Int() to the address defined by the client of this AO
       
   118 inline void CAsyncHelper::RunL() {*iResult = iStatus.Int();}
       
   119 
       
   120 void CAsyncHelper::WaitForOperation(TInt* aResult)
       
   121 /**
       
   122 Invokes SetActive() to wait for the asynchronous operation to complete. The completion
       
   123 code is copied to the aResult when RunL is invoked.
       
   124 @param aResult	out parameter that will be set to iStatus.Int()
       
   125 */
       
   126 	{
       
   127 	iResult = aResult; 	
       
   128 	// Set the result to default value that is unlikely to be returned by the real API
       
   129 	*aResult = KMaxTInt;
       
   130 	SetActive();
       
   131 	}
       
   132 
       
   133 void CAsyncHelper::DoCancel()
       
   134 	{
       
   135 	// Driver should fail if cancel is called when there is not standing request
       
   136 	// so cancel just attempts to cancel everything.
       
   137 	iDisp.CancelGetCompositionBuffer();
       
   138 	iDisp.CancelPostUserBuffer();
       
   139 	iDisp.CancelWaitForPost();
       
   140 	iDisp.NotifyOnDisplayChangeCancel();
       
   141 	}
       
   142 
       
   143 /**
       
   144 Class to test device driver for RDisplayChannel
       
   145 */
       
   146 class CDisplayChannelTest : public CActive
       
   147 	{
       
   148 	enum TTestState {
       
   149 		ETestDisplayInfo,
       
   150 		ETestCompositionBuffers,
       
   151 		ETestUserBuffers,
       
   152 		ETestRotations,
       
   153 		ETestDisplayChange,
       
   154 		ETestDisplayChangeDoCancel,
       
   155 		ETestDisplayChangeCheckCancel,
       
   156 		ETestGetCompositionBufferDoCancel,
       
   157 		ETestGetCompositionBufferCheckCancel,
       
   158 		ETestWaitForPostDoCancel,
       
   159 		ETestWaitForPostCheckCancel,
       
   160 		ETestResolutions,
       
   161 		ETestPixelFormats,
       
   162 		ETestBufferFormats,
       
   163 		ETestV11inV10,
       
   164 		EVisualTest,
       
   165 		ETestSecondHandle,
       
   166 		ETestFinished
       
   167 	};
       
   168 	
       
   169 	public:
       
   170 		static CDisplayChannelTest* NewLC(TInt aScreenId);
       
   171 		void Start();
       
   172 		~CDisplayChannelTest();
       
   173 		
       
   174 	private:		
       
   175 		// From CActive
       
   176 		void DoCancel();
       
   177 		TInt RunError(TInt aError);
       
   178 		void RunL();
       
   179 
       
   180 	private:		
       
   181 		CDisplayChannelTest(TInt aScreenId);
       
   182 		void CompleteSelf(TTestState aNextState);
       
   183 
       
   184 		// The tests
       
   185 		void CheckDisplayInfo();
       
   186 		void CheckResolutions();
       
   187 		void CheckPixelFormats();
       
   188 		void CheckDisplayChange();
       
   189 		void CheckCompositionBuffers();
       
   190 		void CheckBufferFormat();
       
   191 		void CheckUserBuffers();
       
   192 		void CheckRotations();
       
   193 		TBool IsValidRotation(RDisplayChannel::TDisplayRotation aRotation);
       
   194 		TBool IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat);		
       
   195 		void CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation);
       
   196 		void CheckV11inV10();
       
   197 		void VisualTest();
       
   198 		void DrawLegacyBuffer(TInt aStep);
       
   199 		void DrawFillToMemory(TUint8* aFirstPixelAddr, TInt aOffsetBetweenLines, 
       
   200 				RDisplayChannel::TPixelFormat aPixelFormat, TInt aWidth, TInt aHeight, TInt aStep);
       
   201 		void DrawCompositionBuffer(
       
   202 				RDisplayChannel::TPostCount& aPostCount, 
       
   203 				RDisplayChannel::TBufferFormat aBufferFormat,
       
   204 				RDisplayChannel::TDisplayRotation aRotation, TInt aStep);
       
   205 		void GetHalDisplayInfo();
       
   206 		void CheckSecondHandle();
       
   207 
       
   208 	private:
       
   209 		RDisplayChannel iDisp;			/// handle to display channel device driver
       
   210 		TVersion iVersion;				/// version number of disp channel driver interface
       
   211 		THalDisplayInfo iHalInfo;		/// info about legacy buffer from HAL
       
   212 		TInt iScreenId;					/// run tests on each screen
       
   213 		TTestState iState;				/// the current test
       
   214 		CAsyncHelper *iAsyncHelper;				
       
   215 		TInt iAsyncHelperResult;		/// set to iAyncHelper::iStatus.Int()
       
   216 		RArray<RDisplayChannel::TResolution> iResolutions;
       
   217 		RArray<RDisplayChannel::TPixelFormat> iPixelFormats;
       
   218 		TInt iVisualTestFormatIndex;		/// index of the current pixel format in visual test 
       
   219 		TInt iVisualTestRotationIndex;		/// index of the current rotation in the visual test
       
   220 		TUint iDummyCompositionBuffer;		/// dummy var used to test cancel of GetCompositionBuffer
       
   221 		RDisplayChannel::TPostCount iDummyPostCount;	/// dummy var used to test CancelWaitForPost 
       
   222 	};
       
   223 
       
   224 // Gets a HAL value, logs the result and errors if HAL::Get failed
       
   225 #define DBG_HAL(DEVICE, ATT, VAL, ERR, IN) \
       
   226 	{ \
       
   227 	VAL = IN;\
       
   228 	ERR = HAL::Get(DEVICE, ATT, VAL); \
       
   229 	test.Printf(_L(#ATT)); \
       
   230 	test.Printf(_L(" device %d err = %d, val = %d\n"), DEVICE, ERR, VAL); \
       
   231 	test_KErrNone(ERR); \
       
   232 	}
       
   233 
       
   234 void CDisplayChannelTest::GetHalDisplayInfo()
       
   235 /**
       
   236 Retrieves display related HAL settings. This also initialises the legacy buffer by retrieving
       
   237 HAL::EDisplayMemoryAddress
       
   238 */
       
   239 	{
       
   240 	TInt err = KErrNotSupported;	
       
   241 		
       
   242 	DBG_HAL(iScreenId, HAL::EDisplayMemoryAddress, iHalInfo.iMemoryAddress, err, 0);
       
   243 			
       
   244 	iHalInfo.iMemoryHandle = 0;
       
   245 	err = HAL::Get(iScreenId, HAL::EDisplayMemoryHandle, iHalInfo.iMemoryHandle);
       
   246 	test(err == KErrNone || err == KErrNotSupported);
       
   247 	test.Printf(_L("HAL::EDisplayMemoryHandle returned err %d\n"), err);
       
   248 	if (err == KErrNone)
       
   249 		{
       
   250 		// Handle is not needed so don't leak it
       
   251 		RHandleBase h;
       
   252 		h.SetHandle(iHalInfo.iMemoryHandle);
       
   253 		h.Close();
       
   254 		}
       
   255 	
       
   256 	// This is mostly for information purposes to ensure the legacy buffer is sane.
       
   257 	DBG_HAL(iScreenId, HAL::EDisplayState, iHalInfo.iState, err, 0);
       
   258 	DBG_HAL(iScreenId, HAL::EDisplayColors, iHalInfo.iColors, err, 0);
       
   259 	DBG_HAL(iScreenId, HAL::EDisplayXPixels, iHalInfo.iXPixels, err, 0);
       
   260 	DBG_HAL(iScreenId, HAL::EDisplayYPixels, iHalInfo.iYPixels, err, 0);
       
   261 	DBG_HAL(iScreenId, HAL::EDisplayXTwips, iHalInfo.iXTwips, err, 0);
       
   262 	DBG_HAL(iScreenId, HAL::EDisplayYTwips, iHalInfo.iYTwips, err, 0);	
       
   263 	DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderRGB, iHalInfo.iIsPixelOrderRGB, err, 0);
       
   264 	DBG_HAL(iScreenId, HAL::EDisplayIsPixelOrderLandscape, iHalInfo.iIsPixelOrderLandscape, err, 0);
       
   265 	
       
   266 	DBG_HAL(iScreenId, HAL::EDisplayNumModes, iHalInfo.iNumModes, err, 0);		
       
   267 	DBG_HAL(iScreenId, HAL::EDisplayMode, iHalInfo.iMode, err, 0);
       
   268 	
       
   269 	// Get info for current display mode
       
   270 	DBG_HAL(iScreenId, HAL::EDisplayIsMono, iHalInfo.iIsMono, err, iHalInfo.iMode);
       
   271 	DBG_HAL(iScreenId, HAL::EDisplayBitsPerPixel, iHalInfo.iBitsPerPixel, err, iHalInfo.iMode);
       
   272 	DBG_HAL(iScreenId, HAL::EDisplayOffsetBetweenLines, iHalInfo.iOffsetBetweenLines, err, iHalInfo.iMode);
       
   273 	DBG_HAL(iScreenId, HAL::EDisplayOffsetToFirstPixel, iHalInfo.iOffsetToFirstPixel, err, iHalInfo.iMode);
       
   274 	DBG_HAL(iScreenId, HAL::EDisplayIsPalettized, iHalInfo.iIsPalettized, err, iHalInfo.iMode);
       
   275 	}
       
   276 
       
   277 CDisplayChannelTest::CDisplayChannelTest(TInt aScreenId)
       
   278 /**
       
   279 Constructor
       
   280 @param aScreenId	the screen number to run the test on
       
   281 */
       
   282 	: CActive(EPriorityStandard), iScreenId(aScreenId)
       
   283 	{	
       
   284 	TVersion versionRequired = iDisp.VersionRequired();
       
   285 	test.Printf(_L("Opening display channel for screen %d. Test compiled against version %d.%d.%d\n"), 
       
   286 			iScreenId, versionRequired.iMajor, versionRequired.iMinor, versionRequired.iBuild);
       
   287 	TInt err = iDisp.Open(iScreenId);
       
   288 	test_KErrNone(err);
       
   289 	
       
   290 	test.Printf(_L("Successfully opened display channel for screen %d\n"), iScreenId);
       
   291 
       
   292 	// This test should be updated if a change to the driver requires a version change
       
   293 	err = iDisp.Version(iVersion);
       
   294 	if (err == KErrNotSupported)
       
   295 		{
       
   296 		test.Printf(_L("Version API not supported. Assuming v1.0.0\n"));
       
   297 		iVersion.iMajor = 1;
       
   298 		iVersion.iMinor = 0;
       
   299 		iVersion.iBuild = 0;
       
   300 		}
       
   301 	else
       
   302 		{
       
   303 		test.Printf(_L("Display channel driver version %d.%d.%d\n"), 
       
   304 				iVersion.iMajor, iVersion.iMinor, iVersion.iBuild);
       
   305 		test_KErrNone(err);
       
   306 		}
       
   307 	test(iVersion.iMajor >= 1 && iVersion.iMinor >= 0);		
       
   308 	GetHalDisplayInfo();
       
   309 	CActiveScheduler::Add(this);
       
   310 	
       
   311 	iAsyncHelper = new CAsyncHelper(iDisp);
       
   312 	test_NotNull(iAsyncHelper);
       
   313 	}
       
   314 
       
   315 CDisplayChannelTest::~CDisplayChannelTest()
       
   316 /**
       
   317 Destructor
       
   318 */
       
   319 	{
       
   320 	Deque();
       
   321 	delete iAsyncHelper;
       
   322 	iPixelFormats.Close();
       
   323 	iResolutions.Close();
       
   324 	iDisp.Close();	
       
   325 	}
       
   326 
       
   327 CDisplayChannelTest* CDisplayChannelTest::NewLC(TInt aScreenId)
       
   328 /**
       
   329 Factory method that creates a new instance of the screen
       
   330 display channel unit test object and places a pointer to this on the cleanup stack
       
   331 
       
   332 @param aScreenId	the screen number to run the test on
       
   333 @return	a pointer to the new CDisplayTest object.
       
   334 */
       
   335 	{
       
   336 	CDisplayChannelTest* self = new(ELeave) CDisplayChannelTest(aScreenId);
       
   337 	CleanupStack::PushL(self);
       
   338 	return self;
       
   339 	}
       
   340 
       
   341 void CDisplayChannelTest::CheckDisplayInfo()
       
   342 /**
       
   343 Check the values returned by CheckDisplayInfo
       
   344 */
       
   345 	{
       
   346 	test.Next(_L("Test GetDisplayInfo"));
       
   347 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
       
   348 
       
   349 	test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
       
   350 
       
   351 	test_Compare(infoPkg().iBitsPerPixel, >=, 1);
       
   352 	test_Compare(infoPkg().iAvailableRotations, !=, 0);
       
   353 
       
   354 	// check for invalid rotations i.e. those not defined by TRotation
       
   355 	test((infoPkg().iAvailableRotations & 0xFFF0) == 0);
       
   356 
       
   357 	// Check that the refresh rate field isn't garbage
       
   358 	test_Compare(infoPkg().iRefreshRateHz, >=, 1);
       
   359 	test_Compare(infoPkg().iRefreshRateHz, <=, KMaxExpectedRefreshRate);
       
   360 
       
   361 	// Should always be at least one composition buffer
       
   362 	test_Compare(infoPkg().iNumCompositionBuffers, >=, 1);
       
   363 	}
       
   364 
       
   365 void CDisplayChannelTest::CheckResolutions()
       
   366 /**
       
   367  Validate that the APIs to get / set resolutions.
       
   368 
       
   369  Tests<br>
       
   370  NumberOfResolutions, GetResolutions, GetResolution, GetRotation
       
   371  */
       
   372 	{
       
   373 	test.Next(_L("Test NumberOfResolutions, GetResolutions, GetResolution, GetRotation"));
       
   374 
       
   375 	// Get and reserve space for expected number of resolutions
       
   376 	TInt n = iDisp.NumberOfResolutions();
       
   377 	test_Compare(n, >=, 1);
       
   378 	
       
   379 	iResolutions.Reset();
       
   380 	test_KErrNone(iResolutions.Reserve(n));
       
   381 	for (TInt i = 0; i < n; ++i)
       
   382 		{
       
   383 		test_KErrNone(iResolutions.Append(RDisplayChannel::TResolution(TSize(0,0), TSize(0,0), 0)));
       
   384 		}
       
   385 	
       
   386 	// Retrieve the resolutions and make sure the number of resolutions returned matches the 
       
   387 	// expected number. It is assumed that the display state won't be changed during the execution
       
   388 	// of this test.
       
   389 	TInt actualResolutions = 0;	
       
   390 	TPtr8 resPtr(reinterpret_cast<TUint8*>(&iResolutions[0]), 
       
   391 			sizeof(RDisplayChannel::TResolution) * n, sizeof(RDisplayChannel::TResolution) * n);
       
   392 	test_KErrNone(iDisp.GetResolutions(resPtr, actualResolutions));
       
   393 	test_Equal(n, actualResolutions);	
       
   394 
       
   395 	test.Printf(_L("Supported resolutions"));
       
   396 	for (TInt res = 0; res < n; ++res)
       
   397 		{
       
   398 		RDisplayChannel::TResolution& r = iResolutions[res];
       
   399 		test.Printf(_L("pixelX = %d heightX = %d twipsX = %d twipsY = %d flags = 0x%08x\n"), 
       
   400 				r.iPixelSize.iWidth, r.iPixelSize.iHeight, r.iTwipsSize.iWidth, r.iTwipsSize.iHeight, r.iFlags);		
       
   401 		
       
   402 		// If either pixel height or pixel width is zero then both must be zero
       
   403 		// If either pixel height or pixel width is non-zero then both must be positive
       
   404 		test((r.iPixelSize.iHeight == 0 && r.iPixelSize.iWidth == 0) ||
       
   405 			 (r.iPixelSize.iHeight > 0 && r.iPixelSize.iWidth > 0));
       
   406 
       
   407 		// Test resolutions are sane
       
   408 		test(r.iPixelSize.iHeight <= KMaxExpectedPixelRes && r.iPixelSize.iWidth <= KMaxExpectedPixelRes);
       
   409 
       
   410 		// If either twips height or pixel width is zero then both must be zero
       
   411 		// If either twips height or pixel width is non-zero then both must be positive
       
   412 		test((r.iTwipsSize.iHeight == 0 && r.iTwipsSize.iWidth == 0) ||
       
   413 			 (r.iTwipsSize.iHeight > 0 && r.iTwipsSize.iWidth > 0));
       
   414 		
       
   415 		// twips resolution can be zero iff pixel resolution is also zero
       
   416 		test((r.iPixelSize.iHeight == 0 && r.iTwipsSize.iHeight == 0) ||
       
   417 			 (r.iPixelSize.iHeight > 0  && r.iTwipsSize.iHeight > 0));
       
   418 
       
   419 		// At least one rotation must be supported. Ignore other bits in the flags field
       
   420 		test(r.iFlags & RDisplayChannel::ERotationAll != 0);
       
   421 		}
       
   422 
       
   423 	// Get current resolution in pixels
       
   424 	TSize currentResolution;
       
   425 	test_KErrNone(iDisp.GetResolution(currentResolution));
       
   426 
       
   427 	// Get current resolution in twips
       
   428 	TSize currentTwips;
       
   429 	test_KErrNone(iDisp.GetTwips(currentTwips));
       
   430 
       
   431 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
       
   432 	test(IsValidRotation(currentRotation));
       
   433 
       
   434 	// The current resolution and rotation must be in the list of supported resolutions
       
   435 	TBool foundCurrentRes = EFalse;
       
   436 	for (TInt j = iResolutions.Count() - 1; j >= 0; --j)
       
   437 		{
       
   438 		if (iResolutions[j].iPixelSize == currentResolution &&
       
   439 			iResolutions[j].iTwipsSize == currentTwips &&
       
   440 			iResolutions[j].iFlags & currentRotation)
       
   441 			{
       
   442 			foundCurrentRes = ETrue;
       
   443 			break;
       
   444 			}
       
   445 		}
       
   446 	test(foundCurrentRes);
       
   447 	
       
   448 	// Now and try every supported resolution
       
   449 	TInt err;
       
   450 	for (TInt k = iResolutions.Count() - 1; k >= 0; --k)
       
   451 		{
       
   452 		err = iDisp.SetResolution(iResolutions[k].iPixelSize);
       
   453 		test(err == KErrNone || err == KErrNotSupported);
       
   454 		}
       
   455 	// attempt to set back to original resolution, this could fail
       
   456 	err = iDisp.SetResolution(currentResolution);
       
   457 	test(err == KErrNone || err == KErrNotSupported);
       
   458 	}
       
   459 
       
   460 void CDisplayChannelTest::CheckPixelFormats()
       
   461 /**
       
   462  Validates that the pixel format APIs are sane/consistent.
       
   463 
       
   464  In version 1.1 the APIs are just stubs that return KErrNotSupported
       
   465  */
       
   466 	{
       
   467 	test.Next(_L("Test NumberOfPixelFormats, GetPixelFormats"));
       
   468 
       
   469 	// At least one pixel format must be supported
       
   470 	TInt n = iDisp.NumberOfPixelFormats();
       
   471 
       
   472 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   473 		{
       
   474 		test_Compare(n, ==, KErrNotSupported);
       
   475 		n = 1; // Override return to test stub for GetPixelFormats
       
   476 		}
       
   477 	else
       
   478 		{
       
   479 		test_Compare(n, >=, 1);
       
   480 		}
       
   481 
       
   482 	TInt err = iPixelFormats.Reserve(n);
       
   483 	test_KErrNone(err);
       
   484 	for (TInt i = 0; i < n; ++i)
       
   485 		{
       
   486 		test_KErrNone(iPixelFormats.Append(-1));
       
   487 		}
       
   488 	TPtr8 pixelFormatsPtr(reinterpret_cast<TUint8*>(&iPixelFormats[0]),
       
   489 			sizeof(RDisplayChannel::TPixelFormat) * n, sizeof(RDisplayChannel::TPixelFormat) * n);		
       
   490 
       
   491 	TInt actualFormats = -1;	
       
   492 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   493 		{
       
   494 		test_Compare(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats), ==, KErrNotSupported);
       
   495 		}
       
   496 	else
       
   497 		{		
       
   498 		test_KErrNone(iDisp.GetPixelFormats(pixelFormatsPtr, actualFormats));
       
   499 		
       
   500 		// The number of formats shouldn't have changed whilst this test is running
       
   501 		test_Equal(n, actualFormats);			
       
   502 		RArray<RDisplayChannel::TPixelFormat> pixelFormatsArray(
       
   503 				reinterpret_cast<RDisplayChannel::TPixelFormat*>(&pixelFormatsPtr[0]), actualFormats);
       
   504 		
       
   505 		// Check the pixel formats returned are all valid
       
   506 		for (TInt pf = pixelFormatsArray.Count() - 1; pf >= 0; --pf)
       
   507 			{
       
   508 			IsValidPixelFormat(pixelFormatsArray[pf]);
       
   509 			}		
       
   510 		}
       
   511 	}
       
   512 
       
   513 void CDisplayChannelTest::CheckDisplayChange()
       
   514 /**
       
   515  Register for display change notification then immediately cancel.
       
   516  */
       
   517 	{
       
   518 	test.Next(_L("Test NotifyOnDisplayChange, NotifyOnDisplayChangeCancel"));
       
   519 	// Cancel should be allowed even if NotifyOnyDisplayChange has not been called
       
   520 	iDisp.NotifyOnDisplayChangeCancel();
       
   521 
       
   522 	iDisp.NotifyOnDisplayChange(iAsyncHelper->Status());
       
   523 	iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
       
   524 	}
       
   525 
       
   526 void CDisplayChannelTest::DrawFillToMemory(
       
   527 		TUint8* aFirstPixelAddr, 
       
   528 		TInt aOffsetBetweenLines, 
       
   529 		RDisplayChannel::TPixelFormat aPixelFormat, 
       
   530 		TInt aWidth, 
       
   531 		TInt aHeight, 
       
   532 		TInt aStep)
       
   533 /** 
       
   534  Draws a shaded fill to a memory region
       
   535  @param	aFirstPixelAddr			the address of the first pixel in the buffer.
       
   536  @param	aOffsetBetweenLines		offset between pixels at the start of each line
       
   537  @param aBpp					bits per pixel
       
   538  @param	aWidth					width of the region in pixels
       
   539  @param aHeight					height of the region in pixels
       
   540  @aStep	aStep					integer >= 1 to vary the pattern by test number 
       
   541  */	{
       
   542 	test.Printf(_L("DrawFileToMemory\npixelformat = 0x%08x offsetbetweenlines = %d pixel address = 0x%08x width=%d height = %d\n"), 
       
   543 			aPixelFormat, aOffsetBetweenLines, aFirstPixelAddr, aWidth, aHeight);	
       
   544 
       
   545 
       
   546 	TInt xShadeMax = 0xFF;
       
   547 	TInt yShadeMax = 0xFF;
       
   548 	
       
   549 	if (aPixelFormat == EUidPixelFormatRGB_565)
       
   550 		{
       
   551 		xShadeMax = 0x3F;	// 6 bits for green
       
   552 		yShadeMax = 0x1F;
       
   553 		}
       
   554 	else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
       
   555 		{
       
   556 		xShadeMax = 0x0F;
       
   557 		yShadeMax = 0x0F;
       
   558 		}
       
   559 	
       
   560 	aStep = Max(1, aStep);
       
   561 	TUint8* lineAddr = aFirstPixelAddr;
       
   562 	for (TInt y = 0; y < aHeight; ++y)
       
   563 		{
       
   564 		TInt yShade = (y * yShadeMax) / aHeight;
       
   565 		TUint8* pixelAddr = lineAddr;
       
   566 		for (TInt x = 0; x < aWidth; ++x)
       
   567 			{
       
   568 			TInt xShade = (x * xShadeMax) / aWidth;			
       
   569 			TUint8 red = 0;
       
   570 			TUint8 green = 0;
       
   571 			TUint8 blue = 0;
       
   572 			
       
   573 			if ( aStep == 0 || y > aStep * 10)
       
   574 				{
       
   575 				// Green top left, blue bottom right
       
   576 				green = static_cast<TUint8>(xShadeMax - xShade);
       
   577 				blue = static_cast<TUint8>(yShade);
       
   578 				}							
       
   579 			else
       
   580 				{
       
   581 				// The size of the red band indicates different test steps			
       
   582 				red = static_cast<TUint8>((yShadeMax * x) / aWidth);
       
   583 				}
       
   584 			
       
   585 			if (aPixelFormat == EUidPixelFormatRGB_565)
       
   586 				{
       
   587 				*pixelAddr++ = static_cast<TUint8>(blue | (green << 5));
       
   588 				*pixelAddr++ = static_cast<TUint8>((green >> 3) | (red << 3));
       
   589 				}
       
   590 			else if (aPixelFormat == EUidPixelFormatARGB_4444 || aPixelFormat == EUidPixelFormatXRGB_4444)
       
   591 				{
       
   592 				*pixelAddr++ = static_cast<TUint8>(blue | (green << 4));
       
   593 				*pixelAddr++ = red;					
       
   594 				}
       
   595 			else if (aPixelFormat == EUidPixelFormatXRGB_8888 || aPixelFormat == EUidPixelFormatARGB_8888 
       
   596 					|| aPixelFormat == EUidPixelFormatARGB_8888)
       
   597 				{
       
   598 				*pixelAddr++ = blue;
       
   599 				*pixelAddr++ = green;
       
   600 				*pixelAddr++ = red;
       
   601 				*pixelAddr++ = 0xFF;	// unused
       
   602 				}
       
   603 			}
       
   604 		lineAddr += aOffsetBetweenLines;
       
   605 		}
       
   606 	}
       
   607 
       
   608 void CDisplayChannelTest::DrawLegacyBuffer(TInt aStep)
       
   609 	{
       
   610 	test.Printf(_L("DrawLegacyBuffer\n"));
       
   611 	TInt oldMode;
       
   612 	TInt err;
       
   613 	err = HAL::Get(iScreenId, HAL::EDisplayMode, oldMode);
       
   614 	for (TInt i = 0; i < iHalInfo.iNumModes; ++i)
       
   615 		{
       
   616 		// Attempt to set the legacy buffer to a mode supporting 32bit (RGBA or RGBX)
       
   617 		TInt modeBpp = i;
       
   618 		err = HAL::Get(iScreenId, HAL::EDisplayBitsPerPixel, modeBpp);
       
   619 				
       
   620 		test_KErrNone(err);				
       
   621 		if ((modeBpp == 24 || modeBpp == 32))
       
   622 			{
       
   623 			TInt newMode = i;
       
   624 			err = HAL::Set(iScreenId, HAL::EDisplayMode, newMode);
       
   625 			break;
       
   626 			}
       
   627 		}
       
   628 		
       
   629 	GetHalDisplayInfo();
       
   630 	err = HAL::Set(iScreenId, HAL::EDisplayMode, oldMode);
       
   631 	TUint8* firstPixelAddr = reinterpret_cast<TUint8*>(iHalInfo.iMemoryAddress + iHalInfo.iOffsetToFirstPixel);
       
   632 	TInt offsetBetweenLines = iHalInfo.iOffsetBetweenLines;
       
   633 	TInt width = iHalInfo.iXPixels;
       
   634 	TInt height = iHalInfo.iYPixels;
       
   635 	
       
   636 	if ((! iHalInfo.iIsPalettized) && iHalInfo.iIsPixelOrderRGB)
       
   637 		{		
       
   638 		DrawFillToMemory(firstPixelAddr, offsetBetweenLines,
       
   639 				EUidPixelFormatXRGB_8888, width, height, aStep);
       
   640 		}
       
   641 	}
       
   642 
       
   643 void CDisplayChannelTest::DrawCompositionBuffer(
       
   644 		RDisplayChannel::TPostCount& aPostCount,
       
   645 		RDisplayChannel::TBufferFormat aBufferFormat,
       
   646 		RDisplayChannel::TDisplayRotation aRotation, TInt aStep)
       
   647 /**
       
   648 Attempts to set the requested buffer format and rotation then draws a shaded fill 
       
   649 to the buffer returned by RDisplayChannel::GetCompositionBuffer.
       
   650 If it is not possible to set the desired buffer format then the actual buffer format
       
   651 is used.
       
   652 
       
   653 @param	aPostCount		out parameter that is set to the post count returned by PostCompositionBuffer
       
   654 @param	aBufferFormat	the buffer format to use for this test step
       
   655 @param	aRotation		the rotation to set for this test step
       
   656 @param	aStep			test step number
       
   657 */
       
   658 	{
       
   659 	test.Printf(_L("DrawCompositionBuffer\n"));
       
   660 		
       
   661 	TBool configChanged;
       
   662 	TInt err;
       
   663 	
       
   664 	RDisplayChannel::TBufferFormat actualBufferFormat(TSize(0,0),0);
       
   665 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
       
   666 		{
       
   667 		// It should be possible to set the rotation and the buffer format in either order.
       
   668 		// To test this the order is swapped every test step
       
   669 		if (aStep % 2 == 0)
       
   670 			{
       
   671 			test_KErrNone(iDisp.SetRotation(aRotation, configChanged));
       
   672 			err = iDisp.SetBufferFormat(aBufferFormat);
       
   673 			}
       
   674 		else
       
   675 			{
       
   676 			err = iDisp.SetBufferFormat(aBufferFormat);		
       
   677 			test_KErrNone(iDisp.SetRotation(aRotation, configChanged));		
       
   678 			}
       
   679 		if (err != KErrNone)
       
   680 			{
       
   681 			test.Printf(_L("Unable to set buffer format 0x%08x width %d height %d"),
       
   682 					aBufferFormat.iPixelFormat, aBufferFormat.iSize.iWidth, aBufferFormat.iSize.iHeight);
       
   683 			}			
       
   684 		test_KErrNone(iDisp.GetBufferFormat(actualBufferFormat));
       
   685 		}
       
   686 	else
       
   687 		{
       
   688 		// buffer format not switched in v1.1 so test just validates post / wait for post
       
   689 		actualBufferFormat = aBufferFormat;
       
   690 		test_KErrNone(iDisp.SetRotation(aRotation, configChanged));
       
   691 		}
       
   692 	
       
   693 	// Get the composition buffer index
       
   694 	TUint bufferIndex;
       
   695 	TRequestStatus status;
       
   696 	iDisp.GetCompositionBuffer(bufferIndex, status);
       
   697 	User::WaitForRequest(status);
       
   698 	test(status == KErrNone);
       
   699 
       
   700 	// Now get access to the composition buffer
       
   701 	RChunk compChunk;
       
   702 	TInt offset = 0;
       
   703 	err = iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset);
       
   704 	test_KErrNone(err);	
       
   705 	
       
   706 	TUint8* baseAddr = compChunk.Base();
       
   707 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
       
   708 	err = iDisp.GetDisplayInfo(infoPkg);
       
   709 	test_KErrNone(err);
       
   710 	
       
   711 	test.Printf(_L("DrawCompositionBuffer::GetCompositionBufferInfo index = 0x%08x base = 0x%08x offset = 0x%08x\n"),
       
   712 			bufferIndex, baseAddr, offset);
       
   713 	
       
   714 	// Find out structure of the buffer
       
   715 	TUint8* firstPixelAddr = baseAddr + offset;	
       
   716 		
       
   717 	// Find out current display dimensions
       
   718 	TInt width;
       
   719 	TInt height;	
       
   720 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
       
   721 	test(IsValidRotation(currentRotation));
       
   722 	if (currentRotation == RDisplayChannel::ERotationNormal ||
       
   723 		currentRotation == RDisplayChannel::ERotation180)
       
   724 		{
       
   725 		width = actualBufferFormat.iSize.iWidth;
       
   726 		height = actualBufferFormat.iSize.iHeight;
       
   727 		}
       
   728 	else
       
   729 		{
       
   730 		height = actualBufferFormat.iSize.iWidth;
       
   731 		width = actualBufferFormat.iSize.iHeight;
       
   732 		}	
       
   733 	
       
   734 	TInt offsetBetweenLines;
       
   735 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
       
   736 		{
       
   737 		 offsetBetweenLines = iDisp.NextLineOffset(actualBufferFormat, 0);
       
   738 		}
       
   739 	else
       
   740 		{
       
   741 		// NextLineOffset not supported in v1.0 and displayinfo offset doesn't work on H4
       
   742 		offsetBetweenLines = 4 * width;
       
   743 		}
       
   744 	DrawFillToMemory(firstPixelAddr, offsetBetweenLines, actualBufferFormat.iPixelFormat, 
       
   745 			width, height, aStep);
       
   746 
       
   747 	err = iDisp.PostCompositionBuffer(NULL, aPostCount);
       
   748 	test_KErrNone(err);
       
   749 	User::After(KDrawWaitTime);
       
   750 	
       
   751 	compChunk.Close();
       
   752 	}
       
   753 
       
   754 void CDisplayChannelTest::CheckCompositionBuffers()
       
   755 /**
       
   756  Retrieves the current composition buffer index and checks the information about
       
   757  this buffer.
       
   758  */
       
   759 	{
       
   760 	test.Next(_L("Test GetCompositionBuffer, CancelGetCompositionBuffer, GetCompositionBufferInfo, PostLegacyBuffer"));
       
   761 
       
   762 	iDisp.CancelGetCompositionBuffer();	// Test cancel without an outstanding call
       
   763 
       
   764 	TUint bufferIndex;
       
   765 	TRequestStatus status;
       
   766 	// Get with immediate cancel
       
   767 	iDisp.GetCompositionBuffer(bufferIndex, status);
       
   768 	iDisp.CancelGetCompositionBuffer();
       
   769 	test(status == KErrNone || status == KErrCancel);
       
   770 
       
   771 	iDisp.GetCompositionBuffer(bufferIndex, status);	// Get, no cancel
       
   772 	User::WaitForRequest(status);
       
   773 	test(status == KErrNone);
       
   774 
       
   775 	RChunk compChunk;
       
   776 	TInt offset = 0;
       
   777 	test_KErrNone(iDisp.GetCompositionBufferInfo(bufferIndex, compChunk, offset));
       
   778 
       
   779 	// client must be able to read and write to the chunk
       
   780 	test(compChunk.IsReadable());
       
   781 	test(compChunk.IsWritable());
       
   782 	test_Compare(offset, >=, 0);
       
   783 
       
   784 	RDisplayChannel::TPostCount postCountA;
       
   785 	RDisplayChannel::TPostCount postCountB;
       
   786 	test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountA));
       
   787 	test_KErrNone(iDisp.PostCompositionBuffer(NULL, postCountB));
       
   788 	test_Compare(postCountB - postCountA, >=, 1);
       
   789 	
       
   790 	// Wait for first postcount value
       
   791 	iDisp.WaitForPost(postCountA, status);
       
   792 	User::WaitForRequest(status);
       
   793 	test(status == KErrNone);
       
   794 
       
   795 	// It should be possible to wait again on postCountA
       
   796 	// and this should complete immediately with KErrNone. However, there
       
   797 	// there is bug in the emulator causes this to wait forever.
       
   798 	
       
   799 	compChunk.Close();
       
   800 
       
   801 	// Legacy buffer should have been initialised by retrieval of HAL::EDisplayMemoryAddress 
       
   802 	test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCountA));
       
   803 	test_Compare(postCountA - postCountB, >=, 1);	
       
   804 	}
       
   805 
       
   806 void CDisplayChannelTest::VisualTest()
       
   807 /**
       
   808 Iterates over the arrays of pixel formats and rotations attempting to 
       
   809 draw a shaded fill to the composition buffer
       
   810 */
       
   811 	{
       
   812 	test.Next(_L("Visual test"));	
       
   813 	
       
   814 	RDisplayChannel::TPostCount postCount;	
       
   815 	if (iVisualTestFormatIndex < KNumPixelFormats)
       
   816 		{
       
   817 		RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);		
       
   818 		if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
       
   819 			{
       
   820 			// only one format supported in v1.0 so only one loop needed
       
   821 			bufferFormat.iPixelFormat = EUidPixelFormatXRGB_8888;
       
   822 			iVisualTestFormatIndex = KNumPixelFormats - 1; 	
       
   823 			TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
       
   824 			iDisp.GetDisplayInfo(infoPkg);
       
   825 			bufferFormat.iSize.iWidth = infoPkg().iNormal.iWidth;
       
   826 			bufferFormat.iSize.iHeight = infoPkg().iNormal.iHeight;
       
   827 			}
       
   828 		else
       
   829 			{			
       
   830 			test_KErrNone(iDisp.GetBufferFormat(bufferFormat));
       
   831 			bufferFormat.iPixelFormat = KPixelFormats[iVisualTestFormatIndex];			
       
   832 			}
       
   833 		DrawCompositionBuffer(postCount, bufferFormat, KRotations[iVisualTestRotationIndex], iVisualTestRotationIndex);	
       
   834 		iVisualTestRotationIndex++;
       
   835 		if (iVisualTestRotationIndex >= KNumRotations)
       
   836 			{
       
   837 			iVisualTestRotationIndex = 0;
       
   838 			iVisualTestFormatIndex++;
       
   839 			}
       
   840 		iDisp.WaitForPost(postCount, iStatus);
       
   841 		SetActive();
       
   842 		}
       
   843 	else
       
   844 		{
       
   845 		// Test drawing to the legacy buffer
       
   846 		test.Printf(_L("Drawing to legacy buffer\n"));
       
   847 		
       
   848 		TBool configChanged;
       
   849 		iDisp.SetRotation(KRotations[0], configChanged);		
       
   850 		DrawLegacyBuffer(20); // Make legacy buffer obviously different
       
   851 		test_KErrNone(iDisp.PostLegacyBuffer(NULL, postCount));
       
   852 		CompleteSelf(ETestSecondHandle);
       
   853 		User::After(KDrawWaitTime);
       
   854 		}
       
   855 	}
       
   856 
       
   857 void CDisplayChannelTest::CheckBufferFormat()
       
   858 /**
       
   859  Tests the APIs for getting and setting the buffer format.
       
   860   In version 1.1 these APIs are only stubs that return KErrNotSupported
       
   861  
       
   862  @pre CheckResolutions must have called prior to calling this method
       
   863  @pre CheckPixelFormats must have been called prior to calling this method.
       
   864  */
       
   865 	{
       
   866 	test.Next(_L("Test GetBufferFormat, SetBufferFormat, NextLineOffset, NextPlaneOffset"));
       
   867 
       
   868 	RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0), 0);
       
   869 	TInt err = iDisp.GetBufferFormat(bufferFormat);
       
   870 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   871 		{
       
   872 		test_Compare(err, ==, KErrNotSupported);
       
   873 		}
       
   874 	else
       
   875 		{
       
   876 		test(IsValidPixelFormat(bufferFormat.iPixelFormat));
       
   877 		test(bufferFormat.iSize.iHeight > 0 && bufferFormat.iSize.iHeight > 0);
       
   878 		// Check that the buffer is at least as large as the current pixel resolution
       
   879 		TSize resSize;
       
   880  		test_KErrNone(iDisp.GetResolution(resSize));
       
   881 		test(bufferFormat.iSize.iHeight >= resSize.iHeight && bufferFormat.iSize.iWidth >= resSize.iWidth);
       
   882 		}
       
   883 	
       
   884 	RDisplayChannel::TBufferFormat newBufferFormat(TSize(iHalInfo.iXPixels, iHalInfo.iYPixels), 0);
       
   885 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   886 		{
       
   887 		// API not support in 1.1
       
   888 		test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrNotSupported);
       
   889 		}
       
   890 	else
       
   891 		{
       
   892 		// Tests assumes that 32bpp XRGB888 is supported on most hardware
       
   893 		RDisplayChannel::TBufferFormat newBufferFormat(TSize(0,0), EUidPixelFormatXRGB_8888);
       
   894 		test_Compare(iDisp.SetBufferFormat(newBufferFormat), ==, KErrArgument);	// buffer must be large enough for resolution
       
   895 						
       
   896 		// Should be able to current buffer format
       
   897 		test_KErrNone(iDisp.SetBufferFormat(bufferFormat));
       
   898 		}
       
   899 
       
   900 	// Get current information and check this against new APIs that give 
       
   901 	// line and plane information for any mode.
       
   902 	TSize currentPixelRes;
       
   903 	TSize currentTwipRes;
       
   904 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
       
   905 	RDisplayChannel::TBufferFormat currentBufferFormat(TSize(0,0), 0);
       
   906 	
       
   907 	test_KErrNone(iDisp.GetResolution(currentPixelRes));
       
   908 	test_KErrNone(iDisp.GetTwips(currentTwipRes));
       
   909 	test_KErrNone(iDisp.GetBufferFormat(currentBufferFormat));
       
   910 	RDisplayChannel::TResolution res(currentPixelRes, currentTwipRes, currentRotation);
       
   911 
       
   912 	TInt planeOffset = iDisp.NextPlaneOffset(currentBufferFormat, 0);
       
   913 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   914 		{
       
   915 		test_Compare(planeOffset, ==, KErrNotSupported);
       
   916 		}
       
   917 	else
       
   918 		{
       
   919 		// Supported in v1.1
       
   920 		test_Compare(planeOffset, >=, 0);
       
   921 		
       
   922 		if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
       
   923 			{
       
   924 			// Extended API in v1.2
       
   925 			test.Printf(_L("Check that planeoffset APIs match"));
       
   926 			TInt planeOffset2 = iDisp.NextPlaneOffset(currentBufferFormat, res, currentRotation, 0);
       
   927 			test_Compare(planeOffset, ==, planeOffset2);		
       
   928 							
       
   929 			// check that invalid buffer formats are rejected
       
   930 			RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
       
   931 			badBufferFormat.iPixelFormat = -1;
       
   932 			test(iDisp.NextPlaneOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
       
   933 			}
       
   934 		}
       
   935 
       
   936 	TInt lineOffset = iDisp.NextLineOffset(currentBufferFormat, 0);	
       
   937 	if (iVersion.iMajor == 1 && iVersion.iMinor <= 1)
       
   938 		{
       
   939 		test_Compare(lineOffset, ==, KErrNotSupported);
       
   940 		}
       
   941 	else
       
   942 		{
       
   943 		test_Compare(lineOffset, >, 0);	// supported in v1.1
       
   944 		
       
   945 		if (iVersion.iMajor > 1 || iVersion.iMinor > 1)
       
   946 			{
       
   947 			// Extended API in v1.2
       
   948 			test.Printf(_L("Check that lineoffset APIs match"));
       
   949 			TInt lineOffset2 = iDisp.NextLineOffset(currentBufferFormat, res, currentRotation, 0);
       
   950 			// stride values must be the same and > 0 for any non-zero resolution and the current
       
   951 			// resolution should not be zero in size.
       
   952 			
       
   953 			test_Compare(lineOffset, ==, lineOffset2);
       
   954 			// check that invalid buffer formats are rejected
       
   955 			RDisplayChannel::TBufferFormat badBufferFormat(currentBufferFormat);
       
   956 			badBufferFormat.iPixelFormat = -1;
       
   957 			test(iDisp.NextLineOffset(badBufferFormat, res, currentRotation, 0) == KErrArgument);
       
   958 			}
       
   959 		}
       
   960 	}
       
   961 
       
   962 void CDisplayChannelTest::CheckUserBuffers()
       
   963 /**
       
   964  Test APIs that manage user composition buffers. Since this unit test doesn't
       
   965  have access to the real surfaces the tests are mostly robustness tests.
       
   966  */
       
   967 	{
       
   968 	test.Next(_L("Test WaitForPost, DeRegisterUserBuffer"));
       
   969 
       
   970 	// Cancel should not fail even if WaitForPost has not been called
       
   971 	iDisp.CancelWaitForPost();
       
   972 	
       
   973 	// Check that cancelling a non-existent post request doesn't fail
       
   974 	iDisp.CancelPostUserBuffer();
       
   975 
       
   976 	// Make sure wait immediately followed by cancel doesn't crash
       
   977 	TRequestStatus status;
       
   978 	RDisplayChannel::TPostCount postCount = 0;
       
   979     iDisp.WaitForPost(postCount, status);
       
   980     iDisp.CancelWaitForPost();
       
   981 	test(status == KErrNone || status == KErrCancel);
       
   982 
       
   983 	// De-register a non-existent buffer id
       
   984 	RDisplayChannel::TBufferId badBufferId(42);
       
   985 	TInt err = iDisp.DeregisterUserBuffer(badBufferId);
       
   986 	// emulator KErrArugment but on H4 KErrNotFound	
       
   987 	test(err == KErrArgument || err == KErrNotFound);
       
   988 
       
   989 	// Create and use a new buffer, should fail because chunk must be a SHARED chunk
       
   990 	RChunk myChunk;
       
   991 	const TInt chunkSize = 320 * 200 * 4; // actual size is not important because this should fail
       
   992 	err =  myChunk.CreateGlobal(KNullDesC, chunkSize, chunkSize, EOwnerProcess);
       
   993 	test_KErrNone(err); // Allocation should not fail under normal conditions
       
   994 	RDisplayChannel::TBufferId myBufferId;
       
   995 	err = iDisp.RegisterUserBuffer(myBufferId, myChunk, 0);
       
   996 	// emulator KErrBadHandle but on H4 KErrArgument
       
   997 	test(err == KErrBadHandle || err == KErrArgument);
       
   998 	myChunk.Close();
       
   999 
       
  1000 	// Try to post a request from a bad buffer id
       
  1001 	iDisp.PostUserBuffer(badBufferId, status, NULL, postCount);
       
  1002 	User::WaitForRequest(status);
       
  1003 	// Emulator KErrArgument H4 KErrNotFound
       
  1004 	test(status.Int() == KErrArgument || status.Int() == KErrNotFound);
       
  1005 	
       
  1006 	// Attempt to register an already existing buffer as a user buffer
       
  1007 	TUint compId;
       
  1008 	iDisp.GetCompositionBuffer(compId, status);
       
  1009 	User::WaitForRequest(status);
       
  1010 	RChunk compChunk;
       
  1011 	TInt offset;
       
  1012 	test_KErrNone(iDisp.GetCompositionBufferInfo(compId, compChunk, offset));
       
  1013 	test_KErrNone(iDisp.RegisterUserBuffer(myBufferId, compChunk, offset));
       
  1014 	err = iDisp.DeregisterUserBuffer(myBufferId);
       
  1015 	test(err == KErrNone || err == KErrInUse);
       
  1016 	compChunk.Close();
       
  1017 	}
       
  1018 
       
  1019 TBool CDisplayChannelTest::IsValidPixelFormat(RDisplayChannel::TPixelFormat aPixelFormat)
       
  1020 /**
       
  1021 Validates whether the value of aPixelFormat corresponds to a valid enum in TUidPixelFormat
       
  1022 @param	aPixelFormat	the pixel format value to test
       
  1023 @return	ETrue if aPixelFormat is valid; otherwise, EFalse is returned.
       
  1024 */
       
  1025 	{
       
  1026 	switch (aPixelFormat)
       
  1027 		{
       
  1028 		case EUidPixelFormatUnknown:
       
  1029 		case EUidPixelFormatXRGB_8888:
       
  1030 		case EUidPixelFormatBGRX_8888:
       
  1031 		case EUidPixelFormatXBGR_8888:
       
  1032 		case EUidPixelFormatBGRA_8888:
       
  1033 		case EUidPixelFormatARGB_8888:
       
  1034 		case EUidPixelFormatABGR_8888:
       
  1035 		case EUidPixelFormatARGB_8888_PRE:
       
  1036 		case EUidPixelFormatABGR_8888_PRE:
       
  1037 		case EUidPixelFormatBGRA_8888_PRE:
       
  1038 		case EUidPixelFormatARGB_2101010:
       
  1039 		case EUidPixelFormatABGR_2101010:
       
  1040 		case EUidPixelFormatBGR_888:
       
  1041 		case EUidPixelFormatRGB_888:
       
  1042 		case EUidPixelFormatRGB_565:
       
  1043 		case EUidPixelFormatBGR_565:
       
  1044 		case EUidPixelFormatARGB_1555:
       
  1045 		case EUidPixelFormatXRGB_1555:
       
  1046 		case EUidPixelFormatARGB_4444:
       
  1047 		case EUidPixelFormatARGB_8332:
       
  1048 		case EUidPixelFormatBGRX_5551:
       
  1049 		case EUidPixelFormatBGRA_5551:
       
  1050 		case EUidPixelFormatBGRA_4444:
       
  1051 		case EUidPixelFormatBGRX_4444:
       
  1052 		case EUidPixelFormatAP_88:
       
  1053 		case EUidPixelFormatXRGB_4444:
       
  1054 		case EUidPixelFormatXBGR_4444:
       
  1055 		case EUidPixelFormatRGB_332:
       
  1056 		case EUidPixelFormatA_8:
       
  1057 		case EUidPixelFormatBGR_332:
       
  1058 		case EUidPixelFormatP_8:
       
  1059 		case EUidPixelFormatP_4:
       
  1060 		case EUidPixelFormatP_2:
       
  1061 		case EUidPixelFormatP_1:
       
  1062 		case EUidPixelFormatYUV_420Interleaved:
       
  1063 		case EUidPixelFormatYUV_420Planar:
       
  1064 		case EUidPixelFormatYUV_420PlanarReversed:
       
  1065 		case EUidPixelFormatYUV_420SemiPlanar:
       
  1066 		case EUidPixelFormatYUV_422Interleaved:
       
  1067 		case EUidPixelFormatYUV_422Planar:
       
  1068 		case EUidPixelFormatYUV_422Reversed:
       
  1069 		case EUidPixelFormatYUV_422SemiPlanar:
       
  1070 		case EUidPixelFormatYUV_422InterleavedReversed:
       
  1071 		case EUidPixelFormatYUV_422Interleaved16bit:
       
  1072 		case EUidPixelFormatYUV_444Interleaved:
       
  1073 		case EUidPixelFormatYUV_444Planar:
       
  1074 		case EUidPixelFormatL_8:
       
  1075 		case EUidPixelFormatL_4:
       
  1076 		case EUidPixelFormatL_2:
       
  1077 		case EUidPixelFormatL_1:
       
  1078 		case EUidPixelFormatSpeedTaggedJPEG:
       
  1079 		case EUidPixelFormatJPEG:
       
  1080 			return ETrue;
       
  1081 		default:
       
  1082 			return EFalse;
       
  1083 		}
       
  1084 	}
       
  1085 
       
  1086 TBool CDisplayChannelTest::IsValidRotation(RDisplayChannel::TDisplayRotation aRotation)
       
  1087 /**
       
  1088 Checks whether the supplied rotation is a valid rotation. <br>
       
  1089 N.B. Only single rotations are accepted so EFalse is returned for ERotationAll.
       
  1090 @param	aRotation	the rotation to validate
       
  1091 @return ETrue if the supplied rotation is valid; otherwise, EFalse is returned.
       
  1092 */
       
  1093 	{
       
  1094 	switch (aRotation)
       
  1095 		{
       
  1096 		case RDisplayChannel::ERotationNormal:
       
  1097 		case RDisplayChannel::ERotation90CW:
       
  1098 		case RDisplayChannel::ERotation180:
       
  1099 		case RDisplayChannel::ERotation270CW:
       
  1100 			return ETrue;
       
  1101 		default:
       
  1102 			return EFalse;
       
  1103 		}
       
  1104 	}
       
  1105 
       
  1106 void CDisplayChannelTest::CheckSetRotation(TUint aSupported, RDisplayChannel::TDisplayRotation aNewRotation)
       
  1107 /**
       
  1108 Tests the SetRotation API attempting to set the requested resolution. If the resolution is supported
       
  1109 then SetRotation should succeed and the CurrentRotation should change. Otherwise, SetResolution should
       
  1110 fail and the current rotation should be unchanged.
       
  1111 
       
  1112 @param	aSupported		The set of supported resolutions for TDisplayInfo
       
  1113 @param	aNewRotation	The new rotation to set
       
  1114 */
       
  1115 	{
       
  1116 	RDisplayChannel::TDisplayRotation currentRotation = iDisp.CurrentRotation();
       
  1117 	test(IsValidRotation(currentRotation));
       
  1118 
       
  1119 	TBool displayConfigChanged = EFalse;
       
  1120 	TInt err = iDisp.SetRotation(aNewRotation, displayConfigChanged);
       
  1121 	TInt expectedErr = KErrNone;
       
  1122 	if (! IsValidRotation(aNewRotation))
       
  1123 		{
       
  1124 		expectedErr = KErrArgument;
       
  1125 		}
       
  1126 	else if ((aSupported & aNewRotation) == 0)
       
  1127 		{
       
  1128 		expectedErr = KErrNotSupported;
       
  1129 		}
       
  1130 	test(err == expectedErr);
       
  1131 
       
  1132 	// Check whether the rotation should / shouldn't have changed
       
  1133 	test (iDisp.CurrentRotation() == (err == KErrNone ? aNewRotation : currentRotation));
       
  1134 	}
       
  1135 
       
  1136 void CDisplayChannelTest::CheckRotations()
       
  1137 /**
       
  1138 Tests the SetRotation and GetRotation APIs by attempting to set each valid rotation
       
  1139 plus some invalid rotation values.
       
  1140 If a rotation is valid but not supported then KErrNotSupported should be returned.
       
  1141 */
       
  1142 	{
       
  1143 	test.Next(_L("Test CurrentRotation, SetRotation"));
       
  1144 
       
  1145 	// Find out supported resolutions
       
  1146 	TPckgBuf<RDisplayChannel::TDisplayInfo> infoPkg;
       
  1147 	test_KErrNone(iDisp.GetDisplayInfo(infoPkg));
       
  1148 
       
  1149 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
       
  1150 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation90CW);
       
  1151 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation180);
       
  1152 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotation270CW);
       
  1153 	CheckSetRotation(infoPkg().iAvailableRotations, RDisplayChannel::ERotationNormal);
       
  1154 	CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(-1));
       
  1155 	CheckSetRotation(infoPkg().iAvailableRotations, static_cast<RDisplayChannel::TDisplayRotation>(0));
       
  1156 	}
       
  1157 
       
  1158 void CDisplayChannelTest::CheckV11inV10()
       
  1159 /**
       
  1160 The purpose of this test is to verify that v1.0 of the display channel driver
       
  1161 returns KErrNotSupported for methods that only exist in newer versions as opposed
       
  1162 to panicking.
       
  1163 To run this test for real t_display needs to be built against v1.1 and then copied
       
  1164 to a v1.0 environment.
       
  1165 
       
  1166 If the version number is > 1.0 then this method does nothing.
       
  1167 */
       
  1168 	{
       
  1169 	if (iVersion.iMajor > 1 || iVersion.iMinor > 0)
       
  1170 		{
       
  1171 		return;
       
  1172 		}
       
  1173 	
       
  1174 	test.Next(_L("Test check v1.1 functions fail gracefully in v1.0"));
       
  1175 
       
  1176 	// APIs should fail before evaluating parameters
       
  1177 	TInt intDummy;
       
  1178 	TInt err;
       
  1179 	TBuf8<256> buf;
       
  1180 	TSize size;
       
  1181 	
       
  1182 #ifdef __WINS__	// Unknown requests panic on H4 implementation
       
  1183 	test.Printf(_L("Testing display change APIs"));
       
  1184 	iDisp.NotifyOnDisplayChangeCancel();
       
  1185 	TRequestStatus status;	
       
  1186 	iDisp.NotifyOnDisplayChange(status);
       
  1187 	test(status == KErrNotSupported);
       
  1188 #endif	
       
  1189 
       
  1190 	err = iDisp.NumberOfResolutions();
       
  1191 	test(err == KErrNotSupported);
       
  1192 
       
  1193 	err = iDisp.GetResolutions(buf, intDummy);
       
  1194 	test(err == KErrNotSupported);
       
  1195 
       
  1196 	err = iDisp.GetResolution(size);
       
  1197 	test(err == KErrNotSupported);
       
  1198 
       
  1199 	err = iDisp.GetTwips(size);
       
  1200 	test(err == KErrNotSupported);
       
  1201 
       
  1202 	err = iDisp.NumberOfPixelFormats();
       
  1203 	test(err == KErrNotSupported);
       
  1204 
       
  1205 	err = iDisp.GetPixelFormats(buf, intDummy);
       
  1206 	test(err == KErrNotSupported);
       
  1207 
       
  1208 	RDisplayChannel::TBufferFormat bufferFormat(TSize(0,0),0);
       
  1209 	err = iDisp.GetBufferFormat(bufferFormat);
       
  1210 	test(err == KErrNotSupported);
       
  1211 	
       
  1212 	err = iDisp.SetBufferFormat(bufferFormat);
       
  1213 	test(err == KErrNotSupported);
       
  1214 
       
  1215 	err = iDisp.NextPlaneOffset(bufferFormat, 0);
       
  1216 	test(err == KErrNotSupported);
       
  1217 
       
  1218 	err = iDisp.NextLineOffset(bufferFormat, 0);
       
  1219 	test(err == KErrNotSupported);
       
  1220 	}
       
  1221 
       
  1222 void CDisplayChannelTest::CheckSecondHandle()
       
  1223 /**
       
  1224 Opens a second RDisplayChannel. 
       
  1225 The driver may not support this but must not crash. 
       
  1226 */
       
  1227 	{
       
  1228 	test.Next(_L("Open a second handle\n"));
       
  1229 #ifdef	__WINS__	
       
  1230 	// This crashes on H4
       
  1231 	RDisplayChannel disp2;
       
  1232 	TInt err = disp2.Open(iScreenId);
       
  1233 	test_KErrNone(err);
       
  1234 	disp2.Close();
       
  1235 #endif
       
  1236 	}
       
  1237 
       
  1238 void CDisplayChannelTest::Start()
       
  1239 /**
       
  1240  Run all of the test cases
       
  1241  */
       
  1242 	{
       
  1243 	CompleteSelf(ETestDisplayInfo);
       
  1244 	}
       
  1245 
       
  1246 void CDisplayChannelTest::CompleteSelf(TTestState aNextState)
       
  1247 /*
       
  1248 Advances to the next test state for test steps that don't invoke
       
  1249 asynchronous requests on this AO. 
       
  1250 */
       
  1251 	{	
       
  1252 	iState = aNextState;
       
  1253 	TRequestStatus* status = &iStatus;	
       
  1254 	SetActive();
       
  1255 	User::RequestComplete(status, KErrNone);
       
  1256 	}
       
  1257 
       
  1258 void CDisplayChannelTest::DoCancel()
       
  1259 	{	
       
  1260 	iAsyncHelper->Cancel();
       
  1261 	}
       
  1262 
       
  1263 TInt CDisplayChannelTest::RunError(TInt aError)
       
  1264 	{
       
  1265 	test_KErrNone(aError);
       
  1266 	return KErrNone;
       
  1267 	}
       
  1268 
       
  1269 void CDisplayChannelTest::RunL()
       
  1270 /**
       
  1271  Run all of the tests where the API is defined for that version.
       
  1272  */
       
  1273 	{
       
  1274 	test_KErrNone(iStatus.Int());
       
  1275 	
       
  1276 	test.Printf(_L("Test state %d"), iState);
       
  1277 	switch (iState)
       
  1278 		{
       
  1279 		case ETestDisplayInfo:
       
  1280 			CheckDisplayInfo();
       
  1281 			CompleteSelf(ETestCompositionBuffers);
       
  1282 			break;
       
  1283 		case ETestCompositionBuffers:
       
  1284 			CheckCompositionBuffers();
       
  1285 			CompleteSelf(ETestUserBuffers);
       
  1286 			break;
       
  1287 		case ETestUserBuffers:
       
  1288 			CheckUserBuffers();
       
  1289 			CompleteSelf(ETestRotations);
       
  1290 			break;
       
  1291 		case ETestRotations:
       
  1292 			CheckRotations();			
       
  1293 			CompleteSelf(ETestWaitForPostDoCancel);				
       
  1294 			break;
       
  1295 		case ETestWaitForPostDoCancel:
       
  1296 			// Post the composition buffer, register wait and cancel wait.
       
  1297 			iDisp.PostCompositionBuffer(NULL, iDummyPostCount);
       
  1298 			iDisp.WaitForPost(iDummyPostCount, iAsyncHelper->Status());
       
  1299 			iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
       
  1300 			iDisp.CancelWaitForPost();
       
  1301 			CompleteSelf(ETestWaitForPostCheckCancel);
       
  1302 			break;
       
  1303 		case ETestWaitForPostCheckCancel:
       
  1304 			test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
       
  1305 			CompleteSelf(ETestGetCompositionBufferDoCancel);
       
  1306 			break;
       
  1307 		case ETestGetCompositionBufferDoCancel:
       
  1308 			iDisp.GetCompositionBuffer(iDummyCompositionBuffer, iAsyncHelper->Status());
       
  1309 			iAsyncHelper->WaitForOperation(&iAsyncHelperResult);
       
  1310 			iDisp.CancelGetCompositionBuffer();
       
  1311 			CompleteSelf(ETestGetCompositionBufferCheckCancel);
       
  1312 			break;
       
  1313 		case ETestGetCompositionBufferCheckCancel:
       
  1314 			test(iAsyncHelperResult == KErrCancel || iAsyncHelperResult == KErrNone);
       
  1315 			
       
  1316 			if (iVersion.iMajor == 1 && iVersion.iMinor == 0)
       
  1317 				{
       
  1318 				CompleteSelf(ETestV11inV10);
       
  1319 				}
       
  1320 			else
       
  1321 				{
       
  1322 				CompleteSelf(ETestDisplayChange);
       
  1323 				}
       
  1324 			break;
       
  1325 		case ETestDisplayChange:	// API in v1.1 +
       
  1326 			CheckDisplayChange();
       
  1327 			CompleteSelf(ETestDisplayChangeDoCancel);
       
  1328 			break;			
       
  1329 		case ETestDisplayChangeDoCancel:	// API in v1.1 +
       
  1330 			iDisp.NotifyOnDisplayChangeCancel();
       
  1331 			CompleteSelf(ETestDisplayChangeCheckCancel);
       
  1332 			break;
       
  1333 		case ETestDisplayChangeCheckCancel:	// API in v1.1 +
       
  1334 			test(iAsyncHelperResult == KErrCancel);	// display should not have changed
       
  1335 			CompleteSelf(ETestResolutions);
       
  1336 			break;
       
  1337 		case ETestResolutions:	// API in v1.1 +
       
  1338 			CheckResolutions();
       
  1339 			CompleteSelf(ETestPixelFormats);
       
  1340 			break;
       
  1341 		case ETestPixelFormats:	// API in v1.1 +
       
  1342 			CheckPixelFormats();
       
  1343 			CompleteSelf(ETestBufferFormats);
       
  1344 			break;
       
  1345 		case ETestBufferFormats:	// API in v1.1 +
       
  1346 			CheckBufferFormat();
       
  1347 			CompleteSelf(EVisualTest);
       
  1348 			break;
       
  1349 		case ETestV11inV10:			
       
  1350 			CheckV11inV10();
       
  1351 			CompleteSelf(EVisualTest);
       
  1352 			break;
       
  1353 		case EVisualTest:
       
  1354 			VisualTest();	// visual test is async because of WaitForPost
       
  1355 			break;
       
  1356 		case ETestSecondHandle:
       
  1357 			CheckSecondHandle();
       
  1358 			CompleteSelf(ETestFinished);
       
  1359 		case ETestFinished:
       
  1360 			CActiveScheduler::Stop();
       
  1361 			break;
       
  1362 		default:
       
  1363 			test(EFalse);		
       
  1364 		}
       
  1365 	}
       
  1366 
       
  1367 void MainL()
       
  1368 /**
       
  1369  Initialise RTest and run the tests
       
  1370  */
       
  1371 	{
       
  1372 	test.Start(_L("Testing display channel driver"));
       
  1373 	
       
  1374 	// If the device driver does not exist then this is considered a pass
       
  1375 	// because the display channel is not a mandatory part of the base port
       
  1376 	_LIT(KLdd, "display0.ldd");
       
  1377 	test.Printf(_L("Loading logical %S\n"), &KLdd);
       
  1378 	TInt err = User::LoadLogicalDevice(KLdd);	
       
  1379 	test(err == KErrNone || err == KErrAlreadyExists || err == KErrNotFound);		
       
  1380 	
       
  1381 	if (err == KErrNone || err == KErrAlreadyExists)
       
  1382 		{
       
  1383 		TInt numberOfScreens;
       
  1384 		User::LeaveIfError(HAL::Get(HAL::EDisplayNumberOfScreens, numberOfScreens));
       
  1385 		for (TInt screenNum  = 0; screenNum < numberOfScreens; ++screenNum)
       
  1386 			{
       
  1387 			CActiveScheduler* s = new(ELeave) CActiveScheduler();
       
  1388 			CActiveScheduler::Install(s);
       
  1389 			CleanupStack::PushL(s);
       
  1390 			CDisplayChannelTest* displayTest = CDisplayChannelTest::NewLC(screenNum);
       
  1391 			displayTest->Start();
       
  1392 			s->Start();
       
  1393 			CleanupStack::PopAndDestroy(2, s);	// s, displayTest 
       
  1394 			}
       
  1395 		}
       
  1396 	else
       
  1397 		{
       
  1398 		test.Printf(_L("display0.ldd not present. Finishing test."));
       
  1399 		}
       
  1400 	
       
  1401 	test.End();
       
  1402 	}
       
  1403 
       
  1404 TInt E32Main()
       
  1405 /**
       
  1406  Create cleanup stack, initialise memory checks and run the tests.
       
  1407  */
       
  1408 	{
       
  1409 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
  1410 	if (!cleanup)
       
  1411 		{
       
  1412 		return KErrNoMemory;
       
  1413 		}
       
  1414 	__UHEAP_MARK;
       
  1415 	test.Title();
       
  1416 	TRAPD(err, MainL());
       
  1417 	test.Close();
       
  1418 	__UHEAP_MARKEND;
       
  1419 	delete cleanup;
       
  1420 	return err;
       
  1421 	}