devicediagnostics/devdiagapp/src/devdiagexecutionresults.cpp
changeset 0 3ce708148e4d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devicediagnostics/devdiagapp/src/devdiagexecutionresults.cpp	Thu Dec 17 08:40:12 2009 +0200
@@ -0,0 +1,706 @@
+/*
+* 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:  This class encapsulates test results from live execution runs
+*                as well as logged results and presents a common interface for
+*                both.
+*
+*/
+
+
+// System Include Files
+#include <centralrepository.h>                  // CRepository
+#include <drmserviceapi.h>                      // CDrmServiceApi
+#include <DiagEngineCommon.h>                   // MDiagEngineCommon
+#include <DiagPluginExecPlan.h>                 // CDiagPluginExecPlan
+#include <DiagExecPlanEntry.h>                  // MDiagExecPlanEntry
+#include <DiagResultsDatabaseItem.h>            // CDiagResultsDatabaseItem
+#include <DiagPlugin.h>                         // MDiagPlugin
+#include <DiagTestPlugin.h>                     // MDiagTestPlugin
+#include <DiagPluginPool.h>                     // CDiagPluginPool
+#include <DiagResultsDatabaseTestRecordInfo.h>  // TDiagResultsDatabaseTestRecordInfo
+#include <DiagResultsDbRecordEngineParam.h>     // CDiagResultsDbRecordEngineParam
+#include <DiagResultsDatabase.h>                // RDiagResultsDatabase,
+                                                // RDiagResultsDatabaseRecord
+#include <DiagFrameworkDebug.h>                 // Debugging Macros
+
+// User Include Files
+#include "devdiagexecutionresults.h"                 // CDevDiagExecResults
+#include "devdiagapp.hrh"                    // UID definition
+#include "devdiag.pan"                    // Panic
+#include "devdiagprivatecrkeys.h"           // CR Key ID Definitions
+
+// Local Constants
+///@@@KSR: changes for BAD Warnings - #177-D: variable "KRecordsArrayGranularity" was declared but never referenced
+//const TInt KRecordsArrayGranularity = ( 5 );
+
+// Local Data Types
+typedef CArrayFixFlat< TDiagResultsDatabaseTestRecordInfo > CDatabaseRecordInfoArray;
+
+
+// ============================ MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Static two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult* CDevDiagExecResults::CResult::NewL(
+    const MDiagPlugin& aPlugin )
+    {
+    CResult* self = CResult::NewLC( aPlugin );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Static two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult* CDevDiagExecResults::CResult::NewLC(
+    const MDiagPlugin& aPlugin )
+    {
+    CResult* self = new ( ELeave ) CResult( aPlugin );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult::~CResult()
+    {
+    delete iResult;
+    iResult = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Return the test result.  This may be NULL if the test has not been run.
+// ---------------------------------------------------------------------------
+//
+const CDiagResultsDatabaseItem* CDevDiagExecResults::CResult::Result() const
+    {
+    return iResult;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Return a reference to the plugin for this result.
+// ---------------------------------------------------------------------------
+//
+const MDiagPlugin& CDevDiagExecResults::CResult::Plugin() const
+    {
+    return iPlugin;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Return the execution error code.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::CResult::ExecStatus() const
+    {
+    return iExecStatus;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Return the current execution step for this result.
+// ---------------------------------------------------------------------------
+//
+TUint CDevDiagExecResults::CResult::CurrentStep() const
+    {
+    return iCurrentStep;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Return the total execution steps for this result.
+// ---------------------------------------------------------------------------
+//
+TUint CDevDiagExecResults::CResult::TotalSteps() const
+    {
+    return iTotalSteps;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// This function takes ownership of a result object.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::CResult::SetResult(
+    CDiagResultsDatabaseItem* aResult,
+    TInt aError )
+    {
+    // Sanity check.
+    if ( iResult )
+        {
+        delete iResult;
+        }
+
+    // Set the result and error code Ownership of the result is transferred.
+    iResult = aResult;
+    iExecStatus = aError;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// Set the progress information for this result.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::CResult::SetProgress( TUint aCurrentStep,
+                                                TUint aTotalSteps )
+    {
+    iCurrentStep = aCurrentStep;
+    iTotalSteps = aTotalSteps;
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// The default constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult::CResult( const MDiagPlugin& aPlugin )
+:   iPlugin( aPlugin )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// From nested class CDevDiagExecResults::CResult.
+// The second phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::CResult::ConstructL()
+    {
+    }
+
+
+// ============================ MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------------------------
+// Static two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults* CDevDiagExecResults::NewL(
+    TUid aRecordId,
+    CDiagPluginPool& aPluginPool,
+    RDiagResultsDatabase& aDbSession )
+    {
+    LOGSTRING2( "CDevDiagExecResults::NewL( %d )", aRecordId.iUid )
+
+    CDevDiagExecResults* self = new ( ELeave ) CDevDiagExecResults(
+        aRecordId,
+        aPluginPool,
+        aDbSession );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Static two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults* CDevDiagExecResults::NewL(
+    TUid aRecordId,
+    CDiagPluginPool& aPluginPool,
+    RDiagResultsDatabase& aDbSession,
+    TUid aExecutedUid,
+    MDiagEngineCommon* aDiagEngine )
+    {
+    LOGSTRING3( "CDevDiagExecResults::NewL( %d, 0x%x )",
+                aRecordId.iUid,
+                aDiagEngine )
+
+    CDevDiagExecResults* self = new ( ELeave ) CDevDiagExecResults(
+        aRecordId,
+        aPluginPool,
+        aDbSession,
+        aExecutedUid,
+        aDiagEngine );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::~CDevDiagExecResults()
+    {
+    LOGSTRING( "CDevDiagExecResults::~CDevDiagExecResults()" )
+    iResults.ResetAndDestroy();
+    }
+
+// ---------------------------------------------------------------------------
+// This function is called during live execution to transfer ownership of a
+// test result.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::AddEntryL( CDiagResultsDatabaseItem* aResult,
+                                     TInt aStatus )
+    {
+    LOGSTRING3( "CDevDiagExecResults::AddEntryL( 0x%x, %d )",
+                aResult,
+                aStatus )
+
+    // This is only valid for live executions.
+    if ( iType != ETypeExecution )
+        {
+        delete aResult;
+        User::Leave( KErrCompletion );
+        }
+
+    // Assign the result object to the corresponding item in the local array.
+    iResults[ CurrentIndexL() ]->SetResult( aResult, aStatus );
+
+    // Update the completed step counter.
+    if ( iResults[ CurrentIndexL() ]->Plugin().Type() ==
+        MDiagPlugin::ETypeTestPlugin )
+        {
+        iCompletedSteps += static_cast< const MDiagTestPlugin& >(
+            iResults[ CurrentIndexL() ]->Plugin() ).TotalSteps();
+
+        if ( aResult && ( aResult->TestResult() ==
+                            CDiagResultsDatabaseItem::EFailed ||
+                          aResult->TestResult() ==
+                            CDiagResultsDatabaseItem::EDependencyFailed ) )
+            {
+            iFailedCount++;
+            }
+        
+        if ( aResult && ( aResult->TestResult() ==
+                            CDiagResultsDatabaseItem::ESuccess) )
+            {
+            iPassedCount++;
+            }
+        }
+    iCurrentPluginStep = 0;
+    }
+
+// ---------------------------------------------------------------------------
+// This function is called during live execution to transfer ownership of a
+// test result.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::SetProgressL( TUint aCurrentStep, TUint aTotalSteps )
+    {
+    LOGSTRING3( "CDevDiagExecResults::SetProgressL( %d, %d )",
+            aCurrentStep,
+            aTotalSteps )
+
+    // This is only valid for live executions.
+    if ( iType != ETypeExecution )
+        {
+        return;
+        }
+
+    // Assign the progress to the corresponding item in the local array.
+    iResults[ CurrentIndexL() ]->SetProgress( aCurrentStep, aTotalSteps );
+
+    // Update the current step counter.
+    if ( iResults[ CurrentIndexL() ]->Plugin().Type() ==
+        MDiagPlugin::ETypeTestPlugin )
+        {
+        iCurrentPluginStep = aCurrentStep;
+        }
+    else
+        {
+        iCurrentPluginStep = 0;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the corresponding results item from the local array.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult& CDevDiagExecResults::operator[] ( TInt aIndex )
+    {
+    return *iResults[ aIndex ];
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the corresponding results item from the local array.
+// ---------------------------------------------------------------------------
+//
+const CDevDiagExecResults::CResult& CDevDiagExecResults::operator[] (
+    TInt aIndex ) const
+    {
+    return *iResults[ aIndex ];
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the current item from the local array.  For results
+// which are from execution, this is the current execution item.  For results
+// which are from the database, this is always the last item.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CResult& CDevDiagExecResults::CurrentItemL()
+    {
+    return *iResults[ CurrentIndexL() ];
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the current item from the local array.  For results
+// which are from execution, this is the current execution item.  For results
+// which are from the database, this is always the last item.
+// ---------------------------------------------------------------------------
+//
+const CDevDiagExecResults::CResult& CDevDiagExecResults::CurrentItemL() const
+    {
+    return *iResults[ CurrentIndexL() ];
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the number of items in the local array.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::Count() const
+    {
+    return iResults.Count();
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the index of the currently-executing item.
+// ---------------------------------------------------------------------------
+//
+TUint CDevDiagExecResults::CurrentIndexL() const
+    {
+    // For live execution, the index from the execution plan is returned.
+    if ( iType == ETypeExecution )
+        {
+        TUint index = 0;
+        index = iDiagEngine->ExecutionPlanL().CurrentIndex();
+        return index;
+        }
+
+    // For logged test results, the last index is returned.
+    return iResults.Count() - 1;
+    }
+
+// ---------------------------------------------------------------------------
+// This utility function allows the result view to check if testing is
+// complete but the diagnostics engine has not yet reported testing as
+// finished.
+// ---------------------------------------------------------------------------
+//
+TBool CDevDiagExecResults::LastTestFinishedL() const
+    {
+    if ( !iDiagEngine ||
+         ( iDiagEngine->ExecutionPlanL().IsLastTest() &&
+           ( iResults[ iLastTestIndex ] )->Result() ) )
+        {
+        return ETrue;
+        }
+
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// This utility function checks to see if a test is being executed / was
+// executed as a dependency.
+// ---------------------------------------------------------------------------
+//
+TBool CDevDiagExecResults::IsDependencyL( TInt aIndex ) const
+    {
+    //__ASSERT_ALWAYS( ( aIndex < Count() ), Panic( EDevDiagApplicationGeneral ) );
+
+    // For live execution, get the information from the execution plan.
+    if ( iType == ETypeExecution )
+        {
+        TBool dependent = EFalse;
+        dependent = iDiagEngine->ExecutionPlanL()[ aIndex ].AsDependency();
+        return dependent;
+        }
+
+    // For logged test results, get the information from the test result.  The
+    // NULL check is needed in case the plugin failed during running and did
+    // not report a result.
+    if ( iResults[ aIndex ]->Result() )
+        {
+        return iResults[ aIndex ]->Result()->WasDependency();
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Returns whether or not the results are from a completed test record.  This
+// information is used to determine the validity of the session's "end time."
+// ---------------------------------------------------------------------------
+//
+TBool CDevDiagExecResults::IsRecordCompleted() const
+    {
+    return iCompleted;
+    }
+
+// ---------------------------------------------------------------------------
+// This function locks "execution" style results from further changes, by
+// changing the results type and clearing the reference to the engine.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::Finalize( TBool aTestingComplete )
+    {
+    LOGSTRING( "CDevDiagExecResults::Finalize()" )
+
+    iDiagEngine = NULL;
+    iType = ETypeLog;
+    iCompletedSteps = iTotalSteps;
+    iCurrentPluginStep = 0;
+    iCompleted = aTestingComplete;
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the total number of steps for all items in the
+// execution results.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::TotalExecutionSteps() const
+    {
+    return iTotalSteps;
+    }
+
+// ---------------------------------------------------------------------------
+// This function returns the current execution step based on all items in the
+// execution results.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::CurrentExecutionStep() const
+    {
+    return iCompletedSteps + iCurrentPluginStep;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns a reference to the plugin that execution was requested for.
+// ---------------------------------------------------------------------------
+//
+const MDiagPlugin& CDevDiagExecResults::ExecutedPluginL() const
+    {
+    LOGSTRING( "CDevDiagExecResults::ExecutedPluginL()" )
+
+    MDiagPlugin* plugin = NULL;
+    User::LeaveIfError( iPluginPool.FindPlugin( iExecutedPlugin, plugin ) );
+
+    return *plugin;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns whether or not the execution is for a single plugin.
+// ---------------------------------------------------------------------------
+//
+TBool CDevDiagExecResults::SinglePluginExecutionL() const
+    {
+    if ( !iDiagEngine )
+        {
+        return EFalse;
+        }
+    
+    return ( iDiagEngine->ExecutionPlanL().TestCount( EFalse ) == 1 );
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the number of failed tests in this set of results.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::FailedResultsCount() const
+    {
+    return iFailedCount;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns the number of passed tests in this set of results.
+// ---------------------------------------------------------------------------
+//
+TInt CDevDiagExecResults::PassedResultsCount() const
+    {
+    return iPassedCount;
+    }
+
+// ---------------------------------------------------------------------------
+// Returns whether or not the execution plan's resume index has been reached.
+// ---------------------------------------------------------------------------
+//
+TBool CDevDiagExecResults::ResumeIndexReachedL() const
+    {
+    if ( !iDiagEngine )
+        {
+        return ETrue;
+        }
+
+    return ( iDiagEngine->ExecutionPlanL().CurrentIndex() >=
+        iDiagEngine->ExecutionPlanL().ResumeIndex() );
+    }
+
+// ---------------------------------------------------------------------------
+// Returns the UID of the record associated with this set of results.
+// ---------------------------------------------------------------------------
+//
+const TUid& CDevDiagExecResults::RecordId() const
+    {
+    return iRecordId;
+    }
+
+// ---------------------------------------------------------------------------
+// The default constructor.
+// ---------------------------------------------------------------------------
+//
+CDevDiagExecResults::CDevDiagExecResults( TUid aRecordId,
+                                          CDiagPluginPool& aPluginPool,
+                                          RDiagResultsDatabase& aDbSession,
+                                          TUid aExecutedUid,
+                                          MDiagEngineCommon* aDiagEngine )
+:   iRecordId( aRecordId ),
+    iPluginPool( aPluginPool ),
+    iDbSession( aDbSession ),
+    iDiagEngine( aDiagEngine ),
+    iExecutedPlugin( aExecutedUid )
+    {
+    LOGSTRING3( "CDevDiagExecResults::CDevDiagExecResults( %d, 0x%x )",
+                aRecordId.iUid,
+                aDiagEngine )
+
+    }
+
+// ---------------------------------------------------------------------------
+// The second phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CDevDiagExecResults::ConstructL()
+    {
+    LOGSTRING( "CDevDiagExecResults::ConstructL()" )
+
+    // There are two types of results: (1) Current Execution, and (2) Logs.
+
+    // (1) If a pointer to the diagnostics engine was provided, then it is
+    // assumed that the results are from a live execution and this object will
+    // wait for the results to be assigned .
+    if ( iDiagEngine )
+        {
+        // This is the "current execution" type.
+        iType = ETypeExecution;
+        const MDiagPluginExecPlan& execPlan = iDiagEngine->ExecutionPlanL();
+
+        // Add an entry for every item in the plan.
+        TUint numItems = execPlan.Count();
+        for ( TUint i = 0; i < numItems; i++ )
+            {
+            CResult* result = CResult::NewLC( execPlan[ i ].Plugin() );
+            iResults.AppendL( result );
+            CleanupStack::Pop( result );
+
+            // Update the total step counter with this plugin's information.
+            if ( execPlan[ i ].Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
+                {
+                iTotalSteps += static_cast< const MDiagTestPlugin& >(
+                    execPlan[ i ].Plugin() ).TotalSteps();
+                iLastTestIndex = i;
+                }
+            }
+        }
+    // (2) If no pointer to the diagnostics engine was provided, then all the
+    // results which correspond to the record id will be looked up from the
+    // results database.
+    else
+        {
+        // This is the "logged" type.
+        iType = ETypeLog;
+
+        // Get the record's results from the database.
+        RDiagResultsDatabaseRecord dbRecord;
+        User::LeaveIfError( dbRecord.Connect( iDbSession, iRecordId, ETrue ) );
+        CleanupClosePushL( dbRecord );
+        User::LeaveIfError( dbRecord.IsTestCompleted( iCompleted ) );
+        RPointerArray< CDiagResultsDatabaseItem > logResults;
+        CleanupClosePushL( logResults );
+        User::LeaveIfError( dbRecord.GetTestResults( logResults ) );
+
+        // Add an entry for each result item.
+        TUint numItems = logResults.Count();
+        for ( TUint i = 0; i < numItems; i++ )
+            {
+            MDiagPlugin* plugin = NULL;
+            TInt err = iPluginPool.FindPlugin( logResults[ i ]->TestUid(),
+                                               plugin );
+
+            // If a matching plugin was not found for this result, we just
+            // skip over it, because we can't do anything useful with it.
+            // This case should only occur if a plugin logged results
+            // previously, but was later removed from the phone.
+            if ( err != KErrNone )
+                {
+                continue; //lint !e960 A continue makes sense here.
+                }
+
+            CResult* result = CResult::NewLC( *plugin );
+
+            // Ownership of the results item is transferred.
+            result->SetResult( logResults[ i ], KErrNone );
+            logResults[ i ] = NULL;
+
+            // Get the test result.
+            if ( result->Result()->TestResult() ==
+                    CDiagResultsDatabaseItem::EFailed ||
+                 result->Result()->TestResult() ==
+                    CDiagResultsDatabaseItem::EDependencyFailed )
+                {
+                iFailedCount++;
+                }
+
+            iResults.AppendL( result );
+            CleanupStack::Pop( result );
+            }
+        iLastTestIndex = numItems - 1;
+
+        CleanupStack::Pop(); // logResults
+        logResults.ResetAndDestroy();
+
+        // Get the uid of the executed test.
+        CDiagResultsDbRecordEngineParam* execParam;
+        User::LeaveIfError( dbRecord.GetEngineParam( execParam ) );
+        iExecutedPlugin = execParam->ExecutionsUidArray()[ 0 ];
+        delete execParam;
+
+        CleanupStack::PopAndDestroy(); // dbRecord
+
+        // Set dummy numbers for the execution steps.
+        iTotalSteps = 1;
+        iCompletedSteps = 1;
+        }
+    }
+    
+    
+
+ const CDiagResultsDatabaseItem* CDevDiagExecResults::GetSinglepluginExecutionResult() const
+    {
+    
+    	return iResults[ iLastTestIndex ]->Result();
+    	/*
+    	CDiagResultsDatabaseItem* aResult;
+    	const CDevDiagExecResults::CResult& result = CDevDiagExecResults::CurrentItemL();
+    	aResult = result.Result();
+    	return aResult;*/
+    	
+    }
+// End of File