--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/sosserver/src/nsmlsosthread.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1034 @@
+/*
+* Copyright (c) 2002-2005 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: Symbian OS Server source.
+*
+*/
+
+#include <e32math.h>
+#include <DevManInternalCRKeys.h>
+#include <centralrepository.h>
+#include <nsmldebug.h>
+
+#include "nsmlsosthread.h"
+#include <DataSyncInternalPSKeys.h>
+
+#include <PolicyEngineClient.h>
+#include <centralrepository.h>
+#include "PMUtilInternalCRKeys.h"
+#include <featmgr.h>
+// --------------------------------------------------------------------------
+// EXPORT_C TInt ThreadFunction( TAny* )
+// --------------------------------------------------------------------------
+//
+TInt ThreadFunction( TAny* aStarted )
+ {
+ #ifdef __CLIENT_API_MT_
+ __UHEAP_MARK;
+ #endif
+
+ CNSmlThreadParams* params = (CNSmlThreadParams*) aStarted;
+
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ _DBG_FILE("CNSmlSOSServer : Session thread started");
+
+ CActiveScheduler* scheduler = new CActiveScheduler;
+ __ASSERT_ALWAYS( scheduler, User::Panic( KSOSServerThread, EMainSchedulerError ) );
+
+ CActiveScheduler::Install( scheduler );
+
+ TInt endStatus(KErrNone);
+ CNSmlThreadEngine * threadEngine = 0;
+
+ params->iCurrentJob.iSilentJob = EFalse;
+
+ TRAPD(err,
+ threadEngine = CNSmlThreadEngine::NewL( *params );
+
+ if ( params->iSyncInit == EServerAlerted && params->iCurrentJob.iPending )
+ {
+ if ( threadEngine->SilentModeL( params ))
+ {
+ //in silent mode DM client UI is not opened
+ params->iCurrentJob.iPending = EFalse;
+ params->iCurrentJob.iSilentJob = ETrue;
+ threadEngine->SaveSessionInfoL();
+ threadEngine->ForcedCertificateCheckL( ETrue );
+ threadEngine->StartJobSessionL();
+ }
+ else
+ {
+ //if not a silent mode behave as in a normal DM session
+ threadEngine->ForcedCertificateCheckL( EFalse );
+ threadEngine->VerifyJobFromNotifierL();
+ }
+ }
+ else
+ {
+ //when sync session is not alerted behave as in a normal DM session
+ threadEngine->ForcedCertificateCheckL( EFalse );
+ threadEngine->StartJobSessionL();
+ }
+ );
+
+ endStatus = err;
+
+ if ( err != KErrNone )
+ {
+ if ( params->iCurrentJob.TransportId() != KUidNSmlMediumTypeInternet.iUid )
+ {
+ // Disconnect if local connection
+ TRAP_IGNORE( params->iSOSHandler->DoDisconnectL() );
+ }
+ }
+
+ // start scheduler after succesfull initialization
+ if ( threadEngine )
+ {
+ if ( threadEngine->IsActive() )
+ {
+ CActiveScheduler::Start();
+ }
+ }
+
+ delete scheduler;
+
+ if ( endStatus == KErrNone )
+ {
+ endStatus = threadEngine->FinishedStatus();
+ }
+
+ if ( threadEngine )
+ {
+ delete threadEngine;
+ }
+
+ _DBG_FILE("SosServer Job Thread ended");
+ delete cleanup;
+
+ #ifdef __CLIENT_API_MT_
+ __UHEAP_MARKEND;
+ #endif
+
+ return endStatus;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::NewL( CNSmlThreadParams& aParams )
+// Two phase Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine* CNSmlThreadEngine::NewL( CNSmlThreadParams& aParams )
+ {
+ CNSmlThreadEngine* self = new (ELeave) CNSmlThreadEngine( aParams );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::ConstructL()
+// 2nd Constructor
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::ConstructL()
+ {
+ FeatureManager::InitializeLibL();
+ iThreadParams.iThreadEngine = this;
+ iContentArray = new(ELeave) CArrayFixFlat<TNSmlContentSpecificSyncType>(1);
+
+ if ( iThreadParams.iCSArray )
+ {
+ for (TInt i = 0; i < iThreadParams.iCSArray->Count(); i++)
+ {
+ TNSmlContentSpecificSyncType type;
+ type.iTaskId = iThreadParams.iCSArray->At( i ).iTaskId;
+ type.iType = iThreadParams.iCSArray->At( i ).iType;
+ iContentArray->AppendL( type );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine( TNSmlThreadParams& aParams )
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine::CNSmlThreadEngine( CNSmlThreadParams& aParams )
+: CActive(EPriorityLow), iThreadParams(aParams)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::~CNSmlThreadEngine()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadEngine::~CNSmlThreadEngine()
+ {
+ delete iContentArray;
+ delete iNotifierObserver;
+ Cancel();
+ RThread().Close();
+ delete iDSAgent;
+ delete iDMAgent;
+ delete iCancelTimeout;
+ FeatureManager::UnInitializeLib();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::SilentModeL()
+// Check is current serverid mentioned to work in silent mode (TARM feature)
+// --------------------------------------------------------------------------
+//
+TBool CNSmlThreadEngine::SilentModeL( const CNSmlThreadParams* aParams )
+ {
+ _DBG_FILE("CNSmlThreadEngine::SilentModeL() : start");
+ TInt retVal = ETrue;
+
+ if ( aParams->iCurrentJob.UsageType() == ESmlDataSync )
+ {
+ return EFalse;
+ }
+ if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+ {
+ //get DM profile -> get profile serverid
+ CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+ CNSmlDMProfile* prof = settings->ProfileL(
+ aParams->iCurrentJob.ProfileId() );
+ CleanupStack::PushL( prof );
+
+ //connect to policy engine
+ RPolicyEngine policyEngine;
+ User::LeaveIfError( policyEngine.Connect() );
+ CleanupClosePushL( policyEngine );
+
+ RPolicyManagement policyManagement;
+ User::LeaveIfError( policyManagement.Open( policyEngine ) );
+
+ //check is the specific server id allowed to work in silent mode
+ TInt err = policyManagement.IsAllowedServerId(
+ prof->StrValue( EDMProfileServerId ) );
+
+ policyManagement.Close();
+
+ CleanupStack::PopAndDestroy( 3, settings );
+
+ if ( err == KErrNone )
+ {
+ retVal = ETrue;
+ }
+ else
+ {
+ retVal = EFalse;
+ }
+}
+else
+{
+ //if policy management is not installed....
+ retVal = EFalse;
+}
+
+ if( retVal )
+ {
+ _DBG_FILE("CNSmlThreadEngine::SilentModeL() : end, return ETrue");
+ }
+ else
+ {
+ _DBG_FILE("CNSmlThreadEngine::SilentModeL() : end, return EFalse");
+ }
+
+ return retVal;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::SaveSessionInfo()
+// Save session info which is needed later in DM agent to launch notifier
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::SaveSessionInfoL()
+ {
+ if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+ {
+ CRepository * rep = CRepository::NewLC(
+ KCRUidPolicyManagementUtilInternalKeys );
+
+ TSyncMLAppLaunchNotifParams params;
+
+ if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )
+ {
+ params.iSessionType = ESyncMLSyncSession;
+ }
+ else
+ {
+ params.iSessionType = ESyncMLMgmtSession;
+ }
+
+ params.iJobId = iThreadParams.iCurrentJob.JobId();
+ params.iProfileId = iThreadParams.iCurrentJob.ProfileId();
+
+ TPckg<TSyncMLAppLaunchNotifParams> data( params );
+
+ TInt err = rep->Set( KSyncMLSessionParamsKey, data );
+
+ if ( err == KErrNotFound )
+ {
+ User::LeaveIfError( rep->Create( KSyncMLSessionParamsKey, data ) );
+ }
+ else
+ {
+ _DBG_FILE("CNSmlThreadEngine::SaveSessionInfoL TInt err = \
+ rep->Set( KParamsKey, data );");
+ User::LeaveIfError( err );
+ }
+
+ CleanupStack::PopAndDestroy( rep );
+}
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::ForcedCertificateCheckL( TBool aForcedState )
+// Launch job session in thread
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::ForcedCertificateCheckL( TBool aForcedState )
+ {
+ if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement))
+ {
+ CRepository * rep = CRepository::NewLC( KCRUidPolicyManagementUtilInternalKeys );
+
+ TInt err = rep->Set( KSyncMLForcedCertificateCheckKey, aForcedState );
+
+ if ( err == KErrNotFound )
+ {
+ User::LeaveIfError( rep->Create( KSyncMLForcedCertificateCheckKey, aForcedState ));
+ }
+
+ CleanupStack::PopAndDestroy( rep );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartJobSessionL()
+// Launch job session in thread
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::StartJobSessionL()
+ {
+ _DBG_FILE("CNSmlThreadStart::StartJobSession() : Begin");
+
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+ TInt status( KErrNone );
+ if ( iThreadParams.iCurrentJob.UsageType() == ESmlDevMan )
+ {
+ TRAP( status, StartDMSessionL() );
+ }
+ else
+ {
+ TRAP( status, StartDSSessionL() );
+ }
+
+ if ( status != KErrNone )
+ {
+ TRequestStatus* sStatus = &iStatus;
+ User::RequestComplete( sStatus, status );
+ }
+ _DBG_FILE("CNSmlThreadStart::StartJobSession() : End");
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::CancelJob()
+// Cancel current running job
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::CancelJob()
+ {
+ if ( iCancelTimeout )
+ {
+ iCancelTimeout->SetJobCancelled( iThreadParams.iCurrentJob.UsageType() );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartDMSessionL()
+// Start DM job
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::StartDMSessionL()
+ {
+ TInt result = iSessionLib.Load( KSmlDMAgentLoaderLibName );
+ if ( result != KErrNone )
+ {
+ _DBG_FILE("CNSmlSOSHandler::StartDMSyncL(): loading agent failed !");
+ User::Leave( result );
+ }
+ TNSmlCreateDMAgentFunc createDMAgentL = (TNSmlCreateDMAgentFunc)iSessionLib.Lookup(1);
+ iDMAgent = createDMAgentL(iThreadParams.iSOSHandler);
+
+ iCancelTimeout = new (ELeave) CNSmlCancelTimeOut( *iDMAgent, *iDSAgent );
+
+ iDMAgent->Configure(iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), (TNSmlSyncInitiation)iThreadParams.iSyncInit,
+ iThreadParams.iCurrentJob.GetJobIapId());
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::StartDSSessionL()
+// Start DS job
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::StartDSSessionL()
+ {
+
+ TInt result = iSessionLib.Load( KSmlDSAgentLoaderLibName );
+ if ( result != KErrNone )
+ {
+ _DBG_FILE("CNSmlSOSHandler::StartDSSyncL(): loading agent failed!");
+ User::Leave( result );
+ }
+
+ TNSmlCreateDSAgentFunc createDSAgentL = (TNSmlCreateDSAgentFunc)iSessionLib.Lookup(1);
+ iDSAgent = createDSAgentL( iThreadParams.iSOSHandler );
+
+ iCancelTimeout = new (ELeave) CNSmlCancelTimeOut( *iDMAgent, *iDSAgent );
+
+ // Select correct sync method and start sync
+ TNSmlSyncInitiation syncInit = (TNSmlSyncInitiation)iThreadParams.iSyncInit;
+
+ switch ( iThreadParams.iCurrentJob.JobType() )
+ {
+ case EDSJobProfile:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, NULL, syncInit );
+ break;
+ case EDSJobProfileST:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + syncType
+ break;
+ case EDSJobTasks:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + tasks
+ break;
+ case EDSJobTasksST:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), KNSmlNullId, iContentArray, syncInit ); // + tasks & syncType
+ break;
+ case EDSJobTransport:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), NULL, syncInit ); // + transport
+ break;
+ case EDSJobTransportST:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit ); // + transport & syncType
+ break;
+ case EDSJobTaskTrans:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit ); // + tasks & transport
+ break;
+ case EDSJobTaskTransST:
+ iDSAgent->Synchronise( iStatus, iThreadParams.iCurrentJob.ProfileId(), iThreadParams.iCurrentJob.TransportId(), iContentArray, syncInit, iThreadParams.iCurrentJob.iSessionId, iThreadParams.iCurrentJob.iPackage ); // + tasks & transport & syncType & server alert
+ break;
+ default:
+ break;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::VerifyJobFromNotifierL()
+// Launches notifier and waits for
+// --------------------------------------------------------------------------
+//
+TInt CNSmlThreadEngine::VerifyJobFromNotifierL()
+ {
+ _DBG_FILE("CNSmlThreadEngine::VerifyJobFromNotifierL() : Begin");
+ iNotifierObserver = new (ELeave) CNSmlNotifierObserver(iStatus, iThreadParams);
+ SetActive();
+
+ TSyncMLAppLaunchNotifParams params;
+ params.iSessionType = ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync ) ? ESyncMLSyncSession : ESyncMLMgmtSession;
+ params.iJobId = iThreadParams.iCurrentJob.JobId();
+ params.iProfileId = iThreadParams.iCurrentJob.ProfileId();
+ params.iUimode = iThreadParams.iCurrentJob.iUimode;
+ iNotifierObserver->ConnectToNotifierL( params );
+ _DBG_FILE("CNSmlThreadEngine::VerifyJobFromNotifierL() : End");
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DMAgentL()
+// Returns dm agent if it is created, otherwise leaves with KErrNotFound.
+// --------------------------------------------------------------------------
+//
+CNSmlDMAgent* CNSmlThreadEngine::DMAgentL() const
+ {
+ if ( !iDMAgent )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ return iDMAgent;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DSAgentL()
+// Returns ds agent if it is created, otherwise leaves with KErrNotFound.
+// --------------------------------------------------------------------------
+//
+CNSmlDSAgent* CNSmlThreadEngine::DSAgentL() const
+ {
+ if ( !iDSAgent )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ return iDSAgent;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::DoCancel()
+ {
+ _DBG_FILE("CNSmlThreadStart::DoCancel() : Begin");
+ _DBG_FILE("CNSmlThreadStart::DoCancel() : End");
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::RunL()
+// From base class :
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::RunL()
+ {
+ _DBG_FILE("CNSmlThreadEngine::RunL() : Begin");
+ TBool resume( EFalse );
+ TRAP_IGNORE( resume = DoRunL() );
+
+ if ( resume )
+ {
+ return;
+ }
+ _DBG_FILE("CNSmlThreadEngine::RunL() : End");
+ CActiveScheduler::Stop();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::DoRunL()
+// Method to perform RunL, that can be trapped.
+// --------------------------------------------------------------------------
+//
+TBool CNSmlThreadEngine::DoRunL()
+ {
+ _DBG_FILE("CNSmlThreadEngine::DoRunL() : Begin");
+
+ if ( iThreadParams.iCurrentJob.iPending != EFalse )
+ {
+ iThreadParams.iCurrentJob.iPending = EFalse;
+ if ( iStatus.Int() == KErrNone )
+ {
+ StartJobSessionL();
+ return ETrue;
+ }
+ else
+ {
+ if ( iThreadParams.iCurrentJob.TransportId() != KUidNSmlMediumTypeInternet.iUid )
+ {
+ // Disconnect local connection.
+ TRAP_IGNORE( iThreadParams.iSOSHandler->DoDisconnectL() );
+ }
+
+ WriteHistoryLogL( iStatus.Int() );
+ }
+ }
+ _DBG_FILE("CNSmlThreadEngine::DoRunL() : Begin");
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadEngine::WriteHistoryLogL( TInt aErrorCode )
+// Writes history log when notifier start
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadEngine::WriteHistoryLogL( TInt aErrorCode )
+ {
+ RArray<TInt> tasks;
+
+ if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )
+ {
+ iThreadParams.iCurrentJob.TaskIds( tasks );
+ }
+ CleanupClosePushL(tasks);
+
+ CSyncMLHistoryJob* historyLog = CSyncMLHistoryJob::NewL( iThreadParams.iCurrentJob.ProfileId(), tasks );
+ CleanupStack::PushL( historyLog );
+
+ TTime time;
+ time.UniversalTime();
+
+ historyLog->SetResult( time, aErrorCode );
+
+ if ( iThreadParams.iCurrentJob.UsageType() == ESmlDataSync )
+ {
+ CNSmlDSSettings* settings = CNSmlDSSettings::NewLC();
+ CNSmlDSProfile* prof = settings->ProfileL( iThreadParams.iCurrentJob.ProfileId() );
+ CleanupStack::PushL( prof );
+ CNSmlHistoryArray* array = CNSmlHistoryArray::NewL();
+ CleanupStack::PushL( array );
+ array->SetOwnerShip( ETrue );
+
+ RReadStream& readStream = prof->LogReadStreamL();
+ CleanupClosePushL( readStream );
+
+ if ( readStream.Source()->SizeL() > 0 )
+ {
+ array->InternalizeL( readStream );
+ }
+
+ CleanupStack::PopAndDestroy(); // readStream
+
+ array->AppendEntryL( historyLog );
+ RWriteStream& writeStream = prof->LogWriteStreamL();
+ CleanupClosePushL( writeStream );
+ array->ExternalizeL( writeStream );
+ CleanupStack::PopAndDestroy(); // writeStream
+ prof->WriteStreamCommitL();
+
+ CleanupStack::PopAndDestroy(array);
+ CleanupStack::PopAndDestroy(prof);
+ CleanupStack::PopAndDestroy(settings);
+ }
+ else // DevMan
+ {
+ CNSmlDMSettings* settings = CNSmlDMSettings::NewLC();
+ CNSmlDMProfile* prof = settings->ProfileL( iThreadParams.iCurrentJob.ProfileId() );
+ CleanupStack::PushL( prof );
+ CNSmlHistoryArray* array = CNSmlHistoryArray::NewL();
+ CleanupStack::PushL( array );
+ array->SetOwnerShip( ETrue );
+
+ RReadStream& readStream = prof->LogReadStreamL();
+ CleanupClosePushL( readStream );
+
+ if ( readStream.Source()->SizeL() > 0 )
+ {
+ array->InternalizeL( readStream );
+ }
+
+ CleanupStack::PopAndDestroy(); // readStream
+
+ array->AppendEntryL( historyLog );
+ RWriteStream& writeStream = prof->LogWriteStreamL();
+ CleanupClosePushL( writeStream );
+ array->ExternalizeL( writeStream );
+ CleanupStack::PopAndDestroy(); // writeStream
+ prof->WriteStreamCommitL();
+
+ CleanupStack::PopAndDestroy(array);
+ CleanupStack::PopAndDestroy(prof);
+ CleanupStack::PopAndDestroy(settings);
+ }
+
+ CleanupStack::Pop(historyLog);
+ CleanupStack::PopAndDestroy(&tasks);
+ }
+// --------------------------------------------------------------------------
+// TNSmlThreadLauncher::RunJobSession( CNSmlThreadParams& aParams, CNSmlThreadObserver& aObserver )
+// Launches a new thread for job session
+// --------------------------------------------------------------------------
+//
+TInt TNSmlThreadLauncher::RunJobSession( CNSmlThreadParams& aParams, CNSmlThreadObserver& aObserver )
+ {
+ _DBG_FILE("TNSmlThreadLauncher::RunJobSession() : Begin");
+ RThread thread;
+
+ TName threadName ( KNSmlJobThread );
+ threadName.Append ( _L("_") );
+ threadName.AppendNum ( Math::Random(), EHex );
+
+ TInt status = thread.Create(threadName, ThreadFunction, KNSmlSOSServerStackSize, NULL, &aParams, EOwnerProcess);
+
+ if (status != KErrNone)
+ {
+ thread.Close();
+ return status;
+ }
+
+ thread.SetPriority( EPriorityNormal ); // set priority
+ thread.Resume();
+
+ //Request notification when DM session thread ends.
+ aObserver.LogonToThread( thread );
+
+ thread.Close();
+ _DBG_FILE("TNSmlThreadLauncher::RunJobSession() : End");
+ return status;
+ }
+
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::CNSmlThreadObserver()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadObserver::CNSmlThreadObserver(TRequestStatus& aStatus)
+:CActive(0), iSosStatus(aStatus)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::~CNSmlThreadObserver()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadObserver::~CNSmlThreadObserver()
+ {
+ Cancel();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::LogonToThread( RThread& aThread )
+// Logs on to given thread. Wakes the server scheduler
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadObserver::LogonToThread( RThread& aThread )
+ {
+ _DBG_FILE("CNSmlThreadObserver::LogonToThread() : Begin");
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+ aThread.Logon( iStatus );
+ _DBG_FILE("CNSmlThreadObserver::LogonToThread() : End");
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadObserver::DoCancel()
+ {
+
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadObserver::RunL()
+// Logs on to given thread. Called when thread finishes.
+// --------------------------------------------------------------------------
+//
+void CNSmlThreadObserver::RunL()
+ {
+ DBG_FILE_CODE(iStatus.Int(), _S8("CNSmlThreadObserver::RunL() : Begin"));
+
+ TInt err;
+ TInt dsStatus = KErrNotFound;
+
+ err = RProperty::Set( KPSUidDataSynchronizationInternalKeys, KDataSyncStatus, dsStatus );
+
+ if(err == KErrNone)
+ {
+ if(dsStatus != EDataSyncNotRunning )
+ {
+ RProperty::Set( KPSUidDataSynchronizationInternalKeys, KDataSyncStatus, EDataSyncNotRunning );
+ }
+
+ }
+ //Notify thread completion status code to caller.
+ TRequestStatus* sStatus = &iSosStatus;
+ User::RequestComplete( sStatus, iStatus.Int() );
+
+ _DBG_FILE("CNSmlThreadObserver::LogonToThread() : End");
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::CNSmlNotifierObserver(TRequestStatus& aStatus, CNSmlThreadEngine* aEngine, CNSmlThreadParams& aParams)
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierObserver::CNSmlNotifierObserver(TRequestStatus& aStatus, CNSmlThreadParams& aParams)
+: CActive(0), iCallerStatus(aStatus), iThreadParams(aParams)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::~CNSmlNotifierObserver()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierObserver::~CNSmlNotifierObserver()
+ {
+
+ // StartNotifier called to avoid Notifier server panic, if
+ // notifier does not exist anymore.
+ TBuf8<1> dummy;
+ iNotifier.StartNotifier(KNullUid, dummy, dummy); // KNullUid should do also..
+
+ iNotifier.CancelNotifier( KUidNotifier );
+ iNotifier.Close();
+ Cancel();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::ConnectToNotifierL( const TSyncMLAppLaunchNotifParams& aParam )
+// Starts connection with notifier
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierObserver::ConnectToNotifierL( const TSyncMLAppLaunchNotifParams& aParam )
+ {
+ _DBG_FILE( "CNSmlNotifierObserver::ConnectToNotifierL:Begin" );
+ iTimeOut = EFalse;
+
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+
+ TSyncMLAppLaunchNotifParamsPckg data( aParam );
+
+ if ( !KNSmlWaitNotifierForEver )
+ {
+ iNotifierTimeOut.LaunchNotifierTimer( this );
+ }
+
+ TInt err = iNotifier.Connect();
+ if ( err == KErrNone )
+ {
+ iNotifier.StartNotifierAndGetResponse( iStatus, KUidNotifier, data, iResBuf );
+ }
+ else
+ {
+ // Stop job. Error connecting to notifier.
+ TRequestStatus* sStatus = &iStatus;
+ User::RequestComplete( sStatus, err );
+ }
+ _DBG_FILE("CNSmlNotifierObserver::ConnectToNotifierL:End");
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::NotifierTimeOut()
+// Starts notifier time out timer
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierObserver::NotifierTimeOut()
+ {
+ iTimeOut = ETrue;
+
+ // StartNotifier called to avoid Notifier server panic, if
+ // notifier does not exist anymore.
+ TBuf8<1> dummy;
+ iNotifier.StartNotifier(KNullUid, dummy, dummy); // KNullUid should do also..
+ iNotifier.CancelNotifier( KUidNotifier );
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierObserver::DoCancel()
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierObserver::RunL()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierObserver::RunL()
+ {
+
+ TInt ret = iStatus.Int();
+ if ( ret == KErrCancel && iTimeOut )
+ {
+
+ }
+ else
+ if ( ret == KErrNone )
+ {
+
+ TInt sid = iResBuf().iSecureId.iUid; // read secure id from notifier.
+
+ // Check the response and error code. If there is a fail, dump the job.
+ // Also compare sid to creator id saved for current job to secure that listener owns the job.
+ if ( ret != KErrNone || sid != iThreadParams.iCurrentJob.CreatorId() )
+ {
+ if ( ret == KErrNone && sid != iThreadParams.iCurrentJob.CreatorId() )
+ {
+#ifndef __WINS__
+ ret = KErrPermissionDenied;
+#endif
+ }
+ }
+
+ }
+
+ TRequestStatus* sStatus = &iCallerStatus;
+ User::RequestComplete( sStatus, ret );
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierTimeOut::CNSmlNotifierTimeOut()
+:CActive(0)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlNotifierTimeOut::~CNSmlNotifierTimeOut()
+ {
+ Cancel();
+ iTimeOutTimer.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::LaunchNotifierTimer( CNSmlNotifierObserver* aObserver )
+// Starts notifier time out timer
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::LaunchNotifierTimer( CNSmlNotifierObserver* aObserver )
+ {
+
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+ iTimeOutTimer.CreateLocal();
+ iTimeOutTimer.After( iStatus, KNotifierTimeout );
+ iObserver = aObserver;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::DoCancel()
+ {
+ iTimeOutTimer.Cancel();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlNotifierTimeOut::RunL()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlNotifierTimeOut::RunL()
+ {
+ if ( iStatus.Int() != KErrCancel )
+ {
+ iObserver->NotifierTimeOut();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::CNSmlCancelTimeOut()
+// Constructor
+// --------------------------------------------------------------------------
+//
+CNSmlCancelTimeOut::CNSmlCancelTimeOut( CNSmlDMAgent& aDMAgent, CNSmlDSAgent& aDSAgent )
+: CActive(0), iDMAgent(aDMAgent), iDSAgent(aDSAgent)
+ {
+ CActiveScheduler::Add(this);
+ iTimeOutTimer.CreateLocal();
+ iDoCancel = EFalse;
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+
+ iTimeOutTimer.After( iStatus, 10000 );
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::~CNSmlCancelTimeOut()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlCancelTimeOut::~CNSmlCancelTimeOut()
+ {
+ Cancel();
+ iTimeOutTimer.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::SetJobCancelled()
+// Flags job to be cancelled
+// --------------------------------------------------------------------------
+//
+void CNSmlCancelTimeOut::SetJobCancelled( TSmlUsageType aUsageType )
+ {
+ iDoCancel = ETrue;
+ iUsageType = aUsageType;
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::DoCancel()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlCancelTimeOut::DoCancel()
+ {
+ iTimeOutTimer.Cancel();
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlCancelTimeOut::RunL()
+// From base class
+// --------------------------------------------------------------------------
+//
+void CNSmlCancelTimeOut::RunL()
+ {
+ if ( iDoCancel )
+ {
+ if ( iUsageType == ESmlDevMan )
+ {
+ iDMAgent.Cancel();
+ }
+ else
+ {
+ iDSAgent.Cancel();
+ }
+ }
+ else
+ {
+ if ( !IsActive() )
+ {
+ SetActive();
+ }
+ iTimeOutTimer.After( iStatus, 10000 );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CNSmlThreadParams::~CNSmlThreadParams()
+// Destructor
+// --------------------------------------------------------------------------
+//
+CNSmlThreadParams::~CNSmlThreadParams()
+ {
+ delete iCSArray;
+ iCSArray = 0;
+ }