graphicshwdrivers/surfacemgr/test/src/tsurfacemanagermultithread.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicshwdrivers/surfacemgr/test/src/tsurfacemanagermultithread.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1849 @@
+// 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-threaded test code
+// 
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#include "tsurfacemanagermultithread.h"
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32std.h>
+#include <e32cmn.h>
+#include <e32def.h>	  
+
+static TSurfaceId globalSurfaceId;	
+static TInt testResult;
+
+typedef CTSurfaceManagerMultiThread::TInfo TInfo;
+
+CTSurfaceManagerMultiThread::CTSurfaceManagerMultiThread(CTestStep* aStep):
+	CTGraphicsBase(aStep)
+	{
+	
+	}
+
+CTSurfaceManagerMultiThread::~CTSurfaceManagerMultiThread()
+	{
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::RunTestCaseL(TInt aCurTestCase)
+	{
+	TInt procHandles1  =0;
+	TInt threadHandles1=0;
+	RThread().HandleCount(procHandles1, threadHandles1);
+	((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
+	switch(aCurTestCase)
+		{
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0078
+@SYMPREQ				PREQ1879, PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing surface in another thread without opening it
+						Thread 1: Create Surface 
+						Thread 2: Map Surface - KErrNone (still accessible)
+						Thread 2: SurfaceInfo - KErrNone (still accessible)
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),MapSurface(), SurfaceInfo()
+@SYMTestExpectedResults The surface can be successfully accessed in other threads without first opening it.
+*/
+	case 1:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0078"));
+		TestAccessSurfaceWithoutOpeningL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0079
+@SYMPREQ				PREQ1879, PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing a surface created in the existing shared chunk in another thread without opening it.
+						Thread 1: Create a Surface in the new chunk with valid creation attributes
+						Thread 1: Map the surface in the current process to get the chunk handle
+						Thread 1: Create a new surface in the existing chunk with valid creation attributes
+						Thread 2: Map the second Surface – KErrNone (still accessible)
+						Thread 2: SurfaceInfo – KErrNone (still accessible)
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),MapSurface(), SurfaceInfo()
+@SYMTestExpectedResults MapSurface, SurfaceInfo return KerrNone
+*/	
+	case 2:
+        ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0079"));
+		TestAccessSurfaceInExistingSharedChunkL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0080
+@SYMPREQ				PREQ1879, PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing surface in another thread without opening it
+						Thread 1: Create Surface 
+						Thread 2: Close Surface - KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface()
+@SYMTestExpectedResults The surface can be successfully closed in other threads without first opening it.
+*/
+	case 3:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0080"));
+		TestCloseSurfaceWithoutOpeningL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0081
+@SYMPREQ				PREQ1879, PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing an surface which is created in another thread but closed in current thread 
+						Thread 2: Create Surface
+						Thread 1: Close Surface - KerrNone
+						Thread 2: Map Surface - KErrArgument
+						Thread 2: SurfaceInfo - KErrArgument
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo()
+@SYMTestExpectedResults The surface cant be accessd even after it is closed in other threads.
+*/
+	case 4:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0081"));
+		TestAccessSurfaceClosedThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0067
+@SYMPREQ				PREQ1879, PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing surface created in the existing chunk in another thread without opening it 
+						Thread 1: Create a Surface in a new shared chunk with valid attributes
+						Thread 1: Map the surface in the process to get the shared chunk handle
+						Thread 1: Create a new surface in the existing shared chunk
+						Thread 2: Close the second surface – KErrNone (the second surface is deleted)
+						Thread 2: Call SurfaceInfo to the first surface and it returns KErrNone, but it returns KErrArgument to the second surface.
+						Thread 2: Close the first surface and check it returns KErrNone (the first surface is deleted).
+						Thread 1: Call SurfaceInfo to both surfaces and return KErrArgument
+						Thread 1: Check the chunk is still accessible by calling RChunk::Base() 
+						Thread 1: Close the chunk handle  
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface()
+@SYMTestExpectedResults CloseSurface returns KErrNone. The chunk handle is not closed even when both surfaces are deleted.
+*/		
+	case 5:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0067"));
+		TestCloseSurfaceExistingSharedChunkL();
+		break;
+
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0068
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing an surface which is already closed in other thread return KErrArgument 
+						Thread 2: Create Surface
+						Thread 1: Close Surface - KerrNone
+						Thread 2: Close Surface - KErrArgument
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface()
+@SYMTestExpectedResults The surface cant be closed again.
+*/
+	case 6:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0068"));
+		TestCloseSurfaceClosedThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0069
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing an surface which is already opened and closed in another thread, given that the process still owns the surface 
+						Thread 1: Create Surface
+						Thread 2: Open Surface -- KErrNone
+						Thread 2: Close Surface -- KErrNone
+						Thread 1: Map Surface - KErrNone
+						Thread 1: SurfaceInfo - KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo, OpenSurface()
+@SYMTestExpectedResults The surface is still accessible in the thread residing the owning process
+*/
+	case 7:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0069"));
+		TestAccessSurfaceOpenedClosedThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0070
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing an surface which is already opened and closed in another thread, given that the process still owns the surface
+    					Thread 1: Create Surface
+						Thread 2: Open Surface
+						Thread 2: Close Surface
+						Thread 1: Close Surface - KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), OpenSurface()
+@SYMTestExpectedResults The surface is still closible in the thread residing in the owning process
+*/
+	case 8:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0070"));
+		TestCloseSurfaceOpenedClosedThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0071
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing surface in another thread when the opening thread is killed   
+						Thread 1: Create Surface 
+						Thread 2: Open Surface
+						Thread 2: Kill the thread
+						Thread 1: Map Surface - KErrNone
+						Thread 1: Surface Info -- KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), OpenSurface()
+@SYMTestExpectedResults The surface is accessible when the opening thread is killed
+*/
+	case 9:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0071"));
+		TestAccessSurfaceOpenedKilledThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0072
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing surface in another thread when the opening thread is killed   
+						Thread 1: Create Surface 
+						Thread 2: Open Surface
+						Thread 2: Kill the thread
+						Thread 1: Close Surface - KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), OpenSurface()
+@SYMTestExpectedResults The surface is closible when the opening thread is killed
+*/
+	case 10:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0072"));
+		TestCloseSurfaceOpenedKilledThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0073
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing surface in another thread when the creating thread is killed and it is closed in other threads
+						Thread 2: Create Surface
+						Thread 1: Close Surface
+						Thread 2: Kill Thread
+						Thread 1: Map Surface - KErrArgument
+						Thread 1: Surface Info - KErrArgument
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(),
+@SYMTestExpectedResults The surface is accessible when the creating thread is killed and it is closed in other threads
+*/
+	case 11:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0073"));
+		TestAccessSurfaceCreateKilledThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0074
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test accessing surface in another thread when the creating thread is killed and it is closed in other threads
+						Thread 2: Create Surface
+						Thread 1: Close Surface
+						Thread 2: Kill Thread
+						Thread 1: Close Surface - KErrArgument
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface()
+@SYMTestExpectedResults The surface is accessible when the creating thread is killed and it is closed in other threads
+*/
+	case 12:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0074"));
+		TestCloseSurfaceCreateKilledThreadL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0075
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface
+    					Thread 1: Create Surface
+						Thread 2: Open Surface
+						Thread 2: Close Surface
+						Thread 3: Open Surface - KerrNone
+						Thread 3: Map Surface - KerrNone
+						Thread 3: SurfaceInfo -- KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(),
+@SYMTestExpectedResults It is expected that closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface
+*/
+	case 13:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0075"));
+		TestAccessSurfaceThreeThreadsL();
+		break;	
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0076
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test surface can be accessed from third thread when creating thread dies and second thread closes
+    					Thread 2: Create Surface
+						Thread 1: Open Surface
+						Thread 3: Open Surface
+						Thread 1: Close Surface
+						Thread 2: Kill Thread
+ 					 	Thread 3: Close Surface
+						Thread 3: Map Surface - KerrNone
+						Thread 3: SurfaceInfo -- KErrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), OpenSurface()
+@SYMTestExpectedResults It is expected that surface can be accessed from third thread when creating thread dies and second thread closes
+*/
+	case 14:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0076"));
+		TestAccessSurfaceDieCloseOtherThreadsL();
+		break;
+/**
+@SYMTestCaseID			GRAPHICS-SURFACEMANAGER-0077
+@SYMPREQ				PREQ1007
+@SYMREQ					REQ8222,REQ8223
+@SYMTestPriority		High 
+@SYMTestCaseDesc		Test that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface
+   						Thread 2: Create Surface
+						Thread 1: Open Surface
+						Thread 3: Open Surface
+						Thread 1: Close Surface
+						Thread 2: Kill Thread
+ 					    Thread 3: Close Surface
+						Thread 3: Open Surface - KerrNone
+@SYMTestStatus			Implemented
+@SYMTestActions			Call CreateSurface(),CloseSurface(), OpenSurface()
+@SYMTestExpectedResults It is expected that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface
+*/
+	case 15:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0077"));
+		TestOpenSurfaceDieCloseOtherThreadsL();
+		break;
+	default:
+		((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
+		((CTSurfaceManagerMultiThreadStep*)iStep)->CloseTMSGraphicsStep();
+		TestComplete();
+		break;
+		}
+	((CTSurfaceManagerMultiThreadStep*)iStep)->RecordTestResultL();
+	// Handle check
+	TInt procHandles2  =0;
+	TInt threadHandles2=0;
+	RThread().HandleCount(procHandles2,threadHandles2);
+	if (threadHandles1 != threadHandles2)
+		{
+		User::Leave(KErrGeneral);  // Thread-owned handles not closed
+		}
+ 	}
+
+void CTSurfaceManagerMultiThread::CloseSurfaceWhenLeave(TAny* aInfo) 
+	{
+	TInt err1 = ((TInfo*)aInfo)->iSurfaceManager.CloseSurface(((TInfo*)aInfo)->iSurfaceId);
+	TInt err2 = ((TInfo*)aInfo)->iSurfaceManager.CloseSurface(((TInfo*)aInfo)->iSurfaceIdNew);
+	if (err1!=KErrNone || err2!=KErrNone)
+	   	RDebug::Print(_L("Error closing surfaces err1= %d, err2= %d\n"),err1,err2);	
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceWithoutOpeningL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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.iMappable = ETrue;
+	
+	// Test create surface doesn't return an error
+	TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    // Logging info   
+    INFO_PRINTF1(_L("Test accessing surface in another thread without opening it\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);	
+	
+	// Create a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iSurfaceIdNew = TSurfaceId::CreateNullId();
+	iInfo.iThreadTestCase = EMapSurfaceInfo;		
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+		
+    RThread thread1;
+    _LIT(KNameThreadSecond1, "Test_SurfaceManager_ThreadSecond1");
+	User::LeaveIfError(thread1.Create(KNameThreadSecond1,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+    // Launch second thread
+	TRequestStatus statusThreadSecond;
+	thread1.Logon(statusThreadSecond);
+	thread1.SetPriority(EPriorityLess);
+	thread1.Resume();	
+	testResult = EAllZero;
+	// Passes control to the second process
+	sem.Wait();
+	thread1.Suspend();
+
+	// Test results in second thread
+	TEST (testResult = (EMapSurfaceTestPassed | ESurfaceInfoTestPassed));
+
+	// Pass control off to the second process again
+	thread1.Resume();
+
+	// Wait for a second for the second thread to terminate
+	User::WaitForRequest(statusThreadSecond);
+
+	//Close the handles
+    CleanupStack::PopAndDestroy(1, &sem);  //invoke surface manager to close the surface also close the handle to RSemaphore
+    thread1.Close();
+    iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceInExistingSharedChunkL()
+    {
+    // Logging info   
+    INFO_PRINTF1(_L("Test accessing a surface created in the existing shared chunk in another thread without opening it\r\n"));
+
+    User::LeaveIfError(iSurfaceManager.Open());
+    
+    // Setup attributes 
+    
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+    RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+
+    attributes.iSize = TSize(100,100);
+    attributes.iBuffers = 1;                // number of buffers in the surface
+    attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar;     // 2bpp
+    attributes.iStride = 400;               // Number of bytes between start of one line and start of next
+    attributes.iOffsetToFirstBuffer = 0;    // way of reserving space before the surface pixel data
+    attributes.iAlignment = 2;          // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+    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;
+
+    // Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    
+    //Map the surface in the current processs
+    RChunk handle;
+    TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId,handle));
+    
+    // Cache, Contiguous and Alignment attributes are ignored for the already existing chunks
+    RSurfaceManager::TSurfaceCreationAttributesBuf buff;
+    RSurfaceManager::TSurfaceCreationAttributes& attributesNew = buff();
+
+    attributesNew.iSize = TSize(480,16);
+    attributesNew.iBuffers = 2;             // number of buffers in the surface
+    attributesNew.iPixelFormat = EUidPixelFormatYUV_422Reversed;        // 2bpp
+    attributesNew.iStride = 1013;               // Number of bytes between start of one line and start of next
+    attributesNew.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
+    
+    attributesNew.iHintCount = 1;
+    attributesNew.iSurfaceHints = hints;
+    hints[0].Set(TUid::Uid(0x124545), 50, EFalse);
+    
+    attributesNew.iAlignment = 2;
+    attributesNew.iOffsetBetweenBuffers = 0;
+    attributes.iMappable = ETrue;
+    
+    // Test create surface doesn't return an error
+    // For the time being KErrArgument will be returned as the core codes are
+    // not ready to check the passed in shared chunk handle.
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buff, iSurfaceIdNew, handle));
+
+
+    // Create a semaphore
+    RSemaphore sem;
+    TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+    CleanupClosePushL(sem); 
+    
+    // Create a second thread in the current process and opens the handle
+    iInfo.iSurfaceManager = iSurfaceManager;
+    iInfo.iSurfaceId = iSurfaceIdNew;
+    iInfo.iSurfaceIdNew = iSurfaceId;
+    iInfo.iThreadTestCase = EMapSurfaceInfo;    
+    // Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+    
+    RThread thread2;
+    _LIT(KNameThreadSecond2, "Test_SurfaceManager_ThreadSecond2");
+    User::LeaveIfError(thread2.Create(KNameThreadSecond2,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+ 
+    CleanupStack::Pop();
+    // Launch second thread
+    TRequestStatus statusThreadSecond;
+    thread2.Logon(statusThreadSecond);
+    thread2.SetPriority(EPriorityLess);
+    thread2.Resume();   
+    testResult = EAllZero;
+    // Passes control to the second process
+    sem.Wait();
+    thread2.Suspend();
+
+    // Test results in second thread
+    TEST (testResult = (EMapSurfaceTestPassed | ESurfaceInfoTestPassed));
+
+    // Pass control off to the second process again
+    thread2.Resume();
+
+    // Wait for a second for the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+    
+    //Close the handles
+    CleanupStack::PopAndDestroy(1, &sem);  //invoke surface manager to close the surface also close the handle to RSemaphore
+    handle.Close();
+    thread2.Close();
+    iSurfaceManager.Close();
+    
+    }
+
+void CTSurfaceManagerMultiThread::TestCloseSurfaceWithoutOpeningL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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.iMappable = ETrue;
+	
+	// Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+   
+    INFO_PRINTF1(_L("Test closing surface in another thread without opening it\r\n"));
+	
+	// Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+   	CleanupClosePushL(sem);	
+
+  	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECloseSurfaces;	
+   	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread3;
+    _LIT(KNameThreadSecond3, "Test_SurfaceManager_ThreadSecond3");
+	User::LeaveIfError(thread3.Create(KNameThreadSecond3,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+    CleanupStack::Pop();
+    // Launch second thread to close the surface
+	TRequestStatus statusThreadSecond;
+	thread3.Logon(statusThreadSecond);
+	thread3.SetPriority(EPriorityLess);
+	thread3.Resume();	
+	testResult = EAllZero;
+	// Passes control to the second thread
+	sem.Wait();
+	thread3.Suspend();
+
+	// Test the results in the second thread
+	TEST(testResult == ECloseSurfaceTestPassed);
+	
+	thread3.Resume();
+	// Wait for a second for the second process to terminate
+	User::WaitForRequest(statusThreadSecond);
+	
+	//Close the handle
+    CleanupStack::PopAndDestroy(1, &sem);
+    thread3.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceClosedThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    // Logging info
+    INFO_PRINTF1(_L("Test accessing an surface which is created in another thread but closed in current thread\r\n"));
+    
+    // Create a semaphore
+	RSemaphore sem;
+	RSemaphore semMain;
+	
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+    CleanupClosePushL(sem);	
+    TEST(KErrNone == semMain.CreateGlobal(KMainThreadSemaphore, 0));
+    CleanupClosePushL(semMain);	
+
+	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateSurfaceMapInfo;	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread4;
+    _LIT(KNameThreadSecond4, "Test_SurfaceManager_ThreadSecond4");
+	User::LeaveIfError(thread4.Create(KNameThreadSecond4,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+    CleanupStack::Pop();
+    // Launch the second trhead
+	TRequestStatus statusThreadSecond;
+	thread4.Logon(statusThreadSecond);
+	thread4.SetPriority(EPriorityLess);
+	thread4.Resume();	
+    
+    testResult = EAllZero;
+  	// Passes control to the second process
+    sem.Wait(); 
+	// Test creating surface in second thread
+   	TEST(testResult == ECreateSurfaceTestPassed);
+   	// Reset testResult
+    testResult = EAllZero;
+    // Test closing surface
+    iSurfaceId = globalSurfaceId;
+	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+	semMain.Signal();
+    // Wait the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+	// Test mapsurface and surfaceinfo executed in the second thread
+	TEST(testResult == (EMapSurfaceTestFailed|ESurfaceInfoTestFailed));
+	// Close all the handles
+    CleanupStack::PopAndDestroy(2, &sem);
+    thread4.Close();
+	iSurfaceManager.Close();
+
+	}
+
+void CTSurfaceManagerMultiThread::TestCloseSurfaceExistingSharedChunkL()
+    {
+    // Logging info   
+    INFO_PRINTF1(_L("Test closing surface created in the existing chunk in another thread without opening it\r\n"));
+ 
+    User::LeaveIfError(iSurfaceManager.Open());
+    // Setup attributes 
+    
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+    RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+
+    attributes.iSize = TSize(100,100);
+    attributes.iBuffers = 1;                // number of buffers in the surface
+    attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar;     // 2bpp
+    attributes.iStride = 400;               // Number of bytes between start of one line and start of next
+    attributes.iOffsetToFirstBuffer = 0;    // way of reserving space before the surface pixel data
+    attributes.iAlignment = 2;          // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+    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;
+    
+    // Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    
+    //Map the surface in the current processs
+    RChunk handle;
+    TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId,handle));
+    
+    // Cache, Contiguous and Alignment attributes are ignored for the already existing chunks
+    RSurfaceManager::TSurfaceCreationAttributesBuf buff;
+    RSurfaceManager::TSurfaceCreationAttributes& attributesNew = buff();
+
+    attributesNew.iSize = TSize(480,16);
+    attributesNew.iBuffers = 2;             // number of buffers in the surface
+    attributesNew.iPixelFormat = EUidPixelFormatYUV_422Reversed;        // 2bpp
+    attributesNew.iStride = 1013;               // Number of bytes between start of one line and start of next
+    attributesNew.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
+    
+    attributesNew.iHintCount = 1;
+    attributesNew.iSurfaceHints = hints;
+    hints[0].Set(TUid::Uid(0x124545), 50, EFalse);
+
+    attributesNew.iAlignment = 2;
+    attributesNew.iOffsetBetweenBuffers = 0;
+    attributesNew.iMappable = ETrue;
+
+    // Test create surface doesn't return an error
+    // For the time being KErrArgument will be returned as the core codes are
+    // not ready to check the passed in shared chunk handle.
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buff, iSurfaceIdNew, handle));
+
+    // Create a semaphore
+    RSemaphore sem;
+    TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+    CleanupClosePushL(sem); 
+    
+    // Create a second thread in the current process and opens the handle
+    iInfo.iSurfaceManager = iSurfaceManager;
+    iInfo.iSurfaceId = iSurfaceId;
+    iInfo.iSurfaceIdNew = iSurfaceIdNew;
+    iInfo.iThreadTestCase = ECloseBothSurfaces; 
+    // Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+        
+    RThread thread5;
+    _LIT(KNameThreadSecond5, "Test_SurfaceManager_ThreadSecond5");
+    User::LeaveIfError(thread5.Create(KNameThreadSecond5,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+    CleanupStack::Pop();
+    // Launch second thread
+    TRequestStatus statusThreadSecond;
+    thread5.Logon(statusThreadSecond);
+    thread5.SetPriority(EPriorityLess);
+    thread5.Resume();   
+    testResult = EAllZero;
+    // Passes control to the second process
+    sem.Wait();
+    thread5.Suspend();
+
+    // Test results in second thread
+    TEST (testResult = (ECloseSurfaceTestPassed | ESurfaceInfoTestPassed | ESurfaceInfoTestPassed2));
+    RSurfaceManager::TInfoBuf infoBuf;
+    TEST (KErrArgument == iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
+    TEST (KErrArgument == iSurfaceManager.SurfaceInfo(iSurfaceIdNew, infoBuf));
+
+    // Pass control off to the second process again
+    thread5.Resume();
+
+    // Wait for a second for the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+    CleanupStack::PopAndDestroy(1, &sem);  //invoke surface manager to close the surface also close the handle to RSemaphore
+    handle.Close();
+    thread5.Close();
+    iSurfaceManager.Close();
+    }
+
+void CTSurfaceManagerMultiThread::TestCloseSurfaceClosedThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+    // Logging info
+    INFO_PRINTF1(_L("Test closing an surface which is already closed in other thread return KErrArgument\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	RSemaphore semMain;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+    CleanupClosePushL(sem);	
+    TEST(KErrNone == semMain.CreateGlobal(KMainThreadSemaphore, 0));
+    CleanupClosePushL(semMain);	
+
+ 	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateSurfaceClose;	
+	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread6;
+    _LIT(KNameThreadSecond6, "Test_SurfaceManager_ThreadSecond6");
+	User::LeaveIfError(thread6.Create(KNameThreadSecond6,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+    CleanupStack::Pop();
+    // Launch second thread
+	TRequestStatus statusThreadSecond;
+	thread6.Logon(statusThreadSecond);
+	thread6.SetPriority(EPriorityLess);
+	thread6.Resume();	
+	testResult = EAllZero;
+  	// Passes control to the second thread
+    sem.Wait(); 
+    // Test creating surface in second thread
+   	TEST(testResult == ECreateSurfaceTestPassed);
+   	testResult = EAllZero;
+    // Test closing surface
+    iSurfaceId = globalSurfaceId;
+	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+    	
+	semMain.Signal();
+	// Wait for a second for the second process to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+    TEST(testResult == ECloseSurfaceTestFailed);
+    // Close all the handles
+    CleanupStack::PopAndDestroy(2, &sem);
+    thread6.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceOpenedClosedThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+	
+	// Test create surface doesn't return an error
+	TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    // Logging info
+    INFO_PRINTF1(_L("Test accessing an surface which is already opened and closed in another thread, given that the process still owns the surface\r\n"));
+ 	// Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+    CleanupClosePushL(sem);	
+
+	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = EOpenCloseSurface;	
+ 	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+	
+    RThread thread7;
+    _LIT(KNameThreadSecond7, "Test_SurfaceManager_ThreadSecond7");
+	User::LeaveIfError(thread7.Create(KNameThreadSecond7,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+   	
+    // Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread7.Logon(statusThreadSecond);
+	thread7.SetPriority(EPriorityLess);
+	thread7.Resume();
+	testResult = EAllZero;
+	sem.Wait();	  
+	
+	thread7.Suspend();
+	// Test open and close surface in the second thread
+	TEST(testResult == (EOpenSurfaceTestPassed|ECloseSurfaceTestPassed));
+	
+	RChunk handle;
+	// To prove killing threads doesnt affect the ref count...
+	TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId, handle));
+	handle.Close();
+	
+	RSurfaceManager::TInfoBuf infoBuf;
+	TEST(KErrNone ==iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
+	
+	thread7.Resume();
+	
+	// Wait for a second for the second process to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+	// Close all the handles
+    CleanupStack::PopAndDestroy(1, &sem);
+    thread7.Close();
+	iSurfaceManager.Close();
+	}	
+
+void CTSurfaceManagerMultiThread::TestCloseSurfaceOpenedClosedThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+
+	// Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    
+    INFO_PRINTF1(_L("Test closing an surface which is already opened and closed in another thread, given that the process still owns the surface\r\n"));
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+   	CleanupClosePushL(sem);
+
+	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = EOpenCloseSurface;	
+ 
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread8;
+    _LIT(KNameThreadSecond8, "Test_SurfaceManager_ThreadSecond8");
+	User::LeaveIfError(thread8.Create(KNameThreadSecond8,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+    CleanupStack::Pop();
+	TRequestStatus statusThreadSecond;
+	thread8.Logon(statusThreadSecond);
+	thread8.SetPriority(EPriorityLess);
+	thread8.Resume();
+	testResult = EAllZero;
+	sem.Wait();	
+	thread8.Suspend();
+	// Test open and close surface in the second thread
+	TEST(testResult == (EOpenSurfaceTestPassed|ECloseSurfaceTestPassed));
+
+	thread8.Resume();
+	// Wait for a second for the second process to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+	// Close all the handles 
+    CleanupStack::PopAndDestroy(1, &sem);
+    thread8.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceOpenedKilledThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+
+	// Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    
+    INFO_PRINTF1(_L("Test accessing surface in another thread when the opening thread is killed\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+
+	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = EOpenKillSurface;	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread9;
+    _LIT(KNameThreadSecond9, "Test_SurfaceManager_ThreadSecond9");
+	User::LeaveIfError(thread9.Create(KNameThreadSecond9,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+	CleanupStack::Pop();
+	// Launch the second thraed
+	TRequestStatus statusThreadSecond;
+	thread9.Logon(statusThreadSecond);
+	thread9.SetPriority(EPriorityLess);
+	thread9.Resume();
+	// Waiting the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+   	RChunk handle;
+	// Test the surface is still accessible
+	TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId, handle));
+	handle.Close();
+	
+	RSurfaceManager::TInfoBuf infoBuf;
+	TEST(KErrNone ==iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf));
+	
+    // Close all the handles
+    CleanupStack::PopAndDestroy(1, &sem);
+    thread9.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestCloseSurfaceOpenedKilledThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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 a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+	
+	// Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    // Logging info
+    INFO_PRINTF1(_L("Test closing surface in another thread when the opening thread is killed\r\n"));
+  	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = EOpenKillSurface;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread10;
+    _LIT(KNameThreadSecond10, "Test_SurfaceManager_ThreadSecond10");
+	User::LeaveIfError(thread10.Create(KNameThreadSecond10,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+	// Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread10.Logon(statusThreadSecond);
+	thread10.SetPriority(EPriorityLess);
+	thread10.Resume();
+	// Waiting the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+    // Test closing surface
+	TEST(KErrNone ==iSurfaceManager.CloseSurface(iSurfaceId));
+	
+	// Close all the handles
+	CleanupStack::PopAndDestroy(1, &sem);
+	thread10.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceCreateKilledThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+	
+    // Logging info
+    INFO_PRINTF1(_L("Test accessing surface in another thread when the creating thread is killed\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+
+  	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateKillSurface;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread11;
+    _LIT(KNameThreadSecond11, "Test_SurfaceManager_ThreadSecond11");
+	User::LeaveIfError(thread11.Create(KNameThreadSecond11,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+    // Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread11.Logon(statusThreadSecond);
+	thread11.SetPriority(EPriorityLess);
+	thread11.Resume();
+	testResult = EAllZero;
+	sem.Wait();	
+	// Test creating surface in the second thread
+	TEST(testResult = ECreateSurfaceTestPassed);
+    // Test closing surface
+   	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+    // Wait the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+
+    // Test the surface is not accessible any more
+   	RChunk handle;
+	TEST(KErrArgument == iSurfaceManager.MapSurface(globalSurfaceId, handle));
+	handle.Close();
+	RSurfaceManager::TInfoBuf infoBuf;
+	TEST(KErrArgument ==iSurfaceManager.SurfaceInfo(globalSurfaceId, infoBuf));
+ 	// Close all the handles
+	CleanupStack::PopAndDestroy(1, &sem);
+	thread11.Close();
+	iSurfaceManager.Close();
+    }
+	
+/**
+	210 Test closing surface in another thread when the creating thread is killed
+	Thread 2: Create Surface 
+	Thread 1: Close Surface
+	Thread 2: Kill the thread
+	Thread 1: Close Surface - KErrArgument
+*/
+void CTSurfaceManagerMultiThread::TestCloseSurfaceCreateKilledThreadL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+
+    // Logging info
+    INFO_PRINTF1(_L("Test closing surface in another thread when the creating thread is killed\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+
+  	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateKillSurface;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread12;
+    _LIT(KNameThreadSecond12, "Test_SurfaceManager_ThreadSecond12");
+	User::LeaveIfError(thread12.Create(KNameThreadSecond12,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+    // Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread12.Logon(statusThreadSecond);
+	thread12.SetPriority(EPriorityLess);
+	thread12.Resume();
+	sem.Wait();	
+	// Test creating surface in the second thread
+	TEST(testResult = ECreateSurfaceTestPassed);
+    // Test closing surface
+   	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+    // Wait the second thread to terminate
+    User::WaitForRequest(statusThreadSecond);
+     
+	// Test the surface is removed and not closable   	
+	TEST(KErrArgument ==iSurfaceManager.CloseSurface(globalSurfaceId));
+    // Close the handles
+   	CleanupStack::PopAndDestroy(1, &sem);
+   	thread12.Close();
+	iSurfaceManager.Close();
+	}
+	
+void CTSurfaceManagerMultiThread::TestAccessSurfaceThreeThreadsL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+	
+	// Test create surface doesn't return an error
+    TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId));
+    // Logging info
+    INFO_PRINTF1(_L("Test closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore,0));
+	CleanupClosePushL(sem);
+
+   	// Creates a second thread in the current process and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = EOpenCloseSurfaceMultiThread;	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread13;
+    _LIT(KNameThreadSecond13, "Test_SurfaceManager_ThreadSecond13");
+	User::LeaveIfError(thread13.Create(KNameThreadSecond13,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+    // Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread13.Logon(statusThreadSecond);
+	thread13.SetPriority(EPriorityLess);
+	thread13.Resume();
+	testResult = EAllZero;
+	sem.Wait();	
+	TEST(testResult == EOpenSurfaceTestPassed);
+	testResult = EAllZero;
+
+	// Create a third thread in the same process and opens the handle
+	iInfo2 = iInfo;
+	iInfo2.iThreadTestCase = EOpenMapSurfaceInfoMultiThread;	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2));
+
+    RThread thread13_2;
+    _LIT(KNameThreadSecond13_2, "Test_SurfaceManager_ThreadSecond13_2");
+	User::LeaveIfError(thread13_2.Create(KNameThreadSecond13_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2));
+	CleanupStack::Pop();
+	// Launch the third thread
+	TRequestStatus statusThreadThird;
+	thread13_2.Logon(statusThreadThird);
+	thread13_2.SetPriority(EPriorityLess);
+	thread13_2.Resume();
+	sem.Wait();
+	TEST(testResult == EOpenSurfaceTestPassed);
+	testResult = EAllZero;
+	thread13.Resume();
+    User::WaitForRequest(statusThreadSecond);
+
+	TEST(testResult == ECloseSurfaceTestPassed);
+	testResult = EAllZero;
+
+	thread13_2.Resume();
+    User::WaitForRequest(statusThreadThird);
+
+	TEST(testResult == (EMapSurfaceTestPassed|ESurfaceInfoTestPassed));
+
+	// Close all the handles
+	CleanupStack::PopAndDestroy(1, &sem);
+
+	thread13.Close();
+	thread13_2.Close();
+	iSurfaceManager.Close();
+	}
+
+void CTSurfaceManagerMultiThread::TestAccessSurfaceDieCloseOtherThreadsL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+    // Logging info
+    INFO_PRINTF1(_L("Test surface can be accessed from third thread when creating thread dies and second thread closes\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+
+	// Create a second thread and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateKillSurface;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+
+    RThread thread14;
+    _LIT(KNameThreadSecond14, "Test_SurfaceManager_ThreadSecond14");
+	User::LeaveIfError(thread14.Create(KNameThreadSecond14,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+	// Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread14.Logon(statusThreadSecond);
+	thread14.SetPriority(EPriorityLess);
+	thread14.Resume();
+	testResult = EAllZero;
+	sem.Wait();	
+	//suspend the 2nd thread
+	thread14.Suspend(); 
+	
+	TEST(testResult == ECreateSurfaceTestPassed);
+	testResult = EAllZero;
+	
+	TEST(KErrNone == iSurfaceManager.OpenSurface(globalSurfaceId));
+
+    // Create a third thread in the current process and opens the handle 
+	iInfo2.iSurfaceManager = iSurfaceManager;
+	iInfo2.iSurfaceId = globalSurfaceId;
+	iInfo2.iSurfaceIdNew = iSurfaceId;
+	iInfo2.iThreadTestCase = EOpenCloseMapSurfaceInfoMultiThread;	
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2));
+
+    RThread thread14_2;
+    _LIT(KNameThreadSecond14_2, "Test_SurfaceManager_ThreadSecond14_2");
+	User::LeaveIfError(thread14_2.Create(KNameThreadSecond14_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2));
+   	CleanupStack::Pop();
+    // Launch the third thread
+	TRequestStatus statusThreadThird;
+	thread14_2.Logon(statusThreadThird);
+	thread14_2.SetPriority(EPriorityLess);
+	thread14_2.Resume();
+	sem.Wait();
+	// Test opening the surface in the second thread
+	TEST(testResult == EOpenSurfaceTestPassed);
+	testResult = EAllZero;
+    // Test closing the surface in the main thread
+	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+
+	thread14.Resume();
+    User::WaitForRequest(statusThreadSecond);
+
+    thread14_2.Resume();
+    User::WaitForRequest(statusThreadThird);
+
+	// Test the execution results in the third thread
+	TEST(testResult == (ECloseSurfaceTestPassed|EMapSurfaceTestPassed|ESurfaceInfoTestPassed));	
+
+    // Close all the handles
+    CleanupStack::PopAndDestroy(1, &sem);
+    thread14.Close();
+    thread14_2.Close();
+	iSurfaceManager.Close();
+
+	}
+
+void CTSurfaceManagerMultiThread::TestOpenSurfaceDieCloseOtherThreadsL()
+	{
+	User::LeaveIfError(iSurfaceManager.Open());
+    
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	attributes.iSize = TSize(480,16);
+	attributes.iBuffers = 2;				// number of buffers in the surface
+	attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed;		// 2bpp
+	attributes.iStride = 1013;				// Number of bytes between start of one line and start of next
+	attributes.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
+	attributes.iAlignment = RSurfaceManager::EPageAligned;			// alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
+
+	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;
+
+    // Logging info
+    INFO_PRINTF1(_L("Test that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface\r\n"));
+    // Create a semaphore
+	RSemaphore sem;
+	TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
+	CleanupClosePushL(sem);
+
+    // Create a second thread and opens the handle
+	iInfo.iSurfaceManager = iSurfaceManager;
+	iInfo.iSurfaceId = iSurfaceId;
+	iInfo.iThreadTestCase = ECreateKillSurface;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo));
+    RThread thread15;
+    _LIT(KNameThreadSecond15, "Test_SurfaceManager_ThreadSecond15");
+	User::LeaveIfError(thread15.Create(KNameThreadSecond15,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo));
+   	CleanupStack::Pop();
+   	// Launch the second thread
+	TRequestStatus statusThreadSecond;
+	thread15.Logon(statusThreadSecond);
+	thread15.SetPriority(EPriorityLess);
+	thread15.Resume();
+	testResult = EAllZero;
+	sem.Wait();	
+
+	thread15.Suspend(); //suspend the 2nd thread
+
+	TEST(testResult == ECreateSurfaceTestPassed);
+	testResult = EAllZero;
+	// Test creating the surface in the second thread	
+	TEST(KErrNone == iSurfaceManager.OpenSurface(globalSurfaceId));
+
+	// Create a third thread and opens the handle
+	iInfo2.iSurfaceManager = iSurfaceManager;
+	iInfo2.iSurfaceId = globalSurfaceId;
+	iInfo2.iSurfaceIdNew = iSurfaceId;
+	iInfo2.iThreadTestCase = EOpenCloseOpenMultiThread;	
+
+	// Create a TCleanupItem object
+    CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2));
+    RThread thread15_2;
+    _LIT(KNameThreadSecond15_2, "Test_SurfaceManager_ThreadSecond15_2");
+	User::LeaveIfError(thread15_2.Create(KNameThreadSecond15_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2));
+   	CleanupStack::Pop();
+	// Launch the third thread
+	TRequestStatus statusThreadThird;
+	thread15_2.Logon(statusThreadThird);
+	thread15_2.SetPriority(EPriorityLess);
+	thread15_2.Resume();
+	sem.Wait();
+	// Test opening the surface in the third thread
+	TEST(testResult == EOpenSurfaceTestPassed);
+	// Test closing the surface in the main thread	
+	TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId));
+	thread15.Resume();
+    User::WaitForRequest(statusThreadSecond);
+
+    thread15_2.Resume();
+    User::WaitForRequest(statusThreadThird);
+
+    // Test the surface is still accessible in the third thread
+	TEST(testResult == (ECloseSurfaceTestPassed | EOpenSurfaceTestPassed));
+    // Close the handles
+	CleanupStack::PopAndDestroy(1, &sem);
+	thread15.Close();
+	thread15_2.Close();
+	iSurfaceManager.Close();
+
+	}
+	
+
+/**
+The second thread entry point
+*/
+TInt CTSurfaceManagerMultiThread::ThreadSecondStart(TAny* aInfo)
+	{
+	TInt procHandles1  =0;
+	TInt threadHandles1=0;
+	RThread().HandleCount(procHandles1, threadHandles1);
+	__UHEAP_MARK;
+		
+	CChildThreadWrapper* newThread = new CChildThreadWrapper(aInfo);
+	if (newThread==NULL)
+		{
+		return KErrNoMemory;
+		}
+
+    RSemaphore sem;
+    RSemaphore semMain;
+ 	TInt ret = sem.OpenGlobal(KMultiThreadSemaphore);
+    if (ret == KErrNone)
+    	{
+   		TThreadTestCase testCase = newThread->iThreadTestCase;
+		switch (testCase)
+			{
+			case ECreateSurfaceMapInfo:
+				User::LeaveIfError(semMain.OpenGlobal(KMainThreadSemaphore));
+				newThread->CreateSurfaceThread();
+				sem.Signal();
+				semMain.Wait();
+				newThread->MapSurfaceInfo();
+				delete newThread;
+				semMain.Close();
+				break;
+			case ECreateSurfaceClose:
+				User::LeaveIfError(semMain.OpenGlobal(KMainThreadSemaphore));
+				newThread->CreateSurfaceThread();
+				sem.Signal();
+				semMain.Wait();
+				newThread->CloseSurface();
+				delete newThread;
+				semMain.Close();
+				break;
+			case EMapSurfaceInfo:
+		 		newThread->MapSurfaceInfo();
+		 		sem.Signal();
+				delete newThread;
+				break;
+			case ECloseSurfaces:
+				newThread->CloseSurface();
+				sem.Signal();
+				delete newThread;
+				break;
+			case EOpenCloseSurface:
+				newThread->OpenSurface();
+				newThread->CloseSurface();
+				sem.Signal();
+				delete newThread;
+				break;
+			case EOpenKillSurface:
+				newThread->OpenSurface();
+				delete newThread;
+    			sem.Close();
+    			RThread().Kill(ret);
+				break;
+			case ECreateKillSurface:
+				newThread->CreateSurfaceThread();
+				sem.Signal();
+				delete newThread;
+    			sem.Close();
+    			RThread().Kill(ret);
+				break;
+			case EOpenCloseSurfaceMultiThread:
+				newThread->OpenSurface(); 
+				sem.Signal();
+				RThread().Suspend();
+				newThread->CloseSurface();
+				delete newThread;
+				sem.Close();
+				return ret;
+			case ECloseBothSurfaces:
+				newThread->CloseBothSurfaces();
+				sem.Signal();
+				delete newThread;
+				break;
+			default:
+				break;
+			}
+
+		}
+
+	__UHEAP_MARKEND;
+     
+	sem.Close();	
+	TInt procHandles2  =0;
+	TInt threadHandles2=0;
+	RThread().HandleCount(procHandles2,threadHandles2);
+	if (threadHandles1 != threadHandles2)
+		{
+		ret = KErrGeneral;  // Thread-owned handles not closed
+		}
+
+	return ret;
+	}
+	
+// Implementation of CChildThreadWrapper class 
+CChildThreadWrapper::CChildThreadWrapper(TAny* aInfo) :
+	iSurfaceManager    (((TInfo*)aInfo)->iSurfaceManager),
+	iSurfaceId(((TInfo*)aInfo)->iSurfaceId),
+	iSurfaceIdNew(((TInfo*)aInfo)->iSurfaceIdNew),
+	iThreadTestCase(((TInfo*)aInfo)->iThreadTestCase)
+	{
+	}
+
+CChildThreadWrapper::~CChildThreadWrapper()
+	{
+	}
+
+void CChildThreadWrapper::CreateSurfaceThread()
+	{
+	// Setup attributes
+    RSurfaceManager::TSurfaceCreationAttributesBuf buf;
+	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
+	
+	attributes.iSize = TSize(200,200);
+	attributes.iBuffers = 1;				
+	attributes.iPixelFormat = EUidPixelFormatARGB_1555;		
+	attributes.iStride = 1024;				
+	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(0x124578), 25, ETrue);
+	hints[1].Set(TUid::Uid(0x237755), 50, ETrue);
+
+	attributes.iCacheAttrib = RSurfaceManager::ECached;
+	attributes.iOffsetBetweenBuffers = 0;
+	attributes.iMappable = ETrue;
+
+	if (KErrNone == iSurfaceManager.CreateSurface(buf,iSurfaceId))
+		{
+		testResult |= ECreateSurfaceTestPassed;
+		}
+    else
+    	{
+    	testResult |= ECreateSurfaceTestFailed;	
+	   	}
+		
+	// record the surfaceId as a global variable
+	globalSurfaceId = iSurfaceId;
+	}
+	
+void CChildThreadWrapper::MapSurfaceInfo()
+	{
+	// Access the surface and pass back the test results to the main thread
+	RChunk handle;
+	// Call Map Surface
+	if (iSurfaceManager.MapSurface(iSurfaceId,handle)== KErrNone)
+		{
+		testResult |= EMapSurfaceTestPassed;
+		}
+	else 
+		{
+		testResult |= EMapSurfaceTestFailed;
+		}
+	handle.Close();
+
+	RSurfaceManager::TInfoBuf infoBuf;
+	// Call Surface Info
+	if (iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf) == KErrNone)
+		{
+		testResult |= ESurfaceInfoTestPassed;
+		}
+	else 
+		{
+		testResult |= ESurfaceInfoTestFailed;
+		}
+	} 
+			   
+void CChildThreadWrapper::CloseSurface()
+	{
+	// Call close surface and pass back the results to the main thread
+	if (iSurfaceManager.CloseSurface(iSurfaceId) == KErrNone)
+		{
+		testResult |= ECloseSurfaceTestPassed;
+		}
+	else 
+		{
+		testResult |= ECloseSurfaceTestFailed;
+		}
+	} 
+
+void CChildThreadWrapper::OpenSurface()
+	{
+	// Call close surface and pass back the results to the main thread
+	if (iSurfaceManager.OpenSurface(iSurfaceId) == KErrNone)
+		{
+		testResult |= EOpenSurfaceTestPassed;
+		}
+	else
+		{
+		testResult |= EOpenSurfaceTestFailed;
+		}
+	} 
+		 
+void CChildThreadWrapper::CloseBothSurfaces()
+	{
+	// Call close surface and pass back the results to the main thread
+	if (iSurfaceManager.CloseSurface(iSurfaceIdNew) == KErrNone)
+		{
+		testResult |= ECloseSurfaceTestPassed;
+		}
+	else 
+		{
+		testResult |= ECloseSurfaceTestFailed;
+		}
+	RSurfaceManager::TInfoBuf infoBuf;
+	// Call Surface Info
+	if (iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf) == KErrNone)
+		{
+		testResult |= ESurfaceInfoTestPassed;
+		}
+	else 
+		{
+		testResult |= ESurfaceInfoTestFailed;
+		}
+	
+	if (iSurfaceManager.SurfaceInfo(iSurfaceIdNew, infoBuf) == KErrArgument)
+		{
+		testResult |= ESurfaceInfoTestPassed2;
+		}
+	else 
+		{
+		testResult |= ESurfaceInfoTestFailed2;
+		}
+	iSurfaceManager.CloseSurface(iSurfaceId);
+	}
+/**
+The third thread entry point
+*/
+TInt CTSurfaceManagerMultiThread::ThreadThirdStart(TAny* aInfo)
+	{
+	TInt procHandles1  =0;
+	TInt threadHandles1=0;
+	RThread().HandleCount(procHandles1, threadHandles1);
+	__UHEAP_MARK;
+	CTrapCleanup* cleanupStack=CTrapCleanup::New();
+	if (cleanupStack==NULL)
+		{
+		return KErrNoMemory;
+		}
+		
+	CChildThreadWrapper* newThread = new CChildThreadWrapper(aInfo);
+	if (newThread==NULL)
+		{
+		delete cleanupStack;
+		return KErrNoMemory;
+		}
+		
+	// Pass control back to the first process
+    RSemaphore sem;
+	TInt ret = sem.OpenGlobal(KMultiThreadSemaphore);
+	if (ret!=KErrNone)
+		return ret;
+		
+	TInt err = KErrNone;
+    TThreadTestCase testCase = newThread->iThreadTestCase;
+	switch (testCase)
+		{
+		case EOpenMapSurfaceInfoMultiThread:
+			newThread->OpenSurface();
+			sem.Signal();
+			RThread().Suspend();
+			newThread->MapSurfaceInfo();
+			break;
+		case EOpenCloseMapSurfaceInfoMultiThread:
+			newThread->OpenSurface();
+			sem.Signal();
+			RThread().Suspend();
+			newThread->CloseSurface();
+			newThread->MapSurfaceInfo();
+			break;
+		case EOpenCloseOpenMultiThread:
+			newThread->OpenSurface();
+			sem.Signal();
+			RThread().Suspend();
+			newThread->CloseSurface();
+			newThread->OpenSurface();
+			break;
+		default:
+			break;
+		}
+
+   	delete newThread;
+	delete cleanupStack;
+	__UHEAP_MARKEND;
+	
+    sem.Close();	
+	TInt procHandles2  =0;
+	TInt threadHandles2=0;
+	RThread().HandleCount(procHandles2,threadHandles2);
+	if (threadHandles1 != threadHandles2)
+		{
+		err = KErrGeneral;  // Thread-owned handles not closed
+		}
+
+	return err;
+	}
+
+
+	
+//--------------
+__CONSTRUCT_STEP__(SurfaceManagerMultiThread)
+
+void CTSurfaceManagerMultiThreadStep::TestSetupL()
+	{
+    }
+
+void CTSurfaceManagerMultiThreadStep::TestClose()
+	{
+	}