fontservices/fontstore/tfs/t_fontsessioncache.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 06 Jul 2010 16:23:19 +0300
changeset 44 601ab138ba0b
parent 21 f2f7b3284356
child 51 a7c938434754
permissions -rw-r--r--
Revision: 201027 Kit: 2010127

/*
* Copyright (c) 2006-2010 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 Internal Symbian test code
*/

#include "FNTSTORE.H"
#include "t_fontsessioncache.h"
#include "T_IsolatedFontStore.h"

_LIT(KWorkerProcess,"tfontsessioncacheproc");
_LIT(KSharedChunk,"TestSharedChunk_T_FontSessionCache");

const TInt KNumOfProc = 4;
const TInt KRunningTime = 1000 * 1000 * 5;

//Make sure font is large enough that font and session caches are used sufficiently. 
const TInt KFontHeight = 250;   

// This class is a data mirror to CBitmapFont in order to check its private 
// member iOpenFont. It is only used by TestOpenFontForQtL().
class CBitmapFontDummy:public CFont
    {
public:
    TFontSpec iFontSpecInTwips;
    TAlgStyle iAlgStyle;        
    RHeap* iHeap;
    TInt iFontBitmapOffset;
    COpenFont* iOpenFont; 
    TUint32 iReserved;
    TUint32 iUniqueFontId;     
    };

class CTFontSessionCache : public CTGraphicsBase
    {
public:
    CTFontSessionCache(CTestStep* aStep);
    ~CTFontSessionCache();
    TInt Base();

protected:
// From CTGraphicsStep
    virtual void RunTestCaseL(TInt aCurTestCase);
    virtual void ConstructL();
private:
    void TestOpenFontForQtL();
    void RunMultiWorkerProcessL();
    
    void FlushCaches();
    
private:
    CTIsolatedFontStore *iIFontStore;
    RHeap   *iSharedHeap;
    RChunk  iChunk;
    CFont *iFont;
    };

CTFontSessionCache::CTFontSessionCache(CTestStep* aStep)
 :  CTGraphicsBase(aStep)
    {

    }

CTFontSessionCache::~CTFontSessionCache()
    {
    iIFontStore->iFs->ReleaseFont(iFont);
    delete iIFontStore;
    iChunk.Close(); 
    }

inline TInt CTFontSessionCache::Base() 
    {
    return reinterpret_cast<TInt>(iChunk.Base());
    }

void CTFontSessionCache::ConstructL()
    {
    User::LeaveIfError(iChunk.CreateGlobal(KNullDesC,500,500));
    iSharedHeap = UserHeap::ChunkHeap(iChunk,0x10000,0x1000,0x10000,0,EFalse,0);
    if(iSharedHeap == NULL)
        {
        RDebug::Print(_L("iSharedHeap = NULL"));
        User::Leave(KErrNoMemory);
        }
    iIFontStore = CTIsolatedFontStore::NewL(iSharedHeap);
    iIFontStore->LoadRasterizersL();
    iIFontStore->iFs->LoadFontsAtStartupL();
    
    _LIT(KTypefaceName, "DejaVu Sans Condensed");
    TFontSpec spec(KTypefaceName, KFontHeight);   
    
    TInt ret = iIFontStore->iFs->GetNearestFontToDesignHeightInPixels(iFont,spec);
    TEST(ret == KErrNone);
 
    }

void CTFontSessionCache::FlushCaches()
    {
    TText ch;
    TOpenFontGlyphData *glyphData = NULL;
    for (TInt sHandle = 0; sHandle < KNumOfProc; sHandle++)
        {
        for (ch = 'A'; ch <= 'z'; ch++)
            {
            static_cast<CBitmapFont*> (iFont)->Rasterize(sHandle, ch, glyphData);
            }
        }
    }

/**
    @SYMTestCaseID
    TI18N-FNTSTORE-UT--4003

    @SYMTestCaseDesc
    Qt needs the last bit of iOpenFont to be set 1 as a workaround to maintain
    its compatibility across difference Symbian OS versions.

    @SYMTestActions
    1. Get a CBitmapFont in the constructor
    2. Check the LSB of its iOpenFont by using CBitmapFontDummy
        
    @SYMTestExpectedResults
    Test should pass
*/

void CTFontSessionCache::TestOpenFontForQtL()
    {    
    TEST(reinterpret_cast<TInt>(reinterpret_cast<CBitmapFontDummy*>(iFont)->iOpenFont) & 1);
    }

