/*
* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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:
* Implementation of class FavouritesSrv
*
*
*/
// INCLUDE FILES
#include <favouritessession.h>
#include "FavouritesSrv.h"
#include "FavouritesSrvSession.h"
#include "FavouritesDef.h"
#include "FavouritesLogger.h"
#include "Timeout.h"
#include "FavouritesUtil.h"
#include "BackupObserver.h"
#include "FavouritesMsg.h"
#ifdef __MYSERVER_NO_PROCESSES__
// ==================== LOCAL FUNCTIONS ====================
/**
* WINS thread entry function.
* @param aPtr Not used.
* @return Error code.
*/
LOCAL_C TInt ThreadEntryFunc( TAny* /*aPtr*/ )
{
return FavouritesSrv::Run();
}
#endif
/**
* 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.
FLOG(( _L("StopScheduler") ));
CActiveScheduler::Stop();
return KErrNone;
}
/**
* Create a server.
* @param Pointer to created server (if created) returned here.
* @return Error code.
*/
LOCAL_C TInt CreateServer( CFavouritesSrv*& aServer )
{
// Server is not allowed to be created if Secure Backup is in progress
TBool backupInProgress = EFalse; // This useless initialization is done
// because of RVCT compiler warning so do not delete it.
TRAPD( err, backupInProgress = FavouritesUtil::IsBackupInProgressL());
if(!err)
{
if(!backupInProgress)
{
// The TRAP is not working in the same stack frame where the
// CTrapCleanup was created. This is why we need this function.
TRAP( err, aServer = CFavouritesSrv::NewL() );
}
else
{
err = KErrLocked;
}
}
return err;
}
// ================= MEMBER FUNCTIONS =======================
// ---------------------------------------------------------
// FavouritesSrv::Start
// ---------------------------------------------------------
//
TInt FavouritesSrv::Start()
{
FLOG(( _L("FavouritesSrv::Start") ));
TInt err( KErrNone );
#ifdef __MYSERVER_NO_PROCESSES__
RThread server;
err = server.Create
(
KFavouritesSrvName,
ThreadEntryFunc,
KFavouritesSrvStackSize,
KFavouritesSrvMinHeapSize,
KFavouritesSrvMaxHeapSize,
NULL,
EOwnerProcess
);
FLOG(( _L(" thread created (%d)"), err ));
#else
RProcess server;
err = server.Create
(
KFavouritesSrvExe,
KNullDesC,
TUidType( KNullUid, KNullUid, KFavouritesUid ),
EOwnerThread
);
FLOG(( _L(" process created (%d)"), err ));
#endif
if ( !err )
{
TRequestStatus status;
server.Rendezvous( status );
if ( status != KRequestPending )
{
FLOG(( _L("FavouritesSrv::Start: abort startup") ));
server.Kill( 0 ); // Abort startup.
}
else
{
FLOG(( _L("FavouritesSrv::Start: resume server") ));
server.Resume(); // Logon OK - start the server.
}
User::WaitForRequest( status ); // Wait for start or death.
// We can't use the 'exit reason' if the server panicked as this
// is the panic 'reason' and may be '0' which cannot be distinguished
// from KErrNone.
err = (server.ExitType() == EExitPanic) ? KErrGeneral : status.Int();
server.Close();
}
FLOG(( _L("FavouritesSrv::Start: returns (%d)"), err ));
return err;
}
// ---------------------------------------------------------
// FavouritesSrv::Run
// ---------------------------------------------------------
//
EXPORT_C TInt FavouritesSrv::Run()
{
FLOG(( _L("FavouritesSrv::Run") ));
__UHEAP_MARK;
CTrapCleanup* trapCleanup = NULL;
CActiveScheduler* activeScheduler = NULL;
CFavouritesSrv* server = NULL;
TInt err = User::RenameThread( KFavouritesSrvName );
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( KFavouritesSrvName );
FLOG(( _L(" server started: (%d)"), err ));
}
}
}
}
// Let the caller know how it went.
#ifdef __MYSERVER_NO_PROCESSES__
RThread::Rendezvous( err );
#else
RProcess::Rendezvous( err );
#endif
if ( !err )
{
FLOG(( _L("FavouritesSrv::Run: starting active scheduler") ));
CActiveScheduler::Start();
FLOG(( _L("FavouritesSrv::Run: active scheduler stopped") ));
}
CActiveScheduler::Install( NULL );
delete activeScheduler;
FLOG(( _L("delete server") ));
delete server;
delete trapCleanup;
__UHEAP_MARKEND;
FLOG(( _L("FavouritesSrv::Run returns (%d)"), err ));
return err;
}
// ================= MEMBER FUNCTIONS =======================
// Platform security
// Custom check is applied to all IPCs. As IPC ids contain not only the ids
// but other information is embadded into them.
static const int KRangeCount = 1;
static const TInt SecurityRanges[KRangeCount] =
{
EFavengNullFunction,
};
static const TUint8 SecurityRangesPolicy[KRangeCount] =
{
CPolicyServer::ECustomCheck
};
static const CPolicyServer::TPolicy Policy =
{
CPolicyServer::EAlwaysPass,
KRangeCount,
SecurityRanges,
SecurityRangesPolicy,
NULL,
};
// ---------------------------------------------------------
// CFavouritesSrv::CustomSecurityCheckL
// ---------------------------------------------------------
//
CPolicyServer::TCustomResult CFavouritesSrv::CustomSecurityCheckL(
const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/)
{
TFavouritesMsg msg( aMsg.Function() );
TFavouritesFunction func = msg.Function();
TCustomResult ret = EFail;
if(func > EFavengTestCapabilityStart &&
func < EFavengTestCapabilityEnd)
{
if(aMsg.HasCapability(ECapabilityAllFiles))
{
ret = EPass;
}
}
else if(func > EFavengReadCapabilityStart &&
func < EFavengReadCapabilityEnd)
{
if(aMsg.HasCapability(ECapabilityReadUserData))
{
ret = EPass;
}
}
else if(func > EFavengWriteCapabilityStart &&
func < EFavengWriteCapabilityEnd)
{
if(aMsg.HasCapability(ECapabilityWriteUserData))
{
ret = EPass;
}
}
else
{
// Left empty by design
}
return ret;
}
// ---------------------------------------------------------
// CFavouritesSrv::NewL
// ---------------------------------------------------------
//
CFavouritesSrv* CFavouritesSrv::NewL()
{
CFavouritesSrv* srv = new (ELeave) CFavouritesSrv();
CleanupStack::PushL( srv );
srv->ConstructL();
CleanupStack::Pop();
return srv;
}
// ---------------------------------------------------------
// CFavouritesSrv::~CFavouritesSrv
// ---------------------------------------------------------
//
CFavouritesSrv::~CFavouritesSrv()
{
delete iExitTimer;
delete iBackupObserver;
}
// ---------------------------------------------------------
// CFavouritesSrv::SessionClosed
// ---------------------------------------------------------
//
void CFavouritesSrv::SessionClosed()
{
FLOG(( _L("CFavouritesSrv::SessionClosed") ));
iSessionIter.SetToFirst();
iSessionIter++;
if ( iSessionIter++ == 0 )
{
// Schedule exit when last client has closed.
iExitTimer->Cancel(); // Safety code: cancel if running.
FLOG(( _L(" start exit timer") ));
iExitTimer->After
( TTimeIntervalMicroSeconds32( KFavouritesSrvExitDelay ) );
}
}
// ---------------------------------------------------------
// CFavouritesSrv::PanicClient()
// ---------------------------------------------------------
//
void CFavouritesSrv::PanicClient( TInt aCode )
{
iReceivedMessage.Panic( KFavouritesSrvName, aCode );
}
// ---------------------------------------------------------
// CFavouritesSrv::CFavouritesSrv
// ---------------------------------------------------------
//
CFavouritesSrv::CFavouritesSrv() :
CPolicyServer(CActive::EPriorityStandard, Policy, ESharableSessions)
{
}
// ---------------------------------------------------------
// CFavouritesSrv::ConstructL
// ---------------------------------------------------------
//
void CFavouritesSrv::ConstructL()
{
FLOG(( _L("CFavouritesSrv::ConstructL") ));
iExitTimer = CTimeout::NewL
( CActive::EPriorityStandard, TCallBack( StopScheduler, NULL ) );
FLOG(( _L(" start exit timer") ));
iExitTimer->After
( TTimeIntervalMicroSeconds32( KFavouritesSrvExitDelay ) );
iBackupObserver = CBackupObserver::NewL();
}
// ---------------------------------------------------------
// CFavouritesSrv::NewSessionL
// ---------------------------------------------------------
//
CSession2* CFavouritesSrv::NewSessionL
( const TVersion& aVersion, const RMessage2& /*aMessage*/ ) const
{
FLOG(( _L("CFavouritesSrv::NewSessionL") ));
if ( !User::QueryVersionSupported
( RFavouritesSession::Version(), aVersion ) )
{
User::Leave( KErrNotSupported );
}
CSession2* session = CFavouritesSession::NewL();
iExitTimer->Cancel(); // We have a client, cancel exit (if pending).
return session;
}
// End of File