tsrc/testtools/stubsrv/src/stubsrv.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 19 Aug 2010 10:54:11 +0300
branchRCL_3
changeset 22 5b2a402e96ac
permissions -rw-r--r--
Revision: 201031 Kit: 201033

/*
* Copyright (c) 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:
*
*/

#include "stubsrv.h"
#include "stubsrvsession.h"
#include "stubsrvapiexecutor.h"
#include "apibehavior.h"
#include "stubsrvsecuritypolicy.h"

CStubSrv::CStubSrv(TInt aPriority)
  	:CPolicyServer(aPriority, KStubSrvPolicy)
    {
    }

CStubSrv* CStubSrv::NewLC()
    {
    CStubSrv* self = new (ELeave) CStubSrv(EPriorityNormal);
    CleanupStack::PushL(self);
    self->StartL(KStubSrvName);
    self->ConstructL();
    return self;
    }

CStubSrv::~CStubSrv()
    {
    iBehQueue.ResetAndDestroy();
    iBehQueue.Close();
    iSessions.Close();
    delete iTimer;
    }

const TInt KShutdownDelay = 1000000;

void CStubSrv::StartShutdownTimerIfNoSessions()
	{
	if (iSessions.Count() == 0 && !iTimer->IsActive())
		{
		iTimer->Start(KShutdownDelay, 0, TCallBack(CStubSrv::TimerFired, this));
		}
	}

TInt CStubSrv::ClientOpened(CStubSrvSess& aSession)
	{
	return iSessions.Append(&aSession);
	}

void CStubSrv::ClientClosed(CStubSrvSess& aSession)
	{
	const TUint sessCount = iSessions.Count();
	for ( TUint ii = 0 ; ii < sessCount ; ++ii )
		{
		if ( iSessions[ii] == &aSession )
			{
			iSessions.Remove(ii);
			break;
			}
		}
	StartShutdownTimerIfNoSessions();
	}

void CStubSrv::EnqueueL(const RMessage2& aMessage)
    {
    TApiBehaviorPckgBuf buf;
    aMessage.ReadL(0, buf);
    TInt duration = aMessage.Int1();
    
    TInt sesss = iSessions.Count();
    for (TInt i = 0; i < sesss; i++)
        {
        TInt err = iSessions[i]->ConsumeApiBehavior(buf(), duration);
        if (err == KErrNone)
            {
            return;
            }
        }
    TApiQueueItem* item = new (ELeave) TApiQueueItem();
    item->iBeh = buf();
    item->iExeDuration = duration;
    item->iTransactionId = 0;  
    CleanupStack::PushL(item);
    iBehQueue.AppendL(item);
    CleanupStack::Pop(item);
    }

void CStubSrv::DeleteQueues(const RMessage2& aMessage)
    {
    TUint lib = aMessage.Int0();
    TUint api = aMessage.Int1();
    TInt count = iBehQueue.Count();
    for (TInt i = count - 1; i >= 0; i--)
        {
        if (iBehQueue[i]->iBeh.MatchId(lib, api))
            {
            delete iBehQueue[i];
            iBehQueue.Remove(i);
            }
        }
    }

TInt CStubSrv::Dequeue(TApiBehavior& aBeh, TInt& aExeDuration, TInt aTransactionId)
	{
    TInt count = iBehQueue.Count();
    for (TInt i = 0; i < count; i++)
        {
        if (iBehQueue[i]->iBeh.MatchId(aBeh.iLib, aBeh.iApi) &&
            aTransactionId == iBehQueue[i]->iTransactionId)
            {
            aBeh = iBehQueue[i]->iBeh;
            aExeDuration = iBehQueue[i]->iExeDuration;
            delete iBehQueue[i];
            iBehQueue.Remove(i);
            return KErrNone;
            }
        }
    return KErrNotFound;	
	}

void CStubSrv::GetApiCompleteCodeL(const RMessage2& aMessage)
    {
    TUint lib = aMessage.Int0();
    TUint api = aMessage.Int1();
    TInt count = iBehQueue.Count();
    for (TInt i = 0; i < count; i++)
        {
        if (iBehQueue[i]->iBeh.MatchId(lib, api))
            {
            iBehQueue[i]->iTransactionId = iTransctionUnique++;
            TPckgBuf<TInt> buf(iBehQueue[i]->iTransactionId);
            aMessage.WriteL(2, buf);
            aMessage.Complete(iBehQueue[i]->iBeh.iCompleteCode);
            return;
            }
        }
    aMessage.Complete(0);
    }

void CStubSrv::ConstructL()
    {
    iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
    }

CSession2* CStubSrv::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
    {
	TVersion v(KStubSrvMajorVersionNumber, KStubSrvMinorVersionNumber, KStubSrvBuildNumber);
	if ( !User::QueryVersionSupported(v, aVersion) )
		User::Leave(KErrNotSupported);
    CStubSrvSess* session = CStubSrvSess::NewL(const_cast<CStubSrv&>(*this));
    const_cast<CStubSrv*>(this)->CancelShutdownTimer();
    return session;
    }

void CStubSrv::CancelShutdownTimer()
    {
    iTimer->Cancel();
    }

TInt CStubSrv::TimerFired(TAny* /*aThis*/)
	{
	CActiveScheduler::Stop();
	return KErrNone;
	}
    
static void RunServerL()
	{
    static_cast<void>(User::LeaveIfError(User::RenameThread(KStubSrvName)));	
	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
	CleanupStack::PushL(scheduler);
	CActiveScheduler::Install(scheduler);
    CStubSrv::NewLC();
	RProcess::Rendezvous(KErrNone);
	CActiveScheduler::Start();
	CleanupStack::PopAndDestroy(2, scheduler);
	}

GLDEF_C TInt E32Main()
    {
	TInt ret = KErrNoMemory;
	__UHEAP_MARK;
	CTrapCleanup* cleanup = CTrapCleanup::New();
	if (cleanup)
		{
		TRAP(ret, RunServerL());
		delete cleanup;
		}
	__UHEAP_MARKEND;
	return ret;    
    }