/**
    @SYMTestCaseID
    TI18N-FNTSTORE-CIT-4002

    @SYMTestCaseDesc
    This case is to test the safty of actions over the shared heap.

    @SYMTestActions
    1. Shared heap is initialised in the constructor
    2. Run rasterizing function to Flush the font caches(glyph tree and session cache).
    3. Launch KNumOfProc worker processes running with random latency at beginning, which
       is to seach the cache from different processes. The globle chunk and font handles are
       passed via process environment variables.
    4. Each one lasts about 1 sec. Within duration of 5 sec, if one terminates, re-launch it.   
        
    @SYMTestExpectedResults
    Test should pass without any Panic.
*/
void CTFontSessionCache::RunMultiWorkerProcessL()
    {
    RProcess ProcArray[KNumOfProc];
    TRequestStatus *completeStatus[KNumOfProc];

    FlushCaches();
    
    for (TInt i = 0; i < KNumOfProc; i++)
        {                    
        RDebug::Print(_L(">>> Launching %d..."),i);
        TInt err;
        err = ProcArray[i].Create(KWorkerProcess, KNullDesC);
        User::LeaveIfError(err);

        TInt FontOffset = reinterpret_cast<TInt>(iFont) - Base();
        ProcArray[i].SetParameter(1,iChunk);        
        ProcArray[i].SetParameter(2,FontOffset);
        ProcArray[i].SetParameter(3,i);
        
        completeStatus[i] = new(ELeave) TRequestStatus; 
        CleanupStack::PushL(completeStatus[i]);
        *completeStatus[i] = KRequestPending;
        
        ProcArray[i].Logon(*completeStatus[i]);
        ProcArray[i].Resume(); //start the process
        }
      
    RTimer timer;
    timer.CreateLocal();
    TRequestStatus timerStatus = KRequestPending;
    TTimeIntervalMicroSeconds32 timeout(KRunningTime);
    timer.After(timerStatus, timeout);
    
    do
        {     
        User::WaitForNRequest(completeStatus, KNumOfProc);
        TInt i = 0;
        for(;i < KNumOfProc;i++ )
            {
                if (*completeStatus[i] != KRequestPending)
                {
                break;
                }
            }

        TExitType exit = ProcArray[i].ExitType();
        TEST(exit == EExitKill);
        TInt reason = ProcArray[i].ExitReason();
        TEST (reason == 0);

        RDebug::Print(_L("<<< Close %d..."), i);
        ProcArray[i].Close();

        RDebug::Print(_L(">>> Launching %d..."), i);
        TInt err;
        err = ProcArray[i].Create(KWorkerProcess, KNullDesC);
        User::LeaveIfError(err);
        
        TInt FontOffset = reinterpret_cast<TInt>(iFont) - Base();
        ProcArray[i].SetParameter(1,iChunk);        
        ProcArray[i].SetParameter(2,FontOffset);
        ProcArray[i].SetParameter(3,i);
        
        //run process 1
        *completeStatus[i] = KRequestPending;
        ProcArray[i].Logon(*completeStatus[i]);
        ProcArray[i].Resume(); //start the process
        }
    while (timerStatus == KRequestPending);
    
    for (TInt i = 0; i < KNumOfProc; i++)
        {
        if(*completeStatus[i] == KRequestPending)
            {
            User::WaitForRequest(*completeStatus[i]);
            }       
        RDebug::Print(_L("<<< Tear down Close %d..."),i);
        ProcArray[i].Close(); //tear down
        }        
    CleanupStack::PopAndDestroy(KNumOfProc);
    }

void CTFontSessionCache::RunTestCaseL( TInt aCurTestCase )
    {
    ((CTFontSessionCacheStep*) iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);

    switch (aCurTestCase)
        {
        case 1:
            ((CTFontSessionCacheStep*) iStep)->SetTestStepID(_L("TI18N-FNTSTORE-UT--4003"));
            INFO_PRINTF1(_L("Test CBitmapFont::iOpenFont last bit for Qt\n"));
            TestOpenFontForQtL();
            break;

        case 2:
            ((CTFontSessionCacheStep*) iStep)->SetTestStepID(_L("TI18N-FNTSTORE-CIT-4002"));
            INFO_PRINTF1(_L("Test GetCharacterData() in muti-process client\n"));
            RunMultiWorkerProcessL();
            break;
            
        case 3:
            ((CTFontSessionCacheStep*) iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
            ((CTFontSessionCacheStep*) iStep)->CloseTMSGraphicsStep();
            TestComplete();
            break;
        }
    ((CTFontSessionCacheStep*)iStep)->RecordTestResultL();
    }

// --------------
__CONSTRUCT_STEP__(FontSessionCache)