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: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "tsmgmultprocessshared.h" sl@0: sl@0: LOCAL_D RTest test(_L("TReceiveSurface")); sl@0: sl@0: sl@0: class CTestDriverSecondProcess : public CTestDriver sl@0: { sl@0: public: sl@0: CTestDriverSecondProcess(); sl@0: ~CTestDriverSecondProcess(); sl@0: void ConstructL(); sl@0: static CTestDriverSecondProcess* NewL(); sl@0: public: sl@0: void TestMultipleChannelsInSecondProcess2(); sl@0: void TestMultipleChannelsInSecondProcess1(); sl@0: void TestCheckSyncOperation(); sl@0: void TestCheckHandleInSecondProcess(); sl@0: void TestSurfaceInfoUsingSurfaceId(); sl@0: void TestOpeningSurfaceUsingSurfaceId(); sl@0: void TestOpeningSurfaceInvalidParams(); sl@0: void OpenWaitMap(); sl@0: void CreateWaitKill(); sl@0: void OpenClose(); sl@0: void MapSurfaceInfoCantAccess(); sl@0: void TestReadFromBufferInSecondProcess(); sl@0: void TestGetSurfaceHint(); sl@0: void TestSetSurfaceHint(); sl@0: void TestAddSurfaceHint(); sl@0: void TestOutofMemory(); sl@0: private: sl@0: RSurfaceManager iSurfaceManagerTwo; sl@0: }; sl@0: sl@0: CTestDriverSecondProcess::CTestDriverSecondProcess():CTestDriver() sl@0: { sl@0: } sl@0: sl@0: CTestDriverSecondProcess::~CTestDriverSecondProcess() sl@0: { sl@0: iSurfaceManagerTwo.Close(); sl@0: } sl@0: sl@0: void CTestDriverSecondProcess::ConstructL() sl@0: { sl@0: CTestDriver::ConstructL(); sl@0: User::LeaveIfError( iSurfaceManagerTwo.Open()); sl@0: } sl@0: sl@0: CTestDriverSecondProcess* CTestDriverSecondProcess::NewL() sl@0: { sl@0: CTestDriverSecondProcess * driver = new (ELeave) CTestDriverSecondProcess(); sl@0: CleanupStack::PushL(driver); sl@0: driver->ConstructL(); sl@0: CleanupStack::Pop(driver); sl@0: return driver; sl@0: } sl@0: sl@0: void CTestDriverSecondProcess::TestMultipleChannelsInSecondProcess2() 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: 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 the surface sl@0: TSurfaceId surfaceIdOne; sl@0: if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceIdOne)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceIdTwo; sl@0: if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceIdTwo)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceIdTwo)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManagerTwo.OpenSurface(surfaceIdOne)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: // Put the surfaceId onto the shared chunk sl@0: iChunkWrapper->SetId(surfaceIdOne); sl@0: sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: sem.Signal(); sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sem2.Wait(); sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: // // Put the surfaceId onto the shared chunk sl@0: iChunkWrapper->SetId(surfaceIdTwo); sl@0: sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: } sl@0: sl@0: void CTestDriverSecondProcess::TestMultipleChannelsInSecondProcess1() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceIdOne = iChunkWrapper->GetId(); sl@0: sl@0: // Open the surface using the surfaceId - check that it returns KErrNone sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceIdOne)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: sem.Signal(); sl@0: sem2.Wait(); sl@0: sl@0: // Get the surface info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceIdOne, infoBuf)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: TSurfaceId surfaceIdTwo = iChunkWrapper->GetId(); sl@0: sl@0: if(KErrArgument == iSurfaceManager.SurfaceInfo(surfaceIdTwo, infoBuf)) sl@0: { sl@0: iTestResult |= EFifthTestPassed; sl@0: } sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: } sl@0: sl@0: void CTestDriverSecondProcess::TestCheckSyncOperation() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: // Check it returns KErrAccessDenied when the surface is not Open sl@0: TInt bufferNo = 1; sl@0: sl@0: RSurfaceManager::TSyncOperation syncOperation = RSurfaceManager::ESyncBeforeNonCPURead; sl@0: sl@0: if(KErrAccessDenied == iSurfaceManager.SynchronizeCache(surfaceId, bufferNo,syncOperation)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Open the surface using the surfaceId - check that it returns KErrNone sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Map the surface sl@0: RChunk handle; sl@0: sl@0: if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManager.SynchronizeCache(surfaceId, bufferNo,syncOperation)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: // Close the chunkwrapper, handle and the surface manager sl@0: handle.Close(); sl@0: sl@0: } sl@0: void CTestDriverSecondProcess::TestCheckHandleInSecondProcess() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: // Open the surface using the surfaceId - check that it returns KErrNone sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Map the surface sl@0: RChunk handle; sl@0: sl@0: if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Get the surface info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceId, infoBuf)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: // Get the adress of this chunk of memory sl@0: TUint8* surfaceAdd = handle.Base(); sl@0: TInt offsetToFirstBuffer; sl@0: if(KErrNone == iSurfaceManager.GetBufferOffset(surfaceId, 0, offsetToFirstBuffer)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: TUint8* bufferAdd = surfaceAdd + offsetToFirstBuffer; sl@0: sl@0: // Write to the first buffer, and test the value is written sl@0: *bufferAdd = 20; sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: // Close the chunkwrapper, handle and the surface manager sl@0: handle.Close(); sl@0: } sl@0: sl@0: /** sl@0: Test 18. Receiving a surface and querying SurfaceInfo for surface properties sl@0: sl@0: Process 1: Create the Surface sl@0: Process 2: Receive the Surface Id sl@0: Process 2: Receive the attributes used to create 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: Check if these are equal to the ones received. sl@0: sl@0: @see TestSurfaceInfoUsingSurfaceIdL() in tsurfacemanager.cpp sl@0: */ sl@0: void CTestDriverSecondProcess::TestSurfaceInfoUsingSurfaceId() sl@0: { sl@0: // Set attributes for the surface - these are expected attributes in the second process 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: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: // Open the surface using the surfaceId - check that it returns KErrNone sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Map the surface sl@0: RChunk handle; sl@0: sl@0: if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Get the surface info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceId, infoBuf)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: TInt offsetToFirstBuffer; sl@0: if(KErrNone == iSurfaceManager.GetBufferOffset(surfaceId, 0, offsetToFirstBuffer)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sl@0: if(info.iSize == attributes.iSize) sl@0: { sl@0: iTestResult |= EFifthTestPassed; sl@0: } sl@0: if(info.iBuffers == attributes.iBuffers) sl@0: { sl@0: iTestResult |= ESixthTestPassed; sl@0: } sl@0: if(info.iPixelFormat == attributes.iPixelFormat) sl@0: { sl@0: iTestResult |= ESeventhTestPassed; sl@0: } sl@0: if(info.iStride == attributes.iStride) sl@0: { sl@0: iTestResult |= EEighthTestPassed; sl@0: } sl@0: if(offsetToFirstBuffer >= attributes.iOffsetToFirstBuffer) sl@0: { sl@0: iTestResult |= ENinthTestPassed; sl@0: } sl@0: if(info.iContiguous == attributes.iContiguous) sl@0: { sl@0: iTestResult |= ETenthTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: // Close handle sl@0: handle.Close(); sl@0: } sl@0: sl@0: /** sl@0: Test 19. Opening a surface using surfaceId sl@0: 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 Surface id sl@0: Check OpenSurface returns KErrNone sl@0: sl@0: @see TestOpeningSurfaceUsingSurfaceIdL() in tsurfacemanager.cpp sl@0: */ sl@0: void CTestDriverSecondProcess::TestOpeningSurfaceUsingSurfaceId() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: // CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue); sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: // Open the surface using the surfaceId - check that it returns KErrNone sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: } sl@0: sl@0: /** sl@0: Test 20. Opening a surface using invalid surfaceId sl@0: sl@0: Process 1:Create the surface sl@0: Process 2: Receive a Surface Id 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: Process 2: Call OpenSurface using the new SurfaceId sl@0: Check that the return value of OpenSurface is KErrArgument sl@0: sl@0: @see TestOpenSurfaceInvalidParams() in tsurfacemanager.cpp sl@0: */ sl@0: void CTestDriverSecondProcess::TestOpeningSurfaceInvalidParams() sl@0: { sl@0: sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: // Open Surface using the right Id sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: // Open the surface using the invalid surfaceId - check that it returns KErrArgument sl@0: TSurfaceId invalidSurfaceId = surfaceId; sl@0: //Add 500 to the first field of surfaceId sl@0: invalidSurfaceId.iInternal[0] = surfaceId.iInternal[0]+500; sl@0: if(KErrArgument == iSurfaceManager.OpenSurface(invalidSurfaceId)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: // Change the surfaceId type to EInvalidSurface sl@0: invalidSurfaceId.iInternal[3] = (surfaceId.iInternal[3] & 0x00FFFFFF) | ( TSurfaceId::EInvalidSurface <<24 ) ; sl@0: if(KErrArgument == iSurfaceManager.OpenSurface(invalidSurfaceId)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: } sl@0: sl@0: /** sl@0: Test 22: Create, Open and Close in 3 different processes, sl@0: leaves surface accessible in first 2 processes sl@0: sl@0: ... sl@0: Process 2: Open Surface sl@0: ... sl@0: Process 2: MapSurface - KErrNone (still accessible) sl@0: ... sl@0: */ sl@0: void CTestDriverSecondProcess::OpenWaitMap() sl@0: { sl@0: sl@0: // Find the surfaceId sl@0: TSurfaceId id = iChunkWrapper->GetId(); sl@0: sl@0: // Open Surface sl@0: if(KErrNone == iSurfaceManager.OpenSurface(id)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sem.Signal(); sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sem2.Wait(); sl@0: sl@0: // Map surface sl@0: RChunk handle; sl@0: if(KErrNone == iSurfaceManager.MapSurface(id, handle)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: handle.Close(); sl@0: sl@0: } sl@0: sl@0: sl@0: /** sl@0: Test 23/24/25/26: Test surface can be accessed when creating process dies / sl@0: Test surface can be closed when creating process dies / sl@0: Test surface can be closed from third process when sl@0: creating process dies and second process closes / sl@0: Test surface can't be accessed in a second process when open sl@0: and closed in the first process. sl@0: sl@0: Process 2: Create Surface sl@0: ... sl@0: Process 2: Kill Process sl@0: ... sl@0: */ sl@0: void CTestDriverSecondProcess::CreateWaitKill() sl@0: { sl@0: // Setup attributes sl@0: RSurfaceManager::TSurfaceCreationAttributesBuf buf; sl@0: RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); sl@0: sl@0: attributes.iSize = TSize(20,80); // w > 0, h > 0 sl@0: attributes.iBuffers = 12; // > 0 sl@0: attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp sl@0: attributes.iStride = 250; // > 0, < width * bpp sl@0: attributes.iOffsetToFirstBuffer = 200; // > 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.iMappable = ETrue; sl@0: sl@0: // Create the surface sl@0: TSurfaceId surfaceId; sl@0: if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: // Put the surfaceId onto the shared chunk sl@0: iChunkWrapper->SetId(surfaceId); sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sem.Signal(); sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sem2.Wait(); sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: // CleanupStack::PopAndDestroy(2,&sem); sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: } sl@0: sl@0: /** sl@0: Test 27/28/29: Test closing doesn't prevent opening on another process sl@0: Test closing doesn't prevent access on another process sl@0: Test closing a surface in the creating process sl@0: when it has already been closed in a second process returns KErrNone sl@0: sl@0: ... sl@0: Process 2: Open Surface sl@0: Process 2: Close Surface sl@0: ... sl@0: */ sl@0: void CTestDriverSecondProcess::OpenClose() sl@0: { sl@0: sl@0: // Find the surfaceId sl@0: TSurfaceId id = iChunkWrapper->GetId(); sl@0: sl@0: // Open Surface sl@0: if(KErrNone == iSurfaceManager.OpenSurface(id)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Close Surface sl@0: if(KErrNone == iSurfaceManager.CloseSurface(id)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sem.Signal(); sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sem2.Wait(); sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: } sl@0: sl@0: /** sl@0: Test 30: Test a surface cannot be accessed in a second process if not opened sl@0: sl@0: ... sl@0: Process 2: Map Surface - KErrAccessDenied sl@0: Process 2: Surface Info - KErrAccessDenied sl@0: */ sl@0: void CTestDriverSecondProcess::MapSurfaceInfoCantAccess() sl@0: { sl@0: // Find the surfaceId sl@0: TSurfaceId id = iChunkWrapper->GetId(); sl@0: sl@0: // Map surface sl@0: RChunk handle; sl@0: if(KErrAccessDenied == iSurfaceManager.MapSurface(id, handle)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Surface Info sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: if(KErrAccessDenied == iSurfaceManager.SurfaceInfo(id, infoBuf)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Pass control back to the first process sl@0: RSemaphore sem; sl@0: if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sem.Signal(); sl@0: sl@0: RSemaphore sem2; sl@0: if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: sem2.Wait(); sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: // CleanupStack::PopAndDestroy(3,&handle); sl@0: sem.Close(); sl@0: sem2.Close(); sl@0: handle.Close(); sl@0: } sl@0: sl@0: /** sl@0: Test 31: Test that a buffer written to in one surface can be read from in another sl@0: 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: */ sl@0: void CTestDriverSecondProcess::TestReadFromBufferInSecondProcess() sl@0: { sl@0: // Find the surfaceId sl@0: TSurfaceId id = iChunkWrapper->GetId(); sl@0: sl@0: // Open Surface sl@0: if(KErrNone == iSurfaceManager.OpenSurface(id)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: // Map surface sl@0: RChunk handle; sl@0: if(KErrNone == iSurfaceManager.MapSurface(id, handle)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: // Read from the buffer sl@0: RSurfaceManager::TInfoBuf infoBuf; sl@0: if(KErrNone == iSurfaceManager.SurfaceInfo(id, infoBuf)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); sl@0: TUint8* surfaceAdd = handle.Base(); sl@0: TInt offsetToFirstBuffer; sl@0: if(KErrNone == iSurfaceManager.GetBufferOffset(id, 0, offsetToFirstBuffer)) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: TUint8* bufferAdd = surfaceAdd + offsetToFirstBuffer; sl@0: if(*bufferAdd == 134) sl@0: { sl@0: iTestResult |= EFifthTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: handle.Close(); sl@0: } sl@0: sl@0: void CTestDriverSecondProcess::TestGetSurfaceHint() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: RSurfaceManager::THintPair hintPair; sl@0: hintPair.iKey.iUid = 0x124578; sl@0: if (KErrAccessDenied == iSurfaceManager.GetSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: if (KErrNone == iSurfaceManager.GetSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: } sl@0: sl@0: sl@0: void CTestDriverSecondProcess::TestSetSurfaceHint() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: RSurfaceManager::THintPair hintPair; sl@0: hintPair.iKey.iUid = 0x124578; sl@0: hintPair.iValue = 300; sl@0: sl@0: if (KErrAccessDenied == iSurfaceManager.SetSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: if (KErrNone == iSurfaceManager.SetSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: RSurfaceManager::THintPair hintPairNew; sl@0: hintPairNew.iKey.iUid = 0x124578; sl@0: sl@0: iSurfaceManager.GetSurfaceHint(surfaceId,hintPairNew); sl@0: if (hintPairNew.iValue == hintPair.iValue) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: } sl@0: sl@0: sl@0: void CTestDriverSecondProcess::TestAddSurfaceHint() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: sl@0: RSurfaceManager::THintPair hintPair; sl@0: hintPair.iKey.iUid = 0x124580; sl@0: hintPair.iValue = 300; sl@0: hintPair.iMutable = ETrue; sl@0: if (KErrAccessDenied == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: sl@0: if(KErrNone == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: sl@0: if (KErrNone == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair)) sl@0: { sl@0: iTestResult |= EThirdTestPassed; sl@0: } sl@0: RSurfaceManager::THintPair hintPairNew; sl@0: hintPairNew.iKey.iUid = 0x124580; sl@0: sl@0: iSurfaceManager.GetSurfaceHint(surfaceId,hintPairNew); sl@0: if (hintPairNew.iValue == hintPair.iValue) sl@0: { sl@0: iTestResult |= EFourthTestPassed; sl@0: } sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: sl@0: } sl@0: sl@0: sl@0: void CTestDriverSecondProcess::TestOutofMemory() sl@0: { sl@0: // Open the chunk wrapper and get the surfaceId sl@0: TSurfaceId surfaceId = iChunkWrapper->GetId(); sl@0: // Test OOM in OpenSurface() sl@0: __KHEAP_SETFAIL(RHeap::EDeterministic, 1); sl@0: if (KErrNoMemory == iSurfaceManager.OpenSurface(surfaceId)) sl@0: { sl@0: iTestResult |= EFirstTestPassed; sl@0: } sl@0: __KHEAP_RESET; sl@0: // Test OOM in AddConnection() sl@0: RSurfaceManager surfaceManagerTest; sl@0: __KHEAP_SETFAIL(RHeap::EDeterministic, 1); sl@0: if (KErrNoMemory == surfaceManagerTest.Open()) sl@0: { sl@0: iTestResult |= ESecondTestPassed; sl@0: } sl@0: __KHEAP_RESET; sl@0: // Set the results so they can be read and tested by the first process sl@0: iChunkWrapper->SetSecondProcessResults(iTestResult); sl@0: } sl@0: // Real main function sl@0: void MainL() sl@0: { sl@0: sl@0: test.Title(); sl@0: RDebug::Print(_L("marker")); sl@0: sl@0: test.Start(_L("Starting 2nd Process")); sl@0: TInt testCase; sl@0: User::GetTIntParameter(EMultiProcessSecondSlot, testCase); sl@0: TInt procHandles1 =0; sl@0: TInt threadHandles1=0; sl@0: RThread().HandleCount(procHandles1, threadHandles1); sl@0: sl@0: CTestDriverSecondProcess* testDriver = CTestDriverSecondProcess::NewL(); sl@0: CleanupStack::PushL(testDriver); sl@0: sl@0: switch(testCase) sl@0: { sl@0: case ETestInfoReceivedSurface: sl@0: testDriver->TestSurfaceInfoUsingSurfaceId(); sl@0: break; sl@0: case ETestOpenReceivedSurface: sl@0: testDriver->TestOpeningSurfaceUsingSurfaceId(); sl@0: break; sl@0: case ETestOpenSurfaceInvalidParams: sl@0: testDriver->TestOpeningSurfaceInvalidParams(); sl@0: break; sl@0: case EOpenWaitMap: sl@0: testDriver->OpenWaitMap(); sl@0: break; sl@0: case ECreateWaitKill: sl@0: testDriver->CreateWaitKill(); sl@0: break; sl@0: case EOpenClose: sl@0: testDriver->OpenClose(); sl@0: break; sl@0: case EMapSurfaceInfoCantAccess: sl@0: testDriver->MapSurfaceInfoCantAccess(); sl@0: break; sl@0: case EReadFromBuffer: sl@0: testDriver->TestReadFromBufferInSecondProcess(); sl@0: break; sl@0: case ECheckHandle: sl@0: testDriver->TestCheckHandleInSecondProcess(); sl@0: break; sl@0: case ESyncOperation: sl@0: testDriver->TestCheckSyncOperation(); sl@0: break; sl@0: case ETestChannelMultiProcess1: sl@0: testDriver->TestMultipleChannelsInSecondProcess1(); sl@0: break; sl@0: case ETestChannelMultiProcess2: sl@0: testDriver->TestMultipleChannelsInSecondProcess2(); sl@0: break; sl@0: case EGetSurfaceHint: sl@0: testDriver->TestGetSurfaceHint(); sl@0: break; sl@0: case ESetSurfaceHint: sl@0: testDriver->TestSetSurfaceHint(); sl@0: break; sl@0: case EAddSurfaceHint: sl@0: testDriver->TestAddSurfaceHint(); sl@0: break; sl@0: case ECheckOutofMemory: sl@0: #ifdef _DEBUG sl@0: testDriver->TestOutofMemory(); sl@0: #endif sl@0: break; sl@0: default: sl@0: User::Leave(KErrArgument); sl@0: break; sl@0: } sl@0: CleanupStack::PopAndDestroy(testDriver); sl@0: 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: test.End(); sl@0: test.Close(); sl@0: } sl@0: sl@0: // Cleanup stack harness sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanupStack = CTrapCleanup::New(); sl@0: TRAPD(error, MainL()); sl@0: _LIT(KTSecondProcessPanic,"tsecondprocessmain"); sl@0: __ASSERT_ALWAYS(!error, User::Panic(KTSecondProcessPanic, error)); sl@0: delete cleanupStack; sl@0: __UHEAP_MARKEND; sl@0: return 0; sl@0: }