/** Copyright (c) 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:**/// INCLUDE FILES#include "menusrv.h"#include "menusrvdef.h"#include "menusrvsession.h"#include "timeout.h"#include "menumsg.h"#include "menuutil.h"#include "menusrveng.h"// CONSTANTS// Custom check is applied to all IPCs. As IPC ids contain not only the ids// but other information is embadded into them.LOCAL_D const TInt KRangeCount = 1;LOCAL_D const TInt KSecurityRanges[KRangeCount] = { EMenuNullFunction, };LOCAL_D const TUint8 SecurityRangesPolicy[KRangeCount] = { CPolicyServer::ECustomCheck };LOCAL_D const CPolicyServer::TPolicy KPolicy = { CPolicyServer::EAlwaysPass, KRangeCount, KSecurityRanges, SecurityRangesPolicy, NULL, };// ==================== LOCAL FUNCTIONS ====================/*** Stop the Active Scheduler.* @param aPtr Not used.* @return KErrNone.*/LOCAL_C TInt StopScheduler( TAny* /*aPtr*/ ) { // Called by the exit timer, after all clients disconnected (plus a small // delay). Stop the scheduler, this will enable he thread exit. CActiveScheduler::Stop(); return KErrNone; }/*** Create a server.* @param Pointer to created server (if created) returned here.* @return Error code.*/LOCAL_C TInt CreateServer( CMenuSrv*& aServer ) { // The TRAP is not working in the same stack frame where the // CTrapCleanup was created. This is why we need this function. TRAPD( err, aServer = CMenuSrv::NewL() ); return err; }// ==================== GLOBAL FUNCTIONS ====================// ---------------------------------------------------------// RunMenuServer// ---------------------------------------------------------//EXPORT_C TInt RunMenuServer() { __UHEAP_MARK; CTrapCleanup* trapCleanup = NULL; CActiveScheduler* activeScheduler = NULL; CMenuSrv* server = NULL; TInt err = User::RenameThread( KMenuSrvName ); if ( !err ) { // Create a trap cleanup, make and install an active scheduler. err = KErrNoMemory; trapCleanup = CTrapCleanup::New(); if ( trapCleanup ) { activeScheduler = new CActiveScheduler(); if ( activeScheduler ) { CActiveScheduler::Install( activeScheduler ); err = CreateServer( server ); // Not pushed (no leaving). if ( !err ) { err = server->Start( KMenuSrvName ); } } else { err = KErrNoMemory; } } } // Let the caller know how it went. RProcess::Rendezvous( err ); if ( !err ) { CActiveScheduler::Start(); // Start off. Exit timer will stop it. } CActiveScheduler::Install( NULL ); delete activeScheduler; delete server; delete trapCleanup; __UHEAP_MARKEND; return err; }// ==================== MEMBER FUNCTIONS ====================// ---------------------------------------------------------// CMenuSrv::NewL// ---------------------------------------------------------//CMenuSrv* CMenuSrv::NewL() { CMenuSrv* srv = new (ELeave) CMenuSrv(); CleanupStack::PushL( srv ); srv->ConstructL(); CleanupStack::Pop( srv ); return srv; }// ---------------------------------------------------------// CMenuSrv::~CMenuSrv// ---------------------------------------------------------//CMenuSrv::~CMenuSrv() { // Cancel requests and delete all sessions first. // Base class would do it for us but that's too late - our sessions // call the server back (SessionClosed, RemoveContainer, etc.). Cancel(); CSession2* session; iSessionIter.SetToFirst(); while ( NULL != (session = iSessionIter++) ) { delete session; } // Here we should have no objects that are dependent on us. delete iObjectConIx; // This kills iEngines too. delete iExitTimer; }// ---------------------------------------------------------// CMenuSrv::NewContainerL// ---------------------------------------------------------//CObjectCon* CMenuSrv::NewContainerL() { return iObjectConIx->CreateL(); }// ---------------------------------------------------------// CMenuSrv::RemoveContainer// ---------------------------------------------------------//void CMenuSrv::RemoveContainer( CObjectCon* aCon ) { iObjectConIx->Remove( aCon ); }// ---------------------------------------------------------// CMenuSrv::GetEngineL// ---------------------------------------------------------//CMenuSrvEng* CMenuSrv::GetEngineL( const TDesC& aName ) { CMenuSrvEng* eng = NULL; for ( TInt i = 0; i < iEngines->Count(); i++ ) { eng = (CMenuSrvEng*)(*iEngines)[i]; if ( eng->ContentName() == aName ) { return eng; } } eng = CMenuSrvEng::NewL( *this, aName ); CleanupClosePushL( *eng ); iEngines->AddL( eng ); CleanupStack::Pop( eng ); return eng; }// ---------------------------------------------------------// CMenuSrv::EngineDeleted// ---------------------------------------------------------//void CMenuSrv::EngineDeleted() { if ( 1 >= iEngines->Count() ) { // Last engine is being deleted now. // Exit now, without delay: the engines had the timeout. // // Engine count is 1 when the engine has been created and added. // Engine count is 0 in case of leave in GetEngineL(). iExitTimer->Cancel(); CActiveScheduler* currentScheduler = CActiveScheduler::Current(); // No more sessions; schedule self-deletion. if (currentScheduler) { iExitTimer->After( TTimeIntervalMicroSeconds32( 0 ) ); } } }// ---------------------------------------------------------// CMenuSrv::CMenuSrv// ---------------------------------------------------------//CMenuSrv::CMenuSrv(): CPolicyServer( CActive::EPriorityStandard, KPolicy, ESharableSessions ) { }// ---------------------------------------------------------// CMenuSrv::ConstructL// ---------------------------------------------------------//void CMenuSrv::ConstructL() { iExitTimer = CTimeout::NewL ( CActive::EPriorityStandard, TCallBack( StopScheduler, NULL ) ); iExitTimer->Cancel(); iExitTimer->After( TTimeIntervalMicroSeconds32( KMenuSrvExitDelay ) ); iObjectConIx = CObjectConIx::NewL(); iEngines = iObjectConIx->CreateL(); }// ---------------------------------------------------------// CMenuSrv::NewSessionL// ---------------------------------------------------------//CSession2* CMenuSrv::NewSessionL( const TVersion& aVersion, const RMessage2& /*aMessage*/ ) const { TVersion version( KMenuMajorVersion, KMenuMinorVersion, KMenuBuild ); if ( !User::QueryVersionSupported( version, aVersion ) ) { User::Leave( KErrNotSupported ); } CSession2* session = CMenuSrvSession::NewL( (CMenuSrv&)*this ); iExitTimer->Cancel(); // We have a client, cancel exit (if pending). return session; }// ---------------------------------------------------------// CMenuSrv::CustomSecurityCheckL// ---------------------------------------------------------//CPolicyServer::TCustomResult CMenuSrv::CustomSecurityCheckL ( const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/ ) { TInt func = aMsg.Function(); TCustomResult ret = EFail; if( func > EMenuTestCapabilityStart && func < EMenuTestCapabilityEnd ) { if( aMsg.HasCapability( ECapabilityAllFiles ) ) { ret = EPass; } } else if( func > EMenuReadCapabilityStart && func < EMenuReadCapabilityEnd ) { if( aMsg.HasCapability( ECapabilityReadDeviceData ) ) { ret = EPass; } } else if( func > EMenuWriteCapabilityStart && func < EMenuWriteCapabilityEnd ) { if( aMsg.HasCapability( ECapabilityWriteDeviceData ) ) { ret = EPass; } } else { ; } return ret; }// End of File