diff -r efebd1779a59 -r c1e808730d6c devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp --- a/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp Fri Apr 16 16:34:49 2010 +0300 +++ b/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp Mon May 03 13:56:28 2010 +0300 @@ -26,15 +26,15 @@ #define SYMBIAN_DEBPRN0(str) RDebug::Print(str, this) #define SYMBIAN_DEBPRN1(str, val1) RDebug::Print(str, this, val1) #define SYMBIAN_DEBPRN2(str, val1, val2) RDebug::Print(str, this, val1, val2) +#define SYMBIAN_DEBPRN3(str, val1, val2, val3) RDebug::Print(str, this, val1, val2, val3) #else #define SYMBIAN_DEBPRN0(str) #define SYMBIAN_DEBPRN1(str, val1) #define SYMBIAN_DEBPRN2(str, val1, val2) +#define SYMBIAN_DEBPRN3(str, val1, val2, val3) #endif //_DEBUG -//Assume that we can have two user request and one callback request -//at the same time (maximum). -const TInt KMaxQueueRequest = 3; +const TInt KMaxQueueRequest = 6; // MEMBER FUNCTIONS @@ -222,14 +222,23 @@ } // +// NeedToQueue - mid-commit cycle or async queue start AO is active +// +TBool CMMFDevSoundSession::NeedToQueue() const + { + return iOperationCompletePending || iAsyncQueueStart->IsActive(); + } + +// // CMMFDevSoundSession::ServiceL // (other items were commented in a header). // void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage) { SYMBIAN_DEBPRN2(_L("\nCMMFDevSoundSession[0x%x] NEW REQUEST %02x while pending=%d"), - aMessage.Function(), iOperationCompletePending || iAsyncQueueStart->IsActive()); - if( iOperationCompletePending || iAsyncQueueStart->IsActive()) + aMessage.Function(), NeedToQueue()); + + if(NeedToQueue()) { // if not possible to service now, then queue request EnqueueRequest(aMessage); @@ -256,12 +265,17 @@ // void CMMFDevSoundSession::DoServiceRequestL(const RMmfIpcMessage& aMessage) { + iRequestBeingServiced.SetMessage(aMessage); iAsyncQueueStart->Cancel(); // just in case. - TMMFMessageDestinationPckg destinationPckg; + ResetNotifiedError(); + + TMMFMessageDestinationPckg destinationPckg; MmfMessageUtil::ReadL(aMessage, 0, destinationPckg); + SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - DestinationHandle [%d] InterfaceId [%d] "), destinationPckg().DestinationHandle(), destinationPckg().InterfaceId()); if ((destinationPckg().DestinationHandle() == KMMFObjectHandleDevSound) && (destinationPckg().InterfaceId() == KUidInterfaceMMFDevSound)) { + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - Request [%d]"), aMessage.Function()); TBool complete = EFalse; switch(aMessage.Function()) { @@ -437,23 +451,37 @@ // Complete the message // Synchronous requests & Pseudo-asynchronous aMessage.Complete(KErrNone); - } - // Note: There are operations that not complete the message using the following flag - // So if the message is not completed, cannot be assumed that there is an operation pending - - if(iOperationCompletePending) - { - // Keep a copy of the message for Asynchronous requests & Pseudo-asynchronous - iRequestBeingServiced.SetMessage(aMessage); + + // Store function if we need to re-apply it again due to pre-emption clash + if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous) + { + iRedoFunction = aMessage.Function(); + } } } + else if (aMessage.Function() == RMessage2::EDisConnect) + { + TBool complete = iAdapter->CloseDevSound(); + if(!complete) + { + iRequestBeingServiced.SetMessage(aMessage); + iOperationCompletePending = ETrue; + ResetNotifiedError(); + } + else + { + // if we get here, iClosing wait will have been started and we'd be waiting + iClosingWait->AsyncStop(); + } + } else { // If there's a CI extension, see if that handles this request TInt err = KErrNotSupported; if (iCIExtension) { - iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest [%d]"), aMessage.Function()); + iOperationCompletePending = ETrue; iHandlingExtdCI = ETrue; TRAPD(err2, err = iCIExtension->HandleMessageL(aMessage)); if (err2) @@ -462,6 +490,7 @@ } iOperationCompletePending = EFalse; iHandlingExtdCI = EFalse; + SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest[%d] - Exit with Error[%d] "), aMessage.Function(),err); } if (err != KErrNone) @@ -472,6 +501,80 @@ } } +void CMMFDevSoundSession::DoServiceAlreadyCompletedRequestL(const TInt aFunction) + { + ResetNotifiedError(); + + switch(aFunction) + { + case EMMFDevSoundProxyInitialize1: + DoAlreadyCompletedInitialize1L(); + break; + case EMMFDevSoundProxyInitialize2: + DoAlreadyCompletedInitialize2L(); + break; + case EMMFDevSoundProxyInitialize4: + DoAlreadyCompletedInitialize4L(); + break; + case EMMFDevSoundProxyPlayInit: + DoAlreadyCompletedPlayInitL(); + break; + case EMMFDevSoundProxyRecordInit: + DoAlreadyCompletedRecordInitL(); + break; + case EMMFDevSoundProxyPlayTone: + DoAlreadyCompletedPlayToneL(); + break; + case EMMFDevSoundProxyPlayDualTone: + DoAlreadyCompletedPlayDualToneL(); + break; + case EMMFDevSoundProxyPlayDTMFString: + DoAlreadyCompletedPlayDTMFStringL(); + break; + case EMMFDevSoundProxyPlayToneSequence: + DoAlreadyCompletedPlayToneSequenceL(); + break; + case EMMFDevSoundProxyPlayFixedSequence: + DoAlreadyCompletedPlayFixedSequenceL(); + break; + default: + User::Leave(KErrNotSupported); + break; + } + + } + +void CMMFDevSoundSession::HandleAlreadyCompletedRequest() + { + TRAPD(err,DoServiceAlreadyCompletedRequestL(iRedoFunction)); + + if (err != KErrNone) + { + switch(iRedoFunction) + { + case EMMFDevSoundProxyInitialize1: + case EMMFDevSoundProxyInitialize2: + case EMMFDevSoundProxyInitialize4: + InitializeComplete(err); + break; + case EMMFDevSoundProxyPlayInit: + PlayError(err); + break; + case EMMFDevSoundProxyRecordInit: + RecordError(err); + break; + case EMMFDevSoundProxyPlayTone: + case EMMFDevSoundProxyPlayDualTone: + case EMMFDevSoundProxyPlayDTMFString: + case EMMFDevSoundProxyPlayToneSequence: + case EMMFDevSoundProxyPlayFixedSequence: + ToneFinished(err); + break; + default: + break; + } + } + } void CMMFDevSoundSession::EnqueueRequest(const RMmfIpcMessage& aMessage) { @@ -499,11 +602,13 @@ // TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage) { - TInt err = iMsgQueue.Open(aMessage, 2); // a global queue. + iMsgQueue.Close(); // close if already open + TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread User::LeaveIfError(err); DoSetClientConfigL();// added here instead of the CreateL() TMMFDevSoundProxySettingsPckg devSoundBuf; MmfMessageUtil::ReadL(aMessage,1,devSoundBuf); + iCachedClientData = devSoundBuf; TMMFState mode = devSoundBuf().iMode; iAdapter->InitializeL(mode); iBufferPlay = NULL; @@ -515,16 +620,32 @@ } // +// CMMFDevSoundSession::DoAlreadyCompletedInitialize1L +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedInitialize1L() + { + TMMFState mode = iCachedClientData().iMode; + iAdapter->InitializeL(mode); + iBufferPlay = NULL; + iPlayErrorOccured = EFalse; + // Flag to queue any further request + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoInitialize2L // (other items were commented in a header). // TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage) { - TInt err = iMsgQueue.Open(aMessage, 2); // a global queue. + iMsgQueue.Close(); // close if already open + TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread User::LeaveIfError(err); DoSetClientConfigL();// added here instead of the CreateL() TMMFDevSoundProxySettingsPckg devSoundBuf; MmfMessageUtil::ReadL(aMessage,1,devSoundBuf); + iCachedClientData = devSoundBuf; TUid HWDev = devSoundBuf().iHWDev; TMMFState mode = devSoundBuf().iMode; iAdapter->InitializeL(HWDev, mode); @@ -534,16 +655,31 @@ } // +// CMMFDevSoundSession::DoAlreadyCompletedInitialize2L +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedInitialize2L() + { + TUid HWDev = iCachedClientData().iHWDev; + TMMFState mode = iCachedClientData().iMode; + iAdapter->InitializeL(HWDev, mode); + iBufferPlay = NULL; + iPlayErrorOccured = EFalse; + } + +// // CMMFDevSoundSession::DoInitialize4L // (other items were commented in a header). // TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage) { - TInt err = iMsgQueue.Open(aMessage, 2); // a global queue. + iMsgQueue.Close(); + TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread User::LeaveIfError(err); DoSetClientConfigL();// added here instead of the CreateL() TMMFDevSoundProxySettingsPckg devSoundBuf; aMessage.ReadL(TInt(1),devSoundBuf); + iCachedClientData = devSoundBuf; TFourCC desiredFourCC = devSoundBuf().iDesiredFourCC; TMMFState mode = devSoundBuf().iMode; iAdapter->InitializeL(desiredFourCC, mode); @@ -556,6 +692,21 @@ } // +// CMMFDevSoundSession::DoAlreadyCompletedInitialize4L +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedInitialize4L() + { + TFourCC desiredFourCC = iCachedClientData().iDesiredFourCC; + TMMFState mode = iCachedClientData().iMode; + iAdapter->InitializeL(desiredFourCC, mode); + iBufferPlay = NULL; + iPlayErrorOccured = EFalse; + // Flag to queue any further request + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoCancelInitialize // (other items were commented in a header). // @@ -774,6 +925,16 @@ } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayInitL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayInitL() + { + iAdapter->PlayInitL(); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoRecordInitL // (other items were commented in a header). // @@ -785,6 +946,16 @@ } // +// CMMFDevSoundSession::DoAlreadyCompletedRecordInitL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedRecordInitL() + { + iAdapter->RecordInitL(); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoPlayDataL // (other items were commented in a header). // @@ -826,7 +997,8 @@ // TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/) { - // Sometimes Stop is not involved on a commit cycle + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoStopL - Enter")); + // Sometimes Stop is not involved on a commit cycle TBool completed = iAdapter->Stop(); if (completed) { @@ -835,6 +1007,7 @@ iChunk.Close(); } iOperationCompletePending = !completed; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoStopL - Exit. Return value is [%d]"), completed); return completed; } @@ -855,38 +1028,70 @@ // TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage) { - TMMFDevSoundProxySettingsPckg devSoundBuf; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Enter")); + TMMFDevSoundProxySettingsPckg devSoundBuf; aMessage.ReadL(TInt(1),devSoundBuf); + iCachedClientData = devSoundBuf; TInt frequency = devSoundBuf().iFrequencyOne; TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration); iAdapter->PlayToneL(frequency, duration); iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Exit. Return value is [%d]"), ETrue); return ETrue; } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayToneL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayToneL() + { + TInt frequency = iCachedClientData().iFrequencyOne; + TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration); + iAdapter->PlayToneL(frequency, duration); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoPlayDualToneL // (other items were commented in a header). // TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage) { - TMMFDevSoundProxySettingsPckg devSoundBuf; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Enter")); + TMMFDevSoundProxySettingsPckg devSoundBuf; aMessage.ReadL(TInt(1),devSoundBuf); + iCachedClientData = devSoundBuf; TInt frequencyOne = devSoundBuf().iFrequencyOne; TInt frequencyTwo = devSoundBuf().iFrequencyTwo; TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration); iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration); iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Exit. Return value is [%d]"), ETrue); return ETrue; } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL() + { + TInt frequencyOne = iCachedClientData().iFrequencyOne; + TInt frequencyTwo = iCachedClientData().iFrequencyTwo; + TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration); + iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoPlayDTMFStringL // (other items were commented in a header). // TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage) { - TInt dtmfLength = aMessage.GetDesLength(2); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Enter")); + TInt dtmfLength = aMessage.GetDesLength(2); if(iDtmfString) { @@ -900,16 +1105,28 @@ iAdapter->PlayDTMFStringL(*iDtmfString); iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Exit. Return value is [%d]"), ETrue); return ETrue; } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL() + { + iAdapter->PlayDTMFStringL(*iDtmfString); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoPlayToneSequenceL // (other items were commented in a header). // TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage) { - TInt toneLength = aMessage.GetDesLength(1); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Enter")); + TInt toneLength = aMessage.GetDesLength(1); if(iToneSeqBuf) { @@ -923,36 +1140,61 @@ iAdapter->PlayToneSequenceL(*iToneSeqBuf); iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Exit. Return value is [%d]"), ETrue); return ETrue; } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL() + { + iAdapter->PlayToneSequenceL(*iToneSeqBuf); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoPlayFixedSequenceL // (other items were commented in a header). // TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage) { - TPckgBuf buf; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Enter")); + TPckgBuf buf; aMessage.ReadL(TInt(1),buf); TInt seqNum = buf(); - + iSeqNum = seqNum; iAdapter->PlayFixedSequenceL(seqNum); iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Exit. Return value is [%d]"), ETrue); return ETrue; } // +// CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL +// (other items were commented in a header). +// +void CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL() + { + iAdapter->PlayFixedSequenceL(iSeqNum); + iOperationCompletePending = ETrue; + } + +// // CMMFDevSoundSession::DoSetDTMFLengthsL // (other items were commented in a header). // TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage) { - TMMFDevSoundProxySettingsPckg devSoundBuf; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Enter")); + TMMFDevSoundProxySettingsPckg devSoundBuf; aMessage.ReadL(TInt(1),devSoundBuf); TTimeIntervalMicroSeconds32 toneOnLength = devSoundBuf().iToneOnLength; TTimeIntervalMicroSeconds32 toneOffLength = devSoundBuf().iToneOffLength; TTimeIntervalMicroSeconds32 pauseLength = devSoundBuf().iPauseLength; User::LeaveIfError(iAdapter->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength)); + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Exit. Return value is [%d]"), ETrue); return ETrue; } @@ -962,11 +1204,13 @@ // TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage) { - TMMFDevSoundProxySettingsPckg devSoundBuf; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Enter")); + TMMFDevSoundProxySettingsPckg devSoundBuf; aMessage.ReadL(TInt(1),devSoundBuf); TTimeIntervalMicroSeconds duration = devSoundBuf().iDuration; User::LeaveIfError(iAdapter->SetVolumeRamp(duration)); iOperationCompletePending = EFalse; // Volume ramp doesn't result on commit + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Exit. Return value is [%d]"), ETrue); return ETrue; // operation complete } @@ -1044,13 +1288,14 @@ // TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage) { - TPckgBuf countRepeat; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Enter")); + TPckgBuf countRepeat; aMessage.ReadL(TInt(1),countRepeat); TPckgBuf repeatTS; aMessage.ReadL(TInt(2),repeatTS); User::LeaveIfError(iAdapter->SetToneRepeats(countRepeat(), repeatTS())); - + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Exit. Return value is [%d]"), ETrue); return ETrue; } @@ -1076,11 +1321,13 @@ TBool CMMFDevSoundSession::DoFixedSequenceCountL( const RMmfIpcMessage& aMessage) { - TPckgBuf fixSeqCountPckg; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Enter")); + TPckgBuf fixSeqCountPckg; TInt fixSeqCount = iAdapter->FixedSequenceCount(); fixSeqCountPckg = fixSeqCount; aMessage.WriteL(TInt(2),fixSeqCountPckg); + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Exit. Return value is [%d]"), ETrue); return ETrue; } @@ -1339,7 +1586,8 @@ // void CMMFDevSoundSession::FlushEventQueue() { - if(iMsgQueue.Handle() != 0) + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Enter")); + if(iMsgQueue.Handle() != 0) { TMMFDevSoundQueueItem queueItem; TInt err = KErrNone; @@ -1347,12 +1595,14 @@ { err = iMsgQueue.Receive(queueItem); } - } + } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Exit")); } void CMMFDevSoundSession::FilterQueueEvent(TMMFDevSoundProxyRequest aRequest) { - if(iMsgQueue.Handle() != 0) + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Enter")); + if(iMsgQueue.Handle() != 0) { // Pop and push events result at the queue // can be seen as "circular list" @@ -1380,6 +1630,7 @@ } } } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Exit")); } // @@ -1388,14 +1639,28 @@ // void CMMFDevSoundSession::Disconnect(const RMessage2& aMessage) { - TBool complete = iAdapter->CloseDevSound(); - if(!complete) - { - iRequestBeingServiced.SetMessage(aMessage); - iOperationCompletePending = ETrue; - iClosingWait->Start(); - } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Enter")); + if (NeedToQueue()) + { + // if we are in the middle of something, enqueue and wait + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Add to queue")); + EnqueueRequest(aMessage); + iClosingWait->Start(); + } + else + { + // else do now. Enter ActiveSchedulerWait to wait for AsyncOpComplete + TBool complete = iAdapter->CloseDevSound(); + if(!complete) + { + iRequestBeingServiced.SetMessage(aMessage); + iOperationCompletePending = ETrue; + ResetNotifiedError(); + iClosingWait->Start(); + } + } CSession2::Disconnect(aMessage); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Exit")); } @@ -1507,11 +1772,13 @@ // void CMMFDevSoundSession::ToneFinished(TInt aError) { - TMMFDevSoundQueueItem item; + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Enter. Error [%d]"), aError); + TMMFDevSoundQueueItem item; item.iRequest = EMMFDevSoundProxyTFEvent; item.iErrorCode = aError; // assumes sufficient space in the queue so ignores the return value iMsgQueue.Send(item); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Exit")); } // @@ -1553,7 +1820,7 @@ // void CMMFDevSoundSession::PlayError(TInt aError) { - SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError [%d]"), aError); + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError - Enter [%d]"), aError); // Set play error flag to ignore following PlayData requests iPlayErrorOccured = ETrue; @@ -1564,6 +1831,7 @@ iChunk.Close(); // assumes sufficient space in the queue so ignores the return value iMsgQueue.Send(item); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PlayError - Exit")); } // @@ -1647,7 +1915,7 @@ // void CMMFDevSoundSession::CallbackFromAdaptorReceived(TInt aType, TInt aError) { - + SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Enter. Type[%d] Error[%d]"), aType, aError); if(aType == KCallbackRecordPauseComplete) { TMMFDevSoundQueueItem item; @@ -1666,12 +1934,17 @@ } else if (aType == KCallbackFlushComplete) { - iRequestBeingServiced.Complete(aError); - iOperationCompletePending = EFalse; + if(!iHandlingExtdCI && iRequestBeingServiced.Function()==EMMFDevSoundProxyEmptyBuffers) + { + //If we come here then it is due to a EMMFDevSoundProxyEmptyBuffers request from client. + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Calling TMMFDevSoundRequest::Complete on iRequestBeingServiced")); + iRequestBeingServiced.Complete(aError); + iOperationCompletePending = EFalse; + } } else { - if( iOperationCompletePending ) + if( NeedToQueue() ) { // If not possible to service now, then queue request // Encapsule the request @@ -1692,6 +1965,7 @@ } } } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Exit")); } @@ -1701,8 +1975,10 @@ // void CMMFDevSoundSession::PreemptionStartedCallbackReceived() { - // Solution: Enqueue any request that arrives before preemption is completed + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Enter")); + // Solution: Enqueue any request that arrives before preemption is completed iOperationCompletePending = ETrue; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Exit")); } // @@ -1711,16 +1987,46 @@ // void CMMFDevSoundSession::PreemptionFinishedCallbackReceived(TBool aCanStartNewOperation) { + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Enter")); if (iHandlingExtdCI) { // we are in the middle of handling a CI, so ignore - will handle later when unwinding - return; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit. Exiting from if block for CI")); + return; } iOperationCompletePending = EFalse; if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 ) { DequeueRequest(); } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit")); + } + +// +// CMMFDevSoundSession::PreemptionClash +// (other items were commented in a header). +// +void CMMFDevSoundSession::PreemptionClash() + { + //assumes sufficient space in the queue so ignore the return value + iQueuedRequests.Insert(iRequestBeingServiced, 0); + iPreemptionClash=ETrue; + } + +// +// CMMFDevSoundSession::PreemptionClashWithStateChange +// (other items were commented in a header). +// +void CMMFDevSoundSession::PreemptionClashWithStateChange() + { + #ifdef _DEBUG + TMMFDevSoundRequest msg = iQueuedRequests[0]; + // message being removed should be the one we previously pushed via PreemptionClash() + __ASSERT_DEBUG(iRequestBeingServiced==msg, Panic(ERequestBeingServicedMismatch)); + #endif + // remove without processing request with AsynchronousOperationComplete() completing the message + iQueuedRequests.Remove(0); + iPreemptionClash=EFalse; } // @@ -1754,13 +2060,15 @@ // void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent) { - TMMFDevSoundQueueItem item; + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Enter")); + TMMFDevSoundQueueItem item; item.iRequest = EMMFDevSoundProxySETCEvent; item.iErrorCode = KErrNone; item.iEventPckg() = aEvent; // assumes sufficient space in the queue so ignores the return value TInt err = iMsgQueue.Send(item); - __ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg)); + __ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg)); + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Exit")); } void CMMFDevSoundSession::AsynchronousOperationComplete(TInt aError, TBool aCanStartNewOperation) @@ -1768,6 +2076,13 @@ __ASSERT_DEBUG(!iHandlingExtdCI, Panic(EUnexpectedAsyncOpCompleteHandlingCI)); // when handling CIs we should not reach here + TInt error = aError; + if (!error) + { + // if have no error payload, use notified error. It will be KErrNone if not set, so just use. + error = NotifiedError(); + } + switch (iRequestBeingServiced.Type()) { case TMMFDevSoundRequest::ESessionEvents: @@ -1809,7 +2124,7 @@ FlushEventQueue(); } - iRequestBeingServiced.Complete(aError); + iRequestBeingServiced.Complete(error); iOperationCompletePending = EFalse; } } @@ -1837,9 +2152,19 @@ default: break; } + + if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::ECallBackType ) + { + SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete CallbackPF=%d pending=%d"), + iRequestBeingServiced.IsCallBack(), iOperationCompletePending ); + } + else + { + SYMBIAN_DEBPRN3(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d Requestype=%d"), + iRequestBeingServiced.Function(), iOperationCompletePending, iRequestBeingServiced.Type() ); + } - SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d"),iRequestBeingServiced.Function(), iOperationCompletePending ); - + if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 ) { DequeueRequest(); @@ -1848,6 +2173,7 @@ void CMMFDevSoundSession::DequeueRequest() { + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Enter")); iAsyncQueueStart->Cancel(); // if we're in here cancel any background request TMMFDevSoundRequest msg = iQueuedRequests[0]; @@ -1876,6 +2202,7 @@ SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Flag can service new request\n")); iAsyncQueueStart->CallBack(); } + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Exit")); } // AsyncQueueStartCallback @@ -1893,11 +2220,29 @@ SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Service a queued request\n")); TMMFDevSoundRequest msg = iQueuedRequests[0]; iQueuedRequests.Remove(0); - TRAPD(err,DoServiceRequestL(msg.Message())); - if(err != KErrNone) - { - msg.Complete(err); - } + TInt err = KErrNone; + TBool doRequest = ETrue; + if(iPreemptionClash) + { + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::AsyncQueueStartCallback - Re-applying client request due to Pre-emption clash")); + iPreemptionClash=EFalse; // clear flag before reading next request in queue + iAdapter->RollbackAdaptorActiveStateToBeforeCommit(); + if ((iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous)) + { + doRequest = EFalse; + HandleAlreadyCompletedRequest(); + } + } + + if (doRequest) + { + TRAP(err,DoServiceRequestL(msg.Message())); + if(err != KErrNone) + { + msg.Complete(err); + } + } + if (!iOperationCompletePending && iQueuedRequests.Count() != 0) { //dequeue next @@ -1926,6 +2271,8 @@ // void CMMFDevSoundSession::DoProcessingFinished() { + ResetNotifiedError(); + TBool asyncOperation = EFalse; //ProcessingFinished should never fail __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingFinishedReceived(asyncOperation)); @@ -1941,6 +2288,8 @@ // void CMMFDevSoundSession::DoProcessingError() { + ResetNotifiedError(); + TBool asyncOperation = EFalse; //ProcessingFinished should never fail __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingError(asyncOperation)); @@ -2025,7 +2374,7 @@ // Request kernel to create global RChunk if needed if ( !iChunk.Handle() ) { - status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize); + status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize, EOwnerThread); if ( status == KErrNone ) { aBufPckg().iChunkOp = EOpen; @@ -2273,7 +2622,7 @@ void CMMFDevSoundSession::Panic(TMMFDevSoundSessionPanicCodes aCode) { - User::Panic(KMMFDevSoundSessionPanicCategory, aCode); + User::Panic(KMMFDevSoundSessionPanicCategory, aCode); } void CMMFDevSoundSession::BufferErrorEvent() @@ -2281,4 +2630,26 @@ // this will generate an processing error event and callback iAdapter->BufferErrorEvent(); } + +void CMMFDevSoundSession::ResetNotifiedError() +// called at beginning of commit cycle, so any error will be from callbacks + { + SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ResetNotifiedError")); + iNotifiedError = KErrNone; + } + +TInt CMMFDevSoundSession::NotifiedError() const +// NotifiedError property + { + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifiedError(%d)"), iNotifiedError); + return iNotifiedError; + } + +void CMMFDevSoundSession::NotifyError(TInt aError) +// cache notified error + { + SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifyError(%d)"), aError); + iNotifiedError = aError; + } + // End of file