sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // TSIMmfCtlfrmStep.cpp sl@0: // sl@0: // sl@0: sl@0: // EPOC includes sl@0: #include sl@0: sl@0: // Test system includes sl@0: #include sl@0: #include "TSI_MmfCtlfrmStep.h" sl@0: #include "TSI_MmfCtlfrmSuite.h" sl@0: #include "TSI_MmfCodes.h" sl@0: #include "TSI_MmfEventIds.h" sl@0: #include "ActrlTestUids.h" sl@0: sl@0: #include sl@0: #include sl@0: sl@0: const TUid KTestControllerUid = {KTSIMmfControllerUid}; sl@0: const TUid KTestController2Uid = {KTSIMmfController2Uid}; sl@0: //const TUid KTestDataSourceUid = {KTSIMmfDataSourceUid}; sl@0: //const TUid KTestDataSinkUid = {KTSIMmfDataSinkUid}; sl@0: sl@0: // audio controller, from mmfControllerImplementationUIDs.hrh sl@0: //const TUid KTestAudioControllerUid = {KMmfUidControllerAudio}; sl@0: sl@0: // event values for audio controller testing sl@0: const TInt KDelay = 1000000; sl@0: const TInt KMaxRetries = 12; sl@0: sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrm sl@0: // base class sl@0: sl@0: RTestStepMmfCtlfrm::RTestStepMmfCtlfrm() sl@0: { sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmTest1 sl@0: // base class with preamble / postamble to open and close the test controller sl@0: sl@0: TVerdict RTestStepMmfCtlfrmTest1::OpenL() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityLow; sl@0: iSettings.iPref = EMdaPriorityPreferenceTime; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KTestControllerUid, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmTest1::Close() sl@0: { sl@0: iController.Close(); sl@0: sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmTest2 sl@0: // base class with preamble / postamble to open and close the test controller 2 sl@0: sl@0: TVerdict RTestStepMmfCtlfrmTest2::OpenL() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityLow; sl@0: iSettings.iPref = EMdaPriorityPreferenceTime; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KTestController2Uid, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmTest2::Close() sl@0: { sl@0: iController.Close(); sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmAudio sl@0: // base class with preamble / postamble to open and close the audio controller sl@0: sl@0: TVerdict RTestStepMmfCtlfrmAudio::OpenL() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityHigh; sl@0: iSettings.iPref = EMdaPriorityPreferenceQuality; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KUidCustomTestAudioPlugin, iSettings); sl@0: // error = iController.Open(KTestAudioControllerUid, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: INFO_PRINTF2(_L("Opened Custom Audio Controller, UID 0x%8x"), KUidCustomTestAudioPlugin); sl@0: // Add a source and sink sl@0: _LIT(KTestWavFile, "c:\\TsiMmfCtlfrmData\\test.wav"); sl@0: iFileConfig().iPath = KTestWavFile; sl@0: error = iController.AddDataSource(KUidMmfFileSource, iFileConfig); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("failed to add a data source, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: error = iController.AddDataSink(KUidMmfAudioOutput, KNullDesC8); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("failed to add a data sink, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmAudio::Close() sl@0: { sl@0: iController.Stop(); sl@0: iController.Reset(); sl@0: iController.Close(); sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: sl@0: // Searches for an event sl@0: TVerdict RTestStepMmfCtlfrmAudio::SearchForEvent( TMMFEvent& aEvent ) sl@0: { sl@0: #ifdef EVENT_SEARCH_DISABLED sl@0: WARN_PRINTF1(_L("Warning : SearchForEvent disabled")); sl@0: TMMFEvent dummyEvent; // JS sl@0: aEvent = dummyEvent; // to get rid of compiler warning sl@0: return EPass; sl@0: #else sl@0: sl@0: TVerdict result = EFail; sl@0: sl@0: // status of events sl@0: TRequestStatus timerStatus; sl@0: TRequestStatus eventStatus; sl@0: sl@0: // due to problems with the timer as a member variable sl@0: // added a local timer here sl@0: RTimer myTimer ; sl@0: myTimer.CreateLocal(); sl@0: sl@0: // create an event and initialise with unknown marker sl@0: sl@0: TMMFEventPckg receivedEvent; sl@0: sl@0: // for KMaxRetries attempt to find the event sl@0: for( TInt retries = 0; retries < KMaxRetries; retries++ ) sl@0: { sl@0: // post receive event to controller sl@0: iController.ReceiveEvents( receivedEvent, eventStatus ); sl@0: // start breakout timer to escape sl@0: myTimer.After(timerStatus, KDelay); sl@0: sl@0: // wait for an event to mature sl@0: User::WaitForRequest( eventStatus, timerStatus ); sl@0: sl@0: // check if the command is the event sl@0: // and that a timeout did not occur sl@0: if( IsTimeOut( eventStatus )) sl@0: { sl@0: // cancel the receive events sl@0: CancelReceivedEvents(); sl@0: } sl@0: else if( IsSoughtEvent( aEvent, receivedEvent ) ) sl@0: { sl@0: // cancel the outstanding timer sl@0: User::Check(); sl@0: myTimer.Cancel(); sl@0: // set status to pass since we have found the event sl@0: result = EPass; sl@0: break; sl@0: } sl@0: else sl@0: { sl@0: // We rx'd an event other than expected sl@0: myTimer.Cancel(); sl@0: } sl@0: } sl@0: return result; sl@0: #endif // EVENT_SEARCH_DISABLED sl@0: } sl@0: sl@0: TBool RTestStepMmfCtlfrmAudio::IsTimeOut( TRequestStatus& aEventStatus ) sl@0: { sl@0: return ( aEventStatus == KRequestPending); sl@0: } sl@0: sl@0: TBool RTestStepMmfCtlfrmAudio::IsSoughtEvent( TMMFEvent& aExpectedEvent, TMMFEventPckg& aReceivedEvent ) sl@0: { sl@0: sl@0: TInt expectedUid = aExpectedEvent.iEventType.iUid; sl@0: TInt receivedUid = aReceivedEvent().iEventType.iUid; sl@0: sl@0: // display any events we get sl@0: INFO_PRINTF3(_L("Event received : 0x%08x %d"), sl@0: aReceivedEvent().iEventType.iUid, aReceivedEvent().iErrorCode); sl@0: sl@0: return ((expectedUid == receivedUid) && sl@0: (aExpectedEvent.iErrorCode == aReceivedEvent().iErrorCode)); sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmAudio::CancelReceivedEvents() sl@0: { sl@0: iController.CancelReceiveEvents(); sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmAudioPrimed sl@0: // as above, with source / sink handles, primed in preamble sl@0: sl@0: TVerdict RTestStepMmfCtlfrmAudioPrimed::OpenL() sl@0: { sl@0: // initialise the controller, including adding source and sink; prime it. sl@0: // retain handles to the source and sink so we can verify them after reset sl@0: TInt error = KErrNone; sl@0: TVerdict result = EPass; sl@0: sl@0: iSourceHandlePtr = NULL; sl@0: iSinkHandlePtr = NULL; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityHigh; sl@0: iSettings.iPref = EMdaPriorityPreferenceQuality; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KUidCustomTestAudioPlugin, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: INFO_PRINTF2(_L("Opened Custom Audio Controller, UID 0x%8x"), KUidCustomTestAudioPlugin); sl@0: // Add a source and sink sl@0: _LIT(KTestWavFile, "c:\\TsiMmfCtlfrmData\\test.wav"); sl@0: iFileConfig().iPath = KTestWavFile; sl@0: sl@0: // add a data source with a handle sl@0: iSourceHandlePtr = new (ELeave) TMMFMessageDestination(); sl@0: TMMFMessageDestination& sourceHandle = *iSourceHandlePtr; sl@0: error = iController.AddDataSource(KUidMmfFileSource, iFileConfig, sourceHandle); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("AddDataSource failed, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: // add a data sink with a handle sl@0: iSinkHandlePtr = new (ELeave) TMMFMessageDestination(); sl@0: TMMFMessageDestination& sinkHandle = *iSinkHandlePtr; sl@0: sl@0: error = iController.AddDataSink(KUidMmfAudioOutput, KNullDesC8, sinkHandle); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("AddDataSink failed, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: // prime it sl@0: error = iController.Prime(); sl@0: if(error) sl@0: { sl@0: ERR_PRINTF2(_L("Prime failed, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: // wait for and process the return event from the custom audio controller sl@0: TMMFEvent primeEvent( KPrimeTestId, KErrNone); sl@0: result = SearchForEvent( primeEvent ); sl@0: if( result == EFail ) sl@0: { sl@0: ERR_PRINTF1(_L("Custom audio controller did not return a prime event")); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmAudioPrimed::Close() sl@0: { sl@0: iController.Stop(); sl@0: iController.Reset(); sl@0: delete iSinkHandlePtr; sl@0: delete iSourceHandlePtr; sl@0: iController.Close(); sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmAudioNoSource sl@0: // same as RTestStepMmfCtlfrmAudio, but has no source or sink loaded yet sl@0: TVerdict RTestStepMmfCtlfrmAudioNoSource::OpenL() sl@0: { sl@0: // preamble - load a controller but give it no data source sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityHigh; sl@0: iSettings.iPref = EMdaPriorityPreferenceQuality; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KUidCustomTestAudioPlugin, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: INFO_PRINTF2(_L("Opened Custom Audio Controller, UID 0x%8x"), KUidCustomTestAudioPlugin); sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmDualAudio sl@0: // same as RTestStepMmfCtlfrmAudio, with 2 identical controllers sl@0: sl@0: TVerdict RTestStepMmfCtlfrmDualAudio::OpenL() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityHigh; sl@0: iSettings.iPref = EMdaPriorityPreferenceTime; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open both controllers sl@0: error = iController1.Open(KUidCustomTestAudioPlugin, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController1 failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: INFO_PRINTF2(_L("Controller 1 : Opened Custom Audio Controller, UID 0x%8x"), KUidCustomTestAudioPlugin); sl@0: error = iController2.Open(KUidCustomTestAudioPlugin, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController2 failed to open, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: INFO_PRINTF2(_L("Controller 2 : Opened Custom Audio Controller, UID 0x%8x"), KUidCustomTestAudioPlugin); sl@0: sl@0: // Add source and sink sl@0: // Use two different files to avoid conflict sl@0: _LIT(KTestWavFile1, "c:\\TsiMmfCtlfrmData\\test.wav"); sl@0: _LIT(KTestWavFile2, "c:\\TsiMmfCtlfrmData\\test2.wav"); sl@0: iFileConfig1().iPath = KTestWavFile1; sl@0: iFileConfig2().iPath = KTestWavFile2; sl@0: error = iController1.AddDataSource(KUidMmfFileSource, iFileConfig1); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController1 failed to add a data source, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: error = iController1.AddDataSink(KUidMmfAudioOutput, KNullDesC8); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController1 failed to add a data sink, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: error = iController2.AddDataSource(KUidMmfFileSource, iFileConfig2); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController2 failed to add a data source, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: error = iController2.AddDataSink(KUidMmfAudioOutput, KNullDesC8); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("iController2 failed to add a data sink, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmDualAudio::Close() sl@0: { sl@0: iController1.Stop(); sl@0: iController1.Reset(); sl@0: iController1.Close(); sl@0: sl@0: iController2.Stop(); sl@0: iController2.Reset(); sl@0: iController2.Close(); sl@0: sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: sl@0: // Searches for an event sl@0: TVerdict RTestStepMmfCtlfrmDualAudio::SearchForEvent( TMMFEvent& aEvent, TInt aWhichController ) sl@0: { sl@0: // NB don't worry about EVENT_SEARCH_DISABLED here, sl@0: // as generally we'll be looking for events from the Controller Framework here, sl@0: // not from the custom Audio Controller sl@0: sl@0: TVerdict result = EFail; sl@0: sl@0: // status of events sl@0: TRequestStatus timerStatus ; sl@0: TRequestStatus eventStatus ; sl@0: sl@0: RMMFController* theController; sl@0: // which controller are we searching on? sl@0: if(aWhichController == 1) sl@0: theController = &iController1; sl@0: else if(aWhichController == 2) sl@0: theController = &iController2; sl@0: else sl@0: { sl@0: ERR_PRINTF1(_L("SearchForEvent error : controller must be 1 or 2")); sl@0: return result = EFail; sl@0: } sl@0: sl@0: // due to problems with the timer as a member variable sl@0: // added a local timer here sl@0: RTimer myTimer ; sl@0: myTimer.CreateLocal(); sl@0: sl@0: // create an event and initialise with unknown marker sl@0: sl@0: TMMFEventPckg receivedEvent; sl@0: sl@0: // for KMaxRetries attempt to find the event sl@0: for( TInt retries = 0; retries < KMaxRetries; retries++ ) sl@0: { sl@0: // post receive event to controller sl@0: (*theController).ReceiveEvents( receivedEvent, eventStatus ); sl@0: // start breakout timer to escape sl@0: myTimer.After( timerStatus, KDelay ); sl@0: sl@0: // wait for an event to mature sl@0: User::WaitForRequest( eventStatus, timerStatus ); sl@0: sl@0: // check if the command is the event sl@0: // and that a timeout did not occur sl@0: if( IsTimeOut( eventStatus )) sl@0: { sl@0: // cancel the receive events sl@0: CancelReceivedEvents(aWhichController); sl@0: } sl@0: else if( IsSoughtEvent( aEvent, receivedEvent ) ) sl@0: { sl@0: // cancel the outstanding timer sl@0: User::Check(); sl@0: myTimer.Cancel(); sl@0: // set status to pass since we have found the event sl@0: result = EPass; sl@0: break; sl@0: } sl@0: else sl@0: { sl@0: // We rx'd an event other than expected sl@0: myTimer.Cancel(); sl@0: } sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: TBool RTestStepMmfCtlfrmDualAudio::IsTimeOut( TRequestStatus& aEventStatus ) sl@0: { sl@0: return (aEventStatus == KRequestPending); sl@0: } sl@0: sl@0: TBool RTestStepMmfCtlfrmDualAudio::IsSoughtEvent( TMMFEvent& aExpectedEvent, TMMFEventPckg& aReceivedEvent ) sl@0: { sl@0: sl@0: TInt expectedUid = aExpectedEvent.iEventType.iUid; sl@0: TInt receivedUid = aReceivedEvent().iEventType.iUid; sl@0: sl@0: // display any events we get sl@0: INFO_PRINTF3(_L("Event expected : 0x%08x %d"), sl@0: expectedUid, aExpectedEvent.iErrorCode); sl@0: INFO_PRINTF3(_L("Event received : 0x%08x %d"), sl@0: aReceivedEvent().iEventType.iUid, aReceivedEvent().iErrorCode); sl@0: sl@0: return ((expectedUid == receivedUid) && sl@0: (aExpectedEvent.iErrorCode == aReceivedEvent().iErrorCode)); sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmDualAudio::CancelReceivedEvents(TInt aWhichController) sl@0: { sl@0: RMMFController* theController; sl@0: // which controller are we searching on? sl@0: if(aWhichController == 1) sl@0: theController = &iController1; sl@0: else if(aWhichController == 2) sl@0: theController = &iController2; sl@0: else sl@0: { sl@0: ERR_PRINTF1(_L("CancelReceivedEvents error : controller must be 1 or 2")); sl@0: return; sl@0: } sl@0: (*theController).CancelReceiveEvents(); sl@0: } sl@0: sl@0: // --------------------------- sl@0: // RTestStepMmfCtlfrmVideo sl@0: // base class with preamble / postamble to open and close the video controller sl@0: // NB we're only actually using this to test custom commands sl@0: sl@0: TVerdict RTestStepMmfCtlfrmVideo::OpenL() sl@0: { sl@0: TInt error = KErrNone; sl@0: sl@0: iSettings.iPriority = ETSIMmfPriorityHigh; sl@0: iSettings.iPref = EMdaPriorityPreferenceQuality; sl@0: iSettings.iState = EMMFStateIdle; sl@0: sl@0: // Open a controller sl@0: error = iController.Open(KMmfVideoTestControllerUid, iSettings); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("controller failed to open, error %d"), error); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: INFO_PRINTF2(_L("Opened Custom Video Controller, UID 0x%8x"), KMmfVideoTestControllerUid); sl@0: // Add a source and sink sl@0: _LIT(KTestAviFile, "c:\\VclntITestData\\LongVideo.avi"); sl@0: iFileConfig().iPath = KTestAviFile; sl@0: error = iController.AddDataSource(KUidMmfFileSource, iFileConfig); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("failed to add a data source, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: error = iController.AddDataSink(KUidMmfAudioOutput, KNullDesC8); sl@0: if (error) sl@0: { sl@0: ERR_PRINTF2(_L("failed to add a data sink, error %d"), error); sl@0: Close(); sl@0: return iTestStepResult = EInconclusive; sl@0: } sl@0: sl@0: return iTestStepResult = EPass; sl@0: } sl@0: sl@0: void RTestStepMmfCtlfrmVideo::Close() sl@0: { sl@0: iController.Stop(); sl@0: iController.Reset(); sl@0: iController.Close(); sl@0: // close controller delay - ensure it has time to finish sl@0: // (so we don't get access violation from something trying to dequeue it before it's closed) sl@0: const TTimeIntervalMicroSeconds32 KCloseControllerDelay = 500000L; sl@0: User::After(KCloseControllerDelay); sl@0: } sl@0: