sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "mmfaudioclientserver.h" sl@0: #include "mmfaudioserver.h" sl@0: #include "mmfdevsoundserver.h" sl@0: #include "mmfdevsoundsession.h" sl@0: #include sl@0: #include sl@0: #ifdef _DEBUG sl@0: #include "e32debug.h" sl@0: sl@0: #define SYMBIAN_DEBPRN0(str) RDebug::Print(str, this) sl@0: #define SYMBIAN_DEBPRN1(str, val1) RDebug::Print(str, this, val1) sl@0: #define SYMBIAN_DEBPRN2(str, val1, val2) RDebug::Print(str, this, val1, val2) sl@0: #define SYMBIAN_DEBPRN3(str, val1, val2, val3) RDebug::Print(str, this, val1, val2, val3) sl@0: #else sl@0: #define SYMBIAN_DEBPRN0(str) sl@0: #define SYMBIAN_DEBPRN1(str, val1) sl@0: #define SYMBIAN_DEBPRN2(str, val1, val2) sl@0: #define SYMBIAN_DEBPRN3(str, val1, val2, val3) sl@0: #endif //_DEBUG sl@0: sl@0: const TInt KMaxQueueRequest = 6; sl@0: sl@0: // MEMBER FUNCTIONS sl@0: sl@0: TMMFDevSoundRequest::TMMFDevSoundRequest() sl@0: : iMessageCompleted(EFalse), sl@0: iRequestType(EUndefinedType), sl@0: iCallBackPF(KCallbackNone) sl@0: { sl@0: } sl@0: sl@0: TMMFDevSoundRequest::TMMFDevSoundRequest(TInt aIsCallBack) sl@0: : iMessageCompleted(EFalse), sl@0: iRequestType(ECallBackType), sl@0: iCallBackPF(aIsCallBack) sl@0: { sl@0: } sl@0: sl@0: TMMFDevSoundRequest::TMMFDevSoundRequest(const TMMFDevSoundRequest& aRequest) sl@0: : iMessageCompleted(EFalse), sl@0: iMessage(aRequest.iMessage), sl@0: iCallBackPF(aRequest.iCallBackPF) sl@0: { sl@0: iRequestType = ResolveType(); sl@0: } sl@0: sl@0: TBool TMMFDevSoundRequest::operator==(const TMMFDevSoundRequest& aRequest) const sl@0: { sl@0: TBool retval = EFalse; sl@0: if ( aRequest.Function() == Function() ) sl@0: { sl@0: retval = ETrue; sl@0: } sl@0: else sl@0: { sl@0: retval = EFalse; sl@0: } sl@0: return retval; sl@0: } sl@0: sl@0: const RMmfIpcMessage& TMMFDevSoundRequest::Message() sl@0: { sl@0: return iMessage; sl@0: } sl@0: sl@0: void TMMFDevSoundRequest::SetMessage(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iMessageCompleted = EFalse; sl@0: iMessage = aMessage; sl@0: iRequestType = ResolveType(); sl@0: } sl@0: sl@0: void TMMFDevSoundRequest::SetMessageCallback() sl@0: { sl@0: iMessageCompleted = EFalse; sl@0: iRequestType = ECallBackType; sl@0: } sl@0: sl@0: TInt TMMFDevSoundRequest::IsCallBack() const sl@0: { sl@0: return iCallBackPF; sl@0: } sl@0: sl@0: TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::ResolveType() sl@0: { sl@0: TA3FDevSoundRequestType type = EUndefinedType; sl@0: switch(iMessage.Function()) sl@0: { sl@0: case EMMFDevSoundProxyInitialize1: sl@0: case EMMFDevSoundProxyInitialize2: sl@0: case EMMFDevSoundProxyInitialize4: sl@0: case EMMFDevSoundProxyPlayInit: sl@0: case EMMFDevSoundProxyRecordInit: sl@0: case EMMFDevSoundProxyPlayTone: sl@0: case EMMFDevSoundProxyPlayDualTone: sl@0: case EMMFDevSoundProxyPlayDTMFString: sl@0: case EMMFDevSoundProxyPlayToneSequence: sl@0: case EMMFDevSoundProxyPlayFixedSequence: sl@0: type = EAction_PseudoAsynchronous; sl@0: break; sl@0: sl@0: case EMMFDevSoundProxyStop: sl@0: case EMMFDevSoundProxyPause: sl@0: case EMMFDevSoundProxyClose: sl@0: case EMMFDevSoundProxyCancelInitialize: sl@0: case EMMFDevSoundProxyResume: sl@0: case EMMFDevSoundProxyEmptyBuffers: sl@0: type = EAction_Asynchronous; sl@0: break; sl@0: sl@0: case EMMFDevSoundProxySetConfig: sl@0: case EMMFDevSoundProxyPostOpen: // Although this is not a configure operation technically, it has same calling pattern. sl@0: case EMMFDevSoundProxySetVolume: sl@0: case EMMFDevSoundProxySetGain: sl@0: case EMMFDevSoundProxySetPlayBalance: sl@0: case EMMFDevSoundProxySetRecordBalance: sl@0: case EMMFDevSoundProxySetVolumeRamp: sl@0: case EMMFDevSoundProxySetPrioritySettings: sl@0: type = EConfigure_Asynchronous; sl@0: break; sl@0: sl@0: case EMMFDevSoundProxySetDTMFLengths: sl@0: case EMMFDevSoundProxySetToneRepeats: sl@0: type = EConfigure_Synchronous; sl@0: break; sl@0: case EMMFDevSoundProxyCapabilities: sl@0: type = EQuery_Asynchronous; sl@0: break; sl@0: case EMMFDevSoundProxyMaxVolume: sl@0: case EMMFDevSoundProxyMaxGain: sl@0: case EMMFDevSoundProxyConfig: sl@0: case EMMFDevSoundProxyVolume: sl@0: case EMMFDevSoundProxyGain: sl@0: case EMMFDevSoundProxyPlayBalance: sl@0: case EMMFDevSoundProxyRecordBalance: sl@0: case EMMFDevSoundProxyGetSupportedInputDataTypes: sl@0: case EMMFDevSoundProxyGetSupportedOutputDataTypes: sl@0: case EMMFDevSoundProxyFixedSequenceName: sl@0: case EMMFDevSoundProxyFixedSequenceCount: sl@0: case EMMFDevSoundProxySamplesRecorded: sl@0: case EMMFDevSoundProxySamplesPlayed: sl@0: case EMMFDevSoundProxyCopyFourCCArrayData: sl@0: case EMMFDevSoundProxyGetTimePlayed: sl@0: case EMMFDevSoundProxyIsResumeSupported: sl@0: type = EQuery_Synchronous; sl@0: break; sl@0: sl@0: case EMMFDevSoundProxyBTBFData: sl@0: case EMMFDevSoundProxyBTBEData: sl@0: case EMMFDevSoundProxyPlayData: sl@0: case EMMFDevSoundProxyRecordData: sl@0: type = EBufferExchangeRelated; sl@0: break; sl@0: sl@0: // Custom Interfaces sl@0: case EMMFDevSoundProxySyncCustomCommand: sl@0: case EMMFDevSoundProxySyncCustomCommandResult: sl@0: case EMMFDevSoundProxyAsyncCustomCommand: sl@0: case EMMFDevSoundProxyAsyncCustomCommandResult: sl@0: case EMMFDevSoundProxyCustomInterface: sl@0: type = ECustomInterfacesRelated; sl@0: break; sl@0: case RMessage2::EDisConnect: sl@0: type = ESessionEvents; sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: return type; sl@0: } sl@0: sl@0: sl@0: void TMMFDevSoundRequest::Complete(TInt aError) sl@0: { sl@0: if(!iMessageCompleted && iRequestType != EUndefinedType && iRequestType != ECallBackType) sl@0: { sl@0: iMessage.Complete(aError); sl@0: iMessageCompleted = ETrue; sl@0: iRequestType = EUndefinedType; sl@0: } sl@0: } sl@0: sl@0: TInt TMMFDevSoundRequest::Function() const sl@0: { sl@0: return iMessage.Function(); sl@0: } sl@0: sl@0: TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::Type() const sl@0: { sl@0: return iRequestType; sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::CreateL sl@0: // Creates a new object sl@0: // sl@0: void CMMFDevSoundSession::CreateL(const CMmfIpcServer& aServer) sl@0: { sl@0: CMmfIpcSession::CreateL(aServer); sl@0: CMMFDevSoundServer& server = sl@0: const_cast( sl@0: static_cast(aServer)); sl@0: server.IncrementSessionId(); sl@0: iDevSoundSessionId = server.DevSoundSessionId(); sl@0: } sl@0: sl@0: // sl@0: // NeedToQueue - mid-commit cycle or async queue start AO is active sl@0: // sl@0: TBool CMMFDevSoundSession::NeedToQueue() const sl@0: { sl@0: return iOperationCompletePending || iAsyncQueueStart->IsActive(); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::ServiceL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN2(_L("\nCMMFDevSoundSession[0x%x] NEW REQUEST %02x while pending=%d"), sl@0: aMessage.Function(), NeedToQueue()); sl@0: sl@0: if(NeedToQueue()) sl@0: { sl@0: // if not possible to service now, then queue request sl@0: EnqueueRequest(aMessage); sl@0: } sl@0: else sl@0: { sl@0: // If there is no oustanding operation service inmediately sl@0: TRAPD(err, DoServiceRequestL(aMessage)); sl@0: if (err) sl@0: { sl@0: aMessage.Complete(err); // repeat normal ServiceL() behaviour since we may keep going sl@0: } sl@0: if (!iOperationCompletePending && iQueuedRequests.Count() != 0) sl@0: { sl@0: //dequeue next sl@0: DequeueRequest(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoServiceL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoServiceRequestL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iRequestBeingServiced.SetMessage(aMessage); sl@0: iAsyncQueueStart->Cancel(); // just in case. sl@0: ResetNotifiedError(); sl@0: sl@0: if (aMessage.Function() == RMessage2::EDisConnect) sl@0: { sl@0: TBool complete = iAdapter->CloseDevSound(); sl@0: if(!complete) sl@0: { sl@0: iRequestBeingServiced.SetMessage(aMessage); sl@0: iOperationCompletePending = ETrue; sl@0: ResetNotifiedError(); sl@0: } sl@0: else sl@0: { sl@0: // if we get here, iClosing wait will have been started and we'd be waiting sl@0: iClosingWait->AsyncStop(); sl@0: } sl@0: return; sl@0: } sl@0: sl@0: TMMFMessageDestinationPckg destinationPckg; sl@0: User::LeaveIfError(MessageRead(aMessage, 0, destinationPckg)); sl@0: SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - DestinationHandle [%d] InterfaceId [%d] "), destinationPckg().DestinationHandle(), destinationPckg().InterfaceId()); sl@0: if ((destinationPckg().DestinationHandle() == KMMFObjectHandleDevSound) && sl@0: (destinationPckg().InterfaceId() == KUidInterfaceMMFDevSound)) sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - Request [%d]"), aMessage.Function()); sl@0: TBool complete = EFalse; sl@0: switch(aMessage.Function()) sl@0: { sl@0: case EMMFDevSoundProxyPostOpen: sl@0: complete = DoPostOpenL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyInitialize1: sl@0: complete = DoInitialize1L(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyInitialize2: sl@0: complete = DoInitialize2L(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyInitialize4: sl@0: complete = DoInitialize4L(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyCapabilities: sl@0: complete = DoCapabilitiesL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyConfig: sl@0: complete = DoConfigL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetConfig: sl@0: complete = DoSetConfigL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyMaxVolume: sl@0: complete = DoMaxVolumeL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyVolume: sl@0: complete = DoVolumeL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetVolume: sl@0: complete = DoSetVolumeL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyMaxGain: sl@0: complete = DoMaxGainL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyGain: sl@0: complete = DoGainL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetGain: sl@0: complete = DoSetGainL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayBalance: sl@0: complete = DoGetPlayBalanceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetPlayBalance: sl@0: complete = DoSetPlayBalanceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyRecordBalance: sl@0: complete = DoGetRecordBalanceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetRecordBalance: sl@0: complete = DoSetRecordBalanceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyBTBFData: sl@0: complete = DoBufferToBeFilledDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyBTBEData: sl@0: complete = DoBufferToBeEmptiedDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayInit: sl@0: complete = DoPlayInitL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyRecordInit: sl@0: complete = DoRecordInitL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayData: sl@0: complete = DoPlayDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyRecordData: sl@0: complete = DoRecordDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyStop: sl@0: complete = DoStopL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPause: sl@0: complete = DoPauseL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayTone: sl@0: complete = DoPlayToneL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayDualTone: sl@0: complete = DoPlayDualToneL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayDTMFString: sl@0: complete = DoPlayDTMFStringL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayToneSequence: sl@0: complete = DoPlayToneSequenceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyPlayFixedSequence: sl@0: complete = DoPlayFixedSequenceL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetDTMFLengths: sl@0: complete = DoSetDTMFLengthsL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetVolumeRamp: sl@0: complete = DoSetVolumeRampL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyGetSupportedInputDataTypes: sl@0: complete = DoGetSupportedInputDataTypesL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyGetSupportedOutputDataTypes: sl@0: complete = DoGetSupportedOutputDataTypesL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyCopyFourCCArrayData: sl@0: complete = DoCopyFourCCArrayDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySamplesRecorded: sl@0: complete = DoSamplesRecordedL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySamplesPlayed: sl@0: complete = DoSamplesPlayedL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetToneRepeats: sl@0: complete = DoSetToneRepeatsL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetPrioritySettings: sl@0: complete = DoSetPrioritySettingsL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyFixedSequenceCount: sl@0: complete = DoFixedSequenceCountL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyCancelInitialize: sl@0: complete = DoCancelInitializeL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyEmptyBuffers: sl@0: complete = DoEmptyBuffersL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyGetTimePlayed: sl@0: complete = DoGetTimePlayedL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyIsResumeSupported: sl@0: complete = DoQueryResumeSupportedL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyResume: sl@0: complete = DoResumeL(aMessage); sl@0: break; sl@0: sl@0: // DevSound custom command support sl@0: case EMMFDevSoundProxySyncCustomCommand: sl@0: case EMMFDevSoundProxySyncCustomCommandResult: sl@0: case EMMFDevSoundProxyAsyncCustomCommand: sl@0: case EMMFDevSoundProxyAsyncCustomCommandResult: sl@0: complete = DoCustomCommandL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyClose: sl@0: complete = DoPrepareCloseL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyRequestResourceNotification: sl@0: complete = DoRegisterAsClientL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyCancelRequestResourceNotification: sl@0: complete = DoCancelRegisterAsClientL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyGetResourceNotificationData: sl@0: complete = DoGetResourceNotificationDataL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxyWillResumePlay: sl@0: complete = DoWillResumePlayL(aMessage); sl@0: break; sl@0: case EMMFDevSoundProxySetClientThreadInfo: sl@0: complete = DoSetClientThreadInfoL(aMessage); sl@0: break; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: sl@0: // Check if can complete the message now sl@0: if (complete) sl@0: { sl@0: // Complete the message sl@0: // Synchronous requests & Pseudo-asynchronous sl@0: aMessage.Complete(KErrNone); sl@0: sl@0: // Store function if we need to re-apply it again due to pre-emption clash sl@0: if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous) sl@0: { sl@0: iRedoFunction = aMessage.Function(); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // If there's a CI extension, see if that handles this request sl@0: TInt err = KErrNotSupported; sl@0: if (iCIExtension) sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest [%d]"), aMessage.Function()); sl@0: iOperationCompletePending = ETrue; sl@0: iHandlingExtdCI = ETrue; sl@0: TRAPD(err2, err = iCIExtension->HandleMessageL(aMessage)); sl@0: if (err2) sl@0: { sl@0: err = err2; sl@0: } sl@0: iOperationCompletePending = EFalse; sl@0: iHandlingExtdCI = EFalse; sl@0: SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::DoServiceRequestL - CIExtensionRequest[%d] - Exit with Error[%d] "), aMessage.Function(),err); sl@0: } sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: // Not been handled, the request is not supported sl@0: aMessage.Complete(KErrNotSupported); sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CMMFDevSoundSession::DoServiceAlreadyCompletedRequestL(const TInt aFunction) sl@0: { sl@0: ResetNotifiedError(); sl@0: sl@0: switch(aFunction) sl@0: { sl@0: case EMMFDevSoundProxyInitialize1: sl@0: DoAlreadyCompletedInitialize1L(); sl@0: break; sl@0: case EMMFDevSoundProxyInitialize2: sl@0: DoAlreadyCompletedInitialize2L(); sl@0: break; sl@0: case EMMFDevSoundProxyInitialize4: sl@0: DoAlreadyCompletedInitialize4L(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayInit: sl@0: DoAlreadyCompletedPlayInitL(); sl@0: break; sl@0: case EMMFDevSoundProxyRecordInit: sl@0: DoAlreadyCompletedRecordInitL(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayTone: sl@0: DoAlreadyCompletedPlayToneL(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayDualTone: sl@0: DoAlreadyCompletedPlayDualToneL(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayDTMFString: sl@0: DoAlreadyCompletedPlayDTMFStringL(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayToneSequence: sl@0: DoAlreadyCompletedPlayToneSequenceL(); sl@0: break; sl@0: case EMMFDevSoundProxyPlayFixedSequence: sl@0: DoAlreadyCompletedPlayFixedSequenceL(); sl@0: break; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: sl@0: } sl@0: sl@0: void CMMFDevSoundSession::HandleAlreadyCompletedRequest() sl@0: { sl@0: TRAPD(err,DoServiceAlreadyCompletedRequestL(iRedoFunction)); sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: switch(iRedoFunction) sl@0: { sl@0: case EMMFDevSoundProxyInitialize1: sl@0: case EMMFDevSoundProxyInitialize2: sl@0: case EMMFDevSoundProxyInitialize4: sl@0: InitializeComplete(err); sl@0: break; sl@0: case EMMFDevSoundProxyPlayInit: sl@0: PlayError(err); sl@0: break; sl@0: case EMMFDevSoundProxyRecordInit: sl@0: RecordError(err); sl@0: break; sl@0: case EMMFDevSoundProxyPlayTone: sl@0: case EMMFDevSoundProxyPlayDualTone: sl@0: case EMMFDevSoundProxyPlayDTMFString: sl@0: case EMMFDevSoundProxyPlayToneSequence: sl@0: case EMMFDevSoundProxyPlayFixedSequence: sl@0: ToneFinished(err); sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CMMFDevSoundSession::EnqueueRequest(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::EnqueueRequest - Enter")); sl@0: // Encapsule the request sl@0: TMMFDevSoundRequest request; sl@0: request.SetMessage(aMessage); sl@0: // Append sl@0: TInt error = iQueuedRequests.Append(request); sl@0: __ASSERT_DEBUG(error == KErrNone, Panic(EQueueRequestsFailedToAppend)); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::EnqueueRequest - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPostOpenL sl@0: // sl@0: TBool CMMFDevSoundSession::DoPostOpenL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iAdapter->PostOpenL(); sl@0: iOperationCompletePending = ETrue; sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoInitialize1L sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iMsgQueue.Close(); // close if already open sl@0: TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread sl@0: User::LeaveIfError(err); sl@0: DoSetClientConfigL();// added here instead of the CreateL() sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,1,devSoundBuf)); sl@0: iCachedClientData = devSoundBuf; sl@0: TMMFState mode = devSoundBuf().iMode; sl@0: iAdapter->InitializeL(mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: // Flag to queue any further request sl@0: // but the message can be completed now sl@0: iOperationCompletePending = ETrue; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedInitialize1L sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedInitialize1L() sl@0: { sl@0: TMMFState mode = iCachedClientData().iMode; sl@0: iAdapter->InitializeL(mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: // Flag to queue any further request sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoInitialize2L sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iMsgQueue.Close(); // close if already open sl@0: TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread sl@0: User::LeaveIfError(err); sl@0: DoSetClientConfigL();// added here instead of the CreateL() sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,1,devSoundBuf)); sl@0: iCachedClientData = devSoundBuf; sl@0: TUid HWDev = devSoundBuf().iHWDev; sl@0: TMMFState mode = devSoundBuf().iMode; sl@0: iAdapter->InitializeL(HWDev, mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedInitialize2L sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedInitialize2L() sl@0: { sl@0: TUid HWDev = iCachedClientData().iHWDev; sl@0: TMMFState mode = iCachedClientData().iMode; sl@0: iAdapter->InitializeL(HWDev, mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoInitialize4L sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iMsgQueue.Close(); sl@0: TInt err = iMsgQueue.Open(aMessage, 2, EOwnerThread); // a global queue but owned by thread sl@0: User::LeaveIfError(err); sl@0: DoSetClientConfigL();// added here instead of the CreateL() sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage, TInt(1), devSoundBuf)); sl@0: iCachedClientData = devSoundBuf; sl@0: TFourCC desiredFourCC = devSoundBuf().iDesiredFourCC; sl@0: TMMFState mode = devSoundBuf().iMode; sl@0: iAdapter->InitializeL(desiredFourCC, mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: // Flag to queue any further request sl@0: // but the message can be completed now sl@0: iOperationCompletePending = ETrue; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedInitialize4L sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedInitialize4L() sl@0: { sl@0: TFourCC desiredFourCC = iCachedClientData().iDesiredFourCC; sl@0: TMMFState mode = iCachedClientData().iMode; sl@0: iAdapter->InitializeL(desiredFourCC, mode); sl@0: iBufferPlay = NULL; sl@0: iPlayErrorOccured = EFalse; sl@0: // Flag to queue any further request sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoCancelInitialize sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoCancelInitializeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err=iAdapter->CancelInitialize(); sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: iOperationCompletePending = EFalse; sl@0: return ETrue; sl@0: } sl@0: else sl@0: { sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoCapabilitiesL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoCapabilitiesL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err = iAdapter->Capabilities(iDevSoundCapabilities); sl@0: if(err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: iOperationCompletePending = EFalse; sl@0: } sl@0: else sl@0: { sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoConfigL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoConfigL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iConfig = iAdapter->Config(); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetConfigL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetConfigL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TMMFCapabilities config = devSoundBuf().iConfig; sl@0: iAdapter->SetConfigL(config); sl@0: iOperationCompletePending = ETrue; sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::axVolumeL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoMaxVolumeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iMaxVolume = iAdapter->MaxVolume(); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoVolumeL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoVolumeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iVolume = iAdapter->Volume(); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetVolumeL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetVolumeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage, TInt(1),devSoundBuf)); sl@0: TInt volume = devSoundBuf().iVolume; sl@0: TBool asyncOperation; sl@0: User::LeaveIfError(iAdapter->SetVolume(volume, asyncOperation)); sl@0: iOperationCompletePending = asyncOperation; sl@0: return !asyncOperation; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoMaxGainL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoMaxGainL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iMaxGain = iAdapter->MaxGain(); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoGainL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGainL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iGain = iAdapter->Gain(); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetGainL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetGainL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TInt gain = devSoundBuf().iGain; sl@0: TBool asyncOperation; sl@0: User::LeaveIfError(iAdapter->SetGain(gain, asyncOperation)); sl@0: iOperationCompletePending = asyncOperation; sl@0: return !asyncOperation; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoGetPlayBalanceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGetPlayBalanceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: iAdapter->GetPlayBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetPlayBalanceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetPlayBalanceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TInt leftPercentage = devSoundBuf().iLeftPercentage; sl@0: TInt rightPercentage = devSoundBuf().iRightPercentage; sl@0: TBool asyncOperation; sl@0: iAdapter->SetPlayBalanceL(leftPercentage, rightPercentage, asyncOperation); sl@0: iOperationCompletePending = asyncOperation; sl@0: return !asyncOperation; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoGetRecordBalanceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGetRecordBalanceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: iAdapter->GetRecordBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage); sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetRecordBalanceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetRecordBalanceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TInt leftPercentage = devSoundBuf().iLeftPercentage; sl@0: TInt rightPercentage = devSoundBuf().iRightPercentage; sl@0: TBool asyncOperation; sl@0: iAdapter->SetRecordBalanceL(leftPercentage, rightPercentage, asyncOperation); sl@0: iOperationCompletePending = asyncOperation; sl@0: return !asyncOperation; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayInitL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayInitL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iAdapter->PlayInitL(); sl@0: iOperationCompletePending = ETrue; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayInitL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayInitL() sl@0: { sl@0: iAdapter->PlayInitL(); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoRecordInitL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoRecordInitL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iAdapter->RecordInitL(); sl@0: iOperationCompletePending = ETrue; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedRecordInitL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedRecordInitL() sl@0: { sl@0: iAdapter->RecordInitL(); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayDataL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayDataL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Enter")); sl@0: sl@0: if( iPlayErrorOccured ) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Ignore and Exit")); sl@0: return ETrue; sl@0: } sl@0: sl@0: TMMFDevSoundProxyHwBufPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: iBufferPlay->SetLastBuffer(devSoundBuf().iLastBuffer); sl@0: sl@0: TPtr8 dataPtr(iChunk.Base(), devSoundBuf().iBufferSize, devSoundBuf().iBufferSize); sl@0: // Copy data over from chunk sl@0: iBufferPlay->Data().Copy(dataPtr); sl@0: iAdapter->PlayData(); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Exit")); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoRecordDataL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoRecordDataL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iAdapter->RecordData(); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoStopL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoStopL - Enter")); sl@0: // Sometimes Stop is not involved on a commit cycle sl@0: TBool completed = iAdapter->Stop(); sl@0: if (completed) sl@0: { sl@0: FlushQueuedRequests(); sl@0: FlushEventQueue(); // completed returned here means we were idle to start with. TODO could possibly skip this flush sl@0: iChunk.Close(); sl@0: } sl@0: iOperationCompletePending = !completed; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoStopL - Exit. Return value is [%d]"), completed); sl@0: return completed; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPauseL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPauseL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: User::LeaveIfError(iAdapter->Pause()); sl@0: iOperationCompletePending = ETrue; sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayToneL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Enter")); sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: iCachedClientData = devSoundBuf; sl@0: TInt frequency = devSoundBuf().iFrequencyOne; sl@0: TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration); sl@0: iAdapter->PlayToneL(frequency, duration); sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayToneL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayToneL() sl@0: { sl@0: TInt frequency = iCachedClientData().iFrequencyOne; sl@0: TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration); sl@0: iAdapter->PlayToneL(frequency, duration); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayDualToneL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Enter")); sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: iCachedClientData = devSoundBuf; sl@0: TInt frequencyOne = devSoundBuf().iFrequencyOne; sl@0: TInt frequencyTwo = devSoundBuf().iFrequencyTwo; sl@0: TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration); sl@0: iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration); sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDualToneL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayDualToneL() sl@0: { sl@0: TInt frequencyOne = iCachedClientData().iFrequencyOne; sl@0: TInt frequencyTwo = iCachedClientData().iFrequencyTwo; sl@0: TTimeIntervalMicroSeconds duration(iCachedClientData().iDuration); sl@0: iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayDTMFStringL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Enter")); sl@0: TInt dtmfLength = aMessage.GetDesLength(2); sl@0: sl@0: if(iDtmfString) sl@0: { sl@0: delete iDtmfString; sl@0: iDtmfString = NULL; sl@0: } sl@0: sl@0: iDtmfString = HBufC::NewL(dtmfLength); sl@0: TPtr dtmfPtr = iDtmfString->Des(); sl@0: User::LeaveIfError(MessageRead(aMessage, TInt(2), dtmfPtr)); sl@0: iAdapter->PlayDTMFStringL(*iDtmfString); sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayDTMFStringL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayDTMFStringL() sl@0: { sl@0: iAdapter->PlayDTMFStringL(*iDtmfString); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayToneSequenceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Enter")); sl@0: TInt toneLength = aMessage.GetDesLength(1); sl@0: sl@0: if(iToneSeqBuf) sl@0: { sl@0: delete iToneSeqBuf; sl@0: iToneSeqBuf = NULL; sl@0: } sl@0: sl@0: iToneSeqBuf = HBufC8::NewL(toneLength); sl@0: TPtr8 toneSeqPtr = iToneSeqBuf->Des(); sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1), toneSeqPtr)); sl@0: sl@0: iAdapter->PlayToneSequenceL(*iToneSeqBuf); sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayToneSequenceL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayToneSequenceL() sl@0: { sl@0: iAdapter->PlayToneSequenceL(*iToneSeqBuf); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoPlayFixedSequenceL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Enter")); sl@0: TPckgBuf buf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),buf)); sl@0: TInt seqNum = buf(); sl@0: iSeqNum = seqNum; sl@0: iAdapter->PlayFixedSequenceL(seqNum); sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoPlayFixedSequenceL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DoAlreadyCompletedPlayFixedSequenceL() sl@0: { sl@0: iAdapter->PlayFixedSequenceL(iSeqNum); sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetDTMFLengthsL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Enter")); sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TTimeIntervalMicroSeconds32 toneOnLength = devSoundBuf().iToneOnLength; sl@0: TTimeIntervalMicroSeconds32 toneOffLength = devSoundBuf().iToneOffLength; sl@0: TTimeIntervalMicroSeconds32 pauseLength = devSoundBuf().iPauseLength; sl@0: User::LeaveIfError(iAdapter->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength)); sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetDTMFLengthsL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetVolumeRampL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Enter")); sl@0: TMMFDevSoundProxySettingsPckg devSoundBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),devSoundBuf)); sl@0: TTimeIntervalMicroSeconds duration = devSoundBuf().iDuration; sl@0: User::LeaveIfError(iAdapter->SetVolumeRamp(duration)); sl@0: iOperationCompletePending = EFalse; // Volume ramp doesn't result on commit sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetVolumeRampL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; // operation complete sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoGetSupportedInputDataTypesL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGetSupportedInputDataTypesL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: iArray.Reset(); sl@0: sl@0: TMMFPrioritySettingsPckg prioritySetBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),prioritySetBuf)); sl@0: TMMFPrioritySettings prioritySet = prioritySetBuf(); sl@0: sl@0: iAdapter->GetSupportedInputDataTypesL(iArray, prioritySet); sl@0: sl@0: TPckgBuf pckg; sl@0: pckg() = iArray.Count(); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoGetSupportedOutputDataTypesL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGetSupportedOutputDataTypesL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: iArray.Reset(); sl@0: sl@0: TMMFPrioritySettingsPckg prioritySetBuf; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),prioritySetBuf)); sl@0: TMMFPrioritySettings prioritySet = prioritySetBuf(); sl@0: sl@0: iAdapter->GetSupportedOutputDataTypesL(iArray, prioritySet); sl@0: sl@0: TPckgBuf pckg; sl@0: pckg() = iArray.Count(); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSamplesRecordedL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSamplesRecordedL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf pckg; sl@0: pckg() = iAdapter->SamplesRecorded(); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSamplesPlayedL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSamplesPlayedL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf pckg; sl@0: pckg() = iAdapter->SamplesPlayed(); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),pckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetToneRepeatsL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Enter")); sl@0: TPckgBuf countRepeat; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),countRepeat)); sl@0: sl@0: TPckgBuf repeatTS; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(2),repeatTS)); sl@0: User::LeaveIfError(iAdapter->SetToneRepeats(countRepeat(), repeatTS())); sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoSetToneRepeatsL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetPrioritySettingsL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoSetPrioritySettingsL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf prioritySet; sl@0: User::LeaveIfError(MessageRead(aMessage,TInt(1),prioritySet)); sl@0: sl@0: User::LeaveIfError(iAdapter->SetPrioritySettings(prioritySet())); sl@0: iOperationCompletePending = EFalse; sl@0: return ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoFixedSequenceCountL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoFixedSequenceCountL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Enter")); sl@0: TPckgBuf fixSeqCountPckg; sl@0: TInt fixSeqCount = iAdapter->FixedSequenceCount(); sl@0: fixSeqCountPckg = fixSeqCount; sl@0: sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),fixSeqCountPckg)); sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::DoFixedSequenceCountL - Exit. Return value is [%d]"), ETrue); sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoCopyFourCCArrayDataL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoCopyFourCCArrayDataL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: const TInt KBufExpandSize8 = 8;//two TInts sl@0: CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8); sl@0: CleanupStack::PushL(dataCopyBuffer); sl@0: RBufWriteStream stream; sl@0: stream.Open(*dataCopyBuffer); sl@0: CleanupClosePushL(stream); sl@0: sl@0: TInt i = 0; sl@0: TInt count = iArray.Count(); sl@0: sl@0: while (i < count) sl@0: { sl@0: stream.WriteInt32L(iArray[i].FourCC()); sl@0: i++; sl@0: } sl@0: User::LeaveIfError(MessageWrite(aMessage, TInt(2), dataCopyBuffer->Ptr(0))); sl@0: stream.Close(); sl@0: CleanupStack::PopAndDestroy(&stream); sl@0: CleanupStack::PopAndDestroy(dataCopyBuffer); sl@0: return ETrue; sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoBufferToBeFilledDataL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoBufferToBeFilledDataL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: // if CMMFDevSoundSession::PlayError() has been called, RChunk would have got closed. sl@0: // Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client. sl@0: if(!iChunk.Handle()) sl@0: { sl@0: aMessage.Complete(KErrBadHandle); sl@0: return EFalse; sl@0: } sl@0: TPckgBuf requestChunkBuf; sl@0: User::LeaveIfError(MessageRead(aMessage, TInt(1), requestChunkBuf)); sl@0: TBool requestChunk = requestChunkBuf(); sl@0: if (requestChunk) sl@0: { sl@0: // if the client requests, always do EOpen sl@0: iHwBufPckgFill().iChunkOp = EOpen; sl@0: } sl@0: TInt err = MessageWrite(aMessage, TInt(2), iHwBufPckgFill); sl@0: if ( (err == KErrNone) && (iHwBufPckgFill().iChunkOp == EOpen) ) sl@0: { sl@0: aMessage.Complete(iChunk); sl@0: } sl@0: else sl@0: { sl@0: aMessage.Complete(err); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: // CMMFDevSoundSession::DoBufferToBeEmptiedDataL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoBufferToBeEmptiedDataL( sl@0: const RMmfIpcMessage& aMessage) sl@0: { sl@0: // if CMMFDevSoundSession::RecordError() has been called, RChunk would have got closed. sl@0: // Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client. sl@0: if(!iChunk.Handle()) sl@0: { sl@0: aMessage.Complete(KErrBadHandle); sl@0: return EFalse; sl@0: } sl@0: sl@0: TInt err = MessageWrite(aMessage, TInt(2), iHwBufPckgEmpty); sl@0: if ( (err == KErrNone) && (iHwBufPckgEmpty().iChunkOp == EOpen) ) sl@0: { sl@0: aMessage.Complete(iChunk); sl@0: } sl@0: else sl@0: { sl@0: aMessage.Complete(err); sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoEmptyBuffersL sl@0: // (other items were commented in a header). sl@0: // sl@0: sl@0: TBool CMMFDevSoundSession::DoEmptyBuffersL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err = KErrNone; sl@0: FilterQueueEvent(EMMFDevSoundProxyBTBFEvent); sl@0: // This is now asynchronous sl@0: err = iAdapter->EmptyBuffers(); sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: iOperationCompletePending = ETrue; sl@0: return EFalse; sl@0: } sl@0: // sl@0: // CMMFDevSoundSession::DoGetTimePlayedL sl@0: // (other items were commented in a header). sl@0: // sl@0: TBool CMMFDevSoundSession::DoGetTimePlayedL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err = KErrNone; sl@0: TTimeIntervalMicroSeconds time(0); sl@0: TPckgBuf timePckg(time); sl@0: err = iAdapter->GetTimePlayed(timePckg()); sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),timePckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoQueryResumeSupportedL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TBool isSupported = EFalse; sl@0: TPckgBuf isSupportedPckg(isSupported); sl@0: isSupportedPckg() = iAdapter->IsResumeSupported(); sl@0: User::LeaveIfError(MessageWrite(aMessage,TInt(2),isSupportedPckg)); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoResumeL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: User::LeaveIfError( iAdapter->Resume() ); sl@0: iOperationCompletePending = ETrue; sl@0: FilterQueueEvent(EMMFDevSoundProxyPausedRecordCompleteEvent); sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoPrepareCloseL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: TBool complete = iAdapter->CloseDevSound(); sl@0: if(!complete) sl@0: { sl@0: iOperationCompletePending = ETrue; sl@0: } sl@0: return complete; sl@0: } sl@0: sl@0: sl@0: TBool CMMFDevSoundSession::DoCustomCommandL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt retVal = KErrNone; sl@0: TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage)); sl@0: if (err != KErrNone) sl@0: { sl@0: // the framework left with an error condition sl@0: // so we complete the message with this error sl@0: // irrespective of whether its a Sync or Async custom command sl@0: aMessage.Complete(err); sl@0: } sl@0: else sl@0: { sl@0: TInt messageType = aMessage.Function(); sl@0: if ((messageType == EMMFDevSoundProxySyncCustomCommand) || sl@0: (messageType == EMMFDevSoundProxySyncCustomCommandResult)) sl@0: { sl@0: // If its a sync custom command sl@0: // we can pass back valid values here since command sl@0: // has been handled by the DeMux framework sl@0: aMessage.Complete(retVal); sl@0: } sl@0: } sl@0: sl@0: // we complete our own message so don't need the framework to do so sl@0: return EFalse; sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::CMMFDevSoundSession sl@0: // (other items were commented in a header). sl@0: // sl@0: CMMFDevSoundSession::CMMFDevSoundSession() : sl@0: iSetClientConfigApplied (EFalse), sl@0: iDisconnecting (EFalse) sl@0: { sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::~CMMFDevSoundSession sl@0: // (other items were commented in a header). sl@0: // sl@0: CMMFDevSoundSession::~CMMFDevSoundSession() sl@0: { sl@0: delete iAsyncQueueStart; sl@0: // clear the array of custom interfaces sl@0: TInt count = iCustomInterfaceArray.Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: // we could have already deleted interfaces without sl@0: // removing them from the array so check for this sl@0: // and only delete release plugin if non-null sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface; sl@0: if (ptr) sl@0: { sl@0: iCustomInterfaceArray[i].iInterface->Release(); sl@0: } sl@0: } sl@0: iCustomInterfaceArray.Reset(); sl@0: iCustomInterfaceArray.Close(); sl@0: sl@0: delete iDeMuxUtility; sl@0: sl@0: if (iCIExtension) sl@0: { sl@0: iCIExtension->Release(); sl@0: iCIExtension = NULL; sl@0: } sl@0: sl@0: iMsgQueue.Close(); sl@0: iArray.Close(); sl@0: iQueuedRequests.Close(); sl@0: delete iDtmfString; sl@0: delete iToneSeqBuf; sl@0: delete iAdapter; sl@0: delete iClosingWait; sl@0: sl@0: CMMFDevSoundServer* server = sl@0: const_cast( sl@0: static_cast(Server())); sl@0: sl@0: if (server) sl@0: { sl@0: server->DecrementSessionId(); sl@0: } sl@0: sl@0: // delete iCustomCommandParserManager; sl@0: // delete iMMFObjectContainer; sl@0: sl@0: // Close chunk sl@0: iChunk.Close(); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::FlushEventQueue() sl@0: // sl@0: void CMMFDevSoundSession::FlushEventQueue() sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Enter")); sl@0: if(iMsgQueue.Handle() != 0) sl@0: { sl@0: TMMFDevSoundQueueItem queueItem; sl@0: TInt err = KErrNone; sl@0: while(err != KErrUnderflow) sl@0: { sl@0: err = iMsgQueue.Receive(queueItem); sl@0: } sl@0: } sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FlushEventQueue - Exit")); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::FilterQueueEvent(TMMFDevSoundProxyRequest aRequest) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Enter")); sl@0: if(iMsgQueue.Handle() != 0) sl@0: { sl@0: // Pop and push events result at the queue sl@0: // can be seen as "circular list" sl@0: // set a mark to traverse it safely sl@0: TMMFDevSoundQueueItem markItem; sl@0: markItem.iRequest = EMMFDevSoundProxyMarkEvent; sl@0: // assumes sufficient space in the queue sl@0: TInt err = iMsgQueue.Send(markItem); sl@0: __ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg)); sl@0: sl@0: while(ETrue) sl@0: { sl@0: // At least the markEvent is at the queue so ignore the error sl@0: TMMFDevSoundQueueItem queueItem; sl@0: err = iMsgQueue.Receive(queueItem); sl@0: if(queueItem.iRequest == EMMFDevSoundProxyMarkEvent) sl@0: { sl@0: break; sl@0: } sl@0: // Look for the specific event sl@0: else if(queueItem.iRequest != aRequest) sl@0: { sl@0: // assumes sufficient space in the queue sl@0: err = iMsgQueue.Send(queueItem); sl@0: } sl@0: } sl@0: } sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::FilterQueueEvent - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::Disconnect sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::Disconnect(const RMessage2& aMessage) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Enter")); sl@0: iDisconnecting = ETrue; sl@0: sl@0: if (NeedToQueue()) sl@0: { sl@0: // if we are in the middle of something, enqueue and wait sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Add to queue")); sl@0: EnqueueRequest(aMessage); sl@0: iClosingWait->Start(); sl@0: } sl@0: else sl@0: { sl@0: // else do now. Enter ActiveSchedulerWait to wait for AsyncOpComplete sl@0: TBool complete = iAdapter->CloseDevSound(); sl@0: if(!complete) sl@0: { sl@0: iRequestBeingServiced.SetMessage(aMessage); sl@0: iOperationCompletePending = ETrue; sl@0: ResetNotifiedError(); sl@0: iClosingWait->Start(); sl@0: } sl@0: } sl@0: CSession2::Disconnect(aMessage); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::Disconnect - Exit")); sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::NewL sl@0: // (other items were commented in a header). sl@0: // sl@0: CMMFDevSoundSession* CMMFDevSoundSession::NewL(MGlobalProperties& aGlobalProperties) sl@0: { sl@0: CMMFDevSoundSession* self = new (ELeave) CMMFDevSoundSession; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aGlobalProperties); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::ConstructL sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::ConstructL(MGlobalProperties& aGlobalProperties) sl@0: { sl@0: iAdapter = CMMFDevSoundAdaptation::NewL(*this, aGlobalProperties); sl@0: sl@0: iClosingWait = new(ELeave) CActiveSchedulerWait(); sl@0: sl@0: // Create the Custom Interface DeMux Utility sl@0: iDeMuxUtility = CMMFDevSoundCIDeMuxUtility::NewL(this); sl@0: sl@0: // Create the Custom Interface extension sl@0: TUid implUid = {KMmfUidCIServerExtensionImpl}; sl@0: TInt uidAsInteger = implUid.iUid; sl@0: const TInt KCIExtTempBufferSize = 20; sl@0: TBuf8 tempBuffer; sl@0: tempBuffer.Num(uidAsInteger, EHex); sl@0: TUid interfaceUid = {KUidDevSoundCIServerExtension}; sl@0: TUid destructorKey; sl@0: TRAPD(err, iCIExtension = static_cast sl@0: (MmPluginUtils::CreateImplementationL(interfaceUid, destructorKey, tempBuffer, KRomOnlyResolverUid))); sl@0: if (KErrNotSupported == err) sl@0: { sl@0: iCIExtension = NULL; sl@0: } sl@0: else sl@0: { sl@0: User::LeaveIfError(err); sl@0: } sl@0: if (iCIExtension) sl@0: { sl@0: // Extension exists. Complete the setup sl@0: iCIExtension->PassDestructorKey(destructorKey); sl@0: User::LeaveIfError(iCIExtension->Setup(*this)); sl@0: } sl@0: sl@0: iQueuedRequests.ReserveL(KMaxQueueRequest); sl@0: iAsyncQueueStart = new (ELeave) CAsyncCallBack(CActive::EPriorityStandard); sl@0: TCallBack asyncCallback(AsyncQueueStartCallback, this); sl@0: iAsyncQueueStart->Set(asyncCallback); sl@0: } sl@0: sl@0: // CMMFDevSoundSession::InitializeComplete sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::InitializeComplete(TInt aError) sl@0: { sl@0: // this may be a re-initialization and so we need to sl@0: // re-get our custom interfaces on the DeMux plugins sl@0: TInt count = iCustomInterfaceArray.Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: // we could have already deleted interfaces without sl@0: // removing them from the array so check for this sl@0: // and only refresh plugin if non-null sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface; sl@0: if (ptr) sl@0: { sl@0: // we can't keep track of.. sl@0: // 1. where a custom interface is implemented sl@0: // 2. the uid of the custom interface to be refreshed sl@0: // so assume all have to be refreshed sl@0: TRAPD(err, ptr->RefreshL()); sl@0: sl@0: // Error indicates this is no longer a valid interface sl@0: if (err != KErrNone) sl@0: { sl@0: TMMFEvent event; sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair; sl@0: item.iErrorCode = err; sl@0: event.iEventType.iUid = i+1; sl@0: item.iEventPckg() = event; sl@0: TInt lErr = iMsgQueue.Send(item); sl@0: __ASSERT_DEBUG(lErr == KErrNone, Panic(EMsgQueueFailedToSendMsg)); sl@0: sl@0: // NB proper panic code required here for this part. sl@0: } sl@0: } sl@0: } sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxyICEvent; sl@0: item.iErrorCode = aError; sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iMsgQueue.Send(item); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::ToneFinished sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::ToneFinished(TInt aError) sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Enter. Error [%d]"), aError); sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxyTFEvent; sl@0: item.iErrorCode = aError; sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iMsgQueue.Send(item); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ToneFinished - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::BufferToBeFilled sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::BufferToBeFilled(CMMFBuffer* aBuffer) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Enter")); sl@0: sl@0: // Set play error flag to false sl@0: iPlayErrorOccured = EFalse; sl@0: sl@0: // Store pointer to the buffer to use it later with PlayData sl@0: iBufferPlay = reinterpret_cast(aBuffer); sl@0: TInt status = CreateChunk(iHwBufPckgFill, iBufferPlay->RequestSize()); sl@0: iHwBufPckgFill().iRequestSize = iBufferPlay->RequestSize(); sl@0: iHwBufPckgFill().iBufferSize = iBufferPlay->Data().MaxLength(); sl@0: iHwBufPckgFill().iLastBuffer = iBufferPlay->LastBuffer(); sl@0: TMMFDevSoundQueueItem queueItem; sl@0: if ( status != KErrNone ) sl@0: { sl@0: BufferErrorEvent(); sl@0: PlayError(status); sl@0: } sl@0: else sl@0: { sl@0: queueItem.iRequest = EMMFDevSoundProxyBTBFEvent; sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: status = iMsgQueue.Send(queueItem); sl@0: } sl@0: sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Exit [%d]"), status); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::PlayError sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::PlayError(TInt aError) sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError - Enter [%d]"), aError); sl@0: sl@0: // Set play error flag to ignore following PlayData requests sl@0: iPlayErrorOccured = ETrue; sl@0: sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxyPEEvent; sl@0: item.iErrorCode = aError; sl@0: iChunk.Close(); sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iMsgQueue.Send(item); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PlayError - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::BufferToBeEmptied sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::BufferToBeEmptied(CMMFBuffer* aBuffer) sl@0: { sl@0: // Store pointer to the buffer to use it later with RecordData sl@0: iBufferRecord = reinterpret_cast(aBuffer); sl@0: TInt status = CreateChunk(iHwBufPckgEmpty, iBufferRecord->RequestSize()); sl@0: sl@0: if ( status != KErrNone ) sl@0: { sl@0: BufferErrorEvent(); sl@0: RecordError(status); sl@0: } sl@0: else sl@0: { sl@0: iHwBufPckgEmpty().iRequestSize = iBufferRecord->RequestSize(); sl@0: iHwBufPckgEmpty().iBufferSize = iBufferRecord->Data().MaxLength(); sl@0: iHwBufPckgEmpty().iLastBuffer = iBufferRecord->LastBuffer(); sl@0: //copy the data into the chunk sl@0: Mem::Copy(iChunk.Base(),iBufferRecord->Data().Ptr(),iBufferRecord->RequestSize()); sl@0: TMMFDevSoundQueueItem queueItem; sl@0: queueItem.iRequest = EMMFDevSoundProxyBTBEEvent; sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iMsgQueue.Send(queueItem); sl@0: } sl@0: } sl@0: sl@0: // CMMFDevSoundSession::RecordError sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::RecordError(TInt aError) sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::Record Error [%d]"), aError); sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxyREEvent; sl@0: item.iErrorCode = aError; sl@0: iChunk.Close(); sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iMsgQueue.Send(item); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DeviceMessage sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::DeviceMessage(TUid /*aMessageType*/, sl@0: const TDesC8& /*aMsg*/) sl@0: { sl@0: // Not used sl@0: } sl@0: sl@0: void CMMFDevSoundSession::InterfaceDeleted(TUid aInterfaceId) sl@0: { sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = InterfaceFromUid(aInterfaceId); sl@0: if (ptr == NULL) sl@0: { sl@0: // Not found sl@0: return; sl@0: } sl@0: TRAPD(err, ptr->RefreshL()); sl@0: if (err != KErrNone) sl@0: { sl@0: // Refresh failed, so tear down Mux/DeMux pair sl@0: TMMFEvent event; sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair; sl@0: item.iErrorCode = err; sl@0: event.iEventType = aInterfaceId; sl@0: item.iEventPckg() = event; sl@0: iMsgQueue.Send(item); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::CallbackFromAdaptorReceived sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::CallbackFromAdaptorReceived(TInt aType, TInt aError) sl@0: { sl@0: SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Enter. Type[%d] Error[%d]"), aType, aError); sl@0: if(aType == KCallbackRecordPauseComplete) sl@0: { sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxyPausedRecordCompleteEvent; sl@0: item.iErrorCode = KErrNone; sl@0: TInt status = iMsgQueue.Send(item); sl@0: } sl@0: else if(aType == KCallbackAutoPauseResume) sl@0: { sl@0: TMMFEvent event; sl@0: event.iErrorCode = KErrNone; sl@0: event.iEventType = KMMFEventCategoryAudioResourceAvailable; sl@0: SendEventToClient(event); sl@0: //coverity[uninit_use_in_call] sl@0: // Disabled Coverity warning, since it complains about iReserved1 member in TMMFEvent being uninitialised sl@0: } sl@0: else if (aType == KCallbackFlushComplete) sl@0: { sl@0: if(!iHandlingExtdCI && iRequestBeingServiced.Function()==EMMFDevSoundProxyEmptyBuffers) sl@0: { sl@0: //If we come here then it is due to a EMMFDevSoundProxyEmptyBuffers request from client. sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Calling TMMFDevSoundRequest::Complete on iRequestBeingServiced")); sl@0: iRequestBeingServiced.Complete(aError); sl@0: iOperationCompletePending = EFalse; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if( NeedToQueue() ) sl@0: { sl@0: // If not possible to service now, then queue request sl@0: // Encapsule the request sl@0: TMMFDevSoundRequest request(aType); sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: iQueuedRequests.Insert(request, 0); sl@0: } sl@0: else sl@0: { sl@0: // If there is no oustanding operation service inmediately sl@0: if (aType == KCallbackProcessingFinished) sl@0: { sl@0: DoProcessingFinished(); sl@0: } sl@0: else if(aType == KCallbackProcessingUnitError) sl@0: { sl@0: DoProcessingError(); sl@0: } sl@0: } sl@0: } sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::CallbackFromAdaptorReceived - Exit")); sl@0: } sl@0: sl@0: sl@0: // sl@0: // CMMFDevSoundSession::PreemptionStartedCallbackReceived sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::PreemptionStartedCallbackReceived() sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Enter")); sl@0: // Solution: Enqueue any request that arrives before preemption is completed sl@0: iOperationCompletePending = ETrue; sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionStartedCallbackReceived - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::PreemptionFinishedCallbackReceived sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::PreemptionFinishedCallbackReceived(TBool aCanStartNewOperation) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Enter")); sl@0: if (iHandlingExtdCI) sl@0: { sl@0: // we are in the middle of handling a CI, so ignore - will handle later when unwinding sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit. Exiting from if block for CI")); sl@0: return; sl@0: } sl@0: iOperationCompletePending = EFalse; sl@0: if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 ) sl@0: { sl@0: DequeueRequest(); sl@0: } sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::PreemptionFinishedCallbackReceived - Exit")); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::PreemptionClash sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::PreemptionClash() sl@0: { sl@0: //assumes sufficient space in the queue so ignore the return value sl@0: iQueuedRequests.Insert(iRequestBeingServiced, 0); sl@0: iPreemptionClash=ETrue; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::PreemptionClashWithStateChange sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::PreemptionClashWithStateChange() sl@0: { sl@0: #ifdef _DEBUG sl@0: TMMFDevSoundRequest msg = iQueuedRequests[0]; sl@0: // message being removed should be the one we previously pushed via PreemptionClash() sl@0: __ASSERT_DEBUG(iRequestBeingServiced==msg, Panic(ERequestBeingServicedMismatch)); sl@0: #endif sl@0: // remove without processing request with AsynchronousOperationComplete() completing the message sl@0: iQueuedRequests.Remove(0); sl@0: iPreemptionClash=EFalse; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::AdaptorControlsContext() sl@0: // sl@0: sl@0: TBool CMMFDevSoundSession::AdaptorControlsContext() const sl@0: { sl@0: return !iHandlingExtdCI; sl@0: } sl@0: sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* CMMFDevSoundSession::InterfaceFromUid(TUid aUid) sl@0: { sl@0: TInt count = iCustomInterfaceArray.Count(); sl@0: TInt id = aUid.iUid; sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* interface = NULL; sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: if (id == iCustomInterfaceArray[i].iId.iUid) sl@0: { sl@0: interface = iCustomInterfaceArray[i].iInterface; sl@0: break; sl@0: } sl@0: } sl@0: return interface; sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::SendEventToClient sl@0: // (other items were commented in a header). sl@0: // sl@0: void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Enter")); sl@0: TMMFDevSoundQueueItem item; sl@0: item.iRequest = EMMFDevSoundProxySETCEvent; sl@0: item.iErrorCode = KErrNone; sl@0: item.iEventPckg() = aEvent; sl@0: // assumes sufficient space in the queue so ignores the return value sl@0: TInt err = iMsgQueue.Send(item); sl@0: __ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg)); sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::SendEventToClient - Exit")); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::AsynchronousOperationComplete(TInt aError, TBool aCanStartNewOperation) sl@0: { sl@0: __ASSERT_DEBUG(!iHandlingExtdCI, Panic(EUnexpectedAsyncOpCompleteHandlingCI)); sl@0: // when handling CIs we should not reach here sl@0: sl@0: TInt error = aError; sl@0: if (!error) sl@0: { sl@0: // if have no error payload, use notified error. It will be KErrNone if not set, so just use. sl@0: error = NotifiedError(); sl@0: } sl@0: sl@0: switch (iRequestBeingServiced.Type()) sl@0: { sl@0: case TMMFDevSoundRequest::ESessionEvents: sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x] ==== ClosingDueException ==== ")); sl@0: iOperationCompletePending = EFalse; sl@0: if(iClosingWait->IsStarted()) sl@0: { sl@0: iClosingWait->AsyncStop(); sl@0: } sl@0: return; sl@0: } sl@0: // Complete the message for asynchronous requests sl@0: case TMMFDevSoundRequest::EConfigure_Asynchronous: sl@0: case TMMFDevSoundRequest::EAction_Asynchronous: sl@0: case TMMFDevSoundRequest::EQuery_Asynchronous: sl@0: case TMMFDevSoundRequest::ECustomInterfacesRelated: sl@0: { sl@0: if(iOperationCompletePending && aCanStartNewOperation) sl@0: { sl@0: if (iRequestBeingServiced.Function()==EMMFDevSoundProxyStop) sl@0: { sl@0: // flush the queue - will have removed any stale items added between initial call and MMRC's reaction sl@0: FlushQueuedRequests(); sl@0: FlushEventQueue(); sl@0: iChunk.Close(); sl@0: } sl@0: sl@0: if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCapabilities) sl@0: { sl@0: TMMFDevSoundProxySettings devSoundSet; sl@0: devSoundSet.iCaps = iDevSoundCapabilities; sl@0: TMMFDevSoundProxySettingsPckg pckg(devSoundSet); sl@0: MessageWrite(iRequestBeingServiced.Message(),TInt(2),pckg); sl@0: } sl@0: sl@0: if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCancelInitialize) sl@0: { sl@0: FlushEventQueue(); sl@0: } sl@0: sl@0: iRequestBeingServiced.Complete(error); sl@0: iOperationCompletePending = EFalse; sl@0: } sl@0: } sl@0: break; sl@0: case TMMFDevSoundRequest::EAction_PseudoAsynchronous: sl@0: { sl@0: if(iOperationCompletePending && aCanStartNewOperation) sl@0: { sl@0: iOperationCompletePending = EFalse; sl@0: } sl@0: } sl@0: break; sl@0: case TMMFDevSoundRequest::EQuery_Synchronous: sl@0: case TMMFDevSoundRequest::EConfigure_Synchronous: sl@0: case TMMFDevSoundRequest::EBufferExchangeRelated: sl@0: break; sl@0: case TMMFDevSoundRequest::ECallBackType: sl@0: { sl@0: if(iOperationCompletePending && aCanStartNewOperation) sl@0: { sl@0: iOperationCompletePending = EFalse; sl@0: } sl@0: } sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: sl@0: if(iRequestBeingServiced.Type() == TMMFDevSoundRequest::ECallBackType ) sl@0: { sl@0: SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete CallbackPF=%d pending=%d"), sl@0: iRequestBeingServiced.IsCallBack(), iOperationCompletePending ); sl@0: } sl@0: else sl@0: { sl@0: SYMBIAN_DEBPRN3(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d Requestype=%d"), sl@0: iRequestBeingServiced.Function(), iOperationCompletePending, iRequestBeingServiced.Type() ); sl@0: } sl@0: sl@0: sl@0: if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 ) sl@0: { sl@0: DequeueRequest(); sl@0: } sl@0: } sl@0: sl@0: void CMMFDevSoundSession::DequeueRequest() sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Enter")); sl@0: iAsyncQueueStart->Cancel(); // if we're in here cancel any background request sl@0: sl@0: TMMFDevSoundRequest msg = iQueuedRequests[0]; sl@0: sl@0: if (msg.IsCallBack() > 0) sl@0: { sl@0: iRequestBeingServiced.SetMessageCallback(); sl@0: //Call iPf function sl@0: SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x] ======== Service a queued request\n")); sl@0: if (msg.IsCallBack() == KCallbackProcessingFinished) sl@0: { sl@0: iQueuedRequests.Remove(0); sl@0: DoProcessingFinished(); sl@0: } sl@0: else if(msg.IsCallBack() == KCallbackProcessingUnitError) sl@0: { sl@0: iQueuedRequests.Remove(0); sl@0: DoProcessingError(); sl@0: } sl@0: sl@0: } sl@0: sl@0: if (iQueuedRequests.Count()>0) sl@0: { sl@0: // Some rules about what request can be followed sl@0: SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Flag can service new request\n")); sl@0: iAsyncQueueStart->CallBack(); sl@0: } sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DequeueRequest - Exit")); sl@0: } sl@0: sl@0: // AsyncQueueStartCallback sl@0: sl@0: sl@0: TInt CMMFDevSoundSession::AsyncQueueStartCallback(TAny* aPtr) sl@0: { sl@0: CMMFDevSoundSession* self = static_cast(aPtr); sl@0: self->AsyncQueueStartCallback(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CMMFDevSoundSession::AsyncQueueStartCallback() sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Service a queued request\n")); sl@0: TMMFDevSoundRequest msg = iQueuedRequests[0]; sl@0: iQueuedRequests.Remove(0); sl@0: TInt err = KErrNone; sl@0: TBool doRequest = ETrue; sl@0: if(iPreemptionClash) sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::AsyncQueueStartCallback - Re-applying client request due to Pre-emption clash")); sl@0: iPreemptionClash=EFalse; // clear flag before reading next request in queue sl@0: iAdapter->RollbackAdaptorActiveStateToBeforeCommit(); sl@0: if ((iRequestBeingServiced.Type() == TMMFDevSoundRequest::EAction_PseudoAsynchronous)) sl@0: { sl@0: doRequest = EFalse; sl@0: HandleAlreadyCompletedRequest(); sl@0: } sl@0: } sl@0: sl@0: if (doRequest) sl@0: { sl@0: TRAP(err,DoServiceRequestL(msg.Message())); sl@0: if(err != KErrNone) sl@0: { sl@0: msg.Complete(err); sl@0: } sl@0: } sl@0: sl@0: if (!iOperationCompletePending && iQueuedRequests.Count() != 0) sl@0: { sl@0: //dequeue next sl@0: DequeueRequest(); sl@0: } sl@0: } sl@0: sl@0: // CMMFDevSoundSession::CustomInterface() sl@0: // Returns a pointer reference to custom interface implementation returned by sl@0: // adaptation::CustomInterface method. sl@0: // Note this method is called indirectly by CI server-side plugins - both DeMux and sl@0: // CIServerExtension call this variously via MMMFDevSoundCustomInterfaceTarget or MCustomInterface sl@0: // sl@0: TAny* CMMFDevSoundSession::CustomInterface(TUid aInterfaceId) sl@0: { sl@0: TInt err = DoSetClientConfig(); // if required, this will connect to MMRC etc sl@0: if (err) sl@0: { sl@0: return NULL; // on any error, return NULL - not much more we can do sl@0: } sl@0: return iAdapter->CustomInterface(aInterfaceId); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoProcessingFinished() sl@0: // sl@0: void CMMFDevSoundSession::DoProcessingFinished() sl@0: { sl@0: ResetNotifiedError(); sl@0: sl@0: TBool asyncOperation = EFalse; sl@0: //ProcessingFinished should never fail sl@0: __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingFinishedReceived(asyncOperation)); sl@0: iOperationCompletePending = asyncOperation; sl@0: if (iOperationCompletePending) sl@0: { sl@0: iRequestBeingServiced.SetMessageCallback(); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoProcessingError() sl@0: // sl@0: void CMMFDevSoundSession::DoProcessingError() sl@0: { sl@0: ResetNotifiedError(); sl@0: sl@0: TBool asyncOperation = EFalse; sl@0: //ProcessingFinished should never fail sl@0: __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingError(asyncOperation)); sl@0: iOperationCompletePending = asyncOperation; sl@0: if (iOperationCompletePending) sl@0: { sl@0: iRequestBeingServiced.SetMessageCallback(); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::DoSetClientConfigL() sl@0: // Sets client configuration information to Adaptation. sl@0: // sl@0: TInt CMMFDevSoundSession::DoSetClientConfig() sl@0: { sl@0: TInt err = KErrNone; sl@0: if(!iSetClientConfigApplied) sl@0: { sl@0: CMMFDevSoundServer* server = sl@0: const_cast( sl@0: static_cast(Server())); sl@0: sl@0: ASSERT(server); // session should always have a server! sl@0: sl@0: TProcessId actualProcessId = server->ActualProcessId(); sl@0: TProcessId processId = server->ProcessId(); sl@0: sl@0: if (actualProcessId!=processId) sl@0: { sl@0: // we have a differing actual process id, so pass that to the adaptor too sl@0: err = iAdapter->SetClientConfig(actualProcessId, processId); sl@0: } sl@0: else sl@0: { sl@0: err = iAdapter->SetClientConfig(processId); sl@0: } sl@0: sl@0: if (!err) sl@0: { sl@0: iSetClientConfigApplied = ETrue; sl@0: } sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: // CMMFDevSoundSession::DoSetClientConfigL() sl@0: // Sets client configuration information to Adaptation. sl@0: // sl@0: void CMMFDevSoundSession::DoSetClientConfigL() sl@0: { sl@0: User::LeaveIfError(DoSetClientConfig()); sl@0: } sl@0: sl@0: // sl@0: // CMMFDevSoundSession::CreateChunk() sl@0: // Requests kernel to create global RChunk sl@0: // sl@0: TInt CMMFDevSoundSession::CreateChunk(TMMFDevSoundProxyHwBufPckg& aBufPckg, TInt aRequestedSize) sl@0: { sl@0: TInt status(KErrNone); sl@0: sl@0: if ( iChunk.Handle() ) sl@0: { sl@0: // If the DevSound Adaptation component requests a buffer size sl@0: // that can fit into current chunk's size, then re-use chunk. sl@0: if ( aRequestedSize <= iChunk.Size() ) sl@0: { sl@0: if (iForceSendOfChunkHandle) sl@0: { sl@0: iForceSendOfChunkHandle = EFalse; sl@0: aBufPckg().iChunkOp = EOpen; sl@0: } sl@0: else sl@0: { sl@0: aBufPckg().iChunkOp = ENull; sl@0: } sl@0: return status; sl@0: } sl@0: // The new request size exceeds the current chunk's area, close it. We sl@0: // will be creating new one in the following sequences. Note we could sl@0: // try to Adjust() the chunk, and see if the existing chunk could be sl@0: // extended instead, but this is assumed too rare an event for this sl@0: // optimisation sl@0: else sl@0: { sl@0: iChunk.Close(); sl@0: } sl@0: } sl@0: sl@0: // Request kernel to create global RChunk if needed sl@0: if ( !iChunk.Handle() ) sl@0: { sl@0: status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize, EOwnerThread); sl@0: if ( status == KErrNone ) sl@0: { sl@0: aBufPckg().iChunkOp = EOpen; sl@0: } sl@0: else sl@0: { sl@0: aBufPckg().iChunkOp = ENull; sl@0: } sl@0: } sl@0: iForceSendOfChunkHandle = EFalse; sl@0: return status; sl@0: } sl@0: sl@0: sl@0: // Custom Interface // sl@0: TInt CMMFDevSoundSession::DoOpenSlaveL(TUid aInterface, const TDesC8& aPackageBuf) sl@0: { sl@0: // it shouldn't be necessary to check if we have already instantiated this sl@0: // interface since the client would already know - however this is something sl@0: // that a licensee could implement if they required additional functionality sl@0: // e.g. many : 1 mappings between client and DevSound. sl@0: sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = NULL; sl@0: sl@0: // try and instantiate a plugin tunnelling sl@0: // pair to support this Custom Interface sl@0: ptr = iDeMuxUtility->CreateCustomInterfaceDeMuxL(aInterface); sl@0: sl@0: TInt handle = KNullHandle; sl@0: sl@0: if (ptr) sl@0: { sl@0: TMMFDevSoundCustomInterfaceDeMuxData data; sl@0: data.iInterface = ptr; sl@0: data.iId = aInterface; sl@0: sl@0: CleanupReleasePushL(*ptr); sl@0: sl@0: // setup demux plugin sl@0: ptr->SetInterfaceTarget(this); sl@0: sl@0: // try and open interface sl@0: // this will fetch the interface from the svr implementation sl@0: ptr->DoOpenSlaveL(aInterface, aPackageBuf); sl@0: User::LeaveIfError(iCustomInterfaceArray.Append(data)); sl@0: sl@0: CleanupStack::Pop(); // ptr sl@0: sl@0: handle = iCustomInterfaceArray.Count(); sl@0: return handle; sl@0: } sl@0: sl@0: // we couldn't set up the interface correctly so return a NULL sl@0: // handle to the client sl@0: return KNullHandle; sl@0: } sl@0: sl@0: void CMMFDevSoundSession::DoCloseSlaveL(TInt aHandle) sl@0: { sl@0: if (aHandle==KNullHandle) sl@0: { sl@0: // null-handle -> NOP sl@0: return; sl@0: } sl@0: sl@0: if (aHandle iCustomInterfaceArray.Count()) sl@0: { sl@0: // handle out of range - should not happen, but leave to show error sl@0: User::Leave(KErrBadHandle); sl@0: } sl@0: sl@0: TMMFDevSoundCustomInterfaceDeMuxData& data = iCustomInterfaceArray[aHandle-1]; sl@0: sl@0: // close and delete the plugin sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = data.iInterface; sl@0: ptr->DoCloseSlaveL(aHandle); sl@0: ptr->Release(); sl@0: sl@0: // clear the entry sl@0: data.iInterface = NULL; sl@0: data.iId.iUid = 0; sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::DoSendSlaveSyncCommandL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // use the demux utility to get the handle sl@0: TMMFDevSoundCIMessageData data; sl@0: iDeMuxUtility->GetSyncMessageDataL(aMessage, data); sl@0: sl@0: TInt handle = data.iHandle; sl@0: sl@0: if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count()))) sl@0: { sl@0: sl@0: User::Leave(KErrBadHandle); sl@0: } sl@0: sl@0: // call on demux plugin sl@0: return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandL(aMessage); sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::DoSendSlaveSyncCommandResultL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // use the demux utility to get the handle sl@0: TMMFDevSoundCIMessageData data; sl@0: iDeMuxUtility->GetSyncMessageDataL(aMessage, data); sl@0: sl@0: TInt handle = data.iHandle; sl@0: sl@0: if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count()))) sl@0: { sl@0: sl@0: User::Leave(KErrBadHandle); sl@0: } sl@0: sl@0: // call on demux plugin sl@0: return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandResultL(aMessage); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::DoSendSlaveAsyncCommandL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // use the demux utility to get the handle sl@0: TMMFDevSoundCIMessageData data; sl@0: iDeMuxUtility->GetAsyncMessageDataL(aMessage, data); sl@0: sl@0: TInt handle = data.iHandle; sl@0: sl@0: if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count()))) sl@0: { sl@0: User::Leave(KErrBadHandle); sl@0: } sl@0: sl@0: // call on demux plugin sl@0: iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandL(aMessage); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::DoSendSlaveAsyncCommandResultL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // use the demux utility to get the handle sl@0: TMMFDevSoundCIMessageData data; sl@0: iDeMuxUtility->GetAsyncMessageDataL(aMessage, data); sl@0: sl@0: TInt handle = data.iHandle; sl@0: sl@0: if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count()))) sl@0: { sl@0: User::Leave(KErrBadHandle); sl@0: } sl@0: sl@0: // call on demux plugin sl@0: iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandResultL(aMessage); sl@0: } sl@0: sl@0: sl@0: TBool CMMFDevSoundSession::DoRegisterAsClientL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg buf; sl@0: User::LeaveIfError(MessageRead(aMessage,0,buf)); sl@0: HBufC8* notificationRegistrationData = NULL; sl@0: notificationRegistrationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLengthL(1))); sl@0: TPtr8 dataPtr(notificationRegistrationData->Des()); sl@0: User::LeaveIfError(MessageRead(aMessage,1,dataPtr)); sl@0: DoSetClientConfigL();// added here instead of the CreateL() sl@0: TInt err = KErrNone; sl@0: err = iAdapter->RegisterAsClient(buf().iNotificationEventUid,dataPtr); sl@0: CleanupStack::PopAndDestroy(1); // Notification Registeration data sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoCancelRegisterAsClientL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg buf; sl@0: User::LeaveIfError(MessageRead(aMessage,0,buf)); sl@0: TInt err = KErrNone; sl@0: err = iAdapter->CancelRegisterAsClient(buf().iNotificationEventUid); sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoGetResourceNotificationDataL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TMMFDevSoundProxySettingsPckg buf; sl@0: User::LeaveIfError(MessageRead(aMessage,0,buf)); sl@0: HBufC8* notificationData = NULL; sl@0: notificationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLengthL(2))); sl@0: TPtr8 dataPtr(notificationData->Des()); sl@0: User::LeaveIfError(MessageRead(aMessage,2,dataPtr)); sl@0: TInt err = KErrNone; sl@0: err = iAdapter->GetResourceNotificationData(buf().iNotificationEventUid,dataPtr); sl@0: User::LeaveIfError(MessageWrite(aMessage,2,*notificationData)); sl@0: CleanupStack::PopAndDestroy(1); // Notification data sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoWillResumePlayL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err = KErrNone; sl@0: err = iAdapter->WillResumePlay(); sl@0: if (err != KErrNone) sl@0: { sl@0: aMessage.Complete(err); sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CMMFDevSoundSession::DoSetClientThreadInfoL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if(!iSetClientConfigApplied) sl@0: { sl@0: if (aMessage.HasCapability(ECapabilityMultimediaDD) && aMessage.HasCapability(ECapabilityUserEnvironment)) sl@0: { sl@0: TPckgBuf threadId; sl@0: User::LeaveIfError(MessageRead(aMessage, 1, threadId)); sl@0: sl@0: CMMFDevSoundServer* server = sl@0: const_cast(static_cast(Server())); sl@0: server->SetClientProcessIdL(threadId()); sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrPermissionDenied); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: void CMMFDevSoundSession::Panic(TMMFDevSoundSessionPanicCodes aCode) sl@0: { sl@0: User::Panic(KMMFDevSoundSessionPanicCategory, aCode); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::BufferErrorEvent() sl@0: { sl@0: // this will generate an processing error event and callback sl@0: iAdapter->BufferErrorEvent(); sl@0: } sl@0: sl@0: void CMMFDevSoundSession::FlushQueuedRequests() sl@0: { sl@0: for (TInt queueIndex = (iQueuedRequests.Count() - 1); queueIndex >= 0; --queueIndex) sl@0: { sl@0: if ((iQueuedRequests[queueIndex].Type() == TMMFDevSoundRequest::ESessionEvents) && sl@0: (iQueuedRequests[queueIndex].Function() == RMessage2::EDisConnect)) sl@0: { sl@0: continue; sl@0: } sl@0: iQueuedRequests.Remove(queueIndex); sl@0: } sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::MessageRead(const RMmfIpcMessage& aMessage, TInt aParam, TDes8& aResult) sl@0: { sl@0: if (!iDisconnecting) sl@0: { sl@0: return MmfMessageUtil::Read(aMessage, aParam, aResult); sl@0: } sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::MessageRead(const RMmfIpcMessage& aMessage, TInt aParam, TDes16& aResult) sl@0: { sl@0: if (!iDisconnecting) sl@0: { sl@0: return aMessage.Read(aParam, aResult); sl@0: } sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::MessageWrite(const RMmfIpcMessage& aMessage, TInt aParam, const TDesC8& aValue) sl@0: { sl@0: if (!iDisconnecting) sl@0: { sl@0: return MmfMessageUtil::Write(aMessage, aParam, aValue); sl@0: } sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: void CMMFDevSoundSession::ResetNotifiedError() sl@0: // called at beginning of commit cycle, so any error will be from callbacks sl@0: { sl@0: SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::ResetNotifiedError")); sl@0: iNotifiedError = KErrNone; sl@0: } sl@0: sl@0: TInt CMMFDevSoundSession::NotifiedError() const sl@0: // NotifiedError property sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifiedError(%d)"), iNotifiedError); sl@0: return iNotifiedError; sl@0: } sl@0: sl@0: void CMMFDevSoundSession::NotifyError(TInt aError) sl@0: // cache notified error sl@0: { sl@0: SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::NotifyError(%d)"), aError); sl@0: iNotifiedError = aError; sl@0: } sl@0: sl@0: // End of file