os/mm/devsound/a3fdevsound/src/devsoundadaptor/cdevcommoncontrol.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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