devicediagnosticsfw/diagframework/src/diagengineimpl.cpp
branchRCL_3
changeset 61 b183ec05bd8c
parent 59 13d7c31c74e0
child 62 19bba8228ff0
equal deleted inserted replaced
59:13d7c31c74e0 61:b183ec05bd8c
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class definition of CDiagEngineImpl
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // CLASS DECLARATION
       
    20 #include "diagengineimpl.h"                 // CDiagEngineImpl
       
    21 
       
    22 // SYSTEM INCLUDE FILES
       
    23 #include <DiagPluginPool.h>                 // CDiagPluginPool
       
    24 #include <DiagFrameworkDebug.h>             // LOGSTRING
       
    25 #include <DiagPlugin.h>                     // MDiagPlugin
       
    26 #include <DiagTestExecParam.h>              // TDiagTestExecParam
       
    27 #include <DiagSuiteExecParam.h>             // TDiagSuiteExecParam
       
    28 #include <DiagResultsDbItemBuilder.h>       // CDiagResultsDbItemBuilder
       
    29 #include <DiagResultsDbRecordEngineParam.h> // CDiagResultsDbRecordEngineParam
       
    30 
       
    31 // USER INCLUDE FILES
       
    32 #include "diagpluginexecplanimpl.h"         // CDiagPluginExecPlanImpl
       
    33 #include "diagexecplanentryimpltest.h"      // CDiagExecPlanEntryImplTest
       
    34 #include "diagenginestatemachine.h"         // DiagFwInternal::CStateMachine
       
    35 #include "diagenginecallhandler.h"          // CDiagEngineCallHandler
       
    36 #include "diagframework.pan"                // Panic Codes
       
    37 #include "diagengineconfig.h"               // TDiagEngineConfig
       
    38 
       
    39 // EVENT INCLUDE FILES
       
    40 #include "diagengineeventbasic.h"           // DiagFwInternal::CEventBasic
       
    41 #include "diagengineeventtestprogress.h"    // DiagFwInternal::CEventTestProgress
       
    42 
       
    43 using namespace DiagFwInternal;
       
    44 
       
    45 // DATA
       
    46 
       
    47 // ======== LOCAL FUNCTIONS ========
       
    48 
       
    49 // ======== MEMBER FUNCTIONS ========
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // CDiagEngineImpl::NewL()
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 CDiagEngineImpl* CDiagEngineImpl::NewL( 
       
    56         CAknViewAppUi&          aViewAppUi, 
       
    57         MDiagEngineObserver&    aObserver,
       
    58         RDiagResultsDatabase&   aDbSession,
       
    59         CDiagPluginPool&        aPluginPool,
       
    60         TBool                   aDisableDependency,
       
    61         const RArray< TUid >&   aExecutionBatch )
       
    62     {
       
    63     CDiagEngineImpl* self = CDiagEngineImpl::NewLC( aViewAppUi,
       
    64                                                     aObserver,
       
    65                                                     aDbSession,
       
    66                                                     aPluginPool,
       
    67                                                     aDisableDependency,
       
    68                                                     aExecutionBatch );
       
    69     CleanupStack::Pop( self );
       
    70     return self;
       
    71     }
       
    72 
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // CDiagEngineImpl::NewLC()
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CDiagEngineImpl* CDiagEngineImpl::NewLC( 
       
    79         CAknViewAppUi&          aViewAppUi, 
       
    80         MDiagEngineObserver&    aObserver,
       
    81         RDiagResultsDatabase&   aDbSession,
       
    82         CDiagPluginPool&        aPluginPool,
       
    83         TBool                   aDisableDependency,
       
    84         const RArray< TUid >&   aExecutionBatch )
       
    85     {
       
    86     CDiagEngineImpl* self = new ( ELeave ) CDiagEngineImpl( aViewAppUi,
       
    87                                                             aObserver,
       
    88                                                             aDbSession,
       
    89                                                             aPluginPool );
       
    90 
       
    91     CleanupStack::PushL( self );
       
    92     self->ConstructNewRecordL( aDisableDependency, aExecutionBatch );
       
    93     return self;
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // CDiagEngineImpl::NewL()
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 CDiagEngineImpl* CDiagEngineImpl::NewL( CAknViewAppUi&          aViewAppUi, 
       
   101                                         MDiagEngineObserver&    aObserver,
       
   102                                         RDiagResultsDatabase&   aDbSession,
       
   103                                         CDiagPluginPool&        aPluginPool,
       
   104                                         TUid                    aIncompleteRecordUid )
       
   105     {
       
   106     CDiagEngineImpl* self = CDiagEngineImpl::NewLC( aViewAppUi,
       
   107                                                     aObserver,
       
   108                                                     aDbSession,
       
   109                                                     aPluginPool,
       
   110                                                     aIncompleteRecordUid );
       
   111     CleanupStack::Pop( self );
       
   112     return self;
       
   113     }
       
   114 
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // CDiagEngineImpl::NewLC()
       
   118 // ---------------------------------------------------------------------------
       
   119 //
       
   120 CDiagEngineImpl* CDiagEngineImpl::NewLC( CAknViewAppUi&    aViewAppUi, 
       
   121                                    MDiagEngineObserver&    aObserver,
       
   122                                    RDiagResultsDatabase&   aDbSession,
       
   123                                    CDiagPluginPool&        aPluginPool,
       
   124                                    TUid                    aIncompleteRecordUid )
       
   125     {
       
   126     CDiagEngineImpl* self = new ( ELeave ) CDiagEngineImpl( aViewAppUi,
       
   127                                                             aObserver,
       
   128                                                             aDbSession,
       
   129                                                             aPluginPool );
       
   130 
       
   131     CleanupStack::PushL( self );
       
   132     self->ConstructIncompleteRecordL( aIncompleteRecordUid );
       
   133     return self;
       
   134     }
       
   135 
       
   136 // ---------------------------------------------------------------------------
       
   137 // CDiagEngineImpl::CDiagEngineImpl
       
   138 // ---------------------------------------------------------------------------
       
   139 //
       
   140 CDiagEngineImpl::CDiagEngineImpl( CAknViewAppUi&          aViewAppUi,
       
   141                                   MDiagEngineObserver&    aObserver,
       
   142                                   RDiagResultsDatabase&   aDbSession,
       
   143                                   CDiagPluginPool&        aPluginPool )
       
   144     :   CActive( EPriorityStandard ),
       
   145         iViewAppUi( aViewAppUi ),
       
   146         iObserver( aObserver ),
       
   147         iDbSession( aDbSession ),
       
   148         iPluginPool( aPluginPool )
       
   149     {
       
   150     LOGSTRING( "---- DIAG ENGINE BEGIN ---- DIAG ENGINE BEGIN ----{" )
       
   151     CActiveScheduler::Add( this );
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------------------------
       
   155 // CDiagEngineImpl::ConstructNewRecordL
       
   156 // ---------------------------------------------------------------------------
       
   157 //
       
   158 void CDiagEngineImpl::ConstructNewRecordL( TBool aDisableDependency,
       
   159                                            const RArray< TUid >& aExecutionBatch )
       
   160     {
       
   161     ConstructCommonL();
       
   162 
       
   163     LOGSTRING( "CDiagEngineImpl::ConstructNewRecordL()" )
       
   164 
       
   165     iContinueIncompleteRecord = EFalse;
       
   166     iEngineConfig.SetDependencyDisabled( aDisableDependency );
       
   167 
       
   168     // convert uid array to plugin reference array.
       
   169     // Also, make a copy of the plug-in UID array so that it can be
       
   170     // passed to database.
       
   171     TInt batchCount = aExecutionBatch.Count();
       
   172 
       
   173     // uidList must be allocated in heap since it database will own the data later.
       
   174     RArray< TUid >* uidList = new( ELeave )RArray< TUid >();
       
   175     CleanupStack::PushL( uidList );     // to delete array itself.
       
   176     CleanupClosePushL( *uidList );      // to call close.
       
   177 
       
   178     uidList->ReserveL( batchCount );
       
   179     
       
   180     MDiagPlugin* plugin = NULL;
       
   181 
       
   182     for ( TInt i = 0; i < batchCount ; i++ )
       
   183         {
       
   184         LOGSTRING2( "CDiagEngineImpl::ConstructNewRecordL() "
       
   185             L"Add plugin 0x%08x", aExecutionBatch[i].iUid )
       
   186             
       
   187         iPluginPool.FindPlugin( aExecutionBatch[i], plugin );
       
   188         iBatch.AppendL( plugin );
       
   189         plugin = NULL;
       
   190 
       
   191         uidList->AppendL( aExecutionBatch[i] );
       
   192         }
       
   193 
       
   194     CDiagResultsDbRecordEngineParam* engineParam = 
       
   195         CDiagResultsDbRecordEngineParam::NewL(
       
   196             uidList,                                // ownership transfer
       
   197             !iEngineConfig.IsDependencyDisabled()   /* isDependencyExecution */ );
       
   198 
       
   199     CleanupStack::Pop( uidList );   // CleanupClosePushL( *uidList )
       
   200     CleanupStack::Pop( uidList );   // CleanupStack::PushL( uidList )
       
   201     uidList = NULL;
       
   202 
       
   203     CleanupStack::PushL( engineParam );
       
   204     User::LeaveIfError( 
       
   205         iDbRecord.CreateNewRecord( iDbSession, iRecordId, *engineParam ) );
       
   206     CleanupStack::PopAndDestroy( engineParam );
       
   207     engineParam = NULL;
       
   208 
       
   209     iPlan = CDiagPluginExecPlanImpl::NewL( *this, iEngineConfig, *this );
       
   210     }
       
   211 
       
   212 // ---------------------------------------------------------------------------
       
   213 // CDiagEngineImpl::ConstructIncompleteRecordL
       
   214 // ---------------------------------------------------------------------------
       
   215 //
       
   216 void CDiagEngineImpl::ConstructIncompleteRecordL( TUid aIncompleteRecordUid )
       
   217     {
       
   218     ConstructCommonL();
       
   219 
       
   220     LOGSTRING2( "CDiagEngineImpl::ConstructIncompleteRecordL() "
       
   221         L"RecordId = 0x%08x", aIncompleteRecordUid.iUid )
       
   222         
       
   223     iRecordId = aIncompleteRecordUid;
       
   224     iContinueIncompleteRecord = ETrue;
       
   225 
       
   226     User::LeaveIfError( 
       
   227         iDbRecord.Connect( iDbSession, 
       
   228                            iRecordId,
       
   229                            EFalse   /* aReadOnly */ ) );
       
   230 
       
   231     // make sure that record is open for writing.
       
   232     TBool isTestCompleted = EFalse;
       
   233     User::LeaveIfError( iDbRecord.IsTestCompleted( isTestCompleted ) );
       
   234     if ( isTestCompleted )
       
   235         {
       
   236         User::Leave( KErrLocked );
       
   237         }
       
   238 
       
   239     // recover original parameter
       
   240     CDiagResultsDbRecordEngineParam* engineParam = NULL;
       
   241     User::LeaveIfError(
       
   242         iDbRecord.GetEngineParam( engineParam ) );
       
   243 
       
   244     CleanupStack::PushL( engineParam );
       
   245 
       
   246     // Recover original batch.
       
   247     MDiagPlugin* plugin = NULL;
       
   248     iEngineConfig.SetDependencyDisabled( !engineParam->DependencyExecution() );
       
   249     const RArray< TUid >& uidArray = engineParam->ExecutionsUidArray();
       
   250     TInt count = uidArray.Count();
       
   251     for ( TInt i = 0; i < count; i++ )
       
   252         {
       
   253         LOGSTRING2( "CDiagEngineImpl::ConstructNewRecordL() "
       
   254             L"Add plugin 0x%08x", uidArray[i].iUid )
       
   255             
       
   256         User::LeaveIfError( 
       
   257             iPluginPool.FindPlugin( uidArray[i], plugin ) );
       
   258         iBatch.AppendL( plugin );
       
   259         plugin = NULL;
       
   260         }
       
   261     
       
   262     CleanupStack::PopAndDestroy( engineParam );
       
   263     engineParam = NULL;
       
   264 
       
   265     iPlan = CDiagPluginExecPlanImpl::NewL( *this, iEngineConfig, *this );
       
   266     }
       
   267 
       
   268 // ---------------------------------------------------------------------------
       
   269 // CDiagEngineImpl::ConstructCommonL()
       
   270 // ---------------------------------------------------------------------------
       
   271 //
       
   272 void CDiagEngineImpl::ConstructCommonL()
       
   273     {
       
   274     LOGSTRING( "CDiagEngineImpl::ConstructCommonL." )
       
   275 
       
   276     // Read Cenrep key
       
   277     iEngineConfig.ReadCenrepKeysL();
       
   278 
       
   279     // Create state machine.
       
   280     iStateMachine = CStateMachine::NewL( *this );
       
   281 
       
   282     // Create call handler.
       
   283     iCallHandler = CDiagEngineCallHandler::NewL( *this );
       
   284 
       
   285     }
       
   286 
       
   287 // ---------------------------------------------------------------------------
       
   288 // CDiagEngineImpl::~CDiagEngineImpl
       
   289 // ---------------------------------------------------------------------------
       
   290 //
       
   291 CDiagEngineImpl::~CDiagEngineImpl()
       
   292     {
       
   293     LOGSTRING( "CDiagEngineImpl::~CDiagEngineImpl() Destructor" )
       
   294 
       
   295     StopAllRequests();
       
   296 
       
   297     CleanupIncompleteTestSession();
       
   298 
       
   299     // always delete plan before record is closed.
       
   300     delete iPlan;
       
   301     iPlan = NULL;
       
   302 
       
   303     iDbRecord.Close();
       
   304 
       
   305     iBatch.Close(); // MUST NOT destroy since we don't own elements within it
       
   306 
       
   307     delete iStateMachine;
       
   308     iStateMachine = NULL;
       
   309 
       
   310     delete iSuspendedResult;
       
   311     iSuspendedResult = NULL;
       
   312 
       
   313     delete iCallHandler;
       
   314     iCallHandler = NULL;
       
   315 
       
   316     LOGSTRING( "} ---- DIAG ENGINE END ---- DIAG ENGINE END ----" )
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // CDiagEngineImpl::CleanupIncompleteTestSession
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 void CDiagEngineImpl::CleanupIncompleteTestSession()
       
   324     {
       
   325     if ( iStateMachine == NULL || 
       
   326             iStateMachine->CurrentState() == EStateNotReady ||
       
   327             iStateMachine->CurrentState() == EStateStopped )
       
   328         {
       
   329         // Test is never started or already finished. Nothing to clean up here.
       
   330         return;
       
   331         }
       
   332 
       
   333     // At this point, we can either suspend or complete the test record.
       
   334     // Normally, since state machine is not in EStateStopped state,
       
   335     // record should suspended.
       
   336     //
       
   337     // However, even if it is not completely done executing the plan, 
       
   338     // if last test is already completed, engine will report TestCompleted( ETrue ).
       
   339     // Otherwise, when examining db record for resuming, the record will appear
       
   340     // incomplete, but in reality there is no more test to execute and resuming the
       
   341     // record will immediately finish the session, which is meaningless.
       
   342     // Hence, when last test plug-in is executed, engine will record test completed,
       
   343     // instead of suspend, even if there are suite items left in plan.
       
   344 
       
   345     LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() State = %d", 
       
   346         iStateMachine->CurrentState() )
       
   347 
       
   348     switch( iStateMachine->CurrentState() )
       
   349         {
       
   350         case EStateStopped:
       
   351             // all completed. Nothing to finalize.
       
   352             break;
       
   353 
       
   354         case EStateNotReady:        // fall through
       
   355         case EStateCreatingPlan:
       
   356             // Plan was not fully created.
       
   357             // Mark the record as incomplete and let execution plan
       
   358             // to figure out how to resume later.
       
   359             // No need to call NotifyPluginsOfTestSessionEnd() since 
       
   360             // TestSessionBeginL() was never called. 
       
   361             iDbRecord.Suspend();    // in destructor. Error ignored.
       
   362             break;
       
   363         
       
   364         case EStateCancelAll:
       
   365             {
       
   366             // Test session was being cancelled. Since we were in cancel all mode,
       
   367             // it cannot be resumed. Mark the record completed.
       
   368             NotifyPluginsOfTestSessionEnd();
       
   369 
       
   370             TInt err =  iDbRecord.TestCompleted( EFalse /* aFullyComplete */ );
       
   371             LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() "
       
   372                 L" TestCompleted( EFalse ) err = %d", err )
       
   373             // in destructor. Error ignored.
       
   374             }
       
   375             break;
       
   376 
       
   377         case EStateFinalizing:
       
   378             {
       
   379             // Engine was about to finalize, but never got a chance to.
       
   380             // In this state, db record should always be closed with TestCompleted
       
   381             // since it is a normal execution finish scenario and it cannot
       
   382             // be resumed later.
       
   383             NotifyPluginsOfTestSessionEnd();
       
   384 
       
   385             TBool isFullyCompleted = ( iEngineError == KErrNone );
       
   386             TInt err = iDbRecord.TestCompleted( isFullyCompleted );
       
   387             LOGSTRING3( "CDiagEngineImpl::CleanupIncompleteTestSession() "
       
   388                 L"iDbRecord.TestCompleted( %d ) err = %d", isFullyCompleted, err )
       
   389             
       
   390             // We are in destructor. Ignore errors from db.
       
   391             }
       
   392             break;
       
   393 
       
   394         default:
       
   395             // In other states, engine was still executing some items.
       
   396             // Check if it shoud be marked as suspended or not.
       
   397             {
       
   398             TBool allTestsCompleted = EFalse;
       
   399             for ( TInt i = iPlan->CurrentIndex(); i < iPlan->Count(); i++ )
       
   400                 {
       
   401                 if ( (*iPlan)[i].Plugin().Type() == MDiagPlugin::ETypeTestPlugin &&
       
   402                      (*iPlan)[i].State() != MDiagExecPlanEntry::EStateCompleted )
       
   403                     {
       
   404                     // Found a test entry that is not completed.
       
   405                     allTestsCompleted = EFalse;
       
   406                     break; //lint !e960  break OK here.
       
   407                     }
       
   408                 }
       
   409 
       
   410             NotifyPluginsOfTestSessionEnd();
       
   411 
       
   412             if ( allTestsCompleted )
       
   413                 {
       
   414                 TInt err =  iDbRecord.TestCompleted( ETrue /* aFullyComplete */ );
       
   415                 LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession() "
       
   416                     L" iDbRecord.TestCompleted( ETrue ) err = %d", err )
       
   417                 }
       
   418             else
       
   419                 {
       
   420                 TInt err = iDbRecord.Suspend();
       
   421                 LOGSTRING2( "CDiagEngineImpl::CleanupIncompleteTestSession(). "
       
   422                     L"iDbRecord.Suspend() err = %d", err )
       
   423                 }
       
   424             
       
   425             }
       
   426             break;
       
   427 
       
   428         }
       
   429     }
       
   430 
       
   431 // ---------------------------------------------------------------------------
       
   432 // CDiagEngineImpl::ExecuteL
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 void CDiagEngineImpl::ExecuteL()
       
   436     {
       
   437     __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateNotReady,
       
   438                      Panic( EDiagFrameworkInvalidState ) );
       
   439 
       
   440     iStateMachine->AddEventL( EEventExecute );
       
   441     }
       
   442 
       
   443 // ---------------------------------------------------------------------------
       
   444 // CDiagEngineImpl::SetCustomParam
       
   445 // ---------------------------------------------------------------------------
       
   446 //
       
   447 void CDiagEngineImpl::SetCustomParam( TAny* aCustomParams )
       
   448     {
       
   449     __ASSERT_ALWAYS( aCustomParams, Panic( EDiagFrameworkBadArgument ) );
       
   450 
       
   451     // Custom parameter can be set only when engine is not running.
       
   452     __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateNotReady, 
       
   453                      Panic( EDiagFrameworkInvalidState ) );
       
   454 
       
   455     iCustomParam = aCustomParams;
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // CDiagEngineImpl::SuspendL
       
   460 // ---------------------------------------------------------------------------
       
   461 //
       
   462 void CDiagEngineImpl::SuspendL()
       
   463     {
       
   464     DiagFwInternal::TState state = iStateMachine->CurrentState();
       
   465 
       
   466     // Suspendable states:
       
   467     __ASSERT_ALWAYS( ( state == EStateRunning ||
       
   468                        state == EStateCreatingPlan ||
       
   469                        state == EStateFinalizing ||
       
   470                        state == EStateStopped ),
       
   471                      Panic( EDiagFrameworkInvalidState ) );
       
   472 
       
   473     if ( state == EStateFinalizing || state == EStateStopped )
       
   474         {
       
   475         // ignore suspend request. All tests are already completed and
       
   476         // we are just waiting to finalize db record and report final
       
   477         // result.
       
   478         return;
       
   479         }
       
   480 
       
   481     StopAllRequests();
       
   482 
       
   483     LOGSTRING( "CDiagEngineImpl::SuspendL(). Adding suspend event" )
       
   484     iStateMachine->AddEventL( EEventSuspend );
       
   485     }
       
   486 
       
   487 // ---------------------------------------------------------------------------
       
   488 // CDiagEngineImpl::ResumeL
       
   489 // ---------------------------------------------------------------------------
       
   490 //
       
   491 void CDiagEngineImpl::ResumeL()
       
   492     {
       
   493     __ASSERT_ALWAYS( iStateMachine->CurrentState() == EStateSuspended,
       
   494                      Panic( EDiagFrameworkInvalidState ) );
       
   495 
       
   496     LOGSTRING( "CDiagEngineImpl::SuspendL(). Adding resume event" )
       
   497     AddResumeEventL( MDiagEngineObserver::EResumedByClient );
       
   498     }
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 // From class MDiagEngineCommon
       
   502 // CDiagEngineImpl::ExecutionPlanL
       
   503 // ---------------------------------------------------------------------------
       
   504 //
       
   505 const MDiagPluginExecPlan& CDiagEngineImpl::ExecutionPlanL() const
       
   506     {
       
   507     return *iPlan;
       
   508     }
       
   509 
       
   510 
       
   511 // ---------------------------------------------------------------------------
       
   512 // From class MDiagEngineCommon
       
   513 // CDiagEngineImpl::ExecutionStopL
       
   514 // ---------------------------------------------------------------------------
       
   515 //
       
   516 void CDiagEngineImpl::ExecutionStopL( TCancelMode aCancelMode )
       
   517     {
       
   518     DiagFwInternal::TState state = iStateMachine->CurrentState();
       
   519 
       
   520     // Acceptable states for execution stop.
       
   521     __ASSERT_ALWAYS( state == EStateCreatingPlan ||
       
   522                      state == EStateRunning ||
       
   523                      state == EStateSuspended ||
       
   524                      state == EStateFinalizing ||
       
   525                      state == EStateStopped,
       
   526                      Panic( EDiagFrameworkInvalidState ) );
       
   527 
       
   528     if ( state == EStateFinalizing || state == EStateStopped )
       
   529         {
       
   530         // ignore cancel request. All tests are already completed and
       
   531         // we are just waiting to finalize db record and report final
       
   532         // result.
       
   533         return;
       
   534         }
       
   535 
       
   536     StopAllRequests();
       
   537     
       
   538     if ( aCancelMode == ESkip )
       
   539         {
       
   540         iStateMachine->AddEventL( EEventSkip );
       
   541         }
       
   542     else
       
   543         {
       
   544         iStateMachine->AddEventL( EEventCancelAll );
       
   545         }
       
   546     }
       
   547 
       
   548 // ---------------------------------------------------------------------------
       
   549 // From class MDiagEngineCommon
       
   550 // CDiagEngineImpl::ResetWatchdog
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 void CDiagEngineImpl::ResetWatchdog()
       
   554     {
       
   555     iPlan->CurrentExecutionItem().ResetWatchdog();
       
   556     }
       
   557 
       
   558 // ---------------------------------------------------------------------------
       
   559 // From class MDiagEngineCommon
       
   560 // CDiagEngineImpl::ResetWatchdog
       
   561 // ---------------------------------------------------------------------------
       
   562 //
       
   563 void CDiagEngineImpl::ResetWatchdog( TDiagEngineWatchdogTypes aWatchdogType )
       
   564     {
       
   565     iPlan->CurrentExecutionItem().ResetWatchdog( aWatchdogType );
       
   566     }
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 // From class MDiagEngineCommon
       
   570 // CDiagEngineImpl::ResetWatchdog
       
   571 // ---------------------------------------------------------------------------
       
   572 //
       
   573 void CDiagEngineImpl::ResetWatchdog( TTimeIntervalMicroSeconds32 aExpectedTimeToComplete )
       
   574     {
       
   575     iPlan->CurrentExecutionItem().ResetWatchdog( aExpectedTimeToComplete );
       
   576     }
       
   577 
       
   578 // ---------------------------------------------------------------------------
       
   579 // From class MDiagEngineCommon
       
   580 // CDiagEngineImpl::ViewAppUi
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 CAknViewAppUi& CDiagEngineImpl::ViewAppUi()
       
   584     {
       
   585     return iViewAppUi;
       
   586     }
       
   587 
       
   588 // ---------------------------------------------------------------------------
       
   589 // From class MDiagEngineCommon
       
   590 // CDiagEngineImpl::ViewAppUi
       
   591 // ---------------------------------------------------------------------------
       
   592 //
       
   593 const CAknViewAppUi& CDiagEngineImpl::ViewAppUi() const
       
   594     {
       
   595     return iViewAppUi;
       
   596     }
       
   597 
       
   598 // ---------------------------------------------------------------------------
       
   599 // From class MDiagEngineCommon
       
   600 // CDiagEngineImpl::DbRecord
       
   601 // ---------------------------------------------------------------------------
       
   602 //
       
   603 RDiagResultsDatabaseRecord& CDiagEngineImpl::DbRecord()
       
   604     {
       
   605     return iDbRecord;
       
   606     }
       
   607 
       
   608 // ---------------------------------------------------------------------------
       
   609 // From class MDiagEngineCommon
       
   610 // CDiagEngineImpl::DbRecord
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 const RDiagResultsDatabaseRecord& CDiagEngineImpl::DbRecord() const
       
   614     {
       
   615     return iDbRecord;
       
   616     }
       
   617 
       
   618 // ---------------------------------------------------------------------------
       
   619 // From class MDiagEngineCommon
       
   620 // CDiagEngineImpl::PluginPool
       
   621 // ---------------------------------------------------------------------------
       
   622 //
       
   623 CDiagPluginPool& CDiagEngineImpl::PluginPool()
       
   624     {
       
   625     return iPluginPool;
       
   626     }
       
   627 
       
   628 // ---------------------------------------------------------------------------
       
   629 // From class MDiagEngineCommon
       
   630 // CDiagEngineImpl::PluginPool
       
   631 // ---------------------------------------------------------------------------
       
   632 //
       
   633 const CDiagPluginPool& CDiagEngineImpl::PluginPool() const
       
   634     {
       
   635     return iPluginPool;
       
   636     }
       
   637 
       
   638 // ---------------------------------------------------------------------------
       
   639 // From class MDiagEngineCommon
       
   640 // CDiagEngineImpl::AddToConfigListL
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 void CDiagEngineImpl::AddToConfigListL(
       
   644         MDiagEngineCommon::TConfigListType aListType, 
       
   645         const TDesC& aText )
       
   646     {
       
   647     switch ( aListType )
       
   648         {
       
   649         case MDiagEngineCommon::EConfigListCallIngore:
       
   650             iCallHandler->AddIgnoreNumberL( aText );
       
   651             break;
       
   652 
       
   653         default:
       
   654             LOGSTRING2( "CDiagEngineImpl::AddToConfigListL(). Invalid ListType %d",
       
   655                 aListType )
       
   656             Panic( EDiagFrameworkBadArgument );
       
   657             break;
       
   658         }
       
   659     }
       
   660 
       
   661 // ---------------------------------------------------------------------------
       
   662 // From class MDiagEngineCommon
       
   663 // CDiagEngineImpl::RemoveFromConfigListL
       
   664 // ---------------------------------------------------------------------------
       
   665 //
       
   666 void CDiagEngineImpl::RemoveFromConfigListL(
       
   667         MDiagEngineCommon::TConfigListType aListType,
       
   668         const TDesC& aText )
       
   669     {
       
   670     switch ( aListType )
       
   671         {
       
   672         case MDiagEngineCommon::EConfigListCallIngore:
       
   673             iCallHandler->RemoveIgnoreNumberL( aText );
       
   674             break;
       
   675 
       
   676         default:
       
   677             LOGSTRING2( "CDiagEngineImpl::RemoveFromConfigListL(). Invalid ListType %d",
       
   678                 aListType )
       
   679             Panic( EDiagFrameworkBadArgument );
       
   680             break;
       
   681         }
       
   682     }
       
   683 
       
   684 // ---------------------------------------------------------------------------
       
   685 // From class MDiagEngineCommon
       
   686 // CDiagEngineImpl::CreateCommonDialogLC
       
   687 // ---------------------------------------------------------------------------
       
   688 //
       
   689 CAknDialog* CDiagEngineImpl::CreateCommonDialogLC( TDiagCommonDialog aDialogType,
       
   690                                                    TAny* aInitData )
       
   691     {
       
   692     return iObserver.CreateCommonDialogLC( aDialogType, aInitData );
       
   693     }
       
   694 
       
   695 // ---------------------------------------------------------------------------
       
   696 // From class MDiagEngineCommon
       
   697 // CDiagEngineImpl::ExecuteAppCommandL
       
   698 // ---------------------------------------------------------------------------
       
   699 //
       
   700 void CDiagEngineImpl::ExecuteAppCommandL( TDiagAppCommand aCommand, 
       
   701                                           TAny* aParam1,
       
   702                                           TAny* aParam2 )
       
   703     {
       
   704     iObserver.ExecuteAppCommandL( aCommand, aParam1, aParam2 );
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // From class MDiagEngineCommon
       
   709 // CDiagEngineImpl::StopWatchdogTemporarily
       
   710 // ---------------------------------------------------------------------------
       
   711 //
       
   712 void CDiagEngineImpl::StopWatchdogTemporarily()
       
   713     {
       
   714     if ( iStateMachine == NULL || iPlan == NULL )
       
   715         {
       
   716         return;
       
   717         }
       
   718 
       
   719     if ( iStateMachine->CurrentState() == EStateRunning )
       
   720         {
       
   721         iPlan->CurrentExecutionItem().StopWatchdogTemporarily();
       
   722         }
       
   723     }
       
   724 
       
   725 // ---------------------------------------------------------------------------
       
   726 // From class MDiagEngineCommon
       
   727 // CDiagEngineImpl::IsDependencyDisabled
       
   728 // ---------------------------------------------------------------------------
       
   729 //
       
   730 TBool CDiagEngineImpl::IsDependencyDisabled() const
       
   731     {
       
   732     return iEngineConfig.IsDependencyDisabled();
       
   733     }
       
   734 
       
   735 // ---------------------------------------------------------------------------
       
   736 // From class MDiagEngineCommon
       
   737 // CDiagEngineImpl::CustomParam
       
   738 // ---------------------------------------------------------------------------
       
   739 //
       
   740 TAny* CDiagEngineImpl::CustomParam() const
       
   741     {
       
   742     return iCustomParam;
       
   743     }   //lint !e1763 Custom param is just passed along. Does not actually change engine.
       
   744 
       
   745 // ---------------------------------------------------------------------------
       
   746 // From class MDiagExecPlanEntryImplObserver
       
   747 // CDiagEngineImpl::ExecPlanEntryProgressL
       
   748 // ---------------------------------------------------------------------------
       
   749 //
       
   750 void CDiagEngineImpl::ExecPlanEntryProgressL( 
       
   751         CDiagExecPlanEntryImpl& aSender,
       
   752         TUint aCurrentStep, 
       
   753         TUint aTotalSteps )
       
   754     {
       
   755     LOGSTRING4( "CDiagEngineImpl::ExecPlanEntryProgressL: Plugin = 0x%08x, (%d / %d) ",
       
   756         aSender.Plugin().Uid().iUid,
       
   757         aCurrentStep, 
       
   758         aTotalSteps )
       
   759 
       
   760     if ( aSender.Plugin().Uid() == iPlan->CurrentExecutionItem().Plugin().Uid() )
       
   761         {
       
   762         CEventTestProgress* event = new ( ELeave ) CEventTestProgress(
       
   763                 aSender.Plugin(), aCurrentStep, aTotalSteps );
       
   764 
       
   765         iStateMachine->AddEventL( event ); // ownership changed.
       
   766         }
       
   767     else
       
   768         {
       
   769         // probably timing issue. Ignore event.
       
   770         __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) );
       
   771         }
       
   772     }
       
   773 
       
   774 // ---------------------------------------------------------------------------
       
   775 // From class MDiagExecPlanEntryImplObserver
       
   776 // CDiagEngineImpl::ExecPlanEntryExecutedL
       
   777 // ---------------------------------------------------------------------------
       
   778 //
       
   779 void CDiagEngineImpl::ExecPlanEntryExecutedL( CDiagExecPlanEntryImpl& aSender )
       
   780     {
       
   781     LOGSTRING2( "CDiagEngineImpl::ExecPlanEntryExecutedL: Plugin = 0x%08x",
       
   782         aSender.Plugin().Uid().iUid )
       
   783 
       
   784     if ( aSender.Plugin().Uid() != iPlan->CurrentExecutionItem().Plugin().Uid() )
       
   785         {
       
   786         // probably timing issue. Ignore event.
       
   787         __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) );
       
   788         }
       
   789     else
       
   790         {
       
   791         TInt error = KErrNone;
       
   792         if ( aSender.IsStoppedByClient() )
       
   793             {
       
   794             error = KErrCancel;
       
   795             }
       
   796 
       
   797         CDiagResultsDatabaseItem* result = NULL;
       
   798 
       
   799         if ( aSender.Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
       
   800             {
       
   801             // Test was completed. Get test result.
       
   802             CDiagExecPlanEntryImplTest& testEntry = 
       
   803                 static_cast< CDiagExecPlanEntryImplTest& >( aSender );
       
   804 
       
   805             result = testEntry.GetLastTestResultL();
       
   806 
       
   807             __ASSERT_ALWAYS( result != NULL, Panic( EDiagFrameworkNullTestResult ) );
       
   808             }
       
   809 
       
   810         NotifyResultAndContinueL( error, result );
       
   811         }
       
   812     }
       
   813 
       
   814 // ---------------------------------------------------------------------------
       
   815 // From class MDiagExecPlanEntryImplObserver
       
   816 // CDiagEngineImpl::ExecPlanEntryCriticalError
       
   817 // ---------------------------------------------------------------------------
       
   818 //
       
   819 void CDiagEngineImpl::ExecPlanEntryCriticalError( TInt aError )
       
   820     {
       
   821     LOGSTRING2( "CDiagEngineImpl::ExecPlanEntryCriticalError: "
       
   822         L"Critical failure %d", aError )
       
   823 
       
   824     // Unrecoverable error has occered. e.g. out of memory, disk full etc.
       
   825     iStateMachine->HandleError( aError );
       
   826     }
       
   827 
       
   828 
       
   829 // ---------------------------------------------------------------------------
       
   830 // From class MDiagEngineStateMachineObserver
       
   831 // CDiagEngineImpl::HandleStateChangedL
       
   832 // ---------------------------------------------------------------------------
       
   833 //
       
   834 void CDiagEngineImpl::HandleStateChangedL( 
       
   835         TState aPreviousState, 
       
   836         TState aCurrentState,
       
   837         const CEventBasic& aEventPreview )
       
   838     {
       
   839     // NOTE: This method is called by state machine as soon as an event that
       
   840     // changes states is called. This means that it could execute within caller's
       
   841     // call stack. (e.g. it could be still within application or plug-in's 
       
   842     // call stack.) It is best to limit amount of implementation here to
       
   843     // things that must be done as soon as an event occurs.
       
   844     // 
       
   845     // Suspend and Resume are exceptions since they require immediate notification
       
   846     // to observer. Otherwise, observer might have mismatch in notifications.
       
   847 
       
   848     LOGSTRING3( "CDiagEngineImpl::HandleStateChangedL(): "
       
   849             L"Entering State : %d( %S )",
       
   850             aCurrentState, &iStateMachine->StateName( aCurrentState ) )
       
   851 
       
   852     switch ( aCurrentState )
       
   853         {
       
   854         case EStateSuspended:
       
   855             // keep track of state befor suspended, so that we can resume
       
   856             // to correct state.
       
   857             iSuspendedPrevState = aPreviousState;
       
   858 
       
   859             MDiagEngineObserver::TSuspendReason reason;
       
   860             if ( aEventPreview.GetType() == EEventSuspend )
       
   861                 {
       
   862                 reason = MDiagEngineObserver::ESuspendByClient;
       
   863                 }
       
   864             else
       
   865                 {
       
   866                 reason = MDiagEngineObserver::ESuspendByPhoneCall;
       
   867                 }
       
   868 
       
   869             // This will also notify iObserver.
       
   870             DoSuspendL( reason );
       
   871             break;
       
   872 
       
   873         case EStateRunning: 
       
   874             if ( aEventPreview.GetType() == EEventResumeToRunning )
       
   875                 {
       
   876                 LOGSTRING( "CDiagEngineImpl::HandleStateChangedL(). Notify resume" )
       
   877                 iObserver.TestExecutionResumedL( iResumeReason );
       
   878                 }
       
   879             break;
       
   880 
       
   881         case EStateCreatingPlan:
       
   882             if ( aEventPreview.GetType() == EEventResumeToCreatingPlan )
       
   883                 {
       
   884                 LOGSTRING( "CDiagEngineImpl::HandleStateChangedL(). Notify resume" )
       
   885                 iObserver.TestExecutionResumedL( iResumeReason );
       
   886                 }
       
   887             break;
       
   888         
       
   889         default:
       
   890             // Do nothing.
       
   891             break;
       
   892         }
       
   893     }
       
   894 
       
   895 // ---------------------------------------------------------------------------
       
   896 // From class MDiagEngineStateMachineObserver
       
   897 // CDiagEngineImpl::HandleEventL
       
   898 // ---------------------------------------------------------------------------
       
   899 //
       
   900 void CDiagEngineImpl::HandleEventL( CEventBasic& aEvent )
       
   901     {
       
   902     LOGSTRING5( "CDiagEngineImpl::HandleEventL(): State=%d(%S), Event=%d(%S)",
       
   903         iStateMachine->CurrentState(), 
       
   904         &iStateMachine->StateName( iStateMachine->CurrentState() ),
       
   905         aEvent.GetType(), &aEvent.ToString() )
       
   906             
       
   907     switch ( iStateMachine->CurrentState() )
       
   908         {
       
   909         case EStateNotReady:
       
   910             LOGSTRING( "CDiagEngineImpl::HandleEventL: "
       
   911                 L"ERROR! Cannot accept events in EStateNotReady State" )
       
   912             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) );
       
   913             break;
       
   914 
       
   915         case EStateCreatingPlan:
       
   916             HandleEventInCreatingPlanStateL( aEvent );
       
   917             break;
       
   918 
       
   919         case EStateRunning:
       
   920             HandleEventInRunningStateL( aEvent );
       
   921             break;
       
   922 
       
   923         case EStateCancelAll:
       
   924             HandleEventInCancelAllStateL( aEvent );
       
   925             break;
       
   926 
       
   927         case EStateSuspended:
       
   928             HandleEventInSuspendedStateL( aEvent );
       
   929             break;
       
   930 
       
   931         case EStateFinalizing:
       
   932             HandleEventInFinalizingStateL( aEvent );
       
   933             break;
       
   934 
       
   935         case EStateStopped:
       
   936             HandleEventInStoppedStateL( aEvent );
       
   937             break;
       
   938 
       
   939         case EStateAny:     // fall through
       
   940         default:
       
   941             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) );
       
   942             break;
       
   943         }
       
   944     LOGSTRING( "CDiagEngineImpl::HandleEventL(): return" )
       
   945     }
       
   946 
       
   947 // ---------------------------------------------------------------------------
       
   948 // CDiagEngineImpl::HandleEventInCreatingPlanStateL
       
   949 // ---------------------------------------------------------------------------
       
   950 //
       
   951 void CDiagEngineImpl::HandleEventInCreatingPlanStateL( CEventBasic& aEvent )
       
   952     {
       
   953     switch ( aEvent.GetType() )
       
   954         {
       
   955         case EEventExecute:                 // fall through
       
   956         case EEventResumeToCreatingPlan:
       
   957             StartCreateExecutionPlanL();
       
   958             break;
       
   959         
       
   960         default:
       
   961             LOGSTRING2( "CDiagEngineImpl::HandleEventInCreatingPlanStateL: "
       
   962                         L"Invalid event = %d", aEvent.GetType() )
       
   963             // Ignored.
       
   964             break;
       
   965         }
       
   966     }
       
   967 
       
   968 // ---------------------------------------------------------------------------
       
   969 // CDiagEngineImpl::HandleEventInRunningStateL
       
   970 // ---------------------------------------------------------------------------
       
   971 //
       
   972 void CDiagEngineImpl::HandleEventInRunningStateL( CEventBasic& aEvent )
       
   973     {
       
   974     switch ( aEvent.GetType() )
       
   975         {
       
   976         case EEventPlanCreated:         
       
   977             // Normal case. Plan is created normally.
       
   978             HandlePlanCreatedL();
       
   979             break;
       
   980         
       
   981         case EEventExecuteNext:
       
   982             ExecuteNextPluginL();
       
   983             break;
       
   984 
       
   985         case EEventSkip:
       
   986             HandleSkipL();
       
   987             break;
       
   988 
       
   989         case EEventTestProgress:
       
   990             NotifyTestProgressL( static_cast<CEventTestProgress&>( aEvent ) );
       
   991             break;
       
   992 
       
   993         case EEventResumeToRunning:
       
   994             DoResumeL();
       
   995             break;
       
   996 
       
   997         default:
       
   998             LOGSTRING2( "CDiagEngineImpl::HandleEventInRunningStateL "
       
   999                         L"Invalid event = %d", aEvent.GetType() )
       
  1000             break;
       
  1001         }
       
  1002     }
       
  1003 
       
  1004 // ---------------------------------------------------------------------------
       
  1005 // CDiagEngineImpl::HandleEventInCancelAllStateL
       
  1006 // ---------------------------------------------------------------------------
       
  1007 //
       
  1008 void CDiagEngineImpl::HandleEventInCancelAllStateL( CEventBasic& aEvent )
       
  1009     {
       
  1010     switch ( aEvent.GetType() )
       
  1011         {
       
  1012         case EEventCancelAll:
       
  1013         case EEventExecuteNext:
       
  1014             HandleCancelAllL();
       
  1015             break;
       
  1016 
       
  1017         case EEventSuspend:                 // fall through
       
  1018         case EEventVoiceCallActive:
       
  1019             // suspend is always handed in its own state
       
  1020             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) );
       
  1021             break;
       
  1022 
       
  1023         default:
       
  1024             // other events are ingored( e.g. progress ), since
       
  1025             // cancel has been requested
       
  1026             LOGSTRING2( "CDiagEngineImpl::HandleEventInCancelAllStateL "
       
  1027                         L"Invalid event = %d", aEvent.GetType() )
       
  1028             break;
       
  1029         }
       
  1030     }
       
  1031 
       
  1032 // ---------------------------------------------------------------------------
       
  1033 // CDiagEngineImpl::HandleEventInSuspendedStateL
       
  1034 // ---------------------------------------------------------------------------
       
  1035 //
       
  1036 void CDiagEngineImpl::HandleEventInSuspendedStateL( CEventBasic& aEvent )
       
  1037     {
       
  1038     switch ( aEvent.GetType() )
       
  1039         {
       
  1040         case EEventSuspend:
       
  1041             // nothing to do. Suspend is immediate, so it is handled
       
  1042             // in HandleStateChangedL 
       
  1043             break;
       
  1044 
       
  1045         default:
       
  1046             // suspended. ignore.
       
  1047             LOGSTRING2( "CDiagEngineImpl::HandleEventInSuspendedStateL "
       
  1048                         L"Invalid event = %d", aEvent.GetType() )
       
  1049             break;
       
  1050         }
       
  1051     }
       
  1052 
       
  1053 // ---------------------------------------------------------------------------
       
  1054 // CDiagEngineImpl::HandleEventInFinalizingStateL
       
  1055 // ---------------------------------------------------------------------------
       
  1056 //
       
  1057 void CDiagEngineImpl::HandleEventInFinalizingStateL( CEventBasic& aEvent )
       
  1058     {
       
  1059     switch ( aEvent.GetType() )
       
  1060         {
       
  1061         case EEventAllPluginsCompleted:
       
  1062             FinalizeTestSessionL();
       
  1063             break;
       
  1064 
       
  1065         default:
       
  1066             // ignore all others. This is because if the state machine
       
  1067             // gets here due to error, there may be left over events in
       
  1068             // event queue. Those should be ignored.
       
  1069             LOGSTRING2( "CDiagEngineImpl::HandleEventInFinalizingStateL "
       
  1070                         L"Invalid event = %d", aEvent.GetType() )
       
  1071             break;
       
  1072         }
       
  1073     }
       
  1074 
       
  1075 // ---------------------------------------------------------------------------
       
  1076 // CDiagEngineImpl::HandleEventInStoppedStateL
       
  1077 // ---------------------------------------------------------------------------
       
  1078 //
       
  1079 void CDiagEngineImpl::HandleEventInStoppedStateL( CEventBasic& /* aEvent */ )
       
  1080     {
       
  1081     // ignore all events. This is because if the state machine
       
  1082     // gets here due to error, there may be left over events in
       
  1083     // event queue. Those should be ignored.
       
  1084     }
       
  1085 
       
  1086 
       
  1087 // ---------------------------------------------------------------------------
       
  1088 // From class MDiagEngineStateMachineObserver
       
  1089 // CDiagEngineImpl::HandleError
       
  1090 // ---------------------------------------------------------------------------
       
  1091 //
       
  1092 TState CDiagEngineImpl::HandleError( TState aCurrentState, TInt aError )
       
  1093     {
       
  1094     LOGSTRING4( "CDiagEngineImpl::HandleError() State %d(%S), ERROR %d",
       
  1095         aCurrentState,
       
  1096         &iStateMachine->StateName( aCurrentState ),
       
  1097         aError )
       
  1098 
       
  1099     switch ( aCurrentState )
       
  1100         {
       
  1101         case EStateNotReady:    // fall through.
       
  1102         case EStateStopped:
       
  1103             // was not running.. Nothing to do.
       
  1104             return aCurrentState;
       
  1105 
       
  1106         default:
       
  1107             {
       
  1108             iEngineError = aError;
       
  1109 
       
  1110             // Database record is open. Suspend the record so that
       
  1111             // user can retry later.
       
  1112             iDbRecord.Suspend(); // error ignored
       
  1113 
       
  1114             // Ignore error from application in this case since we are already
       
  1115             // handling error.
       
  1116             TRAP_IGNORE( iObserver.TestExecutionCompletedL( aError ) )
       
  1117             }
       
  1118             return EStateStopped;
       
  1119         }
       
  1120     }
       
  1121 
       
  1122 // ---------------------------------------------------------------------------
       
  1123 // CDiagEngineImpl::StartCreateExecutionPlanL
       
  1124 //
       
  1125 // ---------------------------------------------------------------------------
       
  1126 //
       
  1127 void CDiagEngineImpl::StartCreateExecutionPlanL()
       
  1128     {
       
  1129     LOGSTRING( "CDiagEngineImpl::StartCreateExecutionPlanL() Start creating plan" )
       
  1130     if ( iContinueIncompleteRecord )
       
  1131         {
       
  1132         iPlan->InitializeL( iStatus );
       
  1133         }
       
  1134     else
       
  1135         {
       
  1136         iPlan->InitializeL( iStatus, iBatch );
       
  1137         }
       
  1138     SetActive();
       
  1139     }
       
  1140 
       
  1141 // ---------------------------------------------------------------------------
       
  1142 // CDiagEngineImpl::HandleEventExecute
       
  1143 //
       
  1144 // ---------------------------------------------------------------------------
       
  1145 //
       
  1146 void CDiagEngineImpl::HandlePlanCreatedL()
       
  1147     {
       
  1148     if ( iPlan->Count() == 0 )
       
  1149         {
       
  1150         // Error. There were no items in the plan.
       
  1151         iEngineError = KErrArgument;
       
  1152         iStateMachine->AddEventL( EEventAllPluginsCompleted );
       
  1153         return;
       
  1154         }
       
  1155 
       
  1156     // First initialize each plugins for execution.
       
  1157     // Note that if initialization step fails, it will be caught by
       
  1158     // CStateMachine's active object, and will call ::HandleError()
       
  1159     LOGSTRING( "CDiagEngineImpl::HandlePlanCreatedL() : Phase I - Initaliaze all plugins" )
       
  1160     for ( TInt i = 0; i < iPlan->Count(); i++ )
       
  1161         {
       
  1162         MDiagPlugin& plugin = (*iPlan)[i].Plugin();
       
  1163         plugin.TestSessionBeginL( *this, iEngineConfig.IsDependencyDisabled(), iCustomParam );
       
  1164         }
       
  1165 
       
  1166     LOGSTRING( "CDiagEngineImpl::HandlePlanCreatedL() : Phase II - Execution Begins" )
       
  1167     iPlan->ResetExecutionCursor();
       
  1168     iStateMachine->AddEventL( EEventExecuteNext );
       
  1169     iObserver.TestExecutionBeginL();
       
  1170     }
       
  1171 
       
  1172 // ---------------------------------------------------------------------------
       
  1173 // CDiagEngineImpl::ExecuteNextPluginL
       
  1174 //
       
  1175 // ---------------------------------------------------------------------------
       
  1176 //
       
  1177 void CDiagEngineImpl::ExecuteNextPluginL()
       
  1178     {
       
  1179     // first, check if cursor needs to be advanced
       
  1180     if ( iPlan->CurrentExecutionItem().State() == MDiagExecPlanEntry::EStateCompleted )
       
  1181         {
       
  1182         TBool moved = iPlan->MoveCursorToNext();
       
  1183         if ( !moved )
       
  1184             {
       
  1185             // cursor should always move. This is because execute next event
       
  1186             // should have never been created by NotifyResultAndContinueL
       
  1187             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) );
       
  1188             return;
       
  1189             }
       
  1190         }
       
  1191 
       
  1192     // Check if we are in call. If so, suspend current execution immediately.
       
  1193     if ( iCallHandler->CurrentState() == EDiagEngineCallHandlerStateBusy )
       
  1194         {
       
  1195         LOGSTRING( "CDiagEngineImpl::ExecuteNextPluginL() Call in progress" )
       
  1196         iStateMachine->AddEventL( EEventVoiceCallActive );
       
  1197         return;
       
  1198         }
       
  1199 
       
  1200     LOGSTRING2( "CDiagEngineImpl::ExecuteNextPluginL() : "
       
  1201         L"Executing plugin 0x%08x", 
       
  1202         iPlan->CurrentExecutionItem().Plugin().Uid().iUid )
       
  1203 
       
  1204     iPlan->CurrentExecutionItem().ExecuteL();
       
  1205     }
       
  1206 
       
  1207 
       
  1208 // ---------------------------------------------------------------------------
       
  1209 // CDiagEngineImpl::NotifyTestProgressL
       
  1210 //
       
  1211 // ---------------------------------------------------------------------------
       
  1212 //
       
  1213 void CDiagEngineImpl::NotifyTestProgressL( CEventTestProgress& aEvent )
       
  1214     {
       
  1215     // make sure that we are reporting progress on currently executing test.
       
  1216     CDiagExecPlanEntryImpl& currItem = iPlan->CurrentExecutionItem();
       
  1217 
       
  1218     if ( currItem.Plugin().Uid() == aEvent.Sender().Uid() &&
       
  1219          currItem.State() != MDiagExecPlanEntry::EStateCompleted )
       
  1220         {
       
  1221         LOGSTRING3( "CDiagEngineImpl::NotifyTestProgressL. "
       
  1222             L"Calling TestExecutionProgressL( %d, %d )", 
       
  1223             aEvent.CurrStep(), 
       
  1224             aEvent.TotalSteps() )
       
  1225         iObserver.TestExecutionProgressL( aEvent.CurrStep(), aEvent.TotalSteps() );
       
  1226         }
       
  1227     }
       
  1228 
       
  1229 // ---------------------------------------------------------------------------
       
  1230 // CDiagEngineImpl::NotifyResultAndContinueL
       
  1231 //
       
  1232 // ---------------------------------------------------------------------------
       
  1233 //
       
  1234 void CDiagEngineImpl::NotifyResultAndContinueL( 
       
  1235         TInt aError,
       
  1236         CDiagResultsDatabaseItem* aResult )
       
  1237     {
       
  1238     // aResult can be NULL if it was executing suite.
       
  1239     if ( aResult )
       
  1240         {
       
  1241         CleanupStack::PushL( aResult );
       
  1242         }
       
  1243     
       
  1244     if ( aResult )
       
  1245         {
       
  1246         CleanupStack::Pop( aResult );
       
  1247         }
       
  1248 
       
  1249     iObserver.TestExecutionPluginExecutedL( aError, aResult ); 
       
  1250     aResult = NULL; // aResult ownership transferred above.
       
  1251 
       
  1252     if ( iPlan->IsLastPlugin() )
       
  1253         {
       
  1254         User::After(2000000);
       
  1255         iStateMachine->AddEventL( EEventAllPluginsCompleted );
       
  1256         }
       
  1257     else
       
  1258         {
       
  1259         iStateMachine->AddEventL( EEventExecuteNext );
       
  1260         }
       
  1261     }
       
  1262 
       
  1263 // ---------------------------------------------------------------------------
       
  1264 // CDiagEngineImpl::HandleSkipL
       
  1265 //
       
  1266 // ---------------------------------------------------------------------------
       
  1267 //
       
  1268 void CDiagEngineImpl::HandleSkipL()
       
  1269     {
       
  1270     // if plan was empty, ( e.g. before any execution has actually started.
       
  1271     // do nothing.
       
  1272     if ( iPlan->Count() == 0 )
       
  1273         {
       
  1274         iEngineError = KErrArgument;
       
  1275         iStateMachine->AddEventL( EEventAllPluginsCompleted );
       
  1276         return;
       
  1277         }
       
  1278 
       
  1279     // Stop execution.  While plug-ins are required to stop immediately,
       
  1280     // writing to results db is async. Completion is notified is
       
  1281     // ExecPlanEntryExecutedL()
       
  1282     iPlan->CurrentExecutionItem().StopExecutionByClientL( ESkip );
       
  1283     }
       
  1284 
       
  1285 // ---------------------------------------------------------------------------
       
  1286 // CDiagEngineImpl::HandleCancelAllL
       
  1287 //
       
  1288 // ---------------------------------------------------------------------------
       
  1289 //
       
  1290 void CDiagEngineImpl::HandleCancelAllL()
       
  1291     {
       
  1292     iEngineError = KErrCancel;
       
  1293 
       
  1294     if ( iPlan->Count() == 0 )
       
  1295         {
       
  1296         // If plan was empty, ( e.g. before any execution has actually started ),
       
  1297         // do nothing and send back completed with KErrCancel.
       
  1298         iStateMachine->AddEventL( EEventAllPluginsCompleted );
       
  1299         return;
       
  1300         }
       
  1301 
       
  1302     if ( iPlan->CurrentExecutionItem().State() == MDiagExecPlanEntry::EStateCompleted )
       
  1303         {
       
  1304         TBool moved = iPlan->MoveCursorToNext();
       
  1305         if ( !moved )
       
  1306             {
       
  1307             // cursor should always move. This is because execute next event
       
  1308             // should have never been created by NotifyResultAndContinueL
       
  1309             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) );
       
  1310             return;
       
  1311             }
       
  1312         }
       
  1313 
       
  1314     iPlan->CurrentExecutionItem().StopExecutionByClientL( ECancelAll );
       
  1315     // Continue to ::ExecPlanEntryExecutedL
       
  1316     }
       
  1317 
       
  1318 // ---------------------------------------------------------------------------
       
  1319 // CDiagEngineImpl::DoSuspendL
       
  1320 //
       
  1321 // ---------------------------------------------------------------------------
       
  1322 //
       
  1323 void CDiagEngineImpl::DoSuspendL( MDiagEngineObserver::TSuspendReason aReason )
       
  1324     {
       
  1325     if ( iSuspendedPrevState == EStateNotReady ||
       
  1326          iSuspendedPrevState == EStateCreatingPlan ||
       
  1327          iSuspendedPrevState == EStateStopped )
       
  1328         {
       
  1329         // not much to do here.
       
  1330         }
       
  1331     else
       
  1332         {
       
  1333         StopAllRequests();
       
  1334 
       
  1335         iSuspendReason = aReason;
       
  1336 
       
  1337         iPlan->CurrentExecutionItem().SuspendL();
       
  1338         }
       
  1339 
       
  1340     LOGSTRING( "CDiagEngineImpl::DoSuspendL: Engine Suspended" )
       
  1341     iObserver.TestExecutionSuspendedL( aReason );
       
  1342     }
       
  1343 
       
  1344 // ---------------------------------------------------------------------------
       
  1345 // CDiagEngineImpl::AddResumeEventL
       
  1346 //
       
  1347 // ---------------------------------------------------------------------------
       
  1348 //
       
  1349 void CDiagEngineImpl::AddResumeEventL( MDiagEngineObserver::TResumeReason aReason )
       
  1350     {
       
  1351     iResumeReason = aReason;
       
  1352     if ( iSuspendedPrevState == EStateNotReady ||
       
  1353          iSuspendedPrevState == EStateCreatingPlan )
       
  1354         {
       
  1355         iStateMachine->AddEventL( EEventResumeToCreatingPlan );
       
  1356         }
       
  1357     else
       
  1358         {
       
  1359         iStateMachine->AddEventL( EEventResumeToRunning );
       
  1360         }
       
  1361     }
       
  1362 
       
  1363 // ---------------------------------------------------------------------------
       
  1364 // CDiagEngineImpl::DoResumeL
       
  1365 //
       
  1366 // ---------------------------------------------------------------------------
       
  1367 //
       
  1368 void CDiagEngineImpl::DoResumeL()
       
  1369     {
       
  1370     LOGSTRING( "CDiagEngineImpl::DoResumeL: Resuming Engine..." )
       
  1371     CDiagExecPlanEntryImpl& entry = iPlan->CurrentExecutionItem();
       
  1372 
       
  1373     if ( entry.State() == MDiagExecPlanEntry::EStateCompleted )
       
  1374         {
       
  1375         // already completed. nothing to resume.
       
  1376         ExecuteNextPluginL();
       
  1377         }
       
  1378     else
       
  1379         {
       
  1380         entry.ResumeL();
       
  1381         }
       
  1382     }
       
  1383 
       
  1384 
       
  1385 // ---------------------------------------------------------------------------
       
  1386 // CDiagEngineImpl::CreateDbItem
       
  1387 //
       
  1388 // ---------------------------------------------------------------------------
       
  1389 //
       
  1390 CDiagResultsDatabaseItem* CDiagEngineImpl::CreateDbItemL(
       
  1391         CDiagExecPlanEntryImpl& aCurrItem,
       
  1392         CDiagResultsDatabaseItem::TResult aResultType ) const
       
  1393     {
       
  1394     return CDiagResultsDbItemBuilder::CreateSimpleDbItemL( aCurrItem.Plugin().Uid(),
       
  1395                                                            aCurrItem.AsDependency(),
       
  1396                                                            aResultType );
       
  1397     }
       
  1398 
       
  1399 // ---------------------------------------------------------------------------
       
  1400 // CDiagEngineImpl::NotifyPluginsOfTestSessionEnd
       
  1401 //
       
  1402 // ---------------------------------------------------------------------------
       
  1403 //
       
  1404 void CDiagEngineImpl::NotifyPluginsOfTestSessionEnd()
       
  1405     {
       
  1406     LOGSTRING( "CDiagEngineImpl::NotifyPluginsOfTestSessionEnd() : "
       
  1407         L"Phase III - Cleaning up stage" )
       
  1408     // unlike initialization stage, it will TRAP all errors so that 
       
  1409     // every plug-ins will have a chance to run its clean up code.
       
  1410     for ( TInt index = 0; index < iPlan->Count(); index++ )
       
  1411         {
       
  1412         MDiagPlugin& plugin = (*iPlan)[index].Plugin();
       
  1413         TRAPD( err, plugin.TestSessionEndL( 
       
  1414             *this, iEngineConfig.IsDependencyDisabled(), iCustomParam ) );
       
  1415         if ( err != KErrNone )
       
  1416             {
       
  1417             LOGSTRING3( "CDiagEngineImpl::NotifyPluginsOfTestSessionEnd(): "
       
  1418                 L"Plug-in Uid %d CleanupL failed with error %d", 
       
  1419                 plugin.Uid().iUid, err )
       
  1420             }
       
  1421         }
       
  1422     }
       
  1423 
       
  1424 // ---------------------------------------------------------------------------
       
  1425 // CDiagEngineImpl::StopAllRequests
       
  1426 //
       
  1427 // ---------------------------------------------------------------------------
       
  1428 //
       
  1429 void CDiagEngineImpl::StopAllRequests()
       
  1430     {
       
  1431     Cancel();
       
  1432     StopWatchdogTemporarily();
       
  1433     }
       
  1434 
       
  1435 // ---------------------------------------------------------------------------
       
  1436 // CDiagEngineImpl::FinalizeTestSessionL
       
  1437 //
       
  1438 // ---------------------------------------------------------------------------
       
  1439 //
       
  1440 void CDiagEngineImpl::FinalizeTestSessionL()
       
  1441     {
       
  1442     LOGSTRING( "CDiagEngineImpl::FinalizeTestSessionL() " )
       
  1443     
       
  1444     // This causes state to change to EStateStopped
       
  1445     //iStateMachine->AddEventL( EEventFinalized );
       
  1446 
       
  1447     // Call TestSessionEnd on all plug-ins
       
  1448     NotifyPluginsOfTestSessionEnd();
       
  1449 
       
  1450     // Mark DB completed.
       
  1451     TBool isFullyCompleted = ( iEngineError == KErrNone );
       
  1452     
       
  1453     TInt err = iDbRecord.TestCompleted( isFullyCompleted );
       
  1454     if ( err != KErrNone )
       
  1455         {
       
  1456         LOGSTRING3( "CDiagEngineImpl::FinalizeTestSessionL() "
       
  1457             L"iDbRecord.TestCompleted( %d ) return err %d", 
       
  1458             isFullyCompleted, 
       
  1459             err )
       
  1460         iEngineError = err;
       
  1461         }
       
  1462     
       
  1463     // Let observer know that test is completed.
       
  1464     iObserver.TestExecutionCompletedL( iEngineError );
       
  1465     }
       
  1466 
       
  1467 // ---------------------------------------------------------------------------
       
  1468 // From class MDiagEngineCallHandlerObserver
       
  1469 // CDiagEngineImpl::CallHandlerStateChangedL
       
  1470 // ---------------------------------------------------------------------------
       
  1471 //
       
  1472 void CDiagEngineImpl::CallHandlerStateChangedL( TDiagEngineCallHandlerState aState )
       
  1473     {
       
  1474     if ( aState == EDiagEngineCallHandlerStateBusy && 
       
  1475             ( iStateMachine->CurrentState() == EStateRunning) )
       
  1476         {
       
  1477         iStateMachine->AddEventL( EEventVoiceCallActive );
       
  1478         }
       
  1479     else if ( aState == EDiagEngineCallHandlerStateIdle && 
       
  1480             iStateMachine->CurrentState() == EStateSuspended  &&
       
  1481             iSuspendReason == MDiagEngineObserver::ESuspendByPhoneCall )
       
  1482         {
       
  1483         AddResumeEventL( MDiagEngineObserver::EAutoResumedByCallHangup );
       
  1484         }
       
  1485     else
       
  1486         {
       
  1487         // Ignored
       
  1488         }
       
  1489     }
       
  1490 
       
  1491 
       
  1492 // ---------------------------------------------------------------------------
       
  1493 // From class CActive
       
  1494 // CDiagEngineImpl::RunL
       
  1495 // ---------------------------------------------------------------------------
       
  1496 //
       
  1497 void CDiagEngineImpl::RunL()
       
  1498     {
       
  1499     LOGSTRING2( "CDiagEngineImpl::RunL() error %d", iStatus.Int() )
       
  1500     
       
  1501     User::LeaveIfError( iStatus.Int() );
       
  1502     
       
  1503     switch ( iStateMachine->CurrentState()  )
       
  1504         {
       
  1505         case EStateCreatingPlan:
       
  1506             // plan created successfully.
       
  1507             iStateMachine->AddEventL( EEventPlanCreated );
       
  1508             break;
       
  1509 
       
  1510         default:
       
  1511             __ASSERT_DEBUG( 0, Panic( EDiagFrameworkCorruptStateMachine ) );
       
  1512             break;
       
  1513         }
       
  1514     }
       
  1515 
       
  1516 // ---------------------------------------------------------------------------
       
  1517 // From class CActive
       
  1518 // CDiagEngineImpl::DoCancel
       
  1519 // ---------------------------------------------------------------------------
       
  1520 //
       
  1521 void CDiagEngineImpl::DoCancel()
       
  1522     {
       
  1523     switch ( iStateMachine->CurrentState() )
       
  1524         {
       
  1525         case EStateCreatingPlan:
       
  1526             iPlan->Cancel();
       
  1527             break;
       
  1528 
       
  1529         default:
       
  1530             // Nothing to do
       
  1531             break;
       
  1532         }
       
  1533     }
       
  1534 
       
  1535 // ---------------------------------------------------------------------------
       
  1536 // From class CActive
       
  1537 // CDiagEngineImpl::RunError
       
  1538 // ---------------------------------------------------------------------------
       
  1539 //
       
  1540 TInt CDiagEngineImpl::RunError( TInt aError )
       
  1541     {
       
  1542     if ( iStateMachine )
       
  1543         {
       
  1544         iStateMachine->HandleError( aError );
       
  1545         }
       
  1546 
       
  1547     return KErrNone;
       
  1548     }
       
  1549 
       
  1550 // End of File
       
  1551