sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Surface manager multi-processed test code sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @test sl@0: @internalComponent - Internal Symbian test code sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "tsurfacemanagermultiprocess.h" sl@0: sl@0: _LIT(KSecondProcess,"tsecondprocess.exe"); sl@0: _LIT(KThirdProcess,"tthirdprocess.exe"); sl@0: sl@0: sl@0: CTSurfaceManagerMultiProcess::CTSurfaceManagerMultiProcess(CTestStep* aStep): sl@0: CTGraphicsBase(aStep) sl@0: { sl@0: } sl@0: sl@0: CTSurfaceManagerMultiProcess::~CTSurfaceManagerMultiProcess() sl@0: { sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::RunTestCaseL(TInt aCurTestCase) sl@0: { sl@0: TInt procHandles1 =0; sl@0: TInt threadHandles1=0; sl@0: RThread().HandleCount(procHandles1, threadHandles1); sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); sl@0: sl@0: switch(aCurTestCase) sl@0: { sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0083 sl@0: @SYMPREQ PREQ 1879,PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test mapping a surface created in the existing shared chunk to a different process sl@0: Process 1: Create a surface in a new shared chunk with valid attributes sl@0: Process 1: Map the surface in the current process to get the chunk handle. sl@0: Process 1: Create another surface in the existing chunk (rotation of the first) sl@0: Process 2: Open and Map the second surface in and get the second chunk handles sl@0: Process 2: Check these two chunks handles are different sl@0: Process 2: Get the pixel start address of the pixel data for the second surface via the second chunk handle and write a number to it sl@0: Process 1: Get the pixel start address of the pixel data for the first surface via the first chunk handle and read the number. sl@0: Process 1: Check the number is identical to what we write to in the second process. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults Mapping one surface created in the existing shared chunk to the other process will not alter the surface chunk memory sl@0: */ sl@0: case 1: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0083")); sl@0: TestMapSurfaceExistinChunkL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0084 sl@0: @SYMPREQ PREQ 1879,PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test that the API SynchronizeCache() behaves correctly in the multi-process case. sl@0: Process 1: Create the surface in a new shared chunk with valid creation attributes. The cache attribute is set to ECached. sl@0: Process 2: Open the surface and map it in the current process to get the chunk handle sl@0: Process 2: Synchronise the cache before the hardware writes to the buffer. Pass TSyncOperation::ESyncBeforeHandwareWrite, valid buffer number and surfaceID in SynchronizeCache() sl@0: Process 2: Synchronise again the cache after the hardware write the buffer. Pass TSyncOperation::ESyncAfterHandwareWrite, valid buffer number and surfaceID in SynchronizeCache() sl@0: Process 1: Synchronise again the cache before the hardware reads the buffer. Pass TSyncOperation::ESyncBeforeHardwareRead, valid buffer number and surfaceID in SynchronizeCache() sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults All synchronisation operation return KErrNone, the surface memory is synchronised properly with cached contents. sl@0: */ sl@0: case 2: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0084")); sl@0: TestSynchronizeCacheMultiProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0046 sl@0: @SYMPREQ PREQ 1879,PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Testing the behaviour of closing driver channels in multiple processes when the last channel to the device driver is closed sl@0: Process 1: Open a channel called as SurfaceManager1 to the LDD by calling RSurfaceManager::Open() sl@0: Process 1: Create a surface SurfaceID1 using SurfaceManager1 sl@0: Process 1: Open another channel called as SurfaceManager2 to the LDD sl@0: Process 1: Create another surface SurfaceID2 using SurfaceManager2 sl@0: Process 1: Open SurfaceID1 using both SurfaceManager1 and SurfaceManager2 sl@0: Process 1: Open SurfaceID2 using both SurfaceManager1 and SurfaceManager2 sl@0: Process 2: Open a channel to the LDD and open the surfaceID1 in the process sl@0: Process 1: Close both channels to the LDD SurfaceManager1 and SurfaceManager2 sl@0: Process 2: Call SurfaceInfo() on surfaceID1 and check the return is KErrNone. Call SurfaceInfo() on surfaceID2 and check it returns KErrArgument. sl@0: Process 1: Reopen the channel to the LDD. Call SurfaceInfo() on surfaceID1. The return value is KErrNone. Call SurfaceInfo() on surfaceID2. The return value is KErrArgument. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults If all the channels to the driver are closed in a process, the surfaces which have been opened in the other process will not be closed. They are still usable when the first process connects to the driver again. sl@0: */ sl@0: case 3: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0046")); sl@0: TestCloseChannelsMultiProcess1L(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0047 sl@0: @SYMPREQ PREQ 1879,PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Testing the behaviour of closing driver channels and surfaces when the process is killed sl@0: Process 2: Open a channel called as SurfaceManager1 to the LDD by calling RSurfaceManager::Open() sl@0: Process 2: Create a surface SurfaceID1 using SurfaceManager1 sl@0: Process 2: Open another channel called as SurfaceManager2 to the LDD sl@0: Process 2: Create another surface SurfaceID2 using SurfaceManager2 sl@0: Process 2: Open SurfaceID1 using both SurfaceManager1 and SurfaceManager2 sl@0: Process 2: Open SurfaceID2 using both SurfaceManager1 and SurfaceManager2 sl@0: Process 1: Open a channel called as SurfaceManager3 to the LDD and open the surfaceID1 in the process sl@0: Process 2: Kill the process sl@0: Process 1: Call OpenSurface() on surfaceID1 using SurfaceManager3 and check it returns KErrNone, as the surfaceID1 is still open sl@0: Process 1: Call OpenSurface() on surfaceID2 using SurfaceManager3 and check it returns KErrArgument, as the surfaceID2 is already deleted sl@0: Process 1: Close surfaceID1 and SurfaceManager3 sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults When the last channel to the surface manager by the process exiting, the surface manager will automatically close the surfaces which are open in that process. Any surfaces which were only open in that process will be deleted. sl@0: */ sl@0: case 4: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0047")); sl@0: TestCloseChannelsMultiProcess2L(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0048 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Multiprocess API testing for getting information using SurfaceInfo sl@0: Process 1: Create the Surface sl@0: Process 2: Receive the Surface Id sl@0: Process 2: Receive the attributes expected to be used by the surface sl@0: Process 2: Open the surface using the id sl@0: Process 2: Map the surface sl@0: Process 2: Call SurfaceInfo to get the attributes of the Surface sl@0: Process 2: Check if these are equal to the ones received. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults The surface can be successfully transmitted between processes sl@0: */ sl@0: case 5: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0048")); sl@0: TestSurfaceInfoUsingSurfaceIdL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0049 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Multiprocess API testing for opening the Surface using SurfaceId sl@0: Priocess 1: Create the surface sl@0: Process 2: Receive the Surface id sl@0: Process 2: Open the Surface using the stored SurfaceId sl@0: Process 2: Check that it returns KErrNone sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface() sl@0: @SYMTestExpectedResults Check that opening the surface using a recieved id returns KErrNone sl@0: */ sl@0: case 6: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0049")); sl@0: TestOpeningSurfaceUsingSurfaceIdL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0050 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Multiprocess test for opening the surface (OpenSurface negative test) sl@0: Receive a Surface Id from another process sl@0: Change Surface Id by sl@0: 1. adding 500 to the SurfaceId sl@0: 2. making the Surface ID negative sl@0: 3. converting the type of the Surface ID to EInvalidSurface sl@0: Call OpenSurface using the new SurfaceId sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface() sl@0: @SYMTestExpectedResults Check that opening the surface using a modified id returns KErrArgument sl@0: */ sl@0: case 7: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0050")); sl@0: TestOpenSurfaceInvalidParamsL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0051 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Closing an unopened surface in a second process sl@0: Process 1: Create Surface sl@0: Process 2: Close Surface sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface() sl@0: @SYMTestExpectedResults Check that CloseSurface() returns KErrAccessDenied sl@0: */ sl@0: case 8: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0051")); sl@0: TestClosingUnopenedSurfaceL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0052 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Accessing an unopened surface in a second process give KErrArgument sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults The surface cant be accessed/closed if it is not opened first in another process. sl@0: */ sl@0: case 9: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0052")); sl@0: TestSurfaceInfoUnopenedSurfaceL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0053 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Create, Open and Close in 3 different processes, sl@0: leaves surface accessible in first 2 processes sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults The surface cant be accessed/closed if it is not opened first in another process. sl@0: */ sl@0: case 10: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0053")); sl@0: CreateOpenCloseThreeProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0054 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test surface can be accessed when creating process dies sl@0: Process 2: Create Surface sl@0: Process 1: Open Surface sl@0: Process 2: Kill Process sl@0: Process 1: Map Surface sl@0: Process 1: Surface Info sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults It is expected that the surface can be accessed when creating process dies sl@0: */ sl@0: case 11: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0054")); sl@0: TestSurfaceAccessWhenCreatingProcessDiesL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0055 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test surface can be closed when creating process dies sl@0: Process 2: Create Surface sl@0: Process 1: Open Surface sl@0: Process 2: Kill Process sl@0: Process 1: Close Surface sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults It is expected that the surface can be closed when creating process dies sl@0: */ sl@0: case 12: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0055")); sl@0: TestClosingSurfaceWhenCreatingProcessDiesL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0056 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test surface can be closed from third process when sl@0: creating process dies and second process closes sl@0: Process 2: Create Surface sl@0: Process 1: Open Surface sl@0: Process 3: Open Surface sl@0: Process 2: Kill Process sl@0: Process 1: Close Surface - KErrNone sl@0: Process 3: Close Surface - KErrNone sl@0: Process 3: Open Surface - KErrArgument sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults It is expected that surface can be closed from third process when sl@0: creating process dies and second process closes sl@0: */ sl@0: case 13: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0056")); sl@0: TestCloseSurfaceInThirdProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0057 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test surface can't be accessed in a second process when open sl@0: and closed in the first process. sl@0: Process 2: Create Surface sl@0: Process 1: Open Surface sl@0: Process 1: Close Surface sl@0: Process 2: Kill Process sl@0: Process 1: Open Surface sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults It is expected that test surface can't be accessed when closed (2process) sl@0: */ sl@0: case 14: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0057")); sl@0: TestNoAccessWhenSurfaceClosedTwoProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0058 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test closing on one process doesn't prevent opening on other processes, sl@0: provided one process still owns surface sl@0: Process 1: Create Surface sl@0: Process 2: Open Surface sl@0: Process 2: Close Surface sl@0: Process 3: Open Surface - KErrNone sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults It is expected that closing on one process doesn't prevent opening on other processes, sl@0: provided one process still owns surface sl@0: */ sl@0: case 15: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0058")); sl@0: TestOpeningOnProcessAfterClosingOnOtherL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0059 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test closing on one process doesn't prevent access on other sl@0: processes, provided one process still owns surface sl@0: Process 1: Create Surface sl@0: Process 2: Open Surface sl@0: Process 2: Close Surface sl@0: Process 1: Map Surface - KErrNone sl@0: Process 1: SurfaceInfo - KErrNone sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface(), MapSurface(), SurfaceInfo() sl@0: @SYMTestExpectedResults It is expected that closing on one process doesn't prevent access on other sl@0: */ sl@0: case 16: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0059")); sl@0: TestAccessAfterClosingL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0060 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test closing a surface in the creating process when it sl@0: has already been closed in a second process sl@0: Process 1: Create Surface sl@0: Process 2: Open Surface sl@0: Process 2: Close Surface sl@0: Process 1: Close Surface sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults Check Close Surface in process 1 returns KErrNone sl@0: */ sl@0: case 17: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0060")); sl@0: TestClosingAfterClosingOnOtherProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0061 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test a surface cannot be accessed in a second process if not opened sl@0: Process 1: Create Surface sl@0: Process 2: Map Surface sl@0: Process 2: Surface Info sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() sl@0: @SYMTestExpectedResults Check Map Surface and SurfaceInfo in the second process return KErrAccessDenied sl@0: */ sl@0: case 18: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0061")); sl@0: TestErrSufaceAccessNotOpenL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0062 sl@0: @SYMPREQ PREQ1007 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test surface buffers written to in one process can be read from in another sl@0: Process 1: Create Surface sl@0: Process 1: Map Surface sl@0: Process 1: Write to buffer sl@0: Process 2: Open the surface sl@0: Process 2: Read from buffer sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),MapSurface(), OpenSurface() sl@0: @SYMTestExpectedResults Value written to buffer in process 1 is equal to value retrieved from buffer in process 2. sl@0: */ sl@0: case 19: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0062")); sl@0: TestReadFromBufferInSecondProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0063 sl@0: @SYMPREQ PREQ1007, PREQ 1879 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test that the API GetSurfaceHint() behaves correctly in the multi-process case. sl@0: Process 1: Create the surface in a new shared chunk with valid creation attributes. sl@0: Process 2: Set a THintPair with a key value set to 0x124580 and value set to 300, iMutable set to ETrue. sl@0: Process 2: Call GetSurfaceHint()and Check it returns KErrAccessDenied sl@0: Process 2: Open the surface and then Call SetSurfaceHint(), Check it returns KErrNone. sl@0: Process 2: Call GetSurfaceHint() to retrieve the THintPair with the key value 0x124578 sl@0: Check the THintPair has the iValue set to 20 and iMutable set to ETrue. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), GetSurfaceHint() sl@0: @SYMTestExpectedResults GetSurfaceHint() behaves properly in the multiprocess. sl@0: */ sl@0: case 20: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0063")); sl@0: TestGetSurfaceHintMultiProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0064 sl@0: @SYMPREQ PREQ1007, PREQ 1879 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test that the API SetSurfaceHint() behaves correctly in the multi-process case. sl@0: Process 1: Create the surface in a new shared chunk with valid creation attributes. sl@0: Process 2: Set a THintPair with a key value set to 0x124580 and value set to 300, iMutable set to ETrue. sl@0: Process 2: Call SetSurfaceHint()and Check it returns KErrAccessDenied sl@0: Process 2: Open the surface and then Call SetSurfaceHint(), Check it returns KErrNone. sl@0: Process 2: Call GetSurfaceHint() to retrieve the THintPair with the key value 0x124578 sl@0: Check the retrieved THintPair has the iValue set to 300. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), SetSurfaceHint(),GetSurfaceHint() sl@0: @SYMTestExpectedResults SetSurfaceHint() behaves properly in the multiprocess. sl@0: */ sl@0: case 21: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0064")); sl@0: TestSetSurfaceHintMultiProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0065 sl@0: @SYMPREQ PREQ1007, PREQ 1879 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Test that the API AddSurfaceHint() behaves correctly in the multi-process case. sl@0: Process 1: Process 1: Create the surface in a new shared chunk with valid creation attributes. sl@0: Process 2: Set a THintPair with a key value set to 0x124580 and value set to 300, iMutable set to ETrue. sl@0: Process 2: Call AddSurfaceHint()and Check it returns KErrAccessDenied sl@0: Process 2: Open the surface and then Call AddSurfaceHint(), Check it returns KErrNone. sl@0: Process 2: Call GetSurfaceHint() to retrieve the THintPair with the key value 0x124580 sl@0: Check the retrieved THintPair has the iValue set to 300 and iMutable set to ETrue. sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), GetSurfaceHint(), AddSurfaceHint() sl@0: @SYMTestExpectedResults AddSurfaceHint() behaves properly in the multiprocess. sl@0: */ sl@0: case 22: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0065")); sl@0: TestAddSurfaceHintMultiProcessL(); sl@0: break; sl@0: /** sl@0: @SYMTestCaseID GRAPHICS-SURFACEMANAGER-0066 sl@0: @SYMPREQ PREQ1007, PREQ 1879 sl@0: @SYMREQ REQ8222,REQ8223 sl@0: @SYMTestPriority High sl@0: @SYMTestCaseDesc Testing how OpenSurface() and AddConnection() behanves under out of memory conditions sl@0: Process 1: Create a surface and pass it in to the second process sl@0: Process 2: Open the surface manager, inducing a kernel alloc failure on each possible kernel alloc with the use of MACRO(__KHEAP_SETFAIL). sl@0: Check that returns KerrNoMemory sl@0: Process 2: Call OpenSurface() on the new shared chunk, inducing a kernel alloc failure on each possible kernel alloc with the use of MACRO(__KHEAP_SETFAIL). sl@0: Check that returns KerrNoMemory sl@0: @SYMTestStatus Implemented sl@0: @SYMTestActions Call CreateSurface(),OpenSurface(), RSurfaceManager::Open() sl@0: @SYMTestExpectedResults OpenSurface and AddConnection should return KerrNoMemory. sl@0: */ sl@0: case 23: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); sl@0: #ifdef _DEBUG sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0066")); sl@0: TestOutofMemoryCasesL(); sl@0: #endif sl@0: break; sl@0: default: sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->CloseTMSGraphicsStep(); sl@0: TestComplete(); sl@0: break; sl@0: } sl@0: ((CTSurfaceManagerMultiProcessStep*)iStep)->RecordTestResultL(); sl@0: // Handle check sl@0: TInt procHandles2 =0; sl@0: TInt threadHandles2=0; sl@0: RThread().HandleCount(procHandles2,threadHandles2); sl@0: if (threadHandles1 != threadHandles2) sl@0: { sl@0: User::Leave(KErrGeneral); // Thread-owned handles not closed sl@0: } sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestMapSurfaceExistinChunkL() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Test mapping a surface created in the existing shared chunk to a different process\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: attributes.iSize = TSize(100,100); sl@0: attributes.iBuffers = 1; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 400; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = 2; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: attributes.iMappable = ETrue; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: //store all the attributes sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: TEST(KErrNone == surfaceManager.SurfaceInfo(surfaceId, infoBuf)); sl@0: sl@0: //Map the surface in the current processs sl@0: RChunk handle; sl@0: TEST(KErrNone == surfaceManager.MapSurface(surfaceId,handle)); sl@0: sl@0: // Cache, Contiguous and Alignment attributes are ignored for the already existing chunks sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buff; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributesNew = buff(); sl@0: sl@0: attributesNew.iSize = TSize(480,16); sl@0: attributesNew.iBuffers = 2; // number of buffers in the surface sl@0: attributesNew.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributesNew.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributesNew.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributesNew.iMappable = ETrue; sl@0: sl@0: attributes.iHintCount = 1; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: sl@0: attributesNew.iAlignment = RSurfaceManager::EPageAligned; sl@0: attributesNew.iOffsetBetweenBuffers = 0; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceIdNew; sl@0: // Test create surface doesn't return an error sl@0: // For the time being KErrArgument will be returned as the core codes are sl@0: // not ready to check the passed in shared chunk handle. sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buff, surfaceIdNew, handle)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECheckHandle)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: sl@0: // Get the adress of this chunk of memory sl@0: TUint8* surfaceAdd = handle.Base(); sl@0: TUint8* bufferAdd = surfaceAdd + attributes.iOffsetToFirstBuffer; sl@0: sl@0: // Reads from first buffer, and test the value is written sl@0: TInt temp = *bufferAdd; sl@0: TEST(temp == 20); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: handle.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestSynchronizeCacheMultiProcessL() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Test that the API SynchronizeCache() behaves correctly in the multi-process case\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(480,16); sl@0: attributes.iBuffers = 2; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributes.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ESyncOperation)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: // Only four tests were carried out in the second process sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestCloseChannelsMultiProcess1L() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Testing the behaviour of closing driver channels in multiple processes when the last channel to the device driver is closed\r\n")); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManagerOne; sl@0: // Close the surface manager without opening it first sl@0: INFO_PRINTF1(_L("Close the surface manager without opening it first\r\n")); sl@0: // Is this Ok? sl@0: // surfaceManagerOne.Close(); sl@0: sl@0: User::LeaveIfError(surfaceManagerOne.Open()); sl@0: CleanupClosePushL(surfaceManagerOne); sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: attributes.iSize = TSize(280,301); sl@0: attributes.iBuffers = 1; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 1; sl@0: attributes.iOffsetToFirstBuffer = 1; sl@0: attributes.iAlignment = 1; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create a surface sl@0: TSurfaceId surfaceIdOne; sl@0: TEST(KErrNone == surfaceManagerOne.CreateSurface(buf, surfaceIdOne)); sl@0: sl@0: RSurfaceManager surfaceManagerTwo; sl@0: User::LeaveIfError(surfaceManagerTwo.Open()); sl@0: CleanupClosePushL(surfaceManagerTwo); sl@0: // Create a surface sl@0: TSurfaceId surfaceIdTwo; sl@0: TEST(KErrNone == surfaceManagerTwo.CreateSurface(buf,surfaceIdTwo)); sl@0: sl@0: TEST(KErrNone == surfaceManagerOne.OpenSurface(surfaceIdTwo)); sl@0: TEST(KErrNone == surfaceManagerTwo.OpenSurface(surfaceIdOne)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceIdOne; sl@0: iInfo2.iSurfaceManager = surfaceManagerOne; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceIdOne); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ETestChannelMultiProcess1)); sl@0: process.Resume(); sl@0: CleanupClosePushL(process); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: surfaceManagerOne.Close(); sl@0: surfaceManagerTwo.Close(); sl@0: sl@0: // Pass control off to the second process again sl@0: chunkWrapper->SetId(surfaceIdTwo); sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: sl@0: // Copme back from the second process - find the surfaceId sl@0: // Check that the tests in the second process have passed sl@0: result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFourthTestPassed); sl@0: TEST(result & EFifthTestPassed); sl@0: //More things to check in here sl@0: // TEST(KErrNone == surfaceManagerOne.Open())); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: CleanupStack::PopAndDestroy(5, &sem); sl@0: sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestCloseChannelsMultiProcess2L() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Testing the behaviour of closing driver channels in multiple processes when the last channel to the device driver is closed\r\n")); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ETestChannelMultiProcess2)); sl@0: process.Resume(); sl@0: CleanupClosePushL(process); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Open the chunk wrapper and get the surfaceId sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceIdOne = chunkWrapper->GetId(); sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManagerThree; sl@0: User::LeaveIfError(surfaceManagerThree.Open()); sl@0: CleanupClosePushL(surfaceManagerThree); sl@0: sl@0: TEST(KErrNone == surfaceManagerThree.OpenSurface(surfaceIdOne)); sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: TSurfaceId surfaceIdTwo = chunkWrapper->GetId(); sl@0: sl@0: // Call OpenSurface() on surfaceID1 using SurfaceManager3 and check it returns KErrNone, as the surfaceID1 is still open sl@0: TEST(KErrNone == surfaceManagerThree.OpenSurface(surfaceIdOne)); sl@0: // Call OpenSurface() on surfaceID1 using SurfaceManager3 and check it returns KErrNone, as the surfaceID1 is still open sl@0: TEST(KErrArgument == surfaceManagerThree.OpenSurface(surfaceIdTwo)); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: CleanupStack::PopAndDestroy(4, &sem); sl@0: } sl@0: sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestSurfaceInfoUsingSurfaceIdL() sl@0: { sl@0: INFO_PRINTF1(_L("Receiving a surface and querying SurfaceInfo for surface properties\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: sl@0: // Set attributs for creating the surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes=buf(); sl@0: attributes.iSize = TSize(100,100); sl@0: attributes.iBuffers = 1; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 400; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = 2; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: attributes.iContiguous=ETrue; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iCacheAttrib = RSurfaceManager::ENotCached; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(attributes, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ETestInfoReceivedSurface)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: TEST(result & EFifthTestPassed); sl@0: TEST(result & ESixthTestPassed); sl@0: TEST(result & ESeventhTestPassed); sl@0: TEST(result & EEighthTestPassed); sl@0: TEST(result & ENinthTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestOpeningSurfaceUsingSurfaceIdL() sl@0: { sl@0: INFO_PRINTF1(_L("Test Opening a surface using surfaceId (passed from this to another process)\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: sl@0: // Set attributs for creating the surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes=buf(); sl@0: attributes.iSize = TSize(200,200); sl@0: attributes.iBuffers = 1; sl@0: attributes.iPixelFormat = EUidPixelFormatARGB_1555; sl@0: attributes.iStride = 1600; sl@0: attributes.iOffsetToFirstBuffer = 80; sl@0: attributes.iAlignment = 8; sl@0: attributes.iContiguous = ETrue; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(attributes, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ETestOpenReceivedSurface)); sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the test results of the second process sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestOpenSurfaceInvalidParamsL() sl@0: { sl@0: INFO_PRINTF1(_L("Opening a surface with invalid parameters\r\n")); sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(150,412); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatARGB_1555; // 2bpp sl@0: attributes.iStride = 1000; sl@0: attributes.iOffsetToFirstBuffer = 5; sl@0: attributes.iAlignment = 1; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create a surface - increments reference count by 1 sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ETestOpenSurfaceInvalidParams)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: TRequestStatus status; sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: // Tidy up sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestClosingUnopenedSurfaceL() sl@0: { sl@0: INFO_PRINTF1(_L("Closing an unopened surface in a second process\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,301); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 605; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KThirdProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECloseSurface)); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the result sl@0: TInt result = chunkWrapper->GetThirdProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: } sl@0: sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestSurfaceInfoUnopenedSurfaceL() sl@0: { sl@0: INFO_PRINTF1(_L("Access an unopened surface in a second process\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,301); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 605; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KThirdProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ESurfaceInfo)); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the result sl@0: TInt result = chunkWrapper->GetThirdProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::CreateOpenCloseThreeProcessL() sl@0: { sl@0: INFO_PRINTF1(_L("Create Open close across 3 processes\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,230); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 1100; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process2; sl@0: TEST(KErrNone == process2.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status2 = KRequestPending; sl@0: process2.Logon(status2); sl@0: process2.SetParameter(EMultiProcessSecondSlot, EOpenWaitMap); sl@0: process2.Resume(); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Create a third process sl@0: RProcess process3; sl@0: TEST(KErrNone == process3.Create(KThirdProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status3 = KRequestPending; sl@0: process3.Logon(status3); sl@0: process3.SetParameter(EMultiProcessSecondSlot, ECloseSurface); sl@0: process3.Resume(); sl@0: sl@0: // Let the second process continue its work - calling MapSurface sl@0: sem2.Signal(); sl@0: sl@0: // Call Surface Info on the surface in this process sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: TEST(KErrNone == surfaceManager.SurfaceInfo(surfaceId, infoBuf)); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status2); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Wait for the third process to terminate and chaeck the results sl@0: User::WaitForRequest(status3); sl@0: result = chunkWrapper->GetThirdProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process2.Close(); sl@0: process3.Close(); sl@0: sl@0: CleanupStack::PopAndDestroy(3, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestSurfaceAccessWhenCreatingProcessDiesL() sl@0: { sl@0: INFO_PRINTF1(_L("Test surface can be accessed when creating process dies\r\n")); sl@0: // Create two semaphores sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECreateWaitKill)); sl@0: process.Resume(); sl@0: CleanupClosePushL(process); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Copme back from the second process - find the surfaceId sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceId = chunkWrapper->GetId(); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Open the surface sl@0: TEST(KErrNone == surfaceManager.OpenSurface(surfaceId)); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: // Map Surface sl@0: RChunk handle; sl@0: TEST(KErrNone == surfaceManager.MapSurface(surfaceId, handle)); sl@0: handle.Close(); sl@0: // Surface Info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: TEST(KErrNone == surfaceManager.SurfaceInfo(surfaceId, infoBuf)); sl@0: sl@0: TEST(KErrNone == surfaceManager.CloseSurface(surfaceId)); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: CleanupStack::PopAndDestroy(4, &sem); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestClosingSurfaceWhenCreatingProcessDiesL() sl@0: { sl@0: INFO_PRINTF1(_L("Test surface can be closed when creating process dies\r\n")); sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECreateWaitKill)); sl@0: process.Resume(); sl@0: CleanupClosePushL(process); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Copme back from the second process - find the surfaceId sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceId = chunkWrapper->GetId(); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Open the surface sl@0: TEST(KErrNone == surfaceManager.OpenSurface(surfaceId)); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: TEST(KErrNone == surfaceManager.CloseSurface(surfaceId)); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: CleanupStack::PopAndDestroy(4, &sem); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestCloseSurfaceInThirdProcessL() sl@0: { sl@0: INFO_PRINTF1(_L("Test surface access in a third process\r\n")); sl@0: // Create 2 semaphores for signalling between process 1 and process 2 sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Create a second process sl@0: RProcess process2; sl@0: TEST(KErrNone == process2.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status2 = KRequestPending; sl@0: process2.Logon(status2); sl@0: process2.SetParameter(EMultiProcessSecondSlot, ECreateWaitKill); sl@0: process2.Resume(); sl@0: CleanupClosePushL(process2); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Come back from the second process - find the surfaceId sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceId = chunkWrapper->GetId(); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Open the surface sl@0: TEST(KErrNone == surfaceManager.OpenSurface(surfaceId)); sl@0: sl@0: // Create another two semaphores for signalling between process 1 and process 3 sl@0: RSemaphore sem3; sl@0: TEST(KErrNone == sem3.CreateGlobal(KMultiProcessSemaphore3, initCount)); sl@0: sl@0: RSemaphore sem4; sl@0: TEST(KErrNone == sem4.CreateGlobal(KMultiProcessSemaphore4, initCount)); sl@0: sl@0: // Create a third process sl@0: RProcess process3; sl@0: TEST(KErrNone == process3.Create(KThirdProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status3 = KRequestPending; sl@0: process3.Logon(status3); sl@0: process3.SetParameter(EMultiProcessSecondSlot, EOpenWaitCloseOpen); sl@0: process3.Resume(); sl@0: sl@0: // Passes control to the third process - opens the surface sl@0: sem3.Wait(); sl@0: sl@0: // Pass control to the second process again - kill the process sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the third process to terminate sl@0: User::WaitForRequest(status2); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: // Close the surface sl@0: TEST(KErrNone == surfaceManager.CloseSurface(surfaceId)); sl@0: sl@0: // Pass control to the third process - close the surface sl@0: sem4.Signal(); sl@0: sl@0: // Wait for the third process to terminate sl@0: User::WaitForRequest(status3); sl@0: sl@0: // Check that the tests in the third process have passed sl@0: result = chunkWrapper->GetThirdProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: TEST(result & EFifthTestPassed); sl@0: // TEST(result & ESixthTestPassed); sl@0: sl@0: // Cleanup sl@0: delete chunkWrapper; sl@0: sem3.Close(); sl@0: sem4.Close(); sl@0: process3.Close(); sl@0: sl@0: CleanupStack::PopAndDestroy(4, &sem); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestNoAccessWhenSurfaceClosedTwoProcessL() sl@0: { sl@0: INFO_PRINTF1(_L("Test surface can't be accessed when closed (2process)\r\n")); sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECreateWaitKill)); sl@0: process.Resume(); sl@0: CleanupClosePushL(process); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Come back from the second process - find the surfaceId sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceId = chunkWrapper->GetId(); sl@0: sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: // Open the surface sl@0: TEST(KErrNone == surfaceManager.OpenSurface(surfaceId)); sl@0: sl@0: // Close the surface sl@0: TEST(KErrNone == surfaceManager.CloseSurface(surfaceId)); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the third process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: TEST(KErrArgument == surfaceManager.OpenSurface(surfaceId)); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: CleanupStack::PopAndDestroy(4, &sem); sl@0: } sl@0: void CTSurfaceManagerMultiProcess::TestOpeningOnProcessAfterClosingOnOtherL() sl@0: { sl@0: INFO_PRINTF1(_L("Test closing on one process doesn't prevent opening on another\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,15); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 901; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process2; sl@0: TEST(KErrNone == process2.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status2 = KRequestPending; sl@0: process2.Logon(status2); sl@0: process2.SetParameter(EMultiProcessSecondSlot, EOpenClose); sl@0: process2.Resume(); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Create a third process sl@0: RProcess process3; sl@0: TEST(KErrNone == process3.Create(KThirdProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status3 = KRequestPending; sl@0: process3.Logon(status3); sl@0: process3.SetParameter(EMultiProcessSecondSlot, EOpenSurface); sl@0: process3.Resume(); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status2); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Wait for the third process to terminate sl@0: User::WaitForRequest(status3); sl@0: sl@0: // Test results sl@0: result = chunkWrapper->GetThirdProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process2.Close(); sl@0: process3.Close(); sl@0: CleanupStack::PopAndDestroy(3, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestAccessAfterClosingL() sl@0: { sl@0: INFO_PRINTF1(_L("Test closing doesn't prevent access\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,199); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 711; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iCacheAttrib = RSurfaceManager::ENotCached; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EOpenClose)); sl@0: process.Resume(); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Map Surface sl@0: RChunk handle; sl@0: TEST(KErrNone == surfaceManager.MapSurface(surfaceId, handle)); sl@0: handle.Close(); sl@0: // Surface Info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: TEST(KErrNone == surfaceManager.SurfaceInfo(surfaceId, infoBuf)); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(3, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestClosingAfterClosingOnOtherProcessL() sl@0: { sl@0: INFO_PRINTF1(_L("Test can close in two processes\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,301); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 768; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iCacheAttrib = RSurfaceManager::ENotCached; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EOpenClose)); sl@0: process.Resume(); sl@0: sl@0: // Passes control to the second process sl@0: sem.Wait(); sl@0: sl@0: // Test closing the surface manager sl@0: TEST(KErrNone == surfaceManager.CloseSurface(surfaceId)); sl@0: sl@0: // Pass control off to the second process again sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(3, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestErrSufaceAccessNotOpenL() sl@0: { sl@0: INFO_PRINTF1(_L("Test a surface cannot be accessed in a second process if not opened\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: // Store the attributes used to create the Surface sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(280,301); sl@0: attributes.iBuffers = 3; sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 1400; sl@0: attributes.iOffsetToFirstBuffer = 4; sl@0: attributes.iAlignment = 4; sl@0: attributes.iContiguous=EFalse; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Create a semaphore sl@0: const TInt initCount = 0; sl@0: RSemaphore sem; sl@0: TEST(KErrNone == sem.CreateGlobal(KMultiProcessSemaphore, initCount)); sl@0: CleanupClosePushL(sem); sl@0: RSemaphore sem2; sl@0: TEST(KErrNone == sem2.CreateGlobal(KMultiProcessSemaphore2, initCount)); sl@0: CleanupClosePushL(sem2); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: process.Logon(status); sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EMapSurfaceInfoCantAccess)); sl@0: process.Resume(); sl@0: sl@0: // Passes control to the second process - to test MapSurface and SurfaceInfo sl@0: sem.Wait(); sl@0: sl@0: // Pass control off to the second process again - to allow it to terminate sl@0: sem2.Signal(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(3, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestReadFromBufferInSecondProcessL() sl@0: { sl@0: INFO_PRINTF1(_L("Writing to a buffer and reading from another process\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: // Setup attributes, setting iBuffers to 2 sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(12,80); // w > 0, h > 0 sl@0: attributes.iBuffers = 2; // > 0, <= 4 sl@0: attributes.iPixelFormat = EUidPixelFormatARGB_1555; // 2bpp sl@0: attributes.iStride = 25; // > 0, > width * bpp sl@0: attributes.iOffsetToFirstBuffer = 20; // > 0, divisible by alignment sl@0: attributes.iAlignment = 4; // 1 || 2 || 4 || 8 sl@0: attributes.iContiguous = ETrue; sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124545), 50, EFalse); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, EFalse); sl@0: sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iCacheAttrib = RSurfaceManager::ENotCached; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: // Map the surface to a chunk of memory sl@0: RChunk handle; sl@0: TEST(KErrNone == surfaceManager.MapSurface(surfaceId, handle)); sl@0: CleanupClosePushL(handle); sl@0: sl@0: // Get the adress of this chunk of memory sl@0: TUint8* surfaceAdd = handle.Base(); sl@0: TUint8* bufferAdd = surfaceAdd + attributes.iOffsetToFirstBuffer; sl@0: sl@0: // Write to the buffer sl@0: *bufferAdd = 134; sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: // Kick off the process and wait for it to complete sl@0: TRequestStatus status = KRequestPending; sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EReadFromBuffer)); sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: sl@0: // Wait for the second process to terminate sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check that the tests in the second process have passed sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: sl@0: // Delete the chunkWrapper and the semaphore sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(2, &surfaceManager); sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestGetSurfaceHintMultiProcessL() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Test that the GetSurfaceHint() behaves properly in the multiprocesses\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(480,16); sl@0: attributes.iBuffers = 2; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributes.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EGetSurfaceHint)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: // Only four tests were carried out in the second process sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestSetSurfaceHintMultiProcessL() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Test that the SetSurfaceHint() behaves properly in the multiprocesses\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(480,16); sl@0: attributes.iBuffers = 2; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributes.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ESetSurfaceHint)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: // Only four tests were carried out in the second process sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestAddSurfaceHintMultiProcessL() sl@0: { sl@0: // Create a surface in a new shared chunk sl@0: INFO_PRINTF1(_L("Test that the AddSurfaceHint() behaves properly in the multiprocesses\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(480,16); sl@0: attributes.iBuffers = 2; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributes.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, EAddSurfaceHint)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: // Only four tests were carried out in the second process sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: TEST(result & EThirdTestPassed); sl@0: TEST(result & EFourthTestPassed); sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcess::TestOutofMemoryCasesL() sl@0: { sl@0: sl@0: RDebug::Printf("test 45 start"); sl@0: INFO_PRINTF1(_L("Test OutofMemory conditions in OpenSurface()and AddConnection()\r\n")); sl@0: // Open the surface manager sl@0: RSurfaceManager surfaceManager; sl@0: User::LeaveIfError(surfaceManager.Open()); sl@0: CleanupClosePushL(surfaceManager); sl@0: sl@0: TRequestStatus status; sl@0: // Setup attributes sl@0: sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(480,16); sl@0: attributes.iBuffers = 2; // number of buffers in the surface sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp sl@0: attributes.iStride = 1013; // Number of bytes between start of one line and start of next sl@0: attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data sl@0: attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned sl@0: sl@0: RSurfaceManager::THintPair hints[2]; // two hint pairs specified sl@0: attributes.iHintCount = 2; sl@0: attributes.iSurfaceHints = hints; sl@0: hints[0].Set(TUid::Uid(0x124578), 25, ETrue); sl@0: hints[1].Set(TUid::Uid(0x237755), 50, ETrue); sl@0: sl@0: attributes.iContiguous = ETrue; sl@0: attributes.iCacheAttrib = RSurfaceManager::ECached; sl@0: attributes.iOffsetBetweenBuffers = 0; sl@0: attributes.iMappable = ETrue; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TSurfaceId surfaceId; sl@0: sl@0: // Test create surface doesn't return an error sl@0: TEST(KErrNone == surfaceManager.CreateSurface(buf, surfaceId)); sl@0: sl@0: iInfo2.iSurfaceId = surfaceId; sl@0: iInfo2.iSurfaceManager = surfaceManager; sl@0: // Create a TCleanupItem object sl@0: CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); sl@0: sl@0: // Save the surfaceId to the shared chunk sl@0: CChunkWrapper* chunkWrapper = CChunkWrapper::CreateL(KSharedChunkName, KSharedChunkSize, KSharedChunkSize); sl@0: chunkWrapper->SetId(surfaceId); sl@0: CleanupStack::Pop(); sl@0: sl@0: // Create a second process sl@0: RProcess process; sl@0: TEST(KErrNone == process.Create(KSecondProcess, KNullDesC)); sl@0: sl@0: // Specify the test for the second process sl@0: TEST(KErrNone == process.SetParameter(EMultiProcessSecondSlot, ECheckOutofMemory)); sl@0: // Kick off the second process and wait for it to complete sl@0: // The actual testing is done in the second process sl@0: process.Logon(status); sl@0: process.Resume(); sl@0: User::WaitForRequest(status); sl@0: sl@0: // Check the results of the second process tests sl@0: TInt result = chunkWrapper->GetSecondProcessResults(); sl@0: // Only four tests were carried out in the second process sl@0: TEST(result & EFirstTestPassed); sl@0: TEST(result & ESecondTestPassed); sl@0: sl@0: // Delete the chunkWrapper sl@0: delete chunkWrapper; sl@0: process.Close(); sl@0: CleanupStack::PopAndDestroy(1, &surfaceManager); sl@0: sl@0: } sl@0: sl@0: //-------------- sl@0: __CONSTRUCT_STEP__(SurfaceManagerMultiProcess) sl@0: sl@0: void CTSurfaceManagerMultiProcessStep::TestSetupL() sl@0: { sl@0: } sl@0: sl@0: void CTSurfaceManagerMultiProcessStep::TestClose() sl@0: { sl@0: } sl@0: