--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestEngine/src/TestCaseController.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,2878 @@
+/*
+* Copyright (c) 2009 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 module contains implementation of
+* CTestCaseController class member functions.
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32svr.h>
+#include <e32uid.h>
+#include <StifLogger.h>
+#include "StifTFwIfProt.h"
+#include "TestCaseController.h"
+#include "TestModuleController.h"
+#include "TestReport.h"
+#include "Logging.h"
+#include "StifHWReset.h"
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+// None
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+// None
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ==================== LOCAL FUNCTIONS =======================================
+// None
+
+
+#define LOGGER iEngine->Logger()
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: CTestCaseController
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+ CAtsLogger& aAtsLogger: in: Reference to CAtsLogger
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+ const TTestInfo& aTestInfo: in: Test Info
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCaseController::CTestCaseController( CTestEngine* aEngine,
+ CTestReport* aTestReport,
+ CAtsLogger& aAtsLogger,
+ RTestExecution aTestExecution,
+ const TTestInfo& aTestInfo ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aEngine ),
+ iTestReport( aTestReport ),
+ iTestExecution( aTestExecution ),
+ iTestInfo( aTestInfo ),
+ iState( ETestCaseIdle ),
+ iResultPckg( iResult ),
+ iAtsLogger( aAtsLogger )
+ {
+ CActiveScheduler::Add( this );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::ConstructL()
+ {
+ __TRACE( KVerbose, ( _L( "CTestCaseController::ConstructL, [%S]" ), &iTestInfo.iTestCaseInfo.iTitle ) );
+
+ // Logger settings
+ TLoggerSettings loggerSettings;
+ loggerSettings.iCreateLogDirectories = EFalse;
+ loggerSettings.iOverwrite = ETrue;
+ loggerSettings.iTimeStamp = EFalse;
+ loggerSettings.iLineBreak = EFalse;
+ loggerSettings.iEventRanking = EFalse;
+ loggerSettings.iThreadId = EFalse;
+ loggerSettings.iHardwareFormat = CStifLogger::ETxt;
+ loggerSettings.iHardwareOutput = CStifLogger::ERDebug;
+ loggerSettings.iEmulatorFormat = CStifLogger::ETxt;
+ loggerSettings.iEmulatorOutput = CStifLogger::ERDebug;
+ loggerSettings.iUnicode = EFalse;
+ loggerSettings.iAddTestCaseTitle = EFalse;
+
+ iRDebugLogger = CStifLogger::NewL( _L( "" ), _L( "" ), loggerSettings );
+
+ // If timeout is specified, then create timeout handler.
+ if ( iTestInfo.iTestCaseInfo.iTimeout > TTimeIntervalMicroSeconds(0) )
+ {
+ iTimeout = CTestCaseTimeout::NewL ( this,
+ iTestInfo.iTestCaseInfo.iTimeout );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ CTestReport* aTestReport: in: Pointer to CTestReport
+ CAtsLogger& aAtsLogger: in: Reference to CAtsLogger
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+ const TTestInfo& aTestInfo: in: Test Info
+
+ Return Values: CTestCaseController* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestCaseController fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCaseController* CTestCaseController::NewL( CTestEngine* aEngine,
+ CTestReport* aTestReport,
+ CAtsLogger& aAtsLogger,
+ RTestExecution aTestExecution,
+ const TTestInfo& aTestInfo )
+ {
+ CTestCaseController* self = new ( ELeave ) CTestCaseController( aEngine,
+ aTestReport, aAtsLogger, aTestExecution, aTestInfo );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: ~CTestCaseController
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTestCaseController::~CTestCaseController()
+ {
+ __TRACE( KVerbose, ( _L( "CTestCaseController::~CTestCaseController" ) ) );
+ Cancel();
+
+ delete iRDebugLogger;
+ delete iTimeout;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: StartL
+
+ Description: Start active object
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::StartL( const RMessage2& aMessage )
+ {
+ iRDebugLogger->Log( _L( "Starting testcase [%S]" ), &iTestInfo.iTestCaseInfo.iTitle );
+ __TRACE( KInit, ( _L(" Starting testcase [%S]"), &iTestInfo.iTestCaseInfo.iTitle ) );
+
+ // Check that this request is not pending!!
+ __ASSERT_ALWAYS( iState != ETestCaseRunning,
+ iEngine->PanicClient( EReqPending, aMessage ) );
+ iMessage = aMessage;
+
+ iState = ETestCaseRunning;
+
+ SetActive();
+
+ iTestExecution.RunTestCase( iResultPckg, iStatus );
+
+ // If testcase has timeout (handler), then start it
+ if ( iTimeout )
+ {
+ iTimeout->Start();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: Timeout
+
+ Description: Timeouts active request.
+ - Cancel request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::Timeout()
+ {
+ if ( iState == ETestCaseRunning )
+ {
+ iState = ETestCaseTimeout;
+ Cancel();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: RunL
+
+ Description: RunL handles completed requests. Leaves are handled in
+ RunError method
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if AddTestCaseResultL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::RunL()
+ {
+ iState = ETestCaseCompleted;
+
+
+ // "iStatus.Int()" error code is received from system's framework not from
+ // test case execution.
+ if ( iStatus.Int() != KErrNone )
+ {
+ if ( iStatus.Int() == KErrServerTerminated )
+ {
+ // something went badly wrong!
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "TestCase [%S] cannot be executed, STIF panics with[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iStatus.Int() ) );
+
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "Possible reason: Test case has paniced seriously" ) ) );
+
+ // We don't leave here but we write information to
+ // forward(testreport etc.)
+ _LIT( KLeaveInfo, "Test case execution fails" );
+ // Sets test case to crash category
+ iResult.iCaseExecutionResultCode = iStatus.Int();
+ // Test case result
+ iResult.iTestResult.iResult = iStatus.Int();
+ iResult.iTestResult.iResultDes = KLeaveInfo;
+
+ }
+
+ else
+ {
+ // For example testmodule's NewL or testmodule's constructor has
+ // leaved and STIF cannot connect to test module
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "TestCase [%S] cannot execute, TestModule loading operations fails with[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iStatus.Int() ) );
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "Possible reason: TestModule's NewL or Constructor has leaved and STIF cannot connect to test module" ) ) );
+
+ // We don't leave here but we write information to
+ // forward(testreport etc.)
+ _LIT( KLeaveInfo, "TestModule loading fails, cannot connect to the TestModule" );
+ // Sets test case to crash category
+ iResult.iCaseExecutionResultCode = iStatus.Int();
+ // Test case result
+ iResult.iTestResult.iResult = iStatus.Int();
+ iResult.iTestResult.iResultDes = KLeaveInfo;
+ }
+ }
+
+ else
+ {
+
+ // Cancel event request, because the testcase is completed
+ iTestExecution.CancelAsyncRequest( ETestExecutionNotifyEvent );
+ }
+
+ // Test case is executed
+ if( iTestInfo.iTestCaseInfo.iTitle.Length() > 0 )
+ {
+ iRDebugLogger->Log( _L( "TestCase [%S] finished with verdict[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iResult.iTestResult.iResult );
+
+ __TRACE( KInit, ( _L( " TestCase [%S] finished with verdict[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iResult.iTestResult.iResult ) );
+ }
+ else
+ {
+ iRDebugLogger->Log( _L( "TestCase [%d] finished with verdict[%d]" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber,
+ iResult.iTestResult.iResult );
+
+ __TRACE( KInit, ( _L( " TestCase [%d] finished with verdict[%d]" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber,
+ iResult.iTestResult.iResult ) );
+ }
+ __TRACE( KVerbose, (
+ _L( "CTestCaseController::RunL: iStatus=[%d]" ), iStatus.Int() ));
+
+ GenerateXmlLogL();
+
+ // Report test case result
+ if( iTestReport )
+ {
+ iTestReport->AddTestCaseResultL( iTestInfo, iResult, iStatus.Int() );
+ iTestReport->UpdateReportSummaryL();
+ }
+
+ TRAPD( ret, iMessage.WriteL( 0, iResultPckg ) );
+
+ // Case done
+ iMessage.Complete( ret );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::DoCancel()
+ {
+
+ switch ( iState )
+ {
+ case ETestCaseRunning:
+ iTestExecution.CancelAsyncRequest( ETestExecutionRunTestCase );
+ if( iTestInfo.iTestCaseInfo.iTitle.Length() > 0 )
+ {
+ iRDebugLogger->Log( _L( "TestCase [%S] execution aborted" ),
+ &iTestInfo.iTestCaseInfo.iTitle );
+
+ __TRACE( KInit, ( _L( "TestCase [%S] execution aborted" ),
+ &iTestInfo.iTestCaseInfo.iTitle ) );
+ }
+ else
+ {
+ iRDebugLogger->Log( _L( "TestCase [%S] execution aborted" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber );
+
+ __TRACE( KInit, ( _L( "TestCase [%S] execution aborted" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber ) );
+ }
+ break;
+ case ETestCaseTimeout:
+ iTestExecution.CancelAsyncRequest( ETestExecutionRunTestCase );
+ // Update result to timeout
+ iResult.iCaseExecutionResultType = TFullTestResult::ECaseTimeout;
+ iResult.iTestResult.iResultDes = _L("Test case was timeouted and cancelled");
+
+ if( iTestReport )
+ {
+ iTestReport->AddTestCaseResultL( iTestInfo, iResult, KErrTimedOut );
+ }
+
+ if( iTestInfo.iTestCaseInfo.iTitle.Length() > 0 )
+ {
+ iRDebugLogger->Log( _L( "TestCase [%S] finished with verdict[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iResult.iTestResult.iResult );
+
+ __TRACE( KInit, ( _L( " TestCase [%S] finished with verdict[%d]" ),
+ &iTestInfo.iTestCaseInfo.iTitle,
+ iResult.iTestResult.iResult ) );
+ }
+ else
+ {
+ iRDebugLogger->Log( _L( "TestCase [%d] finished with verdict[%d]" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber,
+ iResult.iTestResult.iResult );
+
+ __TRACE( KInit, ( _L( " TestCase [%d] finished with verdict[%d]" ),
+ iTestInfo.iTestCaseInfo.iCaseNumber,
+ iResult.iTestResult.iResult ) );
+ }
+
+ break;
+ case ETestCaseSuicided:
+ {
+ //Store current results because cancel operation overwrites it
+ TInt currentTestResult = iResult.iTestResult.iResult;
+ TInt currentExecutionResult = iResult.iCaseExecutionResultCode;
+ iTestExecution.CancelAsyncRequest(ETestExecutionRunTestCase);
+ // Update result to suicide
+ switch(iStopExecutionType)
+ {
+ case EOk:
+ iResult.iCaseExecutionResultType = TFullTestResult::ECaseExecuted;
+ iResult.iTestResult.iResultDes = _L("Test case passed (StopExecution())");
+ break;
+ case EFail:
+ iResult.iCaseExecutionResultType = TFullTestResult::ECaseExecuted;
+ iResult.iTestResult.iResultDes = _L("Test case failed (StopExecution())");
+ break;
+ default: //EAbort
+ iResult.iCaseExecutionResultType = TFullTestResult::ECaseSuicided;
+ iResult.iTestResult.iResultDes = _L("Test case killed (StopExecution())");
+ }
+ iResult.iTestResult.iResult = currentTestResult;
+ iResult.iCaseExecutionResultCode = currentExecutionResult;
+ }
+ if(iTestReport)
+ {
+ iTestReport->AddTestCaseResultL(iTestInfo, iResult, KErrNone);
+ }
+
+ // Log some message
+ if(iTestInfo.iTestCaseInfo.iTitle.Length() > 0)
+ {
+ _LIT(KTestCaseDesc, "TestCase [%S] finished with verdict [%d]");
+ switch(iStopExecutionType)
+ {
+ case EOk:
+ {
+ _LIT(KTestCaseResult, "***Testcase PASSED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult));
+ break;
+ }
+ case EFail:
+ {
+ _LIT(KTestCaseResult, "***Testcase FAILED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult));
+ break;
+ }
+ default: //EAbort
+ {
+ _LIT(KTestCaseResult, "***Testcase KILLED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, &iTestInfo.iTestCaseInfo.iTitle, iResult.iTestResult.iResult));
+ }
+ }
+ }
+ else
+ {
+ _LIT(KTestCaseDesc, "TestCase [%d] finished with verdict [%d]");
+ switch(iStopExecutionType)
+ {
+ case EOk:
+ {
+ _LIT(KTestCaseResult, "***Testcase PASSED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult));
+ break;
+ }
+ case EFail:
+ {
+ _LIT(KTestCaseResult, "***Testcase FAILED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult));
+ break;
+ }
+ default: //EAbort
+ {
+ _LIT(KTestCaseResult, "***Testcase KILLED***");
+
+ iRDebugLogger->Log(KTestCaseResult);
+ __TRACE(KInit, (KTestCaseResult));
+ iRDebugLogger->Log(KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult);
+ __TRACE(KInit, (KTestCaseDesc, iTestInfo.iTestCaseInfo.iCaseNumber, iResult.iTestResult.iResult));
+ }
+ }
+ }
+ break;
+ case ETestCaseIdle:
+ case ETestCaseCompleted:
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestCaseController, "CTestCaseController" );
+ User::Panic( KTestCaseController, EDoCancelDisorder );
+ break;
+ }
+
+ // Write result and complete
+ TRAPD( ret, iMessage.WriteL( 0, iResultPckg ) );
+
+ iMessage.Complete( ret );
+
+ iState = ETestCaseCompleted;
+
+ // Generate xml result log
+ GenerateXmlLogL();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCaseController::RunError( TInt aError )
+ {
+ __TRACE( KError, ( CStifLogger::ERed,
+ _L( "CTestCaseController::RunError: Test case execution has failed! aError=[%d]" ), aError ) );
+ TInt completionError = aError;
+
+ // Write result, because it could include descriptive result for
+ // failed case
+ TRAPD( err, iMessage.WriteL( 0, iResultPckg ); );
+
+ if ( err != KErrNone )
+ {
+ completionError = err;
+ }
+
+ // Complete message with error
+ iMessage.Complete( completionError );
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: GenerateXmlLogL
+
+ Description: Generate XML log.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::GenerateXmlLogL()
+ {
+
+ // Report result with AtsLogger
+ iAtsLogger.BeginTestCaseReportL( iTestInfo.iTestCaseInfo.iTitle,
+ KErrNone, // Expected result not supported
+ iResult.iStartTime );
+
+ if( iResult.iCaseExecutionResultCode != KErrNone )
+ {
+ iAtsLogger.SetTestCaseResultL( iResult.iCaseExecutionResultCode );
+ iAtsLogger.TestCaseFailed();
+ if( iResult.iTestResult.iResultDes.Length() > 0 )
+ {
+ iAtsLogger.ErrorL( iResult.iTestResult.iResultDes );
+ }
+ }
+ else
+ {
+ iAtsLogger.SetTestCaseResultL( iResult.iTestResult.iResult );
+ if( iResult.iTestResult.iResult == KErrNone )
+ {
+ iAtsLogger.TestCasePassed();
+ }
+ else
+ {
+ iAtsLogger.TestCaseFailed();
+ if( iResult.iTestResult.iResultDes.Length() > 0 )
+ {
+ iAtsLogger.ErrorL( iResult.iTestResult.iResultDes );
+ }
+ }
+ }
+ // Set test case result to ATS Logger
+ iAtsLogger.EndTestCaseL();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: GetTestCaseInfo
+
+ Description: Get testcase info(test module, config file, test case, etc).
+
+ Parameters: TTestInfo& aTestInfo: inout: Test information
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::GetTestCaseInfo( TTestInfo& aTestInfo )
+ {
+ aTestInfo = iTestInfo;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCaseController
+
+ Method: Suicide
+
+ Description: Cancels active request.
+
+ Parameters: aCode: the reason of suicide
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCaseController::Suicide(TStopExecutionType aType, TInt aCode)
+ {
+ if(iState == ETestCaseRunning)
+ {
+ iStopExecutionType = aType;
+ switch(iStopExecutionType)
+ {
+ case EOk:
+ iResult.iTestResult.iResult = KErrNone;
+ iResult.iCaseExecutionResultCode = KErrNone;
+ break;
+ case EFail:
+ iResult.iTestResult.iResult = aCode;
+ iResult.iCaseExecutionResultCode = KErrNone;
+ break;
+ default: //EAbort
+ iResult.iTestResult.iResult = aCode;
+ iResult.iCaseExecutionResultCode = aCode;
+ }
+ iState = ETestCaseSuicided;
+ Cancel();
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestProgressNotifier class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: CTestProgressNotifier
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestProgressNotifier::CTestProgressNotifier( CTestEngine* aEngine,
+ RTestExecution aTestExecution ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aEngine ),
+ iTestExecution( aTestExecution ),
+ iState( ETestProgressIdle ),
+ iProgressPckg( iProgress )
+ {
+ CActiveScheduler::Add( this );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestProgressNotifier::ConstructL()
+ {
+ __TRACE( KVerbose, ( _L( "CTestProgressNotifier::ConstructL" ) ) );
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: CTestProgressNotifier* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestProgressNotifier fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestProgressNotifier* CTestProgressNotifier::NewL( CTestEngine* aEngine,
+ RTestExecution aTestExecution )
+ {
+ CTestProgressNotifier* self = new ( ELeave ) CTestProgressNotifier(
+ aEngine, aTestExecution );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: ~CTestProgressNotifier
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestProgressNotifier::~CTestProgressNotifier()
+ {
+ __TRACE( KVerbose, ( _L( "CTestProgressNotifier::~CTestProgressNotifier" ) ) );
+ Cancel();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: StartL
+
+ Description: Start active object
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestProgressNotifier::StartL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestProgressNotifier::StartL" ) ) );
+ // Check that this request is not pending!!
+ __ASSERT_ALWAYS( iState != ETestProgressPending,
+ iEngine->PanicClient( EReqPending, aMessage ) );
+ iMessage = aMessage;
+
+ iState = ETestProgressPending;
+ SetActive();
+
+ iTestExecution.NotifyProgress( iProgressPckg, iStatus );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if WriteL leaves
+ Leaves if iStatus is not KErrNone or KErrEof
+ Leaves are handled in RunError method
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestProgressNotifier::RunL()
+ {
+ __TRACE( KVerbose, (_L("CTestProgressNotifier::RunL: iStatus=[%d]" ), iStatus.Int() ));
+
+ iState = ETestProgressCompleted;
+
+ // Check that request was successful or completed with acceptable error
+ // KErrEof is acceptable error and it means that the test case will not
+ // send progresses anymore (because it is closed)
+ if ( KErrNone == iStatus.Int() )
+ {
+ iMessage.WriteL( 0, iProgressPckg );
+ }
+ else if ( KErrEof != iStatus.Int() )
+ {
+ // Leave, error will be handled in RunError
+ User::Leave( iStatus.Int() );
+ }
+
+ // Complete message
+ iMessage.Complete( iStatus.Int() );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestProgressNotifier::DoCancel()
+ {
+ switch ( iState )
+ {
+ case ETestProgressPending:
+ iTestExecution.CancelAsyncRequest( ETestExecutionNotifyProgress );
+ iMessage.Complete( KErrCancel );
+ break;
+ case ETestProgressIdle:
+ case ETestProgressCompleted:
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestProgressNotifier, "CTestProgressNotifier" );
+ User::Panic( KTestProgressNotifier, EDoCancelDisorder );
+ break;
+ }
+ iState = ETestProgressIdle;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestProgressNotifier::RunError( TInt aError )
+ {
+ // Complete message with error
+ iMessage.Complete( aError );
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestEventNotifier class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: CTestEventNotifier
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventNotifier::CTestEventNotifier( CTestEngine* aEngine,
+ RTestExecution aTestExecution ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aEngine ),
+ iTestExecution( aTestExecution ),
+ iState( ETestEventIdle ),
+ iEventPckg( iEvent ),
+ iEventNotifyPckg( iEventNotify ),
+ iController( NULL )
+ {
+ CActiveScheduler::Add( this );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventNotifier::ConstructL( )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::ConstructL" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: CTestEventNotifier* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestEventNotifier fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventNotifier* CTestEventNotifier::NewL( CTestEngine* aEngine,
+ RTestExecution aTestExecution )
+ {
+ CTestEventNotifier* self = new ( ELeave ) CTestEventNotifier(
+ aEngine, aTestExecution );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: ~CTestEventNotifier
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventNotifier::~CTestEventNotifier()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::~CTestEventNotifier" ) ) );
+ Cancel();
+ iEventArray.ResetAndDestroy();
+ iEventArray.Close();
+ delete iController;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: StartL
+
+ Description: Start active object
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventNotifier::Start()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::StartL" ) ) );
+ // Check that this request is not pending!!
+ __ASSERT_ALWAYS( iState != ETestEventPending,
+ User::Leave( KErrAlreadyExists ) );
+
+ iEvent.SetType( TEventIf::EEnable );
+ iState = ETestEventPending;
+ iTestExecution.NotifyEvent( iEventPckg, iStatus );
+ SetActive();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if iStatus is not KErrNone
+ Leaves if iState is not ETestEventPending
+ Leaves if some leaving method called here leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventNotifier::RunL()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::RunL: iStatus=[%d]" ), iStatus.Int() ) );
+
+ User::LeaveIfError( iStatus.Int() );
+
+ switch( iState )
+ {
+ case ETestEventPending:
+ {
+ iState = ETestEventCompleted;
+
+ switch( iEvent.Type() )
+ {
+ case TEventIf::EReqEvent:
+ {
+ __RDEBUG( ( _L("CTestEventNotifier(ReqEvent) %S"),
+ &iEvent.Name() ));
+ if( iEngine->IsStateEventAndSet( iEvent.Name() ) )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::RunL: Requested Global event already set" ) ) );
+ TEventIf event( TEventIf::ESetEvent, iEvent.Name(),
+ TEventIf::EState );
+ TEventIfPckg eventPckg( event );
+ TRequestStatus status;
+ iTestExecution.NotifyEvent( eventPckg, status );
+ User::WaitForRequest( status );
+ }
+ //add to iEventArray
+ HBufC* name = iEvent.Name().AllocLC();
+ if( iEventArray.Append( name ) != KErrNone )
+ {
+ User::Leave( KErrNoMemory );
+ }
+ CleanupStack::Pop( name );
+ }
+ break;
+ case TEventIf::ERelEvent:
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier(RelEvent) %S" ), &iEvent.Name() ) );
+ //remove from iEventArray
+ TInt count = iEventArray.Count();
+ const TDesC& eventName = iEvent.Name();
+ TInt i;
+ for( i = 0; i < count; i++ )
+ {
+ TPtrC name = iEventArray[i]->Des();
+ if( name == eventName )
+ {
+ HBufC* tmp = iEventArray[i];
+ iEventArray.Remove( i );
+ delete tmp;
+ break;
+ }
+ }
+ // Check that event was found
+ if( i == count )
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+ break;
+ case TEventIf::ESetEvent:
+ {
+ __RDEBUG( ( _L("CTestEventNotifier(SetEvent) %S"),
+ &iEvent.Name() ));
+ iController = iEngine->CtlEventL( iEvent, iStatus );
+ SetActive();
+ return;
+ }
+ case TEventIf::EUnsetEvent:
+ {
+ __RDEBUG( ( _L("CTestEventNotifier(UnsetEvent) %S"),
+ &iEvent.Name() ));
+ iController = iEngine->CtlEventL( iEvent, iStatus );
+ SetActive();
+ return;
+ }
+ default:
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+ // Set request again
+ Start();
+ // Otherwise request is enabled again later
+ }
+ break;
+ case ETestEventCompleted:
+ __RDEBUG( ( _L("CTestEventNotifier(Complete)")));
+ Start();
+ break;
+ default:
+ User::Leave( KErrGeneral );
+ break;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventNotifier::DoCancel()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::DoCancel" ) ) );
+
+ switch ( iState )
+ {
+ case ETestEventPending:
+ iTestExecution.CancelAsyncRequest( ETestExecutionNotifyEvent );
+ break;
+ case ETestEventCompleted:
+ delete iController;
+ iController = NULL;
+ break;
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestEventNotifier, "CTestEventNotifier" );
+ User::Panic( KTestEventNotifier, EDoCancelDisorder );
+ break;
+ }
+
+ iState = ETestEventIdle;
+ iEventArray.ResetAndDestroy();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEventNotifier::RunError( TInt aError )
+ {
+ switch ( iState )
+ {
+ case ETestEventPending:
+ if( aError != KErrCancel )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "CTestEventNotifier::RunError %d"), aError) );
+ }
+ else
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier stopped")) );
+ }
+
+ // We stop event notifier if we get error here
+ // Clear requested event list
+ iEventArray.ResetAndDestroy();
+ break;
+ case ETestEventCompleted:
+ // Do not close here
+ __TRACE( KError, ( CStifLogger::ERed, _L( "CTestEventNotifier::RunError %d"), aError) );
+ delete iController;
+ iController = NULL;
+ // forward error to testcase
+ iEvent.SetType( TEventIf::EEnable );
+ iState = ETestEventPending;
+ iTestExecution.NotifyEvent( iEventPckg, iStatus, aError );
+ SetActive();
+ break;
+ default:
+ __TRACE( KError, ( CStifLogger::ERed, _L( "CTestEventNotifier::RunError %d"), aError) );
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestEventNotifier, "CTestEventNotifier" );
+ User::Panic( KTestEventNotifier, EDoCancelDisorder );
+ break;
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: CtlEventL
+
+ Description: Controls events
+
+ Parameters: const TEventIf& aEvent: in: Event
+ TRequestStatus& aStatus: in: Request status
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventNotifier::CtlEvent( const TEventIf& aEvent,
+ TRequestStatus& aStatus )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEventNotifier::CtlEventL" ) ) );
+ const TDesC& eventName = aEvent.Name();
+ TInt count = iEventArray.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ TPtrC name = iEventArray[i]->Des();
+ if( name == eventName )
+ {
+ iEventNotify.Copy( aEvent );
+ iTestExecution.NotifyEvent( iEventNotifyPckg, aStatus );
+ return;
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: CheckCtlEventL
+
+ Description: Checks if CtlEvent should be called
+
+ Parameters: const TEventIf& aEvent: in: Event
+
+ Return Values: ETrue: If CtlEvent sould be called.
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestEventNotifier::CheckCtlEvent( const TEventIf& aEvent )
+ {
+ const TDesC& eventName = aEvent.Name();
+ TInt count = iEventArray.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ TPtrC name = iEventArray[i]->Des();
+ if( name == eventName )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestEventController class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: CTestEventController
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ const TEventIf& aEvent: in: Event
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventController::CTestEventController( CTestEngine* aEngine,
+ const TEventIf& aEvent ) :
+ iEngine( aEngine ),
+ iRequestStatus( NULL ),
+ iEventPckg( iEvent ),
+ iActiveEventCmds( 0 )
+ {
+ iEvent.Copy( aEvent );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: TRequestStatus* aStatus: in: Request status
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventController::ConstructL( TRequestStatus* aStatus )
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::ConstructL" ) );
+
+ if( CheckEventsL() == 0 )
+ {
+ // No request was pending, complete immediately
+ User::RequestComplete( aStatus, KErrNone );
+ }
+ else
+ {
+ iRequestStatus = aStatus;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: RMessage& aMessage: inout: Message to be handled
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventController::ConstructL( RMessage2& aMessage )
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::ConstructL" ) );
+
+ if( CheckEventsL() == 0 )
+ {
+ // No request was pending, complete immediately
+ aMessage.Complete( KErrNone );
+ }
+ else
+ {
+ iMessage = aMessage;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ const TEventIf& aEvent: in: Event
+ TRequestStatus* aStatus: in: Request status
+
+ Return Values: CTestEventController* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestEventController fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+
+CTestEventController* CTestEventController::NewL( CTestEngine* aEngine,
+ const TEventIf& aEvent,
+ TRequestStatus* aStatus )
+ {
+ CTestEventController* self =
+ new ( ELeave )CTestEventController( aEngine, aEvent );
+ CleanupStack::PushL( self );
+ self->ConstructL( aStatus );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ const TEventIf& aEvent: in: Event
+ RMessage& aMessage: inout: Message to be handled
+
+ Return Values: CTestEventController* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestEventController fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventController* CTestEventController::NewL( CTestEngine* aEngine,
+ const TEventIf& aEvent,
+ RMessage2& aMessage )
+ {
+ CTestEventController* self =
+ new ( ELeave )CTestEventController( aEngine, aEvent );
+ CleanupStack::PushL( self );
+ self->ConstructL( aMessage );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: ~CTestEventController
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+CTestEventController::~CTestEventController()
+ {
+ if( iEngine != NULL )
+ {
+ if( iEngine->Logger() != NULL )
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::~CTestEventController" ) );
+ }
+ }
+
+ if( iRequestStatus )
+ {
+ // Must be completed if pending, otherwise
+ // CTestEventNotifier::DoCancel blocks
+ User::RequestComplete( iRequestStatus, KErrCancel );
+ }
+
+ iEventCallBacks.ResetAndDestroy();
+ iEventCallBacks.Close();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: CheckEventsL
+
+ Description: Check all events.
+
+ Parameters: None
+
+ Return Values: TInt: Active event commands
+
+ Errors/Exceptions: Leaves if CtlEventL leaves
+ Leaves if memory allocation fails
+ Leaves if unset event not found from pending
+ state event list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEventController::CheckEventsL()
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::CheckEventsL" ) );
+
+ iActiveEventCmds += CheckClientEventsL();
+ iActiveEventCmds += CheckTestcaseEventsL();
+
+ return iActiveEventCmds;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: CheckClientEventsL
+
+ Description: Check client events.
+
+ Parameters: None
+
+ Return Values: TInt: Request of pending
+
+ Errors/Exceptions: Leaves if CtlEventL leaves
+ Leaves if memory allocation fails
+ Leaves if unset event not found from pending
+ state event list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEventController::CheckClientEventsL()
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::CheckClientEventsL" ) );
+ TInt reqPending = 0;
+
+ // Check client event requests
+ TInt count = iEngine->ClientEvents().Count();
+ for( TInt index = 0; index < count; index++ )
+ {
+ if( iEngine->ClientEvents()[index]->Name() == iEvent.Name() )
+ {
+ TEventMsg* event = iEngine->ClientEvents()[index];
+ if( iEvent.Type() == TEventIf::ESetEvent )
+ {
+ // Set found event
+ event->Set( iEvent.EventType() );
+ }
+ else if( iEvent.Type() == TEventIf::EUnsetEvent )
+ {
+ // Unset found event
+ // Create callback for change notifier
+ TCallBack callBack( EventCallBack, this );
+ CCallBack* eventCallBack = new (ELeave)CCallBack( callBack,
+ CActive::EPriorityHigh );
+ CleanupStack::PushL( eventCallBack );
+
+ event->Unset( eventCallBack->Status() );
+ reqPending++;
+ eventCallBack->SetActive();
+ User::LeaveIfError( iEventCallBacks.Append( eventCallBack ) );
+ CleanupStack::Pop( eventCallBack );
+ }
+ break;
+ }
+ }
+
+ return reqPending;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: CheckTestcaseEventsL
+
+ Description: Check testcase events.
+
+ Parameters: None
+
+ Return Values: TInt: Request of pending
+
+ Errors/Exceptions: Leaves if CtlEventL leaves
+ Leaves if memory allocation fails
+ Leaves if unset event not found from pending
+ state event list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEventController::CheckTestcaseEventsL()
+ {
+ TInt reqPending = 0;
+ TCallBack callBack( EventCallBack, this );
+ CCallBack* eventCallBack = NULL;
+
+ // Then check testcase event requests
+ TInt count = iEngine->TestCaseArray().Count();
+ eventCallBack = new (ELeave)CCallBack( callBack,
+ CActive::EPriorityHigh );
+ CleanupStack::PushL( eventCallBack );
+ for ( TInt index = 0; index < count; index++ )
+ {
+
+ if( iEngine->TestCaseArray()[index]->CheckCtlEvent( iEvent ))
+ {
+ reqPending++;
+ eventCallBack->SetActive();
+ iEngine->TestCaseArray()[index]->CtlEvent( iEvent,
+ eventCallBack->Status() );
+ User::LeaveIfError( iEventCallBacks.Append( eventCallBack ) );
+ CleanupStack::Pop( eventCallBack );
+ eventCallBack = new (ELeave)CCallBack( callBack,
+ CActive::EPriorityHigh );
+ CleanupStack::PushL( eventCallBack );
+ }
+ }
+ CleanupStack::PopAndDestroy( eventCallBack );
+ return reqPending;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: EventComplete
+
+ Description: EventComplete handles completed event requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions:
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEventController::EventComplete()
+ {
+ iEngine->Logger()->Log( _L( "CTestEventController::EventComplete" ));
+
+ iActiveEventCmds--;
+
+ if( iActiveEventCmds == 0 )
+ {
+ TInt error = KErrNone;
+ TInt count = iEventCallBacks.Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ if( iEventCallBacks[i]->iStatus.Int() != KErrNone )
+ {
+ error = iEventCallBacks[i]->iStatus.Int();
+ break;
+ }
+ }
+ iEventCallBacks.ResetAndDestroy();
+
+ // All event commands are completed
+ if( iRequestStatus )
+ {
+ User::RequestComplete( iRequestStatus, error );
+ }
+ else
+ {
+ // No request was pending, complete immediately
+ iMessage.Complete( error );
+ }
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEventController
+
+ Method: EventCallBack
+
+ Description: static EventCallBack handles completed event requests.
+
+ Parameters: TAny* aTestEventController: in: Test event controller
+
+ Return Values: TInt: returns KErrNone
+
+ Errors/Exceptions:None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEventController::EventCallBack( TAny* aTestEventController )
+ {
+ CTestEventController* controller =
+ (CTestEventController*) aTestEventController;
+ controller->EventComplete();
+ return KErrNone;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestRemoteCmdNotifier class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestProgressNotifier
+
+ Method: CTestRemoteCmdNotifier
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CTestRemoteCmdNotifier::CTestRemoteCmdNotifier( CTestEngine* aEngine,
+ RTestExecution aTestExecution,
+ CTestCaseController* aTestCaseController,
+ CAtsLogger& aAtsLogger ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aEngine ),
+ iTestExecution( aTestExecution ),
+ iState( ETestProgressIdle ),
+ iRemoteTypePckg( iRemoteType ),
+ iMsgSizePckg( iMsgSize ),
+ iTestCaseController( aTestCaseController ),
+ iAtsLogger( aAtsLogger )
+ {
+ CActiveScheduler::Add( this );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::ConstructL( )
+ {
+ __TRACE( KVerbose, ( _L( "CTestRemoteCmdNotifier::ConstructL" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: CTestRemoteCmdNotifier* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestRemoteCmdNotifier fails
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CTestRemoteCmdNotifier* CTestRemoteCmdNotifier::NewL( CTestEngine* aEngine,
+ RTestExecution aTestExecution,
+ CTestCaseController* aTestCaseController,
+ CAtsLogger& aAtsLogger )
+ {
+ CTestRemoteCmdNotifier* self = new ( ELeave ) CTestRemoteCmdNotifier(
+ aEngine, aTestExecution, aTestCaseController, aAtsLogger );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: ~CTestRemoteCmdNotifier
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CTestRemoteCmdNotifier::~CTestRemoteCmdNotifier()
+ {
+ __TRACE( KVerbose, ( _L( "CTestRemoteCmdNotifier::~CTestRemoteCmdNotifier" ) ) );
+ Cancel();
+
+ delete iReceivedMsg;
+ iReceivedMsg = 0;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: EnableReceive
+
+ Description: Prepare to start active object
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::EnableReceive( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestRemoteCmdNotifier::EnableReceive" ) ) );
+
+ iMessage = aMessage;
+ iMessageAvail = ETrue;
+
+ Start( aMessage );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: GetReceivedMsg
+
+ Description: Read received message
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::GetReceivedMsg( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestRemoteCmdNotifier::GetReceivedMsg" ) ) );
+
+ TInt ret = KErrNone;
+ if( iReceivedMsg )
+ {
+ TRAP( ret, aMessage.WriteL( 0, iReceivedMsg->Des() ) );
+ delete iReceivedMsg;
+ iReceivedMsg = 0;
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+
+ // Complete message
+ aMessage.Complete( ret );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: StartL
+
+ Description: Start active object
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::Start( const RMessage2& aMessage )
+ {
+ // Check that this request is not pending!!
+ __ASSERT_ALWAYS( iState != ETestProgressPending,
+ iEngine->PanicClient( EReqPending, aMessage ) );
+ iState = ETestProgressPending;
+ SetActive();
+ // Start first phase of the remote command's operations
+ iTestExecution.NotifyRemoteCmd( iRemoteTypePckg,
+ iMsgSizePckg,
+ iStatus );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: CancelReq
+
+ Description: Cancel the request.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::CancelReq()
+ {
+ if(iMessageAvail)
+ {
+ iMessageAvail = EFalse;
+ iMessage.Complete( KErrCancel );
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if WriteL leaves
+ Leaves if iStatus is not KErrNone or KErrEof
+ Leaves are handled in RunError method
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::RunL()
+ {
+ __TRACE( KVerbose, ( _L( "CTestRemoteCmdNotifier::StartL: iStatus=[%d]" ), iStatus.Int() ) );
+
+ User::LeaveIfError( iStatus.Int() );
+
+ iState = ETestProgressCompleted;
+
+ TInt ret( 0 );
+ switch( iRemoteType )
+ {
+ case EStifCmdSend: // "Sending"
+ {
+ if( ( iMessageAvail == EFalse ) ||
+ ( iMsgSize <= 0 ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ // Delete previous if exists
+ delete iReceivedMsg;
+ iReceivedMsg = 0;
+ // Create new buffer
+ iReceivedMsg = HBufC8::NewL( iMsgSize );
+
+ // Start second phase of the remote command's operations,
+ // buffer is read with GetReceivedMsg
+ TPtr8 tmp = iReceivedMsg->Des();
+ ret = iTestExecution.ReadRemoteCmdInfo( tmp, iRemoteType );
+
+ // Writing received info to UI
+ iMessage.WriteL( 0, iRemoteTypePckg );
+ iMessage.WriteL( 1, iMsgSizePckg );
+
+ // Complete message
+ iMessage.Complete( ret );
+ iMessageAvail = EFalse;
+
+ break;
+ }
+ case EStifCmdReboot: // "Sending"
+ {
+ TRebootParams remoteType;
+ TRebootParamsPckg remoteTypePckg( remoteType );
+ // Start second phase of the remote command's operations
+ ret = iTestExecution.ReadRemoteCmdInfo( remoteTypePckg, iRemoteType );
+ __TRACE( KInit, ( CStifLogger::ERed, _L("REBOOT PHONE (type %d)" ), remoteType.aType ) );
+
+ if( remoteType.aType == CTestModuleIf::EKernelReset )
+ {
+ __TRACE( KInit, ( _L("Rebooting with kernel reset" ) ) );
+ __TRACE( KInit, ( _L("Kernel reset implementation is ongoing, trying different reset..." ) ) );
+ }
+
+#ifdef __WINS__
+ __TRACE( KInit, ( _L("Rebooting with Process kill(WINS)" ) ) );
+ RProcess thisProcess;
+ //thisProcess.SetSystem( ETrue );
+ thisProcess.Kill( KErrNone );
+ thisProcess.Close();
+#else // Hardware specific
+ TInt r( KErrNone );
+ __TRACE( KInit, ( _L("Rebooting with reset module(HW)" ) ) );
+ r = DynamicResetModule( remoteType.aType );
+ if( r != KErrNone )
+ {
+ __TRACE( KInit, ( CStifLogger::EError, _L("This reseting type is failed, trying different reset...")) );
+ }
+#endif // Hardware specific
+
+ // if( !remoteType.aType == CTestModuleIf::EDefaultReset )
+ // Note this change needs an error code tranceiver between reboot
+ // module and engine. (If reboot fails return error code, if reboot
+ // is default then kill process else error code returning)
+
+ // Do process kill as a last option
+ __TRACE( KInit, ( _L("Rebooting with Process kill" ) ) );
+
+ RProcess thisProcess2;
+ thisProcess2.Kill( KErrNone );
+ thisProcess2.Close();
+
+ // If this text is shown in UI something is wrong and this needs some investigation.
+ iEngine->ErrorPrint( 0, _L( "Reboot phone...E.g. disconnect battery!!!" ) );
+ break;
+ }
+ case EStifCmdStoreState: // "Sending"
+ {
+ if( iMessageAvail == EFalse )
+ {
+ User::Leave( KErrGeneral );
+ }
+ TRebootStateParams remoteState;
+ TRebootStateParamsPckg remoteStatePckg( remoteState );
+
+ // Start second phase of the remote command's operations
+ ret = iTestExecution.ReadRemoteCmdInfo( remoteStatePckg,
+ iRemoteType );
+
+ // Get test case information(test module, test case file, etc.)
+ TTestInfo testInfo;
+ iTestCaseController->GetTestCaseInfo( testInfo );
+
+ // Write state informations to the file
+ iEngine->WriteRebootParams( testInfo, remoteState.aCode,
+ remoteState.aName );
+
+ // Write ATS loggers buffers to drive
+ iEngine->FlushAtsLogger();
+
+ // Pause test cases that there cannot make e.g. new store state
+ // calls. iCaseNumber is index type value so increment by one to
+ // get current test case.
+ iEngine->PauseAllTestCases();
+ // Resume current test case
+ iTestCaseController->iTestExecution.Resume();
+
+ // Writing received info to UI
+ iMessage.WriteL( 0, iRemoteTypePckg );
+
+ // Complete message
+ iMessage.Complete( ret );
+ iMessageAvail = EFalse;
+ break;
+ }
+ case EStifCmdGetStoredState: // "Reading, this must be done with two phase"
+ {
+ // Get test case information(test module, test case file, etc.)
+ TTestInfo testInfo;
+ iTestCaseController->GetTestCaseInfo( testInfo );
+
+ TGetRebootStoredParams remoteStoredState;
+ // Read state informations from the file
+ TInt errorCodeToClient =
+ iEngine->ReadRebootParams( testInfo,
+ remoteStoredState.aName,
+ remoteStoredState.aCode );
+
+ TGetRebootStoredParamsPckg remoteStoredPckg( remoteStoredState );
+
+ // Start second phase of the remote command's operations
+ ret = iTestExecution.ReadRemoteCmdInfo( remoteStoredPckg,
+ iRemoteType,
+ errorCodeToClient );
+
+ Start( iMessage ); // Starts active object
+
+ break;
+ }
+ case EStifCmdMeasurement: // "Reading, this must be done with two phase"
+ {
+ TGetMeasurementOptions remoteMeasurementOptions;
+ remoteMeasurementOptions.iOptions = iEngine->StifMeasurement();
+
+ TGetMeasurementOptionsPckg remoteMeasurementPckg( remoteMeasurementOptions );
+
+ // Start second phase of the remote command's operations
+ ret = iTestExecution.ReadRemoteCmdInfo( remoteMeasurementPckg,
+ iRemoteType,
+ KErrNone );
+
+ Start( iMessage ); // Starts active object
+
+ break;
+ }
+
+ case EStifCmdReceive: // "Reading"
+ default:
+ User::Leave( KErrNotFound );
+ break;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRemoteCmdNotifier::DoCancel()
+ {
+ switch ( iState )
+ {
+ case ETestProgressPending:
+ iTestExecution.CancelAsyncRequest( ETestExecutionNotifyRemoteCmd );
+ //iMessage.Complete( KErrCancel );
+ break;
+ case ETestProgressIdle:
+ case ETestProgressCompleted:
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestRemoteCmdNotifier, "CTestRemoteCmdNotifier" );
+ User::Panic( KTestRemoteCmdNotifier, EDoCancelDisorder );
+ break;
+ }
+ iState = ETestProgressIdle;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestRemoteCmdNotifier::RunError( TInt aError )
+ {
+ // Complete message with error
+ if(iMessageAvail)
+ {
+ iMessageAvail = EFalse;
+ iMessage.Complete( aError );
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRemoteCmdNotifier
+
+ Method: ResetL
+
+ Description: Reset HW/WINS. Loads dynamically reset module by name.
+
+ Parameters: CTestModuleIf::TRebootType aResetType: in: Reset type
+
+ Return Values: TInt: Symbian error code.
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestRemoteCmdNotifier::DynamicResetModule(
+ CTestModuleIf::TRebootType aResetType )
+ {
+ __TRACE( KInit, ( _L( "DynamicResetModule()" ) ) );
+ RLibrary resetModule;
+ // Load the module
+ TPtrC dllName;
+ dllName.Set( iEngine->GetDeviceResetDllName() );
+ // Loading should work with and without '.dll' extension.
+ TInt r = resetModule.Load( dllName );
+ if ( r != KErrNone )
+ {
+ __TRACE( KError, ( CStifLogger::EError, _L("Can't initialize reset module[%S], code = %d"), &dllName, r ) );
+ return KErrNotFound;
+ }
+ else
+ {
+ // Print reset module name
+ __TRACE( KInit, ( _L("Loaded reset module[%S]"), &dllName ) );
+ }
+
+ // Verify the UID
+ TUid KUidTestModule = TUid::Uid ( 0x101FB3E7 );
+ TUidType requiredUID( KDynamicLibraryUid, KSharedLibraryUid, KUidTestModule );
+
+ TUidType moduleUID = resetModule.Type();
+ if ( moduleUID != requiredUID )
+ {
+ // New instance can't be created
+ RDebug::Print( ( _L("STIF TF: Reset module has invalid UID. Aborting loading!") ) );
+ __TRACE ( KError, ( CStifLogger::EError, _L("Reset module has invalid UID. Aborting loading!" ) ) );
+ return KErrNotSupported;
+ }
+
+ // Get pointer to first exported function
+ CTestInterfaceFactory libEntry;
+ libEntry = (CTestInterfaceFactory) resetModule.Lookup( 1 );
+ if ( libEntry == NULL )
+ {
+ // New instance can't be created
+ __TRACE ( KError, ( CStifLogger::EError, _L("Can't initialize reset module, NULL libEntry" ) ) );
+ return KErrNoMemory;
+ }
+ else
+ {
+ __TRACE ( KInit, ( _L("Pointer to 1st exported received")));
+ }
+
+ CStifHWReset* reset;
+ reset = NULL;
+
+ // initialize test module
+ __TRACE ( KVerbose, (_L("Calling 1st exported at 0x%x"), (TUint32) libEntry ));
+ TRAPD ( err, reset = (*libEntry)() );
+
+ // Handle leave from test module
+ if ( err != KErrNone )
+ {
+ __TRACE (KError, ( CStifLogger::EError, _L("Leave when calling 1st exported function, code %d"), err));
+ return err;
+ }
+ else if ( reset == NULL ) // Handle NULL from test module init
+ {
+ __TRACE (KError, ( CStifLogger::EError, _L("NULL pointer received when constructing test module")));
+ delete reset;
+
+ // Set error codes
+ return KErrNoMemory;
+ }
+ else
+ {
+ __TRACE (KInit, (_L("Entrypoint successfully called, test module instance at 0x%x"), (TUint32)reset ) );
+ }
+
+ // Calls dynamically loaded reset module's method.
+ TInt ret = reset->DoReset( aResetType );
+ if( ret != KErrNone )
+ {
+ __TRACE (KInit, (_L("DynamicResetModule; DoReset fails with error: %d"), ret ) );
+ return ret;
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestCommandNotifier class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: CTestCommandNotifier
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCommandNotifier::CTestCommandNotifier(CTestEngine* aEngine,
+ RTestExecution aTestExecution):
+ CActive(CActive::EPriorityStandard),
+ iEngine(aEngine),
+ iTestExecution(aTestExecution),
+ iCommandPckg(iCommand)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCommandNotifier::ConstructL( )
+ {
+ __TRACE(KVerbose, (_L("CTestCommandNotifier::ConstructL")));
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+ RTestExecution aTestExecution: in: Handle to RTestExecution
+
+ Return Values: CTestCommandNotifier* : pointer to created object
+
+ Errors/Exceptions: Leaves if construction of CTestCommandNotifier fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCommandNotifier* CTestCommandNotifier::NewL(CTestEngine* aEngine,
+ RTestExecution aTestExecution)
+ {
+ CTestCommandNotifier* self = new (ELeave) CTestCommandNotifier(aEngine, aTestExecution);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: ~CTestCommandNotifier
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCommandNotifier::~CTestCommandNotifier()
+ {
+ __TRACE(KVerbose, (_L("CTestEventNotifier::~CTestEventNotifier")));
+ Cancel();
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: StartL
+
+ Description: Start active object
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCommandNotifier::Start()
+ {
+ __TRACE(KVerbose, (_L("CTestEventNotifier::StartL")));
+
+ TInt res = iTestExecution.NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone);
+ SetActive();
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if iStatus is not KErrNone
+ Leaves if iState is not ETestEventPending
+ Leaves if some leaving method called here leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCommandNotifier::RunL()
+ {
+ __TRACE(KVerbose, (_L("CTestCommandNotifier::RunL: iStatus=[%d]"), iStatus.Int()));
+
+ User::LeaveIfError(iStatus.Int());
+
+ iEngine->ExecuteCommandL(iCommand, iParamsPckg);
+
+ // Set request again
+ Start();
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCommandNotifier::DoCancel()
+ {
+ __TRACE(KVerbose, (_L( "CTestEventNotifier::DoCancel")));
+
+ iTestExecution.CancelAsyncRequest(ETestExecutionNotifyCommand);
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCommandNotifier
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCommandNotifier::RunError(TInt aError)
+ {
+ __TRACE(KError, (CStifLogger::ERed, _L("CTestCommandNotifier::RunError %d"), aError));
+ return KErrNone;
+ }
+
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+// None
+
+// End of File