devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp
changeset 0 b8ed18f6c07b
child 2 5c1df44f2eed
equal deleted inserted replaced
-1:000000000000 0:b8ed18f6c07b
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "cdevcommoncontrol.h"
       
    17 #include <a3f/maudiocontext.h> 
       
    18 #include <a3f/maudiocodec.h>
       
    19 
       
    20 
       
    21 CDevCommonControl::CDevCommonControl()
       
    22     {
       
    23     TRACE_CREATE();
       
    24     DP_CONTEXT(CDevCommonControl::CDevCommonControl, CtxDevSound, DPLOCAL);
       
    25     DP_IN();
       
    26     DP_OUT();
       
    27     }
       
    28 
       
    29 
       
    30 CDevCommonControl::~CDevCommonControl()
       
    31     {
       
    32     DP_CONTEXT(CDevCommonControl::~CDevCommonControl, CtxDevSound, DPLOCAL);
       
    33     DP_IN();
       
    34     DP_OUT();
       
    35     }
       
    36 
       
    37 
       
    38 TInt CDevCommonControl::Stop() // from CDevAudioControl
       
    39     {
       
    40     DP_CONTEXT(CDevCommonControl::Stop, CtxDevSound, DPLOCAL);
       
    41     DP_IN();
       
    42 
       
    43     TInt err = KErrNone;
       
    44     switch(iDevAudio->iActiveState)
       
    45         {
       
    46         case EDevSoundAdaptorActive_Active:
       
    47         case EDevSoundAdaptorPaused_Primed:
       
    48             err = iDevAudio->iAudioStream->Stop();
       
    49             if (err == KErrNone)
       
    50                 {
       
    51                 err = iDevAudio->CommitAudioContext();
       
    52                 }
       
    53             if (err == KErrNone)
       
    54                 {
       
    55                 iDevAudio->iActiveState = EDevSoundAdaptorStopping;
       
    56                 }
       
    57             break;
       
    58         case EDevSoundAdaptorGoingActive:
       
    59             iDevAudio->iActiveState = EDevSoundAdaptorStopping;
       
    60             break;
       
    61         case EDevSoundAdaptorInitialised_Idle:
       
    62         	{
       
    63         	//If following condition is true, then we are here because of a
       
    64         	//pre-emption clash in last Commit cycle started from
       
    65         	//CDevCommonControl::ContextEventUpdateWithStateEventNoError.
       
    66         	if(iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
       
    67         		{
       
    68 				err = Unload();
       
    69 				break;
       
    70         		}
       
    71         	}
       
    72         default:
       
    73             break;
       
    74         }
       
    75     
       
    76     if(err == KErrNone)
       
    77         {
       
    78         iDevAudio->iStop = ETrue;
       
    79         }
       
    80     
       
    81     DP0_RET(err,"%d");
       
    82     }
       
    83 
       
    84 
       
    85 TInt CDevCommonControl::Pause() // from CDevAudioControl
       
    86     {
       
    87     DP_CONTEXT(CDevCommonControl::Pause, CtxDevSound, DPLOCAL);
       
    88     DP_IN();
       
    89 
       
    90     TInt err = iDevAudio->iAudioStream->Prime();
       
    91     if ( err == KErrNone)
       
    92         {
       
    93         err = iDevAudio->CommitAudioContext();
       
    94         }
       
    95     if (err == KErrNone)
       
    96         {
       
    97         iDevAudio->iActiveState = EDevSoundAdaptorPausing;
       
    98         }
       
    99     
       
   100     DP0_RET(err,"%d");
       
   101     }
       
   102 
       
   103 
       
   104 TInt CDevCommonControl::Resume() // from CDevAudioControl
       
   105     {
       
   106     DP_CONTEXT(CDevCommonControl::Resume, CtxDevSound, DPLOCAL);
       
   107     DP_IN();
       
   108     
       
   109     TInt err = KErrNone;
       
   110 
       
   111     //If following condition is true, then we are here because of a
       
   112     //pre-emption clash in last Commit cycle started from
       
   113     //CDevCommonControl::ContextEventUpdateWithStateEventAndError.
       
   114     if(iDevAudio->iActiveState == EDevSoundAdaptorInitialised_Idle &&
       
   115     		iDevAudio->iPreviousState == EDevSoundAdaptorUnloading)
       
   116     	{
       
   117 		err = Unload();
       
   118 		DP0_RET(err,"%d");
       
   119     	}
       
   120     else if(iDevAudio->iActiveState != EDevSoundAdaptorPaused_Primed)
       
   121         {
       
   122         DP0_RET(KErrNotReady, "%d");
       
   123         }
       
   124 
       
   125     if(err == KErrNone)
       
   126         {
       
   127         // Populate gain and balance values set in the Paused state and being cached
       
   128         err = iDevAudio->RequestGainAndBalance(this);
       
   129         }
       
   130     if(err == KErrNone)
       
   131         {
       
   132         err = iDevAudio->iAudioStream->Activate();
       
   133         }
       
   134     if ( err == KErrNone)
       
   135         {
       
   136         err = iDevAudio->CommitAudioContext();
       
   137         }
       
   138     if (err == KErrNone)
       
   139         {
       
   140         iDevAudio->iActiveState = EDevSoundAdaptorActivating;
       
   141         }
       
   142     
       
   143     DP0_RET(err,"%d");
       
   144     }
       
   145 
       
   146 
       
   147 void CDevCommonControl::StateEvent(MAudioStream& aStream, TInt aError,  // from MAudioProcessingUnitObserver
       
   148                                     TAudioState aNewState)
       
   149     {
       
   150     DP_CONTEXT(CDevCommonControl::StateEvent, CtxDevSound, DPLOCAL);
       
   151     DP3_IN("activeState %d -> newstate %d, (%d)",
       
   152             iDevAudio->iActiveState, aNewState, aError);
       
   153     
       
   154     __ASSERT_ALWAYS(iDevAudio->iAudioStream == &aStream, Panic(EStreamMismatch));
       
   155     
       
   156     if(aError != KErrNone || iDevAudio->iActiveStreamState != aNewState) 
       
   157         {
       
   158         iDevAudio->iActiveStreamState = aNewState;
       
   159         iStateEventReceived = ETrue;
       
   160         }
       
   161     // Since the audiostream already demoted the state for the most of the cases
       
   162     // only is need  when a error comes were the stream was at the middle of A3f two-phase transition
       
   163     else
       
   164         {
       
   165         switch (aNewState)
       
   166             {
       
   167             case EIdle:
       
   168                 // Demote the stream state
       
   169                 iDevAudio->iActiveStreamState = EIdle;
       
   170                 break;
       
   171             default:
       
   172                 break;
       
   173             }
       
   174         }
       
   175     iStateEventError = aError;
       
   176     
       
   177     DP_OUT();
       
   178     }
       
   179 
       
   180 
       
   181 void CDevCommonControl::ProcessingUnitError(MAudioProcessingUnit* /*aInstance*/, // from MAudioProcessingUnitObserver
       
   182                                                                  TInt aError)
       
   183     {
       
   184     DP_CONTEXT(CDevCommonControl::ProcessingUnitError, CtxDevSound, DPLOCAL);
       
   185     DP_IN();
       
   186 
       
   187     if(iCallbackFromAdaptor == KCallbackNone)   
       
   188         {
       
   189         iProcessingUnitError = aError;
       
   190         iCallbackFromAdaptor = KCallbackProcessingUnitError;
       
   191         iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackProcessingUnitError, aError);
       
   192         }
       
   193     else
       
   194         {
       
   195         // Multiple callbacks from adaptor
       
   196         DP0(DLINFO, "Multiple callbacks from adaptor");
       
   197         }
       
   198     
       
   199     DP_OUT();
       
   200     }
       
   201 
       
   202 
       
   203 void CDevCommonControl::ContextEvent(TUid aEvent, TInt aError) 
       
   204     {
       
   205     DP_CONTEXT(CDevCommonControl::ContextEvent, CtxDevSound, DPLOCAL);
       
   206     DP3_IN("ContextEvent aEvent=%x iActiveState=%d aError=%d",aEvent, iDevAudio->iActiveState, aError);
       
   207 
       
   208     // Can't "switch {...}" on UIDs unfortunately:
       
   209     if (aEvent == KUidA3FContextUpdateComplete)
       
   210         {
       
   211         if(iBeingPreempted)
       
   212             {
       
   213 			if(iStateEventReceived)
       
   214 				{
       
   215 				//use a sub state pattern to make pre-emption cycles like other cycles.
       
   216 				DP1(DLERR,"Preemption error=%d", aError);
       
   217 				iDevAudio->iActiveState = EDevSoundAdaptorBeingPreempted;
       
   218 				if(iPreemptionClash)
       
   219 					{
       
   220 					// remove last request from front of queue without processing it
       
   221 					iAdaptationObserver->PreemptionClashWithStateChange();
       
   222 					iPreemptionClash=EFalse;
       
   223 					}
       
   224 				}
       
   225             else if(!iStateEventReceived && iPreemptionClash)
       
   226         		{
       
   227 				iIgnoreAsyncOpComplete=ETrue;
       
   228 				iPreemptionClash=EFalse;
       
   229         		}
       
   230 			iBeingPreempted=EFalse;
       
   231             }
       
   232 		ContextEventUpdateComplete(aError);
       
   233         }
       
   234 
       
   235     else if ((aEvent == KUidA3FContextCommitUpdate))
       
   236         {
       
   237         iBeingPreempted=EFalse; // clear being preempted
       
   238         iPreemptionClash=EFalse; // clear pre-emption clash flag
       
   239         TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
       
   240         iIgnoreAsyncOpComplete = !adaptorControlsContext;
       
   241             // if we don't control context, always send a PreemptionFinishedCallbackReceived()
       
   242 		iStateEventReceived=EFalse;
       
   243         }
       
   244 
       
   245     else if (aEvent == KUidA3FContextPreEmption)
       
   246         {
       
   247         // clear iBeingPreepted - will be set in ContextEventPreEmption if req
       
   248         iBeingPreempted=EFalse;
       
   249         iPreemptionClash=EFalse; // clear pre-emption clash flag
       
   250         TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
       
   251 		iStateEventReceived=EFalse;
       
   252         iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete
       
   253         ContextEventPreEmption(aEvent, aError);
       
   254         if (!adaptorControlsContext)
       
   255             {
       
   256             iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete
       
   257             }
       
   258         }
       
   259     else if (aEvent == KUidA3FContextPreEmptedCommit)
       
   260         {
       
   261 		DP0(DLINFO,"KUidA3FContextPreEmptedCommit event received, thus clash with Pre-emption");
       
   262         // clear iBeingPreepted - will be set in ContextEventPreEmption if req
       
   263         iBeingPreempted=EFalse;
       
   264         TBool adaptorControlsContext = iAdaptationObserver->AdaptorControlsContext();
       
   265         if (adaptorControlsContext)
       
   266         	{
       
   267 			// push current request that was being processed onto front of queue.
       
   268         	iAdaptationObserver->PreemptionClash();
       
   269         	iPreemptionClash=ETrue;
       
   270         	}
       
   271 		iStateEventReceived=EFalse;
       
   272         iIgnoreAsyncOpComplete=EFalse; // clear being iIgnoreAsyncOpComplete
       
   273         ContextEventPreEmption(aEvent, aError);
       
   274         if (!adaptorControlsContext)
       
   275             {
       
   276             iIgnoreAsyncOpComplete = ETrue; // if we don't control context never do AsyncOpComplete
       
   277             }
       
   278         }
       
   279 
       
   280     else if (aEvent == KUidA3FContextAbort)
       
   281         {
       
   282         ContextEventAbort(aError);
       
   283         }
       
   284 
       
   285     DP_OUT();
       
   286     }
       
   287 
       
   288 
       
   289 void CDevCommonControl::ContextEventAsynchronousPlayCompletion(TInt aError) // from CDevCommonControl
       
   290     {
       
   291     DP_CONTEXT(CDevCommonControl::ContextEventAsynchronousPlayCompletion, CtxDevSound, DPLOCAL);
       
   292     DP_IN();
       
   293     
       
   294 	iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
       
   295 		
       
   296     if (aError)
       
   297         {
       
   298         FinishWithError(aError);
       
   299         }
       
   300            
       
   301     DP_OUT();
       
   302     }
       
   303 
       
   304 
       
   305 void CDevCommonControl::ContextEventAsynchronousInitializeComplete(TInt aError) // from CDevCommonControl
       
   306     {
       
   307     DP_CONTEXT(CDevCommonControl::ContextEventAsynchronousInitializeComplete, CtxDevSound, DPLOCAL);
       
   308     DP_IN();
       
   309     
       
   310     iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
       
   311     iAdaptationObserver->InitializeComplete(aError);
       
   312     
       
   313     DP_OUT();
       
   314     }
       
   315 
       
   316 
       
   317 void CDevCommonControl::ContextEventUpdateComplete(TInt aError) // from CDevCommonControl
       
   318     {
       
   319     DP_CONTEXT(CDevCommonControl::ContextEventUpdateComplete, CtxDevSound, DPLOCAL);
       
   320     DP_IN();
       
   321     
       
   322     if (iStateEventReceived)
       
   323         {
       
   324         iStateEventReceived = EFalse;
       
   325         DP0(DLINFO,"Context event for that does involve state change");         
       
   326         
       
   327         if (aError)
       
   328             {
       
   329             ContextEventUpdateWithStateEventAndError(aError);
       
   330             }
       
   331         else
       
   332             {
       
   333             ContextEventUpdateWithStateEventNoError();
       
   334             }   
       
   335         DP_OUT();
       
   336         return;
       
   337         }
       
   338     
       
   339     DP0(DLINFO,"Context event for that doesn't involve state change");
       
   340 
       
   341     if (aError)
       
   342         {
       
   343         ContextEventUpdateWithoutStateEventButWithError(aError);
       
   344         }
       
   345     else
       
   346         {
       
   347         ContextEventUpdateWithoutStateEventNoError();
       
   348         }
       
   349     
       
   350     DP_OUT();
       
   351     }
       
   352 
       
   353 
       
   354 void CDevCommonControl::ContextEventPreEmption(TUid aEvent, TInt aError) // from CDevCommonControl
       
   355     {
       
   356     DP_CONTEXT(CDevCommonControl::ContextEventPreEmption, CtxDevSound, DPLOCAL);
       
   357     DP_IN();
       
   358     
       
   359     DP1(DLERR,"Preemption error=%d", aError);
       
   360     CDevAudioControl::ContextEvent(aEvent, aError);
       
   361     iBeingPreempted=ETrue;
       
   362         
       
   363     DP_OUT();
       
   364     }
       
   365 
       
   366 
       
   367 void CDevCommonControl::ContextEventAbort(TInt aError) // from CDevCommonControl
       
   368     {
       
   369     DP_CONTEXT(CDevCommonControl::ContextEventAbort, CtxDevSound, DPLOCAL);
       
   370     DP_IN();
       
   371     
       
   372     DP1(DLERR,"Abort error=%d", aError);
       
   373     FinishWithError(aError==KErrAbort ? KErrDied:aError);
       
   374     
       
   375     DP_OUT();
       
   376     }
       
   377 
       
   378 
       
   379 void CDevCommonControl::ContextEventStopDevSoundNotifications() // from CDevCommonControl
       
   380     {
       
   381     DP_CONTEXT(CDevCommonControl::ContextEventStopDevSoundNotifications, CtxDevSound, DPLOCAL);
       
   382     DP_IN();
       
   383     
       
   384     iDevAudio->iAudioStream->UnregisterAudioStreamObserver(*this);
       
   385     iGainControl->UnregisterAudioGainControlObserver(*this);
       
   386     iAudioCodecIf->UnregisterAudioCodecObserver(*this);
       
   387     iAudioCodecIf = NULL;
       
   388     
       
   389     DP_OUT();
       
   390     }
       
   391 
       
   392 
       
   393 void CDevCommonControl::ContextEventPauseResumeSequenceDueToEmptyBuffers(TBool aFlush) // from CDevCommonControl
       
   394     {
       
   395     DP_CONTEXT(CDevCommonControl::ContextEventPauseResumeSequenceDueToEmptyBuffers, CtxDevSound, DPLOCAL);
       
   396     DP_IN();
       
   397     
       
   398     TInt err(KErrNone);
       
   399 
       
   400     if (iPauseResumeSequenceDueToEmptyBuffers)
       
   401         {
       
   402         if (aFlush)
       
   403             {
       
   404             err = iDevAudio->iAudioStream->Flush();
       
   405             }
       
   406         
       
   407         if ((err) or (aFlush==EFalse))
       
   408             {
       
   409             iPauseResumeSequenceDueToEmptyBuffers = EFalse;
       
   410             iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, err);
       
   411             }
       
   412         }
       
   413     else
       
   414         {
       
   415         iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue);    
       
   416         }
       
   417     
       
   418     DP_OUT();
       
   419     }
       
   420 
       
   421 
       
   422 void CDevCommonControl::ContextEventStateDevSoundAdaptorUnloading() // from CDevCommonControl
       
   423     {
       
   424     DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorUnloading, CtxDevSound, DPLOCAL);
       
   425     DP_IN();
       
   426     
       
   427     // Due destruction sequence or reinitialization
       
   428     if (iDevAudio->iClosing or iDevAudio->iReinitializing)
       
   429         {
       
   430         TInt err = Uninitialize();
       
   431         if (err and iDevAudio->iReinitializing)
       
   432             {
       
   433             ContextEventAsynchronousInitializeComplete(err);
       
   434     
       
   435             }
       
   436         
       
   437         DP_OUT();
       
   438         return;
       
   439         }
       
   440 
       
   441     // Notify the user that ProcessingFinished is complete. 
       
   442     // Stop call complete, sent callback.
       
   443     if (iCallbackFromAdaptor != KCallbackNone)
       
   444         {
       
   445         iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue);
       
   446         
       
   447         if (iCallbackFromAdaptor == KCallbackProcessingFinished)
       
   448             {
       
   449             FinishWithError(KErrUnderflow);
       
   450             }
       
   451         else if (iCallbackFromAdaptor == KCallbackProcessingUnitError)
       
   452             {
       
   453             FinishWithError(iProcessingUnitError);
       
   454             }
       
   455         
       
   456         iCallbackFromAdaptor = KCallbackNone;
       
   457         DP_OUT();
       
   458         return;
       
   459         }
       
   460     
       
   461     // Error condition
       
   462     if (iErrorCondition)
       
   463         {
       
   464         FinishWithError(iErrorCondition);
       
   465         iErrorCondition = KErrNone;
       
   466         }
       
   467     else
       
   468         {
       
   469     
       
   470         iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue);
       
   471         }
       
   472     
       
   473     DP_OUT();
       
   474     }
       
   475 
       
   476 
       
   477 void CDevCommonControl::ContextEventStateDevSoundAdaptorLoading() // from CDevCommonControl
       
   478     {
       
   479     DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorLoading, CtxDevSound, DPLOCAL);
       
   480     DP_IN();
       
   481     
       
   482     iDevAudio->RequestGainAndBalance(this); // TODO handle error
       
   483 
       
   484     TInt err = iDevAudio->iAudioStream->Activate();
       
   485     if (err)
       
   486         {
       
   487         DP_OUT();
       
   488         return;
       
   489         }
       
   490     
       
   491     err = iDevAudio->CommitAudioContext();
       
   492     if (err)
       
   493         {
       
   494         ContextEventAsynchronousPlayCompletion(err);
       
   495         DP_OUT();
       
   496         return;
       
   497         }
       
   498     
       
   499     iDevAudio->iActiveState = EDevSoundAdaptorActivating;
       
   500     iAdaptationObserver->AsynchronousOperationComplete(KErrNone, EFalse);
       
   501     
       
   502     DP_OUT();
       
   503     }
       
   504 
       
   505 
       
   506 void CDevCommonControl::ContextEventStateDevSoundAdaptorStopping() // from CDevCommonControl
       
   507     {   
       
   508     DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorStopping, CtxDevSound, DPLOCAL);
       
   509     DP_IN();
       
   510     
       
   511     TInt err = Unload();
       
   512     if (err)
       
   513         {
       
   514         DP0(DLINFO,"Commit failed during stopping");
       
   515         FinishWithError(err);
       
   516         }
       
   517     
       
   518     __ASSERT_DEBUG(err==KErrNone, Panic(ECommitFailedDuringStop));
       
   519     
       
   520     DP_OUT();
       
   521     }
       
   522 
       
   523 
       
   524 void CDevCommonControl::ContextEventStateDevSoundAdaptorBeingPreempted() // from CDevCommonControl
       
   525     {
       
   526     DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorBeingPreempted, CtxDevSound, DPLOCAL);
       
   527     DP_IN();
       
   528     
       
   529     __ASSERT_DEBUG(iDevAudio->iActiveStreamState == EInitialized, Panic(EStreamBeingDemotedToEIdle));
       
   530     FinishWithError(KErrInUse);
       
   531     if (iIgnoreAsyncOpComplete)
       
   532         {
       
   533         iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
       
   534         iIgnoreAsyncOpComplete=EFalse;
       
   535         DP_OUT();
       
   536         return;
       
   537         }
       
   538     
       
   539     ContextEventPauseResumeSequenceDueToEmptyBuffers(EFalse);
       
   540     
       
   541     DP_OUT();
       
   542     }
       
   543 
       
   544 
       
   545 void CDevCommonControl::ContextEventStateDevSoundAdaptorUninitializing() // from CDevCommonControl
       
   546     {
       
   547     DP_CONTEXT(CDevCommonControl::ContextEventStateDevSoundAdaptorUninitializing, CtxDevSound, DPLOCAL);
       
   548     DP_IN();
       
   549     TInt err = RemoveProcessingUnits();
       
   550 
       
   551     if (err == KErrNone)
       
   552         {
       
   553         iDevAudio->iActiveState = EDevSoundAdaptorRemovingProcessingUnits;
       
   554         }
       
   555     else if (iDevAudio->iReinitializing)
       
   556         {
       
   557         ContextEventAsynchronousInitializeComplete(err);
       
   558         }
       
   559     
       
   560     DP_OUT();
       
   561     }
       
   562 
       
   563 
       
   564 void CDevCommonControl::ContextEventErrorStateDevSoundAdaptorActivating(TInt aError) // from CDevCommonControl
       
   565     {
       
   566     DP_CONTEXT(CDevCommonControl::ContextEventErrorStateDevSoundAdaptorActivating, CtxDevSound, DPLOCAL);
       
   567     DP_IN();
       
   568 
       
   569     // If the resume operation fails as result of EmptyBuffers
       
   570     // Notify about operation complete through CallbackFromAdaptorReceived
       
   571     // and continue to allow client to receive PlayError()
       
   572     if (iPauseResumeSequenceDueToEmptyBuffers)
       
   573         {
       
   574         iPauseResumeSequenceDueToEmptyBuffers = EFalse;
       
   575         iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, KErrNone);
       
   576         }
       
   577     
       
   578     iErrorCondition = aError;
       
   579     
       
   580     TInt err = Unload();
       
   581     if (err)
       
   582         {
       
   583         DP0(DLINFO,"Commit failed during stopping");
       
   584         FinishWithError(err);
       
   585         }
       
   586     __ASSERT_DEBUG(err==KErrNone, Panic(ECommitFailedDuringStop));
       
   587     
       
   588     DP_OUT();
       
   589     }
       
   590 
       
   591 
       
   592 void CDevCommonControl::ContextEventErrorStateDevSoundAdaptorBeingPreempted() // from CDevCommonControl
       
   593     {
       
   594     DP_CONTEXT(CDevCommonControl::ContextEventErrorStateDevSoundAdaptorBeingPreempted, CtxDevSound, DPLOCAL);
       
   595     DP_IN();
       
   596     
       
   597 __ASSERT_DEBUG(iDevAudio->iActiveStreamState == EInitialized, Panic(EStreamBeingDemotedToEIdle));
       
   598     FinishWithError(KErrInUse);
       
   599 
       
   600     if(iIgnoreAsyncOpComplete)
       
   601         {
       
   602         iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
       
   603         }
       
   604     
       
   605     DP_OUT();
       
   606     }
       
   607 
       
   608 
       
   609 void CDevCommonControl::ContextEventUpdateWithoutStateEventNoError() // from CDevCommonControl
       
   610     {
       
   611     DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithoutStateEventNoError, CtxDevSound, DPLOCAL);
       
   612     DP2_IN("iActiveState=%d iIgnoreAsyncOpComplete=%d",iDevAudio->iActiveState, iIgnoreAsyncOpComplete);
       
   613     
       
   614     if (iDevAudio->iActiveState != EDevSoundAdaptorRemovingProcessingUnits)
       
   615         {
       
   616 	    if (iIgnoreAsyncOpComplete)
       
   617 	      {
       
   618 	      iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
       
   619 	      iIgnoreAsyncOpComplete = EFalse;
       
   620 	      }
       
   621 	    else
       
   622 	      {
       
   623 	      iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue);
       
   624 	      }
       
   625         DP_OUT();
       
   626         return;
       
   627         }
       
   628 
       
   629     //If the Commit cycle when going into EDevSoundAdaptorRemovingProcessingUnits fails due to pre-emption
       
   630     //clash then we re-apply the client request again.
       
   631     if (iDevAudio->iActiveState == EDevSoundAdaptorRemovingProcessingUnits && iIgnoreAsyncOpComplete)
       
   632     	{
       
   633 		//Pop front of queue to re-apply the request again via CMMFDevSoundSession::DequeueRequest
       
   634 		//from the callback into CMMFDevSoundSession below:
       
   635 		iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
       
   636 		iIgnoreAsyncOpComplete = EFalse;
       
   637 		DP_OUT();
       
   638 		return;
       
   639     	}
       
   640 
       
   641     iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised;
       
   642     
       
   643     if (iDevAudio->iReinitializing)
       
   644         {
       
   645         ContextEventStopDevSoundNotifications();
       
   646         
       
   647         TInt err = iDevAudio->Initialize(iDevAudio->iTargetFormat, iDevAudio->iTargetMode);
       
   648         if(err)
       
   649             {
       
   650             ContextEventAsynchronousInitializeComplete(err);
       
   651             }
       
   652 
       
   653         iDevAudio->iReinitializing = EFalse;
       
   654         DP_OUT();
       
   655         return;
       
   656         }
       
   657     
       
   658     iDevAudio->iClosing = EFalse;
       
   659     iAdaptationObserver->AsynchronousOperationComplete(KErrNone, ETrue);
       
   660     
       
   661     DP_OUT();
       
   662     }
       
   663 
       
   664 
       
   665 void CDevCommonControl::ContextEventUpdateWithoutStateEventButWithError(TInt aError) // from CDevCommonControl
       
   666     {
       
   667     DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithoutStateEventButWithError, CtxDevSound, DPLOCAL);
       
   668     DP_IN();
       
   669 
       
   670     //If flag is true below then it must be due to a stateless normal pre-emption or
       
   671     //stateless pre-emption clash scenario.
       
   672     if(iIgnoreAsyncOpComplete)
       
   673     	{
       
   674 		//If we are in pre-emption clash then callback below will retry the client request again.
       
   675 		iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue); // notify client of end of cycle
       
   676 		iIgnoreAsyncOpComplete = EFalse;
       
   677     	}
       
   678     else
       
   679     	{
       
   680         TDevSoundAdaptorState previousState = iDevAudio->iPreviousState;
       
   681 
       
   682         DP3(DLINFO,"Error with no state change, state %d, previous %d, error %d during Commit cycle",
       
   683                     iDevAudio->iActiveState, previousState, aError);
       
   684 
       
   685         // We can end up here for a number of reasons. For non "mid states", this is
       
   686         // a standard error scenario. For some mid-states (e.g. Activating, Loading etc),
       
   687         // when we try and "promote" the state, this happens when the promotion is rejected
       
   688         // and we handle thus accordingly. For other mid-states the situation is less clear
       
   689         // and we call AsynchronousOperationComplete() with the error assuming the parent
       
   690         // session will deal with it. Whatever we don't want to stay in a mid-state, so
       
   691         // rewind to the previous ("normal") one if we are in one.
       
   692 
       
   693         // Longer term TODO. If the code were refactored so that the InitializeComplete(),
       
   694         // PlayError() etc callback came from AsynchronousOperationComplete() then the
       
   695         // following code might be simpler. Most of the time (at least) we get here because
       
   696         // we are doing a session function, and we can use the function to determine what
       
   697         // to do more easily than relying on the state. As it is, for some mid-states we
       
   698         // try and work out what error code to generate. Not clear this covers 100% cases,
       
   699         // although demotion transitions should not fail, so the problem cases might not occur.
       
   700         //
       
   701 
       
   702 		//If we reach this condition then it is because of rejection/error during Commit cycle.
       
   703 		switch (iDevAudio->iActiveState)
       
   704 			{
       
   705 			case EDevSoundAdaptorInitialising:
       
   706 				{
       
   707 				iDevAudio->iActiveState = previousState;
       
   708 				ContextEventAsynchronousInitializeComplete(aError);
       
   709 				break;
       
   710 				}
       
   711 			case EDevSoundAdaptorLoading:
       
   712 				{
       
   713 				iDevAudio->iActiveState = previousState;
       
   714 				ContextEventAsynchronousPlayCompletion(aError);
       
   715 				break;
       
   716 				}
       
   717 			case EDevSoundAdaptorActivating:
       
   718 				{
       
   719 				iDevAudio->iActiveState = previousState;
       
   720 				ContextEventAsynchronousPlayCompletion(aError);
       
   721 				break;
       
   722 				}
       
   723 			case EDevSoundAdaptorRemovingProcessingUnits:
       
   724 			case EDevSoundAdaptorUninitialising:
       
   725 			case EDevSoundAdaptorUnloading:
       
   726 			case EDevSoundAdaptorStopping:
       
   727 			case EDevSoundAdaptorPausing:
       
   728 			    {
       
   729                 DP2(DLINFO,"Unexpected mid state [%d] when handling error [%d] during Commit cycle, workback", iDevAudio->iActiveState, aError);
       
   730 			    iDevAudio->iActiveState = previousState;
       
   731                 iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
       
   732 			    break;
       
   733 			    }
       
   734 			default:
       
   735 				{
       
   736 				DP2(DLINFO,"Unexpected state [%d] when handling error [%d] during Commit cycle", iDevAudio->iActiveState, aError);
       
   737 		        iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
       
   738 				}
       
   739 			}
       
   740     	}
       
   741        
       
   742     DP_OUT();
       
   743     }
       
   744 
       
   745 
       
   746 void CDevCommonControl::ContextEventUpdateWithStateEventNoError() // from CDevCommonControl 
       
   747     {
       
   748     DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithStateEventNoError, CtxDevSound, DPLOCAL);
       
   749     DP_IN();
       
   750 
       
   751     switch (iDevAudio->iActiveState)
       
   752         {
       
   753     case EDevSoundAdaptorUninitialising:
       
   754         iDevAudio->iActiveState = EDevSoundAdaptorUnitialised_Uninitialised;
       
   755         ContextEventStateDevSoundAdaptorUninitializing();
       
   756         break;
       
   757 
       
   758     case EDevSoundAdaptorInitialising:
       
   759         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
       
   760         ContextEventAsynchronousInitializeComplete(KErrNone);
       
   761         break;
       
   762 
       
   763     case EDevSoundAdaptorUnloading:
       
   764         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
       
   765         ContextEventStateDevSoundAdaptorUnloading();
       
   766         break;
       
   767 
       
   768     case EDevSoundAdaptorLoading:
       
   769         iDevAudio->iActiveState = EDevSoundAdaptorGoingActive;
       
   770         ContextEventStateDevSoundAdaptorLoading();
       
   771         break;
       
   772 
       
   773     case EDevSoundAdaptorStopping:
       
   774         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Idle;
       
   775         ContextEventStateDevSoundAdaptorStopping();
       
   776         break;
       
   777 
       
   778     case EDevSoundAdaptorActivating:
       
   779         iDevAudio->iActiveState = EDevSoundAdaptorActive_Active;
       
   780         ContextEventPauseResumeSequenceDueToEmptyBuffers(EFalse);
       
   781         break;
       
   782         
       
   783     case EDevSoundAdaptorPausing:
       
   784         iDevAudio->iActiveState = EDevSoundAdaptorPaused_Primed;
       
   785         ContextEventPauseResumeSequenceDueToEmptyBuffers(ETrue);
       
   786         break;
       
   787 
       
   788     case EDevSoundAdaptorBeingPreempted:
       
   789         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
       
   790         ContextEventStateDevSoundAdaptorBeingPreempted();
       
   791         break;
       
   792         
       
   793     default:
       
   794         break;
       
   795         }   
       
   796     
       
   797     DP_OUT();
       
   798     }
       
   799 
       
   800 
       
   801 void CDevCommonControl::ContextEventUpdateWithStateEventAndError(TInt aError) // from CDevCommonControl
       
   802     {
       
   803     DP_CONTEXT(CDevCommonControl::ContextEventUpdateWithStateEventAndError, CtxDevSound, DPLOCAL);
       
   804     DP_IN();
       
   805 
       
   806     DP1(DLERR,"ContextEventUpdateWithStateEventAndError error=%d", aError);
       
   807     
       
   808     switch(iDevAudio->iActiveState)
       
   809         {
       
   810     case EDevSoundAdaptorInitialising:
       
   811         iDevAudio->iActiveState = EDevSoundAdaptorCreated_Uninitialised;
       
   812         iAdaptationObserver->InitializeComplete(aError);
       
   813         break;
       
   814         
       
   815     case EDevSoundAdaptorLoading:
       
   816         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
       
   817         FinishWithError(aError);
       
   818         break;
       
   819         
       
   820     case EDevSoundAdaptorActivating:
       
   821         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Idle;
       
   822         ContextEventErrorStateDevSoundAdaptorActivating(aError);
       
   823         break;
       
   824         
       
   825     case EDevSoundAdaptorBeingPreempted:
       
   826         iDevAudio->iActiveState = EDevSoundAdaptorInitialised_Initialised;
       
   827         ContextEventErrorStateDevSoundAdaptorBeingPreempted();
       
   828         break;
       
   829 
       
   830     default:
       
   831         break;
       
   832         }
       
   833     
       
   834     iCallbackFromAdaptor = KCallbackNone;
       
   835     
       
   836     if(!iIgnoreAsyncOpComplete)
       
   837         {
       
   838         iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
       
   839         }
       
   840     else
       
   841         {
       
   842         iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
       
   843         iIgnoreAsyncOpComplete=EFalse;
       
   844         }
       
   845     
       
   846     DP_OUT();
       
   847     }
       
   848 
       
   849 
       
   850 // end of file