diff -r 000000000000 -r 5d03bc08d59c windowing/windowserver/tauto/TWSGRAPHS.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/tauto/TWSGRAPHS.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,2593 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// This test step contains a series of tests cases to validate the correct behaviour of PREQ1246 implementation. +// In order to create these test cases, basic implementations of the objects involved in this PREQ will be created, +// .i.e. CWsGraphic-derived objects (generically named CWsGraphicTest) and CWsGraphicDrawer-derived objects +// (generically named CWsGraphicDrawerTest). +// Actual construction is performed by a UI-specific entity such as a theme manager. The test code shall replace +// that theme manager functionality, in terms of being the test code who owns a collection of CWsGraphicTest +// objects. +// +// + +/** + @file + @test + @internalComponent - Internal Symbian test code +*/ + +#include "TWSGRAPHS.H" +#include "../inc/WSGRAPHICDRAWERARRAY.H" +#include "../../nga/graphicdrawer/panics.h" +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA +#include "wsbufferdrawer.h" +#endif + +_LIT(KTestExe, "TWSGRAPHICTEST.exe"); +_LIT(KSpace, " "); + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA +const TInt KCustomTextCursorId = TTextCursor::ETypeLastBasic + 57; // 57 is arbitrary +#endif + +CCrWin* CCrWin::NewL(TInt aScreenId, TBool aDraw) + { + CCrWin* win = new(ELeave) CCrWin; + CleanupStack::PushL(win); + win->ConstructL(aScreenId, aDraw); + CleanupStack::Pop(win); + return win; + } + +CCrWin::~CCrWin() + { + iWin.Close(); + iGroup.Close(); + delete iGc; + delete iScr; + iWs.Close(); + } + +void CCrWin::ConstructL(TInt aScreenId, TBool aDraw) + { + User::LeaveIfError(iWs.Connect()); + iScr = new(ELeave) CWsScreenDevice(iWs); + User::LeaveIfError(iScr->Construct(aScreenId)); + User::LeaveIfError(iScr->CreateContext(iGc)); + iGroup = RWindowGroup(iWs); + User::LeaveIfError(iGroup.Construct(0xbadbabe,ETrue)); + iGroup.SetOrdinalPosition(0,100); + iWin = RWindow(iWs); + User::LeaveIfError(iWin.Construct(iGroup,0xbadcafe)); + iWin.SetRequiredDisplayMode(EColor64K); + iWin.Activate(); + iWs.Flush(); + if (aDraw) + Draw(); + } + +void CCrWin::Draw() + { + iWin.BeginRedraw(); + iGc->Activate(iWin); + iGc->SetBrushColor(KRgbRed); + iGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + TRect rect(iScr->SizeInPixels()); + iGc->DrawRect(rect); + iGc->SetBrushColor(KRgbBlue); + iGc->DrawEllipse(TRect(rect.iTl.iX,rect.iTl.iY,rect.iBr.iX/2,rect.iBr.iY)); + iGc->DrawEllipse(TRect(rect.iBr.iX/2,rect.iTl.iY,rect.iBr.iX,rect.iBr.iY)); + iGc->Deactivate(); + iWin.EndRedraw(); + iWs.Flush(); + } + + +void CCrWin::DrawFirstHalf() + { + iWin.BeginRedraw(); + iGc->Activate(iWin); + iGc->SetBrushColor(KRgbRed); + iGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + TRect rect(TPoint(0,0),TSize(iScr->SizeInPixels().iWidth/2,iScr->SizeInPixels().iHeight)); + iGc->DrawRect(rect); + iWs.Flush(); + } + +void CCrWin::DrawSecondHalf() + { + TRect rect(TPoint(iScr->SizeInPixels().iWidth/2,0),TSize(iScr->SizeInPixels().iWidth/2,iScr->SizeInPixels().iHeight)); + iGc->DrawRect(rect); + iGc->Deactivate(); + iWin.EndRedraw(); + iWs.Flush(); + } + +/** +The objective of this function is, two animations should run independently +with respective frame rate in the given time interval. +The time delay allows to draw animations freely and the plug-in +calculates number of times DoDraw() function called during this interval. + +@param TInt Wsgrphic test plug-in id. +*/ +void CCrWin::DrawGraphic(TInt aWsId) + { + // draw the animation in two positions + const TSize screenSize = iScr->SizeInPixels(); + const TRect position(0,0,screenSize.iWidth/2,screenSize.iHeight); + const TRect position2((screenSize.iWidth/2)+1,0,screenSize.iWidth,screenSize.iHeight); + //PeterI if CWsGraphic animation areas overlap then when one redraws the other will as well. + //2 separate positions are needed otherwise the framerates will be identical. + + iWin.BeginRedraw(); + iGc->Activate(iWin); + const TUint8 animid1=0; + const TUint8 fps1=20; + TBuf8<2> animData1; + animData1.Append(animid1); //animId1 + animData1.Append(fps1); //20fps + iGc->DrawWsGraphic(aWsId,position,animData1); + iWs.Flush(); + User::After(200000); + const TUint8 animid2=1; + const TUint8 fps2=60; + TBuf8<2> animData2; + animData2.Append(animid2); //animId2 + animData2.Append(fps2); //60fps + iGc->DrawWsGraphic(aWsId,position2,animData2); + iWs.Flush(); + User::After(200000); + iGc->Deactivate(); + iWin.EndRedraw(); + iWs.Flush(); + } + +/** + * Set a standard text cursor on this window. + * @see RWindowGroup::SetTextCursor() + */ +void CCrWin::SetTextCursor(const TPoint &aPos, const TTextCursor &aCursor) + { + iGroup.SetTextCursor(iWin, aPos, aCursor); + } + +/** + * Cancel a text cursor from this window. + * @see RWindowGroup::CancelTextCursor() + */ +void CCrWin::CancelTextCursor() + { + iGroup.CancelTextCursor(); + } + +CCrAlphaWin* CCrAlphaWin::NewL(TInt aScreenId) + { + CCrAlphaWin* win = new(ELeave) CCrAlphaWin; + CleanupStack::PushL(win); + win->ConstructL(aScreenId); + CleanupStack::Pop(win); + return win; + } + +CCrAlphaWin::~CCrAlphaWin() + { + iWin.Close(); + iGroup.Close(); + delete iScr; + iWs.Close(); + } + +void CCrAlphaWin::ConstructL(TInt aScreenId) + { + User::LeaveIfError(iWs.Connect()); + iScr = new(ELeave) CWsScreenDevice(iWs); + User::LeaveIfError(iScr->Construct(aScreenId)); + iGroup = RWindowGroup(iWs); + User::LeaveIfError(iGroup.Construct(0xbadc0de,ETrue)); + iGroup.SetOrdinalPosition(0,100); + iWin = RWindow(iWs); + User::LeaveIfError(iWin.Construct(iGroup,0xbadbeef)); + iWin.SetRequiredDisplayMode(EColor64K); + iWin.SetTransparencyAlphaChannel(); + iWin.SetBackgroundColor(TRgb(0xff,0xff,0,0x80)); + iWin.Activate(); + iWs.Flush(); + } + + +// +// CTWsGraphs +// + +CTWsGraphs::CTWsGraphs(CTestStep* aStep): + CTWsGraphicsBase(aStep) + { + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA +LOCAL_D void DeleteSpriteMember(TAny* aSpriteMember) + { + TSpriteMember* member=reinterpret_cast(aSpriteMember); + delete member->iBitmap; + member->iBitmap=NULL; + delete member->iMaskBitmap; + member->iMaskBitmap=NULL; + } +#endif + +CTWsGraphs::~CTWsGraphs() + { +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + DeleteSpriteMember(&iSpriteMemberArray[0]); + iSpriteMemberArray.Close(); +#endif + delete iGdCoverage; +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + delete iAfter; + delete iBefore; + delete iBackCopy; + delete iFrontCopy; +#endif + delete iListen; + delete iNotify2; + delete iNotify1; +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + delete iRedir; +#endif + } + +void CTWsGraphs::ConstructL() + { +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + iRedir = CWsRedir::NewL(iTest->iScreenNumber,ETrue); + iRedir->SetCallBack(TCallBack(CTWsGraphs::PluginCallBack,this)); +#endif + iNotify1 = CWsNotify::NewL(EFalse); + iNotify2 = CWsNotify::NewL(ETrue); + iListen = CWsListen::NewL(ETrue); + iListen->SetCallBack(TCallBack(CTWsGraphs::PluginCallBack,this)); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + iFrontCopy = new(ELeave) CFbsBitmap; + iBackCopy = new(ELeave) CFbsBitmap; + iBefore = new(ELeave) CFbsBitmap; + User::LeaveIfError(iBefore->Create(TheClient->iScreen->SizeInPixels(), EColor64K)); + iAfter = new(ELeave) CFbsBitmap; + User::LeaveIfError(iAfter->Create(TheClient->iScreen->SizeInPixels(), EColor64K)); +#endif + iGdCoverage = CWsGdCoverage::NewL(); + iGdCoverage->SetCallBack(TCallBack(CTWsGraphs::PluginCallBack,this)); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + TSpriteMember spriteMember; + spriteMember.iBitmap = NULL; + spriteMember.iMaskBitmap = NULL; + spriteMember.iInvertMask =EFalse; + spriteMember.iDrawMode = CGraphicsContext::EDrawModePEN; + spriteMember.iOffset = TPoint(); + spriteMember.iInterval = TTimeIntervalMicroSeconds32(0); + CleanupStack::PushL(TCleanupItem(DeleteSpriteMember, &spriteMember)); + spriteMember.iBitmap = new (ELeave) CFbsBitmap; + User::LeaveIfError(spriteMember.iBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1)); + spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap; + User::LeaveIfError(spriteMember.iMaskBitmap->Load(TEST_BITMAP_NAME, EMbmWsautotestBmp1mask)); + User::LeaveIfError(iSpriteMemberArray.Append(spriteMember)); + CleanupStack::Pop(&spriteMember); +#endif + } + +void CTWsGraphs::LaunchNewProcess(const TDesC& aExecutable) + { + TBuf<128> args; + args.Append(KSpace); + args.AppendNum(iTest->iScreenNumber); + RProcess pr; + TInt err = pr.Create(aExecutable,args); + if (err == KErrNone) + { + TRequestStatus status; + pr.Logon(status); + pr.Resume(); + User::WaitForRequest(status); + err = pr.ExitReason(); + pr.Close(); + if (err != KErrNone) + { + _LIT(KLog,"%S returned error: %d. Check RDebug output."); + LOG_MESSAGE3(KLog, &aExecutable, err); + } + } + else + { + _LIT(KLog,"Can't create the process (%S), err=%d"); + LOG_MESSAGE3(KLog, &aExecutable, err); + } + TEST(err == KErrNone); + // Restore main test group to foreground. + TheClient->iGroup->GroupWin()->SetOrdinalPosition(0); + } + +TInt CTWsGraphs::PluginCallBack(TAny* /*aArg*/) + { + return (TInt)EWait; + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +/** + @SYMTestCaseID GRAPHICS-WSERV-0371 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Test interface extension + @SYMTestPriority High + @SYMTestStatus Implemented + @SYMTestActions Retrieves object interfaces from Content Rendering Plugin (plugin). + Actions step: + -Create plugin + -Query interfaces obtained from plugin side + @SYMTestExpectedResults Supported interfaces should return non null +*/ +TestState CTWsGraphs::TestInterfaceExtensionL() + { + if (iSubState==0) + { + _LIT(KTestInterfaceExtension, "TestInterfaceExtension"); + INFO_PRINTF1(KTestInterfaceExtension); + + ++iSubState; + Mem::FillZ(&iRedirInfo, sizeof(TRedirectorInfo)); + iRedir->QueryPlugin(iRedirInfo); + return EWait; + } + TEST(iRedirInfo.iScreenConfigInterface!=NULL); + TEST(iRedirInfo.iFrontBufferInterface!=NULL); + TEST(iRedirInfo.iScreenBitmapHandle!=0); + iFrontCopy->Duplicate(iRedirInfo.iScreenBitmapHandle); + + if (TransparencySupportedL()!=KErrNotSupported) + { + TEST(iRedirInfo.iBackBufferInterface!=NULL); + TEST(iRedirInfo.iFlickerBitmapHandle!=0); + iBackCopy->Duplicate(iRedirInfo.iFlickerBitmapHandle); + } + + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +void CTWsGraphs::CreateWindowL(TBool aDraw) + { + iWin = CCrWin::NewL(iTest->iScreenNumber, aDraw); + } + +void CTWsGraphs::DestroyWindowL() + { + delete iWin; + iWin = NULL; + } + +void CTWsGraphs::CreateAlphaWindowL() + { + iAlpha = CCrAlphaWin::NewL(iTest->iScreenNumber); + } + +void CTWsGraphs::DestroyAlphaWindowL() + { + delete iAlpha; + iAlpha = NULL; + } + +TBool CTWsGraphs::CompareBitmapArea16Bpp(CFbsBitmap* aBmp1, const TPoint& aPos1, CFbsBitmap* aBmp2, const TPoint& aPos2, const TSize& aSize) + { + const TDisplayMode dispmode = aBmp1->DisplayMode(); + if (dispmode!=aBmp2->DisplayMode()) + return EFalse; + const TInt stride1 = aBmp1->DataStride(); + const TInt stride2 = aBmp2->DataStride(); + const TInt linebytes = aSize.iWidth * 2; + const TInt pixelbytes = 2; + aBmp1->LockHeap(); + const TUint8* p1 = ((const TUint8*)aBmp1->DataAddress())+aPos1.iY*stride1+aPos1.iX*pixelbytes; + const TUint8* p2 = ((const TUint8*)aBmp2->DataAddress())+aPos2.iY*stride2+aPos2.iX*pixelbytes; + for (TInt y=0; yUnlockHeap(); + return EFalse; + } + } + aBmp1->UnlockHeap(); + return ETrue; + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA +TestState CTWsGraphs::TestScreenRedirectionL() + { + if (iSubState==0) + { + _LIT(KTestScreenRedirection, "TestScreenRedirection"); + INFO_PRINTF1(KTestScreenRedirection); + + ++iSubState; + /** + @SYMTestCaseID GRAPHICS-WSERV-0372 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Redirect wserv screen drawing to custom graphics context + @SYMTestPriority High + @SYMTestStatus Implemented + @SYMTestActions Redirects wserv screen drawing to bitmap context owned by plugin. + Actions step: + -Draw opaque window. + -Save screen content to a bitmap + -Instruct plugin to redirect wserv screen drawing to a bitmap device + -Draw the same window again + -Retrieve plugin bitmap and compare against the saved bitmap + @SYMTestExpectedResults Bitmap content match + */ + CreateWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iBefore); + DestroyWindowL(); + iRedir->Redirect(CWsRedir::EFrontBuffer, ETrue); + return EWait; + } + + if (iSubState==1) + { + ++iSubState; + CreateWindowL(); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iBefore->LockHeap(); + TEST(Mem::Compare((const TUint8*)iFrontCopy->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes)==0); + iBefore->UnlockHeap(); + + Mem::FillZ(&iRedirInfo, sizeof(TRedirectorInfo)); + iRedir->QueryPlugin(iRedirInfo); + return EWait; + } + + if (iSubState==2) + { + ++iSubState; + /** + @SYMTestCaseID GRAPHICS-WSERV-0047 + @SYMTestCaseDesc Screen update event + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Check plugin receive screen update event during redirection + @SYMTestExpectedResults Counter is non-zero + */ + TEST(iRedirInfo.iUpdateCounter>0); + + DestroyWindowL(); + /** + @SYMTestCaseID GRAPHICS-WSERV-0373 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Stop wserv screen drawing redirection + @SYMTestPriority High + @SYMTestStatus Implemented + @SYMTestActions Stop wserv screen drawing redirection. + Actions step: + -Instruct plugin to stop wserv screen drawing redirection + -Draw the same window again + -Save screen content to another bitmap + -Compare the saved bitmap against newly saved bitmap + @SYMTestExpectedResults Bitmap content match + */ + iRedir->Redirect(CWsRedir::EFrontBuffer, EFalse); + return EWait; + } + + if (iSubState==3) + { + ++iSubState; + CreateWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iAfter); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iAfter->LockHeap(); + TEST(Mem::Compare((const TUint8*)iAfter->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes)==0); + iAfter->UnlockHeap(); + DestroyWindowL(); + + Mem::FillZ(&iRedirInfo, sizeof(TRedirectorInfo)); + iRedir->QueryPlugin(iRedirInfo); + return EWait; + } + + /** + @SYMTestCaseID GRAPHICS-WSERV-0374 + @SYMTestCaseDesc Screen update event + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Check plugin receive no screen update event when redirection is terminated + @SYMTestExpectedResults Counter is zero + */ + TEST(iRedirInfo.iUpdateCounter==0); + + ++(iTest->iState); + iSubState = 0; + + return ENext; + } + +TestState CTWsGraphs::TestTextCursorUnderRedirectionL(TTestCursorType aCursorType) + { + /** + @SYMTestCaseID GRAPHICS-WSERV-0363 + @SYMTestCaseDesc Text Cursor when drawing redirected + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Action steps: + - Draw the text cursor in the left side of the screen + - Re-direct the Front Buffer + - Move the text cursor to the right side of the screen + - Pause 0.5 seconds because this amount of time is needed + to change from the flash ON phase to the flash OFF phase + - Stop re-directing + - See if when we exit re-direction in a different place in + the phase of the text cursor flashing, whether we get + non-text cursor drawing artefacts in the old location + where the text cursor used to be + @SYMTestExpectedResults Left side of the screen does not show a Text Cursor + */ + + ASSERT(aCursorType == ETestStandardTextCursor || aCursorType == ETestCustomTextCursor); + + // Cursor Flash Period is 1 second (comprising two phases; ON and OFF) + const TInt KCursorFlashPeriod = 1000000; + const TInt KWaitForNextFlashPhase = KCursorFlashPeriod / 2; + + // Size of the cursor; it may be either a standard or custom text cursor + TSize cursorSize = (aCursorType == ETestStandardTextCursor) ? TSize(15, 20) : TSize(80, 80); + + // Original Text Cursor position in the left part of the screen + const TPoint originalCursorPos(45, 40); + + // New Text Cursor position in the right half of the screen + const TPoint newCursorPos((TheClient->iScreen->SizeInPixels().iWidth/2) + 45, 40); + + // Clean area of the screen which never had a text cursor + const TPoint cleanReferencePos(45, 40 + 80); + + /* Initial setup to get a window with a standard flashing text cursor */ + if (iSubState == 0) + { + ++iSubState; + CreateWindowL(ETrue); + + if (aCursorType == ETestStandardTextCursor) + { + _LIT(KTestTextCursorUnderRedirection, "TestTextCursorUnderRedirection(Standard Cursor)"); + INFO_PRINTF1(KTestTextCursorUnderRedirection); + iTextCursor.iType=TTextCursor::ETypeRectangle; + iTextCursor.iHeight=cursorSize.iHeight; + iTextCursor.iAscent=0; + iTextCursor.iWidth=cursorSize.iWidth; + iTextCursor.iFlags=0; // means flash the cursor + iTextCursor.iColor=KRgbGreen; + iWin->SetTextCursor(originalCursorPos, iTextCursor); + } + else if (aCursorType == ETestCustomTextCursor) + { + _LIT(KTestTextCursorUnderRedirection, "TestTextCursorUnderRedirection(Custom Cursor)"); + INFO_PRINTF1(KTestTextCursorUnderRedirection); + + TInt err = TheClient->iWs.SetCustomTextCursor( + KCustomTextCursorId, + iSpriteMemberArray.Array(), + ESpriteFlash, + RWsSession::ECustomTextCursorAlignTop + ); + iTextCursor.iType=KCustomTextCursorId; + iTextCursor.iHeight=cursorSize.iHeight; + iTextCursor.iAscent=0; + iTextCursor.iWidth=cursorSize.iWidth; + iTextCursor.iFlags=TTextCursor::EFlagClipHorizontal; // means flash the cursor and clip the sprite + iTextCursor.iColor=KRgbCyan; + iWin->SetTextCursor(originalCursorPos, iTextCursor); + } + else + { + // unknown type of test being requested + ASSERT(0); + } + iWin->DrawFirstHalf(); + return EWait; + } + /* + * Re-direct drawing to another Front Buffer. Whilst re-directed, change the + * position of the text cursor. Then pause 0.5 seconds because this is how + * long it will take to enter the next phase in the flashing cycle. Finally + * stop re-directing. We exit the re-direction in a different point in the + * phase of the text cursor from when we entered it. + * This is key to testing for faulty behaviour. + */ + if (iSubState==1) + { + ++iSubState; + User::After(KCursorFlashPeriod * 2); // so its easy to visually review progress + iRedir->Redirect(CWsRedir::EFrontBuffer, ETrue); + iWin->SetTextCursor(newCursorPos, iTextCursor); + User::After(KWaitForNextFlashPhase); + iRedir->Redirect(CWsRedir::EFrontBuffer, EFalse); + return EWait; + } + /* + * Paint the right hand side of the screen which should now have a text cursor. + */ + if (iSubState==2) + { + ++iSubState; + iWin->DrawSecondHalf(); + return EWait; + } + /* + * Let the cursor flash a few times, as it assists manual viewing of the progress + * of the test. + */ + if (iSubState==3) + { + ++iSubState; + User::After(KCursorFlashPeriod * 3); + return EWait; + } + /* + * Check to see if the text cursor did move to the right of the screen. + */ + if (iSubState==4) + { + ++iSubState; + + /* When we do a screen comparison, we supply flag 0, which means + * don't include the text cursor. We do this because we are interested + * in screen artefacts. + */ + TEST(TheClient->iScreen->RectCompare( + TRect(originalCursorPos, cursorSize), + TRect(cleanReferencePos, cursorSize), + 0)); // must not supply CWsScreenDevice::EIncludeTextCursor + + return EWait; + } + /* Clean up */ + if (iSubState==5) + { + ++iSubState; + iWin->CancelTextCursor(); + DestroyWindowL(); + } + + iSubState = 0; + + return ENext; + } + +/** + @SYMTestCaseID GRAPHICS-WSERV-0375 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Redirect wserv flickerfree drawing to custom graphics context + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Redirect wserv flickerfree buffer drawing. + Action step: + -Draw opaque window (as background) and transparent window + -Save screen content to a bitmap + -Instruct plugin to redirect wserv flickerfree buffer drawing + -Draw the same opaque window and transparent window again + -Retrieve plugin bitmap and compare against the saved bitmap + @SYMTestExpectedResults Bitmap content match +*/ +/** + @SYMTestCaseID GRAPHICS-WSERV-0376 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Stop wserv flickerfree drawing redirection + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Stop wserv flickerfree buffer drawing redirection. + Action step: + -Instruct plugin to stop wserv filckerfree drawing redirection + -Draw the same opaque and transparent window + -Save screen content to another bitmap + -Compare saved bitmap against newly saved bitmap + @SYMTestExpectedResults Bitmap content match +*/ + +TestState CTWsGraphs::TestFlickerRedirectionL() + { + if (TransparencySupportedL()==KErrNotSupported) + { + ++(iTest->iState); + return ENext; + } + + // flush transparent window destruction created in TransparencySupportedL before + // proceeding with the test + + TheClient->iWs.Flush(); + + if (iSubState==0) + { + _LIT(KTestFlickerRedirection, "TestFlickerRedirection"); + INFO_PRINTF1(KTestFlickerRedirection); + + ++iSubState; + + CreateWindowL(); + CreateAlphaWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iBefore); + DestroyAlphaWindowL(); + DestroyWindowL(); + iRedir->Redirect(CWsRedir::EBackBuffer, ETrue); + return EWait; + } + + if (iSubState==1) + { + ++iSubState; + CreateWindowL(); + CreateAlphaWindowL(); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iBefore->LockHeap(); + TInt ret=Mem::Compare((const TUint8*)iBackCopy->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes); + TEST(ret==0); + if (ret!=0) + { + _LIT(KLog,"The memory of two bitmaps doesn't match"); + LOG_MESSAGE(KLog); + } + iBefore->UnlockHeap(); + DestroyAlphaWindowL(); + DestroyWindowL(); + iRedir->Redirect(CWsRedir::EBackBuffer, EFalse); + return EWait; + } + + CreateWindowL(); + CreateAlphaWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iAfter); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iAfter->LockHeap(); + TEST(Mem::Compare((const TUint8*)iAfter->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes)==0); + iAfter->UnlockHeap(); + DestroyAlphaWindowL(); + DestroyWindowL(); + + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +/** + @SYMTestCaseID GRAPHICS-WSERV-0377 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Enable event notification + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Enable plugin to register to event notification. + Action step: + -Instruct plugin to register event handler + -Draw fullscreen window (plugin will receive window visibility changed event) + -Query visibility region from plugin side + -Compare window visible region against value obtained by plugin + @SYMTestExpectedResults Visible region match +*/ +/** + @SYMTestCaseID GRAPHICS-WSERV-0378 + @SYMREQ GT247-CR0714 + @SYMTestCaseDesc Disable event notification + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Disable plugin to register to event notification. + Action step: + -Instruct plugin to unregister event handler + -Destroy fullscreen window (plugin will not receive window visibility changed event) + -Query visibility region from plugin side + + @SYMTestExpectedResults Plugin does not receive events notification +*/ +TestState CTWsGraphs::TestEventNotificationL() + { + if (iSubState==0) + { + _LIT(KTestEventNotification, "TestEventNotification"); + INFO_PRINTF1(KTestEventNotification); + + ++iSubState; + iListen->Enable(ETrue); + CreateWindowL(); + Mem::FillZ(&iListenInfo, sizeof(TListenerInfo)); + TheClient->iWs.Finish(); + TheClient->WaitForRedrawsToFinish(); + iListen->QueryPlugin(iListenInfo); + return EWait; + } + + if (iSubState==1) + { + ++iSubState; + iListen->Enable(EFalse); + TEST(iListenInfo.iNumRect==1); + TEST(iListenInfo.iRect==TRect(TPoint(0,0),TheClient->iScreen->SizeInPixels())); + DestroyWindowL(); + Mem::FillZ(&iListenInfo, sizeof(TListenerInfo)); + iListen->QueryPlugin(iListenInfo); + iListen->Enable(EFalse); + DestroyWindowL(); + return EWait; + } + + TEST(iListenInfo.iNumRect==0); + + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +TestState CTWsGraphs::TestRedirectionUsingWsBackBufferL() + { + if (TransparencySupportedL()==KErrNotSupported) + { + ++(iTest->iState); + return ENext; + } + + // flush transparent window destruction created in TransparencySupportedL before + // proceeding with the test + + TheClient->iWs.Flush(); + + if (iSubState==0) + { + _LIT(KTestRedirectionWsBack, "TestRedirectionUsingWsBackBuffer"); + INFO_PRINTF1(KTestRedirectionWsBack); + + ++iSubState; + + /** + @SYMTestCaseID GRAPHICS-WSERV-0379 + @SYMTestCaseDesc Redirect wserv flickerfree to MWsBackBuffer object + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions -Draw opaque window (as background) and transparent window + -Save screen content to a bitmap + -Instruct plugin to redirect flickerfree buffer to MWsBackBuffer object + -Draw the same opaque window and transparent window again + -Retrieve plugin bitmap and compare against the saved bitmap + @SYMTestExpectedResults Bitmap content match + */ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0379")); + CreateWindowL(); + CreateAlphaWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iBefore); + DestroyAlphaWindowL(); + DestroyWindowL(); + iRedir->RedirectUsingWsBackBuffer(ETrue); + return EWait; + } + + if (iSubState==1) + { + ++iSubState; + CreateWindowL(); + CreateAlphaWindowL(); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iBefore->LockHeap(); + TInt ret=Mem::Compare((const TUint8*)iBackCopy->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes); + TEST(ret==0); + if (ret!=0) + { + _LIT(KLog,"The memory of two bitmaps doesn't match"); + LOG_MESSAGE(KLog); + } + iBefore->UnlockHeap(); + DestroyAlphaWindowL(); + DestroyWindowL(); + + /** + @SYMTestCaseID GRAPHICS-WSERV-0380 + @SYMTestCaseDesc Restore wserv flickerfree redirection from MWsBackBuffer object + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions -Instruct plugin to stop wserv filckerfree drawing redirection + -Draw the same opaque and transparent window + -Save screen content to another bitmap + -Compare saved bitmap against newly saved bitmap + @SYMTestExpectedResults Bitmap content match + */ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0380")); + iRedir->RedirectUsingWsBackBuffer(EFalse); + return EWait; + } + + CreateWindowL(); + CreateAlphaWindowL(); + TheClient->iScreen->CopyScreenToBitmap(iAfter); + TSize sz = iBefore->SizeInPixels(); + TInt bytes = sz.iWidth*sz.iHeight*2; // EColor64K + iAfter->LockHeap(); + TEST(Mem::Compare((const TUint8*)iAfter->DataAddress(),bytes,(const TUint8*)iBefore->DataAddress(),bytes)==0); + iAfter->UnlockHeap(); + DestroyAlphaWindowL(); + DestroyWindowL(); +/** + @SYMTestCaseID GRAPHICS-WSERV-0527 +*/ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0527")); + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +//A call to do coverage through a plugin. +//This can serve as a basis for future coverage to objects exposed by the +//plugin. For now a single simple test is implmeneted. +TestState CTWsGraphs::TestGraphicDrawerCoverage() + { + __ASSERT_ALWAYS(iGdCoverage->RunTest(1)==KErrNone||KErrNotReady, User::Invariant()); + return ENext; + } + +//Simplified non-functional class to create a few dummy CWsGraphicDrawer instances. +//This code is intended to test the Array class, not the Drawer. +//Note that this object is not at all functional! The only guaranteed method is Id(). +//WsGraphicDrawer is declared as a friend and is actually intended to be the factory class for CWsGraphicDrawer +class WsGraphicDrawer:public CWsGraphicDrawer + { +public: + WsGraphicDrawer() + { + } + //stub for virtual construction. Most members are ignored + virtual void ConstructL(MWsGraphicDrawerEnvironment& ,const TGraphicDrawerId& id,MWsClient& ,const TDesC8& ) + { + ConstructL(id); + } + //simplified custom construction + void ConstructL(const TGraphicDrawerId& id) + { + MWsGraphicDrawerEnvironment* nullEnv=NULL; + MWsGraphicDrawerEnvironment& aEnv=*nullEnv; + MWsClient* nullClient=NULL; + MWsClient& aOwner=*nullClient; + this->BaseConstructL(aEnv,id,aOwner); + this->iDtor_ID_Key=TUid::Null(); + + } + //stubs for pure virtual methods + virtual void HandleMessage(const TDesC8& ) + {} + virtual void DoDraw(MWsGc& ,const TRect& ,const TDesC8& ) const + {} + + }; +//Class to allow me to pre-allocate the CWsGraphicDrawerArray so it doesn't pop up a false-positive memory allocation! +class DummyCleanup:public TCleanupItem + { +public: + static void CleanUp(TAny*) {} + DummyCleanup(): TCleanupItem(CleanUp,this) {} + operator DummyCleanup*() { return this; } + + }; + +//Helper function to explain test fails. Most other tests are against KErrNone +void CTWsGraphs::ReportNegativeResultfail(TInt aLine,TInt aResult,TInt aExpectedResult) + { + testBooleanTrue((aResult==aExpectedResult), (TText8*)__FILE__, aLine); + if (aResult!=aExpectedResult) + { + INFO_PRINTF3(_L("Expected return code %i, got %i"),aExpectedResult,aResult); + } + + } + +//This is an attempt to use wserv test's pre-existing Panic handler to perform some negative tests. +//At present this handler appears to be broken: +// 1) It doesn't write to the correct html log file +// 2) It no longer writes to the WSERV.LOG file it was writing to a few versions ago +// 3) It doesn't close the panic window so subsequent tests that check the display output fail. +//That was a waste of effort. +struct CTWsGraphs::WrapTestCall + { + CTWsGraphs* thisThis; + TUint testCount; + TBool continueTests; + TUint testFailedLine; + //This field was intended to allow threaded panicing tests to report other errors + //As I can't get threaded panicing tests to operate correctly, I have not implemented support for the field. + //TBuf<1024> errorMessages; + + WrapTestCall ( CTWsGraphs* thisThis, TUint testCount): + thisThis(thisThis), testCount(testCount) + { continueTests=false;testFailedLine=0; } + }; + +TInt CTWsGraphs::DoNegTestCall(TInt /*aInt*/, TAny *aPtr) + { + CTWsGraphs::WrapTestCall* aWrap=static_cast(aPtr); + aWrap->continueTests=aWrap->thisThis->NegTestAddSwapGDArrayL(aWrap->testCount,aWrap); + return 0; + } + +TBool CTWsGraphs::LaunchNegTestCall(TUint aTestCount,TUint PanicCode,const TDesC &aPanicCategory) + { + WrapTestCall wt(this,aTestCount); + (void)PanicCode; + (void)aPanicCategory; +//I have disabled the panicing tests because they don't output diagnostics +//and the open panic window causes subsequent screen bitmap comparrisson tests to fail. +// iTest->TestPanicL(DoNegTestCall,aPanicCode,3,&wt,aPanicCategory); + return wt.continueTests; + } + +/** + Loops through all the positive and negative tests associated with the GraphicDrawerArray. + The aim is to perform isolated testing of these classes as some are not currently being used. + +**/ +void CTWsGraphs::TestAddSwapGDArrayL() + { + + + INFO_PRINTF1(_L("Positive tests for GraphicDrawerArray")); + for (TInt i=0;PosTestAddSwapGDArrayL(i);i++) + {} + + + + INFO_PRINTF1(_L("Verifying that negative tests for GraphicDrawerArray don't actually panic")); + for (TInt i=1;NegTestAddSwapGDArrayL(i);i++) + {} + } +/** + Resets and deallocates the GDA withoud deleting the objects. + @param testArray the array to reset + @return true if the array was already empty. +**/ +static bool ResetArray(CWsGraphicDrawerArray& testArray) +{ + bool rv=(testArray.IsEmpty()); + MWsClient* nullClient=NULL; + testArray.RemoveAll(*nullClient); + testArray.ResetAndDestroy(); + return rv; +} +/** + @SYMTestCaseID GRAPHICS-WSERV-AddSwapGDArray-0001 + @SYMDEF DEF093926 + + @SYMTestCaseDesc DEF093926: Check for stability of Add and Swap unwind methods in isolation. + Note that this code is testing the functionality of a class internal to CWindowServer. + At present CWindowServer presents just a simple shim on this class, + but if that implementation of CWindowServer changes than this test will be redudant. + + @SYMTestPriority High + + @SYMTestStatus Implemented + + @SYMTestActions + The sequence for each of these positive test sections is pretty much the same: + Add one record with id 1234(test for errors) + Add one record with id Badf00d + Swap with another record with id Badf00d + Remove 2 records + result=no leaks + + Add/Swap: no Cleanup item - no leaks after Remove the added items + AddTLC/SwapTLC: Cleanup item requires Commit - check for no leaks after Remove. + AddTLC/SwapTLC: Cleanup item gets executed by forced Leave - check for no leaks after. + AddTLC, SwapTLC in allocation failure scenarios. Add/Swap don't allocate anything! + obsoleted AddLC/SwapLC to ensure correct function when forced Leave - check for no leaks after + obsoleted AddLC/SwapLC to ensure correct function. These will always leak in good case. + @SYMTestExpectedResults + no exceptions or panics within this fn. + only the old AddLC and SwapLC should leak as indicated. + */ +TBool CTWsGraphs::PosTestAddSwapGDArrayL(TInt testcase) + { + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-AddSwapGDArray-0001")); + CWsGraphicDrawerArray testArray; + //Represents the memory cached in the array once it has been used even when it is then resized to zero +#if defined(_DEBUG) + const TInt KArrayMemUseBaseline=1; +#endif + //Use testArray.IsEmpty() to prove the array is clear when it should be! + TGraphicDrawerId id1234= { 1234, EFalse }; + TGraphicDrawerId idBADF00D= { 0xBADF00D, EFalse }; + WsGraphicDrawer dg1234; + dg1234.ConstructL(id1234); + WsGraphicDrawer dgBADF00D; + dgBADF00D.ConstructL(idBADF00D); + WsGraphicDrawer dgBADF00D_2; + dgBADF00D_2.ConstructL(idBADF00D); + CWsGraphicDrawerArray::XRollBackBase* rollBack1; + TInt errCode=KErrAbort; + TInt leaveCode=KErrNone; + DummyCleanup markerCleanup; + CleanupStack::PushL(markerCleanup); //This allows me to check the stack is clear! + //expected result of this fn: no exceptions or panics. + //Put as much as you like in here, so long as it shouldn't fail. + + __UHEAP_MARK; + __UHEAP_CHECK(0); + TUint expectedLeakCount=0; + TBool returnCode=ETrue; + switch (testcase) + { + case 0: + + INFO_PRINTF1(_L("Sub test P0: AddL/Swap: no Cleanup item")); + TEST(testArray.IsEmpty()); + TRAP(leaveCode,errCode=testArray.Add(&dg1234)); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(!testArray.IsEmpty()); + TRAP(leaveCode,errCode=testArray.Add(&dgBADF00D)); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode,errCode=testArray.Swap(&dgBADF00D_2)); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode,errCode=testArray.Remove(dg1234.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + //Note that it is the ID that matters here... dgBADF00D & dgBADF00D_2 have same id. + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(testArray.IsEmpty()); + break; + // + case 1: + INFO_PRINTF1(_L("Sub test P1: AddTLC/SwapTLC: Cleanup item requires Commit.")); + + rollBack1=NULL; + TEST(testArray.IsEmpty()); + TRAP(leaveCode, + rollBack1=testArray.AddTLC(&dg1234); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1!=NULL); + TEST(leaveCode==KErrNone); + TEST(!testArray.IsEmpty()); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.AddTLC(&dgBADF00D); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1!=NULL); + TEST(leaveCode==KErrNone); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.SwapTLC(&dgBADF00D_2); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1!=NULL); + TEST(leaveCode==KErrNone); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.RemoveTLC(dg1234.Id()); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1!=NULL); + TEST(leaveCode==KErrNone); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.RemoveTLC(dgBADF00D_2.Id()); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1!=NULL); + TEST(leaveCode==KErrNone); + rollBack1=NULL; + TEST(testArray.IsEmpty()); + break; + // + case 2: + INFO_PRINTF1(_L("Sub test P2: AddTLC/SwapTLC: Cleanup item gets executed.")); + + rollBack1=NULL; + TEST(testArray.IsEmpty()); + TRAP(leaveCode, + rollBack1=testArray.AddTLC(&dg1234); + User::Leave(1234); + ); + TEST(rollBack1!=NULL); + TEST(leaveCode==1234); + TEST(testArray.IsEmpty()); + rollBack1=NULL; + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(KArrayMemUseBaseline); + + TRAP(leaveCode, errCode=testArray.Add(&dgBADF00D)); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.SwapTLC(&dgBADF00D_2); + User::Leave(1234); + ); + TEST(rollBack1!=NULL); + TEST(leaveCode==1234); + TEST(!testArray.IsEmpty()); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.RemoveTLC(dgBADF00D_2.Id()); + TEST(testArray.IsEmpty()); + User::Leave(1234); + ); + TEST(rollBack1!=NULL); + TEST(leaveCode==1234); + TEST(!testArray.IsEmpty()); + + + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(testArray.IsEmpty()); + rollBack1=NULL; + break; + // + case 3: + INFO_PRINTF1(_L("Sub test P3: AddLC/SwapLC: Cleanup item gets executed - doesn't leak")); + TEST(testArray.IsEmpty()); + TRAP(leaveCode, + testArray.AddLC(&dg1234); + User::Leave(1234); + ); + TEST(leaveCode==1234); + TEST(testArray.IsEmpty()); + rollBack1=NULL; + __UHEAP_CHECK(KArrayMemUseBaseline); //because it threw it didn't leak + + //use my new method to add the object to be swapped out so no leak + TRAP(leaveCode,errCode=testArray.Add(&dgBADF00D)); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + __UHEAP_CHECK(KArrayMemUseBaseline); //new method doesn't leak. + rollBack1=NULL; + TRAP(leaveCode, + errCode=testArray.SwapLC(&dgBADF00D_2); + User::Leave(1234); + ); + TEST(errCode==KErrNone); + TEST(leaveCode==1234); + TEST(!testArray.IsEmpty()); + + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(testArray.IsEmpty()); + rollBack1=NULL; + break; + // + case 4: + + //I don't really care whether the individual calls succeed or fail, + //just whether it leaks overall, and that the error codes correspond to no-action + for (TInt faultRate=1;faultRate<5;faultRate++) + { + INFO_PRINTF2(_L("Sub test P4: Add/Swap: memory faulting %i"),faultRate); + __UHEAP_SETFAIL(RAllocator::EDeterministic,faultRate); + TInt err1=KErrNone; + rollBack1=NULL; + TRAP(leaveCode, + errCode=testArray.Add(&dg1234); + ) + err1=errCode; + __UHEAP_SETFAIL(RAllocator::ENone,0); + TRAP(leaveCode,errCode=testArray.Add(&dgBADF00D)); + __UHEAP_SETFAIL(RAllocator::EDeterministic,faultRate); + rollBack1=NULL; + TRAP(leaveCode, + errCode=testArray.Swap(&dgBADF00D_2); + ) + __UHEAP_SETFAIL(RAllocator::ENone,0); + //If the first Add fails then the object should not be removed + if (!err1) + { + TRAP(leaveCode,errCode=testArray.Remove(dg1234.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + } + //If the swap fails, then the add still needs to be removed + //Note that it is the ID that matters here... dgBADF00D & dgBADF00D_2 have same id. + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(testArray.IsEmpty()); + ResetArray(testArray); + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(0); + } + break; + // + case 5: + + //I don't really care whether the individual calls succeed or fail, + //just whether it leaks overall, and that the error codes correspond to no-action + for (TInt faultRate=1;faultRate<5;faultRate++) + { + INFO_PRINTF2(_L("Sub test P5: AddTLC/SwapTLC: memory faulting %i"),faultRate); + __UHEAP_SETFAIL(RAllocator::EDeterministic,faultRate); + TInt err1=KErrNone,err2=KErrNone,err3=KErrNone; + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.AddTLC(&dg1234); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + err1=leaveCode; + __UHEAP_SETFAIL(RAllocator::ENone,0); + TRAP(leaveCode,errCode=testArray.Add(&dgBADF00D)); + __UHEAP_SETFAIL(RAllocator::EDeterministic,faultRate); + rollBack1=NULL; + TRAP(leaveCode, + rollBack1=testArray.SwapTLC(&dgBADF00D_2); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + //If the first Add fails then the object should not be removed + if (!err1) + { + TRAP(leaveCode, + rollBack1=testArray.RemoveTLC(dg1234.Id()); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + err2=leaveCode; + } + //If the swap fails, then the add still needs to be removed + //Note that it is the ID that matters here... dgBADF00D & dgBADF00D_2 have same id. + TRAP(leaveCode, + rollBack1=testArray.RemoveTLC(dgBADF00D_2.Id()); + CleanupStack::Check(rollBack1); + testArray.CommitP(rollBack1); + ) + err3=leaveCode; + + + __UHEAP_SETFAIL(RAllocator::ENone,0); + //If the Removes failed then the object should be removed again + if (err2) + { + TRAP(leaveCode,errCode=testArray.Remove(dg1234.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + } + if (err3) + { + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + } + TEST(testArray.IsEmpty()); + ResetArray(testArray); + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(0); + } + + break; + // + case 6: + //this set does leak: + + INFO_PRINTF1(_L("Sub test P6: AddLC/SwapLC: Cleanup item gets popped - unfixable leaks")); + TEST(testArray.IsEmpty()); + TRAP(leaveCode, + testArray.AddLC(&dg1234); + CleanupStack::Pop(); + ); + TEST(leaveCode==KErrNone); + TEST(!testArray.IsEmpty()); + + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(KArrayMemUseBaseline+1); + + TRAP(leaveCode, + testArray.AddLC(&dgBADF00D); + CleanupStack::Pop(); + ) + TEST(leaveCode==KErrNone); + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(KArrayMemUseBaseline+2); + rollBack1=NULL; + TRAP(leaveCode, + errCode=testArray.SwapLC(&dgBADF00D_2); + CleanupStack::Pop(); + ); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(!testArray.IsEmpty()); + TRAP(leaveCode,errCode=testArray.Remove(dg1234.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode,errCode=testArray.Remove(dgBADF00D_2.Id())); + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TEST(testArray.IsEmpty()); + rollBack1=NULL; + expectedLeakCount=3; + break; + // + case 7: + returnCode=EFalse; + break; + } + ResetArray(testArray); + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(expectedLeakCount); + __UHEAP_MARKENDC(expectedLeakCount); + if (expectedLeakCount!=0) + { //Ensure that the leaked items are no longer associated with this debug level. + //Note that __DbgSetAllocFail(FALSE,RAllocator::EReset,1) resets the debug level to 0, + //so levels can't be nested when using this call. + __UHEAP_MARK; + __UHEAP_TOTAL_RESET; + INFO_PRINTF2(_L("Anticipated %i leaks declassified"),expectedLeakCount); //can't get here if wrong + } + + CleanupStack::PopAndDestroy(markerCleanup); + ((CTWsGraphsStep*)iStep)->RecordTestResultL(); + return returnCode; + } + +/** + @param failcase index to test to perform + @param aWrappedParams represents inter-thread information when test is run on a private thread + if aWrappedParams is NULL then the test is running on the main thread. + @return true if there are higher-numbered fail cases. + + @SYMTestCaseID GRAPHICS-WSERV-NegAddSwapGDArray-0001 + @SYMDEF DEF093926 + + @SYMTestCaseDesc DEF093926: Check for stability of Add and Swap unwind methods in isolation, + specifically checking that bad inputs are rejected gracefully. + Note that this code is testing the functionality of a class internal to CWindowServer. + At present CWindowServer presents just a simple shim on this class, + but if that implementation of CWindowServer changes than this test will be redudant. + + @SYMTestPriority High + + @SYMTestStatus Implemented + + @SYMTestActions + + Add/Swap: no Cleanup item - no leaks after Remove the added items + AddTLC/SwapTLC: Cleanup item requires Commit - check for no leaks after Remove. + AddTLC/SwapTLC: Cleanup item gets executed by forced Leave - check for no leaks after. + AddTLC, SwapTLC in allocation failure scenarios. Add/Swap don't allocate anything! + obsoleted AddLC/SwapLC to ensure correct function when forced Leave - check for no leaks after + obsoleted AddLC/SwapLC to ensure correct function. These will always leak in good case. + Calls NegTestAddSwapGDArrayL. + case 1/2/3: Tests AddL, AddLC, AddTLC that a NULL input is rejected + case 4/5/6: Tests SwapL, SwapLC, SwapTLC that a NULL input is rejected + case 7/8/9: Tests AddL, AddLC, AddTLC that a repeat input is rejected + case 10/11/12: Tests SwapL, SwapLC, SwapTLC that a non-repeat input is rejected + @SYMTestExpectedResults + */ +TBool CTWsGraphs::NegTestAddSwapGDArrayL(TInt failcase,WrapTestCall*aWrappedParams) + { + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-NegAddSwapGDArray-0001")); + _LIT(KCategory,"WsGraphicDrawer"); + if (!aWrappedParams) + { + INFO_PRINTF2(_L("NegTestAddSwapGDArrayL Negative sub test %i"),failcase); + }; + CWsGraphicDrawerArray testArray; + TGraphicDrawerId id1234= { 1234, EFalse }; + TGraphicDrawerId idBADF00D= { 0xBADF00D, EFalse }; + WsGraphicDrawer dg1234; + dg1234.ConstructL(id1234); + WsGraphicDrawer dgBADF00D; + dgBADF00D.ConstructL(idBADF00D); + WsGraphicDrawer dgBADF00D_2; + dgBADF00D_2.ConstructL(idBADF00D); + CWsGraphicDrawerArray::XRollBackBase* rollBack1=NULL; + TInt errCode=KErrAbort; + TInt leaveCode=KErrNone; + TBool returnMoreTests=ETrue; + DummyCleanup markerCleanup; + TBool mayPanic=EFalse; +#ifdef __WINS__ + mayPanic=ETrue; +#endif + + CleanupStack::PushL(markerCleanup); //This allows me to check the stack is clear! + __UHEAP_MARK; + + switch (failcase) + { + case 1: //NULL arg: expected result: returns KErrArgument + TRAP(leaveCode, + errCode=testArray.Add(NULL); + ) + TEST(leaveCode==KErrNone); + ReportNegativeResultfail(__LINE__,errCode,KErrArgument); + break; + case 2: //NULL arg: expected result: throws KErrArgument + TRAP(leaveCode, + rollBack1=testArray.AddTLC(NULL); + TEST(EFalse); //Should never get here! + ) + TEST(rollBack1==NULL); + ReportNegativeResultfail(__LINE__,leaveCode,KErrArgument); + break; + case 3: //NULL arg: expected result: debug: panic. In release doesn't return any information! + if (!aWrappedParams && mayPanic) + { + LaunchNegTestCall(failcase,EWsGraphicDrawerPanicBadArgument,KCategory); + } + else + { + TRAP(leaveCode, + testArray.AddLC(NULL); + User::Leave(1234); //Panics before here in debug. No leak if cleanup is taken. + ); + TEST(leaveCode==1234); //Panics before here in debug + } + break; + // + case 4: //NULL arg: expected result: returns KErrArgument + TRAP(leaveCode, + errCode=testArray.Swap(NULL) + ) + TEST(leaveCode==KErrNone); + ReportNegativeResultfail(__LINE__,errCode,KErrArgument); + break; + case 5: //expected result: throws KErrArgument + TRAP(leaveCode, + rollBack1=testArray.SwapTLC(NULL); + testArray.CommitP(rollBack1); + ) + TEST(rollBack1==NULL); + ReportNegativeResultfail(__LINE__,leaveCode,KErrArgument); + break; + case 6: //NULL arg: expected result: debug: panic. In release doesn't return any information! + if (!aWrappedParams && mayPanic) + { + LaunchNegTestCall(failcase,EWsGraphicDrawerPanicBadArgument,KCategory); + } + else + { + TRAP(leaveCode, + errCode=testArray.SwapLC(NULL); + User::Leave(1234); //Panics before here in debug. No leak if cleanup is taken. + ); + TEST(leaveCode==1234); //Panics before here in debug + TEST(errCode==KErrNotFound); + } + break; + // + case 7: //Add overwrites: expected result: returns KErrAlreadyExists + TRAP(leaveCode, + errCode=testArray.Add(&dg1234); + ) + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode, + errCode=testArray.Add(&dg1234); //oops! Already added! + ) + TEST(leaveCode==KErrNone); + ReportNegativeResultfail(__LINE__,errCode,KErrAlreadyExists); + break; + case 8: //Add overwrites: expected result: throws KErrAlreadyExists + TRAP(leaveCode, + errCode=testArray.Add(&dg1234); + ) + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode, + rollBack1=testArray.AddTLC(&dg1234); //oops! Already added! + testArray.CommitP(rollBack1); + ) + TEST(rollBack1==NULL); + ReportNegativeResultfail(__LINE__,leaveCode,KErrAlreadyExists); + break; + case 9: //Add overwrites: expected result: debug: does not panic, but throws KErrAlreadyExists. + TRAP(leaveCode, + errCode=testArray.Add(&dg1234); + ) + TEST(errCode==KErrNone); + TEST(leaveCode==KErrNone); + TRAP(leaveCode, + testArray.AddLC(&dg1234); //oops! Already added! Should leave. + User::Leave(1234); //Should leave before here! No leak if cleanup is taken. + ); + ReportNegativeResultfail(__LINE__,leaveCode,KErrAlreadyExists); + break; + // + case 10: //Swap empty slot: expected result: returns KErrNotFound + TRAP(leaveCode, + errCode=testArray.Swap(&dg1234) //oops! Nothing to swap with! + ) + TEST(leaveCode==KErrNone); + ReportNegativeResultfail(__LINE__,errCode,KErrNotFound); + break; + case 11: //Swap empty slot: expected result: throws KErrNotFound + TRAP(leaveCode, + rollBack1=testArray.SwapTLC(&dg1234); //oops! Nothing to swap with! + testArray.CommitP(rollBack1); + ) + TEST(rollBack1==NULL); + ReportNegativeResultfail(__LINE__,leaveCode,KErrNotFound); + break; + case 12: //Swap empty slot: expected result: debug: panic. In release doesn't return any information! + if (!aWrappedParams && mayPanic) + { + LaunchNegTestCall(failcase,EWsGraphicDrawerPanicBadArgument,KCategory); + } + else + { + TRAP(leaveCode, + errCode=testArray.SwapLC(&dg1234); //oops! Nothing to swap with! + User::Leave(1234); //Panics before here in debug. No leak if cleanup is taken. + ); + TEST(leaveCode==1234); //Panics before here in debug + TEST(errCode==KErrNotFound); //Panics before here in debug + } + break; + + // + default: + returnMoreTests=EFalse; + } + ResetArray(testArray); + CleanupStack::Check(markerCleanup); + __UHEAP_CHECK(0); + __UHEAP_MARKENDC(0); + testArray.Close(); +// CWsGraphicDrawerArray::testArrayValidator::ResetArray(&testArray); + CleanupStack::PopAndDestroy(markerCleanup); + return returnMoreTests; + } + +/** + @SYMTestCaseID GRAPHICS-WSERV-LeakInService-0001 + @SYMDEF DEF093926 + @SYMTestCaseDesc Check for leaks over repeated re-assignments. + + @SYMTestPriority High + + @SYMTestStatus Implemented + + @SYMTestActions + Repeatedly create the same bitmap instance + After a few initial wobbles in the server-side HeapCount it should not increase + 5 calls are made without checking the level, then 5 more check the level. + Note that as we are testing the main server heap, + other threads may interrupt and perform operations that change the memory figures. + + @SYMTestExpectedResults The CWsGraphicBitmap objects are created and no leaks are reported. + */ +void CTWsGraphs::DoTestLeakInServiceL() + { + INFO_PRINTF1(_L("DoTestLeakInServiceL")); + const TInt prepCount=5; + const TInt testCount=5; + + + TUid uid1 = {0x10000001}; + TUid uid2 = {0x10000002}; + + TWsGraphicId twsGraphicId1(uid1); + TEST(twsGraphicId1.Uid()==uid1); + + TWsGraphicId twsGraphicId2(uid2); + TEST(twsGraphicId2.Uid()==uid2); + + TWsGraphicId twsGraphicId3(twsGraphicId2); + TEST(twsGraphicId3.Uid()==uid2); + + TWsGraphicId twsGraphicId4(1); + twsGraphicId4.Set(uid1); + TEST(twsGraphicId4.Uid()==uid1); + + TSize screenSize = TheClient->iScreen->SizeInPixels(); + + __UHEAP_RESET; + __UHEAP_MARK; + // Create local shared CWsGraphicBitmap + // Repeat operation for any sign of memory leak... + CFbsBitmap bitmap2; + CFbsBitmap mask2; + + bitmap2.Create(screenSize,TheClient->iScreen->DisplayMode()); + mask2.Create(bitmap2.SizeInPixels(),TheClient->iScreen->DisplayMode()); + + TInt c0=TheClient->iWs.HeapCount(); + CWsGraphicBitmap* bTestX = CWsGraphicBitmap::NewL(twsGraphicId2.Uid(), &bitmap2,&mask2); + for (TInt i=0;iiWs.HeapCount(); + delete bTestX; + //TInt c3=TheClient->iWs.HeapCount(); + bTestX = CWsGraphicBitmap::NewL(twsGraphicId2.Uid(), &bitmap2,&mask2); + //TInt c4=TheClient->iWs.HeapCount(); + } + // Give WSERV a chance to settle. + TheClient->iWs.Finish(); + User::After (1000000); //1s + + TInt c1=TheClient->iWs.HeapCount(); + TInt failures=0; + for (TInt i=0;iiWs.HeapCount(); + delete bTestX; + //TInt c3=TheClient->iWs.HeapCount(); + //The heap count doesn't go down after delete operation + //because the delete message is buffered by the server, because it does not have a return value. + //Aparrently, although CWsGraphicBitmap and TheClient terminate at the same server, + //and use the same general heap (I have tested this under debug), + //they do not share the same session, so flushing TheClient does not effect CWsGraphicBitmap + bTestX = CWsGraphicBitmap::NewL(twsGraphicId2.Uid(), &bitmap2,&mask2); + + // Give WSERV a chance to settle. + TheClient->iWs.Finish(); + User::After (1000000); //1s + + TInt c4=TheClient->iWs.HeapCount(); + //Can compare immediately after allocation as the server doesn't buffer the create command. + if (!(c2==c4)) + { + if (c4 > c2) // only fail the test if the count has increased + { + failures++; + } + INFO_PRINTF2(_L("Server Heap count change accross delete/new = %i"),c4-c2); + } + } + // Outside of main loop to avoid client/wserv interaction during test. + TEST(failures==0); + TInt c5=TheClient->iWs.HeapCount(); + TEST((c1-c5)/testCount==0); //If every call leaked. + if ((c1-c5)/testCount) + { + INFO_PRINTF3(_L("Server Heap count change accross %i delete/new cycles = %i"),testCount,c5-c1); + INFO_PRINTF3(_L("Before %i / After %i"),c1,c5); + } + + delete bTestX; + + __UHEAP_CHECK(0); + __UHEAP_MARKEND; + + } +/** + @SYMTestCaseID GRAPHICS-WSERV-0381 + @SYMDEF DEF095063 + @SYMTestCaseDesc Test case for INC098114 CWsGraphicDrawer::SendMessage panics window server + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Enable the test flag and reproduce the defect + Action step: + -Instruct plugin to register event handler + -Draw fullscreen window (plugin will receive window visibility changed event) + -Set the test flag + -Query visibility region from plugin side + -Instruct plugin to unregister event handler + -Destroy fullscreen window (plugin will not receive window visibility changed event) + + @SYMTestExpectedResults wserv should not panic with the fix +*/ + +TestState CTWsGraphs::TestSuccessiveMessageL() + { + if (iSubState==0) + { + _LIT(KTestSuccessiveMessage, "TestSuccessiveMessage"); + INFO_PRINTF1(KTestSuccessiveMessage); + + ++iSubState; + iListen->Enable(ETrue); + CreateWindowL(); + Mem::FillZ(&iListenInfo, sizeof(TListenerInfo)); + //Set the test flag to enable the reproduction of defect + iListen->SetTestFlag(); + iListen->QueryPlugin(iListenInfo); + iListen->Enable(EFalse); + DestroyWindowL(); + return EWait; + } + + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +TestState CTWsGraphs::TestWindowGroupChangeL() + { + if (iSubState==0) + { + _LIT(KTestWindowGroupChange, "TestWindowGroupChange"); + INFO_PRINTF1(KTestWindowGroupChange); + + ++iSubState; + iListen->Enable(ETrue); + CreateWindowL(); + Mem::FillZ(&iListenInfo, sizeof(TListenerInfo)); + iListen->QueryPlugin(iListenInfo); + return EWait; + } + + if (iSubState==1) + { + ++iSubState; + iOriginalWindowGroupId = iListenInfo.iWindowGroupId; + iNewWin = CCrWin::NewL(iTest->iScreenNumber, ETrue); + iListen->QueryPlugin(iListenInfo); + return EWait; + } + + TEST(iListenInfo.iWindowGroupId != iOriginalWindowGroupId); + + delete iNewWin; + iNewWin = NULL; + iListen->Enable(EFalse); + DestroyWindowL(); + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +/** + @SYMTestCaseID GRAPHICS-WSERV-0382 + @SYMDEF INC085451 + @SYMTestCaseDesc Test Animation frame rate + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Simulate an Animation artwork by calling DrawWsGraphic and DoDraw. + Action step: + -Calls DrawWsGraphic for two different animations with different frame rates + -Retrieve the frame count for two differnt frames per seconds + -Test the two frame rate shouldn't be same. + + @SYMTestExpectedResults Animation Frame rate should be different for different frames per second +*/ +TestState CTWsGraphs::TestFrameRateL() + { + //Check for Transparency enabled in wsini.ini + if (TransparencySupportedL()==KErrNotSupported) + { + ++(iTest->iState); + return ENext; + } + + // flush transparent window destruction created in TransparencySupportedL before + // proceeding with the test + TheClient->iWs.Flush(); + + //Here iSubState is 0, when this functions executes first time + // iSubState is 1 means the call is from a callback function. + if(iSubState == 0) + { + _LIT(KTestFrameRate, "TestFrameRate"); + INFO_PRINTF1(KTestFrameRate); + + ++iSubState; + iTestframerate = CGraphicTestFrameRate::NewL(iTest->iScreenNumber); + + //Set the callback function + iTestframerate->SetCallBack(TCallBack(CTWsGraphs::PluginCallBack,this)); + + //Create the window and call the graphic animation + CreateWindowL(EFalse); + iWin->DrawGraphic(iTestframerate->Id().Id()); + return EWait; + } + + //PeterI wait a while for animations to redraw then query the plugin + User::After(2000000); + TheClient->iWs.Flush(); + TheClient->WaitForRedrawsToFinish(); + TheClient->iWs.Finish(); + + //Invoke the plug-in and get the counter value + Mem::FillZ(&iAnimCount, sizeof(TAnimRate)); + + iTestframerate->QueryPlugin(iAnimCount); + TheClient->iWs.Flush(); + TheClient->WaitForRedrawsToFinish(); + TheClient->iWs.Finish(); + + //Compare and test the total frame rate for two different frame counts.... + TEST((iAnimCount.iAnim1>0 && iAnimCount.iAnim2>0) && iAnimCount.iAnim1 !=iAnimCount.iAnim2); + if(iSubState == 1) + { + DestroyWindowL(); + delete iTestframerate; + } + ++(iTest->iState); + iSubState = 0; + return ENext; + } + +/** + @SYMTestCaseID GRAPHICS-WSERV-0438 + @SYMDEF INC103472 + @SYMTestCaseDesc CRedrawRegion::ContainsDrawers does not look for all drawers + @SYMTestPriority Medium + @SYMTestStatus Implemented + @SYMTestActions Create ECom-plugins to enable the scenario, in which there is one simple and one container drawer. + In the container drawer, two other simple drawers are enabled. Each drawer draws a coloured ellipse. + In this case, when the contained drawer is requested to change the colour of the ellipse, the screen will not be updated + without the fix. + Action step: + -Create four CRP graphics. + -Call the simple drawer and container drawer to draw ellipses. The container drawer + also enables two other simple drawers to draw ellipses in different colors. + -Update the color of each ellipse in turn. + -Check that the screen display is as required. + @SYMTestExpectedResults The colour of each ellipse residing in the drawers is successfully updated. Those for the contained drawers wont be updated without the fix. +*/ +void CTWsGraphs::TestNestedDrawerCRP() + { + _LIT(KTestContainDrawer, "Test INC103472: A Contained Drawer"); + INFO_PRINTF1(KTestContainDrawer); + + RWindow window1(TheClient->iWs); + CleanupClosePushL(window1); + User::LeaveIfError(window1.Construct(*TheClient->iGroup->GroupWin(), ENullWsHandle)); + + window1.EnableRedrawStore(ETrue); // Force to enable the redraw storing + window1.SetRequiredDisplayMode(EColor256); // Do not set window size here to avoid hardware test failure + window1.SetBackgroundColor(KRgbDarkGreen); + window1.Activate(); + + // A simple graphic + CWsSimpleGraphicBitmap* wsGraphic1 = CWsSimpleGraphicBitmap::NewL(KSimpleDrawerInterfaceId); + CleanupStack::PushL(wsGraphic1); + // A container graphic + CWsContainGraphicBitmap* wsGraphic2 = CWsContainGraphicBitmap::NewL(KContainDrawerInterfaceId); + CleanupStack::PushL(wsGraphic2); + // A contained graphic residing in the container graphic wsGraphic2 + CWsSimpleGraphicBitmap* wsGraphic3 = CWsInvisibleGraphicBitmap1::NewL(KInvisibleDrawerInterfaceId1); + CleanupStack::PushL(wsGraphic3); + // A contained graphic residing in the container graphic wsGraphic2 + CWsSimpleGraphicBitmap* wsGraphic4 = CWsInvisibleGraphicBitmap2::NewL(KInvisibleDrawerInterfaceId2); + CleanupStack::PushL(wsGraphic4); + + window1.Invalidate(); + window1.BeginRedraw(); + TheClient->iGc->Activate(window1); + TheClient->iGc->Clear(); + // Call CRP drawer to draw the coloured ellipses + TheClient->iGc->DrawWsGraphic(wsGraphic1->Id(),TRect(TPoint(20,20),TSize(300,100))); + TheClient->iGc->DrawWsGraphic(wsGraphic2->Id(),TRect(TPoint(20,100),TSize(300,100))); + + TheClient->iGc->Deactivate(); + window1.EndRedraw(); + TheClient->Flush(); + + // Update the colour of four ellipses residing in four CRP drawers. + TInt err = wsGraphic1->UpdateColor(KRgbRed); + TEST(KErrNone == err); + err = wsGraphic2->UpdateColor(KRgbDarkBlue); + TEST(KErrNone == err); + // If the fix is not inserted, the colour of the third and fourth ellipses residing in the contained drawers wont be updated + err = wsGraphic3->UpdateColor(KRgbDarkMagenta); + TEST(KErrNone == err); + err = wsGraphic4->UpdateColor(KRgbDarkCyan); //won't change the displayed color if there is a right place for flush() + TEST(KErrNone == err); + + TheClient->Flush(); + // Force some delays to wait until the color change + User::After(2000000); + // Test whether the screen content is changed as required + CheckResult(); + CleanupStack::PopAndDestroy(5,&window1); + } + +// Check the screen display with the reference bitmap to ensure the color to be updated correctly +void CTWsGraphs::CheckResult() + { + TSize size = TSize(320,200);//The maximum size of the screen content we are looking at + + // Create a reference bitmap + CFbsBitmap* bitmapRef = new(ELeave) CFbsBitmap; + CleanupStack::PushL(bitmapRef); + User::LeaveIfError(bitmapRef->Create(size, EColor256)); + CFbsBitGc* gc; + CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(bitmapRef); + TEST(bitmapDev!=NULL); + CleanupStack::PushL(bitmapDev); + User::LeaveIfError(bitmapDev->CreateContext(gc)); + CleanupStack::PushL(gc); + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetBrushColor(KRgbDarkGreen); + gc->Clear(TRect(TPoint(0,0), size));//background dark green + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetBrushColor(KRgbRed); + gc->DrawEllipse(TRect(TPoint(20,20),TSize(300,100))); //map to the simple drawer + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetBrushColor(KRgbDarkBlue); + gc->DrawEllipse(TRect(TPoint(20,100),TSize(300,100))); //map to the container drawer + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetBrushColor(KRgbDarkMagenta); + gc->DrawEllipse(TRect(TPoint(100,150),TSize(50,50))); //map to the contained drawer + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetBrushColor(KRgbDarkCyan); + gc->DrawEllipse(TRect(TPoint(200,150),TSize(50,50))); //map to the contained drawer + TInt bitmapHeight = bitmapRef->SizeInPixels().iHeight; + TInt bitmapWidth = bitmapRef->SizeInPixels().iWidth; + + // Copy the screen content to bitmap + INFO_PRINTF1(_L("Capture screen content.")); + CFbsBitmap* screenBitmap = new(ELeave) CFbsBitmap(); + CleanupStack::PushL(screenBitmap); + User::LeaveIfError(screenBitmap->Create(size, TheClient->iScreen->DisplayMode())); + TRect rct = TRect(TPoint(0,0), size); + User::LeaveIfError(TheClient->iScreen->CopyScreenToBitmap(screenBitmap,rct)); + + // Compare the displayed bitmap against the reference one + INFO_PRINTF1(_L("Compare the displayed bitmap against the expected one.")); + TInt lineLength=bitmapRef->ScanLineLength(bitmapWidth, EColor256); + HBufC8* compareLineBuf=HBufC8::NewLC(lineLength); + TPtr8 compareLinePtr(compareLineBuf->Des()); + HBufC8* screenLineBuf=HBufC8::NewLC(lineLength); + TPtr8 screenLinePtr(screenLineBuf->Des()); + for (TInt index=0; indexGetScanLine(compareLinePtr, TPoint(0,index), bitmapWidth, EColor256); + screenBitmap->GetScanLine(screenLinePtr, TPoint(0,index),bitmapWidth, EColor256); + TInt compareResult=compareLinePtr.Compare(screenLinePtr); + if (compareResult!=0) + { + INFO_PRINTF2(_L("Scanline compare failed: %d"),index); + TEST(EFalse); + break; + } + } + CleanupStack::PopAndDestroy(6,bitmapRef); + + } + +void ResetScreenMode(TAny* aAny) + { + CWsScreenDevice* screen=static_cast(aAny); + screen->SetScreenMode(0); + screen->SetAppScreenMode(0); + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +void CTWsGraphs::TestScreenModeChangeL() + { + _LIT(KLog,"Screen Doesn't match bitmap. Size=(%d,%d) winSizeMode=%d redrawMode=%d modeIndex=%d"); +// A simple CRP graphic to draw in the test + CWsSimpleGraphicBitmap* wsGraphic1=CWsSimpleGraphicBitmap::NewL(KSimpleDrawerInterfaceId); + CleanupStack::PushL(wsGraphic1); + RWindow testWin(TheClient->iWs); + CleanupClosePushL(testWin); + User::LeaveIfError(testWin.Construct(*TheClient->iGroup->GroupWin(),0xbadbad)); + testWin.SetRequiredDisplayMode(EColor64K); + testWin.Activate(); +// Cleanup display mode by setting back to 0 if we leave in the tests + CleanupStack::PushL(TCleanupItem(ResetScreenMode,TheClient->iScreen)); + TInt numScreenModes=TheClient->iScreenModes.Count(); + TBool match; + + for(TInt winSizeMode=0;winSizeMode<2;winSizeMode++) + { // Two size modes, fullScreen and non-full screen + for(TInt redrawMode=0;redrawMode<2;redrawMode++) + { // Two redraw modes to test drawing inside and outside of a redraw. + const TBool drawInsideRedraw=(redrawMode==0); + for(TInt modeIndex=0;modeIndexiScreenModes[modeIndex]; + const TPoint origin=TheClient->iScreen->GetScreenModeScaledOrigin(screenMode); + if (origin.iX!=0 || origin.iY!=0) + continue; + // Enable redirection before changing screen mode as this is what we are testing + iRedir->Redirect(CWsRedir::EFrontBuffer, ETrue); + TheClient->iScreen->SetAppScreenMode(screenMode); + TheClient->iScreen->SetScreenMode(screenMode); + + TPixelsAndRotation sizeAndRotation; + TheClient->iScreen->GetDefaultScreenSizeAndRotation(sizeAndRotation); +// + TSize screenSize(TheClient->iScreen->SizeInPixels()); + if(sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationRotated90 || + sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationRotated270) + { + screenSize.iWidth = Min(screenSize.iWidth, 240);//to make sure we won't exceed physical screen size + } + TSize winSize(screenSize); + TPoint winPos; + if (winSizeMode==1) + { + winSize.iWidth=winSize.iWidth*2/3; + winSize.iHeight=winSize.iHeight*3/4; + winPos.iX=(screenSize.iWidth-winSize.iWidth)/4; + winPos.iY=(screenSize.iHeight-winSize.iHeight)*3/4; + } + testWin.SetExtent(winPos,winSize); + TSize halfSize(winSize.iWidth/2,winSize.iHeight); + TRect leftHalf(halfSize); + TRect rightHalf(TPoint(halfSize.iWidth,0),halfSize); + TRect leftEllipse(leftHalf); + leftEllipse.Shrink(4,4); + TRect rightEllipse(rightHalf); + rightEllipse.Shrink(4,4); + // Draw half the screen with redirection on, should only go to redirection test bitmap + // Then draw again with redirection off, this time should go to the screen + // The two steps are drawn with the color of the left/right rectangles swapped. + for(TInt drawStep=0;drawStep<2;drawStep++) + { + TRgb leftColor; + TRgb rightColor; + if (drawStep==0) + { + leftColor=KRgbGreen; + rightColor=KRgbRed; + } + else + { // Turn re-direction off for second time around loop + iRedir->Redirect(CWsRedir::EFrontBuffer, EFalse); + leftColor=KRgbRed; + rightColor=KRgbGreen; + } + testWin.Invalidate(); + testWin.BeginRedraw(); + if (!drawInsideRedraw) + testWin.EndRedraw(); + CWindowGc* testWinGc=TheClient->iGc; + testWinGc->Activate(testWin); + testWinGc->SetBrushColor(leftColor); + testWinGc->SetBrushStyle(CGraphicsContext::ESolidBrush); + testWinGc->DrawRect(leftHalf); + // Call CRP drawer to draw the coloured ellipses + TheClient->iGc->DrawWsGraphic(wsGraphic1->Id(),leftEllipse); + testWinGc->SetBrushColor(rightColor); + testWinGc->DrawRect(rightHalf); + TheClient->iGc->DrawWsGraphic(wsGraphic1->Id(),rightEllipse); + testWinGc->Deactivate(); + if (drawInsideRedraw) + testWin.EndRedraw(); + TheClient->iWs.Flush(); + } + // We now check that the left rect of the re-directed drawing matches the right half + // of the on-screen drawing + CFbsBitmap* screenCopy=new(ELeave) CFbsBitmap; + CleanupStack::PushL(screenCopy); + User::LeaveIfError(screenCopy->Create(screenSize, EColor64K)); + TheClient->iScreen->CopyScreenToBitmap(screenCopy); + match=CompareBitmapArea16Bpp(iFrontCopy,winPos,screenCopy,TPoint(winPos.iX+rightHalf.iTl.iX,winPos.iY),halfSize); + TEST(match); + if (!match) + LOG_MESSAGE6(KLog,screenSize.iWidth,screenSize.iHeight,winSizeMode,redrawMode,modeIndex); + // As a double check also check the right half of the off-screen drawing matches the + // on-screen left half. + match=CompareBitmapArea16Bpp(iFrontCopy,TPoint(winPos.iX+rightHalf.iTl.iX,winPos.iY),screenCopy,winPos,halfSize); + TEST(match); + if (!match) + LOG_MESSAGE6(KLog,screenSize.iWidth,screenSize.iHeight,winSizeMode,redrawMode,modeIndex); + CleanupStack::PopAndDestroy(screenCopy); + } + } + } + CleanupStack::PopAndDestroy(3,wsGraphic1); + + TEST(iNotify1->iResult); + if(iNotify1->iResult==EFalse) + { + INFO_PRINTF1(iNotify1->iError); + } + TEST(iNotify2->iResult); + if(iNotify1->iResult==EFalse) + { + INFO_PRINTF1(iNotify2->iError); + } + } + +#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + +/** +@SYMTestCaseID GRAPHICS-WSERV-0443 + +@SYMDEF INC109263 + +@SYMTestCaseDesc TWindowServerEvent::NotifyDrawer can refer to a deleted array index causing a crash + +@SYMTestPriority High + +@SYMTestStatus Implemented + +@SYMTestActions Cause an event that will generate the following behaviour through TWindowServerEvent::NotifyDrawer() + + The for loop performs the following: + 0) Drawer handler 1: Remove handle 1 ; Drawer handler 2: Do nothing + 1) Drawer handler 1: Remove handle 1,Add handle 1 ; Drawer handler 2: Do nothing + 2) Drawer handler 1: Add handle 1 ; Drawer handler 2: Do nothing + 3) Drawer handler 1: Remove handle 2 ; Drawer handler 2: Do nothing + 4) Drawer handler 1: Remove handle 2,Add handle 2 ; Drawer handler 2: Do nothing + 5) Drawer handler 1: Add handle 2 ; Drawer handler 2: Do nothing + 6) Drawer handler 1: Remove handle 1,Remove handle 2 ; Drawer handler 2: Do nothing + + Repeat with handlers 1 and 2 swapped + +@SYMTestExpectedResults Loops through TWindowServerEvent::NotifyDrawer() should complete without crashing wserv +*/ + +void CTWsGraphs::TestNotifyRemoval() + { + _LIT(KTestEventNotification, "TestDrawerEventHandler"); + INFO_PRINTF1(KTestEventNotification); + ++iSubState; + + for (TInt ii = 0; iiSetBehaviour(ii); //Enable this plugin and set it to an event handling method + iNotify2->SetBehaviour(KNotifyDoNothing); //Add a second drawer handler which is enabled but does nothing + CreateWindowL(); //Change visibility activating the event handlers - Fails if wserv crashes! + iNotify1->SetBehaviour(KNotifyDisable); //Disable plugin if still enabled + iNotify2->SetBehaviour(KNotifyDisable); //Disable plugin if still enabled + DestroyWindowL(); + } + INFO_PRINTF1(_L("Swap handlers")); + for (TInt ii = 0; iiSetBehaviour(KNotifyDoNothing); //Add a first drawer handler which is enabled but does nothing + iNotify1->SetBehaviour(ii); //Enable this plugin and set it to an event handling method + CreateWindowL(); //Change visibility activating the event handlers - Fails if wserv crashes! + iNotify2->SetBehaviour(KNotifyDisable); //Disable plugin if still enabled + iNotify1->SetBehaviour(KNotifyDisable); //Disable plugin if still enabled + DestroyWindowL(); + } + + TEST(ETrue); // If the test has failed WServ will have paniced. + } + +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA +/** +@SYMTestCaseID GRAPHICS-WSERV-0491 +@SYMPREQ PREQ39 +@SYMTestPriority High +@SYMTestCaseDesc Draw using a ECom-plugin which has direct access to the screen/OSB buffer +@SYMTestActions Create the plugin + Draw using the plugin + Update the position of the white line to line 70 and test + Update the position of the white line to line 80 and test +@SYMTestExpectedResults White lines are drawn on the correct positions. +*/ +void CTWsGraphs::TestMWsUiBufferL() + { + const TInt KWhiteLinePos = 70; + const TRect KBlueRect(TPoint(50,50),TSize(100,100)); + + // Construct and setup window to be drawn to + RWindow window1 = RWindow(TheClient->iWs); + CleanupClosePushL(window1); + User::LeaveIfError(window1.Construct(*TheClient->iGroup->GroupWin(),ENullWsHandle)); + TSize winSize=TSize(TheClient->iScreen->SizeInPixels()); + window1.SetExtent(TPoint(0,0),winSize); + window1.Activate(); + + CWsBufferGraphic* graphic = CWsBufferGraphic::NewL(); + CleanupStack::PushL(graphic); + + // Draw inital drawing with a Crp which is blue rect and a white line at line 0 + TheGc->Activate(window1); + TheGc->Clear(); + window1.BeginRedraw(); + TheGc->DrawWsGraphic(graphic->Id(),KBlueRect); + window1.EndRedraw(); + TheGc->Deactivate(); + + TheClient->iWs.Finish(); + User::After(2000000); + + // Update the position of the white line to line 70 + INFO_PRINTF1(_L("Update position of white line to line 70")); + graphic->UpdateWhiteLinePos(KWhiteLinePos); + TheClient->iWs.Finish(); + // Force some delays to wait until the line position changes + User::After(2000000); + //Test white line has been drawn and is in the correct postion + TBool res1 = IsWhiteLine(KWhiteLinePos); + TEST(res1); + + // Update the position of the white line to line 80 + INFO_PRINTF1(_L("Update position of white line to line 80")); + graphic->UpdateWhiteLinePos(KWhiteLinePos+10); + TheClient->iWs.Finish(); + // Force some delays to wait until the line position changes + User::After(2000000); + // Test white line has been drawn and is in the correct postion + TBool res2 = IsWhiteLine(KWhiteLinePos+10); + TEST(res2); + + graphic->Destroy(); + CleanupStack::PopAndDestroy(2, &window1); + } + +// Test whether a line is completely white +TBool CTWsGraphs::IsWhiteLine(TInt aWhiteLinePos) + { + TRgb color; + TPoint pixel; + + for(TInt xPos = 0; xPos < TheClient->iScreen->SizeInPixels().iWidth; xPos++) + { + pixel = TPoint(xPos,aWhiteLinePos); + TheClient->iScreen->GetPixel(color,pixel); + if(color.Red() != 255 && color.Blue() != 255 && color.Green() != 255) + { + return EFalse; + } + } + return ETrue; + } +#endif //TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA + +/** + DoTestL() method, called by the WSERV Test Framework. +*/ +void CTWsGraphs::RunTestCaseL(TInt /*aCurTestCase*/) + { + _LIT(KTest1,"DoTestWsGraphics"); + _LIT(KTest2,"DoTestOOMWsGraphics"); + _LIT(KTest3,"Interface Extension"); + _LIT(KTest4,"Screen Redirection"); + _LIT(KTest5,"TextCursor1"); + _LIT(KTest6,"TextCursor2"); + _LIT(KTest7,"Flicker Redirection"); + _LIT(KTest8,"Event Notification"); + _LIT(KTest9,"Successive Message"); + _LIT(KTest10,"Redirection Using WsBackBuffer"); + _LIT(KTest11,"Group Change"); + _LIT(KTest12,"Frame Rate"); + _LIT(KTest13,"Leak In Service"); + _LIT(KTest14,"Add/Swap GDArray"); + _LIT(KTest15,"Nested Drawer CRP"); + _LIT(KTest16,"Notify Removal"); + _LIT(KTest17,"Screen Mode Change"); + _LIT(KTest18,"UI Buffer"); + _LIT(KTest19,"Graphics Drawer Coverage"); + CFbsBitmap bitmap1; + CFbsBitmap mask1; + CWsGraphicBitmap* bTest=NULL; + TSize screenSize=TheClient->iScreen->SizeInPixels(); + + bitmap1.Create(screenSize,TheClient->iScreen->DisplayMode()); + mask1.Create(screenSize,TheClient->iScreen->DisplayMode()); + ((CTWsGraphsStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); + + switch(++iTest->iState) + { + case 1: +/** + @SYMTestCaseID GRAPHICS-WSERV-0528 +*/ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0528")); + // Launch new process with PROTSERV capability to run CWSGraphics tests in + iTest->LogSubTest(KTest1); + // This process only launches succesfully when _DEBUG is defined for the build, because it depends + // on the existance of debug macros such as _UHEAP_MARK, _UHEAP_MARKEND, _UHEAP_FAILNEXT, ... etc + LaunchNewProcess(KTestExe); + break; + case 2: + { + /** + @SYMTestCaseID GRAPHICS-WSERV-0017 + + @SYMPREQ PREQ1246 + + @SYMDEF DEF081259 + + @SYMTestCaseDesc Out of memery test when creating a CWsGraphic. + + @SYMTestPriority High + + @SYMTestStatus Implemented + + @SYMTestActions Out of memory test when creating a CWsGraphic. + + @SYMTestExpectedResults Whenever an API call fails, it should leave the number + of allocated heap cells unchanged. + */ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0017")); + + iTest->LogSubTest(KTest2); + TInt failRate; + for(failRate=1;;failRate++) + { + __UHEAP_RESET; + __UHEAP_SETFAIL(RHeap::EDeterministic,failRate); + __UHEAP_MARK; + + TRAPD(ret,bTest=CWsGraphicBitmap::NewL(&bitmap1,&mask1)); + TEST((ret==KErrNone || ret==KErrNoMemory)); + if (ret!=KErrNone && ret!=KErrNoMemory) + { + _LIT(KLog,"Failed to create CWsGraphicBitmap error=%d"); + LOG_MESSAGE2(KLog,ret); + } + if (ret!=KErrNone) + { + __UHEAP_MARKEND; + } + else + { + TEST(bTest!=NULL); + if (bTest==NULL) + { + _LIT(KLog,"Object creation didn't leave but returned NULL"); + LOG_MESSAGE(KLog); + } + delete bTest; + bTest=NULL; + __UHEAP_MARKEND; + TLogMessageText logMessageText; + _LIT(KSet,"OOM test succeds after %d allocations."); + logMessageText.Format(KSet,failRate); + LOG_MESSAGE(logMessageText); + break; + } + } + __UHEAP_RESET; + } + break; + case 3: + iTest->LogSubTest(KTest3); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0371")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + + if (TestInterfaceExtensionL()==EWait) + --iTest->iState; +#endif + break; + case 4: + iTest->LogSubTest(KTest4); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0372")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + if (TestScreenRedirectionL()==EWait) + --iTest->iState; +#endif + break; + case 5: + iTest->LogSubTest(KTest5); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0363")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + if (TestTextCursorUnderRedirectionL(ETestStandardTextCursor) == EWait) + --iTest->iState; +#endif + break; + case 6: + iTest->LogSubTest(KTest6); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0363")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + if (TestTextCursorUnderRedirectionL(ETestCustomTextCursor) == EWait) + --iTest->iState; +#endif + break; + case 7: + iTest->LogSubTest(KTest7); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0376")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + if (TestFlickerRedirectionL()==EWait) + --iTest->iState; +#endif + break; + case 8: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0378")); + iTest->LogSubTest(KTest8); + if (TestEventNotificationL()==EWait) + --iTest->iState; + break; + case 9: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0381")); + iTest->LogSubTest(KTest9); + if (TestSuccessiveMessageL()==EWait) + --iTest->iState; + break; + case 10: + iTest->LogSubTest(KTest10); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0527")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA + if(TestRedirectionUsingWsBackBufferL()==EWait) + --iTest->iState; +#endif + break; + case 11: +/** + @SYMTestCaseID GRAPHICS-WSERV-0529 +*/ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0529")); + iTest->LogSubTest(KTest11); + if(TestWindowGroupChangeL()==EWait) + --iTest->iState; + break; + case 12: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0382")); + iTest->LogSubTest(KTest12); + if(TestFrameRateL()==EWait) + --iTest->iState; + break; + case 13: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-LeakInService-0001")); + iTest->LogSubTest(KTest13); + DoTestLeakInServiceL(); + break; + case 14: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-NegAddSwapGDArray-0001")); + iTest->LogSubTest(KTest14); + TestAddSwapGDArrayL(); + break; + case 15: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0438")); + iTest->LogSubTest(KTest15); + TestNestedDrawerCRP(); + break; + case 16: + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0443")); + iTest->LogSubTest(KTest16); + TestNotifyRemoval(); + break; + case 17: + iTest->LogSubTest(KTest17); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0530")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA +/** + @SYMTestCaseID GRAPHICS-WSERV-0530 +*/ + + TestScreenModeChangeL(); +#endif + break; + case 18: + iTest->LogSubTest(KTest18); + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0491")); +#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA + + TestMWsUiBufferL(); +#endif + break; + case 19: + iTest->LogSubTest(KTest19); +/** + @SYMTestCaseID GRAPHICS-WSERV-0531 +*/ + ((CTWsGraphsStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0531")); + TestGraphicDrawerCoverage(); + break; + default: + ((CTWsGraphsStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); + ((CTWsGraphsStep*)iStep)->CloseTMSGraphicsStep(); + TestComplete(); + break; + } + ((CTWsGraphsStep*)iStep)->RecordTestResultL(); + } + +__WS_CONSTRUCT_STEP__(WsGraphs)