diff -r 000000000000 -r 3ce708148e4d devicediagnostics/devdiagapp/src/devdiagengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/devicediagnostics/devdiagapp/src/devdiagengine.cpp Thu Dec 17 08:40:12 2009 +0200 @@ -0,0 +1,1188 @@ +/* +* 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: Engine implementation +* +*/ + + +// System Include Files +#include // User +#include // RFs +#include // CDiagEngine +#include // MDiagPlugin +#include // MDiagSuitePlugin +#include // CDiagResultsDatabaseItem +#include // CDiagPluginPool +#include + // TDiagResultsDatabaseTestRecordInfo +#include // CDrmServiceApi +#include // RProperty +#include // Property values +#include // Property values +#include // CRepository +#include // CR Keys for Profile +#include // Debug Logger +#include + +// User Include Files +#include "devdiagapp.hrh" // UID definition +#include "devdiagengine.h" // CDevDiagEngine +#include "devdiagengineobserver.h" // CDevDiagEngineObserver +#include "devdiagexecutionresults.h" // CDevDiagExecResults +#include "devdiag.pan" // Panic +#include "devdiagcommoncanceldialogs.h" // CDevDiagCancelExecutionDialog +#include "devdiagcommonskipdialogs.h" +// Local Constants +const TInt KErrDevDiagAlreadyInitialized = ( -1 ); +const TInt KErrDevDiagAlreadyLoaded = ( -2 ); +const TInt KErrDevDiagUninitialized = ( -3 ); + +///@@@KSR: changes for BAD Warnings - #177-D: variable "KErrDevDiagExecuting" was declared but never referenced +//const TInt KErrDevDiagExecuting = ( -4 ); + +const TInt KErrDevDiagAlreadyRunning = ( -5 ); +const TInt KErrDevDiagNotRunning = ( -6 ); +const TInt KErrDevDiagSuspendResume = ( -7 ); +const TUid KUidDevDiagApplication = { _UID3 }; +///@@@KSR: changes for BAD Warnings - #177-D: variable "KProgressGranularity" was declared but never referenced +//const TInt KProgressGranularity = ( 2 ); + +// Local Data Types +typedef CArrayFixFlat< TDiagResultsDatabaseTestRecordInfo > CDatabaseRecordInfoArray; + +const TInt KArrayGranuality(50); + + +// ============================ MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// Static two-phase constructor. +// --------------------------------------------------------------------------- +// +CDevDiagEngine* CDevDiagEngine::NewL() + { + LOGSTRING( "CDevDiagEngine::NewL()" ) + + CDevDiagEngine* self = CDevDiagEngine::NewLC(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Static two-phase constructor. +// --------------------------------------------------------------------------- +// +CDevDiagEngine* CDevDiagEngine::NewLC() + { + LOGSTRING( "CDevDiagEngine::NewLC()" ) + + CDevDiagEngine* self = new ( ELeave ) CDevDiagEngine(); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CDevDiagEngine::~CDevDiagEngine() + { + LOGSTRING( "CDevDiagEngine::~CDevDiagEngine()" ) + + // Cancel any outstanding asynchronous requests. + Cancel(); + + // Delete the member variables. + delete iResults; + delete iDiagEngine; + delete iPluginPool; + + if ( iUids ) + { + delete iUids; + iUids = NULL; + } + + iLastResults.ResetAndDestroy(); + iLastResults.Close(); + + // Close the session with the results database. + iResultsDatabase.Close(); + } + + +// --------------------------------------------------------------------------- +// This function allows the UI to receive application engine callbacks by +// implementing the MDevDiagEngineObserver interface. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::SetObserver( MDevDiagEngineObserver* aObserver ) + { + LOGSTRING2( "CDevDiagEngine::SetObserver( 0x%x )", aObserver ) + + if ( iObserver && aObserver ) + { + // We have cannot leave here. + TRAP_IGNORE( iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandObserverChanged, + KErrNone, + NULL ) ) + } + + iObserver = aObserver; + } + +// --------------------------------------------------------------------------- +// This function begins test execution. It is the responsibility of the +// caller to check the runtime requirements prior to calling this function. +// This is an asynchronous request. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::ExecuteTestL( TUid aUid, CAknViewAppUi& aAppUi ) + { + LOGSTRING2( "CDevDiagEngine::ExecuteTestL( 0x%x )", aUid.iUid ) + + // Reset the member variables to prepare for a new execution run. + delete iDiagEngine; + iDiagEngine = NULL; + delete iResults; + iResults = NULL; + iSuspendCounter = 0; + + RArray< TUid > uidArray; + uidArray.Append( aUid ); + CleanupClosePushL( uidArray ); + + // Create an engine instance and execute the test or suite. + iDiagEngine = CDiagEngine::NewL( aAppUi, + *this, + iResultsDatabase, + *iPluginPool, + EFalse, + uidArray ); + CleanupStack::PopAndDestroy(); // uidArray + iDiagEngine->ExecuteL(); + + // Do the state transition now that we are successfully starting. + SetState( EStateStartingExecution ); + } + +// --------------------------------------------------------------------------- +// This function will provides the execution results, which may be from an +// execution run which is ongoing, or from logged test results. +// --------------------------------------------------------------------------- +// +const CDevDiagExecResults& CDevDiagEngine::ExecutionResults() const + { + LOGSTRING( "CDevDiagEngine::ExecutionResults()" ) + + __ASSERT_ALWAYS( HasExecutionResults(), + Panic( EDevDiagApplicationNotInitialized ) ); + return *iResults; + } + +// --------------------------------------------------------------------------- +// This function will handle getting the results information for the most +// recent test execution. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::LoadLastLoggedResultsL() + { + LOGSTRING( "CDevDiagEngine::LoadLastLoggedResultsL()" ) + + // Check the state. + __ASSERT_ALWAYS( iState == EStateReady, + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // If there are any existing results, just use them. + if ( iResults ) + { + return; + } + + // Get info about the last test record. If there are no existing records, + // just return -- the caller must check if there are results before they + // do anything. + TUid lastExecutionRecord; + if ( iResultsDatabase.GetLastRecord( lastExecutionRecord ) != KErrNone ) + { + return; + } + + // Now, load the logged results. + iResults = CDevDiagExecResults::NewL( lastExecutionRecord, + *iPluginPool, + iResultsDatabase ); + } + +// --------------------------------------------------------------------------- +// This function will stop test execution. The argument specifies whether all +// execution should be stopped, or just the currently running test. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::ExecutionStopL( TDevDiagAppEngineStopMode aReason ) + { + LOGSTRING2( "CDevDiagEngine::ExecutionStopL( %d )", aReason ) + + // Check the state. + __ASSERT_ALWAYS( IsRunningPlugins(), + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // Stop the execution. + switch ( aReason ) + { + case EStopModeSkip: + iDiagEngine->ExecutionStopL( MDiagEngineCommon::ESkip ); + break; + + case EStopModeCancel: + SetState( EStateStoppingExecution ); + + + // Start an idle active object, which will handle deleting the + // diagnostics engine. This cannot be done here because the + // engine may be executing a test which is displaying the "Cancel + // Execution" dialog, which calls this function. The priority of + // this CIdle MUST be higher than then diagnostics engine and ALL + // of its active objects. + delete iIdle; + iIdle = NULL; + iIdle = CIdle::NewL( CActive::EPriorityHigh ); + iIdle->Start( TCallBack( HandleExecutionCancelledL, this ) ); + + // Inform the observer. In the case where the observer is + // displaying a dialog, this will allow the observer to cancel it. + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandExecutionStopping, + KErrCancel, + NULL ); + } + + break; + + case EStopModeSuspend: + // Increment the suspend counter and check the state. + LOGSTRING2( "CDevDiagEngine::ExecutionStopL, counter: %d", + iSuspendCounter ) + iSuspendCounter++; + if ( iState == EStateExecutionSuspended ) + { + // Do nothing - we're already suspended. + __ASSERT_DEBUG( iSuspendCounter > 1, + Panic( EDevDiagApplicationInvalidEngineState ) ); + break; + } + + SetState( EStateExecutionSuspended ); + iDiagEngine->SuspendL(); + break; + + case EStopModeWatchdog: + iDiagEngine->StopWatchdogTemporarily(); + break; + + default: + __ASSERT_DEBUG( EFalse, Panic( EDevDiagApplicationInvalidStopMode ) ); + break; + } + } + + +TInt CDevDiagEngine::HandleExecutionCancelledL( TAny* aPtr ) + { + LOGSTRING2( "CDevDiagEngine::HandleExecutionCancelledL( 0x%x )", aPtr ) + + CDevDiagEngine* myThis = static_cast< CDevDiagEngine* >( aPtr ); + myThis->iResults->Finalize( EFalse ); + + delete myThis->iDiagEngine; + myThis->iDiagEngine = NULL; + + delete myThis->iIdle; + myThis->iIdle = NULL; + + myThis->SetState( EStateReady ); + + // Inform the observer object. + if ( myThis->iObserver ) + { + + myThis->iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandTestExecutionCancelled, + KErrCancel, + NULL ); + + } + + return KErrNone; + + } +// --------------------------------------------------------------------------- +// This function will resume suspended test execution. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::ExecutionResumeL( TDevDiagAppEngineResumeMode aReason ) + { + LOGSTRING2( "CDevDiagEngine::ExecutionResumeL( %d )", aReason ) + + // Check the state. + __ASSERT_ALWAYS( IsRunningPlugins(), + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // Resume the execution. + switch ( aReason ) + { + case EResumeModeResume: + { + LOGSTRING2( "CDevDiagEngine::ExecutionResumeL, counter: %d", + iSuspendCounter ) + // Decrement the suspend counter and check the state. + --iSuspendCounter; + __ASSERT_DEBUG( iSuspendCounter >= 0, + Panic( EDevDiagApplicationInvalidEngineState ) ); + __ASSERT_ALWAYS( iState == EStateExecutionSuspended, + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // Resume the execution, but only if there have been enough + // "resume" calls to match the number of "suspend" calls. + if ( iSuspendCounter == 0 ) + { + SetState( EStateRunningTests ); + iDiagEngine->ResumeL(); + } + + break; + } + + case EResumeModeWatchdog: + // iDiagEngine->ResetWatchdogL(); + break; + + default: + __ASSERT_DEBUG( EFalse, + Panic( EDevDiagApplicationInvalidEngineState ) ); + break; + } + } + +// --------------------------------------------------------------------------- +// Returns the plugin pool. +// --------------------------------------------------------------------------- +// +const CDiagPluginPool& CDevDiagEngine::PluginPool() const + { + LOGSTRING( "CDevDiagEngine::PluginPool()" ) + + __ASSERT_ALWAYS( ArePluginsLoaded(), + Panic( EDevDiagApplicationNotInitialized ) ); + return *iPluginPool; + } + +// --------------------------------------------------------------------------- +// Returns whether or not tests are running. +// --------------------------------------------------------------------------- +// +TBool CDevDiagEngine::IsRunningPlugins() const + { + LOGSTRING( "CDevDiagEngine::IsRunningPlugins()" ) + + return ( iState == EStateStartingExecution || + iState == EStateRunningTests || + iState == EStateStoppingExecution || + iState == EStateExecutionSuspended ); + } + +// --------------------------------------------------------------------------- +// Checks if the engine is currently stopping execution. +// --------------------------------------------------------------------------- +// +TBool CDevDiagEngine::IsStoppingExecution() const + { + LOGSTRING( "CDevDiagEngine::IsStoppingExecution()" ) + + return ( iState == EStateStoppingExecution ); + } + +// --------------------------------------------------------------------------- +// Returns whether or not plugins are done loading. +// --------------------------------------------------------------------------- +// +TBool CDevDiagEngine::ArePluginsLoaded() const + { + LOGSTRING( "CDevDiagEngine::ArePluginsLoaded()" ) + + return ( iState != EStateInitial && + iState != EStateLoadingPlugins ); + } + +// --------------------------------------------------------------------------- +// Returns whether execution results are available. +// --------------------------------------------------------------------------- +// +TBool CDevDiagEngine::HasExecutionResults() const + { + LOGSTRING( "CDevDiagEngine::HasExecutionResults()" ) + + if ( iResults ) + { + return ETrue; + } + + return EFalse; + } + +// --------------------------------------------------------------------------- +// The default constructor. +// --------------------------------------------------------------------------- +// +CDevDiagEngine::CDevDiagEngine() : CActive( EPriorityStandard ), + iDiagEngine( NULL ) + { + LOGSTRING( "CDevDiagEngine::CDevDiagEngine()" ) + + } + +// --------------------------------------------------------------------------- +// The second phase constructor. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::ConstructL() + { + LOGSTRING( "CDevDiagEngine::ConstructL()" ) + + // Connect to the results database. + User::LeaveIfError( iResultsDatabase.Connect( KUidDevDiagApplication ) ); + LOGSTRING( "CDevDiagEngine::ResultDB connect"); + // Load the plugins. + iPluginPool = CDiagPluginPool::NewL( *this ); + LOGSTRING( "CDevDiagEngine::NewL"); + SetState( EStateLoadingPlugins ); + iPluginPool->LoadAsyncL( KDiagPluginInterfaceUid ); + LOGSTRING( "CDevDiagEngine::LoadPlugin"); + // Add the application engine to the active scheduler. + CActiveScheduler::Add( this ); + } + + +// --------------------------------------------------------------------------- +// To obtain the current engine state +// --------------------------------------------------------------------------- +TInt CDevDiagEngine::GetState() + { + return iState; + } + + +// --------------------------------------------------------------------------- +// The state machine transition handler. If there is an error in changing +// states, then it will be returned and the state will be left unchanged. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::SetState( TDevDiagAppEngineState aNextState ) + { + LOGSTRING3( "CDevDiagEngine::SetState( %d ), iState = %d", + aNextState, + iState ) + + // The state transition table. Structure: State in / State to go to. + static const TInt KStateTable[ EStateMax ][ EStateMax ] = + { + // EStateInitial + { + KErrNone, // To EStateInitial + KErrNone, // To EStateLoadingPlugins + KErrDevDiagUninitialized, // To EStateReady + KErrDevDiagUninitialized, // To EStateStartingExecution + KErrDevDiagUninitialized, // To EStateRunningTests + KErrDevDiagUninitialized, // To EStateStoppingExecution + KErrDevDiagUninitialized // To EStateExecutionSuspended + }, + + // EStateLoadingPlugins + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrNone, // To EStateLoadingPlugins + KErrNone, // To EStateReady + KErrDevDiagUninitialized, // To EStateStartingExecution + KErrDevDiagUninitialized, // To EStateRunningTests + KErrDevDiagUninitialized, // To EStateStoppingExecution + KErrDevDiagUninitialized // To EStateExecutionSuspended + }, + + // EStateReady + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrDevDiagAlreadyLoaded, // To EStateLoadingPlugins + KErrNone, // To EStateReady + KErrNone, // To EStateStartingExecution + KErrDevDiagNotRunning, // To EStateRunningTests + KErrDevDiagNotRunning, // To EStateStoppingExecution + KErrDevDiagNotRunning // To EStateExecutionSuspended + }, + + // EStateStartingExecution + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrDevDiagAlreadyLoaded, // To EStateLoadingPlugins + KErrNone, // To EStateReady + KErrNone, // To EStateStartingExecution + KErrNone, // To EStateRunningTests + KErrNone, // To EStateStoppingExecution + KErrDevDiagNotRunning // To EStateExecutionSuspended + }, + + // EStateRunningTests + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrDevDiagAlreadyLoaded, // To EStateLoadingPlugins + KErrNone, // To EStateReady + KErrDevDiagAlreadyRunning, // To EStateStartingExecution + KErrNone, // To EStateRunningTests + KErrNone, // To EStateStoppingExecution + KErrNone // To EStateExecutionSuspended + }, + + // EStateStoppingExecution + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrDevDiagAlreadyLoaded, // To EStateLoadingPlugins + KErrNone, // To EStateReady + KErrDevDiagAlreadyRunning, // To EStateStartingExecution + KErrDevDiagAlreadyRunning, // To EStateRunningTests + KErrNone, // To EStateStoppingExecution + KErrDevDiagNotRunning // To EStateExecutionSuspended + }, + + // EStateExecutionSuspended + { + KErrDevDiagAlreadyInitialized, // To EStateInitial + KErrDevDiagAlreadyLoaded, // To EStateLoadingPlugins + KErrDevDiagSuspendResume, // To EStateReady + KErrDevDiagAlreadyRunning, // To EStateStartingExecution + KErrNone, // To EStateRunningTests + KErrNone, // To EStateStoppingExecution + KErrNone // To EStateExecutionSuspended + } + }; + + // Check if there is an invalid state. + __ASSERT_DEBUG( ( iState < EStateMax && aNextState < EStateMax ), + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // Change the state if there was no error, and return. + __ASSERT_ALWAYS( KStateTable[ iState ][ aNextState ] == KErrNone, + Panic( EDevDiagApplicationInvalidEngineState ) ); + iState = aNextState; + + } + +// --------------------------------------------------------------------------- +// From class CActive. +// The active object completion function. This is only used for checking the +// runtime requirements. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::RunL() + { + LOGSTRING( "CDevDiagEngine::RunL()" ) + + if ( iStatus.Int() == KErrNone ) + { + TInt error = iResultsDatabase.GetLastResults( iLastResults ); + + if ( error != KErrNone ) + { + LOGSTRING2( "CDevDiagEngine::RunL GetLastResults error: %d", error ); + + } + + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandGetLastResults, + error, + &iLastResults ); + } + } + else + { + LOGSTRING2( "CDevDiagEngine::RunL error: %d", iStatus.Int() ); + } + + } + +// --------------------------------------------------------------------------- +// From class CActive. +// The active object cancellation function. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::DoCancel() + { + LOGSTRING( "CDevDiagEngine::DoCancel()" ) + + // Stop plugin loading, if it is ongoing. + if ( iState == EStateLoadingPlugins ) + { + // Cannot leave here. + TRAP_IGNORE( iPluginPool->CancelLoadPluginsL() ) + } + } + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate that test execution is starting. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionBeginL() + { + LOGSTRING( "CDevDiagEngine::TestExecutionBeginL()" ) + + SetState( EStateRunningTests ); + + // Get the record info, so we can get the record uid. + TDiagResultsDatabaseTestRecordInfo recordInfo; + User::LeaveIfError( iDiagEngine->DbRecord().GetRecordInfo( recordInfo ) ); + + // Get the engine parameters, so we can get the executed uid. + CDiagResultsDbRecordEngineParam* execParam; + User::LeaveIfError( iDiagEngine->DbRecord().GetEngineParam( execParam ) ); + CleanupStack::PushL( execParam ); + + // Initialize the results data. + delete iResults; + iResults = NULL; + iResults = CDevDiagExecResults::NewL( recordInfo.iRecordId, + *iPluginPool, + iResultsDatabase, + execParam->ExecutionsUidArray()[ 0 ], + iDiagEngine ); + + CleanupStack::PopAndDestroy( execParam ); + + // Inform the observer object. + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandTestExecutionBegin, + KErrNone, + NULL ); + } + } + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate test progress. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionProgressL( TUint aCurrentItemStep, + TUint aCurrentItemTotalSteps ) + { + LOGSTRING3( "CDevDiagEngine::TestExecutionProgressL( %d, %d )", + aCurrentItemStep, + aCurrentItemTotalSteps ) + + // Update the results data. + __ASSERT_ALWAYS( iResults, Panic( EDevDiagApplicationInvalidEngineState ) ); + iResults->SetProgressL( aCurrentItemStep, aCurrentItemTotalSteps ); + + // Inform the observer object. + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandProgressDataUpdated, + KErrNone, + NULL ); + } + } + + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate that a plugin has completed and provide the +// result. Ownership of aResult is transferred. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionPluginExecutedL( + TInt aError, + CDiagResultsDatabaseItem* aResult ) + { + LOGSTRING3( "CDevDiagEngine::TestExecutionPluginExecutedL( %d, 0x%x )", + aError, + aResult ) + + // Update the results data. + __ASSERT_ALWAYS( iResults, Panic( EDevDiagApplicationNoExecutionResults ) ); + iResults->AddEntryL( aResult, aError ); + + if ( aResult ) + { + TInt result = aResult->TestResult(); + } + + + const MDiagPlugin& plugin = iResults->CurrentItemL().Plugin(); + + if ( plugin.Type() == MDiagPlugin::ETypeTestPlugin ) + { + //Now we are executing a test (NULL indicates a test suite). + if ( aResult ) + { + MDevDiagEngineObserver::TAppEngineCommand cmd = MDevDiagEngineObserver::EDevDiagEngineCommandSinglePluginExecutionDone; + if ( iObserver ) + iObserver->HandleEngineCommandL(cmd,aError,NULL ); + } + } + + /* + MDevDiagEngineObserver::TAppEngineCommand cmd; + + const MDiagPlugin& plugin = iResults->CurrentItemL().Plugin(); + + if ( plugin.Type() == MDiagPlugin::ETypeTestPlugin ) + { + //Now we are executing a test (NULL indicates a test suite). + if ( aResult ) + { javascript:submitForm('CreateAccountServlet', target='/accounts/my/create_selectService.jsp', '') +9 + cmd = MDevDiagEngineObserver::EDevDiagEngineCommandSinglePluginExecutionDone; + + } + else + { + //cmd = MDevDiagEngineObserver::EDevDiagEngineCommandGroupExecutionProgress; + } + + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + cmd, + aError, + NULL ); + } + } + */ + } + + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate that the diagnostics engine has finished executing +// plugins. This can also indicate a failure to begin executing plugins. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionCompletedL( TInt aError ) + { + LOGSTRING2( "CDevDiagEngine::TestExecutionCompletedL( %d )", aError ) + + SetState( EStateReady ); + + TBool singleExecution = iResults->SinglePluginExecutionL(); + + // Clean up the execution information. + if ( iResults ) + { + // The results are fully complete only if execution cannot be resumed, + // so these are the only error codes that indicate that. + iResults->Finalize( aError == KErrNone || + aError == KErrCancel || + aError == KErrArgument ); + } + + delete iDiagEngine; + iDiagEngine = NULL; + + // Inform the observer object. + if ( iObserver && !singleExecution ) + { + + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandGroupExecutionDone, + aError, + NULL ); + } + + } + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate that test execution has been suspended. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionSuspendedL( TSuspendReason aSuspendReason ) + { + LOGSTRING2( "CDevDiagEngine::TestExecutionSuspendedL( %d )", + aSuspendReason ) + + // Don't do anything if this suspend came from the application, as this + // would duplicate the counter increase. + if ( aSuspendReason == ESuspendByClient ) + { + __ASSERT_DEBUG( + ( iSuspendCounter > 0 && iState == EStateExecutionSuspended ), + Panic( EDevDiagApplicationInvalidEngineState ) ); + return; + } + + LOGSTRING3( "CDevDiagEngine::TestExecutionSuspendedL: counter %d, state: %d", + iSuspendCounter, + iState ) + // Increment the suspend counter and check the state. + iSuspendCounter++; + if ( iState == EStateExecutionSuspended ) + { + // If we are already suspended, then this suspend has no effect. + return; + } + + // Suspend ourself and inform the user. + SetState( EStateExecutionSuspended ); + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandTestExecutionSuspended, + KErrNone, + NULL ); + } + } + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to indicate that test execution has been resumed. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::TestExecutionResumedL( TResumeReason aResumeReason ) + { + LOGSTRING2( "CDevDiagEngine::TestExecutionResumedL( %d )", aResumeReason ) + + // Don't do anything if this suspend came from the application, as this + // would duplicate the counter decrease. + if ( aResumeReason == EResumedByClient ) + { + return; + } + + LOGSTRING3( "CDevDiagEngine::TestExecutionResumedL: counter %d, state: %d", + iSuspendCounter, + iState ) + // Decrement the suspend counter and check the state. + --iSuspendCounter; + __ASSERT_DEBUG( iSuspendCounter >= 0, + Panic( EDevDiagApplicationInvalidEngineState ) ); + if ( iState != EStateExecutionSuspended ) + { + // The resume was already done, so just return. + return; + } + + // Resume ourself and inform the user. + SetState( EStateRunningTests ); + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandTestExecutionResumed, + KErrNone, + NULL ); + } + } + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to to create a custom common-use dialog. This may ONLY be +// called by the Diagnostics Engine. Any application classes must use the +// dialog classes directly. +// --------------------------------------------------------------------------- +// +CAknDialog* CDevDiagEngine::CreateCommonDialogLC( TDiagCommonDialog aDialogType, + TAny* aInitData ) + { + LOGSTRING3( "CDevDiagEngine::CreateCommonDialogLC( %d, 0x%x )", + aDialogType, + aInitData ) + + switch ( aDialogType ) + { + case EDiagCommonDialogConfirmCancelAll: + { + __ASSERT_ALWAYS( !aInitData, + Panic( EDevDiagApplicationGeneral ) ); + return CDevDiagCommonCancelDialogs::NewLC( *this, EFalse ); + } + + case EDiagCommonDialogConfirmSkipAll: + { + __ASSERT_ALWAYS( !aInitData, + Panic( EDevDiagApplicationGeneral ) ); + return CDevDiagCommonSkipDialogs::NewLC( *this, EFalse ); + } + } + + __ASSERT_DEBUG( EFalse, Panic( EDevDiagApplicationBadType ) ); + return NULL; + } + + + +// --------------------------------------------------------------------------- +// From class MDiagEngineObserver. +// The callback to to execute an application command. This may ONLY be +// called by the Diagnostics Engine. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::ExecuteAppCommandL( TDiagAppCommand aCommand, + TAny* aParam1, + TAny* aParam2 ) + { + LOGSTRING4( "CDevDiagEngine::ExecuteAppCommandL( %d, 0x%x, 0x%x )", + aCommand, + aParam1, + aParam2 ) + + switch ( aCommand ) + { + case EDiagAppCommandSwitchToMainView: + { + __ASSERT_ALWAYS( ( !aParam1 && !aParam2 ), + Panic( EDevDiagApplicationGeneral ) ); + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandViewSwitch, + KErrNone, + NULL ); + } + break; + } + + default: + User::Leave( KErrNotSupported ); + } + } + +// --------------------------------------------------------------------------- +// From class MDiagPluginPoolObserver. +// The callback to indicate plugin loading progress. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::LoadProgressL( TUint aCurrentStep, + TUint aTotalSteps, + const TUid& aLoadedPluginUid ) + { + + LOGSTRING4( "CDevDiagEngine::LoadProgressL( %d, %d, 0x%x )", + aCurrentStep, + aTotalSteps, + aLoadedPluginUid.iUid ) + + __ASSERT_ALWAYS( iState == EStateLoadingPlugins, + Panic( EDevDiagApplicationInvalidEngineState ) ); + + // Inform the observer with the loading information. + if ( iObserver ) + { + MDiagPlugin* plugin = NULL; + iPluginPool->FindPlugin( aLoadedPluginUid, plugin ); + + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandPluginLoadProgress, + KErrNone, + plugin ); + } + } + +// --------------------------------------------------------------------------- +// From class MDiagPluginPoolObserver. +// The callback to indicate plugin loading completion. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::LoadCompletedL( TInt aError ) + { + LOGSTRING2( "CDevDiagEngine::LoadCompletedL( %d )", aError ) + + SetState( EStateReady ); + + // Inform the observer of the loading completion. The observer will + // display error messages for loading failures. + if ( iObserver ) + { + iObserver->HandleEngineCommandL( + MDevDiagEngineObserver::EDevDiagEngineCommandPluginLoadComplete, + aError, + NULL ); + } + } + +// --------------------------------------------------------------------------- +// Get Last results from the Results Database. +// --------------------------------------------------------------------------- +// +void CDevDiagEngine::GetLastResultsL( TUid aParentUid ) + { + LOGSTRING( "CDevDiagEngine::GetLastResultsL"); + + RPointerArray children; + CleanupClosePushL( children ); + + MDiagPlugin* plugin; + ///@@@KSR: changes for BAD Warnings - #177-D: variable "formattedName" was declared but never referenced + //HBufC* formattedName = NULL; + + if ( PluginPool().FindPlugin( aParentUid, plugin ) == KErrNone ) + { + MDiagSuitePlugin* suite = static_cast< MDiagSuitePlugin* >( plugin ); + suite->GetChildrenL( children, MDiagSuitePlugin::ESortByPosition ); + } + else + { + User::Leave(KErrNotFound); + } + + if ( iUids ) + { + delete iUids; + iUids = NULL; + } + + iUids = new (ELeave) CArrayFixFlat( KArrayGranuality ); + + iLastResults.ResetAndDestroy(); + + //Create UID array that is needed when results are searched from the DB. + for ( TInt i = 0; i < children.Count(); ++i ) + { + iUids->AppendL( children[i]->Uid() ); + } + + CleanupStack::PopAndDestroy( &children ); + + //Start search. This is an asynchronous call. + iResultsDatabase.InitiateGetLastResults( *iUids, iStatus ); + + SetActive(); + } + + +// --------------------------------------------------------------------------- +// Get last plug-in that crashed (if any). +// +// CDiagResultsDatabaseItem::EQueuedToRun indicates that the test was not +// executed properly. +// --------------------------------------------------------------------------- +// +TBool CDevDiagEngine::CrashedPluginL( TUid& aPluginUid ) + { + LOGSTRING( "CDevDiagEngine::CrashedPluginL"); + TUid recordUid; + TInt error = iResultsDatabase.GetLastNotCompletedRecord ( recordUid ); + LOGSTRING2("crashedpluginL::dbconnect error %d",error); + TBool found = EFalse; + if ( error == KErrNone ) + { + RDiagResultsDatabaseRecord crashedRecord; + + error = crashedRecord.Connect( iResultsDatabase, recordUid, EFalse ); + CleanupClosePushL( crashedRecord ); + + if ( error != KErrNone ) + { + LOGSTRING2( "CDevDiagEngine::CrashedPluginL connect error: %d", error ); + User::Leave( error ); + } + + //ResetAndDestroy + Close would be better + RPointerArray resultsArray; + CleanupClosePushL( resultsArray ); + + error = crashedRecord.GetTestResults ( resultsArray ); + + if ( error != KErrNone ) + { + LOGSTRING2( "CDevDiagEngine::CrashedPluginL GetTestResults error: %d", error ); + User::Leave( error ); + } + + for ( TInt i = 0; i < resultsArray.Count(); ++i ) + { + if ( resultsArray[i]->TestResult() == CDiagResultsDatabaseItem::EQueuedToRun ) + { + aPluginUid = resultsArray[i]->TestUid(); + found = ETrue; + break; + } + } + + resultsArray.ResetAndDestroy(); + CleanupStack::PopAndDestroy(); + CleanupStack::PopAndDestroy(); //crashedRecord + } + + LOGSTRING( "CDevDiagEngine::CrashedPluginL end" ); + + return found; + } + + +// --------------------------------------------------------------------------- +// Completes the crashed test record. +// --------------------------------------------------------------------------- +// +///@@@KSR: changes for Codescanner error val = High +//TInt CDevDiagEngine::CompleteCrashedTestRecord() +TInt CDevDiagEngine::CompleteCrashedTestRecordL() + { + LOGSTRING( "CDevDiagEngine::CompleteCrashedTestRecordL"); + TUid recordUid; + TInt error = iResultsDatabase.GetLastNotCompletedRecord ( recordUid ); + + if ( error == KErrNone ) + { + RDiagResultsDatabaseRecord crashedRecord; + + error = crashedRecord.Connect( iResultsDatabase, recordUid, EFalse ); + CleanupClosePushL( crashedRecord ); + + if ( error != KErrNone ) + { + LOGSTRING2( "CDevDiagEngine::CompleteCrashedTestRecordL connect error: %d", error ); + return error; + } + + error = crashedRecord.TestCompleted( ETrue ); + + if ( error != KErrNone ) + { + LOGSTRING2( "CDevDiagEngine::CompleteCrashedTestRecordL TestCompleted error: %d", error ); + return error; + } + + CleanupStack::PopAndDestroy(); //crashedRecord + } + + LOGSTRING( "CDevDiagEngine::CompleteCrashedTestRecordL end"); + + return error; + } + + +// ADO & Platformization Changes + TBool CDevDiagEngine::GetPluginDependencyL() + { + ///@@@KSR: changes for Codescanner error val = High + //return iDiagEngine->GetPluginDependency(); + return iDiagEngine->GetPluginDependencyL(); + } + +// End of File