Update contrib.
1 // Copyright (c) 2006-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.
19 #include "mmfdevsoundproxy.h"
20 #include "mmfdevsoundcallbackhandler.h"
24 #define SYMBIAN_DEBPRN0(str) RDebug::Print(str, this)
25 #define SYMBIAN_DEBPRN1(str, val1) RDebug::Print(str, this, val1)
26 #define SYMBIAN_DEBPRN2(str, val1, val2) RDebug::Print(str, this, val1, val2)
28 #define SYMBIAN_DEBPRN0(str)
29 #define SYMBIAN_DEBPRN1(str, val1)
30 #define SYMBIAN_DEBPRN2(str, val1, val2)
33 // ============================ MEMBER FUNCTIONS ==============================
35 // ----------------------------------------------------------------------------
36 // CMsgQueueHandler::NewL
37 // Two-phased constructor.
38 // ----------------------------------------------------------------------------
40 CMsgQueueHandler* CMsgQueueHandler::NewL(
41 RMMFDevSoundProxy* aDevSoundProxy,
42 MDevSoundObserver& aDevSoundObserver,
43 RMsgQueue<TMMFDevSoundQueueItem>* aMsgQueue,
44 MMMFDevSoundCustomInterfaceObserver& aDevSoundCIObserver)
46 CMsgQueueHandler* self = new(ELeave) CMsgQueueHandler(aDevSoundProxy,
50 CleanupStack::PushL(self);
52 CleanupStack::Pop(self);
56 // ----------------------------------------------------------------------------
57 // CMsgQueueHandler::CMsgQueueHandler
58 // C++ default constructor can NOT contain any code, that might leave.
59 // ----------------------------------------------------------------------------
61 CMsgQueueHandler::CMsgQueueHandler (RMMFDevSoundProxy* aDevSoundProxy,
62 MDevSoundObserver& aDevSoundObserver,
63 RMsgQueue<TMMFDevSoundQueueItem>* aMsgQueue,
64 MMMFDevSoundCustomInterfaceObserver& aDevSoundCIObserver)
65 : CActive(EPriorityStandard),
66 iDevSoundProxy(aDevSoundProxy),
67 iDevSoundObserver(aDevSoundObserver),
69 iChunkDataPtr(0, 0, 0),
70 iDevSoundCIObserver(aDevSoundCIObserver)
72 CActiveScheduler::Add(this);
75 // ----------------------------------------------------------------------------
76 // CMsgQueueHandler::ConstructL
77 // Symbian 2nd phase constructor can leave.
78 // ----------------------------------------------------------------------------
80 void CMsgQueueHandler::ConstructL()
82 iEmptyBuffer = CMMFDescriptorBuffer::NewL(0);
83 iAsyncQueueFinish = new (ELeave) CAsyncCallBack(CActive::EPriorityStandard);
84 TCallBack asyncCallback(AsyncQueueFinishCallback, this);
85 iAsyncQueueFinish->Set(asyncCallback);
88 // ----------------------------------------------------------------------------
89 // CMsgQueueHandler::~CMsgQueueHandler
91 // ----------------------------------------------------------------------------
93 CMsgQueueHandler::~CMsgQueueHandler()
104 delete iAsyncQueueFinish;
107 // ----------------------------------------------------------------------------
108 // CMsgQueueHandler::ReceiveEvents
109 // Subscribes for Play Error event from the DevSound server.
110 // ----------------------------------------------------------------------------
112 void CMsgQueueHandler::ReceiveEvents()
114 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::ReceiveEvents - Enter"));
117 iMsgQueue->NotifyDataAvailable(iStatus);
120 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::ReceiveEvents - Exit"));
123 // ----------------------------------------------------------------------------
124 // CMsgQueueHandler::RunL
125 // Handles active object’s request completion event.
127 // ----------------------------------------------------------------------------
129 void CMsgQueueHandler::RunL()
131 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunL - Enter"));
132 TInt err = iMsgQueue->Receive(iCurrentItem);
134 if (err == KErrNone || err == KErrUnderflow)
136 // Signal that we're ready to process the next message
142 switch (iCurrentItem.iRequest)
144 case EMMFDevSoundProxyICEvent:
149 case EMMFDevSoundProxyBTBFEvent:
151 iAsyncQueueFinish->Cancel(); // if still active, means previous cycle did not Finish(). Cancel.
152 TRAP(err, DoBTBFCompleteL());
155 iAsyncQueueFinish->CallBack(); // async call to Finish()
156 iDevSoundObserver.PlayError(err);
160 case EMMFDevSoundProxyBTBEEvent:
162 iAsyncQueueFinish->Cancel(); // if still active, means previous cycle did not Finish(). Cancel.
163 TRAP(err, DoBTBECompleteL());
166 iAsyncQueueFinish->CallBack(); // async call to Finish()
167 iDevSoundObserver.RecordError(err);
171 case EMMFDevSoundProxyPEEvent:
173 if (iCurrentItem.iErrorCode == KErrDied ||
174 iCurrentItem.iErrorCode == KErrNotReady)
176 DoPlayErrorComplete();
177 // "this" pointer is no longer valid here as the associated
178 // instance of the DevSound has been deleted along with this
179 // CMsgQueueHandler object. So, we can only return here.
184 DoPlayErrorComplete();
188 case EMMFDevSoundProxyREEvent:
190 DoRecordErrorComplete();
193 case EMMFDevSoundProxyTFEvent:
195 DoToneFinishedComplete();
198 case EMMFDevSoundProxySETCEvent:
200 DoSendEventToClientComplete();
203 case EMMFDevSoundCustomCommandCloseMuxDemuxPair:
205 TMMFEvent pckgevent = iCurrentItem.iEventPckg();
206 TInt handle = pckgevent.iEventType.iUid;
207 iDevSoundCIObserver.CloseCustomInterface(handle);
210 case EMMFDevSoundProxyPausedRecordCompleteEvent:
212 DoPausedRecordComplete();
221 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunL - Exit"));
224 // ----------------------------------------------------------------------------
225 // CMsgQueueHandler::RunError
226 // Called by CActive object framework if RunL leaves.
227 // ----------------------------------------------------------------------------
229 TInt CMsgQueueHandler::RunError(TInt aError)
231 SYMBIAN_DEBPRN1(_L("CMsgQueueHandler[0x%x]::RunError - Enter. Error [%d]"), aError);
233 event.iErrorCode = aError;
234 iDevSoundObserver.SendEventToClient(event);
235 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::RunError - Exit"));
239 // ----------------------------------------------------------------------------
240 // CMsgQueueHandler::DoCancel
241 // Called when client cancels the wait for a completion of an outstanding
243 // ----------------------------------------------------------------------------
245 void CMsgQueueHandler::DoCancel()
247 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoCancel - Enter"));
248 iMsgQueue->CancelDataAvailable();
249 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoCancel - Exit"));
252 // ----------------------------------------------------------------------------
253 // CMsgQueueHandler::DoInitComplete
254 // Handles initialization completion event.
255 // ----------------------------------------------------------------------------
257 void CMsgQueueHandler::DoInitComplete()
259 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoInitComplete - Enter"));
260 iDevSoundObserver.InitializeComplete(iCurrentItem.iErrorCode);
261 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoInitComplete - Exit"));
264 // ----------------------------------------------------------------------------
265 // CMsgQueueHandler::DoPlayErrorComplete
266 // Handles play completion or cancel event.
267 // ----------------------------------------------------------------------------
269 void CMsgQueueHandler::DoPlayErrorComplete()
271 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPlayErrorComplete - Enter"));
272 iAsyncQueueFinish->CallBack(); // async call to Finish()
273 iDevSoundObserver.PlayError(iCurrentItem.iErrorCode);
274 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPlayErrorComplete - Exit"));
277 // ----------------------------------------------------------------------------
278 // CMsgQueueHandler::DoBTBFCompleteL
279 // Handles CMMFDevSound object's data request event to supply CMMFDevSound
280 // with the buffer that it needs to play.
281 // ----------------------------------------------------------------------------
283 void CMsgQueueHandler::DoBTBFCompleteL()
285 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBFCompleteL - Enter"));
286 // Returns either chunk handle or NULL
287 // any error is assumed to be due to a pending PlayError(), so the error here is ignored - the PlayError() call will ensure the client remains lively
288 // the chunk has been closed by the server. No action should be taken.
289 TBool requestChunk = iDataBuffer==NULL; // if we have no buffer, tell server we need a chunk handle
290 TInt handle = iDevSoundProxy->BufferToBeFilledData(requestChunk, iSetPckg);
291 if(handle >= KErrNone)
293 if ( iSetPckg().iChunkOp == EOpen )
295 AssignDataBufferToChunkL(handle);
301 iDataBuffer->SetStatus(EAvailable);
303 // Let the MMF fill the buffer with data
305 iDevSoundObserver.BufferToBeFilled(iDataBuffer);
307 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBFCompleteL - Exit"));
310 // ----------------------------------------------------------------------------
311 // CMsgQueueHandler::DoBTBECompleteL
312 // Handles CMMFDevSound object's data request event to supply CMMFDevSound
313 // with the buffer that it needs to record.
314 // ----------------------------------------------------------------------------
316 void CMsgQueueHandler::DoBTBECompleteL()
318 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBECompleteL - Enter"));
319 // Returns either chunk handle or NULL
320 // any error is assumed to be due to a pending RecordError(), so the error here is ignored - the RecordError() call will ensure the client remains lively
321 // the chunk has been closed by the server. No action should be taken.
322 TInt handle = iDevSoundProxy->BufferToBeEmptiedData(iSetPckg);
323 if(handle >= KErrNone)
325 if ( iSetPckg().iChunkOp == EOpen )
327 AssignDataBufferToChunkL(handle);
329 iDataBuffer->SetStatus(EFull);
330 iDataBuffer->Data().SetLength(iSetPckg().iRequestSize);
331 iDevSoundObserver.BufferToBeEmptied(iDataBuffer);
333 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoBTBECompleteL - Exit"));
336 // ----------------------------------------------------------------------------
337 // CMsgQueueHandler::DoRecordErrorComplete
338 // Handles record completion or cancel event.
339 // ----------------------------------------------------------------------------
341 void CMsgQueueHandler::DoRecordErrorComplete()
343 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoRecordErrorComplete - Enter"));
344 iAsyncQueueFinish->CallBack(); // async call to Finish()
345 iDevSoundObserver.RecordError(iCurrentItem.iErrorCode);
346 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoRecordErrorComplete - Exit"));
349 // ----------------------------------------------------------------------------
350 // CMsgQueueHandler::DoToneFinishedComplete
351 // Handles tone play completion event.
352 // ----------------------------------------------------------------------------
354 void CMsgQueueHandler::DoToneFinishedComplete()
356 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoToneFinishedComplete - Enter"));
357 iDevSoundObserver.ToneFinished(iCurrentItem.iErrorCode);
358 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoToneFinishedComplete - Exit"));
361 // ----------------------------------------------------------------------------
362 // CMsgQueueHandler::DoSendEventToClientComplete
363 // Sends DevSound server event completion notification to the client.
364 // ----------------------------------------------------------------------------
366 void CMsgQueueHandler::DoSendEventToClientComplete()
368 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoSendEventToClientComplete - Enter"));
369 iDevSoundObserver.SendEventToClient(iCurrentItem.iEventPckg());
370 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoSendEventToClientComplete - Exit"));
373 // ----------------------------------------------------------------------------
374 // CMsgQueueHandler::DoPausedRecordComplete
375 // Handles CMMFDevSound object's data request event to supply CMMFDevSound
376 // with the last buffer that it needs to record.
377 // ----------------------------------------------------------------------------
379 void CMsgQueueHandler::DoPausedRecordComplete()
381 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPausedRecordComplete - Enter"));
382 ASSERT(iEmptyBuffer);
383 iEmptyBuffer->SetLastBuffer(ETrue);
384 iDevSoundObserver.BufferToBeEmptied(iEmptyBuffer);
385 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoPausedRecordComplete - Exit"));
388 // ----------------------------------------------------------------------------
389 // CMsgQueueHandler::AssignDataBufferToChunkL
390 // Updates chunk handle.
391 // ----------------------------------------------------------------------------
393 void CMsgQueueHandler::AssignDataBufferToChunkL(TInt aHandle)
395 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::AssignDataBufferToChunkL - Enter"));
396 if ( iChunk.Handle() )
400 User::LeaveIfError(iChunk.SetReturnedHandle(aHandle));
401 // Adjust ptr to map only requested size
402 // The existing clients should handle TPtr with length zero and max length
403 // iSetPckg().iBufferSize.
404 // When we make sure every client handles it, replace second parameter with
406 //iChunkDataPtr.Set(iChunk.Base(), 0, iSetPckg().iBufferSize);
407 iChunkDataPtr.Set(iChunk.Base(), iSetPckg().iBufferSize, iSetPckg().iBufferSize);
410 iDataBuffer = CMMFPtrBuffer::NewL();
413 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::AssignDataBufferToChunkL - Exit"));
416 void CMsgQueueHandler::UpdateDataBufferL()
418 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::UpdateDataBufferL - Enter"));
419 ASSERT(iDataBuffer); // to get here, we should have a data buffer
420 iDataBuffer->SetPtr(iChunkDataPtr);
421 iDataBuffer->SetRequestSizeL(iSetPckg().iRequestSize);
422 iDataBuffer->SetLastBuffer(EFalse);
423 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::UpdateDataBufferL - Exit"));
426 void CMsgQueueHandler::Finish()
428 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::Finish - Enter"));
438 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::Finish - Exit"));
441 // AsyncQueueStartCallback
444 TInt CMsgQueueHandler::AsyncQueueFinishCallback(TAny* aPtr)
446 CMsgQueueHandler* self = static_cast<CMsgQueueHandler*>(aPtr);
447 self->DoAsyncQueueFinishCallback();
451 void CMsgQueueHandler::DoAsyncQueueFinishCallback()
453 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoAsyncQueueFinishCallback - Enter"));
455 SYMBIAN_DEBPRN0(_L("CMsgQueueHandler[0x%x]::DoAsyncQueueFinishCallback - Exit"));