diff -r 13d7c31c74e0 -r b183ec05bd8c devicediagnosticsfw/diagframework/src/diagpluginexecplanimpl.cpp --- a/devicediagnosticsfw/diagframework/src/diagpluginexecplanimpl.cpp Thu Aug 19 10:44:50 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1577 +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 CDiagPluginExecPlanImpl -* -*/ - - -// CLASS DECLARATION -#include "diagpluginexecplanimpl.h" - -// SYSTEM INCLUDE FILES -#include -#include // CStack -#include // MDiagPlugin -#include // MDiagSuitePlugin -#include // MDiagTestPlugin -#include // CDiagPluginPool -#include // RDiagResultsDatabaseRecord -#include // CDiagResultsDbItemBuilder -#include // MDiagResultDetail -#include // For debug log -#include // CDiagResultsDbRecordEngineParam - -// USER INCLUDE FILES -#include "diagframework.pan" // panic codes -#include "diagexecplanentryimpl.h" // CDiagExecPlanEntryImpl -#include "diagexecplanentryimpltest.h" // CDiagExecPlanEntryImplTest -#include "diagexecplanentryimplsuite.h" // CDiagExecPlanEntryImplSuite -#include "diagcleanupresetanddestroy.h" // CleanupRPointerArrayPushL -#include "diagengineconfig.h" // TDiagEngineConfig - - -// DATA - -// MACROS -// Uncomment the line below to enable more plan creation log. -// #define _DEBUG_EXEC_PLAN - - -// LOCAL DATA TYPES -/** -* Used for keeping track of suite level stack. -* It is used in InsertSuiteTransitionsL() function. ( STEP_5 ) -*/ -struct TTransitionStackEntry - { - /** - * iLeavelUid - Uid of the current level. - */ - TUid iLevelUid; - - /** - * iPrepareIndex - Index in the plan where ETypeSuitePrepare entry is. - * This information is used to update the suite iAsDependent field. - */ - TInt iPrepareIndex; - }; - - -// ======== LOCAL FUNCTIONS ======== - - -// ======== MEMBER FUNCTIONS ======== - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::NewL -// --------------------------------------------------------------------------- -// -CDiagPluginExecPlanImpl* CDiagPluginExecPlanImpl::NewL( - MDiagEngineCommon& aEngine, - const TDiagEngineConfig& aEngineConfig, - MDiagExecPlanEntryImplObserver& aEntryObserver ) - { - CDiagPluginExecPlanImpl* self = new ( ELeave ) CDiagPluginExecPlanImpl( - aEngine, - aEngineConfig, - aEntryObserver ); - - return self; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::CDiagPluginExecPlanImpl -// --------------------------------------------------------------------------- -// -CDiagPluginExecPlanImpl::CDiagPluginExecPlanImpl( - MDiagEngineCommon& aEngine, - const TDiagEngineConfig& aEngineConfig, - MDiagExecPlanEntryImplObserver& aEntryObserver ) - : CActive( EPriorityLow ), - iEngine( aEngine ), - iEngineConfig( aEngineConfig ), - iPlanEntryObserver( aEntryObserver ) - { - CActiveScheduler::Add( this ); - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::~CDiagPluginExecPlanImpl -// --------------------------------------------------------------------------- -// -CDiagPluginExecPlanImpl::~CDiagPluginExecPlanImpl() - { - Cancel(); - iPlan.ResetAndDestroy(); - iPlan.Close(); - iExecutedEntries.ResetAndDestroy(); - iExecutedEntries.Close(); - } - - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::InitaliazeL -// Creating a fresh session. -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::InitializeL( TRequestStatus& aStatus, - const RPointerArray< MDiagPlugin >& aBatch ) - { - LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: new session") - - __ASSERT_ALWAYS( iState == EStateIdle, Panic( EDiagFrameworkInternal ) ); - - aStatus = KRequestPending; - iClientStatus = &aStatus; - - iExecutedEntries.ResetAndDestroy(); - iPlan.ResetAndDestroy(); - iResumeIndex = 0; - - // pre-step execution step. copy the argument to a local plan - TInt i; - for ( i = 0; i < aBatch.Count(); i++ ) - { - __ASSERT_ALWAYS( aBatch[i] != NULL, Panic( EDiagFrameworkBadArgument ) ); - - CDiagExecPlanEntryImpl* newEntry = CreateDefaultPlanEntryLC( - *(aBatch[i]), - EFalse ); // aAsDependency - - iPlan.AppendL( newEntry ); // ownership transferred. - CleanupStack::Pop( newEntry ); - newEntry = NULL; - } - - LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: Initial Batch" ) - LogPlanL(); - - ChangeState( EStateExpandDependencyAndSuites ); - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::InitializeL -// Continuing from incomplete session. -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::InitializeL( TRequestStatus& aStatus ) - { - LOGSTRING( "CDiagPluginExecPlanImpl::InitaliazeL: continue" ) - - // validate input. - __ASSERT_ALWAYS( iState == EStateIdle, Panic( EDiagFrameworkInternal ) ); - - // if we are resuming incomplete session, it must incomplete. - TBool isRecordCompleted = EFalse; - User::LeaveIfError( iEngine.DbRecord().IsTestCompleted( isRecordCompleted ) ); - __ASSERT_ALWAYS( !isRecordCompleted, Panic( EDiagFrameworkBadArgument ) ); - - aStatus = KRequestPending; - iClientStatus = &aStatus; - iResumeIndex = 0; - - iExecutedEntries.ResetAndDestroy(); - iPlan.ResetAndDestroy(); - - // Retrieve records from database and use it as base for creating - // a new plan. - RPointerArray< CDiagResultsDatabaseItem > previousResults; - DiagFwInternal::CleanupRPointerArrayPushL< CDiagResultsDatabaseItem >( &previousResults ); - - User::LeaveIfError( - iEngine.DbRecord().GetTestResults( previousResults ) ); - - TInt resultCount = previousResults.Count(); - for( TInt i = 0; i < resultCount; i++ ) - { - // Get the test plug-in. - // Note that FindPlugin does not transfer ownership and hence testPlugin - // and does not need to be deallocated. - MDiagPlugin& testPlugin = - iEngine.PluginPool().FindPluginL( previousResults[i]->TestUid() ); - - // This should have been a test plug-in - __ASSERT_DEBUG( testPlugin.Type() == MDiagPlugin::ETypeTestPlugin, - Panic( EDiagFrameworkInternal ) ); - - CDiagExecPlanEntryImplTest* testEntry = - CDiagExecPlanEntryImplTest::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagTestPlugin& >( testPlugin ), - previousResults[i]->WasDependency(), - previousResults[i]->TestResult() ); - - if ( testEntry->Result() == CDiagResultsDatabaseItem::EQueuedToRun ) - { - // it was queued to be executed. - iPlan.AppendL( testEntry ); // ownership transferred. - } - else - { - // it was already executed. - iExecutedEntries.AppendL( testEntry ); // ownership transferred. - } - CleanupStack::Pop( testEntry ); - testEntry = NULL; - } - - CleanupStack::PopAndDestroy( &previousResults ); - - iResumeIndex = iExecutedEntries.Count(); - - if ( iResumeIndex != 0 ) - { - LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: Queued Items" ) - LogPlanL(); - - ChangeState( EStateExpandDependencyAndSuites ); - } - else - { - LOGSTRING( "CDiagPluginExecPlanImpl::InitializeL: " - L"Items in DB may be invalid. Fully recreate plan" ) - - // If iResumeIndex is 0, it means that all items in the db are - // marked as EQueuedToRun. Because of the async nature of db, - // it could also indicate that not previous plan was not fully - // written to the database. In this case, read the engine parameter - // and try to recreate the plan from scratch. - // - // If it was already fully written but hadn't had a chance to really - // execute anything, this will not cause any ill effects since - // plan created should be identical and simply reset - // all results in db to EQueuedToRun. - iExecutedEntries.ResetAndDestroy(); - iPlan.ResetAndDestroy(); - - RPointerArray< MDiagPlugin > batch; - CleanupClosePushL( batch ); // items are not owned, so no need for "Destroy" - - CDiagResultsDbRecordEngineParam* engineParam = NULL; - User::LeaveIfError( - iEngine.DbRecord().GetEngineParam( engineParam ) ); - - CleanupStack::PushL( engineParam ); - - const RArray< TUid >& batchUids = engineParam->ExecutionsUidArray(); - - // Read original Uids from previous engine param. - for( TInt i = 0; i < batchUids.Count(); i++ ) - { - MDiagPlugin* testPlugin = NULL; - User::LeaveIfError( - iEngine.PluginPool().FindPlugin( batchUids[i], testPlugin ) ); - - __ASSERT_DEBUG( testPlugin != NULL, Panic( EDiagFrameworkInternal ) ); - if ( testPlugin ) //lint !e774 This will be evaluated on non-debug build. - { - batch.AppendL( testPlugin ); - } - } - - CleanupStack::PopAndDestroy( engineParam ); - engineParam = NULL; - - // Call the normal InitializeL() method as if it is a new session. - InitializeL( aStatus, batch ); - - CleanupStack::PopAndDestroy( &batch ); // calls Close() - } - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::operator[] -// --------------------------------------------------------------------------- -// -CDiagExecPlanEntryImpl& CDiagPluginExecPlanImpl::operator[]( TInt aIndex ) - { - return *iPlan[aIndex]; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::CurrentExecutionItem -// --------------------------------------------------------------------------- -// -CDiagExecPlanEntryImpl& CDiagPluginExecPlanImpl::CurrentExecutionItem() - { - return *iPlan[iExecutionCursor]; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::ResetExecutionCursor -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::ResetExecutionCursor() - { - iExecutionCursor = 0; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::MoveCursorToNext -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::MoveCursorToNext() - { - TBool value = EFalse; - - if ( iExecutionCursor < iPlan.Count() - 1 ) - { - iExecutionCursor++; - value = ETrue; - } - else - { - // cannot move beyond the last item. - } - - return value; - } - -// ======== From CActive ========= -// --------------------------------------------------------------------------- -// From CActive -// CDiagPluginExecPlanImpl::RunL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::RunL() - { - /*---------------------------------------------------------------------- - Create execution plan: - Overview: - - STEP_1. Expand Dependency - STEP_2. Expand Suites. - STEP_3. Repeat STEP_1 & STEP_2 until no changes are made to the plan - STEP_4. Check and remove empty suites - STEP_5. Add Prepare/Finalize suite execution. - STEP_6. Store execution plan to results db. - STEP_7. Append items that were executed in the previous test - to the beginning of the test. - - Details: - STEP_1. Expand Dependency - In this step, each item is checked for dependency and - dependent items will be inserted into plan. - Note that if dependent item also depends on something else, those - will be added immediately. - - All items inserted during this phase is inserted as dependent. - - STEP_2. Expand suites - Suites are expandeded to individual tests or suites. Suite - item will be expanded between parent suite's Prepare and - Finalize items. - - iAsDependent value will be inherited from the parent suite - that it expanded from. E.g. if suite was dependent, then so will - all the items that included from that suite. - - Note that it does not remove the original suite entry in the plan. - This is to make sure that dependencies inserted will be grouped - within the same group as the plug-ins that depended on it. - If they are removed, and re-inserted later in STEP_5, it will - cause the dependent items to be outside of the original grouping. - e.g. S1 = {P1} - S2 = {P2, P3} - - and P2 depends on P1 - - When dependency and suites are expanded with original - suite removed, after STEP_3, the plan will look like this: - (* indicates iAsDependent == ETrue) - - 0 1 2 - *P1 P2 P3 - - When it tries to add suite transition back in to the plan, - it will look like this: - (* indicates iAsDependent == ETrue) - (< indicates suite prepare execution.) - (> indicates suite finalize execution.) - - 0 1 2 3 4 5 6 - - - which is somewhat incorrect since *P1 is added due to - dependency. - - Instead, if original suite grouping is kept, after STEP_3 - - 0 1 2 3 4 - - - After STEP_5 - - 0 1 2 3 4 5 6 - P2 P3 S2> - - which is more correct. - - Note that this will be done in breadth first style. If there is a - nested suites, it will not be expanded until next cycle. - This is to allow dependencies of the suite to be expanded before - being removed. - - STEP_3. Repeat STEP_1 & STEP_2 until no changes are made. - This step ensures that suites are expanded, and all dependent - items are added to the plan. - - STEP_4. Remove Empty suites - Because dependent items can be moved, it is possible that plan ends - up with empty suites. This section will check for - suite prepare/finalize that has nothing inside, and remove them. - - STEP_5. Add Prepare/Finalize steps for suites. - As a final step, it will navigate all the entries in the plan, and - insert proper prepare/finalize steps. This is based on stack, - where every suite prepare is pushed into a stack, and poped when - suite finalize is called. e.g. consider following plug-ins: - - S1 = { P1, P2 } - S2 = { P3, P4 } - - And P3 depends on P2. - - And resulting plan after STEP_4 looked like this: - - 0 1 2 3 4 - - - After STEP_5, it should look like this: - - 0 1 2 3 4 5 6 - P3 P4 S2> - - STEP_6. Store execution plan to results db. - This allows continuation of the incomplete results. - Only test plug-ins are written to the database. - - STEP_7. Append items that were executed in the previous test - to the beginning of the test. - - Other Notes: - - NOTE_1) This logic currently does not check for circular dependencies. - If circular dependency exists, the program will go into an - infinite loop in ExpandDependenciesL(). - - NOTE_2) Inserting duplicate items. - Due to dependencies, duplicate entries may exist in the plan. - - When items are inserted during STEP_1 - STEP_2, it will be checked - for duplicates. - - Duplicate removal policy is as follows: - RULE_A) If an item with "iAsDependent == ETrue" is being inserted, - AND if an item already exist in the plan before current index, - then it will not be inserted. - - RULE_B) Any items inserted with "iAsDependent == EFalse" will - always be inserted at the requested index. - This is because they are considered to be user input, and - plan will not try to re-order the execution order that - client or user has specified. - - RULE_C) The first instance of an item has higher priority than later - instances. Later instace of duplicate will be removed, unless - it violates RULE_B. (e.g. item has "iAsDependent == EFalse".) - - This has a side effect: item may execute twice in certain cases. - E.g. original plan has two plug-ins: P1, P2, P3 - P1 depends on P2, and P3 also depends ond P2 - - Original Input: 0 1 2 - P1 P2 P3 - - After STEP_3, it should look like this. - (* indicates iAsDependent == ETrue) - - 0 1 2 3 4 - *P2 P1 P2 *P2 P3 - - During STEP_4, duplicates are removed, and it should look like this: - (* indicates iAsDependent == ETrue) - - 0 1 2 4 - *P2 P1 P2 P3 - - Note that there are two P2s in the plan; - at 0 with iAsDependent == ETrue and at 2 with iAsDependent == EFalse - - There may be some discussions on whether this is how it should be. - However, at this point, it seems that it is more important that - execution appears to the user in the order specified. - - To make sure that user sees that P2 is executed only once, plug-in - developer may need to make sure that if a plug-in provides services, - it should also handle cases where it is executed twice. - - In reality, such cases can be avoided by grouping the plug-ins - in the correct order, hence it should not be an issue. - - ----------------------------------------------------------------------*/ - - // First, error handling. - LOGSTRING3( "CDiagPluginExecPlanImpl::RunL: State = %d, Err = %d", - iState, iStatus.Int() ) - - User::LeaveIfError( iStatus.Int() ); - - switch ( iState ) - { - case EStateExpandDependencyAndSuites: - { - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_1") - // STEP_1. Expand dependency. - if ( !iEngineConfig.IsDependencyDisabled() ) - { - ExpandDependenciesL(); - } - - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_2") - // STEP_2. Expand suites. - if ( ExpandSuitesL() ) - { - // STEP_3. Repeat STEP_1, STEP_2 until no changes are made. - // Do a self transition to repeat STEP_1 and STEP_2 - ChangeState( EStateExpandDependencyAndSuites ); - } - else - { - // no changes are made to the plan. Move to STEP_4 - ChangeState( EStateRemoveEmptySuites ); - } - } - break; - - case EStateRemoveEmptySuites: - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_4") - // STEP_4. Remove empty suites. This can happen because of duplicate - // dependencies moving later dependent test to earlier position. - RemoveEmptySuites(); - - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING( "CDiagPluginExecPlanImpl:CreatePlanL: " - L"Before Inserting Suite Transtions" ) - LogPlanL(); - #endif // _DEBUG_EXEC_PLAN - - // Continue to STEP_5 - ChangeState( EStateInsertSuiteTransitions ); - break; - - case EStateInsertSuiteTransitions: - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_5 - Insert Suite Transtions") - // STEP_5. Add pre/post suite execution - InsertSuiteTransitionsL(); - - // STEP_6. Store plan to db. - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_6 - Store to db") - // this time, manually update state, since storing - // to database needs to use iStatus - iState = EStateStoreToDb; - - // Move cursor to one before so that it can start checking from - // the beginning. StoreNextTestPluginToDbL() will move the cursor - // as soon as it enters. - iExecutionCursor = -1; - StoreNextTestPluginToDbL(); - - break; - - case EStateStoreToDb: - LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: STEP_6 - " - L"item 0x%08x stored.", - iPlan[iExecutionCursor]->Plugin().Uid().iUid ) - - StoreNextTestPluginToDbL(); - break; - - case EStatePlanCreated: - // STEP_7. Prepend the items that were executed in last session - // to the beginning of the execution plan. - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: STEP_7 - prepend executed items" ) - PrependExecutedItemsL(); - - LOGSTRING( "CDiagPluginExecPlanImpl::RunL: Final Plan" ) - LogPlanL(); - - LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: Resume at index %d", iResumeIndex ) - - LogPlanInRecordL(); - - ResetExecutionCursor(); - - ReportResult( KErrNone ); - break; - - case EStateIdle: - default: - __ASSERT_DEBUG( 0, Panic( EDiagFrameworkInternal ) ); - break; - } - } - -// --------------------------------------------------------------------------- -// From CActive -// CDiagPluginExecPlanImpl::DoCancel -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::DoCancel() - { - iPlan.ResetAndDestroy(); - iExecutedEntries.ResetAndDestroy(); - iState = EStateIdle; - - ReportResult( KErrCancel ); - } - -// --------------------------------------------------------------------------- -// From CActive -// CDiagPluginExecPlanImpl::RunError -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::RunError( TInt aError ) - { - iPlan.ResetAndDestroy(); - iExecutedEntries.ResetAndDestroy(); - iState = EStateIdle; - - ReportResult( aError ); - - return KErrNone; - } - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::CurrentIndex -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::CurrentIndex() const - { - return iExecutionCursor; - } - - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::CurrentTestIndex -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::CurrentTestIndex( TBool aIncludeDependency ) const - { - TInt count = 0; - - for ( TInt i = 0; i < iPlan.Count() && i < iExecutionCursor; i++ ) - { - if ( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeTestPlugin ) - { - // if caller wants to include both explicit and dependent - // or if plug-in is not depentent test, count. - if ( aIncludeDependency || ( !iPlan[i]->AsDependency() ) ) - { - count++; - } - } - } - - // subtract 1 if we only went past the last test. - if ( count >= TestCount( aIncludeDependency ) ) - { - count--; - } - return count; - } - - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::TestCount -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::TestCount( TBool aIncludeDependency ) const - { - TInt count = 0; - - for ( TInt i = 0; i < iPlan.Count(); i++ ) - { - if ( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeTestPlugin ) - { - // if caller wants to include both explicit and dependent - // or if plug-in is not depentent test, count. - if ( aIncludeDependency || ( !iPlan[i]->AsDependency() ) ) - count++; - } - } - return count; - } - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::operator[] () const -// --------------------------------------------------------------------------- -// -const MDiagExecPlanEntry& CDiagPluginExecPlanImpl::operator[] ( TInt aIndex ) const - { - __ASSERT_ALWAYS( aIndex >= 0 && aIndex < iPlan.Count(), - Panic( EDiagFrameworkArrayBounds ) ); - return *( static_cast< MDiagExecPlanEntry* >( iPlan[aIndex] ) ); - } - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::CurrentExecutionItem const -// --------------------------------------------------------------------------- -// -const MDiagExecPlanEntry& CDiagPluginExecPlanImpl::CurrentExecutionItem() const - { - __ASSERT_ALWAYS( iExecutionCursor >= 0 && iExecutionCursor < iPlan.Count(), - Panic( EDiagFrameworkArrayBounds ) ); - return *( static_cast< MDiagExecPlanEntry* >( iPlan[iExecutionCursor] ) ); - } - - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::IsLastTest -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::IsLastTest() const - { - if ( TestCount( ETrue ) == 0 ) - { - // there was no test in the plan.. - // In this case, it is always ETrue. - return ETrue; - } - - return ( CurrentTestIndex( ETrue ) == TestCount( ETrue ) - 1 ); - } - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::IsLastPlugin -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::IsLastPlugin() const - { - if ( iPlan.Count() == 0 ) - { - // if plan was empty, always consider it to be the last. - return ETrue; - } - - return iExecutionCursor == ( iPlan.Count() -1 ); - } - - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::Count -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::Count() const - { - return iPlan.Count(); - } - -// --------------------------------------------------------------------------- -// From MDiagPluginExecPlan -// CDiagPluginExecPlanImpl::ResumeIndex -// --------------------------------------------------------------------------- -// -TInt CDiagPluginExecPlanImpl::ResumeIndex() const - { - return iResumeIndex; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::ChangeState -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::ChangeState( TState aState ) - { - LOGSTRING3( "CDiagPluginExecPlanImpl::ChangeState: state change %d -> %d", - iState, aState ) - - iState = aState; - - TRequestStatus* stat = &iStatus; - User::RequestComplete( stat, KErrNone ); - SetActive(); - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::ExpandDependenciesL -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::ExpandDependenciesL() - { - // STEP_1. Expand dependency. - // Before modifying this function, please see STEP_1 comments in CreatePlanL() - TInt planIdx = 0; - TBool planChanged( EFalse ); - while ( planIdx < iPlan.Count() ) - { - TBool itemAdded = EFalse; - - // we are only interested in type ETypeTestExec or ETypeSuiteUnexpanded. - // If it is ETypeSuitePrepare or ETypeSuiteFinalize, that means - // that it is a suite and it has been already been expanded to - // prepare/finalize. Since dependencies are resolved before suites - // are expanded, we are not interested in re-evaluating expanded tests. - if ( iPlan[planIdx]->Type() == CDiagExecPlanEntryImpl::ETypeTestExec || - iPlan[planIdx]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded ) - { - // dependencies should be rare. So granuality 1 should be fine. - CPtrCArray* depList = new( ELeave )CPtrCArray( 1 ); - CleanupStack::PushL( depList ); - iPlan[planIdx]->Plugin().GetLogicalDependenciesL( *depList ); - - // iterate through the dependiencies BACKWARDS to make sure - // that dependencies are inserted in the same order - // specified. If it is not added backwards, developers may - // be surprised that dependencies are executed - // in reverse order of what is specified in the XML. - for ( TInt depIdx = depList->Count() - 1; depIdx >= 0; depIdx-- ) - { - // If dependency is specified, but the dependent plug-in is - // not found in plug-in pool, this probably means - // plug-in database is corrupted. - MDiagPlugin& plugin = iEngine.PluginPool().FindPluginL( ( *depList )[ depIdx ] ); - - if ( InsertPluginL( plugin, - ETrue, - planIdx ) ) - { - itemAdded = ETrue; - } - } - CleanupStack::PopAndDestroy( depList ); - depList = NULL; - } - - // Advance to next item in plan only if no new item is added. - // This ensures that items just added are re-evaluated for - // dependency, and expand if it is an unexpanded suite. - if ( !itemAdded ) - { - planIdx++; - } - else - { - planChanged = ETrue; - } - } - - return planChanged; - } - - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::ExpandSuitesL -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::ExpandSuitesL() - { - // STEP_2. Expand suites. - // Before modifying this function, please see STEP_1 comments in CreatePlanL() - TBool planChanged = EFalse; - TInt i = 0; - while ( i < iPlan.Count() ) - { - if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded ) - { - // If it is unexpanded, it must be a suite. - __ASSERT_DEBUG( iPlan[i]->Plugin().Type() == MDiagPlugin::ETypeSuitePlugin, - Panic( EDiagFrameworkInternal ) ); - planChanged = ETrue; - - // Change type from ETestExec to ETypeSuitePrepare. This indicates - // that the suite item in the plan has been examined and - // expanded. - iPlan[i]->SetType( CDiagExecPlanEntryImpl::ETypeSuitePrepare ); - - // dependency is inherited - TBool asDependency = iPlan[i]->AsDependency(); - - // Get Children from the plug-in - MDiagSuitePlugin& suite = static_cast( iPlan[i]->Plugin() ); - RPointerArray children; - CleanupClosePushL( children ); - - suite.GetChildrenL( children, MDiagSuitePlugin::ESortByPosition ); - - i++; // insert rest after current item. - - TInt childIdx = 0; - while ( childIdx < children.Count() ) - { - if ( InsertPluginL( *( children[childIdx] ), - asDependency, - i ) ) - { - // new item is added. Move to next - i++; - } - childIdx++; - } - - children.Reset(); // children pointers are not owned - CleanupStack::PopAndDestroy( &children ); - - // insert suite finalize entry into plan - CDiagExecPlanEntryImplSuite* finalizeEntry = - CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - suite, - asDependency, - CDiagExecPlanEntryImpl::ETypeSuiteFinalize ); - - iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( finalizeEntry ), i ); - CleanupStack::Pop( finalizeEntry ); // owership transferred - finalizeEntry = NULL; - i++; - } - else - { - // this one is not suite, so examine the next one. - i++; - } - } - - return planChanged; - } - -// Looking for STEP_3? It is in RunL() .. - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::RemoveEmptySuites -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::RemoveEmptySuites() - { - // STEP_4. Remove empty suites - // Before modifying this function, please see STEP_1 comments in CreatePlanL() - - // Checking for duplicate is done by checking if suite prepare/finalize - // is in the plan next to each other. - // - // NOTE_4 - // After a empty suite is removed, step back one index. - // so that the previous item will be re-evaluated, in case removing them cased - // the parent suite to be empty as well. - // e.g - // i == 1 - // index: 0 [1] 2 3 - // A> - // after removal, now prepare/finalize A becomes next to each other - // - // i == 1 - // index: 0 [1] - // - // - // in order to make sure that above case is handled, decrement i and - // re-evaluate from index 0 - // - TInt i = 0; - while ( i < iPlan.Count() - 2 ) // no need to go beyond the last item - { - if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare && - iPlan[i+1]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize ) - { - // if these two do not match, then there may have been - // a problem during plan creation. - __ASSERT_DEBUG( iPlan[i]->Plugin().Uid() == iPlan[i+1]->Plugin().Uid(), - Panic( EDiagFrameworkCorruptPlugin ) ); - - - CDiagExecPlanEntryImpl* entry = iPlan[ i + 1 ]; - iPlan.Remove( i+1 ); - delete entry; - entry = NULL; - - entry = iPlan[i]; - iPlan.Remove( i ); - delete entry; - entry = NULL; - - // Wondering why step back by one? See NOTE_4 - if ( i > 0 ) - { - i--; - } - } - else - { - // it's not empty. Examine next item. - i++; - } - } - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::InsertSuiteTransitionsL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::InsertSuiteTransitionsL() - { - // STEP_5. Add pre/post suite execution based on test parent change. - // Before modifying this function, please see STEP_1 comments in CreatePlanL() - - // if plan is empty, nothing to do. - if ( iPlan.Count() == 0 ) - { - return; - } - - // Create a new CStack. Second template parameter ETrue means that - // CStack owns the stack entries. - CStack* stack = - new( ELeave )CStack; - - CleanupStack::PushL( stack ); - - // create a root entry - AddRootSuiteIfMissingL(); - - // In this loop, iPlan.Count() cannot be cached because new item may be - // added within the loop - TInt i = 0; - while ( i < iPlan.Count() ) - { - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING2( "CDiagPluginExecPlanImpl::InsertSuiteTransitionsL: ------ %d", i ) - LogPlanL(); - #endif // _DEBUG_EXEC_PLAN - - // Case 1 - // If current item is a suite prepare, push a new level into stack. - if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare ) - { - // we are entering a new suite. Push current plan item into stack. - PushNewLevelL( *stack, i ); - i++; - continue; //lint !e960 continue OK. examine next item. - } - - // Case 2 - // If current item is a suite finalize, pop a level from stack. - if ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize && - stack->Head() != NULL && - stack->Head()->iLevelUid == iPlan[i]->Plugin().Uid() ) - { - // we are leaving a suite. Pop top item from suite. - PopLevel( *stack ); - i++; - continue; //lint !e960 : continue OK. examine next item. - } - - // it was neither prepare or finalize. Examine item as current level. - const TTransitionStackEntry& level = *(stack->Head()); // Peek - - TUid newLevelUid = iPlan[i]->Plugin().ParentUid(); - - // Case 3 - if ( newLevelUid == level.iLevelUid ) - { - // still in the same suite level. No need to add new items. - - // check if current item is non-dependent. - // If so, update the iAsDependent to reflect that it includes - // a non-dependent item. - if ( !(iPlan[i]->AsDependency()) ) - { - // update the prepare item, indicating that it has - // an non-dependent item - iPlan[level.iPrepareIndex]->SetAsDependency( EFalse ); - } - i++; - continue; //lint !e960 : continue OK. examine next item. - } - - // If parent UID is differnt from current level uid, - // it can mean one of the following: - // A ) We are entering a new suite. - // B ) We leaving a suite. - // Case B ) can be deteced by checking whether the new parent is - // already in the stack somewhere (stack will be popped until we are - // in the same level), or if there is no more item of the same - // level is in the plan, which means it is not needed. - // If case B ) fails, assume case A. - if ( IsLevelInStack( *stack, newLevelUid ) || - !IsThisSuiteNeededAfterThisIndex( stack->Head()->iLevelUid, i ) ) - { - // Case B) Insert a new Finalize item. - AddSuiteFinalizeL( level.iPrepareIndex, i ); - } - else - { - // Case A) Insert a new prepare item. - AddSuitePrepareL( newLevelUid, i ); - } - } - - // When all done, stack must be empty. - __ASSERT_DEBUG( stack->IsEmpty(), Panic( EDiagFrameworkInternal ) ); - - CleanupStack::PopAndDestroy( stack ); - stack = NULL; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::AddRootSuiteIfMissingL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::AddRootSuiteIfMissingL() - { - // Check to see if root element is already in the plan. - if ( iPlan[0]->Plugin().Uid() != KDiagRootSuiteUid ) - { - // root( uid 0 ) does not exist in the plan. - // Add prepare and finalize root into the plan. - MDiagPlugin& rootPlugin = iEngine.PluginPool().FindPluginL( KDiagRootSuiteUid ); - - CDiagExecPlanEntryImplSuite* rootEntry = - CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagSuitePlugin& >( rootPlugin ), - ETrue, // iAsDependent == ETrue. Updated as later. - CDiagExecPlanEntryImpl::ETypeSuitePrepare ); - - iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( rootEntry ), 0 ); - CleanupStack::Pop( rootEntry ); // ownership transferred above. - rootEntry = NULL; - - rootEntry = CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagSuitePlugin& >( rootPlugin ), - ETrue, // iAsDependent == ETrue. Updated as later. - CDiagExecPlanEntryImpl::ETypeSuiteFinalize ); - - // insert same entry with finalize as type - iPlan.AppendL( static_cast< CDiagExecPlanEntryImpl* >( rootEntry ) ); - CleanupStack::Pop( rootEntry ); // ownership transferred above - rootEntry = NULL; - } - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::PushNewLevelL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::PushNewLevelL( - CStack& aStack, - TInt aHeadIndex ) - { - TTransitionStackEntry* level = new( ELeave )TTransitionStackEntry; - - __ASSERT_ALWAYS( aHeadIndex >= 0 && aHeadIndex < iPlan.Count(), - Panic( EDiagFrameworkInternal ) ); - - level->iLevelUid = iPlan[aHeadIndex]->Plugin().Uid(); - level->iPrepareIndex = aHeadIndex; - - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING2( "CDiagPluginExecPlanImpl:: Push 0x%08x", level->iLevelUid.iUid ) - #endif // _DEBUG_EXEC_PLAN - - aStack.PushL( level ); // owership transferred. - level = NULL; //lint !e423 Ownership transferred. No leak here. - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::PopLevel -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::PopLevel( CStack& aStack ) - { - TTransitionStackEntry* level = aStack.Pop(); - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING2( "CDiagPluginExecPlanImpl:: Pop 0x%08x", level->iLevelUid.iUid ) - #endif // _DEBUG_EXEC_PLAN - delete level; - level = NULL; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::IsLevelInStack -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::IsLevelInStack( - CStack& aStack, - TUid aLevelUid ) const - { - for ( TInt i = 0; i < aStack.Count(); i++ ) - { - const TTransitionStackEntry& currEntry = *aStack[i]; - if ( currEntry.iLevelUid == aLevelUid ) - { - return ETrue; - } - } - - return EFalse; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::IsThisSuiteNeededAfterThisIndex -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::IsThisSuiteNeededAfterThisIndex( - TUid aSuiteUid, - TInt aIndex ) const - { - for ( TInt i = aIndex; i < iPlan.Count(); i++ ) - { - if ( iPlan[i]->Plugin().Uid() == aSuiteUid || // finalize already exists - iPlan[i]->Plugin().ParentUid() == aSuiteUid ) - { - return ETrue; - } - } - - return EFalse; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::AddSuitePrepareL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::AddSuitePrepareL( TUid aLevelUid, TInt aAt ) - { - MDiagPlugin& suitePlugin = iEngine.PluginPool().FindPluginL( aLevelUid ); - - CDiagExecPlanEntryImplSuite* prepareEntry = - CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagSuitePlugin& >( suitePlugin ), - ETrue, // iAsDependent. Updated as later if not true. - CDiagExecPlanEntryImpl::ETypeSuitePrepare ); - - iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( prepareEntry ), aAt ); - CleanupStack::Pop( prepareEntry ); // ownership transfer - prepareEntry = NULL; - - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING2( "CDiagPluginExecPlanImpl:: InsertPrepare 0x%08x", aLevelUid ) - #endif // _DEBUG_EXEC_PLAN - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::AddSuiteFinalizeL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::AddSuiteFinalizeL( TInt aPrepareIndex, TInt aAt ) - { - // It is identical to the prepare entry, except that type is ETypeSuiteFinalize - __ASSERT_ALWAYS( aPrepareIndex >= 0 && aPrepareIndex < iPlan.Count(), - Panic( EDiagFrameworkInternal ) ); - - CDiagExecPlanEntryImplSuite& prepareEntry = - static_cast< CDiagExecPlanEntryImplSuite& > ( *(iPlan[aPrepareIndex]) ); - - CDiagExecPlanEntryImplSuite* finalizeEntry = - CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - prepareEntry.SuitePlugin(), - prepareEntry.AsDependency(), - CDiagExecPlanEntryImpl::ETypeSuiteFinalize ); - - iPlan.InsertL( static_cast< CDiagExecPlanEntryImpl* >( finalizeEntry ), aAt ); - CleanupStack::Pop( finalizeEntry ); // ownership transmitted above - finalizeEntry = NULL; - - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING2( "CDiagPluginExecPlanImpl:: InsertFinalize 0x%08x", prepareEntry.Plugin().Uid().iUid ); - #endif // _DEBUG_EXEC_PLAN - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::StoreNextTestPluginToDbL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::StoreNextTestPluginToDbL() - { - // STEP_6. Store plan to DB. - // In this step, all test entries must be stored in db with EQueuedToRun - // status. Since DbRecord().LogTestResult() is an async call, only one - // item can be written at a time. - // - // To do this, this function will search for the next "TEST" plug-in that - // needs to be logged to DB. Once it is found, it will call async function - // LogTestResult() and wait for RunL() to execute again. - // In RunL(), StoreNextTestPluginToDbL() is called again, and it will look for the - // next test plugin to store until it loops through all items in plan. - while ( MoveCursorToNext() ) - { - if ( CurrentExecutionItem().Plugin().Type() == MDiagPlugin::ETypeTestPlugin ) - { - LOGSTRING2( "CDiagPluginExecPlanImpl::RunL: STEP_6 - storing item 0x%08x", - CurrentExecutionItem().Plugin().Uid().iUid ) - - CDiagResultsDatabaseItem* resultItem = - CDiagResultsDbItemBuilder::CreateSimpleDbItemL( - CurrentExecutionItem().Plugin().Uid(), - CurrentExecutionItem().AsDependency(), - CDiagResultsDatabaseItem::EQueuedToRun ); - - // Record initial test result to db. - // StoreNextTestPluginToDbL() will be called again later from RunL() - iEngine.DbRecord().LogTestResult( iStatus, *resultItem ); - SetActive(); - - delete resultItem; - resultItem = NULL; - - // Exit here since we must wait for LogTestResult() to complete - // before moving on to the next item. - return; - } - } - - // All items are stored now. - ChangeState( EStatePlanCreated ); - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::PrependExecutedItemsL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::PrependExecutedItemsL() - { - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING( "CDiagExecPlanEntryImpl::PrependExecutedItemsL(). " - L" Before prepending executed entries" ); - LogPlanL(); - #endif // _DEBUG_EXEC_PLAN - - for ( TInt lastIndex = iExecutedEntries.Count() - 1; - lastIndex >= 0 ; - lastIndex-- ) - { - // Insert last entry from the executed list to the beginning. - iPlan.InsertL( iExecutedEntries[ lastIndex ], 0 ); - iExecutedEntries.Remove( lastIndex ); - } - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::ReportResult -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::ReportResult( TInt aError ) - { - User::RequestComplete( iClientStatus, aError ); - iClientStatus = NULL; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::InsertPluginL -// --------------------------------------------------------------------------- -// -TBool CDiagPluginExecPlanImpl::InsertPluginL( MDiagPlugin& aPlugin, - TBool aAsDependency, - TInt aAt ) - { - #ifdef _DEBUG_EXEC_PLAN - LOGSTRING4( "CDiagPluginExecPlanImpl::InsertPluginL:" - L"Id = 0x%x, Type = %s, At %d", - aPlugin.Uid().iUid, - ( aPlugin.Type() == MDiagPlugin::ETypeTestPlugin ? L"Test" : L"Suite" ), - aAt ) - #endif // _DEBUG_EXEC_PLAN - - __ASSERT_ALWAYS( aAt >= 0 && aAt <= iPlan.Count(), Panic( EDiagFrameworkArrayBounds ) ); - - // First, examine items before given index. - // If new item has iAsDependent == ETrue, and also found before the given index, - // --> it is okay to not insert the item, since it will just be duplicates. - // if new item has iAsDependent == EFalse, - // --> no need to check for items prior to current position, since - // explicit - // where it was requested. - TInt idx = 0; - if ( aAsDependency ) - { - // check if it was already executed in the previous session. - for ( idx = 0; idx < iExecutedEntries.Count(); idx++ ) - { - if ( iExecutedEntries[idx]->Plugin().Uid() == aPlugin.Uid() ) - { - // matching item found. - // No need to instert a new item. - return EFalse; - } - } - - // check for items in current plan. - for ( idx = 0; idx < aAt && idx < iPlan.Count(); idx++ ) - { - if ( iPlan[idx]->Plugin().Uid() == aPlugin.Uid() ) - { - // Matching item found. - // No change to plan made. - return EFalse; - } - } - } - - // Duplicate item not found before given index. - // An item will be inserted at the given index. Now, we search for - // duplicates after current index, and see if we can remove them. - idx = aAt; - while ( idx < iPlan.Count() ) - { - if ( iPlan[idx]->Plugin().Uid() == aPlugin.Uid() && iPlan[idx]->AsDependency() ) - { - // Item is found, and it was for dependency. - // We can move this item to current position. - // For now, we just need to remove it, since it will be added at - // current position when for loop is done. - CDiagExecPlanEntryImpl* entry = iPlan[idx]; - iPlan.Remove( idx ); - delete entry; - entry = NULL; - - // no need to increment idx, since current item is removed. - // idx should already be at the next item. - } - else - { - idx++; // check next item. - } - } - - // Either plug-in is not found, or we found one that we can move. - // Add to current position. - CDiagExecPlanEntryImpl* newEntry = CreateDefaultPlanEntryLC( - aPlugin, - aAsDependency ); - - iPlan.InsertL( newEntry, aAt ); - CleanupStack::Pop( newEntry ); - newEntry = NULL; - - return ETrue; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::CreateDefaultPlanEntryL -// -// --------------------------------------------------------------------------- -// -CDiagExecPlanEntryImpl* CDiagPluginExecPlanImpl::CreateDefaultPlanEntryLC( - MDiagPlugin& aPlugin, - TBool aAsDependency ) const - { - CDiagExecPlanEntryImpl* newEntry = NULL; - - if ( aPlugin.Type() == MDiagPlugin::ETypeTestPlugin ) - { - newEntry = static_cast< CDiagExecPlanEntryImpl* >( - CDiagExecPlanEntryImplTest::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagTestPlugin& >( aPlugin ), - aAsDependency, - CDiagResultsDatabaseItem::EQueuedToRun ) ); - } - else - { - newEntry = static_cast< CDiagExecPlanEntryImpl* >( - CDiagExecPlanEntryImplSuite::NewLC( - iEngine, - iEngineConfig, - iPlanEntryObserver, - static_cast< MDiagSuitePlugin& >( aPlugin ), - aAsDependency, - CDiagExecPlanEntryImpl::ETypeSuiteUnexpanded ) ); - } - - return newEntry; - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::LogPlan -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::LogPlanL() const - { - #ifdef _DEBUG - LOGSTRING( "CDiagPluginExecPlanImpl::LogPlan(): Plan Dump." ) - for ( TInt i = 0; i < iPlan.Count(); i++ ) - { - HBufC* pluginName = iPlan[i]->Plugin().GetPluginNameL( - MDiagPlugin::ENameLayoutListSingle ); - - LOGSTRING5( "Plan Entry: Id = 0x%08x, %s, Dep=[%s], Name = %S", - iPlan[i]->Plugin().Uid().iUid, - ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuitePrepare ? L"<" : - ( iPlan[i]->Type() == CDiagExecPlanEntryImpl::ETypeSuiteFinalize ? L">" : L" " ) ), - ( iPlan[i]->AsDependency() ? L"*" : L" " ), - pluginName ) - - delete pluginName; - } - #endif // _DEBUG - } - -// --------------------------------------------------------------------------- -// CDiagPluginExecPlanImpl::LogPlanInRecordL -// --------------------------------------------------------------------------- -// -void CDiagPluginExecPlanImpl::LogPlanInRecordL() const - { - #ifdef _DEBUG - - LOGSTRING( "CDiagPluginExecPlanImpl::LogPlanInRecord()" ) - - RPointerArray< CDiagResultsDatabaseItem > results; - DiagFwInternal::CleanupRPointerArrayPushL< CDiagResultsDatabaseItem >( &results ); - User::LeaveIfError( - iEngine.DbRecord().GetTestResults( results ) ); - - TInt resultCount = results.Count(); - - LOGSTRING2( " Result Count = %d", resultCount ) - - for ( TInt i = 0; i < resultCount; i++ ) - { - LOGSTRING4( " Test UID = 0x%08x, Result = %d, Dep = %d", - results[i]->TestUid().iUid, - results[i]->TestResult(), - results[i]->WasDependency() ) - } - - CleanupStack::PopAndDestroy( &results ); - - #endif // _DEBUG - } - -// End of File -