devicediagnosticsfw/diagframework/inc/diagpluginexecplanimpl.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:07:52 +0200
changeset 0 b497e44ab2fc
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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 declaration for CDiagPluginExecPlanImpl
*
*/


#ifndef DIAGPLUGINEXECPLANIMPL_H
#define DIAGPLUGINEXECPLANIMPL_H

// SYSTEM INCLUDE FILES
#include <e32base.h>                    // CBase
#include <DiagPluginExecPlan.h>         // MDiagPluginExecPlan
#include <DiagResultsDatabaseItem.h>    // CDiagResultsDatabaseItem::TResult

// USER INCLUDE FILES
#include "diagexecplanentryimpl.h"      // TDiagPluginExecPlanImpl::TType

// FORWARD DECLARATION
class MDiagPlugin;
class MDiagSuitePlugin;
class MDiagEngineCommon;
class CDiagPluginPool;
class RDiagResultsDatabaseRecord;
class TDiagEngineConfig;
struct TTransitionStackEntry;

template <class T, TBool StackOwnsEntry>
class CStack;

/**
*  Diagnostics Plugin Execution Plan
*
*  This class provides interface to access execution plan.
*  It also provides interface to modify execution plan.
*  A cursor to currently executing item is also maintained.
*
* @since S60 v5.0
*
*/
NONSHARABLE_CLASS( CDiagPluginExecPlanImpl ) : public CActive,
                                               public MDiagPluginExecPlan
    {
public: 
    /**
    * Two-phase constructor
    *
    * @param aEngine - Reference to diagnostics engine.
    * @param aEngineConfig - Engine configuration information.
    * @param aEntryObserver - Reference to entry observer.
    * @return new instance of CDiagPluginExecPlanImpl
    */
    static CDiagPluginExecPlanImpl* NewL( MDiagEngineCommon& aEngine,
                                          const TDiagEngineConfig& aEngineConfig,
                                          MDiagExecPlanEntryImplObserver& aEntryObserver );

    /**
    * Destructor.
    */
    virtual ~CDiagPluginExecPlanImpl();

public:     // New API
    /**
    * Initialize execution plan
    *
    * @param aStatus - Request status to set when plan creatation is completed.
    * @param aBatch - list of plug-ins to execute
    */
    void InitializeL( TRequestStatus& aStatus, 
                      const RPointerArray< MDiagPlugin >& aBatch );

    /**
    * Initialize execution plan from db.
    *   This will read current data from results database and reconstruct
    *   the execution plan.
    *
    *   This should be used to continue an incomplete session.
    *
    * @param aStatus - Request status to set when plan creatation is completed.
    */
    void InitializeL( TRequestStatus& aStatus );

    /**
    * Access an item in plan. 
    *
    * @param aIndex    - index 
    * @return Reference to plan entry at given index.
    */
    CDiagExecPlanEntryImpl& operator[]( TInt aIndex );      //lint !e1411  This is proper overload

    /**
    * Get current execution plan item.
    *
    * @return Reference to currently executing plan item.
    */
    CDiagExecPlanEntryImpl& CurrentExecutionItem();         //lint !e1411  This is proper overload

    /**
    * Reset execution cursor
    * 
    * Resets execution cursor to the beginning.
    */
    void ResetExecutionCursor();

    /**
    * Moves execution cursor to next item.
    *
    * @return ETrue if cursor is updated.
    *         EFalse if cursor is already at last item.
    */
    TInt MoveCursorToNext();

private:     // from CActive
    /**
    * Handle Active Object completion event.
    * @see CActive::RunL()
    */
    virtual void RunL();

    /**
    * Cancel outstanding request
    * @see CActive::RunL()
    */
    virtual void DoCancel();

    /**
    * Handle errors
    * @see CActive::RunError()
    */
    virtual TInt RunError( TInt aError );

public:     // from MDiagPluginExecPlan
    /**
    * Access an item in plan.
    *   @see MDiagPluginExecPlan::operator[]
    */
    virtual const MDiagExecPlanEntry& operator[]( TInt aIndex ) const;

    /**
    * Get current execution plan item.
    *   @see MDiagPluginExecPlan::CurrentExecutionItem
    */
    virtual const MDiagExecPlanEntry& CurrentExecutionItem() const;

    /**
    * Returns index of execution cursor. 
    *   @see MDiagPluginExecPlan::CurrentIndex
    */
    virtual TInt CurrentIndex() const;

    /**
    * Returns total number of items in the plan.
    *   @see MDiagPluginExecPlan::Count
    */
    virtual TInt Count() const;

    /**
    * Get current test index.
    *
    *   @see MDiagPluginExecPlan::CurrentTestIndex
    */
    virtual TInt CurrentTestIndex( TBool aIncludeDependency ) const;

    /**
    * Get total test count.
    *
    *   @see MDiagPluginExecPlan::TestCount
    */
    virtual TInt TestCount( TBool aIncludeDependency ) const;

    /**
    * Check if this is the last test being executed.
    *
    *   @see MDiagPluginExecPlan::IsLastTest
    */
    virtual TBool IsLastTest() const;

    /**
    * Check if this is the last plug-in being executed.
    *
    *   @see MDiagPluginExecPlan::IsLastPlugin
    */
    virtual TBool IsLastPlugin() const;

    /**
    * Returns the plug-in index that plan is resuming from.
    *
    *   @see MDiagPluginExecPlan::ResumeIndex
    */
    virtual TInt ResumeIndex() const;

private: // private data types
    /**
    * State
    */
    enum TState
        {
        EStateIdle  = 0,
        EStateExpandDependencyAndSuites,
        EStateRemoveEmptySuites,
        EStateInsertSuiteTransitions,
        EStateStoreToDb,
        EStatePlanCreated
        };

private: // private functions
    /**
    * C++ Constructor
    * @param aEngine - reference to engine.
    * @param aEngineConfig - reference to engine configuration information.
    * @param aEntryObserver - Reference to observer for each plug-in
    */
    CDiagPluginExecPlanImpl( MDiagEngineCommon& aEngine,
                             const TDiagEngineConfig& aEngineConfig,
                             MDiagExecPlanEntryImplObserver& aEntryObserver );

    /**
    * Symbian 2nd phase constructor
    */
    void ConstructL();

    /**
    * Change state
    *   @param aState - new state.
    */    
    void ChangeState( TState aState );

    /**
    * Plan creation phase 1. Expand dependencies
    *
    * @return ETrue if any changes are made to the plan.
    */
    TBool ExpandDependenciesL();

    /**
    * Plan creation phase 2. Expand suites to plug-ins
    *
    * @return ETrure if any changes are made to the plan
    */
    TBool ExpandSuitesL();

    /**
    * Plan creation phase 3. Remove empty suites. Delete plan entries that
    * just has prepare and finalize without any tests in between.
    *
    */
    void RemoveEmptySuites();

    /**
    * Plan creation phase 4. Insert suite transition based on parent
    *
    */
    void InsertSuiteTransitionsL();

    /**
    * Store next test plan item to database. Part of STEP_6.
    *
    */
    void StoreNextTestPluginToDbL();
    
    /**
    * Plan creation step 7. Prepend items from last session to new plan.
    */
    void PrependExecutedItemsL();

    /**
    * Report result to client.
    * 
    * @param aErr - Result to report back to engine. KErrNone if successful.
    *   
    */
    void ReportResult( TInt aErr );

    /**
    * Insert plugin
    *
    * This function will attempt to add a plugin into plan. 
    * If item already exists in the plan prior to the given index, it will
    * not add a new item. 
    * If item exists after the given index, and the item is a dependent item, it will
    * move it up in the plan, so that it will be executed earlier.
    * If item exists after the given index, and the item is not a dependent item, 
    * it will create a duplicate entry, to make sure that client specified order
    * is not changed.
    *
    * @param aPlugin - Plugin to insert
    * @param aAsDependent - whether new item is to satify dependency or not.
    * @param aAt - index to insert the dependent item to.
    * @return ETrue if plan is updated. EFalse if no changes to plan is made.
    */
    TBool InsertPluginL( MDiagPlugin& aPlugin,
                         TBool aAsDependent, 
                         TInt aAt );

    /**
    * Utility function to create a default execution plan entry
    *   For test plug-ins, it will create an entry with EQueueToRun as status.
    *   For suite plug-ins, it will create an entry with ETypeSuiteUnexpanded as type.
    *
    * @param aPlugin - Plugin to create default entry for. Either test or suite plug-in.
    * @param aAsDependency - Whether the entry should be created as dependency or not.
    *
    * @return New execution plan entry. Ownership is transferred.
    */
    CDiagExecPlanEntryImpl* CreateDefaultPlanEntryLC(
            MDiagPlugin& aPlugin,
            TBool aAsDependency ) const;

    /**
    * Utility function to add root suite if it does not alredy exists 
    * in the plan. 
    * 
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    */
    void AddRootSuiteIfMissingL();

    /**
    * Utility function to push new transition into stack.
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    *
    * @param aStack - Stack to push new transition to.
    * @Param aHeadIndex - index in execution plan to head entry.
    */
    void PushNewLevelL( CStack<TTransitionStackEntry, ETrue>& aStack, TInt aHeadIndex );

    /**
    * Utility function to pop a level from stack. This will remove top entry
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    *
    * @param aStack - Stack to pop the head item from.
    */
    void PopLevel( CStack<TTransitionStackEntry, ETrue>& aStack );

    /**
    * Utility function to check if given level exists in stack
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    *
    * @param aStack - Stack to check levels in.
    * @param aLevelUid - Uid of leven to check in stack.
    * 
    * @return ETrue if item exists in stack. EFalse if not found.
    */
    TBool IsLevelInStack( CStack<TTransitionStackEntry, ETrue>& aStack, TUid aLevelUid ) const;

    /**
    * Utility function to check if there is more of items of the same parent
    * exists in the plan.
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    * 
    * @param aParentUid - Uid of suite to search for.
    * @param aIndex - Index to execution plan to start searching for.
    * @return ETrue if given suite is still needed.
    *   EFalse otherwise.
    */
    TBool IsThisSuiteNeededAfterThisIndex( TUid aSuiteUid, TInt aIndex ) const;

    /**
    * Utility function to add a SuitePrepare entry into plan.
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    *
    * @param aLevelUid - Uid of suite to add in plan.
    * @param aAt - Index in plan to add new prepare entry to.
    */
    void AddSuitePrepareL( TUid aLevelUid, TInt aAt );

    /**
    * Utility function to add a SuiteFinalize entry into plan.
    *
    * NOTE: This should be called only from InsertSuiteTransitionsL()
    *
    * @param aPrepareIndex - location in plan where prepare is at. Some information
    *   from prepare item will be copied to finalize.
    * @param aAt - Index in execution plan to add finalize entry to.
    */
    void AddSuiteFinalizeL( TInt aPrepareIndex, TInt aAt );
    
    /**
    * Log plan information to debug log. This function does nothing in release build.
    */
    void LogPlanL() const;

    /**
    * Debug function that validate that entries are written to db correctly.
    * This function does nothing in release build.
    */
    void LogPlanInRecordL() const;

private: // data

    /**
    * iPlan - holds plan entries
    * Individual entries are owned by the array.
    */
    RPointerArray<CDiagExecPlanEntryImpl> iPlan;

    /**
    * iExecutedEntries  - Items that are already executed in the
    * previous session.
    * Individual entries are owned by the array.
    */
    RPointerArray<CDiagExecPlanEntryImpl> iExecutedEntries;

    /**
    * iExecutionCursor - currently executing item.
    */
    TInt iExecutionCursor;

    /**
    * iResumeIndex - Index which session is being resumed from.
    */
    TInt iResumeIndex;

    /**
    * iEngine - Reference to diag engine.
    */
    MDiagEngineCommon& iEngine;

    /**
    * iEngineConfig - Enine configuration information.
    */
    const TDiagEngineConfig& iEngineConfig;

    /**
    * iPlanEntryObserver - Plan entry observer. Passed to each plan entry
    *    when it is created.
    */
    MDiagExecPlanEntryImplObserver& iPlanEntryObserver;

    /**
    * iClientStatus - TRequestStatus of the client. Used to notify
    * completion and error.
    * Ownership - Does not own.
    */
    TRequestStatus* iClientStatus;

    /**
    * iState - state of the execution plan creation.
    *   @see TState
    */
    TState iState;
    };

#endif // DIAGPLUGINEXECPLANIMPL_H


// End of File