os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSession.cpp
Update contrib.
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "MmfDevSoundSession.h"
18 #include "MmfDevSoundSessionXtnd.h"
19 #include "MmfDevSoundSessionBody.h"
21 #include "MmfAudioClientServer.h"
22 #include "MmfAudioServer.h"
23 #include "MmfDevSoundServer.h"
25 void CMMFDevSoundSession::CreateL(const CMmfIpcServer& aServer)
27 CMmfIpcSession::CreateL(aServer);
28 CMMFDevSoundServer& server =
29 const_cast<CMMFDevSoundServer&>(static_cast<const CMMFDevSoundServer&>(aServer));
30 server.IncrementSessionId();
31 iDevSoundSessionId = server.DevSoundSessionId();
32 iClientHasCaps = server.CheckClientCapabilities();
35 TBool CMMFDevSoundSession::CheckClientCapabilities()
37 return iClientHasCaps;
40 void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage)
42 TBool complete = EFalse;
43 switch(aMessage.Function())
45 case EMMFDevSoundProxyInitialize1:
46 complete = DoInitialize1L(aMessage);
48 case EMMFDevSoundProxyInitialize2:
49 complete = DoInitialize2L(aMessage);
51 case EMMFDevSoundProxyInitialize3:
52 complete = DoInitialize3L(aMessage);
54 case EMMFDevSoundProxyInitialize4:
55 complete = DoInitialize4L(aMessage);
57 case EMMFDevSoundProxyCapabilities:
58 complete = DoCapabilitiesL(aMessage);
60 case EMMFDevSoundProxyConfig:
61 complete = DoConfigL(aMessage);
63 case EMMFDevSoundProxySetConfig:
64 complete = DoSetConfigL(aMessage);
66 case EMMFDevSoundProxyMaxVolume:
67 complete = DoMaxVolumeL(aMessage);
69 case EMMFDevSoundProxyVolume:
70 complete = DoVolumeL(aMessage);
72 case EMMFDevSoundProxySetVolume:
73 complete = DoSetVolumeL(aMessage);
75 case EMMFDevSoundProxyMaxGain:
76 complete = DoMaxGainL(aMessage);
78 case EMMFDevSoundProxyGain:
79 complete = DoGainL(aMessage);
81 case EMMFDevSoundProxySetGain:
82 complete = DoSetGainL(aMessage);
84 case EMMFDevSoundProxyPlayBalance:
85 complete = DoGetPlayBalanceL(aMessage);
87 case EMMFDevSoundProxySetPlayBalance:
88 complete = DoSetPlayBalanceL(aMessage);
90 case EMMFDevSoundProxyRecordBalance:
91 complete = DoGetRecordBalanceL(aMessage);
93 case EMMFDevSoundProxySetRecordBalance:
94 complete = DoSetRecordBalanceL(aMessage);
96 case EMMFDevSoundProxyBTBFData:
97 complete = DoBufferToBeFilledDataL(aMessage);
99 case EMMFDevSoundProxyBTBEData:
100 complete = DoBufferToBeEmptiedDataL(aMessage);
102 case EMMFDevSoundProxyPlayInit:
103 complete = DoPlayInitL(aMessage);
105 case EMMFDevSoundProxyRecordInit:
106 complete = DoRecordInitL(aMessage);
108 case EMMFDevSoundProxyPlayData:
109 complete = DoPlayDataL(aMessage);
111 case EMMFDevSoundProxyRecordData:
112 complete = DoRecordDataL(aMessage);
114 case EMMFDevSoundProxyStop:
115 complete = DoStopL(aMessage);
117 case EMMFDevSoundProxyPause:
118 complete = DoPauseL(aMessage);
120 case EMMFDevSoundProxyPlayTone:
121 complete = DoPlayToneL(aMessage);
123 case EMMFDevSoundProxyPlayDualTone:
124 complete = DoPlayDualToneL(aMessage);
126 case EMMFDevSoundProxyPlayDTMFString:
127 complete = DoPlayDTMFStringL(aMessage);
129 case EMMFDevSoundProxyPlayToneSequence:
130 complete = DoPlayToneSequenceL(aMessage);
132 case EMMFDevSoundProxyPlayFixedSequence:
133 complete = DoPlayFixedSequenceL(aMessage);
135 case EMMFDevSoundProxySetDTMFLengths:
136 complete = DoSetDTMFLengthsL(aMessage);
138 case EMMFDevSoundProxySetVolumeRamp:
139 complete = DoSetVolumeRampL(aMessage);
141 case EMMFDevSoundProxyGetSupportedInputDataTypes:
142 complete = DoGetSupportedInputDataTypesL(aMessage);
144 case EMMFDevSoundProxyGetSupportedOutputDataTypes:
145 complete = DoGetSupportedOutputDataTypesL(aMessage);
147 case EMMFDevSoundProxyCopyFourCCArrayData:
148 complete = DoCopyFourCCArrayDataL(aMessage);
150 case EMMFDevSoundProxyGetRecordedBuffer:
151 complete = DoGetRecordedBufferL(aMessage);
153 case EMMFDevSoundProxySamplesRecorded:
154 complete = DoSamplesRecordedL(aMessage);
156 case EMMFDevSoundProxySamplesPlayed:
157 complete = DoSamplesPlayedL(aMessage);
159 case EMMFDevSoundProxySetToneRepeats:
160 complete = DoSetToneRepeatsL(aMessage);
162 case EMMFDevSoundProxySetPrioritySettings:
163 complete = DoSetPrioritySettingsL(aMessage);
165 case EMMFDevSoundProxyFixedSequenceName:
166 complete = DoFixedSequenceNameL(aMessage);
168 case EMMFDevSoundProxyFixedSequenceCount:
169 complete = DoFixedSequenceCountL(aMessage);
171 case EMMFDevSoundProxyRequestResourceNotification:
172 complete = DoRegisterAsClientL(aMessage);
174 case EMMFDevSoundProxyCancelRequestResourceNotification:
175 complete = DoCancelRegisterAsClientL(aMessage);
177 case EMMFDevSoundProxyGetResourceNotificationData:
178 complete = DoGetResourceNotificationDataL(aMessage);
180 case EMMFDevSoundProxyWillResumePlay:
181 complete = DoWillResumePlayL(aMessage);
183 case EMMFDevSoundProxySetClientThreadInfo:
184 complete = DoSetClientThreadInfoL(aMessage);
186 case EMMFDevSoundProxyGetTimePlayed:
187 complete = DoGetTimePlayedL(aMessage);
190 // custom command support
191 case EMMFDevSoundProxySyncCustomCommand:
192 complete = DoSyncCustomCommandL(aMessage);
194 case EMMFDevSoundProxySyncCustomCommandResult:
195 complete = DoSyncCustomCommandResultL(aMessage);
197 case EMMFDevSoundProxyAsyncCustomCommand:
198 complete = DoAsyncCustomCommandL(aMessage);
200 case EMMFDevSoundProxyAsyncCustomCommandResult:
201 complete = DoAsyncCustomCommandResultL(aMessage);
203 case EMMFDevSoundProxyEmptyBuffers:
204 complete = DoEmptyBuffersL(aMessage);
207 User::Leave(KErrNotSupported);
211 aMessage.Complete(KErrNone);
214 TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage)
216 if(iMsgQueue.Handle() == 0)
218 TInt err = iMsgQueue.Open(aMessage, 1); // a global queue.
219 User::LeaveIfError(err);
221 TMMFDevSoundProxySettingsPckg buf;
222 MmfMessageUtil::ReadL(aMessage,0,buf);
223 TMMFState mode = buf().iMode;
224 iBody->InitializeL(*this, mode);
229 TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage)
231 if(iMsgQueue.Handle() == 0)
233 TInt err = iMsgQueue.Open(aMessage, 1); // a global queue.
234 User::LeaveIfError(err);
236 TMMFDevSoundProxySettingsPckg buf;
237 MmfMessageUtil::ReadL(aMessage,0,buf);
238 TUid HWDev = buf().iHWDev;
239 TMMFState mode = buf().iMode;
240 iBody->InitializeL(*this, HWDev, mode);
245 TBool CMMFDevSoundSession::DoInitialize3L(const RMmfIpcMessage& /*aMessage*/)
247 User::Leave(KErrNotSupported);
251 TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage)
253 if(iMsgQueue.Handle() == 0)
255 TInt err = iMsgQueue.Open(aMessage, 1); // a global queue.
256 User::LeaveIfError(err);
258 TMMFDevSoundProxySettingsPckg buf;
259 aMessage.ReadL(TInt(0),buf);
260 TFourCC desiredFourCC = buf().iDesiredFourCC;
261 TMMFState mode = buf().iMode;
262 iBody->InitializeL(*this, desiredFourCC, mode);
267 TBool CMMFDevSoundSession::DoCapabilitiesL(const RMmfIpcMessage& aMessage)
269 TMMFDevSoundProxySettings set;
270 set.iCaps = iBody->Capabilities();
271 TMMFDevSoundProxySettingsPckg pckg(set);
272 aMessage.WriteL(TInt(2),pckg);
276 TBool CMMFDevSoundSession::DoConfigL(const RMmfIpcMessage& aMessage)
278 TMMFDevSoundProxySettings set;
279 set.iConfig = iBody->Config();
280 TMMFDevSoundProxySettingsPckg pckg(set);
281 aMessage.WriteL(TInt(2),pckg);
285 TBool CMMFDevSoundSession::DoSetConfigL(const RMmfIpcMessage& aMessage)
287 TMMFDevSoundProxySettingsPckg buf;
288 aMessage.ReadL(TInt(0),buf);
289 TMMFCapabilities config = buf().iConfig;
290 iBody->SetConfigL(config);
294 TBool CMMFDevSoundSession::DoMaxVolumeL(const RMmfIpcMessage& aMessage)
296 TMMFDevSoundProxySettings set;
297 set.iMaxVolume = iBody->MaxVolume();
298 TMMFDevSoundProxySettingsPckg pckg(set);
299 aMessage.WriteL(TInt(2),pckg);
303 TBool CMMFDevSoundSession::DoVolumeL(const RMmfIpcMessage& aMessage)
305 TMMFDevSoundProxySettings set;
306 set.iVolume = iBody->Volume();
307 TMMFDevSoundProxySettingsPckg pckg(set);
308 aMessage.WriteL(TInt(2),pckg);
312 TBool CMMFDevSoundSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
314 TMMFDevSoundProxySettingsPckg buf;
315 aMessage.ReadL(TInt(0),buf);
316 TInt volume = buf().iVolume;
317 iBody->SetVolume(volume);
321 TBool CMMFDevSoundSession::DoMaxGainL(const RMmfIpcMessage& aMessage)
323 TMMFDevSoundProxySettings set;
324 set.iMaxGain = iBody->MaxGain();
325 TMMFDevSoundProxySettingsPckg pckg(set);
326 aMessage.WriteL(TInt(2),pckg);
330 TBool CMMFDevSoundSession::DoGainL(const RMmfIpcMessage& aMessage)
332 TMMFDevSoundProxySettings set;
333 set.iGain = iBody->Gain();
334 TMMFDevSoundProxySettingsPckg pckg(set);
335 aMessage.WriteL(TInt(2),pckg);
339 TBool CMMFDevSoundSession::DoSetGainL(const RMmfIpcMessage& aMessage)
341 TMMFDevSoundProxySettingsPckg buf;
342 aMessage.ReadL(TInt(0),buf);
343 TInt gain = buf().iGain;
344 iBody->SetGain(gain);
348 TBool CMMFDevSoundSession::DoGetPlayBalanceL(const RMmfIpcMessage& aMessage)
350 TMMFDevSoundProxySettings set;
351 iBody->GetPlayBalanceL(set.iLeftPercentage, set.iRightPercentage);
352 TMMFDevSoundProxySettingsPckg pckg(set);
353 aMessage.WriteL(TInt(2),pckg);
357 TBool CMMFDevSoundSession::DoSetPlayBalanceL(const RMmfIpcMessage& aMessage)
359 TMMFDevSoundProxySettingsPckg buf;
360 aMessage.ReadL(TInt(0),buf);
361 TInt leftPercentage = buf().iLeftPercentage;
362 TInt rightPercentage = buf().iRightPercentage;
363 iBody->SetPlayBalanceL(leftPercentage, rightPercentage);
367 TBool CMMFDevSoundSession::DoGetRecordBalanceL(const RMmfIpcMessage& aMessage)
369 TMMFDevSoundProxySettings set;
370 iBody->GetRecordBalanceL(set.iLeftPercentage, set.iRightPercentage);
371 TMMFDevSoundProxySettingsPckg pckg(set);
372 aMessage.WriteL(TInt(2),pckg);
376 TBool CMMFDevSoundSession::DoSetRecordBalanceL(const RMmfIpcMessage& aMessage)
378 TMMFDevSoundProxySettingsPckg buf;
379 aMessage.ReadL(TInt(0),buf);
380 TInt leftPercentage = buf().iLeftPercentage;
381 TInt rightPercentage = buf().iRightPercentage;
382 iBody->SetRecordBalanceL(leftPercentage, rightPercentage);
386 TBool CMMFDevSoundSession::DoPlayInitL(const RMmfIpcMessage& /*aMessage*/)
392 TBool CMMFDevSoundSession::DoRecordInitL(const RMmfIpcMessage& aMessage)
394 iBody->RecordInitL(aMessage);
398 TBool CMMFDevSoundSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
400 TMMFDevSoundProxyHwBufPckg buf;
401 aMessage.ReadL(TInt(0),buf);
402 iBufferPlay->SetLastBuffer(buf().iLastBuffer);
404 aMessage.ReadL(TInt(1),iBufferPlay->Data());
405 return iBody->PlayData(aMessage);
408 TBool CMMFDevSoundSession::DoRecordDataL(const RMmfIpcMessage& aMessage)
410 return iBody->RecordData(aMessage);
413 TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/)
415 if(iMsgQueue.Handle() != 0)
417 TMMFDevSoundQueueItem queueItem;
419 while(err != KErrUnderflow)
421 err = iMsgQueue.Receive(queueItem);
428 TBool CMMFDevSoundSession::DoPauseL(const RMmfIpcMessage& /*aMessage*/)
434 TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage)
436 TMMFDevSoundProxySettingsPckg buf;
437 aMessage.ReadL(TInt(0),buf);
438 TInt frequency = buf().iFrequencyOne;
439 TTimeIntervalMicroSeconds duration(buf().iDuration);
440 iBody->PlayToneL(frequency, duration);
444 TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage)
446 TMMFDevSoundProxySettingsPckg buf;
447 aMessage.ReadL(TInt(0),buf);
448 TInt frequencyOne = buf().iFrequencyOne;
449 TInt frequencyTwo = buf().iFrequencyTwo;
450 TTimeIntervalMicroSeconds duration(buf().iDuration);
451 iBody->PlayDualToneL(frequencyOne, frequencyTwo, duration);
455 TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage)
457 TInt DTMFLength = User::LeaveIfError(aMessage.GetDesLength(0));
465 iDTMFString = HBufC::NewL(DTMFLength);
466 TPtr DTMFPtr = iDTMFString->Des();
467 aMessage.ReadL(TInt(0), DTMFPtr);
469 iBody->PlayDTMFStringL(*iDTMFString);
473 TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage)
475 TInt toneLength = User::LeaveIfError(aMessage.GetDesLength(0));
483 iToneSeqBuf = HBufC8::NewL(toneLength);
484 TPtr8 toneSeqPtr = iToneSeqBuf->Des();
485 aMessage.ReadL(TInt(0), toneSeqPtr);
487 iBody->PlayToneSequenceL(*iToneSeqBuf);
491 TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage)
494 aMessage.ReadL(TInt(0),buf);
497 iBody->PlayFixedSequenceL(seqNum);
501 TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage)
503 TMMFDevSoundProxySettingsPckg buf;
504 aMessage.ReadL(TInt(0),buf);
505 TTimeIntervalMicroSeconds32 toneOnLength = buf().iToneOnLength;
506 TTimeIntervalMicroSeconds32 toneOffLength = buf().iToneOffLength;
507 TTimeIntervalMicroSeconds32 pauseLength = buf().iPauseLength;
508 iBody->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength);
512 TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage)
514 TMMFDevSoundProxySettingsPckg buf;
515 aMessage.ReadL(TInt(0),buf);
516 TTimeIntervalMicroSeconds duration = buf().iDuration;
517 iBody->SetVolumeRamp(duration);
521 TBool CMMFDevSoundSession::DoGetSupportedInputDataTypesL(const RMmfIpcMessage& aMessage)
525 TMMFPrioritySettingsPckg buf;
526 aMessage.ReadL(TInt(0),buf);
527 TMMFPrioritySettings prioritySet = buf();
529 iBody->GetSupportedInputDataTypesL(iArray, prioritySet);
532 pckg() = iArray.Count();
533 aMessage.WriteL(TInt(2),pckg);
538 TBool CMMFDevSoundSession::DoGetSupportedOutputDataTypesL(const RMmfIpcMessage& aMessage)
542 TMMFPrioritySettingsPckg buf;
543 aMessage.ReadL(TInt(0),buf);
544 TMMFPrioritySettings prioritySet = buf();
546 iBody->GetSupportedOutputDataTypesL(iArray, prioritySet);
549 pckg() = iArray.Count();
550 aMessage.WriteL(TInt(2),pckg);
555 TBool CMMFDevSoundSession::DoSamplesRecordedL(const RMmfIpcMessage& aMessage)
558 pckg() = iBody->SamplesRecorded();
559 aMessage.WriteL(TInt(2),pckg);
563 TBool CMMFDevSoundSession::DoSamplesPlayedL(const RMmfIpcMessage& aMessage)
566 pckg() = iBody->SamplesPlayed();
567 aMessage.WriteL(TInt(2),pckg);
571 TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage)
573 TPckgBuf<TInt> countRepeat;
574 aMessage.ReadL(TInt(0),countRepeat);
576 TPckgBuf<TTimeIntervalMicroSeconds> repeatTS;
577 aMessage.ReadL(TInt(1),repeatTS);
579 iBody->SetToneRepeats(countRepeat(), repeatTS());
583 TBool CMMFDevSoundSession::DoSetPrioritySettingsL(const RMmfIpcMessage& aMessage)
585 TPckgBuf<TMMFPrioritySettings> prioritySet;
586 aMessage.ReadL(TInt(0),prioritySet);
588 iBody->SetPrioritySettings(prioritySet());
592 TBool CMMFDevSoundSession::DoFixedSequenceNameL(const RMmfIpcMessage& aMessage)
594 TPckgBuf<TInt> seqNum;
595 aMessage.ReadL(0, seqNum);
596 aMessage.WriteL(2, iBody->FixedSequenceName(seqNum()).Left(KMaxFixedSequenceNameLength));
600 TBool CMMFDevSoundSession::DoFixedSequenceCountL(const RMmfIpcMessage& aMessage)
602 TPckgBuf<TInt> fixSeqCountPckg;
603 TInt fixSeqCount = iBody->FixedSequenceCount();
604 fixSeqCountPckg = fixSeqCount;
606 aMessage.WriteL(TInt(0),fixSeqCountPckg);
611 TBool CMMFDevSoundSession::DoCopyFourCCArrayDataL(const RMmfIpcMessage& aMessage)
613 const TInt KBufExpandSize8 = 8;//two TInts
614 CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
615 CleanupStack::PushL(dataCopyBuffer);
616 RBufWriteStream stream;
617 stream.Open(*dataCopyBuffer);
618 CleanupClosePushL(stream);
619 for (TInt i=0;i<iArray.Count();i++)
621 stream.WriteInt32L(iArray[i].FourCC());
623 aMessage.WriteL(TInt(2), dataCopyBuffer->Ptr(0));
624 CleanupStack::PopAndDestroy(2);//iDataCopyBuffer, stream
629 TBool CMMFDevSoundSession::DoGetRecordedBufferL(const RMmfIpcMessage& aMessage)
631 MmfMessageUtil::Write(aMessage, TInt(0), iBufferRecord->Data());
635 TBool CMMFDevSoundSession::DoBufferToBeFilledDataL(const RMmfIpcMessage& aMessage)
637 TInt err = MmfMessageUtil::Write(aMessage, 0, iHwBufPckgFill);
638 aMessage.Complete(err);
642 TBool CMMFDevSoundSession::DoBufferToBeEmptiedDataL(const RMmfIpcMessage& aMessage)
644 TInt err = MmfMessageUtil::Write(aMessage, 0, iHwBufPckgEmpty);
645 aMessage.Complete(err);
649 TBool CMMFDevSoundSession::DoRegisterAsClientL(const RMmfIpcMessage& aMessage)
651 TMMFDevSoundProxySettingsPckg buf;
652 aMessage.ReadL(0,buf);
653 HBufC8* notificationRegistrationData = NULL;
654 notificationRegistrationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLengthL(1)));
655 TPtr8 dataPtr(notificationRegistrationData->Des());
656 aMessage.ReadL(1,dataPtr);
658 err = iBody->RegisterAsClient(buf().iNotificationEventUid,dataPtr);
659 CleanupStack::PopAndDestroy(1); // Notification Registeration data
662 aMessage.Complete(err);
668 TBool CMMFDevSoundSession::DoCancelRegisterAsClientL(const RMmfIpcMessage& aMessage)
670 TMMFDevSoundProxySettingsPckg buf;
671 aMessage.ReadL(0,buf);
673 err = iBody->CancelRegisterAsClient(buf().iNotificationEventUid);
676 aMessage.Complete(err);
682 TBool CMMFDevSoundSession::DoGetResourceNotificationDataL(const RMmfIpcMessage& aMessage)
684 TMMFDevSoundProxySettingsPckg buf;
685 aMessage.ReadL(0,buf);
686 HBufC8* notificationData = NULL;
687 notificationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLengthL(2)));
688 TPtr8 dataPtr(notificationData->Des());
689 aMessage.ReadL(2,dataPtr);
691 err = iBody->GetResourceNotificationData(buf().iNotificationEventUid,dataPtr);
692 aMessage.WriteL(2,*notificationData);
693 CleanupStack::PopAndDestroy(1); // Notification data
696 aMessage.Complete(err);
702 TBool CMMFDevSoundSession::DoWillResumePlayL(const RMmfIpcMessage& aMessage)
705 if(CheckClientCapabilities())
707 err = iBody->WillResumePlay();
711 err = KErrPermissionDenied;
716 aMessage.Complete(err);
722 TBool CMMFDevSoundSession::DoEmptyBuffersL(const RMmfIpcMessage& aMessage)
725 err = iBody->EmptyBuffers();
728 aMessage.Complete(err);
734 TBool CMMFDevSoundSession::DoSetClientThreadInfoL(const RMmfIpcMessage& aMessage)
736 if (aMessage.HasCapability(ECapabilityMultimediaDD))
738 TPckgBuf<TThreadId> threadId;
739 aMessage.ReadL(0, threadId);
741 CMMFDevSoundServer* server =
742 const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
743 server->SetClientCapabilitiesL(threadId());
744 iClientHasCaps = server->CheckClientCapabilities();
748 User::Leave(KErrPermissionDenied);
753 TBool CMMFDevSoundSession::DoGetTimePlayedL(const RMmfIpcMessage& aMessage)
756 TPckgBuf<TTimeIntervalMicroSeconds> timePckg;
757 err = iBody->GetTimePlayed(timePckg());
760 aMessage.Complete(err);
763 aMessage.WriteL(TInt(2),timePckg);
767 TBool CMMFDevSoundSession::DoSyncCustomCommandL(const RMmfIpcMessage& aMessage)
769 // check whether these are custom interface commands
770 // if so then send them into the demux pipeline
771 TInt retVal = KErrNone;
773 // try and process this as a custom interface
774 TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
777 // we can pass back valid values here since command
778 // has been handled by the DeMux framework
779 aMessage.Complete(retVal);
781 else if (err != KErrNotFound)
783 // the framework left with an error condition
784 // so we complete the message with this error
785 aMessage.Complete(err);
789 // commmand was not found inside the Custom Interface framework
790 // so we can pass onto the DevSound server implementation
791 // assume that this will either leave or complete the message
792 iBody->DoSyncCustomCommandL(aMessage);
795 // we complete our own message so don't need the framework to do so
799 TBool CMMFDevSoundSession::DoSyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
801 // check whether these are custom interface commands
802 TInt retVal = KErrNone;
803 TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
806 // we can pass back valid values here since command
807 // has been handled by the DeMux framework
808 aMessage.Complete(retVal);
810 else if (err != KErrNotFound)
812 // the framework left with an error condition
813 // so we complete the message with this error
814 aMessage.Complete(err);
818 // commmand was not found inside the Custom Interface framework
819 // so we can pass onto the DevSound server implementation
820 // assume that this will either leave or complete the message
821 iBody->DoSyncCustomCommandResultL(aMessage);
823 // we complete our own message so don't need the framework to do so
827 TBool CMMFDevSoundSession::DoAsyncCustomCommandL(const RMmfIpcMessage& aMessage)
829 // check whether these are custom interface commands
830 // async message will complete later
831 TRAPD(err, iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
832 if ((err != KErrNotFound) && (err != KErrNone))
834 // the framework left with an error condition
835 // so we complete the message with this error
836 aMessage.Complete(err);
838 else if (err == KErrNotFound)
840 // commmand was not found inside the Custom Interface framework
841 // so we can pass onto the DevSound server implementation
842 // assume that this will either leave or complete the message
843 iBody->DoAsyncCustomCommandL(aMessage);
848 TBool CMMFDevSoundSession::DoAsyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
850 // check whether these are custom interface commands
851 // async message will complete later
852 TRAPD(err, iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
853 if ((err != KErrNotFound) && (err != KErrNone))
855 // the framework left with an error condition
856 // so we complete the message with this error
857 aMessage.Complete(err);
859 else if (err == KErrNotFound)
861 // commmand was not found inside the Custom Interface framework
862 // so we can pass onto the DevSound server implementation
863 // assume that this will either leave or complete the message
864 iBody->DoAsyncCustomCommandL(aMessage);
871 void CMMFDevSoundSession::SendEventToClient(/*TMMFAudioPolicyEvent& aEvent*/)
878 * Default Constructor.
882 CMMFDevSoundSession::CMMFDevSoundSession()
886 CMMFDevSoundSession::~CMMFDevSoundSession()
888 // clear the array of custom interfaces
889 for (TInt i = 0; i < iCustomInterfaceArray.Count(); i++)
891 // we could have already deleted interfaces without
892 // removing them from the array so check for this
893 // and only delete release plugin if non-null
894 MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
897 iCustomInterfaceArray[i].iInterface->Release();
900 iCustomInterfaceArray.Reset();
901 iCustomInterfaceArray.Close();
903 delete iDeMuxUtility;
911 CMMFDevSoundServer* server =
912 const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
915 server->DecrementSessionId();
920 * -doxygen comments moved to header-
922 * Constructs, and returns a pointer to, a new CMMFDevSoundProxy object.
927 CMMFDevSoundSession* CMMFDevSoundSession::NewL(RServer2& aPolicyServerHandle)
929 CMMFDevSoundSession* self = new (ELeave) CMMFDevSoundSessionXtnd;
930 CleanupStack::PushL(self);
931 self->ConstructL(aPolicyServerHandle);
937 * -doxygen comments moved to header-
939 * Second phase constructor.
942 void CMMFDevSoundSession::ConstructL(RServer2& aPolicyServerHandle)
944 iBody = CMMFDevSoundSvrImp::NewL(static_cast<CMMFDevSoundSessionXtnd*>(this));
945 iBody->Construct3L(aPolicyServerHandle);
947 iDeMuxUtility = CMMFDevSoundCIDeMuxUtility::NewL(this);
951 void CMMFDevSoundSession::InitializeComplete(TInt aError)
953 // this may be a re-initialization and so we need to
954 // re-get our custom interfaces on the DeMux plugins
955 for (TInt i = 0; i < iCustomInterfaceArray.Count(); i++)
957 // we could have already deleted interfaces without
958 // removing them from the array so check for this
959 // and only delete release plugin if non-null
960 MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
963 // we can't keep track of..
964 // 1. where a custom interface is implemented
965 // 2. the uid of the custom interface to be refreshed
966 // so assume all have to be refreshed
967 TRAPD(err, iCustomInterfaceArray[i].iInterface->RefreshL());
969 // if there is an error then this is no longer a
970 // valid interface so could be deleted this from the array
971 // but this would involve notifying the client side
973 // since we have no way of notifying the client in this
974 // implementation and the fact that this is a prototype
975 // implementation and we will leave this up to the licensee
976 // to implement as required
980 TMMFDevSoundQueueItem item;
981 item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
982 item.iErrorCode = err;
983 event.iEventType.iUid = i+1;
984 item.iEventPckg() = event;
985 iMsgQueue.Send(item);
990 // The previous implementation was commented out,
991 // so add a new commented out implementation :)
992 TMMFDevSoundQueueItem item;
993 item.iRequest = EMMFDevSoundProxyICEvent;
994 item.iErrorCode = aError;
995 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
998 void CMMFDevSoundSession::ToneFinished(TInt aError)
1000 TMMFDevSoundQueueItem item;
1001 item.iRequest = EMMFDevSoundProxyTFEvent;
1002 item.iErrorCode = aError;
1003 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1006 void CMMFDevSoundSession::BufferToBeFilled(CMMFBuffer* aBuffer)
1008 // Package up the data for retrieval later (using a two stage process
1009 // as this payload is too large to be sent via the queue in one message)
1010 iBufferPlay = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
1011 iHwBufPckgFill().iBufferType = iBufferPlay->Type();
1012 iHwBufPckgFill().iRequestSize = iBufferPlay->RequestSize();
1013 iHwBufPckgFill().iBufferSize = iBufferPlay->Data().MaxLength();
1014 iHwBufPckgFill().iLastBuffer = iBufferPlay->LastBuffer();
1016 TMMFDevSoundQueueItem item;
1017 item.iRequest = EMMFDevSoundProxyBTBFEvent;
1018 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1021 void CMMFDevSoundSession::PlayError(TInt aError)
1023 TMMFDevSoundQueueItem item;
1024 item.iRequest = EMMFDevSoundProxyPEEvent;
1025 item.iErrorCode = aError;
1026 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1029 void CMMFDevSoundSession::BufferToBeEmptied(CMMFBuffer* aBuffer)
1031 iBufferRecord = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
1033 iHwBufPckgEmpty().iBufferType = iBufferRecord->Type();
1034 iHwBufPckgEmpty().iRequestSize = iBufferRecord->RequestSize();
1035 iHwBufPckgEmpty().iBufferSize = iBufferRecord->Data().MaxLength();
1036 iHwBufPckgEmpty().iLastBuffer = iBufferRecord->LastBuffer();
1038 TMMFDevSoundQueueItem item;
1039 item.iRequest = EMMFDevSoundProxyBTBEEvent;
1040 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1043 void CMMFDevSoundSession::RecordError(TInt aError)
1045 TMMFDevSoundQueueItem item;
1046 item.iRequest = EMMFDevSoundProxyREEvent;
1047 item.iErrorCode = aError;
1048 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1051 void CMMFDevSoundSession::ConvertError(TInt /*aError*/)
1055 void CMMFDevSoundSession::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/)
1059 void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent)
1061 TMMFDevSoundQueueItem item;
1062 item.iRequest = EMMFDevSoundProxySETCEvent;
1063 item.iEventPckg() = aEvent;
1064 iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
1067 /********************************************************************************
1068 * Non Exported public functions begins here *
1069 ********************************************************************************/
1072 // Audio Policy specific implementation begins here //
1077 * Sets Id for this instance of DevSound
1079 * @param "TInt aDevSoundId"
1080 * Integer value assigned by Audio Policy Server
1083 void CMMFDevSoundSessionXtnd::SetDevSoundId(TInt aDevSoundId)
1085 iBody->SetDevSoundId(aDevSoundId);
1090 * Returns information about this DevSound instance.
1092 * This method is used by Audio Policy Server to make audio policy decisions.
1094 * @return "TMMFDevSoundinfo"
1095 * A reference to TMMFDevSoundinfo object holding the current settings
1096 * of this DevSound instance.
1099 TMMFDevSoundInfo CMMFDevSoundSessionXtnd::DevSoundInfo()
1101 return iBody->DevSoundInfo();
1106 * Called by Audio Policy Server when a request to play is approved by the
1107 * Audio Policy Server.
1109 * Leaves on failure.
1112 void CMMFDevSoundSessionXtnd::StartPlayDataL()
1114 iBody->StartPlayDataL();
1119 * Called by Audio Policy Server when a request to record is approved by the
1120 * Audio Policy Server.
1122 * Leaves on failure.
1125 void CMMFDevSoundSessionXtnd::StartRecordDataL()
1127 iBody->StartRecordDataL();
1132 * Called by Audio Policy Server when a request to play tone is approved by
1133 * the Audio Policy Server.
1135 * Leaves on failure.
1138 void CMMFDevSoundSessionXtnd::StartPlayToneL()
1140 iBody->StartPlayToneL();
1145 * Called by Audio Policy Server when a request to play a dual tone is approved by
1146 * the Audio Policy Server.
1149 void CMMFDevSoundSessionXtnd::StartPlayDualToneL()
1151 iBody->StartPlayDualToneL();
1156 * Called by Audio Policy Server when a request to play DTMF String is approved
1157 * by the Audio Policy Server.
1159 * Leaves on failure.
1162 void CMMFDevSoundSessionXtnd::StartPlayDTMFStringL()
1164 iBody->StartPlayDTMFStringL();
1169 * Called by Audio Policy Server when a request to play tone sequence is
1170 * approved by the Audio Policy Server.
1172 * Leaves on failure.
1175 void CMMFDevSoundSessionXtnd::StartPlayToneSequenceL()
1177 iBody->StartPlayToneSequenceL();
1182 * Called by Audio Policy Server when the current DevSound instance looses the
1183 * policy because of another instance with a higher priority wants the device.
1186 void CMMFDevSoundSessionXtnd::SendEvent(const TMMFEvent& aEvent)
1188 iBody->SendEventToClient(aEvent);
1193 // Audio Policy specific implementation begins here //
1198 * Updates the total bytes played.
1201 void CMMFDevSoundSessionXtnd::UpdateBytesPlayed()
1203 iBody->UpdateBytesPlayed();
1207 // Custom Interface //
1208 TInt CMMFDevSoundSession::DoOpenSlaveL(TUid aInterface, const TDesC8& aPackageBuf)
1210 // it shouldn't be necessary to check if we have already instantiated this
1211 // interface since the client would already know - however this is something
1212 // that a licensee could implement if they required additional functionality
1213 // e.g. many : 1 mappings between client and DevSound.
1215 MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = NULL;
1217 // try and instantiate a plugin tunnelling
1218 // pair to support this Custom Interface
1219 ptr = iDeMuxUtility->CreateCustomInterfaceDeMuxL(aInterface);
1221 TInt handle = KNullHandle;
1225 TMMFDevSoundCustomInterfaceDeMuxData data;
1226 data.iInterface = ptr;
1227 data.iId = aInterface;
1229 CleanupReleasePushL(*ptr);
1231 // setup demux plugin
1232 ptr->SetInterfaceTarget(iBody);
1234 // try and open interface
1235 // this will fetch the interface from the svr implementation
1236 ptr->DoOpenSlaveL(aInterface, aPackageBuf);
1237 User::LeaveIfError(iCustomInterfaceArray.Append(data));
1239 CleanupStack::Pop(); // ptr
1241 handle = iCustomInterfaceArray.Count();
1245 // we couldn't set up the interface correctly so return a NULL
1246 // handle to the client
1250 void CMMFDevSoundSession::DoCloseSlaveL(TInt aHandle)
1252 if (aHandle==KNullHandle)
1254 // null-handle -> NOP
1258 if (aHandle<KNullHandle || aHandle > iCustomInterfaceArray.Count())
1260 // handle out of range - should not happen, but leave to show error
1261 User::Leave(KErrBadHandle);
1264 // set the current handle location to NULL
1265 // can't re-compress array because this will alter handles
1266 // we could change this to a list type structure but this
1267 // seems overkill for the current prototype
1268 TMMFDevSoundCustomInterfaceDeMuxData& data = iCustomInterfaceArray[aHandle-1];
1270 // close and delete the plugin
1271 MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = data.iInterface;
1272 ptr->DoCloseSlaveL(aHandle);
1276 data.iInterface = NULL;
1280 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandL(const RMmfIpcMessage& aMessage)
1282 // use the demux utility to get the handle
1283 TMMFDevSoundCIMessageData data;
1284 iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
1286 TInt handle = data.iHandle;
1288 if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
1291 User::Leave(KErrBadHandle);
1294 // call on demux plugin
1295 return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandL(aMessage);
1298 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandResultL(const RMmfIpcMessage& aMessage)
1300 // use the demux utility to get the handle
1301 TMMFDevSoundCIMessageData data;
1302 iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
1304 TInt handle = data.iHandle;
1306 if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
1309 User::Leave(KErrBadHandle);
1312 // call on demux plugin
1313 return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandResultL(aMessage);
1316 void CMMFDevSoundSession::DoSendSlaveAsyncCommandL(const RMmfIpcMessage& aMessage)
1318 // use the demux utility to get the handle
1319 TMMFDevSoundCIMessageData data;
1320 iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
1322 TInt handle = data.iHandle;
1324 if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
1326 User::Leave(KErrBadHandle);
1329 // call on demux plugin
1330 iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandL(aMessage);
1333 void CMMFDevSoundSession::DoSendSlaveAsyncCommandResultL(const RMmfIpcMessage& aMessage)
1335 // use the demux utility to get the handle
1336 TMMFDevSoundCIMessageData data;
1337 iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
1339 TInt handle = data.iHandle;
1341 if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
1343 User::Leave(KErrBadHandle);
1346 // call on demux plugin
1347 iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandResultL(aMessage);