diff -r 13d7c31c74e0 -r b183ec05bd8c devicediagnosticsfw/diagframework/src/diagengineimpl.cpp --- a/devicediagnosticsfw/diagframework/src/diagengineimpl.cpp Thu Aug 19 10:44:50 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1551 +0,0 @@ -/* -* Copyright (c) 2007 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: Class definition of CDiagEngineImpl -* -*/ - - -// CLASS DECLARATION -#include "diagengineimpl.h" // CDiagEngineImpl - -// SYSTEM INCLUDE FILES -#include // CDiagPluginPool -#include // LOGSTRING -#include // MDiagPlugin -#include // TDiagTestExecParam -#include // TDiagSuiteExecParam -#include // CDiagResultsDbItemBuilder -#include // CDiagResultsDbRecordEngineParam - -// USER INCLUDE FILES -#include "diagpluginexecplanimpl.h" // CDiagPluginExecPlanImpl -#include "diagexecplanentryimpltest.h" // CDiagExecPlanEntryImplTest -#include "diagenginestatemachine.h" // DiagFwInternal::CStateMachine -#include "diagenginecallhandler.h" // CDiagEngineCallHandler -#include "diagframework.pan" // Panic Codes -#include "diagengineconfig.h" // TDiagEngineConfig - -// EVENT INCLUDE FILES -#include "diagengineeventbasic.h" // DiagFwInternal::CEventBasic -#include "diagengineeventtestprogress.h" // DiagFwInternal::CEventTestProgress - -using namespace DiagFwInternal; - -// DATA - -// ======== LOCAL FUNCTIONS ======== - -// ======== MEMBER FUNCTIONS ======== - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NewL() -// --------------------------------------------------------------------------- -// -CDiagEngineImpl* CDiagEngineImpl::NewL( - CAknViewAppUi& aViewAppUi, - MDiagEngineObserver& aObserver, - RDiagResultsDatabase& aDbSession, - CDiagPluginPool& aPluginPool, - TBool aDisableDependency, - const RArray< TUid >& aExecutionBatch ) - { - CDiagEngineImpl* self = CDiagEngineImpl::NewLC( aViewAppUi, - aObserver, - aDbSession, - aPluginPool, - aDisableDependency, - aExecutionBatch ); - CleanupStack::Pop( self ); - return self; - } - - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NewLC() -// --------------------------------------------------------------------------- -// -CDiagEngineImpl* CDiagEngineImpl::NewLC( - CAknViewAppUi& aViewAppUi, - MDiagEngineObserver& aObserver, - RDiagResultsDatabase& aDbSession, - CDiagPluginPool& aPluginPool, - TBool aDisableDependency, - const RArray< TUid >& aExecutionBatch ) - { - CDiagEngineImpl* self = new ( ELeave ) CDiagEngineImpl( aViewAppUi, - aObserver, - aDbSession, - aPluginPool ); - - CleanupStack::PushL( self ); - self->ConstructNewRecordL( aDisableDependency, aExecutionBatch ); - return self; - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NewL() -// --------------------------------------------------------------------------- -// -CDiagEngineImpl* CDiagEngineImpl::NewL( CAknViewAppUi& aViewAppUi, - MDiagEngineObserver& aObserver, - RDiagResultsDatabase& aDbSession, - CDiagPluginPool& aPluginPool, - TUid aIncompleteRecordUid ) - { - CDiagEngineImpl* self = CDiagEngineImpl::NewLC( aViewAppUi, - aObserver, - aDbSession, - aPluginPool, - aIncompleteRecordUid ); - CleanupStack::Pop( self ); - return self; - } - - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NewLC() -// --------------------------------------------------------------------------- -// -CDiagEngineImpl* CDiagEngineImpl::NewLC( CAknViewAppUi& aViewAppUi, - MDiagEngineObserver& aObserver, - RDiagResultsDatabase& aDbSession, - CDiagPluginPool& aPluginPool, - TUid aIncompleteRecordUid ) - { - CDiagEngineImpl* self = new ( ELeave ) CDiagEngineImpl( aViewAppUi, - aObserver, - aDbSession, - aPluginPool ); - - CleanupStack::PushL( self ); - self->ConstructIncompleteRecordL( aIncompleteRecordUid ); - return self; - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::CDiagEngineImpl -// --------------------------------------------------------------------------- -// -CDiagEngineImpl::CDiagEngineImpl( CAknViewAppUi& aViewAppUi, - MDiagEngineObserver& aObserver, - RDiagResultsDatabase& aDbSession, - CDiagPluginPool& aPluginPool ) - : CActive( EPriorityStandard ), - iViewAppUi( aViewAppUi ), - iObserver( aObserver ), - iDbSession( aDbSession ), - iPluginPool( aPluginPool ) - { - LOGSTRING( "---- DIAG ENGINE BEGIN ---- DIAG ENGINE BEGIN ----{" ) - CActiveScheduler::Add( this ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ConstructNewRecordL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ConstructNewRecordL( TBool aDisableDependency, - const RArray< TUid >& aExecutionBatch ) - { - ConstructCommonL(); - - LOGSTRING( "CDiagEngineImpl::ConstructNewRecordL()" ) - - iContinueIncompleteRecord = EFalse; - iEngineConfig.SetDependencyDisabled( aDisableDependency ); - - // convert uid array to plugin reference array. - // Also, make a copy of the plug-in UID array so that it can be - // passed to database. - TInt batchCount = aExecutionBatch.Count(); - - // uidList must be allocated in heap since it database will own the data later. - RArray< TUid >* uidList = new( ELeave )RArray< TUid >(); - CleanupStack::PushL( uidList ); // to delete array itself. - CleanupClosePushL( *uidList ); // to call close. - - uidList->ReserveL( batchCount ); - - MDiagPlugin* plugin = NULL; - - for ( TInt i = 0; i < batchCount ; i++ ) - { - LOGSTRING2( "CDiagEngineImpl::ConstructNewRecordL() " - L"Add plugin 0x%08x", aExecutionBatch[i].iUid ) - - iPluginPool.FindPlugin( aExecutionBatch[i], plugin ); - iBatch.AppendL( plugin ); - plugin = NULL; - - uidList->AppendL( aExecutionBatch[i] ); - } - - CDiagResultsDbRecordEngineParam* engineParam = - CDiagResultsDbRecordEngineParam::NewL( - uidList, // ownership transfer - !iEngineConfig.IsDependencyDisabled() /* isDependencyExecution */ ); - - CleanupStack::Pop( uidList ); // CleanupClosePushL( *uidList ) - CleanupStack::Pop( uidList ); // CleanupStack::PushL( uidList ) - uidList = NULL; - - CleanupStack::PushL( engineParam ); - User::LeaveIfError( - iDbRecord.CreateNewRecord( iDbSession, iRecordId, *engineParam ) ); - CleanupStack::PopAndDestroy( engineParam ); - engineParam = NULL; - - iPlan = CDiagPluginExecPlanImpl::NewL( *this, iEngineConfig, *this ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ConstructIncompleteRecordL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ConstructIncompleteRecordL( TUid aIncompleteRecordUid ) - { - ConstructCommonL(); - - LOGSTRING2( "CDiagEngineImpl::ConstructIncompleteRecordL() " - L"RecordId = 0x%08x", aIncompleteRecordUid.iUid ) - - iRecordId = aIncompleteRecordUid; - iContinueIncompleteRecord = ETrue; - - User::LeaveIfError( - iDbRecord.Connect( iDbSession, - iRecordId, - EFalse /* aReadOnly */ ) ); - - // make sure that record is open for writing. - TBool isTestCompleted = EFalse; - User::LeaveIfError( iDbRecord.IsTestCompleted( isTestCompleted ) ); - if ( isTestCompleted ) - { - User::Leave( KErrLocked ); - } - - // recover original parameter - CDiagResultsDbRecordEngineParam* engineParam = NULL; - User::LeaveIfError( - iDbRecord.GetEngineParam( engineParam ) ); - - CleanupStack::PushL( engineParam ); - - // Recover original batch. - MDiagPlugin* plugin = NULL; - iEngineConfig.SetDependencyDisabled( !engineParam->DependencyExecution() ); - const RArray< TUid >& uidArray = engineParam->ExecutionsUidArray(); - TInt count = uidArray.Count(); - for ( TInt i = 0; i < count; i++ ) - { - LOGSTRING2( "CDiagEngineImpl::ConstructNewRecordL() " - L"Add plugin 0x%08x", uidArray[i].iUid ) - - User::LeaveIfError( - iPluginPool.FindPlugin( uidArray[i], plugin ) ); - iBatch.AppendL( plugin ); - plugin = NULL; - } - - CleanupStack::PopAndDestroy( engineParam ); - engineParam = NULL; - - iPlan = CDiagPluginExecPlanImpl::NewL( *this, iEngineConfig, *this ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ConstructCommonL() -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ConstructCommonL() - { - LOGSTRING( "CDiagEngineImpl::ConstructCommonL." ) - - // Read Cenrep key - iEngineConfig.ReadCenrepKeysL(); - - // Create state machine. - iStateMachine = CStateMachine::NewL( *this ); - - // Create call handler. - iCallHandler = CDiagEngineCallHandler::NewL( *this ); - - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::~CDiagEngineImpl -// --------------------------------------------------------------------------- -// -CDiagEngineImpl::~CDiagEngineImpl() - { - LOGSTRING( "CDiagEngineImpl::~CDiagEngineImpl() Destructor" ) - - StopAllRequests(); - - CleanupIncompleteTestSession(); - - // always delete plan before record is closed. - delete iPlan; - iPlan = NULL; - - iDbRecord.Close(); - - iBatch.Close(); // MUST NOT destroy since we don't own elements within it - - delete iStateMachine; - iStateMachine = NULL; - - delete iSuspendedResult; - iSuspendedResult = NULL; - - delete iCallHandler; - iCallHandler = NULL; - - LOGSTRING( "} ---- DIAG ENGINE END ---- DIAG ENGINE END ----" ) - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::CleanupIncompleteTestSession -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::CleanupIncompleteTestSession() - { - if ( iStateMachine == NULL || - iStateMachine->CurrentState() == EStateNotReady || - iStateMachine->CurrentState() == EStateStopped ) - { - // Test is never started or already finished. Nothing to clean up here. - return; - } - - // At this point, we can either suspend or complete the test record. - // Normally, since state machine is not in EStateStopped state, - // record should suspended. - // - // However, even if it is not completely done executing the plan, - // if last test is already completed, engine will report TestCompleted( ETrue ). - // Otherwise, when examining db record for resuming, the record will appear - // incomplete, but in reality there is no more test to execute and resuming the - // record will immediately finish the session, which is meaningless. - // Hence, when last test plug-in is executed, engine will record test completed, - // instead of suspend, even if there are suite items left in plan. - - LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() State = %d", - iStateMachine->CurrentState() ) - - switch( iStateMachine->CurrentState() ) - { - case EStateStopped: - // all completed. Nothing to finalize. - break; - - case EStateNotReady: // fall through - case EStateCreatingPlan: - // Plan was not fully created. - // Mark the record as incomplete and let execution plan - // to figure out how to resume later. - // No need to call NotifyPluginsOfTestSessionEnd() since - // TestSessionBeginL() was never called. - iDbRecord.Suspend(); // in destructor. Error ignored. - break; - - case EStateCancelAll: - { - // Test session was being cancelled. Since we were in cancel all mode, - // it cannot be resumed. Mark the record completed. - NotifyPluginsOfTestSessionEnd(); - - TInt err = iDbRecord.TestCompleted( EFalse /* aFullyComplete */ ); - LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() " - L" TestCompleted( EFalse ) err = %d", err ) - // in destructor. Error ignored. - } - break; - - case EStateFinalizing: - { - // Engine was about to finalize, but never got a chance to. - // In this state, db record should always be closed with TestCompleted - // since it is a normal execution finish scenario and it cannot - // be resumed later. - NotifyPluginsOfTestSessionEnd(); - - TBool isFullyCompleted = ( iEngineError == KErrNone ); - TInt err = iDbRecord.TestCompleted( isFullyCompleted ); - LOGSTRING3( "CDiagEngineImpl::CleanupIncompleteTestSession() " - L"iDbRecord.TestCompleted( %d ) err = %d", isFullyCompleted, err ) - - // We are in destructor. Ignore errors from db. - } - break; - - default: - // In other states, engine was still executing some items. - // Check if it shoud be marked as suspended or not. - { - TBool allTestsCompleted = EFalse; - for ( TInt i = iPlan->CurrentIndex(); i < iPlan->Count(); i++ ) - { - if ( (*iPlan)[i].Plugin().Type() == MDiagPlugin::ETypeTestPlugin && - (*iPlan)[i].State() != MDiagExecPlanEntry::EStateCompleted ) - { - // Found a test entry that is not completed. - allTestsCompleted = EFalse; - break; //lint !e960 break OK here. - } - } - - NotifyPluginsOfTestSessionEnd(); - - if ( allTestsCompleted ) - { - TInt err = iDbRecord.TestCompleted( ETrue /* aFullyComplete */ ); - LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() " - L" iDbRecord.TestCompleted( ETrue ) err = %d", err ) - } - else - { - TInt err = iDbRecord.Suspend(); - LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession(). " - L"iDbRecord.Suspend() err = %d", err ) - } - - } - break; - - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ExecuteL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecuteL() - { - __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateNotReady, - Panic( EDiagFrameworkInvalidState ) ); - - iStateMachine->AddEventL( EEventExecute ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::SetCustomParam -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::SetCustomParam( TAny* aCustomParams ) - { - __ASSERT_ALWAYS( aCustomParams, Panic( EDiagFrameworkBadArgument ) ); - - // Custom parameter can be set only when engine is not running. - __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateNotReady, - Panic( EDiagFrameworkInvalidState ) ); - - iCustomParam = aCustomParams; - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::SuspendL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::SuspendL() - { - DiagFwInternal::TState state = iStateMachine->CurrentState(); - - // Suspendable states: - __ASSERT_ALWAYS( ( state == EStateRunning || - state == EStateCreatingPlan || - state == EStateFinalizing || - state == EStateStopped ), - Panic( EDiagFrameworkInvalidState ) ); - - if ( state == EStateFinalizing || state == EStateStopped ) - { - // ignore suspend request. All tests are already completed and - // we are just waiting to finalize db record and report final - // result. - return; - } - - StopAllRequests(); - - LOGSTRING( "CDiagEngineImpl::SuspendL(). Adding suspend event" ) - iStateMachine->AddEventL( EEventSuspend ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ResumeL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ResumeL() - { - __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateSuspended, - Panic( EDiagFrameworkInvalidState ) ); - - LOGSTRING( "CDiagEngineImpl::SuspendL(). Adding resume event" ) - AddResumeEventL( MDiagEngineObserver::EResumedByClient ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ExecutionPlanL -// --------------------------------------------------------------------------- -// -const MDiagPluginExecPlan& CDiagEngineImpl::ExecutionPlanL() const - { - return *iPlan; - } - - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ExecutionStopL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecutionStopL( TCancelMode aCancelMode ) - { - DiagFwInternal::TState state = iStateMachine->CurrentState(); - - // Acceptable states for execution stop. - __ASSERT_ALWAYS( state == EStateCreatingPlan || - state == EStateRunning || - state == EStateSuspended || - state == EStateFinalizing || - state == EStateStopped, - Panic( EDiagFrameworkInvalidState ) ); - - if ( state == EStateFinalizing || state == EStateStopped ) - { - // ignore cancel request. All tests are already completed and - // we are just waiting to finalize db record and report final - // result. - return; - } - - StopAllRequests(); - - if ( aCancelMode == ESkip ) - { - iStateMachine->AddEventL( EEventSkip ); - } - else - { - iStateMachine->AddEventL( EEventCancelAll ); - } - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ResetWatchdog -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ResetWatchdog() - { - iPlan->CurrentExecutionItem().ResetWatchdog(); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ResetWatchdog -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ResetWatchdog( TDiagEngineWatchdogTypes aWatchdogType ) - { - iPlan->CurrentExecutionItem().ResetWatchdog( aWatchdogType ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ResetWatchdog -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ResetWatchdog( TTimeIntervalMicroSeconds32 aExpectedTimeToComplete ) - { - iPlan->CurrentExecutionItem().ResetWatchdog( aExpectedTimeToComplete ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ViewAppUi -// --------------------------------------------------------------------------- -// -CAknViewAppUi& CDiagEngineImpl::ViewAppUi() - { - return iViewAppUi; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ViewAppUi -// --------------------------------------------------------------------------- -// -const CAknViewAppUi& CDiagEngineImpl::ViewAppUi() const - { - return iViewAppUi; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::DbRecord -// --------------------------------------------------------------------------- -// -RDiagResultsDatabaseRecord& CDiagEngineImpl::DbRecord() - { - return iDbRecord; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::DbRecord -// --------------------------------------------------------------------------- -// -const RDiagResultsDatabaseRecord& CDiagEngineImpl::DbRecord() const - { - return iDbRecord; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::PluginPool -// --------------------------------------------------------------------------- -// -CDiagPluginPool& CDiagEngineImpl::PluginPool() - { - return iPluginPool; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::PluginPool -// --------------------------------------------------------------------------- -// -const CDiagPluginPool& CDiagEngineImpl::PluginPool() const - { - return iPluginPool; - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::AddToConfigListL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::AddToConfigListL( - MDiagEngineCommon::TConfigListType aListType, - const TDesC& aText ) - { - switch ( aListType ) - { - case MDiagEngineCommon::EConfigListCallIngore: - iCallHandler->AddIgnoreNumberL( aText ); - break; - - default: - LOGSTRING2( "CDiagEngineImpl::AddToConfigListL(). Invalid ListType %d", - aListType ) - Panic( EDiagFrameworkBadArgument ); - break; - } - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::RemoveFromConfigListL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::RemoveFromConfigListL( - MDiagEngineCommon::TConfigListType aListType, - const TDesC& aText ) - { - switch ( aListType ) - { - case MDiagEngineCommon::EConfigListCallIngore: - iCallHandler->RemoveIgnoreNumberL( aText ); - break; - - default: - LOGSTRING2( "CDiagEngineImpl::RemoveFromConfigListL(). Invalid ListType %d", - aListType ) - Panic( EDiagFrameworkBadArgument ); - break; - } - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::CreateCommonDialogLC -// --------------------------------------------------------------------------- -// -CAknDialog* CDiagEngineImpl::CreateCommonDialogLC( TDiagCommonDialog aDialogType, - TAny* aInitData ) - { - return iObserver.CreateCommonDialogLC( aDialogType, aInitData ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::ExecuteAppCommandL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecuteAppCommandL( TDiagAppCommand aCommand, - TAny* aParam1, - TAny* aParam2 ) - { - iObserver.ExecuteAppCommandL( aCommand, aParam1, aParam2 ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::StopWatchdogTemporarily -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::StopWatchdogTemporarily() - { - if ( iStateMachine == NULL || iPlan == NULL ) - { - return; - } - - if ( iStateMachine->CurrentState() == EStateRunning ) - { - iPlan->CurrentExecutionItem().StopWatchdogTemporarily(); - } - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::IsDependencyDisabled -// --------------------------------------------------------------------------- -// -TBool CDiagEngineImpl::IsDependencyDisabled() const - { - return iEngineConfig.IsDependencyDisabled(); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCommon -// CDiagEngineImpl::CustomParam -// --------------------------------------------------------------------------- -// -TAny* CDiagEngineImpl::CustomParam() const - { - return iCustomParam; - } //lint !e1763 Custom param is just passed along. Does not actually change engine. - -// --------------------------------------------------------------------------- -// From class MDiagExecPlanEntryImplObserver -// CDiagEngineImpl::ExecPlanEntryProgressL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecPlanEntryProgressL( - CDiagExecPlanEntryImpl& aSender, - TUint aCurrentStep, - TUint aTotalSteps ) - { - LOGSTRING4( "CDiagEngineImpl::ExecPlanEntryProgressL: Plugin = 0x%08x, (%d / %d) ", - aSender.Plugin().Uid().iUid, - aCurrentStep, - aTotalSteps ) - - if ( aSender.Plugin().Uid() == iPlan->CurrentExecutionItem().Plugin().Uid() ) - { - CEventTestProgress* event = new ( ELeave ) CEventTestProgress( - aSender.Plugin(), aCurrentStep, aTotalSteps ); - - iStateMachine->AddEventL( event ); // ownership changed. - } - else - { - // probably timing issue. Ignore event. - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) ); - } - } - -// --------------------------------------------------------------------------- -// From class MDiagExecPlanEntryImplObserver -// CDiagEngineImpl::ExecPlanEntryExecutedL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecPlanEntryExecutedL( CDiagExecPlanEntryImpl& aSender ) - { - LOGSTRING2( "CDiagEngineImpl::ExecPlanEntryExecutedL: Plugin = 0x%08x", - aSender.Plugin().Uid().iUid ) - - if ( aSender.Plugin().Uid() != iPlan->CurrentExecutionItem().Plugin().Uid() ) - { - // probably timing issue. Ignore event. - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) ); - } - else - { - TInt error = KErrNone; - if ( aSender.IsStoppedByClient() ) - { - error = KErrCancel; - } - - CDiagResultsDatabaseItem* result = NULL; - - if ( aSender.Plugin().Type() == MDiagPlugin::ETypeTestPlugin ) - { - // Test was completed. Get test result. - CDiagExecPlanEntryImplTest& testEntry = - static_cast< CDiagExecPlanEntryImplTest& >( aSender ); - - result = testEntry.GetLastTestResultL(); - - __ASSERT_ALWAYS( result != NULL, Panic( EDiagFrameworkNullTestResult ) ); - } - - NotifyResultAndContinueL( error, result ); - } - } - -// --------------------------------------------------------------------------- -// From class MDiagExecPlanEntryImplObserver -// CDiagEngineImpl::ExecPlanEntryCriticalError -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecPlanEntryCriticalError( TInt aError ) - { - LOGSTRING2( "CDiagEngineImpl::ExecPlanEntryCriticalError: " - L"Critical failure %d", aError ) - - // Unrecoverable error has occered. e.g. out of memory, disk full etc. - iStateMachine->HandleError( aError ); - } - - -// --------------------------------------------------------------------------- -// From class MDiagEngineStateMachineObserver -// CDiagEngineImpl::HandleStateChangedL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleStateChangedL( - TState aPreviousState, - TState aCurrentState, - const CEventBasic& aEventPreview ) - { - // NOTE: This method is called by state machine as soon as an event that - // changes states is called. This means that it could execute within caller's - // call stack. (e.g. it could be still within application or plug-in's - // call stack.) It is best to limit amount of implementation here to - // things that must be done as soon as an event occurs. - // - // Suspend and Resume are exceptions since they require immediate notification - // to observer. Otherwise, observer might have mismatch in notifications. - - LOGSTRING3( "CDiagEngineImpl::HandleStateChangedL(): " - L"Entering State : %d( %S )", - aCurrentState, &iStateMachine->StateName( aCurrentState ) ) - - switch ( aCurrentState ) - { - case EStateSuspended: - // keep track of state befor suspended, so that we can resume - // to correct state. - iSuspendedPrevState = aPreviousState; - - MDiagEngineObserver::TSuspendReason reason; - if ( aEventPreview.GetType() == EEventSuspend ) - { - reason = MDiagEngineObserver::ESuspendByClient; - } - else - { - reason = MDiagEngineObserver::ESuspendByPhoneCall; - } - - // This will also notify iObserver. - DoSuspendL( reason ); - break; - - case EStateRunning: - if ( aEventPreview.GetType() == EEventResumeToRunning ) - { - LOGSTRING( "CDiagEngineImpl::HandleStateChangedL(). Notify resume" ) - iObserver.TestExecutionResumedL( iResumeReason ); - } - break; - - case EStateCreatingPlan: - if ( aEventPreview.GetType() == EEventResumeToCreatingPlan ) - { - LOGSTRING( "CDiagEngineImpl::HandleStateChangedL(). Notify resume" ) - iObserver.TestExecutionResumedL( iResumeReason ); - } - break; - - default: - // Do nothing. - break; - } - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineStateMachineObserver -// CDiagEngineImpl::HandleEventL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventL( CEventBasic& aEvent ) - { - LOGSTRING5( "CDiagEngineImpl::HandleEventL(): State=%d(%S), Event=%d(%S)", - iStateMachine->CurrentState(), - &iStateMachine->StateName( iStateMachine->CurrentState() ), - aEvent.GetType(), &aEvent.ToString() ) - - switch ( iStateMachine->CurrentState() ) - { - case EStateNotReady: - LOGSTRING( "CDiagEngineImpl::HandleEventL: " - L"ERROR! Cannot accept events in EStateNotReady State" ) - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) ); - break; - - case EStateCreatingPlan: - HandleEventInCreatingPlanStateL( aEvent ); - break; - - case EStateRunning: - HandleEventInRunningStateL( aEvent ); - break; - - case EStateCancelAll: - HandleEventInCancelAllStateL( aEvent ); - break; - - case EStateSuspended: - HandleEventInSuspendedStateL( aEvent ); - break; - - case EStateFinalizing: - HandleEventInFinalizingStateL( aEvent ); - break; - - case EStateStopped: - HandleEventInStoppedStateL( aEvent ); - break; - - case EStateAny: // fall through - default: - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) ); - break; - } - LOGSTRING( "CDiagEngineImpl::HandleEventL(): return" ) - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInCreatingPlanStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInCreatingPlanStateL( CEventBasic& aEvent ) - { - switch ( aEvent.GetType() ) - { - case EEventExecute: // fall through - case EEventResumeToCreatingPlan: - StartCreateExecutionPlanL(); - break; - - default: - LOGSTRING2( "CDiagEngineImpl::HandleEventInCreatingPlanStateL: " - L"Invalid event = %d", aEvent.GetType() ) - // Ignored. - break; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInRunningStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInRunningStateL( CEventBasic& aEvent ) - { - switch ( aEvent.GetType() ) - { - case EEventPlanCreated: - // Normal case. Plan is created normally. - HandlePlanCreatedL(); - break; - - case EEventExecuteNext: - ExecuteNextPluginL(); - break; - - case EEventSkip: - HandleSkipL(); - break; - - case EEventTestProgress: - NotifyTestProgressL( static_cast( aEvent ) ); - break; - - case EEventResumeToRunning: - DoResumeL(); - break; - - default: - LOGSTRING2( "CDiagEngineImpl::HandleEventInRunningStateL " - L"Invalid event = %d", aEvent.GetType() ) - break; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInCancelAllStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInCancelAllStateL( CEventBasic& aEvent ) - { - switch ( aEvent.GetType() ) - { - case EEventCancelAll: - case EEventExecuteNext: - HandleCancelAllL(); - break; - - case EEventSuspend: // fall through - case EEventVoiceCallActive: - // suspend is always handed in its own state - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) ); - break; - - default: - // other events are ingored( e.g. progress ), since - // cancel has been requested - LOGSTRING2( "CDiagEngineImpl::HandleEventInCancelAllStateL " - L"Invalid event = %d", aEvent.GetType() ) - break; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInSuspendedStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInSuspendedStateL( CEventBasic& aEvent ) - { - switch ( aEvent.GetType() ) - { - case EEventSuspend: - // nothing to do. Suspend is immediate, so it is handled - // in HandleStateChangedL - break; - - default: - // suspended. ignore. - LOGSTRING2( "CDiagEngineImpl::HandleEventInSuspendedStateL " - L"Invalid event = %d", aEvent.GetType() ) - break; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInFinalizingStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInFinalizingStateL( CEventBasic& aEvent ) - { - switch ( aEvent.GetType() ) - { - case EEventAllPluginsCompleted: - FinalizeTestSessionL(); - break; - - default: - // ignore all others. This is because if the state machine - // gets here due to error, there may be left over events in - // event queue. Those should be ignored. - LOGSTRING2( "CDiagEngineImpl::HandleEventInFinalizingStateL " - L"Invalid event = %d", aEvent.GetType() ) - break; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventInStoppedStateL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleEventInStoppedStateL( CEventBasic& /* aEvent */ ) - { - // ignore all events. This is because if the state machine - // gets here due to error, there may be left over events in - // event queue. Those should be ignored. - } - - -// --------------------------------------------------------------------------- -// From class MDiagEngineStateMachineObserver -// CDiagEngineImpl::HandleError -// --------------------------------------------------------------------------- -// -TState CDiagEngineImpl::HandleError( TState aCurrentState, TInt aError ) - { - LOGSTRING4( "CDiagEngineImpl::HandleError() State %d(%S), ERROR %d", - aCurrentState, - &iStateMachine->StateName( aCurrentState ), - aError ) - - switch ( aCurrentState ) - { - case EStateNotReady: // fall through. - case EStateStopped: - // was not running.. Nothing to do. - return aCurrentState; - - default: - { - iEngineError = aError; - - // Database record is open. Suspend the record so that - // user can retry later. - iDbRecord.Suspend(); // error ignored - - // Ignore error from application in this case since we are already - // handling error. - TRAP_IGNORE( iObserver.TestExecutionCompletedL( aError ) ) - } - return EStateStopped; - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::StartCreateExecutionPlanL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::StartCreateExecutionPlanL() - { - LOGSTRING( "CDiagEngineImpl::StartCreateExecutionPlanL() Start creating plan" ) - if ( iContinueIncompleteRecord ) - { - iPlan->InitializeL( iStatus ); - } - else - { - iPlan->InitializeL( iStatus, iBatch ); - } - SetActive(); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleEventExecute -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandlePlanCreatedL() - { - if ( iPlan->Count() == 0 ) - { - // Error. There were no items in the plan. - iEngineError = KErrArgument; - iStateMachine->AddEventL( EEventAllPluginsCompleted ); - return; - } - - // First initialize each plugins for execution. - // Note that if initialization step fails, it will be caught by - // CStateMachine's active object, and will call ::HandleError() - LOGSTRING( "CDiagEngineImpl::HandlePlanCreatedL() : Phase I - Initaliaze all plugins" ) - for ( TInt i = 0; i < iPlan->Count(); i++ ) - { - MDiagPlugin& plugin = (*iPlan)[i].Plugin(); - plugin.TestSessionBeginL( *this, iEngineConfig.IsDependencyDisabled(), iCustomParam ); - } - - LOGSTRING( "CDiagEngineImpl::HandlePlanCreatedL() : Phase II - Execution Begins" ) - iPlan->ResetExecutionCursor(); - iStateMachine->AddEventL( EEventExecuteNext ); - iObserver.TestExecutionBeginL(); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::ExecuteNextPluginL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::ExecuteNextPluginL() - { - // first, check if cursor needs to be advanced - if ( iPlan->CurrentExecutionItem().State() == MDiagExecPlanEntry::EStateCompleted ) - { - TBool moved = iPlan->MoveCursorToNext(); - if ( !moved ) - { - // cursor should always move. This is because execute next event - // should have never been created by NotifyResultAndContinueL - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) ); - return; - } - } - - // Check if we are in call. If so, suspend current execution immediately. - if ( iCallHandler->CurrentState() == EDiagEngineCallHandlerStateBusy ) - { - LOGSTRING( "CDiagEngineImpl::ExecuteNextPluginL() Call in progress" ) - iStateMachine->AddEventL( EEventVoiceCallActive ); - return; - } - - LOGSTRING2( "CDiagEngineImpl::ExecuteNextPluginL() : " - L"Executing plugin 0x%08x", - iPlan->CurrentExecutionItem().Plugin().Uid().iUid ) - - iPlan->CurrentExecutionItem().ExecuteL(); - } - - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NotifyTestProgressL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::NotifyTestProgressL( CEventTestProgress& aEvent ) - { - // make sure that we are reporting progress on currently executing test. - CDiagExecPlanEntryImpl& currItem = iPlan->CurrentExecutionItem(); - - if ( currItem.Plugin().Uid() == aEvent.Sender().Uid() && - currItem.State() != MDiagExecPlanEntry::EStateCompleted ) - { - LOGSTRING3( "CDiagEngineImpl::NotifyTestProgressL. " - L"Calling TestExecutionProgressL( %d, %d )", - aEvent.CurrStep(), - aEvent.TotalSteps() ) - iObserver.TestExecutionProgressL( aEvent.CurrStep(), aEvent.TotalSteps() ); - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NotifyResultAndContinueL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::NotifyResultAndContinueL( - TInt aError, - CDiagResultsDatabaseItem* aResult ) - { - // aResult can be NULL if it was executing suite. - if ( aResult ) - { - CleanupStack::PushL( aResult ); - } - - if ( aResult ) - { - CleanupStack::Pop( aResult ); - } - - iObserver.TestExecutionPluginExecutedL( aError, aResult ); - aResult = NULL; // aResult ownership transferred above. - - if ( iPlan->IsLastPlugin() ) - { - User::After(2000000); - iStateMachine->AddEventL( EEventAllPluginsCompleted ); - } - else - { - iStateMachine->AddEventL( EEventExecuteNext ); - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleSkipL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleSkipL() - { - // if plan was empty, ( e.g. before any execution has actually started. - // do nothing. - if ( iPlan->Count() == 0 ) - { - iEngineError = KErrArgument; - iStateMachine->AddEventL( EEventAllPluginsCompleted ); - return; - } - - // Stop execution. While plug-ins are required to stop immediately, - // writing to results db is async. Completion is notified is - // ExecPlanEntryExecutedL() - iPlan->CurrentExecutionItem().StopExecutionByClientL( ESkip ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::HandleCancelAllL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::HandleCancelAllL() - { - iEngineError = KErrCancel; - - if ( iPlan->Count() == 0 ) - { - // If plan was empty, ( e.g. before any execution has actually started ), - // do nothing and send back completed with KErrCancel. - iStateMachine->AddEventL( EEventAllPluginsCompleted ); - return; - } - - if ( iPlan->CurrentExecutionItem().State() == MDiagExecPlanEntry::EStateCompleted ) - { - TBool moved = iPlan->MoveCursorToNext(); - if ( !moved ) - { - // cursor should always move. This is because execute next event - // should have never been created by NotifyResultAndContinueL - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) ); - return; - } - } - - iPlan->CurrentExecutionItem().StopExecutionByClientL( ECancelAll ); - // Continue to ::ExecPlanEntryExecutedL - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::DoSuspendL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::DoSuspendL( MDiagEngineObserver::TSuspendReason aReason ) - { - if ( iSuspendedPrevState == EStateNotReady || - iSuspendedPrevState == EStateCreatingPlan || - iSuspendedPrevState == EStateStopped ) - { - // not much to do here. - } - else - { - StopAllRequests(); - - iSuspendReason = aReason; - - iPlan->CurrentExecutionItem().SuspendL(); - } - - LOGSTRING( "CDiagEngineImpl::DoSuspendL: Engine Suspended" ) - iObserver.TestExecutionSuspendedL( aReason ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::AddResumeEventL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::AddResumeEventL( MDiagEngineObserver::TResumeReason aReason ) - { - iResumeReason = aReason; - if ( iSuspendedPrevState == EStateNotReady || - iSuspendedPrevState == EStateCreatingPlan ) - { - iStateMachine->AddEventL( EEventResumeToCreatingPlan ); - } - else - { - iStateMachine->AddEventL( EEventResumeToRunning ); - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::DoResumeL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::DoResumeL() - { - LOGSTRING( "CDiagEngineImpl::DoResumeL: Resuming Engine..." ) - CDiagExecPlanEntryImpl& entry = iPlan->CurrentExecutionItem(); - - if ( entry.State() == MDiagExecPlanEntry::EStateCompleted ) - { - // already completed. nothing to resume. - ExecuteNextPluginL(); - } - else - { - entry.ResumeL(); - } - } - - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::CreateDbItem -// -// --------------------------------------------------------------------------- -// -CDiagResultsDatabaseItem* CDiagEngineImpl::CreateDbItemL( - CDiagExecPlanEntryImpl& aCurrItem, - CDiagResultsDatabaseItem::TResult aResultType ) const - { - return CDiagResultsDbItemBuilder::CreateSimpleDbItemL( aCurrItem.Plugin().Uid(), - aCurrItem.AsDependency(), - aResultType ); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::NotifyPluginsOfTestSessionEnd -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::NotifyPluginsOfTestSessionEnd() - { - LOGSTRING( "CDiagEngineImpl::NotifyPluginsOfTestSessionEnd() : " - L"Phase III - Cleaning up stage" ) - // unlike initialization stage, it will TRAP all errors so that - // every plug-ins will have a chance to run its clean up code. - for ( TInt index = 0; index < iPlan->Count(); index++ ) - { - MDiagPlugin& plugin = (*iPlan)[index].Plugin(); - TRAPD( err, plugin.TestSessionEndL( - *this, iEngineConfig.IsDependencyDisabled(), iCustomParam ) ); - if ( err != KErrNone ) - { - LOGSTRING3( "CDiagEngineImpl::NotifyPluginsOfTestSessionEnd(): " - L"Plug-in Uid %d CleanupL failed with error %d", - plugin.Uid().iUid, err ) - } - } - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::StopAllRequests -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::StopAllRequests() - { - Cancel(); - StopWatchdogTemporarily(); - } - -// --------------------------------------------------------------------------- -// CDiagEngineImpl::FinalizeTestSessionL -// -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::FinalizeTestSessionL() - { - LOGSTRING( "CDiagEngineImpl::FinalizeTestSessionL() " ) - - // This causes state to change to EStateStopped - //iStateMachine->AddEventL( EEventFinalized ); - - // Call TestSessionEnd on all plug-ins - NotifyPluginsOfTestSessionEnd(); - - // Mark DB completed. - TBool isFullyCompleted = ( iEngineError == KErrNone ); - - TInt err = iDbRecord.TestCompleted( isFullyCompleted ); - if ( err != KErrNone ) - { - LOGSTRING3( "CDiagEngineImpl::FinalizeTestSessionL() " - L"iDbRecord.TestCompleted( %d ) return err %d", - isFullyCompleted, - err ) - iEngineError = err; - } - - // Let observer know that test is completed. - iObserver.TestExecutionCompletedL( iEngineError ); - } - -// --------------------------------------------------------------------------- -// From class MDiagEngineCallHandlerObserver -// CDiagEngineImpl::CallHandlerStateChangedL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::CallHandlerStateChangedL( TDiagEngineCallHandlerState aState ) - { - if ( aState == EDiagEngineCallHandlerStateBusy && - ( iStateMachine->CurrentState() == EStateRunning) ) - { - iStateMachine->AddEventL( EEventVoiceCallActive ); - } - else if ( aState == EDiagEngineCallHandlerStateIdle && - iStateMachine->CurrentState() == EStateSuspended && - iSuspendReason == MDiagEngineObserver::ESuspendByPhoneCall ) - { - AddResumeEventL( MDiagEngineObserver::EAutoResumedByCallHangup ); - } - else - { - // Ignored - } - } - - -// --------------------------------------------------------------------------- -// From class CActive -// CDiagEngineImpl::RunL -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::RunL() - { - LOGSTRING2( "CDiagEngineImpl::RunL() error %d", iStatus.Int() ) - - User::LeaveIfError( iStatus.Int() ); - - switch ( iStateMachine->CurrentState() ) - { - case EStateCreatingPlan: - // plan created successfully. - iStateMachine->AddEventL( EEventPlanCreated ); - break; - - default: - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) ); - break; - } - } - -// --------------------------------------------------------------------------- -// From class CActive -// CDiagEngineImpl::DoCancel -// --------------------------------------------------------------------------- -// -void CDiagEngineImpl::DoCancel() - { - switch ( iStateMachine->CurrentState() ) - { - case EStateCreatingPlan: - iPlan->Cancel(); - break; - - default: - // Nothing to do - break; - } - } - -// --------------------------------------------------------------------------- -// From class CActive -// CDiagEngineImpl::RunError -// --------------------------------------------------------------------------- -// -TInt CDiagEngineImpl::RunError( TInt aError ) - { - if ( iStateMachine ) - { - iStateMachine->HandleError( aError ); - } - - return KErrNone; - } - -// End of File -