diff -r 000000000000 -r bde4ae8d615e os/mm/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/mm/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,850 @@ +// 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: +// + +#include "cdevcommoncontrol.h" +#include +#include + + +CDevCommonControl::CDevCommonControl() + { + TRACE_CREATE(); + DP_CONTEXT(CDevCommonControl::CDevCommonControl, CtxDevSound, DPLOCAL); + DP_IN(); + DP_OUT(); + } + + +CDevCommonControl::~CDevCommonControl() + { + DP_CONTEXT(CDevCommonControl::~CDevCommonControl, CtxDevSound, DPLOCAL); + DP_IN(); + DP_OUT(); + } + + +TInt CDevCommonControl::Stop() // from CDevAudioControl + { + DP_CONTEXT(CDevCommonControl::Stop, CtxDevSound, DPLOCAL); + DP_IN(); + + TInt err = KErrNone; + switch(iDevAudio->iActiveState) + { + case EDevSoundAdaptorActive_Active: + case EDevSoundAdaptorPaused_Primed: + err = iDevAudio->iAudioStream->Stop(); + if (err == KErrNone) + { + err = iDevAudio->CommitAudioContext(); + } + if (err == KErrNone) + { + iDevAudio->iActiveState = EDevSoundAdaptorStopping; + } + break; + case EDevSoundAdaptorGoingActive: + iDevAudio->iActiveState = EDevSoundAdaptorStopping; + break; + case EDevSoundAdaptorInitialised_Idle: + { + //If following condition is true, then we are here because of a + //pre-emption clash in last Commit cycle started from + //CDevCommonControl::ContextEventUpdateWithStateEventNoError. + if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading) + { + err = Unload(); + break; + } + } + default: + break; + } + + if(err == KErrNone) + { + iDevAudio->iStop = ETrue; + } + + DP0_RET(err,"%d"); + } + + +TInt CDevCommonControl::Pause() // from CDevAudioControl + { + DP_CONTEXT(CDevCommonControl::Pause, CtxDevSound, DPLOCAL); + DP_IN(); + + TInt err = iDevAudio->iAudioStream->Prime(); + if ( err == KErrNone) + { + err = iDevAudio->CommitAudioContext(); + } + if (err == KErrNone) + { + iDevAudio->iActiveState = EDevSoundAdaptorPausing; + } + + DP0_RET(err,"%d"); + } + + +TInt CDevCommonControl::Resume() // from CDevAudioControl + { + DP_CONTEXT(CDevCommonControl::Resume, CtxDevSound, DPLOCAL); + DP_IN(); + + TInt err = KErrNone; + + //If following condition is true, then we are here because of a + //pre-emption clash in last Commit cycle started from + //CDevCommonControl::ContextEventUpdateWithStateEventAndError. + if(iDevAudio->iActiveState == EDevSoundAdaptorInitialised_Idle && + iDevAudio->iPreviousState == EDevSoundAdaptorUnloading) + { + err = Unload(); + DP0_RET(err,"%d"); + } + else if(iDevAudio->iActiveState != EDevSoundAdaptorPaused_Primed) + { + DP0_RET(KErrNotReady, "%d"); + } + + if(err == KErrNone) + { + // Populate gain and balance values set in the Paused state and being cached + err = iDevAudio->RequestGainAndBalance(this); + } + if(err == KErrNone) + { + err = iDevAudio->iAudioStream->Activate(); + } + if ( err == KErrNone) + { + err = iDevAudio->CommitAudioContext(); + } + if (err == KErrNone) + { + iDevAudio->iActiveState = EDevSoundAdaptorActivating; + } + + DP0_RET(err,"%d"); + } + + +void CDevCommonControl::StateEvent(MAudioStream& aStream, TInt aError, // from MAudioProcessingUnitObserver + TAudioState aNewState) + { + DP_CONTEXT(CDevCommonControl::StateEvent, CtxDevSound, DPLOCAL); + DP3_IN("activeState %d -> newstate %d, (%d)", + iDevAudio->iActiveState, aNewState, aError); + + __ASSERT_ALWAYS(iDevAudio->iAudioStream == &aStream, Panic(EStreamMismatch)); + + if(aError != KErrNone || iDevAudio->iActiveStreamState != aNewState) + { + iDevAudio->iActiveStreamState = aNewState; + iStateEventReceived = ETrue; + } + // Since the audiostream already demoted the state for the most of the cases + // only is need when a error comes were the stream was at the middle of A3f two-phase transition + else + { + switch (aNewState) + { + case EIdle: + // Demote the stream state + iDevAudio->iActiveStreamState = EIdle; + break; + default: + break; + } + } + iStateEventError = aError; + + DP_OUT(); + } + + +void CDevCommonControl::ProcessingUnitError(MAudioProcessingUnit* /*aInstance*/, // from MAudioProcessingUnitObserver + TInt aError) + { + DP_CONTEXT(CDevCommonControl::ProcessingUnitError, CtxDevSound, DPLOCAL); + DP_IN(); + + if(iCallbackFromAdaptor == KCallbackNone) + { + iProcessingUnitError = aError; + iCallbackFromAdaptor = KCallbackProcessingUnitError; + iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackProcessingUnitError, aError); + } + else + { + // Multiple callbacks from adaptor + DP0(DLINFO, "Multiple callbacks from adaptor"); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEvent(TUid aEvent, TInt aError) + { + DP_CONTEXT(CDevCommonControl::ContextEvent, CtxDevSound, DPLOCAL); + DP3_IN("ContextEvent aEvent=%x iActiveState=%d aError=%d",aEvent, iDevAudio->iActiveState, aError); + + // Can't "switch {...}" on UIDs unfortunately: + if (aEvent == KUidA3FContextUpdateComplete) + { + if(iBeingPreempted) + { + if(iStateEventReceived) + { + //use a sub state pattern to make pre-emption cycles like other cycles. + DP1(DLERR,"Preemption error=%d", aError); + iDevAudio->iActiveState = EDevSoundAdaptorBeingPreempted; + if(iPreemptionClash) + { + // remove last request from front of queue without processing it + iAdaptationObserver->PreemptionClashWithStateChange(); + iPreemptionClash=EFalse; + } + } + else if(!iStateEventReceived && iPreemptionClash) + { + iIgnoreAsyncOpComplete=ETrue; + iPreemptionClash=EFalse; + } + iBeingPreempted=EFalse; + } + ContextEventUpdateComplete(aError); + } + + else if ((aEvent == KUidA3FContextCommitUpdate)) + { + iBeingPreempted=EFalse; // clear being preempted + iPreemptionClash=EFalse; // clear pre-emption clash flag + TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext(); + iIgnoreAsyncOpComplete = !adaptorControlsContext; + // if we don't control context, always send a PreemptionFinishedCallbackReceived() + iStateEventReceived=EFalse; + } + + else if (aEvent == KUidA3FContextPreEmption) + { + // clear iBeingPreepted - will be set in ContextEventPreEmption if req + iBeingPreempted=EFalse; + iPreemptionClash=EFalse; // clear pre-emption clash flag + TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext(); + iStateEventReceived=EFalse; + iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete + ContextEventPreEmption(aEvent, aError); + if (!adaptorControlsContext) + { + iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete + } + } + else if (aEvent == KUidA3FContextPreEmptedCommit) + { + DP0(DLINFO,"KUidA3FContextPreEmptedCommit event received, thus clash with Pre-emption"); + // clear iBeingPreepted - will be set in ContextEventPreEmption if req + iBeingPreempted=EFalse; + TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext(); + if (adaptorControlsContext) + { + // push current request that was being processed onto front of queue. + iAdaptationObserver->PreemptionClash(); + iPreemptionClash=ETrue; + } + iStateEventReceived=EFalse; + iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete + ContextEventPreEmption(aEvent, aError); + if (!adaptorControlsContext) + { + iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete + } + } + + else if (aEvent == KUidA3FContextAbort) + { + ContextEventAbort(aError); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventAsynchronousPlayCompletion(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventAsynchronousPlayCompletion, CtxDevSound, DPLOCAL); + DP_IN(); + + iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue); + + if (aError) + { + FinishWithError(aError); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventAsynchronousInitializeComplete(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventAsynchronousInitializeComplete, CtxDevSound, DPLOCAL); + DP_IN(); + + iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue); + iAdaptationObserver->InitializeComplete(aError); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventUpdateComplete(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventUpdateComplete, CtxDevSound, DPLOCAL); + DP_IN(); + + if (iStateEventReceived) + { + iStateEventReceived = EFalse; + DP0(DLINFO,"Context event for that does involve state change"); + + if (aError) + { + ContextEventUpdateWithStateEventAndError(aError); + } + else + { + ContextEventUpdateWithStateEventNoError(); + } + DP_OUT(); + return; + } + + DP0(DLINFO,"Context event for that doesn't involve state change"); + + if (aError) + { + ContextEventUpdateWithoutStateEventButWithError(aError); + } + else + { + ContextEventUpdateWithoutStateEventNoError(); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventPreEmption(TUid aEvent, TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventPreEmption, CtxDevSound, DPLOCAL); + DP_IN(); + + DP1(DLERR,"Preemption error=%d", aError); + CDevAudioControl::ContextEvent(aEvent, aError); + iBeingPreempted=ETrue; + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventAbort(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventAbort, CtxDevSound, DPLOCAL); + DP_IN(); + + DP1(DLERR,"Abort error=%d", aError); + FinishWithError(aError==KErrAbort ? KErrDied:aError); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStopDevSoundNotifications() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStopDevSoundNotifications, CtxDevSound, DPLOCAL); + DP_IN(); + + iDevAudio->iAudioStream->UnregisterAudioStreamObserver(*this); + iGainControl->UnregisterAudioGainControlObserver(*this); + iAudioCodecIf->UnregisterAudioCodecObserver(*this); + iAudioCodecIf = NULL; + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventPauseResumeSequenceDueToEmptyBuffers(TBool aFlush) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventPauseResumeSequenceDueToEmptyBuffers, CtxDevSound, DPLOCAL); + DP_IN(); + + TInt err(KErrNone); + + if (iPauseResumeSequenceDueToEmptyBuffers) + { + if (aFlush) + { + err = iDevAudio->iAudioStream->Flush(); + } + + if ((err) or (aFlush==EFalse)) + { + iPauseResumeSequenceDueToEmptyBuffers = EFalse; + iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, err); + } + } + else + { + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStateDevSoundAdaptorUnloading() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorUnloading, CtxDevSound, DPLOCAL); + DP_IN(); + + // Due destruction sequence or reinitialization + if (iDevAudio->iClosing or iDevAudio->iReinitializing) + { + TInt err = Uninitialize(); + if (err and iDevAudio->iReinitializing) + { + ContextEventAsynchronousInitializeComplete(err); + + } + + DP_OUT(); + return; + } + + // Notify the user that ProcessingFinished is complete. + // Stop call complete, sent callback. + if (iCallbackFromAdaptor != KCallbackNone) + { + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue); + + if (iCallbackFromAdaptor == KCallbackProcessingFinished) + { + FinishWithError(KErrUnderflow); + } + else if (iCallbackFromAdaptor == KCallbackProcessingUnitError) + { + FinishWithError(iProcessingUnitError); + } + + iCallbackFromAdaptor = KCallbackNone; + DP_OUT(); + return; + } + + // Error condition + if (iErrorCondition) + { + FinishWithError(iErrorCondition); + iErrorCondition = KErrNone; + } + else + { + + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStateDevSoundAdaptorLoading() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorLoading, CtxDevSound, DPLOCAL); + DP_IN(); + + iDevAudio->RequestGainAndBalance(this); // TODO handle error + + TInt err = iDevAudio->iAudioStream->Activate(); + if (err) + { + DP_OUT(); + return; + } + + err = iDevAudio->CommitAudioContext(); + if (err) + { + ContextEventAsynchronousPlayCompletion(err); + DP_OUT(); + return; + } + + iDevAudio->iActiveState = EDevSoundAdaptorActivating; + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, EFalse); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStateDevSoundAdaptorStopping() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorStopping, CtxDevSound, DPLOCAL); + DP_IN(); + + TInt err = Unload(); + if (err) + { + DP0(DLINFO,"Commit failed during stopping"); + FinishWithError(err); + } + + __ASSERT_DEBUG(err==KErrNone, Panic(ECommitFailedDuringStop)); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStateDevSoundAdaptorBeingPreempted() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorBeingPreempted, CtxDevSound, DPLOCAL); + DP_IN(); + + __ASSERT_DEBUG(iDevAudio->iActiveStreamState == EInitialized, Panic(EStreamBeingDemotedToEIdle)); + FinishWithError(KErrInUse); + if (iIgnoreAsyncOpComplete) + { + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); + iIgnoreAsyncOpComplete=EFalse; + DP_OUT(); + return; + } + + ContextEventPauseResumeSequenceDueToEmptyBuffers(EFalse); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventStateDevSoundAdaptorUninitializing() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorUninitializing, CtxDevSound, DPLOCAL); + DP_IN(); + TInt err = RemoveProcessingUnits(); + + if (err == KErrNone) + { + iDevAudio->iActiveState = EDevSoundAdaptorRemovingProcessingUnits; + } + else if (iDevAudio->iReinitializing) + { + ContextEventAsynchronousInitializeComplete(err); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventErrorStateDevSoundAdaptorActivating(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventErrorStateDevSoundAdaptorActivating, CtxDevSound, DPLOCAL); + DP_IN(); + + // If the resume operation fails as result of EmptyBuffers + // Notify about operation complete through CallbackFromAdaptorReceived + // and continue to allow client to receive PlayError() + if (iPauseResumeSequenceDueToEmptyBuffers) + { + iPauseResumeSequenceDueToEmptyBuffers = EFalse; + iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, KErrNone); + } + + iErrorCondition = aError; + + TInt err = Unload(); + if (err) + { + DP0(DLINFO,"Commit failed during stopping"); + FinishWithError(err); + } + __ASSERT_DEBUG(err==KErrNone, Panic(ECommitFailedDuringStop)); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventErrorStateDevSoundAdaptorBeingPreempted() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventErrorStateDevSoundAdaptorBeingPreempted, CtxDevSound, DPLOCAL); + DP_IN(); + +__ASSERT_DEBUG(iDevAudio->iActiveStreamState == EInitialized, Panic(EStreamBeingDemotedToEIdle)); + FinishWithError(KErrInUse); + + if(iIgnoreAsyncOpComplete) + { + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventUpdateWithoutStateEventNoError() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithoutStateEventNoError, CtxDevSound, DPLOCAL); + DP2_IN("iActiveState=%d iIgnoreAsyncOpComplete=%d",iDevAudio->iActiveState, iIgnoreAsyncOpComplete); + + if (iDevAudio->iActiveState != EDevSoundAdaptorRemovingProcessingUnits) + { + if (iIgnoreAsyncOpComplete) + { + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); + iIgnoreAsyncOpComplete = EFalse; + } + else + { + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue); + } + DP_OUT(); + return; + } + + //If the Commit cycle when going into EDevSoundAdaptorRemovingProcessingUnits fails due to pre-emption + //clash then we re-apply the client request again. + if (iDevAudio->iActiveState == EDevSoundAdaptorRemovingProcessingUnits && iIgnoreAsyncOpComplete) + { + //Pop front of queue to re-apply the request again via CMMFDevSoundSession::DequeueRequest + //from the callback into CMMFDevSoundSession below: + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); + iIgnoreAsyncOpComplete = EFalse; + DP_OUT(); + return; + } + + iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised; + + if (iDevAudio->iReinitializing) + { + ContextEventStopDevSoundNotifications(); + + TInt err = iDevAudio->Initialize(iDevAudio->iTargetFormat, iDevAudio->iTargetMode); + if(err) + { + ContextEventAsynchronousInitializeComplete(err); + } + + iDevAudio->iReinitializing = EFalse; + DP_OUT(); + return; + } + + iDevAudio->iClosing = EFalse; + iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue); + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventUpdateWithoutStateEventButWithError(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithoutStateEventButWithError, CtxDevSound, DPLOCAL); + DP_IN(); + + //If flag is true below then it must be due to a stateless normal pre-emption or + //stateless pre-emption clash scenario. + if(iIgnoreAsyncOpComplete) + { + //If we are in pre-emption clash then callback below will retry the client request again. + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); // notify client of end of cycle + iIgnoreAsyncOpComplete = EFalse; + } + else + { + TDevSoundAdaptorState previousState = iDevAudio->iPreviousState; + + DP3(DLINFO,"Error with no state change, state %d, previous %d, error %d during Commit cycle", + iDevAudio->iActiveState, previousState, aError); + + // We can end up here for a number of reasons. For non "mid states", this is + // a standard error scenario. For some mid-states (e.g. Activating, Loading etc), + // when we try and "promote" the state, this happens when the promotion is rejected + // and we handle thus accordingly. For other mid-states the situation is less clear + // and we call AsynchronousOperationComplete() with the error assuming the parent + // session will deal with it. Whatever we don't want to stay in a mid-state, so + // rewind to the previous ("normal") one if we are in one. + + // Longer term TODO. If the code were refactored so that the InitializeComplete(), + // PlayError() etc callback came from AsynchronousOperationComplete() then the + // following code might be simpler. Most of the time (at least) we get here because + // we are doing a session function, and we can use the function to determine what + // to do more easily than relying on the state. As it is, for some mid-states we + // try and work out what error code to generate. Not clear this covers 100% cases, + // although demotion transitions should not fail, so the problem cases might not occur. + // + + //If we reach this condition then it is because of rejection/error during Commit cycle. + switch (iDevAudio->iActiveState) + { + case EDevSoundAdaptorInitialising: + { + iDevAudio->iActiveState = previousState; + ContextEventAsynchronousInitializeComplete(aError); + break; + } + case EDevSoundAdaptorLoading: + { + iDevAudio->iActiveState = previousState; + ContextEventAsynchronousPlayCompletion(aError); + break; + } + case EDevSoundAdaptorActivating: + { + iDevAudio->iActiveState = previousState; + ContextEventAsynchronousPlayCompletion(aError); + break; + } + case EDevSoundAdaptorRemovingProcessingUnits: + case EDevSoundAdaptorUninitialising: + case EDevSoundAdaptorUnloading: + case EDevSoundAdaptorStopping: + case EDevSoundAdaptorPausing: + { + DP2(DLINFO,"Unexpected mid state [%d] when handling error [%d] during Commit cycle, workback", iDevAudio->iActiveState, aError); + iDevAudio->iActiveState = previousState; + iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue); + break; + } + default: + { + DP2(DLINFO,"Unexpected state [%d] when handling error [%d] during Commit cycle", iDevAudio->iActiveState, aError); + iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue); + } + } + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventUpdateWithStateEventNoError() // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithStateEventNoError, CtxDevSound, DPLOCAL); + DP_IN(); + + switch (iDevAudio->iActiveState) + { + case EDevSoundAdaptorUninitialising: + iDevAudio->iActiveState = EDevSoundAdaptorUnitialised_Uninitialised; + ContextEventStateDevSoundAdaptorUninitializing(); + break; + + case EDevSoundAdaptorInitialising: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised; + ContextEventAsynchronousInitializeComplete(KErrNone); + break; + + case EDevSoundAdaptorUnloading: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised; + ContextEventStateDevSoundAdaptorUnloading(); + break; + + case EDevSoundAdaptorLoading: + iDevAudio->iActiveState = EDevSoundAdaptorGoingActive; + ContextEventStateDevSoundAdaptorLoading(); + break; + + case EDevSoundAdaptorStopping: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Idle; + ContextEventStateDevSoundAdaptorStopping(); + break; + + case EDevSoundAdaptorActivating: + iDevAudio->iActiveState = EDevSoundAdaptorActive_Active; + ContextEventPauseResumeSequenceDueToEmptyBuffers(EFalse); + break; + + case EDevSoundAdaptorPausing: + iDevAudio->iActiveState = EDevSoundAdaptorPaused_Primed; + ContextEventPauseResumeSequenceDueToEmptyBuffers(ETrue); + break; + + case EDevSoundAdaptorBeingPreempted: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised; + ContextEventStateDevSoundAdaptorBeingPreempted(); + break; + + default: + break; + } + + DP_OUT(); + } + + +void CDevCommonControl::ContextEventUpdateWithStateEventAndError(TInt aError) // from CDevCommonControl + { + DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithStateEventAndError, CtxDevSound, DPLOCAL); + DP_IN(); + + DP1(DLERR,"ContextEventUpdateWithStateEventAndError error=%d", aError); + + switch(iDevAudio->iActiveState) + { + case EDevSoundAdaptorInitialising: + iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised; + iAdaptationObserver->InitializeComplete(aError); + break; + + case EDevSoundAdaptorLoading: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised; + FinishWithError(aError); + break; + + case EDevSoundAdaptorActivating: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Idle; + ContextEventErrorStateDevSoundAdaptorActivating(aError); + break; + + case EDevSoundAdaptorBeingPreempted: + iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised; + ContextEventErrorStateDevSoundAdaptorBeingPreempted(); + break; + + default: + break; + } + + iCallbackFromAdaptor = KCallbackNone; + + if(!iIgnoreAsyncOpComplete) + { + iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue); + } + else + { + iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); + iIgnoreAsyncOpComplete=EFalse; + } + + DP_OUT(); + } + + +// end of file