graphicshwdrivers/surfacemgr/test/src/tsecondprocess.cpp
changeset 0 5d03bc08d59c
child 36 01a6848ebfd7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicshwdrivers/surfacemgr/test/src/tsecondprocess.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,966 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Surface manager multi-processed test code
+// 
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32std.h>
+#include <e32debug.h>
+#include <e32def_private.h>
+#include <graphics/surface.h>
+#include <graphics/surfacemanager.h>
+#include "tsmgmultprocessshared.h"
+
+LOCAL_D RTest test(_L("TReceiveSurface"));
+
+
+class CTestDriverSecondProcess : public CTestDriver
+{
+public:
+	CTestDriverSecondProcess();
+	~CTestDriverSecondProcess();
+	void ConstructL();
+	static CTestDriverSecondProcess* NewL();
+public:
+	void TestMultipleChannelsInSecondProcess2();
+	void TestMultipleChannelsInSecondProcess1();
+	void TestCheckSyncOperation();
+	void TestCheckHandleInSecondProcess();
+	void TestSurfaceInfoUsingSurfaceId();
+	void TestOpeningSurfaceUsingSurfaceId();
+	void TestOpeningSurfaceInvalidParams();
+	void OpenWaitMap();
+	void CreateWaitKill();
+	void OpenClose();
+	void MapSurfaceInfoCantAccess();
+	void TestReadFromBufferInSecondProcess();
+	void TestGetSurfaceHint();
+	void TestSetSurfaceHint();
+	void TestAddSurfaceHint();
+	void TestOutofMemory();
+private:
+	RSurfaceManager iSurfaceManagerTwo;
+};
+
+CTestDriverSecondProcess::CTestDriverSecondProcess():CTestDriver()
+	{
+	}
+
+CTestDriverSecondProcess::~CTestDriverSecondProcess()
+	{
+	iSurfaceManagerTwo.Close();
+	}
+
+void CTestDriverSecondProcess::ConstructL()
+	{
+	CTestDriver::ConstructL();
+	User::LeaveIfError(	iSurfaceManagerTwo.Open());	
+	}
+
+CTestDriverSecondProcess* CTestDriverSecondProcess::NewL()
+{
+	CTestDriverSecondProcess * driver = new (ELeave) CTestDriverSecondProcess();
+	CleanupStack::PushL(driver);
+	driver->ConstructL();
+	CleanupStack::Pop(driver);
+	return driver;
+}
+
+void CTestDriverSecondProcess::TestMultipleChannelsInSecondProcess2()
+	{
+   	// Store the attributes used to create the Surface
+	RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(280,301);
+	attributes.iBuffers = 1;
+	attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp
+	attributes.iStride = 1;
+	attributes.iOffsetToFirstBuffer = 1;
+	attributes.iAlignment = 1;
+	
+	RSurfaceManager::THintPair hints[2];	// two hint pairs specified
+	attributes.iHintCount = 2;
+	attributes.iSurfaceHints = hints;
+	hints[0].Set(TUid::Uid(0x124578), 25, ETrue);
+	hints[1].Set(TUid::Uid(0x237755), 50, ETrue);
+	
+	attributes.iContiguous = ETrue;
+	attributes.iCacheAttrib = RSurfaceManager::ECached;
+	attributes.iOffsetBetweenBuffers = 0;
+	attributes.iMappable = ETrue;
+
+	// Create the surface
+	TSurfaceId surfaceIdOne;
+    if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceIdOne))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+
+	// Create the surface
+	TSurfaceId surfaceIdTwo;
+    if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceIdTwo))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+    
+    if(KErrNone == iSurfaceManager.OpenSurface(surfaceIdTwo))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+    
+    if(KErrNone == iSurfaceManagerTwo.OpenSurface(surfaceIdOne))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+    
+    // Set the results so they can be read and tested by the first process
+    iChunkWrapper->SetSecondProcessResults(iTestResult);
+    // Put the surfaceId onto the shared chunk
+    iChunkWrapper->SetId(surfaceIdOne);
+
+ 
+    // Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+
+    sem.Signal();
+    
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+    sem2.Wait();
+	
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+//	  // Put the surfaceId onto the shared chunk
+	iChunkWrapper->SetId(surfaceIdTwo);
+
+	sem.Close();
+	sem2.Close();
+	}
+
+void CTestDriverSecondProcess::TestMultipleChannelsInSecondProcess1()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceIdOne = iChunkWrapper->GetId();
+		
+	// Open the surface using the surfaceId - check that it returns KErrNone
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceIdOne))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+
+    // Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+    
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+
+   	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+
+	sem.Signal();
+	sem2.Wait();
+    
+	// Get the surface info
+	RSurfaceManager::TInfoBuf infoBuf;
+	if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceIdOne, infoBuf))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+	TSurfaceId surfaceIdTwo = iChunkWrapper->GetId();
+	
+	if(KErrArgument == iSurfaceManager.SurfaceInfo(surfaceIdTwo, infoBuf))
+		{
+		iTestResult |= EFifthTestPassed;
+		}
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+
+	sem.Close();
+	sem2.Close();
+	}
+
+void CTestDriverSecondProcess::TestCheckSyncOperation()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+	
+	// Check it returns KErrAccessDenied when the surface is not Open
+	TInt bufferNo = 1;
+
+	RSurfaceManager::TSyncOperation syncOperation = RSurfaceManager::ESyncBeforeNonCPURead;
+	
+	if(KErrAccessDenied == iSurfaceManager.SynchronizeCache(surfaceId, bufferNo,syncOperation))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	// Open the surface using the surfaceId - check that it returns KErrNone
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	// Map the surface 
+	RChunk handle;
+	
+	if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	
+	if(KErrNone == iSurfaceManager.SynchronizeCache(surfaceId, bufferNo,syncOperation))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	// Close the chunkwrapper, handle and the surface manager
+ 	handle.Close();
+
+	}
+void CTestDriverSecondProcess::TestCheckHandleInSecondProcess()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+
+	// Open the surface using the surfaceId - check that it returns KErrNone
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	// Map the surface 
+	RChunk handle;
+	
+	if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	// Get the surface info
+	RSurfaceManager::TInfoBuf infoBuf;
+	if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceId, infoBuf))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
+	// Get the adress of this chunk of memory
+	TUint8* surfaceAdd = handle.Base();
+	TInt offsetToFirstBuffer;
+	if(KErrNone == iSurfaceManager.GetBufferOffset(surfaceId, 0, offsetToFirstBuffer))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+	TUint8* bufferAdd = surfaceAdd + offsetToFirstBuffer;
+	
+	// Write to the first buffer, and test the value is written
+	*bufferAdd = 20;
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	// Close the chunkwrapper, handle and the surface manager
+	handle.Close();
+	}
+
+/**
+Test 18. Receiving a surface and querying SurfaceInfo for surface properties
+
+Process 1: Create the Surface
+Process 2: Receive the Surface Id 
+Process 2: Receive the attributes used to create the surface
+Process 2: Open the surface using the id
+Process 2: Map the surface
+Process 2: Call SurfaceInfo to get the attributes of the Surface
+Check if these are equal to the ones received.
+
+@see TestSurfaceInfoUsingSurfaceIdL() in tsurfacemanager.cpp
+*/	
+void CTestDriverSecondProcess::TestSurfaceInfoUsingSurfaceId()
+	{	
+	// Set attributes for the surface - these are expected attributes in the second process
+	RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes=buf();
+	attributes.iSize = TSize(200,200);
+	attributes.iBuffers = 1;				
+	attributes.iPixelFormat = EUidPixelFormatARGB_1555;		
+	attributes.iStride = 415;				
+	attributes.iOffsetToFirstBuffer = 80;	
+	attributes.iAlignment = 8;			
+	attributes.iContiguous=ETrue;
+	
+	RSurfaceManager::THintPair hints[2];	// two hint pairs specified
+	attributes.iHintCount = 2;
+	attributes.iSurfaceHints = hints;
+	hints[0].Set(TUid::Uid(0x124545), 50, EFalse);
+	hints[1].Set(TUid::Uid(0x237755), 50, EFalse);
+	
+	attributes.iOffsetBetweenBuffers = 0;
+	attributes.iCacheAttrib = RSurfaceManager::ENotCached;
+	attributes.iMappable = ETrue;
+	
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+	
+	// Open the surface using the surfaceId - check that it returns KErrNone
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	// Map the surface 
+	RChunk handle;
+	
+	if(KErrNone == iSurfaceManager.MapSurface(surfaceId, handle))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	// Get the surface info
+	RSurfaceManager::TInfoBuf infoBuf;
+	if(KErrNone == iSurfaceManager.SurfaceInfo(surfaceId, infoBuf))		
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
+	TInt offsetToFirstBuffer;
+	if(KErrNone == iSurfaceManager.GetBufferOffset(surfaceId, 0, offsetToFirstBuffer))  	
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+		
+	if(info.iSize == attributes.iSize)
+		{
+		iTestResult |= EFifthTestPassed;
+		}
+	if(info.iBuffers == attributes.iBuffers)
+		{
+		iTestResult |= ESixthTestPassed;
+		}
+	if(info.iPixelFormat == attributes.iPixelFormat)
+		{
+		iTestResult |= ESeventhTestPassed;
+		}
+	if(info.iStride == attributes.iStride)
+		{
+		iTestResult |= EEighthTestPassed;
+		}
+	if(offsetToFirstBuffer >= attributes.iOffsetToFirstBuffer)
+		{
+		iTestResult |= ENinthTestPassed;
+		}
+	if(info.iContiguous == attributes.iContiguous)
+		{
+		iTestResult |= ETenthTestPassed;
+		}
+	
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	// Close handle 
+	handle.Close();
+	}
+
+/**
+Test 19. Opening a surface using surfaceId
+
+Priocess 1: Create the surface
+Process 2: Receive the Surface id
+Process 2: Open the Surface using the stored Surface id
+Check OpenSurface returns KErrNone
+
+@see TestOpeningSurfaceUsingSurfaceIdL() in tsurfacemanager.cpp
+*/
+void CTestDriverSecondProcess::TestOpeningSurfaceUsingSurfaceId()
+	{
+	// Open the chunk wrapper and get the surfaceId
+//	CChunkWrapper* chunkWrapper = CChunkWrapper::OpenL(KSharedChunkName, ETrue);
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+		
+	// Open the surface using the surfaceId - check that it returns KErrNone	
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+		
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+
+	}
+	
+/**
+Test 20. Opening a surface using invalid surfaceId
+
+Process 1:Create the surface
+Process 2: Receive a Surface Id
+Change Surface Id by
+1. adding 500 to the SurfaceId
+2. making the Surface ID negative
+3. converting the type of the Surface ID to EInvalidSurface
+Process 2: Call OpenSurface using the new SurfaceId
+Check that the return value of OpenSurface is KErrArgument
+
+@see TestOpenSurfaceInvalidParams() in tsurfacemanager.cpp
+*/
+void CTestDriverSecondProcess::TestOpeningSurfaceInvalidParams()
+	{
+	
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+	
+	// Open Surface using the right Id
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	// Open the surface using the invalid surfaceId - check that it returns KErrArgument
+	TSurfaceId invalidSurfaceId = surfaceId; 
+	//Add 500 to the first field of surfaceId
+	invalidSurfaceId.iInternal[0] = surfaceId.iInternal[0]+500;
+	if(KErrArgument == iSurfaceManager.OpenSurface(invalidSurfaceId))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	// Change the surfaceId type to EInvalidSurface
+	invalidSurfaceId.iInternal[3] = (surfaceId.iInternal[3] & 0x00FFFFFF) | ( TSurfaceId::EInvalidSurface <<24 ) ;
+	if(KErrArgument == iSurfaceManager.OpenSurface(invalidSurfaceId))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+		
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	}
+
+/**
+Test 22: Create, Open and Close in 3 different processes, 
+			leaves surface accessible in first 2 processes 
+
+...	
+Process 2: Open Surface
+...
+Process 2: MapSurface - KErrNone (still accessible)
+...
+*/
+void CTestDriverSecondProcess::OpenWaitMap()
+	{
+	
+	// Find the surfaceId
+	TSurfaceId id = iChunkWrapper->GetId();
+	
+	// Open Surface
+	if(KErrNone == iSurfaceManager.OpenSurface(id))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	// Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+    sem.Signal();
+
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+    sem2.Wait();
+    
+    // Map surface
+	RChunk handle;
+	if(KErrNone == iSurfaceManager.MapSurface(id, handle))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+
+	sem.Close();
+	sem2.Close();
+	handle.Close();
+
+	}
+
+
+/**
+Test 23/24/25/26: 	Test surface can be accessed when creating process dies /
+					Test surface can be closed when creating process dies /
+					Test surface can be closed from third process when 
+					creating process dies and second process closes / 
+					Test surface can't be accessed in a second process when open 
+					and closed in the first process.
+
+Process 2: Create Surface
+...
+Process 2: Kill Process
+...
+*/
+void CTestDriverSecondProcess::CreateWaitKill()
+	{
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(20,80);    	// w > 0, h > 0
+	attributes.iBuffers = 12; 				// > 0
+	attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar;	// 2bpp
+	attributes.iStride = 250;				// > 0, < width * bpp
+	attributes.iOffsetToFirstBuffer = 200;	// > 0, divisible by alignment
+	attributes.iAlignment = 4;				// 1 || 2 || 4 || 8
+	attributes.iContiguous = ETrue;
+	
+	RSurfaceManager::THintPair hints[2];	// two hint pairs specified
+	attributes.iHintCount = 2;
+	attributes.iSurfaceHints = hints;
+	hints[0].Set(TUid::Uid(0x124545), 50, EFalse);
+	hints[1].Set(TUid::Uid(0x237755), 50, EFalse);
+	
+	attributes.iOffsetBetweenBuffers = 0;
+	attributes.iMappable = ETrue;
+	
+	// Create the surface
+	TSurfaceId surfaceId;
+    if(KErrNone == iSurfaceManager.CreateSurface(buf, surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+    // Put the surfaceId onto the shared chunk
+    iChunkWrapper->SetId(surfaceId);
+ 
+    // Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+    sem.Signal();
+    
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+    sem2.Wait();
+    
+    // Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+ 
+//  CleanupStack::PopAndDestroy(2,&sem);
+	sem.Close();
+	sem2.Close();
+	}
+
+/**
+Test 27/28/29: 	Test closing doesn't prevent opening on another process
+				Test closing doesn't prevent access on another process
+				Test closing a surface in the creating process 
+				when it has already been closed in a second process returns KErrNone
+
+...
+Process 2: Open Surface
+Process 2: Close Surface
+...
+*/
+void CTestDriverSecondProcess::OpenClose()
+	{
+
+	// Find the surfaceId
+	TSurfaceId id = iChunkWrapper->GetId();
+	
+	// Open Surface
+	if(KErrNone == iSurfaceManager.OpenSurface(id))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+		
+	// Close Surface
+	if(KErrNone == iSurfaceManager.CloseSurface(id))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+		
+	// Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+    sem.Signal();
+    
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+    sem2.Wait();
+    
+    // Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+    
+	sem.Close();
+	sem2.Close();
+	}
+
+/**
+Test 30: Test a surface cannot be accessed in a second process if not opened
+
+...
+Process 2: Map Surface - KErrAccessDenied
+Process 2: Surface Info - KErrAccessDenied
+*/
+void CTestDriverSecondProcess::MapSurfaceInfoCantAccess()
+	{
+	// Find the surfaceId
+	TSurfaceId id = iChunkWrapper->GetId();
+	
+	// Map surface
+	RChunk handle;
+	if(KErrAccessDenied == iSurfaceManager.MapSurface(id, handle))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+		
+	// Surface Info
+	RSurfaceManager::TInfoBuf infoBuf;
+	if(KErrAccessDenied == iSurfaceManager.SurfaceInfo(id, infoBuf))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+		
+	// Pass control back to the first process
+    RSemaphore sem;
+	if(KErrNone == sem.OpenGlobal(KMultiProcessSemaphore))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+    sem.Signal();
+    
+    RSemaphore sem2;
+	if(KErrNone == sem2.OpenGlobal(KMultiProcessSemaphore2))
+		{
+		iTestResult |= EFourthTestPassed;
+		}
+    sem2.Wait();
+    
+    // Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+    
+//	CleanupStack::PopAndDestroy(3,&handle);
+	sem.Close();
+	sem2.Close();
+	handle.Close();
+	}
+
+/**
+Test 31: Test that a buffer written to in one surface can be read from in another 
+
+Process 1: Create Surface
+Process 1: Map Surface 
+Process 1: Write to buffer
+Process 2: Open the surface 
+Process 2: Read from buffer 
+*/	
+void CTestDriverSecondProcess::TestReadFromBufferInSecondProcess()
+	{
+	// Find the surfaceId
+	TSurfaceId id = iChunkWrapper->GetId();
+	
+	// Open Surface
+	if(KErrNone == iSurfaceManager.OpenSurface(id))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	// Map surface
+	RChunk handle;
+	if(KErrNone == iSurfaceManager.MapSurface(id, handle))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+		
+	// Read from the buffer
+	RSurfaceManager::TInfoBuf infoBuf;
+	if(KErrNone == iSurfaceManager.SurfaceInfo(id, infoBuf))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
+	TUint8* surfaceAdd = handle.Base();
+	TInt offsetToFirstBuffer;
+	if(KErrNone == iSurfaceManager.GetBufferOffset(id, 0, offsetToFirstBuffer))
+  		{
+		iTestResult |= EFourthTestPassed;
+		}
+	TUint8* bufferAdd = surfaceAdd + offsetToFirstBuffer;
+	if(*bufferAdd == 134)
+		{
+		iTestResult |= EFifthTestPassed;
+		}
+	
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+    
+	handle.Close();
+	}
+	
+void CTestDriverSecondProcess::TestGetSurfaceHint()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+		
+	RSurfaceManager::THintPair hintPair;
+	hintPair.iKey.iUid = 0x124578;
+	if (KErrAccessDenied == iSurfaceManager.GetSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	if (KErrNone == iSurfaceManager.GetSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	}
+
+
+void CTestDriverSecondProcess::TestSetSurfaceHint()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+		
+	RSurfaceManager::THintPair hintPair;
+	hintPair.iKey.iUid = 0x124578;
+	hintPair.iValue = 300;
+
+	if (KErrAccessDenied == iSurfaceManager.SetSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	if (KErrNone == iSurfaceManager.SetSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	RSurfaceManager::THintPair hintPairNew;
+	hintPairNew.iKey.iUid = 0x124578;
+	
+	iSurfaceManager.GetSurfaceHint(surfaceId,hintPairNew);
+	if (hintPairNew.iValue == hintPair.iValue)
+		{
+		iTestResult |= EFourthTestPassed;		
+		}
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	}
+
+
+void CTestDriverSecondProcess::TestAddSurfaceHint()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+		
+	RSurfaceManager::THintPair hintPair;
+	hintPair.iKey.iUid = 0x124580;
+	hintPair.iValue = 300;
+	hintPair.iMutable = ETrue;
+	if (KErrAccessDenied == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	
+	if(KErrNone == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	
+	if (KErrNone == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair))
+		{
+		iTestResult |= EThirdTestPassed;
+		}
+	RSurfaceManager::THintPair hintPairNew;
+	hintPairNew.iKey.iUid = 0x124580;
+	
+	iSurfaceManager.GetSurfaceHint(surfaceId,hintPairNew);
+	if (hintPairNew.iValue == hintPair.iValue)
+		{
+		iTestResult |= EFourthTestPassed;		
+		}
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	
+	}
+
+
+void CTestDriverSecondProcess::TestOutofMemory()
+	{
+	// Open the chunk wrapper and get the surfaceId
+	TSurfaceId surfaceId = iChunkWrapper->GetId();
+	// Test OOM in OpenSurface()
+	__KHEAP_SETFAIL(RHeap::EDeterministic, 1);
+	if (KErrNoMemory == iSurfaceManager.OpenSurface(surfaceId))
+		{
+		iTestResult |= EFirstTestPassed;
+		}
+	__KHEAP_RESET;
+	// Test OOM in AddConnection()
+	RSurfaceManager surfaceManagerTest;
+	__KHEAP_SETFAIL(RHeap::EDeterministic, 1);
+	if (KErrNoMemory == surfaceManagerTest.Open())
+		{
+		iTestResult |= ESecondTestPassed;
+		}
+	__KHEAP_RESET;
+	// Set the results so they can be read and tested by the first process
+	iChunkWrapper->SetSecondProcessResults(iTestResult);
+	}
+// Real main function
+void MainL()
+	{
+	
+	test.Title();
+	RDebug::Print(_L("marker"));
+
+	test.Start(_L("Starting 2nd Process"));
+	TInt testCase;
+	User::GetTIntParameter(EMultiProcessSecondSlot, testCase);
+	TInt procHandles1  =0;
+	TInt threadHandles1=0;
+	RThread().HandleCount(procHandles1, threadHandles1);
+	
+	CTestDriverSecondProcess* testDriver = CTestDriverSecondProcess::NewL(); 
+	CleanupStack::PushL(testDriver);
+	
+	switch(testCase)
+		{
+	case ETestInfoReceivedSurface:
+		testDriver->TestSurfaceInfoUsingSurfaceId();
+		break;
+	case ETestOpenReceivedSurface:
+		testDriver->TestOpeningSurfaceUsingSurfaceId();
+		break;
+	case ETestOpenSurfaceInvalidParams:
+		testDriver->TestOpeningSurfaceInvalidParams();	
+		break;
+	case EOpenWaitMap:
+		testDriver->OpenWaitMap();
+		break;	
+	case ECreateWaitKill:
+		testDriver->CreateWaitKill();
+		break;
+	case EOpenClose:
+		testDriver->OpenClose();
+		break;
+	case EMapSurfaceInfoCantAccess:
+		testDriver->MapSurfaceInfoCantAccess();
+		break;
+	case EReadFromBuffer:
+		testDriver->TestReadFromBufferInSecondProcess();
+		break;
+	case ECheckHandle:
+		testDriver->TestCheckHandleInSecondProcess();
+		break;
+	case ESyncOperation:
+		testDriver->TestCheckSyncOperation();
+		break;
+	case ETestChannelMultiProcess1:
+		testDriver->TestMultipleChannelsInSecondProcess1();
+		break;
+	case ETestChannelMultiProcess2:
+		testDriver->TestMultipleChannelsInSecondProcess2();
+		break;
+	case EGetSurfaceHint:
+		testDriver->TestGetSurfaceHint();
+		break;
+	case ESetSurfaceHint:
+		testDriver->TestSetSurfaceHint();
+		break;
+	case EAddSurfaceHint:
+		testDriver->TestAddSurfaceHint();
+		break;
+	case ECheckOutofMemory:
+#ifdef _DEBUG
+		testDriver->TestOutofMemory();
+#endif
+		break;
+	default:
+		User::Leave(KErrArgument);
+		break;
+		}
+	CleanupStack::PopAndDestroy(testDriver);
+
+	// Handle check
+	TInt procHandles2  =0;
+	TInt threadHandles2=0;
+	RThread().HandleCount(procHandles2,threadHandles2);
+	if (threadHandles1 != threadHandles2)
+		{
+		User::Leave(KErrGeneral);  // Thread-owned handles not closed
+		}
+
+		
+	test.End();
+	test.Close();
+	}
+
+// Cleanup stack harness
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack = CTrapCleanup::New();
+	TRAPD(error, MainL());
+	_LIT(KTSecondProcessPanic,"tsecondprocessmain");
+	__ASSERT_ALWAYS(!error, User::Panic(KTSecondProcessPanic, error));
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	return 0;
+	}