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