sl@0: /* sl@0: * Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: /** sl@0: @file sl@0: @test sl@0: @internalComponent Internal Symbian test code sl@0: */ sl@0: sl@0: #include "FNTSTORE.H" sl@0: #include "t_fontsessioncache.h" sl@0: #include "T_IsolatedFontStore.h" sl@0: sl@0: _LIT(KWorkerProcess,"tfontsessioncacheproc"); sl@0: _LIT(KSharedChunk,"TestSharedChunk_T_FontSessionCache"); sl@0: sl@0: const TInt KNumOfProc = 4; sl@0: const TInt KRunningTime = 1000 * 1000 * 5; sl@0: sl@0: //Make sure font is large enough that font and session caches are used sufficiently. sl@0: const TInt KFontHeight = 250; sl@0: sl@0: // This class is a data mirror to CBitmapFont in order to check its private sl@0: // member iOpenFont. It is only used by TestOpenFontForQtL(). sl@0: class CBitmapFontDummy:public CFont sl@0: { sl@0: public: sl@0: TFontSpec iFontSpecInTwips; sl@0: TAlgStyle iAlgStyle; sl@0: RHeap* iHeap; sl@0: TInt iFontBitmapOffset; sl@0: COpenFont* iOpenFont; sl@0: TUint32 iReserved; sl@0: TUint32 iUniqueFontId; sl@0: }; sl@0: sl@0: class CTFontSessionCache : public CTGraphicsBase sl@0: { sl@0: public: sl@0: CTFontSessionCache(CTestStep* aStep); sl@0: ~CTFontSessionCache(); sl@0: TInt Base(); sl@0: sl@0: protected: sl@0: // From CTGraphicsStep sl@0: virtual void RunTestCaseL(TInt aCurTestCase); sl@0: virtual void ConstructL(); sl@0: private: sl@0: void TestOpenFontForQtL(); sl@0: void RunMultiWorkerProcessL(); sl@0: sl@0: void FlushCaches(); sl@0: sl@0: private: sl@0: CTIsolatedFontStore *iIFontStore; sl@0: RHeap *iSharedHeap; sl@0: RChunk iChunk; sl@0: CFont *iFont; sl@0: }; sl@0: sl@0: CTFontSessionCache::CTFontSessionCache(CTestStep* aStep) sl@0: : CTGraphicsBase(aStep) sl@0: { sl@0: sl@0: } sl@0: sl@0: CTFontSessionCache::~CTFontSessionCache() sl@0: { sl@0: iIFontStore->iFs->ReleaseFont(iFont); sl@0: delete iIFontStore; sl@0: iChunk.Close(); sl@0: } sl@0: sl@0: inline TInt CTFontSessionCache::Base() sl@0: { sl@0: return reinterpret_cast(iChunk.Base()); sl@0: } sl@0: sl@0: void CTFontSessionCache::ConstructL() sl@0: { sl@0: User::LeaveIfError(iChunk.CreateGlobal(KNullDesC,0x10000,0x10000)); sl@0: iSharedHeap = UserHeap::ChunkHeap(iChunk,0x10000,0x1000,0x10000,0,EFalse,0); sl@0: if(iSharedHeap == NULL) sl@0: { sl@0: RDebug::Print(_L("iSharedHeap = NULL")); sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: iIFontStore = CTIsolatedFontStore::NewL(iSharedHeap); sl@0: iIFontStore->LoadRasterizersL(); sl@0: iIFontStore->iFs->LoadFontsAtStartupL(); sl@0: sl@0: _LIT(KTypefaceName, "DejaVu Sans Condensed"); sl@0: TFontSpec spec(KTypefaceName, KFontHeight); sl@0: sl@0: TInt ret = iIFontStore->iFs->GetNearestFontToDesignHeightInPixels(iFont,spec); sl@0: TEST(ret == KErrNone); sl@0: sl@0: } sl@0: sl@0: void CTFontSessionCache::FlushCaches() sl@0: { sl@0: TText ch; sl@0: TOpenFontGlyphData *glyphData = NULL; sl@0: for (TInt sHandle = 0; sHandle < KNumOfProc; sHandle++) sl@0: { sl@0: for (ch = 'A'; ch <= 'z'; ch++) sl@0: { sl@0: static_cast (iFont)->Rasterize(sHandle, ch, glyphData); sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID sl@0: TI18N-FNTSTORE-UT--4003 sl@0: sl@0: @SYMTestCaseDesc sl@0: Qt needs the last bit of iOpenFont to be set 1 as a workaround to maintain sl@0: its compatibility across difference Symbian OS versions. sl@0: sl@0: @SYMTestActions sl@0: 1. Get a CBitmapFont in the constructor sl@0: 2. Check the LSB of its iOpenFont by using CBitmapFontDummy sl@0: sl@0: @SYMTestExpectedResults sl@0: Test should pass sl@0: */ sl@0: sl@0: void CTFontSessionCache::TestOpenFontForQtL() sl@0: { sl@0: TEST(reinterpret_cast(reinterpret_cast(iFont)->iOpenFont) & 1); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID sl@0: TI18N-FNTSTORE-CIT-4002 sl@0: sl@0: @SYMTestCaseDesc sl@0: This case is to test the safty of actions over the shared heap. sl@0: sl@0: @SYMTestActions sl@0: 1. Shared heap is initialised in the constructor sl@0: 2. Run rasterizing function to Flush the font caches(glyph tree and session cache). sl@0: 3. Launch KNumOfProc worker processes running with random latency at beginning, which sl@0: is to seach the cache from different processes. The globle chunk and font handles are sl@0: passed via process environment variables. sl@0: 4. Each one lasts about 1 sec. Within duration of 5 sec, if one terminates, re-launch it. sl@0: sl@0: @SYMTestExpectedResults sl@0: Test should pass without any Panic. sl@0: */ sl@0: void CTFontSessionCache::RunMultiWorkerProcessL() sl@0: { sl@0: RProcess ProcArray[KNumOfProc]; sl@0: TRequestStatus *completeStatus[KNumOfProc]; sl@0: sl@0: FlushCaches(); sl@0: sl@0: for (TInt i = 0; i < KNumOfProc; i++) sl@0: { sl@0: RDebug::Print(_L(">>> Launching %d..."),i); sl@0: TInt err; sl@0: err = ProcArray[i].Create(KWorkerProcess, KNullDesC); sl@0: User::LeaveIfError(err); sl@0: sl@0: TInt FontOffset = reinterpret_cast(iFont) - Base(); sl@0: ProcArray[i].SetParameter(1,iChunk); sl@0: ProcArray[i].SetParameter(2,FontOffset); sl@0: ProcArray[i].SetParameter(3,i); sl@0: sl@0: completeStatus[i] = new(ELeave) TRequestStatus; sl@0: CleanupStack::PushL(completeStatus[i]); sl@0: *completeStatus[i] = KRequestPending; sl@0: sl@0: ProcArray[i].Logon(*completeStatus[i]); sl@0: ProcArray[i].Resume(); //start the process sl@0: } sl@0: sl@0: RTimer timer; sl@0: timer.CreateLocal(); sl@0: TRequestStatus timerStatus = KRequestPending; sl@0: TTimeIntervalMicroSeconds32 timeout(KRunningTime); sl@0: timer.After(timerStatus, timeout); sl@0: sl@0: do sl@0: { sl@0: User::WaitForNRequest(completeStatus, KNumOfProc); sl@0: TInt i = 0; sl@0: for(;i < KNumOfProc;i++ ) sl@0: { sl@0: if (*completeStatus[i] != KRequestPending) sl@0: { sl@0: break; sl@0: } sl@0: } sl@0: sl@0: TExitType exit = ProcArray[i].ExitType(); sl@0: TEST(exit == EExitKill); sl@0: TInt reason = ProcArray[i].ExitReason(); sl@0: TEST (reason == 0); sl@0: sl@0: RDebug::Print(_L("<<< Close %d..."), i); sl@0: ProcArray[i].Close(); sl@0: sl@0: RDebug::Print(_L(">>> Launching %d..."), i); sl@0: TInt err; sl@0: err = ProcArray[i].Create(KWorkerProcess, KNullDesC); sl@0: User::LeaveIfError(err); sl@0: sl@0: TInt FontOffset = reinterpret_cast(iFont) - Base(); sl@0: ProcArray[i].SetParameter(1,iChunk); sl@0: ProcArray[i].SetParameter(2,FontOffset); sl@0: ProcArray[i].SetParameter(3,i); sl@0: sl@0: //run process 1 sl@0: *completeStatus[i] = KRequestPending; sl@0: ProcArray[i].Logon(*completeStatus[i]); sl@0: ProcArray[i].Resume(); //start the process sl@0: } sl@0: while (timerStatus == KRequestPending); sl@0: sl@0: for (TInt i = 0; i < KNumOfProc; i++) sl@0: { sl@0: if(*completeStatus[i] == KRequestPending) sl@0: { sl@0: User::WaitForRequest(*completeStatus[i]); sl@0: } sl@0: RDebug::Print(_L("<<< Tear down Close %d..."),i); sl@0: ProcArray[i].Close(); //tear down sl@0: } sl@0: CleanupStack::PopAndDestroy(KNumOfProc); sl@0: } sl@0: sl@0: void CTFontSessionCache::RunTestCaseL( TInt aCurTestCase ) sl@0: { sl@0: ((CTFontSessionCacheStep*) iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); sl@0: sl@0: switch (aCurTestCase) sl@0: { sl@0: case 1: sl@0: ((CTFontSessionCacheStep*) iStep)->SetTestStepID(_L("TI18N-FNTSTORE-UT--4003")); sl@0: INFO_PRINTF1(_L("Test CBitmapFont::iOpenFont last bit for Qt\n")); sl@0: TestOpenFontForQtL(); sl@0: break; sl@0: sl@0: case 2: sl@0: ((CTFontSessionCacheStep*) iStep)->SetTestStepID(_L("TI18N-FNTSTORE-CIT-4002")); sl@0: INFO_PRINTF1(_L("Test GetCharacterData() in muti-process client\n")); sl@0: RunMultiWorkerProcessL(); sl@0: break; sl@0: sl@0: case 3: sl@0: ((CTFontSessionCacheStep*) iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); sl@0: ((CTFontSessionCacheStep*) iStep)->CloseTMSGraphicsStep(); sl@0: TestComplete(); sl@0: break; sl@0: } sl@0: ((CTFontSessionCacheStep*)iStep)->RecordTestResultL(); sl@0: } sl@0: sl@0: // -------------- sl@0: __CONSTRUCT_STEP__(FontSessionCache)