diff -r 5d03bc08d59c -r 01a6848ebfd7 graphicsresourceservices/graphicsresourceimplementation/test/src/tgraphicsresourcesecondprocess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsresourceservices/graphicsresourceimplementation/test/src/tgraphicsresourcesecondprocess.cpp Fri Apr 16 16:21:04 2010 +0300 @@ -0,0 +1,401 @@ +// 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: +// + +/** + @file + @test + @internalComponent - Graphics Resource API Conformance Test Suite +*/ + +#include +#include "tgraphicsresourcemultiprocessthread.h" +#include "tgraphicsresourceteststepbase.h" + +/** +Helper function to test the equivalence of two TSgImageInfo structures. + +@param aInfo1 A TSgImageInfo structure to compare. +@param aInfo2 A TSgImageInfo structure to compare. + +@return ETrue if the two are identical, EFalse otherwise. +*/ +TBool CompareInfos(TSgImageInfo& aInfo1, TSgImageInfo& aInfo2) + { + TBool result = EFalse; + if(aInfo1.iPixelFormat == aInfo2.iPixelFormat + && aInfo1.iSizeInPixels == aInfo2.iSizeInPixels + && aInfo1.iUsage | aInfo2.iUsage) + { + result = ETrue; + } + return result; + } + +/** +Opens an image in a different process. +@param aInfo The test information passed from outside the current thread +@return The test result indicating which tests passed +*/ +TInt TestOpenImageL(TSgProcessTestInfo& aInfo) + { + TSgDrawableId id = aInfo.iDrawableId; + TSgImageInfo imageInfo1 = aInfo.iImageInfo; + + RSgImage image; + TInt result = 0; + + if(KErrNone == image.Open(id)) + { + result |= EFirstTestPassed; + } + + TSgImageInfo imageInfo2; + TInt attribVal = KMaxTInt; + if(KErrNone == image.GetInfo(imageInfo2)) + { + result |= ESecondTestPassed; + } + if(CompareInfos(imageInfo1, imageInfo2)) + { + result |= EThirdTestPassed; + } + if (image.Id() != KSgNullDrawableId) + { + result |= EFourthTestPassed; + } + if(image.Id() == id) + { + result |= EFifthTestPassed; + } + if (id == aInfo.iDrawableId) + { + result |= ESixthTestPassed; + } + TUid uid = { 0x12345678 }; + if (KErrNotSupported == image.GetAttribute(uid, attribVal)) + { + result |= ESeventhTestPassed; + } + if (KErrArgument == image.GetAttribute(KNullUid, attribVal)) + { + result |= EEighthTestPassed; + } + image.Close(); + + return result; + } + +/** +Opens an image in a different process into a RSgDrawable object. +@param aInfo The test information passed from outside the current thread +@return The test result indicating which tests passed +*/ +TInt TestOpenDrawableL(TSgProcessTestInfo& aInfo) + { + TSgDrawableId id = aInfo.iDrawableId; + + RSgDrawable drawable; + TInt result = 0; + + if(KErrNone == drawable.Open(id)) + { + result |= EFirstTestPassed; + } + TSgDrawableId id2 = drawable.Id(); + if(id2 != KSgNullDrawableId) + { + result |= ESecondTestPassed; + } + if(id2 == id) + { + result |= EThirdTestPassed; + } + + drawable.Close(); + return result; + } + +/** +Opens an image in a different process with different invalid operations. +@param aInfo The test information passed from outside the current thread +@return The test result indicating which tests passed +*/ +TInt TestOpenImageInvalidL(TSgProcessTestInfo& aInfo) + { + TSgDrawableId id = aInfo.iDrawableId; + TSgImageInfo imageInfo = aInfo.iImageInfo; + + RSgImage image; + TInt result = 0; + + //create image + if(KErrNone == image.Create(imageInfo, NULL, 0)) + { + result |= EFirstTestPassed; + } + // non-empty handle + if(KErrInUse == image.Open(id)) + { + result |= ESecondTestPassed; + } + image.Close(); + + // null drawable id + if(KErrArgument == image.Open(KSgNullDrawableId)) + { + result |= EThirdTestPassed; + } + image.Close(); + + // non-existing drawable id + TSgDrawableId fakeid = {0xFFFFFFFFFFFFFFFFU}; + if(KErrNotFound == image.Open(fakeid)) + { + result |= EFourthTestPassed; + } + image.Close(); + + //Valid Drawable Id + if (KErrNone == image.Open(id)) + { + result |= EFifthTestPassed; + } + image.Close(); + return result; + } + +/** +Opens a drawable in a different process with different invalid operations. +@param aInfo The test information passed from outside the current thread +@return The test result indicating which tests passed +*/ +TInt TestOpenDrawableInvalidL() + { + RSgDrawable drawable; + TInt result = 0; + + //null drawable id + if(KErrArgument == drawable.Open(KSgNullDrawableId)) + { + result |= EFirstTestPassed; + } + drawable.Close(); + + //non-existing drawable id + TSgDrawableId fakeid = {0xFFFFFFFFFFFFFFFFU}; + if(KErrNotFound == drawable.Open(fakeid)) + { + result |= ESecondTestPassed; + } + drawable.Close(); + + //non-empty handle + //create an image + TSgImageInfo info1; + info1.iSizeInPixels = TSize(8, 8); + info1.iUsage = ESgUsageBitOpenVgImage; + info1.iPixelFormat = EUidPixelFormatRGB_565; + + + RSgImage image; + TInt err = image.Create(info1, NULL, 0); + if(KErrNoMemory == err) + { + result = KErrNoMemory; + } + else if(KErrNone != err) + { + result = err; + } + else + { + if(KErrNone == drawable.Open(image.Id())) + { + result |= EThirdTestPassed; + + if (KErrInUse == drawable.Open(image.Id())) + { + result |= EFourthTestPassed; + } + } + drawable.Close(); + } + image.Close(); + return result; + } + +TInt TestCloseDriverOpenResources(RSgDriver& aDriver) + { + RSgImage image; + TSgImageInfo info1; + info1.iSizeInPixels = TSize(8, 8); + info1.iUsage = ESgUsageBitOpenVgImage; + info1.iPixelFormat = EUidPixelFormatRGB_565; + + TInt result = image.Create(info1, KCrossImageData, KCrossImageDataStride); + + if (result == KErrNone) + { + //Close the driver without closing the image. + aDriver.Close(); //Should panic with SGRES2 + } + + return result; + } + +/** +Method executed by secondary thread for test TestOpenImageMulththreadedL +*/ +_LIT(KTestOpenImageMultithreadedSem1, "TestOpenImageMulththreadedSem1"); +_LIT(KTestOpenImageMultithreadedSem2, "TestOpenImageMulththreadedSem2"); + +TInt OpenImageMultiSecondThread(TAny* aAny) + { + TInt err = KErrNone; + TSgProcessTestInfo* info = static_cast(aAny); + + RSemaphore sem[2]; + err = sem[0].OpenGlobal(KTestOpenImageMultithreadedSem1, EOwnerThread); + if (err != KErrNone) + { + return err; + } + err = sem[1].OpenGlobal(KTestOpenImageMultithreadedSem2, EOwnerThread); + if (err != KErrNone) + { + sem[0].Close(); + return err; + } + + RSgImage sgImage; + err = sgImage.Open(info->iDrawableId); + + sem[0].Signal(); + sem[1].Wait(); + + sgImage.Close(); + sem[0].Signal(); + return err; + } + +/** +Creates a second thread which will initially open a handle to the passed TSgDrawableId. +The main thread then opens a new handle to the image. +The second thread will then close its handle to the image. +The main thread will then attempt to access the data of the image. + */ +TInt TestOpenImageMulththreadedL(TSgProcessTestInfo& aInfo) + { + TInt result = 0; + + //create a semaphore + RSemaphore sem[2]; + User::LeaveIfError(sem[0].CreateGlobal(KTestOpenImageMultithreadedSem1, 0, EOwnerThread)); + CleanupClosePushL(sem[0]); + User::LeaveIfError(sem[1].CreateGlobal(KTestOpenImageMultithreadedSem2, 0, EOwnerThread)); + CleanupClosePushL(sem[1]); + + //create secondary thread + _LIT(KMultipleThreadName, "TestOpenImageMulththreadedL"); + RThread thread; + TBuf<50> threadName(KMultipleThreadName); + User::LeaveIfError(thread.Create(threadName, OpenImageMultiSecondThread, KDefaultStackSize, KSecondThreadMinHeapSize, KSecondThreadMaxHeapSize, &aInfo)); + thread.Resume(); + + // Make the second thread open the image before this thread. + sem[0].Wait(); + + // Second thread has opened image, now primary thread opens image + RSgImage sgImage; + TInt err = sgImage.Open(aInfo.iDrawableId); + CleanupClosePushL(sgImage); + sem[1].Signal(); + sem[0].Wait(); + + // Second thread has closed image and terminated, now wait for thread to clean-up + User::After(100000); + + if (err == KErrNone) + { + // Do something that requires data access of sgImage, in this case, creating a copy. + result |= EFirstTestPassed; + RSgImage sgImageCopy; + err = sgImageCopy.Create(aInfo.iImageInfo, sgImage); + sgImageCopy.Close(); + if (err == KErrNone) + { + result |= ESecondTestPassed; + } + } + + CleanupStack::PopAndDestroy(3); // sgImage, sem[0], sem[1] + return result; + } + +TInt MainL() + { + TPckgBuf infoPkg; + User::LeaveIfError(User::GetDesParameter(KSecondProcessParametersSlot, infoPkg)); + TSgProcessTestInfo& info = infoPkg(); + TSgresTestCase testCase = info.iTestCase; + TInt result = 0; + + RSgDriver sgDriver; + CleanupClosePushL(sgDriver); + + if(KErrNone == sgDriver.Open()) + { + switch(testCase) + { + case ESgresSecondProcessOpenImage: + result = TestOpenImageL(info); + break; + case ESgresSecondProcessOpenDrawable: + result = TestOpenDrawableL(info); + break; + case ESgresSecondProcessOpenImageInvalid: + result = TestOpenImageInvalidL(info); + break; + case ESgresSecondProcessOpenDrawableInvalid: + result = TestOpenDrawableInvalidL(); + break; + case ESgresSecondProcessPanicDriverCloseOpenResources: + result = TestCloseDriverOpenResources(sgDriver); + break; + case ESgresSecondProcessOpenImageMultithreaded: + result = TestOpenImageMulththreadedL(info); + break; + } + } + + CleanupStack::PopAndDestroy(&sgDriver); + + return result; + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if(cleanupStack == NULL) + { + return KErrNoMemory; + } + TInt ret = 0; + TRAP_IGNORE(ret=MainL()); + delete cleanupStack; + __UHEAP_MARKEND; + return ret; + }