|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Controls playback via plug-ins |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <featmgr.h> |
|
20 #include <mpxprivatecrkeys.h> |
|
21 #include <mpxlog.h> |
|
22 #include <mpxtaskqueue.h> |
|
23 #include <mpxmediageneraldefs.h> |
|
24 #include <mpxmediamusicdefs.h> |
|
25 #include <mpxmedia.h> |
|
26 #include <mpxcommonframeworkdefs.h> |
|
27 #include <mpxcommandgeneraldefs.h> |
|
28 #include <mpxplaybackcommanddefs.h> |
|
29 #include <mpxcollectionpath.h> |
|
30 #include <mpxattributespecs.h> |
|
31 #include <mpxmessagepluginupdatedefs.h> |
|
32 #include <mpxplaybackpluginversion2.h> |
|
33 #include <mpxcmn.h> |
|
34 #include <caf/caferr.h> |
|
35 #include <mpxmediageneralextdefs.h> |
|
36 |
|
37 #include "mpxplaybacksettings.h" |
|
38 #include "mpxautoresumehandler.h" |
|
39 #include "mpxplaybackcommandbuffer.h" |
|
40 #include "mpxplaybackactiveengineobserver.h" |
|
41 #include "mpxplaybackinitializer.h" |
|
42 #include "mpxplaybackengine.h" |
|
43 #include "mpxplaybackmediahelper.h" |
|
44 #include "mpxplaybackdummymediaobserver.h" |
|
45 |
|
46 // CONSTANTS |
|
47 const TInt KMPXSmallVolumeIncrement = 5; |
|
48 const TInt KMPXLargeVolumeIncrement = 10; |
|
49 const TInt KPercentMultiplier = 100; |
|
50 _LIT(KWmaExtension, ".wma"); |
|
51 _LIT(KRaExtension, ".ra"); |
|
52 |
|
53 |
|
54 // ============================ MEMBER FUNCTIONS ============================== |
|
55 |
|
56 // ---------------------------------------------------------------------------- |
|
57 // Two-phased constructor. |
|
58 // ---------------------------------------------------------------------------- |
|
59 // |
|
60 EXPORT_C CMPXPlaybackEngine* CMPXPlaybackEngine::NewL( |
|
61 CMPXPluginMonitor& aPluginMonitor, |
|
62 MMPXPlaybackActiveEngineObserver& aObserver, |
|
63 MMPXClientlistObserver* aClientListObserver, |
|
64 const TUid& aModeId) |
|
65 { |
|
66 CMPXPlaybackEngine* p=new(ELeave)CMPXPlaybackEngine(aPluginMonitor, |
|
67 aObserver, aModeId); |
|
68 CleanupStack::PushL(p); |
|
69 p->ConstructL(aClientListObserver); |
|
70 CleanupStack::Pop(p); |
|
71 return p; |
|
72 } |
|
73 |
|
74 |
|
75 // ---------------------------------------------------------------------------- |
|
76 // Two-phased constructor. |
|
77 // ---------------------------------------------------------------------------- |
|
78 // |
|
79 EXPORT_C CMPXPlaybackEngine* CMPXPlaybackEngine::NewL( |
|
80 CMPXPluginMonitor& aPluginMonitor, |
|
81 MMPXPlaybackActiveEngineObserver& aObserver, |
|
82 MMPXClientlistObserver* aClientListObserver, |
|
83 const TUid& aModeId, |
|
84 const TInt aCategory) |
|
85 { |
|
86 CMPXPlaybackEngine* p=new(ELeave)CMPXPlaybackEngine(aPluginMonitor, |
|
87 aObserver, aModeId, aCategory); |
|
88 CleanupStack::PushL(p); |
|
89 p->ConstructL(aClientListObserver); |
|
90 CleanupStack::Pop(p); |
|
91 return p; |
|
92 } |
|
93 |
|
94 // ---------------------------------------------------------------------------- |
|
95 // Constructor. |
|
96 // ---------------------------------------------------------------------------- |
|
97 // |
|
98 CMPXPlaybackEngine::CMPXPlaybackEngine( |
|
99 CMPXPluginMonitor& aPluginMonitor, |
|
100 MMPXPlaybackActiveEngineObserver& aObserver, |
|
101 const TUid& aModeId) |
|
102 : iReflector(*this), |
|
103 iPluginMonitor(aPluginMonitor), |
|
104 iItemId(KMPXInvalidItemId), |
|
105 iPlaySource(EPlayNone), |
|
106 iAccessPoint(0), |
|
107 iAccessPointSet(EFalse), |
|
108 iState(EPbStateNotInitialised), |
|
109 iNextState(EPbStateNotInitialised), |
|
110 iPluginState(EPbStateNotInitialised), |
|
111 iModeId(aModeId), |
|
112 iObserver(aObserver), |
|
113 iPreservedState( EPbStateNotInitialised ), |
|
114 iPreservedPosition( KErrNotFound ), |
|
115 iSkipping(EFalse), |
|
116 iPluginUid(KNullUid), |
|
117 iLastActiveProcess(KNullProcessId), |
|
118 iLastInactiveProcess(KNullProcessId) |
|
119 { |
|
120 iProperties[EPbPropertyVolumeRamp]=KPbFadeInDurationMicroSeconds; |
|
121 } |
|
122 |
|
123 // ---------------------------------------------------------------------------- |
|
124 // Constructor. |
|
125 // ---------------------------------------------------------------------------- |
|
126 // |
|
127 CMPXPlaybackEngine::CMPXPlaybackEngine( |
|
128 CMPXPluginMonitor& aPluginMonitor, |
|
129 MMPXPlaybackActiveEngineObserver& aObserver, |
|
130 const TUid& aModeId, |
|
131 const TInt aCategory) |
|
132 : iReflector(*this), |
|
133 iPluginMonitor(aPluginMonitor), |
|
134 iItemId(KMPXInvalidItemId), |
|
135 iPlaySource(EPlayNone), |
|
136 iAccessPoint(0), |
|
137 iAccessPointSet(EFalse), |
|
138 iState(EPbStateNotInitialised), |
|
139 iNextState(EPbStateNotInitialised), |
|
140 iPluginState(EPbStateNotInitialised), |
|
141 iModeId(aModeId), |
|
142 iObserver(aObserver), |
|
143 iPreservedState( EPbStateNotInitialised ), |
|
144 iPreservedPosition( KErrNotFound ), |
|
145 iSkipping(EFalse), |
|
146 iPluginUid(KNullUid), |
|
147 iLastActiveProcess(KNullProcessId), |
|
148 iLastInactiveProcess(KNullProcessId), |
|
149 iCategory(aCategory) |
|
150 { |
|
151 iProperties[EPbPropertyVolumeRamp]=KPbFadeInDurationMicroSeconds; |
|
152 } |
|
153 |
|
154 |
|
155 // ---------------------------------------------------------------------------- |
|
156 // 2nd phase constructor. |
|
157 // ---------------------------------------------------------------------------- |
|
158 // |
|
159 void CMPXPlaybackEngine::ConstructL(MMPXClientlistObserver* aClientListObserver) |
|
160 { |
|
161 MPX_FUNC_EX("CMPXPlaybackEngine::ConstructL"); |
|
162 iClientList=CMPXClientList::NewL(aClientListObserver); |
|
163 iPluginHandler=CMPXPlaybackPluginHandler::NewL(iPluginMonitor, *this, *this); |
|
164 iCmdBuffer=CMPXPlaybackCmdBuffer::NewL(*this); |
|
165 iProgressTimer=CHeartbeat::NewL(CActive::EPriorityStandard); |
|
166 iSeekTimer=CPeriodic::NewL(CActive::EPriorityStandard); |
|
167 iAccessoryObs=CMPXAccessoryObserver::NewL(*this); |
|
168 iAutoResumeHandler = CMPXAutoResumeHandler::NewL(*this, EFalse); |
|
169 iPlaybackSettings = CMPXPlaybackSettings::NewL(); |
|
170 iTaskQueue = CMPXActiveTaskQueue::NewL(); |
|
171 FeatureManager::InitializeLibL(); |
|
172 |
|
173 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
174 // Intialise volume level increment based on the accessory plugged in. |
|
175 SetVolumeIncrement( iAccessoryObs->AccessoryModeL() ); |
|
176 #else |
|
177 iVolumeIncrement = KMPXLargeVolumeIncrement; |
|
178 #endif |
|
179 |
|
180 iMediaHelper = CMPXPlaybackMediaHelper::NewL( *this ); |
|
181 iDummyMediaObserver = new(ELeave) CMPXPlaybackDummyMediaObserver(); |
|
182 // Select local plugin by default if none selected |
|
183 iPluginHandler->SelectPlayersL( EPbLocal ); |
|
184 iInitVolume = ETrue; |
|
185 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
186 iVolRoundedUp = EFalse; |
|
187 #endif |
|
188 iPluginHandler->Plugin()->PropertyL( EPbPropertyVolume ); |
|
189 } |
|
190 |
|
191 // ---------------------------------------------------------------------------- |
|
192 // Destructor |
|
193 // ---------------------------------------------------------------------------- |
|
194 // |
|
195 EXPORT_C CMPXPlaybackEngine::~CMPXPlaybackEngine() |
|
196 { |
|
197 MPX_FUNC_EX("CMPXPlaybackEngine::~CMPXPlaybackEngine"); |
|
198 if (iPluginHandler->Plugin()) |
|
199 { |
|
200 iPluginHandler->Plugin()->CancelRequest(); |
|
201 } |
|
202 |
|
203 DoClose(); |
|
204 |
|
205 if (iTaskQueue) |
|
206 { |
|
207 delete iTaskQueue; |
|
208 } |
|
209 |
|
210 if (iProgressTimer) |
|
211 { |
|
212 delete iProgressTimer; |
|
213 } |
|
214 |
|
215 if (iSeekTimer) |
|
216 { |
|
217 delete iSeekTimer; |
|
218 } |
|
219 |
|
220 FeatureManager::UnInitializeLib(); |
|
221 iFile.Close(); |
|
222 delete iCmdBuffer; |
|
223 delete iAccessoryObs; |
|
224 delete iAutoResumeHandler; |
|
225 delete iPluginHandler; |
|
226 delete iClientList; |
|
227 delete iPlaybackSettings; |
|
228 delete iInitializer; |
|
229 iMediaAttrs.Close(); |
|
230 delete iMediaHelper; |
|
231 delete iDummyMediaObserver; |
|
232 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
233 iFile64.Close(); |
|
234 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
235 } |
|
236 |
|
237 // ---------------------------------------------------------------------------- |
|
238 // Initialises from collection |
|
239 // ---------------------------------------------------------------------------- |
|
240 // |
|
241 EXPORT_C void CMPXPlaybackEngine::InitL( |
|
242 const CMPXCollectionPlaylist& aPlaylist, |
|
243 TBool aPlay ) |
|
244 { |
|
245 MPX_FUNC_EX("CMPXPlaybackEngine::InitL"); |
|
246 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
247 iInitNext = aPlaylist.PreInitPlugin(); |
|
248 if ( iInitNext ) |
|
249 { |
|
250 if ( !iInitializer ) |
|
251 { |
|
252 iInitializer=CMPXPlaybackInitializer::NewL(*this, *iMediaHelper); |
|
253 } |
|
254 iInitializer->Close(); |
|
255 } |
|
256 |
|
257 HandleCloseL(); |
|
258 iPlaySource=EPlayFromCollection; |
|
259 iPlaylist=CMPXCollectionPlaylist::NewL(aPlaylist, this); |
|
260 CMPXCollectionPlaylist::TRepeatMode repeatmode = |
|
261 static_cast<CMPXCollectionPlaylist::TRepeatMode>( |
|
262 iProperties[EPbPropertyRepeatMode]); |
|
263 iPlaylist->SetRepeatMode(repeatmode); |
|
264 // if current index is not 0, play the selected item, otherwise play any one |
|
265 iPlaylist->SetShuffleL(iProperties[EPbPropertyRandomMode], |
|
266 iPlaylist->Index()!=-1); |
|
267 iSkipping = EFalse; |
|
268 if ( aPlay ) |
|
269 { |
|
270 if ( iPlaylist->Count() > 0 ) |
|
271 { |
|
272 iNextState=EPbStateNotInitialised; |
|
273 MediaFromCollectionL(); |
|
274 } |
|
275 } |
|
276 else |
|
277 { |
|
278 if ( iPlaylist->Count() > 0 ) |
|
279 { |
|
280 iState = EPbStateStopped; |
|
281 } |
|
282 else |
|
283 { |
|
284 iState = EPbStateNotInitialised; |
|
285 } |
|
286 iAutoResumeHandler->HandlePlaybackStateChange(iState); |
|
287 iClientList->SendMsgL( |
|
288 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
289 iNextState = iState; |
|
290 //update now playing view |
|
291 iClientList->SendMsgL(TMPXPlaybackMessage( |
|
292 TMPXPlaybackMessage::EPlaylistUpdated)); |
|
293 iClientList->SendMsgL( |
|
294 TMPXPlaybackMessage( |
|
295 TMPXPlaybackMessage::EInitializeComplete, |
|
296 0, |
|
297 EFalse)); |
|
298 |
|
299 iPluginUid = iPluginHandler->Plugin()->Uid(); |
|
300 |
|
301 RArray<TMPXAttribute> dummy; |
|
302 CleanupClosePushL( dummy ); |
|
303 dummy.AppendL( KMPXMediaGeneralUri ); // dummy attribute to get |
|
304 iPlaylist->MediaL( dummy.Array(), *iDummyMediaObserver); |
|
305 CleanupStack::PopAndDestroy( &dummy ); |
|
306 } |
|
307 } |
|
308 |
|
309 // ---------------------------------------------------------------------------- |
|
310 // Initialises from URI |
|
311 // ---------------------------------------------------------------------------- |
|
312 // |
|
313 EXPORT_C void CMPXPlaybackEngine::InitL(const TDesC& aUri,const TDesC8& aType) |
|
314 { |
|
315 MPX_FUNC_EX("CMPXPlaybackEngine::InitL(const TDesC& aUri,const TDesC8& aType)"); |
|
316 MPX_DEBUG2("CMPXPlaybackEngine::InitL(%S)", &aUri); |
|
317 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
318 iInitNext=EFalse; |
|
319 HandleCloseL(); |
|
320 iPlaySource=EPlayFromUri; |
|
321 iNextState=EPbStateNotInitialised; |
|
322 delete iUri; |
|
323 iUri = NULL; |
|
324 iUri=aUri.AllocL(); |
|
325 iItemId = KMPXInvalidItemId; |
|
326 TRAPD( err, InitL(&aUri,&aType,NULL) ); |
|
327 if ( KErrNotFound == err || KErrPathNotFound == err ) |
|
328 { |
|
329 // Mark item as Invalid |
|
330 MarkItemInvalid( ETrue ); |
|
331 User::Leave( err ); |
|
332 } |
|
333 } |
|
334 |
|
335 // ---------------------------------------------------------------------------- |
|
336 // Initialises from file. |
|
337 // ---------------------------------------------------------------------------- |
|
338 // |
|
339 EXPORT_C void CMPXPlaybackEngine::InitL(const RFile& aFile) |
|
340 { |
|
341 MPX_FUNC_EX("CMPXPlaybackEngine::InitL(const RFile& aFile)"); |
|
342 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
343 iInitNext=EFalse; |
|
344 HandleCloseL(); |
|
345 iPlaySource=EPlayFromFile; |
|
346 iNextState=EPbStateNotInitialised; |
|
347 iFile.Duplicate(aFile); |
|
348 TRAPD( err, InitL(NULL,NULL,&iFile) ); |
|
349 if ( KErrNotFound == err ) |
|
350 { |
|
351 // Mark item as Invalid |
|
352 MarkItemInvalid( ETrue ); |
|
353 User::Leave( err ); |
|
354 } |
|
355 } |
|
356 |
|
357 // ---------------------------------------------------------------------------- |
|
358 // Initialises from URI |
|
359 // ---------------------------------------------------------------------------- |
|
360 // |
|
361 EXPORT_C void CMPXPlaybackEngine::InitStreamingL(const TDesC& aUri, const TDesC8& aType, const TInt aAccessPoint) |
|
362 { |
|
363 MPX_FUNC_EX("CMPXPlaybackEngine::InitStreamingL(const TDesC& aUri, const TInt aAccessPoint)"); |
|
364 MPX_DEBUG4("CMPXPlaybackEngine::InitStreamingL(%S), (%s), (%d)", &aUri, &aType, aAccessPoint); |
|
365 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
366 iInitNext=EFalse; |
|
367 HandleCloseL(); |
|
368 iPlaySource=EPlayFromUri; |
|
369 iNextState=EPbStateNotInitialised; |
|
370 delete iUri; |
|
371 iUri = NULL; |
|
372 iUri=aUri.AllocL(); |
|
373 iItemId = KMPXInvalidItemId; |
|
374 iAccessPoint = aAccessPoint; |
|
375 iAccessPointSet = ETrue; |
|
376 TRAPD( err, InitL(&aUri,&aType,NULL,aAccessPoint) ); |
|
377 if ( KErrNotFound == err || KErrPathNotFound == err ) |
|
378 { |
|
379 // Mark item as Invalid |
|
380 MarkItemInvalid( ETrue ); |
|
381 User::Leave( err ); |
|
382 } |
|
383 } |
|
384 |
|
385 // ---------------------------------------------------------------------------- |
|
386 // Initialises from file. |
|
387 // ---------------------------------------------------------------------------- |
|
388 // |
|
389 EXPORT_C void CMPXPlaybackEngine::InitStreamingL(const RFile& aFile, const TInt aAccessPoint) |
|
390 { |
|
391 MPX_FUNC_EX("CMPXPlaybackEngine::InitStreamingL(const RFile& aFile, const TInt aAccessPoint)"); |
|
392 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
393 iInitNext=EFalse; |
|
394 HandleCloseL(); |
|
395 iPlaySource=EPlayFromFile; |
|
396 iNextState=EPbStateNotInitialised; |
|
397 iFile.Duplicate(aFile); |
|
398 iAccessPoint = aAccessPoint; |
|
399 iAccessPointSet = ETrue; |
|
400 TRAPD( err, InitL(NULL,NULL,&iFile,aAccessPoint)); |
|
401 if ( KErrNotFound == err ) |
|
402 { |
|
403 // Mark item as Invalid |
|
404 MarkItemInvalid( ETrue ); |
|
405 User::Leave( err ); |
|
406 } |
|
407 } |
|
408 |
|
409 // ---------------------------------------------------------------------------- |
|
410 // Cancels all outsatnding calls (tasks): plug-in should only have one |
|
411 // outstanding so that is canceled; the tasks are deleted and removed from the |
|
412 // queue |
|
413 // ---------------------------------------------------------------------------- |
|
414 // |
|
415 EXPORT_C void CMPXPlaybackEngine::CancelRequests() |
|
416 { |
|
417 MPX_FUNC_EX("CMPXPlaybackEngine::CancelRequests()"); |
|
418 CMPXPlaybackPlugin* p(iPluginHandler->Plugin()); |
|
419 if (iCallback && iTaskQueue->PtrData()) |
|
420 { // there is outstanding request |
|
421 p = static_cast<CMPXPlaybackPlugin*>(iTaskQueue->PtrData()); |
|
422 } |
|
423 if (p) |
|
424 { |
|
425 p->CancelRequest(); |
|
426 if (iCallback) |
|
427 { |
|
428 iTaskQueue->CompleteTask(); |
|
429 iCallback = NULL; |
|
430 } |
|
431 } |
|
432 if (iPlaylist) |
|
433 { |
|
434 iPlaylist->CancelRequest(); |
|
435 } |
|
436 if (iInitializer) |
|
437 { |
|
438 iInitializer->Close(); |
|
439 } |
|
440 iTaskQueue->CancelRequests(); |
|
441 iMediaHelper->CancelRequests(); |
|
442 } |
|
443 |
|
444 // ---------------------------------------------------------------------------- |
|
445 // Handle a command |
|
446 // ---------------------------------------------------------------------------- |
|
447 // |
|
448 EXPORT_C void CMPXPlaybackEngine::CommandL(TMPXPlaybackCommand aCmd, |
|
449 TInt aData) |
|
450 { |
|
451 MPX_DEBUG2("CMPXPlaybackEngine::CommandL(%d) entering", aCmd); |
|
452 iClientList->SendMsgL(TMPXPlaybackMessage( |
|
453 TMPXPlaybackMessage::ECommandReceived, |
|
454 aCmd, |
|
455 0)); |
|
456 if (iCmdBuffer->CommandForBuffering(aCmd)) |
|
457 { |
|
458 // Buffered commands are not valid if there are no items in playlist |
|
459 TBool cmdOK( ETrue ); |
|
460 if ( iPlaySource == EPlayFromCollection ) |
|
461 { |
|
462 if ( iPlaylist ) |
|
463 { |
|
464 cmdOK = ( iPlaylist->Count() > 0 ); |
|
465 } |
|
466 else |
|
467 { |
|
468 cmdOK = EFalse; |
|
469 } |
|
470 } |
|
471 if ( cmdOK ) |
|
472 { |
|
473 iCmdBuffer->BufferCommandL(aCmd,iNextState, |
|
474 iProperties[EPbPropertyPosition]); |
|
475 } |
|
476 } |
|
477 else |
|
478 { |
|
479 HandleCommandL(aCmd,aData); |
|
480 } |
|
481 MPX_DEBUG1("CMPXPlaybackEngine::CommandL() exiting"); |
|
482 } |
|
483 |
|
484 // ---------------------------------------------------------------------------- |
|
485 // Handle a command |
|
486 // ---------------------------------------------------------------------------- |
|
487 // |
|
488 EXPORT_C void CMPXPlaybackEngine::CommandL( |
|
489 CMPXCommand& aCmd, |
|
490 const CMPXMessageQueue& aMsgQueue ) |
|
491 { |
|
492 MPX_FUNC_EX("CMPXPlaybackEngine::CommandL(CMPXCommand& aCmd)"); |
|
493 ASSERT(aCmd.IsSupported(KMPXCommandGeneralId)); |
|
494 TInt id = aCmd.ValueTObjectL<TInt>(KMPXCommandGeneralId); |
|
495 switch (id) |
|
496 { |
|
497 case KMPXCommandIdPlaybackGeneral: |
|
498 { |
|
499 ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralType)); |
|
500 TMPXPlaybackCommand cmd = static_cast<TMPXPlaybackCommand>( |
|
501 aCmd.ValueTObjectL<TInt>(KMPXCommandPlaybackGeneralType)); |
|
502 if ( EPbCmdPlay == cmd || |
|
503 EPbCmdPlayPause == cmd || |
|
504 EPbCmdStop == cmd) |
|
505 { |
|
506 ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralClientPid)); |
|
507 iLastActiveProcess = aCmd.ValueTObjectL<TProcessId>( |
|
508 KMPXCommandPlaybackGeneralClientPid); |
|
509 } |
|
510 else if (EPbCmdStop == cmd) |
|
511 { |
|
512 ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralClientPid)); |
|
513 iLastInactiveProcess = aCmd.ValueTObjectL<TProcessId>( |
|
514 KMPXCommandPlaybackGeneralClientPid); |
|
515 } |
|
516 TInt data(0); |
|
517 if (aCmd.IsSupported(KMPXCommandPlaybackGeneralData)) |
|
518 { |
|
519 data = aCmd.ValueTObjectL<TInt>(KMPXCommandPlaybackGeneralData); |
|
520 } |
|
521 MPX_DEBUG3("CMPXPlaybackEngine::CommandL general command (%d) data %d ", |
|
522 cmd, data); |
|
523 // Check if command is to be buffered, if not then handle command directly |
|
524 TBool noBuffer( EFalse ); |
|
525 if ( aCmd.IsSupported( KMPXCommandPlaybackGeneralNoBuffer )) |
|
526 { |
|
527 noBuffer = aCmd.ValueTObjectL<TBool>( |
|
528 KMPXCommandPlaybackGeneralNoBuffer ); |
|
529 } |
|
530 |
|
531 if ( noBuffer ) |
|
532 { |
|
533 HandleCommandL( cmd, data ); |
|
534 } |
|
535 else |
|
536 { |
|
537 // Map to TMPXCommand command |
|
538 CommandL(cmd, data); |
|
539 } |
|
540 break; |
|
541 } |
|
542 case KMPXCommandSubscriptionAdd: |
|
543 { |
|
544 TInt index( iClientList->Find( aMsgQueue )); |
|
545 CMPXMediaArray* items( |
|
546 aCmd.Value<CMPXMediaArray>( KMPXCommandSubscriptionAddItems )); |
|
547 User::LeaveIfNull(items); |
|
548 CMPXSubscription* subscription( CMPXSubscription::NewL( *items )); |
|
549 CleanupStack::PushL(subscription); |
|
550 iClientList->AddSubscriptionL( index, subscription ); // ownership transferred |
|
551 CleanupStack::Pop(subscription); |
|
552 break; |
|
553 } |
|
554 case KMPXCommandSubscriptionRemove: |
|
555 { |
|
556 TInt index( iClientList->Find( aMsgQueue )); |
|
557 CMPXMediaArray* items( |
|
558 aCmd.Value<CMPXMediaArray>( KMPXCommandSubscriptionAddItems )); |
|
559 User::LeaveIfNull(items); |
|
560 CMPXSubscription* subscription( CMPXSubscription::NewL( *items )); |
|
561 CleanupStack::PushL(subscription); |
|
562 iClientList->RemoveSubscriptionL( index, *subscription ); |
|
563 CleanupStack::PopAndDestroy(subscription); |
|
564 break; |
|
565 } |
|
566 case KMPXCommandSubscriptionRemoveAll: |
|
567 { |
|
568 TInt index( iClientList->Find( aMsgQueue )); |
|
569 iClientList->RemoveAllSubscriptionsL( index ); |
|
570 break; |
|
571 } |
|
572 |
|
573 default: |
|
574 { |
|
575 // Custom command, so just send to plugin to handle |
|
576 if ( iPluginHandler->Plugin() ) |
|
577 { |
|
578 iPluginHandler->Plugin()->CommandL( aCmd ); |
|
579 } |
|
580 } |
|
581 } |
|
582 } |
|
583 |
|
584 // ---------------------------------------------------------------------------- |
|
585 // Set a property |
|
586 // ---------------------------------------------------------------------------- |
|
587 // |
|
588 EXPORT_C void CMPXPlaybackEngine::SetL(TMPXPlaybackProperty aProperty, |
|
589 TInt aValue) |
|
590 { |
|
591 MPX_DEBUG3("-->CMPXPlaybackEngine::SetL(%d, %d)", aProperty, aValue); |
|
592 if ( aProperty < 0 || aProperty > EPbPropertyNum ) |
|
593 { |
|
594 MPX_DEBUG1("CMPXPlaybackEngine::SetL(): Invalid Argument"); |
|
595 User::Leave( KErrArgument ); |
|
596 } |
|
597 switch(aProperty) |
|
598 { |
|
599 case EPbPropertyEmbeddedMode: |
|
600 case EPbPropertyCrossFade: |
|
601 if ( aProperty < iProperties.Count() ) |
|
602 { |
|
603 iProperties[aProperty]=aValue; |
|
604 iClientList->SendMsgL( |
|
605 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
606 aProperty, iProperties[aProperty])); |
|
607 } |
|
608 break; |
|
609 case EPbPropertyVolume: |
|
610 MPX_DEBUG2( "CMPXPlaybackEngine::SetL EPbPropertyVolume %d", aValue ); |
|
611 if ( aValue >= KPbPlaybackVolumeLevelMin && |
|
612 aValue <= KPbPlaybackVolumeLevelMax) |
|
613 { |
|
614 iProperties[EPbPropertyMute] = EFalse; |
|
615 iProperties[aProperty] = aValue; |
|
616 if ( iPluginHandler->Plugin() ) |
|
617 { |
|
618 PluginL()->SetL( aProperty, aValue ); |
|
619 } |
|
620 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
621 iVolRoundedUp = EFalse; |
|
622 #endif |
|
623 } |
|
624 else |
|
625 { |
|
626 User::Leave(KErrArgument); |
|
627 } |
|
628 break; |
|
629 case EPbPropertyMute: |
|
630 MPX_DEBUG2( "CMPXPlaybackEngine::SetL EPbPropertyMute %d", aValue ); |
|
631 if ( iPluginHandler->Plugin() ) |
|
632 { |
|
633 PluginL()->SetL( aProperty, aValue ); |
|
634 } |
|
635 break; |
|
636 case EPbPropertyRandomMode: |
|
637 { |
|
638 MPX_DEBUG2( "CMPXPlaybackEngine::SetL EPbPropertyRandomMode %d", aValue ); |
|
639 TBool randomMode = static_cast<TBool>(aValue); |
|
640 if( iProperties[EPbPropertyRandomMode] != randomMode ) |
|
641 { |
|
642 iProperties[EPbPropertyRandomMode] = randomMode; |
|
643 if (iPlaySource==EPlayFromCollection && iPlaylist) |
|
644 { |
|
645 TRAP_IGNORE(iPlaylist->SetShuffleL(randomMode, ETrue)); |
|
646 // Pre-initializer needs to re-copy the new shuffle list |
|
647 // from the engine |
|
648 if (iInitializer) |
|
649 { |
|
650 iInitializer->Close(); |
|
651 } |
|
652 } |
|
653 TRAP_IGNORE(iClientList->SendMsgL( |
|
654 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
655 EPbPropertyRandomMode, |
|
656 randomMode))); |
|
657 } |
|
658 break; |
|
659 } |
|
660 case EPbPropertyRepeatMode: |
|
661 { |
|
662 MPX_DEBUG2( "CMPXPlaybackEngine::SetL EPbPropertyRepeatMode %d", aValue ); |
|
663 TMPXPlaybackRepeatMode repeat = static_cast<TMPXPlaybackRepeatMode>(aValue); |
|
664 if( iProperties[EPbPropertyRepeatMode] != repeat ) |
|
665 { |
|
666 iProperties[EPbPropertyRepeatMode] = repeat; |
|
667 if (iPlaySource==EPlayFromCollection && iPlaylist) |
|
668 { |
|
669 CMPXCollectionPlaylist::TRepeatMode repeatmode = |
|
670 static_cast<CMPXCollectionPlaylist::TRepeatMode>( |
|
671 repeat); |
|
672 iPlaylist->SetRepeatMode(repeatmode); |
|
673 if (iInitializer) |
|
674 { |
|
675 iInitializer->Close(); |
|
676 } |
|
677 } |
|
678 TRAP_IGNORE(iClientList->SendMsgL( |
|
679 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
680 EPbPropertyRepeatMode, |
|
681 repeat))); |
|
682 } |
|
683 break; |
|
684 } |
|
685 case EPbPropertyPosition: |
|
686 { |
|
687 CMPXPlaybackPlugin* pi = PluginL(); |
|
688 if ( pi ) |
|
689 { |
|
690 MPX_DEBUG2( "CMPXPlaybackEngine::SetL setting position %d", aValue ); |
|
691 iProperties[aProperty] = aValue; |
|
692 pi->SetL(EPbPropertyPosition, aValue); |
|
693 } |
|
694 break; |
|
695 } |
|
696 default: |
|
697 iProperties[aProperty]=aValue; |
|
698 PluginL()->SetL(aProperty,aValue); |
|
699 } |
|
700 MPX_DEBUG3("<--CMPXPlaybackEngine::SetL(%d, %d)", aProperty, aValue); |
|
701 } |
|
702 |
|
703 // ---------------------------------------------------------------------------- |
|
704 // Property request |
|
705 // ---------------------------------------------------------------------------- |
|
706 // |
|
707 EXPORT_C void CMPXPlaybackEngine::PropertyL(TMPXPlaybackProperty aProperty, |
|
708 MMPXPlaybackEngineObserver& aCallback) |
|
709 { |
|
710 MPX_FUNC_EX("CMPXPlaybackEngine::PropertyL()"); |
|
711 MPX_DEBUG4("CMPXPlaybackEngine::PropertyL 0x%08x cb 0x%08x, prop %d", |
|
712 this, &aCallback, aProperty); |
|
713 if (aProperty == EPbPropertyVolume) |
|
714 { |
|
715 aCallback.HandleProperty(aProperty, |
|
716 iProperties[EPbPropertyVolume], |
|
717 KErrNone); |
|
718 } |
|
719 else if (aProperty == EPbPropertyMaxVolume) |
|
720 { |
|
721 aCallback.HandleProperty(aProperty, |
|
722 KPbPlaybackVolumeLevelMax, |
|
723 KErrNone); |
|
724 } |
|
725 else if (aProperty == EPbPropertyRandomMode) |
|
726 { |
|
727 TInt random(0); |
|
728 if ( iPlaylist ) |
|
729 { |
|
730 random = iPlaylist->Shuffle(); |
|
731 } |
|
732 else |
|
733 { |
|
734 random = iProperties[EPbPropertyRandomMode]; |
|
735 } |
|
736 aCallback.HandleProperty(aProperty, |
|
737 random, |
|
738 KErrNone); |
|
739 } |
|
740 else if (aProperty == EPbPropertyRepeatMode) |
|
741 { |
|
742 TInt repeat(0); |
|
743 if ( iPlaylist ) |
|
744 { |
|
745 repeat = iPlaylist->RepeatMode(); |
|
746 } |
|
747 else |
|
748 { |
|
749 repeat = iProperties[EPbPropertyRepeatMode]; |
|
750 } |
|
751 aCallback.HandleProperty(aProperty, |
|
752 repeat, |
|
753 KErrNone); |
|
754 } |
|
755 else if (aProperty == EPbPropertyPosition && |
|
756 EPbStateNotInitialised == iPluginState) |
|
757 { |
|
758 aCallback.HandleProperty(aProperty, |
|
759 iProperties[EPbPropertyPosition], |
|
760 KErrNone); |
|
761 } |
|
762 else |
|
763 { |
|
764 MPX_DEBUG1("CMPXPlaybackEngine::PropertyL add request to task queue"); |
|
765 iTaskQueue->AddTaskL(EProperty, &aCallback, this, aProperty); |
|
766 } |
|
767 } |
|
768 |
|
769 // ---------------------------------------------------------------------------- |
|
770 // Async call: must be added to task queue |
|
771 // ---------------------------------------------------------------------------- |
|
772 // |
|
773 EXPORT_C void CMPXPlaybackEngine::MediaL( |
|
774 MMPXPlaybackEngineObserver& aCallback, |
|
775 CBufBase* /*aBuf*/) |
|
776 { |
|
777 MPX_DEBUG3("-->CMPXPlaybackEngine::MediaL() aBuf 0x%08x cb 0x%08x", this, &aCallback); |
|
778 // DEPRECATED |
|
779 MPX_ASSERT( 0 ); |
|
780 MPX_DEBUG2("<--CMPXPlaybackEngine::MediaL() aBuf 0x%08x", this); |
|
781 } |
|
782 |
|
783 // ---------------------------------------------------------------------------- |
|
784 // Async call: must be added to task queue |
|
785 // ---------------------------------------------------------------------------- |
|
786 // |
|
787 EXPORT_C void CMPXPlaybackEngine::MediaL( |
|
788 MMPXPlaybackEngineObserver& aCallback, |
|
789 const CMPXCommand& aCmd) |
|
790 { |
|
791 MPX_DEBUG3("-->CMPXPlaybackEngine::MediaL() aCmd 0x%08x cb 0x%08x", this, &aCallback); |
|
792 CMPXCommand* cmd( CMPXCommand::NewL( aCmd ) ); |
|
793 CleanupStack::PushL( cmd ); |
|
794 TBool redirect = EFalse; |
|
795 if (CMPXAttributeSpecs* specs = aCmd.Value<CMPXAttributeSpecs>( KMPXCommandMediaAttributeSpecs )) |
|
796 { |
|
797 if (specs->IsSupported(KMPXMediaGeneralExtMediaRedirect)) |
|
798 { |
|
799 redirect = ETrue; |
|
800 MPX_DEBUG1("CMPXPlaybackEngine::MediaL - Redirect to Playback Plugin"); |
|
801 } |
|
802 } |
|
803 |
|
804 // If redirect is false, pass the cmd to mediahelper class |
|
805 if ( iPlaySource == EPlayFromCollection && iPlaylist && !redirect) |
|
806 { |
|
807 // Onwership of cmd is passed to mediahelper class |
|
808 iMediaHelper->MediaL( iPlaylist->Path(), cmd, &aCallback ); |
|
809 } |
|
810 else |
|
811 { |
|
812 // ownership of cmd is transfered |
|
813 MediaFromPluginL( &aCallback, cmd ); |
|
814 } |
|
815 CleanupStack::Pop( cmd ); |
|
816 MPX_DEBUG2("<--CMPXPlaybackEngine::MediaL() aCmd 0x%08x", this); |
|
817 } |
|
818 |
|
819 // ---------------------------------------------------------------------------- |
|
820 // Async call: must be added to task queue |
|
821 // ---------------------------------------------------------------------------- |
|
822 // |
|
823 EXPORT_C void CMPXPlaybackEngine::SubPlayerNamesL(TUid aPlayerUid, |
|
824 MMPXPlaybackEngineObserver& aCallback) |
|
825 { |
|
826 MPX_FUNC_EX("CMPXPlaybackEngine::SubPlayerNamesL()"); |
|
827 CMPXPlaybackPlugin* p = iPluginHandler->CreatePlayerPluginL(aPlayerUid); |
|
828 iTaskQueue->AddTaskL(ESubPlayerNames,&aCallback, this, aPlayerUid.iUid, NULL, p); |
|
829 } |
|
830 |
|
831 // ---------------------------------------------------------------------------- |
|
832 // Async call: must be added to task queue |
|
833 // ---------------------------------------------------------------------------- |
|
834 // |
|
835 void CMPXPlaybackEngine::MediaFromPluginL( |
|
836 MMPXPlaybackEngineObserver* aCallback, |
|
837 CMPXCommand* aCmd ) |
|
838 { |
|
839 MPX_FUNC_EX("CMPXPlaybackEngine::MediaFromPluginL"); |
|
840 CleanupStack::PushL( aCmd ); |
|
841 iTaskQueue->AddTaskL( EMedia, aCallback, this, 0, NULL, NULL, aCmd ); |
|
842 CleanupStack::Pop( aCmd ); // Ownership transferred to the task queue |
|
843 } |
|
844 |
|
845 // ---------------------------------------------------------------------------- |
|
846 // Handles a regular heartbeat timer event |
|
847 // ---------------------------------------------------------------------------- |
|
848 // |
|
849 void CMPXPlaybackEngine::Beat() |
|
850 { |
|
851 |
|
852 // retrieve position from plugins directly |
|
853 if (iState != EPbStatePlaying) |
|
854 { |
|
855 iProgressTimer->Cancel(); |
|
856 } |
|
857 else |
|
858 { |
|
859 TRAP_IGNORE(iTaskQueue->AddTaskL(EProperty, &iReflector, |
|
860 this, EPbPropertyPosition)); |
|
861 } |
|
862 |
|
863 } |
|
864 |
|
865 // ---------------------------------------------------------------------------- |
|
866 // Synchronises the heartbeat timer with system clock |
|
867 // ---------------------------------------------------------------------------- |
|
868 // |
|
869 void CMPXPlaybackEngine::Synchronize() |
|
870 { |
|
871 MPX_FUNC_EX("CMPXPlaybackEngine::Synchronize"); |
|
872 MPX_DEBUG2("CMPXPlaybackEngine::Synchronize(): iState = %d", iState); |
|
873 |
|
874 // do the same thing as Beat |
|
875 Beat(); |
|
876 } |
|
877 |
|
878 // ---------------------------------------------------------------------------- |
|
879 // Handle accessory event |
|
880 // ---------------------------------------------------------------------------- |
|
881 // |
|
882 void CMPXPlaybackEngine::HandleAccesoryEventL(TMPXPlaybackAccessoryMode aMode) |
|
883 { |
|
884 MPX_DEBUG2("CMPXPlaybackEngine::HandleAccesoryEventL(%d) entering", aMode); |
|
885 iClientList->SendMsgL( |
|
886 TMPXPlaybackMessage( TMPXPlaybackMessage::EAccessoryChanged, |
|
887 aMode, |
|
888 0)); |
|
889 |
|
890 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
891 SetVolumeIncrement( aMode ); |
|
892 #endif // HIGH_RESOLUTION_VOLUME |
|
893 |
|
894 MPX_DEBUG1("CMPXPlaybackEngine::HandleAccesoryEventL() exiting"); |
|
895 } |
|
896 |
|
897 // ---------------------------------------------------------------------------- |
|
898 // Callback from plug-in, handle plugin event |
|
899 // ---------------------------------------------------------------------------- |
|
900 // |
|
901 void CMPXPlaybackEngine::HandlePluginEvent( |
|
902 TEvent aEvent, |
|
903 TInt aData, |
|
904 TInt aError) |
|
905 { |
|
906 TRAP_IGNORE(DoHandlePluginEventL(aEvent, aData, aError)); |
|
907 } |
|
908 |
|
909 // ---------------------------------------------------------------------------- |
|
910 // Callback from plug-in, handle plugin message |
|
911 // ---------------------------------------------------------------------------- |
|
912 // |
|
913 void CMPXPlaybackEngine::HandlePlaybackMessage( |
|
914 CMPXMessage* aMsg, |
|
915 TInt aErr) |
|
916 { |
|
917 iClientList->SendMsg(aMsg, aErr); |
|
918 } |
|
919 |
|
920 // ---------------------------------------------------------------------------- |
|
921 // Handler plugin event |
|
922 // ---------------------------------------------------------------------------- |
|
923 // |
|
924 void CMPXPlaybackEngine::DoHandlePluginEventL( |
|
925 TEvent aEvent, |
|
926 TInt aData, |
|
927 TInt aError) |
|
928 { |
|
929 MPX_DEBUG5("-->CMPXPlaybackEngine::DoHandlePluginEventL 0x%08x, event %d, data %d, error %d.", |
|
930 this, aEvent, aData, aError); |
|
931 |
|
932 TInt disconnectionError = aError; |
|
933 if ( aEvent == EPPlayerUnavailable ) |
|
934 { |
|
935 aError = KErrNone; |
|
936 } |
|
937 |
|
938 if (aError!=KErrNone) |
|
939 { |
|
940 // If error occured during pause event, change to pause but also |
|
941 // send error code to clients to handle |
|
942 if ( aEvent == EPPaused ) |
|
943 { |
|
944 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL(): Pause Error = %d", aError); |
|
945 |
|
946 if ( aError != KErrNotSupported ) |
|
947 { |
|
948 // If error during seeking event, keep seeking and set |
|
949 // plugin state to not intialised |
|
950 if ( iState == EPbStateSeekingForward || |
|
951 iState == EPbStateSeekingBackward ) |
|
952 { |
|
953 iPluginState = EPbStateNotInitialised; |
|
954 } |
|
955 else |
|
956 { |
|
957 iState = EPbStatePaused; |
|
958 iNextState = EPbStatePaused; |
|
959 SetPlayerActivated(EFalse); |
|
960 iClientList->SendMsgL( |
|
961 TMPXPlaybackMessage( |
|
962 TMPXPlaybackMessage::EStateChanged, iState, aError )); |
|
963 if ( KErrDied == aError || |
|
964 KErrAccessDenied == aError ) |
|
965 { |
|
966 iPluginState = EPbStateNotInitialised; |
|
967 // fixed |
|
968 iAutoResumeHandler->HandlePlaybackComplete(aError); |
|
969 iAutoResumeHandler->HandlePlaybackStateChange(iState); |
|
970 |
|
971 } |
|
972 } |
|
973 } |
|
974 else // Pause functionality is not supported, no change of state |
|
975 // we just send the error back to Ui to let the user know |
|
976 { |
|
977 iClientList->SendMsgL( |
|
978 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged, aEvent, aError)); |
|
979 |
|
980 TMPXPlaybackState s = EPbStatePlaying; |
|
981 iNextState = EPbStatePlaying; |
|
982 |
|
983 // Set state first before activation, since activation |
|
984 // will send a state changed update event as well |
|
985 SetStateL(s); |
|
986 } |
|
987 } |
|
988 else if ( aEvent != EPSetComplete ) //Not paused and not EPSetComplete |
|
989 { // sometimes upnp failed to set value. |
|
990 MPX_DEBUG4("CMPXPlaybackEngine::DoHandlePluginEventL error aError %d, iState %d, iNextState %d", |
|
991 aError, iState, iNextState ); |
|
992 SavePlaybackInfoL(); |
|
993 HandlePluginEventErrorHandling(aEvent, aError); |
|
994 iState = EPbStateStopped; |
|
995 iClientList->SendMsgL( |
|
996 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
997 if (aError) |
|
998 { |
|
999 iClientList->SendMsgL( |
|
1000 TMPXPlaybackMessage(TMPXPlaybackMessage::EError,aEvent,aError)); |
|
1001 } |
|
1002 } |
|
1003 else // SetComplete |
|
1004 { |
|
1005 if ( aError == KErrNotSupported && |
|
1006 aData == EPbPropertyVolume ) |
|
1007 { |
|
1008 iClientList->SendMsgL( |
|
1009 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1010 aData, aError)); |
|
1011 } |
|
1012 } |
|
1013 } |
|
1014 else // No errors |
|
1015 { |
|
1016 MPX_DEBUG4("CMPXPlaybackEngine::DoHandlePluginEventL, iState %d, iNextState %d, iSkipping %d", |
|
1017 iState, iNextState, iSkipping ); |
|
1018 |
|
1019 switch(aEvent) |
|
1020 { |
|
1021 case EPInitialised: |
|
1022 case EPClosed: |
|
1023 case EPPaused: |
|
1024 case EPPlaying: |
|
1025 case EPStopped: |
|
1026 case EPDownloadPositionChanged: |
|
1027 case EPDownloadStateChanged: |
|
1028 case EPDownloadCmdPauseDownload: |
|
1029 case EPDownloadCmdResumeDownload: |
|
1030 case EPDownloadCmdCancelDownload: |
|
1031 case EPDownloadStarted: |
|
1032 case EPDownloadingUpdated: |
|
1033 case EPDownloadingComplete: |
|
1034 case EPBufferingStarted: |
|
1035 case EPPlayComplete: |
|
1036 case EPPluginSeeking: |
|
1037 { |
|
1038 UpdateStateMachineL(aEvent, aData, aError); |
|
1039 break; |
|
1040 } |
|
1041 case EPActive: |
|
1042 { |
|
1043 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL active message."); |
|
1044 SetPlayerActivated(aData); |
|
1045 break; |
|
1046 } |
|
1047 case EPSubPlayersChanged: |
|
1048 { |
|
1049 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL subplayer changed."); |
|
1050 iClientList->SendMsgL( |
|
1051 TMPXPlaybackMessage(TMPXPlaybackMessage::ESubPlayersChanged)); |
|
1052 break; |
|
1053 } |
|
1054 case EPSupportedFeaturesChanged: |
|
1055 { |
|
1056 iClientList->SendMsgL( |
|
1057 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1058 EPbPropertySupportedFeatures, aData)); |
|
1059 break; |
|
1060 } |
|
1061 case EPSetComplete: |
|
1062 { |
|
1063 if ( aData < iProperties.Count() ) |
|
1064 { |
|
1065 iClientList->SendMsgL( |
|
1066 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1067 aData, iProperties[aData])); |
|
1068 } |
|
1069 break; |
|
1070 } |
|
1071 case EPDurationChanged: |
|
1072 { |
|
1073 iProperties[EPbPropertyDuration]=aData; |
|
1074 SetPropertiesL(); |
|
1075 iClientList->SendMsgL( |
|
1076 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1077 EPbPropertyDuration, |
|
1078 iProperties[EPbPropertyDuration])); |
|
1079 break; |
|
1080 } |
|
1081 case EPPlayerUnavailable: |
|
1082 { |
|
1083 if (iInitializer) |
|
1084 { |
|
1085 iInitializer->Close(); |
|
1086 } |
|
1087 SavePlaybackInfoL(); |
|
1088 iPreservedState = iState; |
|
1089 iPreservedPosition = iProperties[EPbPropertyPosition]; |
|
1090 iClientList->SendMsgL( |
|
1091 TMPXPlaybackMessage(TMPXPlaybackMessage::EPlayerUnavailable, |
|
1092 0, disconnectionError)); |
|
1093 break; |
|
1094 } |
|
1095 case EPVolumeChanged: |
|
1096 { |
|
1097 iProperties[EPbPropertyVolume] = aData; |
|
1098 if (iInitVolume) |
|
1099 { |
|
1100 iInitVolume = EFalse; |
|
1101 } |
|
1102 else |
|
1103 { |
|
1104 iClientList->SendMsgL( |
|
1105 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1106 EPbPropertyVolume, |
|
1107 iProperties[EPbPropertyVolume])); |
|
1108 } |
|
1109 break; |
|
1110 } |
|
1111 case EPMuteChanged: |
|
1112 { |
|
1113 if ( iProperties[EPbPropertyMute] != aData ) |
|
1114 { |
|
1115 iProperties[EPbPropertyMute] = aData; |
|
1116 iClientList->SendMsgL( |
|
1117 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1118 EPbPropertyMute, |
|
1119 iProperties[EPbPropertyMute])); |
|
1120 } |
|
1121 break; |
|
1122 } |
|
1123 case EPPositionChanged: |
|
1124 { |
|
1125 iProperties[EPbPropertyPosition] = aData; |
|
1126 iClientList->SendMsgL( |
|
1127 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1128 EPbPropertyPosition, |
|
1129 iProperties[EPbPropertyPosition])); |
|
1130 break; |
|
1131 } |
|
1132 case EPDownloadFileMoved: |
|
1133 { |
|
1134 CMPXMessage* msg = CMPXMessage::NewL(); |
|
1135 CleanupStack::PushL(msg); |
|
1136 TMPXMessageId id=static_cast<TMPXMessageId>(KMPXMessageGeneral); |
|
1137 HBufC* path = reinterpret_cast<HBufC*>(aData); |
|
1138 msg->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, id); |
|
1139 msg->SetTObjectValueL<TInt>(KMPXMessageGeneralEvent, TMPXPlaybackMessage::EDownloadFileMoved); |
|
1140 msg->SetTObjectValueL<TInt>(KMPXMessageGeneralType, 0); |
|
1141 msg->SetTObjectValueL<TInt>(KMPXMessageGeneralData, 0); |
|
1142 msg->SetTextValueL( KMPXMediaGeneralUri, *path ); |
|
1143 iClientList->SendMsg(msg, KErrNone); |
|
1144 CleanupStack::PopAndDestroy( msg ); |
|
1145 break; |
|
1146 } |
|
1147 default: |
|
1148 ASSERT(0); |
|
1149 } |
|
1150 } |
|
1151 MPX_DEBUG2("<--CMPXPlaybackEngine::DoHandlePluginEventL() 0x%08x", this); |
|
1152 } |
|
1153 |
|
1154 // ---------------------------------------------------------------------------- |
|
1155 // Update State Machine |
|
1156 // Handle plugin events that could cause state change in playback-engine |
|
1157 // ---------------------------------------------------------------------------- |
|
1158 // |
|
1159 void CMPXPlaybackEngine::UpdateStateMachineL( |
|
1160 TEvent aEvent, |
|
1161 TInt aData, |
|
1162 TInt aError) |
|
1163 { |
|
1164 MPX_DEBUG4("CMPXPlaybackEngine::UpdateStateMachine, iState %d, iNextState %d, iSkipping %d", |
|
1165 iState, iNextState, iSkipping ); |
|
1166 |
|
1167 TMPXPlaybackState s=iState; |
|
1168 |
|
1169 switch(aEvent) |
|
1170 { |
|
1171 case EPInitialised: |
|
1172 { |
|
1173 HandlePluginEventInitialisedL( s, aData ); |
|
1174 break; |
|
1175 } |
|
1176 case EPPlaying: |
|
1177 { |
|
1178 s = EPbStatePlaying; |
|
1179 iNextState = EPbStatePlaying; |
|
1180 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL playing."); |
|
1181 |
|
1182 // Set state first before activation, since activation |
|
1183 // will send a state changed update event as well |
|
1184 SetStateL(s); |
|
1185 SetPlayerActivated(ETrue); |
|
1186 iPluginState = EPbStatePlaying; |
|
1187 break; |
|
1188 } |
|
1189 case EPClosed: |
|
1190 { |
|
1191 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL closed."); |
|
1192 MPX_DEBUG2("CMPXPlaybackEngine::HandlePluginEventL: iState = %d", iState); |
|
1193 |
|
1194 iPluginState = EPbStateNotInitialised; |
|
1195 |
|
1196 // Do not set state changed event when initialising |
|
1197 if ( iState != EPbStateInitialising && EPbCmdClose == aData) |
|
1198 { |
|
1199 s=EPbStateNotInitialised; |
|
1200 |
|
1201 // Set state first before deactivation, since deactivation |
|
1202 // will send a state changed update event as well |
|
1203 SetStateL(s); |
|
1204 SetPlayerActivated(EFalse); |
|
1205 } // else close when stop |
|
1206 break; |
|
1207 } |
|
1208 case EPPaused: |
|
1209 { |
|
1210 if (iState != EPbStateSeekingForward && |
|
1211 iState != EPbStateSeekingBackward && |
|
1212 iState != EPbStatePaused && |
|
1213 !iSkipping) |
|
1214 { |
|
1215 s=EPbStatePaused; |
|
1216 |
|
1217 if (EPbStatePlaying == iNextState) |
|
1218 { // only change state from playing to pause |
|
1219 iNextState = EPbStatePaused; |
|
1220 } |
|
1221 |
|
1222 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL paused."); |
|
1223 |
|
1224 // Set state first before deactivation, since deactivation |
|
1225 // will send a state changed update event as well |
|
1226 SetStateL(s); |
|
1227 SetPlayerActivated(EFalse); |
|
1228 } |
|
1229 |
|
1230 iPluginState = EPbStatePaused; |
|
1231 break; |
|
1232 } |
|
1233 case EPActive: |
|
1234 { |
|
1235 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL active message."); |
|
1236 SetPlayerActivated(aData); |
|
1237 break; |
|
1238 } |
|
1239 case EPStopped: |
|
1240 { |
|
1241 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL stopped."); |
|
1242 |
|
1243 s = EPbStateStopped; |
|
1244 SetStateL(s); |
|
1245 TBool handleStop(EFalse); |
|
1246 |
|
1247 if (iState != EPbStateSeekingForward && |
|
1248 iState != EPbStateSeekingBackward && |
|
1249 !iSkipping && |
|
1250 iNextState != EPbStatePlaying) |
|
1251 { |
|
1252 handleStop = ETrue; |
|
1253 } |
|
1254 else if (iProgressTimer->IsActive()) |
|
1255 { // stop from remote player |
|
1256 Suspend(); |
|
1257 iNextState = EPbStateStopped; |
|
1258 handleStop = ETrue; |
|
1259 } // else stop for seeking |
|
1260 if (handleStop) |
|
1261 { |
|
1262 SetPlayerActivated( EFalse ); |
|
1263 s=EPbStateStopped; |
|
1264 if ( iProperties[EPbPropertyPosition] != 0 ) |
|
1265 { |
|
1266 iProperties[EPbPropertyPosition]=0; |
|
1267 iClientList->SendMsgL( |
|
1268 TMPXPlaybackMessage( |
|
1269 TMPXPlaybackMessage::EPropertyChanged, |
|
1270 EPbPropertyPosition, |
|
1271 0 )); |
|
1272 } |
|
1273 } |
|
1274 break; |
|
1275 } |
|
1276 case EPPlayComplete: |
|
1277 { |
|
1278 EndSeek(); |
|
1279 SavePlaybackCompleteInfoL(); |
|
1280 iAutoResumeHandler->HandlePlaybackComplete(aError); |
|
1281 iClientList->SendMsgL( |
|
1282 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1283 EPbPropertyPosition, |
|
1284 iProperties[EPbPropertyDuration])); |
|
1285 iTaskQueue->AddTaskL(EHandleNext, NULL, this, 0); |
|
1286 s=EPbStateStopped; //State Changed indication Stopped will be sent |
|
1287 break; |
|
1288 } |
|
1289 case EPDownloadPositionChanged: |
|
1290 { |
|
1291 if ( EPbStateInitialising == s ) |
|
1292 { |
|
1293 s=EPbStateBuffering; |
|
1294 } |
|
1295 iClientList->SendMsgL( |
|
1296 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadPositionChanged, |
|
1297 0, |
|
1298 aData )); |
|
1299 break; |
|
1300 } |
|
1301 case EPDownloadStateChanged: |
|
1302 { |
|
1303 iClientList->SendMsgL( |
|
1304 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadStateChanged, |
|
1305 0, |
|
1306 aData )); |
|
1307 break; |
|
1308 } |
|
1309 case EPDownloadCmdPauseDownload: |
|
1310 { |
|
1311 iClientList->SendMsgL( |
|
1312 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadCmdPauseDownload, |
|
1313 0, |
|
1314 aData )); |
|
1315 break; |
|
1316 } |
|
1317 case EPDownloadCmdResumeDownload: |
|
1318 { |
|
1319 iClientList->SendMsgL( |
|
1320 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadCmdResumeDownload, |
|
1321 0, |
|
1322 aData )); |
|
1323 break; |
|
1324 } |
|
1325 case EPDownloadCmdCancelDownload: |
|
1326 { |
|
1327 iClientList->SendMsgL( |
|
1328 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadCmdCancelDownload, |
|
1329 0, |
|
1330 aData )); |
|
1331 break; |
|
1332 } |
|
1333 case EPDownloadStarted: |
|
1334 { |
|
1335 iClientList->SendMsgL( |
|
1336 TMPXPlaybackMessage( TMPXPlaybackMessage::EDownloadStarted, |
|
1337 0, |
|
1338 aData)); |
|
1339 break; |
|
1340 } |
|
1341 case EPDownloadingUpdated: |
|
1342 { |
|
1343 iClientList->SendMsgL( |
|
1344 TMPXPlaybackMessage(TMPXPlaybackMessage::EDownloadUpdated, |
|
1345 0,aData)); |
|
1346 s=EPbStateDownloading; |
|
1347 break; |
|
1348 } |
|
1349 // end comment this later |
|
1350 case EPDownloadingComplete: |
|
1351 { |
|
1352 iClientList->SendMsgL( |
|
1353 TMPXPlaybackMessage(TMPXPlaybackMessage::EDownloadComplete, |
|
1354 0,aData)); |
|
1355 s=EPbStateStopped; |
|
1356 |
|
1357 if ( iProperties[EPbPropertyPosition] != 0 ) |
|
1358 { |
|
1359 iProperties[EPbPropertyPosition]=0; |
|
1360 iClientList->SendMsgL( |
|
1361 TMPXPlaybackMessage( |
|
1362 TMPXPlaybackMessage::EPropertyChanged, |
|
1363 EPbPropertyPosition, |
|
1364 0 )); |
|
1365 } |
|
1366 break; |
|
1367 } |
|
1368 case EPBufferingStarted: |
|
1369 { |
|
1370 s = EPbStateBuffering; |
|
1371 iPluginState = EPbStatePlaying; //ToDo: Do we need pluginstate?!?!? |
|
1372 break; |
|
1373 } |
|
1374 case EPPluginSeeking: |
|
1375 { |
|
1376 // suspend playback timer |
|
1377 Suspend(); |
|
1378 // Change to plugin seeking state |
|
1379 iNextState = iState; |
|
1380 s = EPbStatePluginSeeking; |
|
1381 MPX_DEBUG1("CMPXPlaybackEngine::HandlePluginEventL EPbStatePluginSeeking."); |
|
1382 |
|
1383 // Set state first before activation, since activation |
|
1384 // will send a state changed update event as well |
|
1385 SetStateL(s); |
|
1386 iPluginState = EPbStatePluginSeeking; |
|
1387 break; |
|
1388 } |
|
1389 } |
|
1390 SetStateL(s); //Check if state changed and notify clients. |
|
1391 } |
|
1392 |
|
1393 // ---------------------------------------------------------------------------- |
|
1394 // Handle Plugin Event : Initialised |
|
1395 // ---------------------------------------------------------------------------- |
|
1396 // |
|
1397 void CMPXPlaybackEngine::HandlePluginEventInitialisedL(TMPXPlaybackState& s, TInt aData) |
|
1398 { |
|
1399 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
1400 // Merlin twentysteps hack start |
|
1401 if ( iUri ) |
|
1402 { |
|
1403 TParsePtrC parser(*iUri); |
|
1404 |
|
1405 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL(): iUri is %S", iUri); |
|
1406 if (parser.Ext().CompareF(KWmaExtension) == 0 || parser.Ext().CompareF(KRaExtension) == 0) |
|
1407 { |
|
1408 // for wma/ra file, increment is always 10 with or without headset |
|
1409 iVolumeIncrement = KMPXLargeVolumeIncrement; |
|
1410 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL it is a wma/ra file, volumeIncrement: %d !!!!", iVolumeIncrement); |
|
1411 } |
|
1412 } |
|
1413 #ifdef __ACCESSORY_FW |
|
1414 else if (iAccessoryObs->AccessoryModeL() == EPbAccessoryWiredHeadset || iAccessoryObs->AccessoryModeL() == EPbAccessoryHeadphones) |
|
1415 #else |
|
1416 else if (iAccessoryObs->AccessoryModeL() == EPbAccessoryHeadset) |
|
1417 #endif // __ACCESSORY_FW |
|
1418 { |
|
1419 // for non wma files with headset, the volume increment is 5 |
|
1420 iVolumeIncrement = KMPXSmallVolumeIncrement; |
|
1421 } |
|
1422 #endif // HIGH_RESOLUTION_VOLUME |
|
1423 // twentysteps end |
|
1424 |
|
1425 iPluginState = EPbStateStopped; |
|
1426 // Reset corrupted and invalid flags if no error |
|
1427 // Only set if they were not set before, this is because |
|
1428 // calls to SetL() on collection are costly |
|
1429 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL() iDbFlag %x", iDbFlag); |
|
1430 if ( iDbFlag & KMPXMediaGeneralFlagsIsCorrupted || |
|
1431 iDbFlag & KMPXMediaGeneralFlagsIsInvalid || |
|
1432 iDbFlag & KMPXMediaGeneralFlagsIsDrmLicenceInvalid ) |
|
1433 { |
|
1434 TRAP_IGNORE( |
|
1435 SetFlagBitsL( EFalse, |
|
1436 KMPXMediaGeneralFlagsIsCorrupted | |
|
1437 KMPXMediaGeneralFlagsIsInvalid | |
|
1438 KMPXMediaGeneralFlagsIsDrmLicenceInvalid )); |
|
1439 } |
|
1440 |
|
1441 iClientList->SendMsgL(TMPXPlaybackMessage( |
|
1442 TMPXPlaybackMessage::EMediaChanged)); |
|
1443 |
|
1444 iProperties[EPbPropertyDuration]=aData; //Note, radio has no duration! |
|
1445 SetPropertiesL(); |
|
1446 iClientList->SendMsgL( |
|
1447 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1448 EPbPropertyDuration, |
|
1449 iProperties[EPbPropertyDuration])); |
|
1450 |
|
1451 //Assumption: we take duration==0 to mean "live streaming" |
|
1452 // Check if position is not past the duration |
|
1453 if ( iProperties[EPbPropertyPosition] >= iProperties[EPbPropertyDuration] ) |
|
1454 { |
|
1455 iProperties[EPbPropertyPosition] = 0; |
|
1456 } |
|
1457 |
|
1458 // Set position to restore saved position. |
|
1459 TRAP_IGNORE( // uPnP leaves if set position in stop state |
|
1460 PluginL()->SetL( EPbPropertyPosition, iProperties[EPbPropertyPosition] )); |
|
1461 |
|
1462 iAutoResumeHandler->HandleOpenFileComplete(); |
|
1463 |
|
1464 // Check if playback should not be started automatically. |
|
1465 if ( iAccessPoint || ( iPlaylist && (!iPlaylist->AutoPlay()) ) ) |
|
1466 { |
|
1467 iNextState = EPbStateNotInitialised; |
|
1468 } |
|
1469 |
|
1470 TMPXPlaybackState nextState(iNextState); // save next state |
|
1471 switch (iNextState) //What the next state could be (command may have been sent). |
|
1472 { |
|
1473 case EPbStateNotInitialised: |
|
1474 { // Notify client initialized complete |
|
1475 MPX_DEBUG1("CMPXPlaybackEngine sends msg EInitializeComplete"); |
|
1476 iClientList->SendMsgL( |
|
1477 TMPXPlaybackMessage( |
|
1478 TMPXPlaybackMessage::EInitializeComplete, |
|
1479 0, |
|
1480 ETrue)); |
|
1481 s = EPbStateInitialised; //This will cause a StateChanged message to be sent |
|
1482 break; |
|
1483 } |
|
1484 case EPbStateStopped: |
|
1485 { // Play to the end of playlist |
|
1486 PluginL()->CommandL(EPbCmdStop); |
|
1487 if (iInitializer) |
|
1488 { // close file in the initializer |
|
1489 iInitializer->Close(); |
|
1490 } |
|
1491 s = EPbStateStopped; |
|
1492 iClientList->SendMsgL( |
|
1493 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1494 EPbPropertyPosition, |
|
1495 iProperties[EPbPropertyPosition])); |
|
1496 break; |
|
1497 } |
|
1498 default: |
|
1499 { |
|
1500 iState = EPbStateStopped; |
|
1501 HandleCommandL(CommandFromState( iNextState )); |
|
1502 s = iState; // change to new state due to handle command |
|
1503 iClientList->SendMsgL( |
|
1504 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1505 EPbPropertyPosition, |
|
1506 iProperties[EPbPropertyPosition])); |
|
1507 break; |
|
1508 } |
|
1509 } |
|
1510 |
|
1511 if (iInitNext && EPbStateStopped != nextState) |
|
1512 { |
|
1513 // |
|
1514 // Try pre-initialsing the next song, just in case we get there |
|
1515 // |
|
1516 TBool more = iInitializer->Next(); |
|
1517 if (!more && iPlaylist->Shuffle()) |
|
1518 { // Reach to the end and shuffle is on, pre-initializer |
|
1519 // needs to re-copy the new shuffle list from engine |
|
1520 if (iInitializer) |
|
1521 { |
|
1522 iInitializer->Close(); |
|
1523 } |
|
1524 } |
|
1525 } |
|
1526 } |
|
1527 |
|
1528 // ---------------------------------------------------------------------------- |
|
1529 // Error handling for Handler plugin event |
|
1530 // ---------------------------------------------------------------------------- |
|
1531 // |
|
1532 void CMPXPlaybackEngine::HandlePluginEventErrorHandling(TEvent aEvent, TInt aError) |
|
1533 { |
|
1534 switch (aError) |
|
1535 { |
|
1536 case KErrGeneral: |
|
1537 { |
|
1538 // Track initialization failed |
|
1539 if ( ( aEvent == EPInitialised ) || |
|
1540 ( aEvent == EPPlaying ) ) |
|
1541 { |
|
1542 aError = KErrNotSupported; |
|
1543 // Mark item as corrupted |
|
1544 |
|
1545 // fall through on purpose |
|
1546 } |
|
1547 else |
|
1548 { |
|
1549 break; |
|
1550 } |
|
1551 } |
|
1552 case KErrArgument: |
|
1553 case KErrNotSupported: |
|
1554 case KErrCorrupt: |
|
1555 case KErrDivideByZero: |
|
1556 { |
|
1557 // Release file handles |
|
1558 TRAP_IGNORE(DoStopL()); |
|
1559 // Mark item as corrupted |
|
1560 MarkItemCorrupted( ETrue ); |
|
1561 |
|
1562 // Reset DRM and invalid flags if they are set |
|
1563 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL() iDbFlag %x", iDbFlag); |
|
1564 if ( iDbFlag & KMPXMediaGeneralFlagsIsInvalid || |
|
1565 iDbFlag & KMPXMediaGeneralFlagsIsDrmLicenceInvalid ) |
|
1566 { |
|
1567 TRAP_IGNORE( |
|
1568 SetFlagBitsL( EFalse, |
|
1569 KMPXMediaGeneralFlagsIsInvalid | |
|
1570 KMPXMediaGeneralFlagsIsDrmLicenceInvalid )); |
|
1571 } |
|
1572 |
|
1573 break; |
|
1574 } |
|
1575 case KErrNotFound: |
|
1576 { |
|
1577 // Mark item as invalid |
|
1578 MarkItemInvalid( ETrue ); |
|
1579 |
|
1580 // Reset DRM and corrupted flags if they are set |
|
1581 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL() iDbFlag %x", iDbFlag); |
|
1582 if ( iDbFlag & KMPXMediaGeneralFlagsIsCorrupted || |
|
1583 iDbFlag & KMPXMediaGeneralFlagsIsDrmLicenceInvalid ) |
|
1584 { |
|
1585 TRAP_IGNORE( |
|
1586 SetFlagBitsL( EFalse, |
|
1587 KMPXMediaGeneralFlagsIsCorrupted | |
|
1588 KMPXMediaGeneralFlagsIsDrmLicenceInvalid )); |
|
1589 } |
|
1590 |
|
1591 break; |
|
1592 } |
|
1593 case KErrCANotSupported: |
|
1594 case KErrCANoPermission: |
|
1595 case KErrCANoRights: |
|
1596 case KErrCANoAgent: |
|
1597 case KErrCAOutOfRange: |
|
1598 case KErrCAPendingRights: |
|
1599 case KErrCASizeNotDetermined: |
|
1600 case KErrCANewFileHandleRequired: |
|
1601 { |
|
1602 // Release file handles |
|
1603 TRAP_IGNORE(DoStopL()); |
|
1604 // Mark item as DRM Invalid |
|
1605 MarkItemDrmInvalid( ETrue ); |
|
1606 |
|
1607 // Reset corrupted and invalid flags if they are set |
|
1608 MPX_DEBUG2("CMPXPlaybackEngine::DoHandlePluginEventL() iDbFlag %x", iDbFlag); |
|
1609 if ( iDbFlag & KMPXMediaGeneralFlagsIsCorrupted || |
|
1610 iDbFlag & KMPXMediaGeneralFlagsIsInvalid ) |
|
1611 { |
|
1612 TRAP_IGNORE( |
|
1613 SetFlagBitsL( EFalse, |
|
1614 KMPXMediaGeneralFlagsIsCorrupted | |
|
1615 KMPXMediaGeneralFlagsIsInvalid )); |
|
1616 } |
|
1617 |
|
1618 |
|
1619 break; |
|
1620 } |
|
1621 case KErrDied: |
|
1622 { |
|
1623 // Release file handles |
|
1624 TRAP_IGNORE(DoStopL()); |
|
1625 iNextState = EPbStateNotInitialised; |
|
1626 break; |
|
1627 } |
|
1628 default: |
|
1629 // otherwise send error message to clients |
|
1630 break; |
|
1631 } |
|
1632 } |
|
1633 |
|
1634 // ---------------------------------------------------------------------------- |
|
1635 // Callback from plug-in. Retrieve the task that resulted in this (which |
|
1636 // removes it from the queue), get the observer and call back with the results. |
|
1637 // Then the player is free to execute the next task, if any |
|
1638 // ---------------------------------------------------------------------------- |
|
1639 // |
|
1640 void CMPXPlaybackEngine::HandleProperty( |
|
1641 TMPXPlaybackProperty aProperty, |
|
1642 TInt aValue, |
|
1643 TInt aError) |
|
1644 { |
|
1645 MPX_DEBUG5("-->CMPXPlaybackEngine::HandleProperty 0x%08x prop %d val %d err %d", |
|
1646 this, aProperty, aValue, aError); |
|
1647 if ( iInitVolume && EPbPropertyVolume == aProperty ) |
|
1648 { |
|
1649 if (KErrNone == aError) |
|
1650 { |
|
1651 iProperties[EPbPropertyVolume] = aValue; |
|
1652 iInitVolume = EFalse; |
|
1653 } |
|
1654 } |
|
1655 else |
|
1656 { |
|
1657 ASSERT(iTaskQueue->Task() == EProperty && iTaskQueue->Callback() == iCallback); |
|
1658 iCallback->HandleProperty(aProperty,aValue,aError); |
|
1659 iCallback = NULL; |
|
1660 iTaskQueue->CompleteTask(); |
|
1661 |
|
1662 // notify client the new position during the playback |
|
1663 if ((EPbPropertyPosition == aProperty) && (iProgressTimer->IsActive())) |
|
1664 { |
|
1665 TRAP_IGNORE(iClientList->SendMsgL( |
|
1666 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1667 EPbPropertyPosition,aValue))); |
|
1668 } |
|
1669 } |
|
1670 MPX_DEBUG2("<--CMPXPlaybackEngine::HandleProperty 0x%08x", this); |
|
1671 } |
|
1672 |
|
1673 // ---------------------------------------------------------------------------- |
|
1674 // Callback from plug-in. Retrieve the task that resulted in this (which |
|
1675 // removes it from the queue), get the observer and call back with the results. |
|
1676 // Then the player is free to execute the next task, if any |
|
1677 // ---------------------------------------------------------------------------- |
|
1678 // |
|
1679 void CMPXPlaybackEngine::HandleMedia( |
|
1680 CMPXMedia* aMedia, |
|
1681 TInt aError) |
|
1682 { |
|
1683 ASSERT(iTaskQueue->Task() == EMedia && iTaskQueue->Callback() == iCallback); |
|
1684 MPX_FUNC_EX("CMPXPlaybackEngine::HandleMedia()"); |
|
1685 iCallback->HandleMedia(aMedia, aError); |
|
1686 iCallback = NULL; |
|
1687 iTaskQueue->CompleteTask(); |
|
1688 } |
|
1689 |
|
1690 // ---------------------------------------------------------------------------- |
|
1691 // Callback from plug-in. Retrieve the task that resulted in this (which |
|
1692 // removes it from the queue), get the observer and call back with the results. |
|
1693 // Then the player is free to execute the next task, if any |
|
1694 // ---------------------------------------------------------------------------- |
|
1695 // |
|
1696 void CMPXPlaybackEngine::HandleSubPlayerNames( |
|
1697 TUid /*aPlayer*/, |
|
1698 const MDesCArray* aSubPlayers, |
|
1699 TBool aComplete, |
|
1700 TInt aError) |
|
1701 { |
|
1702 ASSERT(iTaskQueue->Task() == ESubPlayerNames && |
|
1703 iTaskQueue->Callback() == iCallback); |
|
1704 MPX_DEBUG4("-->CMPXPlaybackEngine::HandleSubPlayerNames 0x%08x, complete %d, err %d", |
|
1705 this, aComplete, aError); |
|
1706 iCallback->HandleSubPlayerNames(TUid::Uid(0), aSubPlayers, |
|
1707 aComplete, aError); |
|
1708 iCallback = NULL; |
|
1709 iTaskQueue->CompleteTask(); |
|
1710 MPX_DEBUG2("<--CMPXPlaybackEngine::HandleSubPlayerNames 0x%08x", this); |
|
1711 } |
|
1712 |
|
1713 // ---------------------------------------------------------------------------- |
|
1714 // Handle media key event |
|
1715 // ---------------------------------------------------------------------------- |
|
1716 // |
|
1717 void CMPXPlaybackEngine::HandleCmdBufferEventL(const TMPXPlaybackCmdInfo& aEvent) |
|
1718 { |
|
1719 MPX_DEBUG1("CMPXPlaybackEngine::HandleCmdBufferEventL() entering"); |
|
1720 |
|
1721 MPX_DEBUG4("CMPXPlaybackEngine::HandleCmdBufferEventL(): offset=%d, state=%d, navKeyBuffered=%d", aEvent.iTrackOffset, iNextState, aEvent.iNavKeyBuffered); |
|
1722 |
|
1723 // Fix for EJPI-7BHUGX, if the aEvent.iNavKeyBuffered == 1 and aEvent.iTrackOffset == 0 |
|
1724 // That means skip back key press once only, it should not request for media but set pos only |
|
1725 if ( aEvent.iNavKeyBuffered > 1 || aEvent.iTrackOffset != 0 ) |
|
1726 { |
|
1727 iNextState = aEvent.iState; |
|
1728 if ( EPlayFromCollection == iPlaySource && iPlaylist ) |
|
1729 { |
|
1730 MediaFromCollectionL(); |
|
1731 } |
|
1732 else if ( EPlayFromUri == iPlaySource ) |
|
1733 { |
|
1734 TRAP_IGNORE( InitL( iUri, &( KNullDesC8 ), NULL, iAccessPoint ) ); |
|
1735 } |
|
1736 } |
|
1737 else |
|
1738 { |
|
1739 // If position has changed, set the position in plugin. |
|
1740 // Also the current position should be after the original position |
|
1741 if ( Abs(aEvent.iPos - iProperties[EPbPropertyPosition]) > |
|
1742 KPbPositionChangeThreshold && |
|
1743 aEvent.iPos < iProperties[EPbPropertyPosition] ) |
|
1744 { |
|
1745 MPX_DEBUG1("CMPXPlaybackEngine::HandleCmdBufferEventL(): position changed"); |
|
1746 iProperties[EPbPropertyPosition]=aEvent.iPos; |
|
1747 if ( PluginL() ) |
|
1748 { |
|
1749 if (iState == EPbStatePlaying) |
|
1750 { |
|
1751 // Need to send pause command to plugin first so that it will |
|
1752 // not keep playing the rest of it's buffer |
|
1753 MPX_DEBUG1("CMPXPlaybackEngine::HandleCmdBufferEventL() send pause command"); |
|
1754 PluginL()->CommandL(EPbCmdPause); |
|
1755 } |
|
1756 PluginL()->SetL(EPbPropertyPosition, |
|
1757 iProperties[EPbPropertyPosition]); |
|
1758 } |
|
1759 } |
|
1760 |
|
1761 HandleCommandL(CommandFromState( aEvent.iState )); |
|
1762 } |
|
1763 iCmdBuffer->CompleteCommand(); |
|
1764 |
|
1765 MPX_DEBUG1("CMPXPlaybackEngine::HandleCmdBufferEventL() exiting"); |
|
1766 } |
|
1767 |
|
1768 // ---------------------------------------------------------------------------- |
|
1769 // Handle command skip event from key buffering |
|
1770 // ---------------------------------------------------------------------------- |
|
1771 // |
|
1772 void CMPXPlaybackEngine::HandleCmdBufferSkipEventL( |
|
1773 const TMPXPlaybackSkipEvent aSkipEvent ) |
|
1774 { |
|
1775 MPX_DEBUG2("==>CMPXPlaybackEngine::HandleCmdBufferSkipEventL(%d) entering", aSkipEvent); |
|
1776 |
|
1777 if ( EPbsSkipEventNext == aSkipEvent ) |
|
1778 { |
|
1779 iClientList->SendMsgL( |
|
1780 TMPXPlaybackMessage( TMPXPlaybackMessage::ESkipping, 0, 1 )); |
|
1781 |
|
1782 TBool wasSkipping( iSkipping ); |
|
1783 iSkipping = ETrue; |
|
1784 if ( !wasSkipping ) |
|
1785 { |
|
1786 if ( iState == EPbStatePlaying ) |
|
1787 { |
|
1788 Suspend(); |
|
1789 TRAP_IGNORE(PluginL()->CommandL(EPbCmdPause)); |
|
1790 TRAP_IGNORE(SavePlaybackInfoL()); |
|
1791 } |
|
1792 else if ( iState == EPbStatePaused ) |
|
1793 { |
|
1794 TRAP_IGNORE(SavePlaybackInfoL()); |
|
1795 } |
|
1796 } |
|
1797 if ( EPlayFromCollection == iPlaySource && iPlaylist ) |
|
1798 { |
|
1799 if ( iPlaylist->Count() > 0 ) |
|
1800 { |
|
1801 // Stop if playing or paused |
|
1802 if ( !iPlaylist->Next( ETrue ) ) |
|
1803 { |
|
1804 if ( EPbStatePlaying == iNextState || |
|
1805 EPbStatePaused == iNextState ) |
|
1806 { |
|
1807 iCmdBuffer->BufferCommandL( |
|
1808 EPbCmdStop, |
|
1809 iNextState, |
|
1810 iProperties[EPbPropertyPosition]); |
|
1811 } |
|
1812 |
|
1813 // End of playlist, send message to clients. |
|
1814 iClientList->SendMsgL( |
|
1815 TMPXPlaybackMessage(TMPXPlaybackMessage:: |
|
1816 EReachedEndOfPlaylist)); |
|
1817 } |
|
1818 RequestMediaL(); |
|
1819 } |
|
1820 } |
|
1821 } |
|
1822 else if ( EPbsSkipEventPrevious == aSkipEvent ) |
|
1823 { |
|
1824 TBool wasSkipping( iSkipping ); |
|
1825 iSkipping = ETrue; |
|
1826 if ( !wasSkipping && iState == EPbStatePlaying) |
|
1827 { |
|
1828 TRAP_IGNORE(DoStopL()); |
|
1829 PluginL()->CommandL( EPbCmdPause ); |
|
1830 } |
|
1831 |
|
1832 // If first track in list and repeat is off, it will replay current track, |
|
1833 // so do not skip |
|
1834 TBool sendSkip( ETrue ); |
|
1835 if ( iPlaylist ) |
|
1836 { |
|
1837 if ( 0 != iPlaylist->Index() || |
|
1838 CMPXCollectionPlaylist::ERepeatOff != iPlaylist->RepeatMode() ) |
|
1839 { |
|
1840 sendSkip = ETrue; |
|
1841 } |
|
1842 else |
|
1843 { |
|
1844 sendSkip = EFalse; |
|
1845 } |
|
1846 } |
|
1847 if ( sendSkip && EPlayFromCollection == iPlaySource && iPlaylist ) |
|
1848 { |
|
1849 iClientList->SendMsgL( |
|
1850 TMPXPlaybackMessage( TMPXPlaybackMessage::ESkipping, 0, -1 )); |
|
1851 |
|
1852 if (iPlaylist->Count()>0) |
|
1853 { |
|
1854 iPlaylist->Previous( ETrue ); |
|
1855 RequestMediaL(); |
|
1856 } |
|
1857 } |
|
1858 } |
|
1859 else |
|
1860 { |
|
1861 iSkipping = EFalse; |
|
1862 iClientList->SendMsgL( |
|
1863 TMPXPlaybackMessage( TMPXPlaybackMessage::ESkipEnd )); |
|
1864 } |
|
1865 |
|
1866 MPX_DEBUG1("<==CMPXPlaybackEngine::HandleCmdBufferSkipEventL()"); |
|
1867 } |
|
1868 |
|
1869 |
|
1870 // ---------------------------------------------------------------------------- |
|
1871 // Suspend playback |
|
1872 // ---------------------------------------------------------------------------- |
|
1873 // |
|
1874 void CMPXPlaybackEngine::Suspend() |
|
1875 // |
|
1876 // Should stop in current position, i.e. clearing timers etc. |
|
1877 // |
|
1878 { |
|
1879 MPX_FUNC_EX("CMPXPlaybackEngine::Suspend()"); |
|
1880 iProgressTimer->Cancel(); |
|
1881 EndSeek(); |
|
1882 iAutoResumeHandler->CancelResumeTimer(); |
|
1883 } |
|
1884 |
|
1885 // ---------------------------------------------------------------------------- |
|
1886 // Seek timer callback handler |
|
1887 // ---------------------------------------------------------------------------- |
|
1888 // |
|
1889 void CMPXPlaybackEngine::SeekTimerTick() |
|
1890 { |
|
1891 TInt& pos=iProperties[EPbPropertyPosition]; |
|
1892 pos+=iSeekStep; |
|
1893 if (pos>iProperties[EPbPropertyDuration]) |
|
1894 { |
|
1895 pos=iProperties[EPbPropertyDuration]; |
|
1896 iSeekTimer->Cancel(); |
|
1897 } |
|
1898 if (pos<0) |
|
1899 { |
|
1900 pos=0; |
|
1901 iSeekTimer->Cancel(); |
|
1902 } |
|
1903 |
|
1904 iSeekStep*=KPbSeekAccelerationFactor; |
|
1905 if (iSeekStep>iMaxSeekStep) |
|
1906 { |
|
1907 iSeekStep=iMaxSeekStep; |
|
1908 } |
|
1909 else if (iSeekStep<-iMaxSeekStep) |
|
1910 { |
|
1911 iSeekStep=-iMaxSeekStep; |
|
1912 } |
|
1913 TRAP_IGNORE(iClientList->SendMsgL( |
|
1914 TMPXPlaybackMessage(TMPXPlaybackMessage::EPropertyChanged, |
|
1915 EPbPropertyPosition, |
|
1916 pos))); |
|
1917 } |
|
1918 |
|
1919 // ---------------------------------------------------------------------------- |
|
1920 // Seek timer callback |
|
1921 // ---------------------------------------------------------------------------- |
|
1922 // |
|
1923 TInt CMPXPlaybackEngine::SeekTimerCallback(TAny* aPtr) |
|
1924 { |
|
1925 static_cast<CMPXPlaybackEngine*>(aPtr)->SeekTimerTick(); |
|
1926 return KErrNone; |
|
1927 } |
|
1928 |
|
1929 // ---------------------------------------------------------------------------- |
|
1930 // Initialise helper method |
|
1931 // ---------------------------------------------------------------------------- |
|
1932 // |
|
1933 void CMPXPlaybackEngine::InitL(const TDesC* aSong, |
|
1934 const TDesC8* aType, |
|
1935 RFile* aFile, |
|
1936 TInt aAccessPoint) |
|
1937 { |
|
1938 MPX_DEBUG1("==>CMPXPlaybackEngine::InitL(const TDesC* aSong, const TDesC8* aType, RFile* aFile,TInt aAccessPoint)"); |
|
1939 CMPXPlaybackPlugin* p( NULL ); |
|
1940 if ( iPluginHandler->Plugin() ) |
|
1941 { |
|
1942 TRAP_IGNORE(iPluginHandler->Plugin()->CommandL(EPbCmdClose)); |
|
1943 } |
|
1944 |
|
1945 if (aSong && aType) |
|
1946 { |
|
1947 MPX_DEBUG2("CMPXPlaybackEngine::InitL(%S)", aSong); |
|
1948 iPluginHandler->SelectPlayerL(*aSong,*aType); |
|
1949 } |
|
1950 else if (aFile) |
|
1951 { |
|
1952 iPluginHandler->SelectPlayerL(*aFile); |
|
1953 } |
|
1954 else |
|
1955 { // should never happen |
|
1956 ASSERT(0); |
|
1957 } |
|
1958 |
|
1959 p=iPluginHandler->Plugin(); |
|
1960 CheckPtrL(p); |
|
1961 |
|
1962 if (p->Uid()!=iPluginUid) |
|
1963 { // new plugin or new playlist |
|
1964 iPluginUid = p->Uid(); |
|
1965 iInitVolume = ETrue; |
|
1966 p->PropertyL( EPbPropertyVolume ); |
|
1967 iClientList->SendMsgL( |
|
1968 TMPXPlaybackMessage(TMPXPlaybackMessage::EPlayerChanged)); |
|
1969 } |
|
1970 // Stop and close opened file |
|
1971 TRAP_IGNORE(DoStopL(EFalse)); |
|
1972 TRAP_IGNORE(p->CommandL(EPbCmdClose)); |
|
1973 |
|
1974 // If playing from a playlist, send the index as a data |
|
1975 // parameter. This helps performance as the client |
|
1976 // doesn't need to request the index separately |
|
1977 TInt index( KErrNotFound ); |
|
1978 if ( EPlayFromCollection == iPlaySource ) |
|
1979 { |
|
1980 index = iPlaylist->Index(); |
|
1981 } |
|
1982 |
|
1983 TMPXPlaybackMessage msg( TMPXPlaybackMessage::EStateChanged, |
|
1984 EPbStateInitialising, |
|
1985 index ); |
|
1986 SetStateL( msg ); |
|
1987 iProperties[EPbPropertyPosition]=0; |
|
1988 |
|
1989 // make sure our interface is supported |
|
1990 CDesCArray* interfaces = iPluginHandler->SupportedInterfacesL( p->Uid() ); |
|
1991 TBool version2InterfaceSupported = EFalse; |
|
1992 if (interfaces->MdcaCount()) |
|
1993 { |
|
1994 TInt pos(0); |
|
1995 version2InterfaceSupported = !interfaces->FindIsq(KMPXPlaybackPluginVersion2, pos); |
|
1996 } |
|
1997 delete interfaces; |
|
1998 |
|
1999 // cast the plugin to use our interface |
|
2000 if (version2InterfaceSupported) |
|
2001 { |
|
2002 CMPXPlaybackPluginVersion2* plugin = NULL; |
|
2003 plugin = static_cast<CMPXPlaybackPluginVersion2*>(p); |
|
2004 |
|
2005 // if cast was successful, then init streaming with access point |
|
2006 if (plugin) |
|
2007 { |
|
2008 if ( iAccessPointSet ) |
|
2009 { |
|
2010 if (aSong && aType) |
|
2011 { |
|
2012 plugin->InitStreamingL( *aSong, *aType, aAccessPoint ); |
|
2013 } |
|
2014 else if (aFile) |
|
2015 { |
|
2016 plugin->InitStreamingL( *aFile, aAccessPoint ); |
|
2017 } |
|
2018 } |
|
2019 else |
|
2020 { |
|
2021 if (aSong && aType) |
|
2022 { |
|
2023 plugin->InitialiseL( *aSong ); |
|
2024 } |
|
2025 else if (aFile) |
|
2026 { |
|
2027 plugin->InitialiseL( *aFile ); |
|
2028 } |
|
2029 } |
|
2030 } |
|
2031 else // if (plugin) |
|
2032 { |
|
2033 MPX_DEBUG1("CMPXPlaybackEngine::InitL(): *** Init Streaming failed -- failure to convert to expected interface"); |
|
2034 } |
|
2035 } |
|
2036 else // if (version2InterfaceSupported) |
|
2037 { |
|
2038 if (aSong && aType) |
|
2039 { |
|
2040 p->InitialiseL( *aSong ); |
|
2041 } |
|
2042 else if (aFile) |
|
2043 { |
|
2044 p->InitialiseL( *aFile ); |
|
2045 } |
|
2046 } |
|
2047 |
|
2048 MPX_DEBUG1("<==CMPXPlaybackEngine::InitL(const TDesC* aSong, const TDesC8* aType, RFile* aFile, TInt aAccessPoint)"); |
|
2049 } |
|
2050 |
|
2051 // ---------------------------------------------------------------------------- |
|
2052 // Command handler |
|
2053 // ---------------------------------------------------------------------------- |
|
2054 // |
|
2055 void CMPXPlaybackEngine::HandleCommandL(TMPXPlaybackCommand aCmd, TInt aData ) |
|
2056 { |
|
2057 MPX_DEBUG2("CMPXPlaybackEngine::HandleCommandL(%d) entering", aCmd); |
|
2058 switch(aCmd) |
|
2059 { |
|
2060 case EPbCmdPlay: |
|
2061 HandlePlayL(); |
|
2062 break; |
|
2063 case EPbCmdStop: |
|
2064 HandleStopL(); |
|
2065 break; |
|
2066 case EPbCmdPause: |
|
2067 HandlePauseL(); |
|
2068 break; |
|
2069 case EPbCmdNext: |
|
2070 HandleNextL(); |
|
2071 break; |
|
2072 case EPbCmdPrevious: |
|
2073 HandlePreviousL(); |
|
2074 break; |
|
2075 case EPbCmdPlayWithFadeIn: |
|
2076 HandlePlayWithFadeInL(); |
|
2077 break; |
|
2078 case EPbCmdStartSeekForward: |
|
2079 HandleStartSeekL(ETrue); |
|
2080 break; |
|
2081 case EPbCmdStartSeekBackward: |
|
2082 HandleStartSeekL(EFalse); |
|
2083 break; |
|
2084 case EPbCmdStopSeeking: |
|
2085 HandleStopSeekingL(); |
|
2086 break; |
|
2087 case EPbCmdIncreaseVolume: |
|
2088 HandleIncreaseVolumeL(); |
|
2089 break; |
|
2090 case EPbCmdDecreaseVolume: |
|
2091 HandleDecreaseVolumeL(); |
|
2092 break; |
|
2093 case EPbCmdSetVolume: |
|
2094 HandleSetVolumeL( aData ); |
|
2095 break; |
|
2096 case EPbCmdMuteVolume: |
|
2097 HandleMuteL(ETrue); |
|
2098 break; |
|
2099 case EPbCmdUnMuteVolume: |
|
2100 HandleMuteL(EFalse); |
|
2101 break; |
|
2102 case EPbCmdClose: |
|
2103 HandleCloseL( aData ); |
|
2104 break; |
|
2105 case EPbCmdReplay: |
|
2106 HandleReplayL(); |
|
2107 break; |
|
2108 case EPbApplyEffect: |
|
2109 HandleEffectL(aData); |
|
2110 break; |
|
2111 case EPbCmdDisableEffect: |
|
2112 HandleDisableEffectL(); |
|
2113 break; |
|
2114 case EPbCmdPreservePosition: |
|
2115 iPreservedPosition = iProperties[EPbPropertyPosition]; |
|
2116 break; |
|
2117 case EPbCmdPreserveState: |
|
2118 iPreservedState = iState; |
|
2119 break; |
|
2120 case EPbCmdCloseItem: |
|
2121 HandleCloseItemL( aData ); |
|
2122 break; |
|
2123 case EPbCmdCancelInit: |
|
2124 { |
|
2125 if (EPbStateInitialising==iState) |
|
2126 { |
|
2127 PluginL()->CancelRequest(); |
|
2128 iNextState = EPbStateStopped; |
|
2129 |
|
2130 if (iPluginHandler->Plugin()) |
|
2131 { |
|
2132 TRAP_IGNORE(iPluginHandler->Plugin()->CommandL(EPbCmdClose, aData)); |
|
2133 } |
|
2134 if (iInitializer) |
|
2135 { |
|
2136 iInitializer->Close(); |
|
2137 } |
|
2138 //Needs to update iState and report the change to Ui |
|
2139 SetStateL(EPbStateStopped); |
|
2140 } |
|
2141 break; |
|
2142 } |
|
2143 case EPbCmdResetPreserveState: |
|
2144 { |
|
2145 iPreservedState = EPbStateNotInitialised; |
|
2146 break; |
|
2147 } |
|
2148 case EPbCmdUnloadNonActivePlugin: |
|
2149 { |
|
2150 TUid uid = TUid::Uid(aData); |
|
2151 if (iPluginHandler->Plugin()) |
|
2152 { |
|
2153 if (iPluginHandler->Plugin()->Uid() != uid) |
|
2154 { //not current active plugin |
|
2155 iPluginHandler->UnloadPlugin(uid); |
|
2156 } |
|
2157 } |
|
2158 if (iInitializer) |
|
2159 { |
|
2160 if (iInitializer->PluginUid() == uid) |
|
2161 { //Plugin loaded in pre-initializer, not active one. |
|
2162 iInitializer->Close(); |
|
2163 } |
|
2164 } |
|
2165 break; |
|
2166 } |
|
2167 case EPbCmdClearKeyBuffer: |
|
2168 { |
|
2169 MPX_DEBUG1("CMPXPlaybackEngine::HandleCommandL - EPbCmdClearKeyBuffer"); |
|
2170 iCmdBuffer->ClearCommands(); |
|
2171 break; |
|
2172 } |
|
2173 case EPbCmdSetAutoResume: |
|
2174 { |
|
2175 iAutoResumeHandler->SetAutoResume( aData ); |
|
2176 break; |
|
2177 } |
|
2178 default: |
|
2179 ASSERT(0); |
|
2180 } |
|
2181 MPX_DEBUG1("CMPXPlaybackEngine::HandleCommandL() exiting"); |
|
2182 } |
|
2183 |
|
2184 // ---------------------------------------------------------------------------- |
|
2185 // Handle media properties from collection |
|
2186 // ---------------------------------------------------------------------------- |
|
2187 // |
|
2188 void CMPXPlaybackEngine::HandleCollectionMediaL( |
|
2189 const CMPXMedia& aMedia, |
|
2190 TInt aError) |
|
2191 { |
|
2192 MPX_DEBUG3("-->CMPXPlaybackEngine::HandleCollectionMediaL 0x%08x err(%d)", |
|
2193 this, aError); |
|
2194 |
|
2195 if (KErrNone == aError) |
|
2196 { |
|
2197 HBufC8* mimeType = |
|
2198 MPXUser::Alloc8L(aMedia.ValueText(KMPXMediaGeneralMimeType)); |
|
2199 CleanupStack::PushL(mimeType); |
|
2200 |
|
2201 if(iUri) |
|
2202 { |
|
2203 delete iUri; |
|
2204 iUri = NULL; |
|
2205 } |
|
2206 |
|
2207 iUri = aMedia.ValueText(KMPXMediaGeneralUri).AllocL(); |
|
2208 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL uri %S", iUri); |
|
2209 |
|
2210 iItemId = KMPXInvalidItemId; |
|
2211 if (aMedia.IsSupported(KMPXMediaGeneralId)) |
|
2212 { |
|
2213 iItemId = aMedia.ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId ); |
|
2214 MPX_DEBUG3("CMPXPlaybackEngine::HandleCollectionMediaL iItemId %d %d", iItemId.iId1, iItemId.iId2); |
|
2215 } |
|
2216 |
|
2217 iDbFlag = 0; |
|
2218 if ( aMedia.IsSupported( KMPXMediaGeneralFlags )) |
|
2219 { |
|
2220 iDbFlag = aMedia.ValueTObjectL<TUint>( KMPXMediaGeneralFlags ); |
|
2221 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL iDbFlag %x", iDbFlag); |
|
2222 } |
|
2223 |
|
2224 iMediaDuration = 0; |
|
2225 if ( aMedia.IsSupported( KMPXMediaGeneralDuration )) |
|
2226 { |
|
2227 iMediaDuration = aMedia.ValueTObjectL<TInt>( KMPXMediaGeneralDuration ); |
|
2228 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL iMediaDuration %d", iMediaDuration); |
|
2229 } |
|
2230 |
|
2231 iAccessPoint = 0; |
|
2232 iAccessPointSet = EFalse; |
|
2233 if ( aMedia.IsSupported(KMPXMediaGeneralExtAccessPoint) ) |
|
2234 { |
|
2235 iAccessPoint = aMedia.ValueTObjectL<TInt>( KMPXMediaGeneralExtAccessPoint ); |
|
2236 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL iAccessPoint %d", iAccessPoint ); |
|
2237 iAccessPointSet = ETrue; |
|
2238 } |
|
2239 if (*iUri == KNullDesC) |
|
2240 { |
|
2241 aError = KErrNotFound; |
|
2242 } |
|
2243 else |
|
2244 { |
|
2245 TRAP( aError, InitL( iUri, mimeType, NULL, iAccessPoint) ); |
|
2246 /* |
|
2247 // 20 steps fix |
|
2248 // check whether we are playing WMA files, if so |
|
2249 // the increment has to be KMPXLargeVolumeIncrement |
|
2250 TParsePtrC parser(*iUri); |
|
2251 |
|
2252 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL(): iUri is %S", iUri); |
|
2253 if (parser.Ext().CompareF(KWmaExtension) == 0 || parser.Ext().CompareF(KRaExtension) == 0) |
|
2254 { |
|
2255 // for wma file, the increment is always 10 with or without headset |
|
2256 iVolumeIncrement = KMPXLargeVolumeIncrement; |
|
2257 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionMediaL it is a wma/ra file, volumeIncrement: %d !!!!", iVolumeIncrement); |
|
2258 } |
|
2259 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
2260 #ifdef __ACCESSORY_FW |
|
2261 else if (iAccessoryObs->AccessoryModeL() == EPbAccessoryWiredHeadset || iAccessoryObs->AccessoryModeL() == EPbAccessoryHeadphones) |
|
2262 #else |
|
2263 else if (iAccessoryObs->AccessoryModeL() == EPbAccessoryHeadset) |
|
2264 #endif // __ACCESSORY_FW |
|
2265 { |
|
2266 // for non wma files with headset, the volume increment is 5 |
|
2267 iVolumeIncrement = KMPXSmallVolumeIncrement; |
|
2268 } |
|
2269 #endif // HIGH_RESOLUTION_VOLUME |
|
2270 */ |
|
2271 if ( KErrNone == aError ) |
|
2272 { |
|
2273 RestorePlaybackPositionAndStateL( aMedia ); |
|
2274 } |
|
2275 else |
|
2276 { |
|
2277 iClientList->SendMsgL(TMPXPlaybackMessage( |
|
2278 TMPXPlaybackMessage::EMediaChanged)); |
|
2279 iState = EPbStateStopped; |
|
2280 } |
|
2281 } |
|
2282 CleanupStack::PopAndDestroy(mimeType); |
|
2283 } |
|
2284 else |
|
2285 { |
|
2286 // it'll be incorrect to leave iItemId unchanged, also KMPXInvalidItemId has special handling in |
|
2287 // CreateMediaToSetLC so we'd rather set Id to some actual value even if it had some 'issues' |
|
2288 iItemId = iPlaylist->Path().Id(); |
|
2289 } |
|
2290 |
|
2291 // Check for error again, just in case above code had any errors |
|
2292 if ( KErrNone != aError ) |
|
2293 { |
|
2294 if ( KErrNotFound == aError || |
|
2295 KErrPathNotFound == aError || |
|
2296 KErrPermissionDenied == aError ) |
|
2297 { |
|
2298 // Mark item as Invalid |
|
2299 MarkItemInvalid( ETrue ); |
|
2300 iClientList->SendMsgL( |
|
2301 TMPXPlaybackMessage( TMPXPlaybackMessage::EError, |
|
2302 EPInitialised, |
|
2303 aError )); |
|
2304 } |
|
2305 else |
|
2306 { // other system error |
|
2307 HandleStopL(); |
|
2308 } |
|
2309 } |
|
2310 MPX_DEBUG1("<--CMPXPlaybackEngine::HandleCollectionMediaL()"); |
|
2311 } |
|
2312 |
|
2313 // ---------------------------------------------------------------------------- |
|
2314 // Handle playlist change event |
|
2315 // ---------------------------------------------------------------------------- |
|
2316 // |
|
2317 void CMPXPlaybackEngine::HandleCollectionPlaylistChange(TInt aError) |
|
2318 { |
|
2319 MPX_FUNC_EX("CMPXPlaybackEngine::HandleCollectionPlaylistChange"); |
|
2320 MPX_DEBUG2("CMPXPlaybackEngine::HandleCollectionPlaylistChange(%d)", aError); |
|
2321 |
|
2322 if (KErrNotFound == aError) |
|
2323 { |
|
2324 if ( iPlaylist ) |
|
2325 { |
|
2326 TRAP_IGNORE(HandleStopL()); |
|
2327 |
|
2328 // If playlist is empty now, update state |
|
2329 if ( iPlaylist->Count() == 0 ) |
|
2330 { |
|
2331 iNextState = EPbStateNotInitialised; |
|
2332 iState = EPbStateNotInitialised; |
|
2333 } |
|
2334 } |
|
2335 } |
|
2336 else if(KErrEof == aError) |
|
2337 { // current item removed at the end |
|
2338 TRAP_IGNORE(HandleStopL()); |
|
2339 |
|
2340 // If playlist is empty now, update state |
|
2341 if ( iPlaylist->Count() == 0 ) |
|
2342 { |
|
2343 iNextState = EPbStateNotInitialised; |
|
2344 iState = EPbStateNotInitialised; |
|
2345 } |
|
2346 else |
|
2347 { |
|
2348 TRAP_IGNORE(HandleNextL(1, ETrue)); |
|
2349 } |
|
2350 } |
|
2351 else if (iInitializer) |
|
2352 { // Reset initializer anyway. Make sure it is synced |
|
2353 //iInitializer->Close(); //correct auto playlist crash |
|
2354 } |
|
2355 //update now playing view |
|
2356 TRAP_IGNORE(iClientList->SendMsgL(TMPXPlaybackMessage( |
|
2357 TMPXPlaybackMessage::EPlaylistUpdated))); |
|
2358 } |
|
2359 |
|
2360 // ---------------------------------------------------------------------------- |
|
2361 // CMPXPlaybackEngine::HandlePluginHandlerEvent |
|
2362 // ---------------------------------------------------------------------------- |
|
2363 // |
|
2364 void CMPXPlaybackEngine::HandlePluginHandlerEvent( |
|
2365 TPluginHandlerEvents aEvent, |
|
2366 const TUid& aPluginUid, |
|
2367 TBool aLoaded, |
|
2368 TInt aData) |
|
2369 { |
|
2370 MPX_FUNC_EX("CMPXPlaybackEngine::HandlePluginHandlerEvent"); |
|
2371 |
|
2372 switch (aEvent) |
|
2373 { |
|
2374 case MMPXPluginHandlerObserver::EPluginAdd: |
|
2375 { |
|
2376 TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginAdd, aPluginUid, |
|
2377 EFalse, aData)); |
|
2378 break; |
|
2379 } |
|
2380 case MMPXPluginHandlerObserver::EPluginUpdateStart: |
|
2381 { |
|
2382 // Handling the unloading of the previous plugin version and the loading |
|
2383 // of the new plugin version is synchronous and therefore new requests |
|
2384 // will not be processed by the server/engine in between EPluginUpdateStart |
|
2385 // and EPluginUpdateEnd. |
|
2386 // |
|
2387 // If the plugin handler would unload/load plugins asynchronously then a |
|
2388 // mechanism must be created where new requests are not accepted for |
|
2389 // the plugin that is being updated for the duration of the update. |
|
2390 |
|
2391 TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginUpdateStart, |
|
2392 aPluginUid, aLoaded, aData)); |
|
2393 |
|
2394 // If the current loaded plugin is being updated |
|
2395 if (iPluginHandler->Plugin() && |
|
2396 (iPluginHandler->Plugin()->Uid() == aPluginUid)) |
|
2397 { |
|
2398 // Complete all outstanding requests |
|
2399 iTaskQueue->CompleteAllTasks(KErrNotReady); |
|
2400 } |
|
2401 break; |
|
2402 } |
|
2403 case MMPXPluginHandlerObserver::EPluginUpdateEnd: |
|
2404 { |
|
2405 TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginUpdateEnd, |
|
2406 aPluginUid, aLoaded, aData)); |
|
2407 break; |
|
2408 } |
|
2409 case MMPXPluginHandlerObserver::EPluginRemove: |
|
2410 { |
|
2411 // If the current loaded plugin is being removed |
|
2412 if (iPluginHandler->Plugin() && |
|
2413 (iPluginHandler->Plugin()->Uid() == aPluginUid)) |
|
2414 { |
|
2415 // Complete all outstanding requests |
|
2416 iTaskQueue->CompleteAllTasks(KErrNotReady); |
|
2417 } |
|
2418 |
|
2419 TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginRemove, |
|
2420 aPluginUid, aLoaded)); |
|
2421 break; |
|
2422 } |
|
2423 |
|
2424 default: |
|
2425 { |
|
2426 // ignore the event |
|
2427 break; |
|
2428 } |
|
2429 } |
|
2430 } |
|
2431 |
|
2432 // ---------------------------------------------------------------------------- |
|
2433 // CMPXPlaybackEngine::SendPluginHandlerMessageL |
|
2434 // ---------------------------------------------------------------------------- |
|
2435 // |
|
2436 void CMPXPlaybackEngine::SendPluginHandlerMessageL( |
|
2437 TInt aMessageId, |
|
2438 const TUid& aPluginUid, |
|
2439 TBool aLoaded, |
|
2440 TInt aVersion /* = 0 */) |
|
2441 { |
|
2442 CMPXMessage* msg = CMPXMedia::NewL(); |
|
2443 CleanupStack::PushL(msg); |
|
2444 |
|
2445 msg->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, aMessageId); |
|
2446 msg->SetTObjectValueL<TUid>(KMPXAttrPluginId, aPluginUid); |
|
2447 msg->SetTObjectValueL<TBool>(KMPXAttrPluginLoaded, aLoaded); |
|
2448 if (aVersion > 0) |
|
2449 { |
|
2450 msg->SetTObjectValueL<TInt>(KMPXAttrPluginVersion, aVersion); |
|
2451 } |
|
2452 |
|
2453 iClientList->SendMsg(msg, KErrNone); |
|
2454 |
|
2455 CleanupStack::PopAndDestroy(msg); |
|
2456 } |
|
2457 |
|
2458 // ---------------------------------------------------------------------------- |
|
2459 // Handle play command |
|
2460 // ---------------------------------------------------------------------------- |
|
2461 // |
|
2462 void CMPXPlaybackEngine::HandlePlayL() |
|
2463 { |
|
2464 MPX_DEBUG1("CMPXPlaybackEngine::HandlePlayL(): entering"); |
|
2465 CMPXPlaybackPlugin* p(NULL); |
|
2466 TMPXPlaybackState oldNextState( iNextState ); |
|
2467 iNextState = EPbStatePlaying; |
|
2468 if (EPbStateNotInitialised == iPluginState && |
|
2469 EPlayFromCollection == iPlaySource && |
|
2470 EPbStatePaused != iState) |
|
2471 { |
|
2472 MediaFromCollectionL(); |
|
2473 } |
|
2474 else |
|
2475 { |
|
2476 switch (iState) |
|
2477 { |
|
2478 case EPbStatePlaying: //already playing, send message to update clients |
|
2479 if (EPbStatePaused == iPluginState) |
|
2480 { // paused due to skipping |
|
2481 PluginL()->CommandL(EPbCmdPlay); |
|
2482 } |
|
2483 iClientList->SendMsgL( |
|
2484 TMPXPlaybackMessage( |
|
2485 TMPXPlaybackMessage::EStateChanged, iState)); |
|
2486 break; |
|
2487 case EPbStateNotInitialised: // No song initialised in engine |
|
2488 iNextState = EPbStateNotInitialised; |
|
2489 break; |
|
2490 case EPbStateSeekingForward: |
|
2491 case EPbStateSeekingBackward: |
|
2492 EndSeek(); |
|
2493 p = PluginL(); |
|
2494 p->CommandL(EPbCmdPlay); |
|
2495 break; |
|
2496 case EPbStatePaused: |
|
2497 case EPbStateStopped: |
|
2498 { |
|
2499 // If playing from collection playlist and currently in |
|
2500 // stopped state, then re-get media attributes |
|
2501 if ( EPlayFromCollection == iPlaySource && |
|
2502 EPbStateStopped == oldNextState ) |
|
2503 { |
|
2504 MediaFromCollectionL(); |
|
2505 break; |
|
2506 } |
|
2507 else if ( EPlayFromUri == iPlaySource && |
|
2508 EPbStateStopped == oldNextState ) |
|
2509 { |
|
2510 TRAP_IGNORE( InitL( iUri, &( KNullDesC8 ), NULL, iAccessPoint ) ); |
|
2511 break; |
|
2512 } |
|
2513 else |
|
2514 { |
|
2515 // fall through on purpose |
|
2516 } |
|
2517 } |
|
2518 default: |
|
2519 { |
|
2520 p= PluginL(); |
|
2521 p->CommandL(EPbCmdPlay); |
|
2522 break; |
|
2523 } |
|
2524 } |
|
2525 } |
|
2526 MPX_DEBUG1("CMPXPlaybackEngine::HandlePlayL(): exiting"); |
|
2527 } |
|
2528 |
|
2529 // ---------------------------------------------------------------------------- |
|
2530 // Handle play command with fade in |
|
2531 // ---------------------------------------------------------------------------- |
|
2532 // |
|
2533 void CMPXPlaybackEngine::HandlePlayWithFadeInL() |
|
2534 { |
|
2535 MPX_DEBUG1("CMPXPlaybackEngine::HandlePlayWithFadeInL(): entering"); |
|
2536 MPX_DEBUG2("CMPXPlaybackEngine::HandlePlayWithFadeInL(): Ramp = %d", iProperties[EPbPropertyVolumeRamp]); |
|
2537 MPX_DEBUG2("CMPXPlaybackEngine::HandlePlayWithFadeInL(): Position = %d", iProperties[EPbPropertyPosition]); |
|
2538 |
|
2539 CMPXPlaybackPlugin* p( PluginL() ); |
|
2540 TRAP_IGNORE( // uPnP leaves if set in stop state |
|
2541 p->SetL( EPbPropertyVolumeRamp, |
|
2542 iProperties[EPbPropertyVolumeRamp] )); |
|
2543 p->CommandL(EPbCmdPlay); |
|
2544 iNextState = EPbStatePlaying; |
|
2545 MPX_DEBUG1("CMPXPlaybackEngine::HandlePlayWithFadeInL(): exiting"); |
|
2546 } |
|
2547 |
|
2548 // ---------------------------------------------------------------------------- |
|
2549 // Handle pause command |
|
2550 // ---------------------------------------------------------------------------- |
|
2551 // |
|
2552 void CMPXPlaybackEngine::HandlePauseL() |
|
2553 { |
|
2554 MPX_DEBUG1("CMPXPlaybackEngine::HandlePauseL(): entering"); |
|
2555 Suspend(); |
|
2556 if ( EPbStatePaused == iState ) |
|
2557 { |
|
2558 //already paused, send message to update clients |
|
2559 iClientList->SendMsgL( |
|
2560 TMPXPlaybackMessage( |
|
2561 TMPXPlaybackMessage::EStateChanged, iState)); |
|
2562 } |
|
2563 else |
|
2564 { |
|
2565 if (EPbStatePlaying == iNextState) |
|
2566 { // only change state from playing to pause |
|
2567 iNextState = EPbStatePaused; |
|
2568 } |
|
2569 PluginL()->CommandL(EPbCmdPause); |
|
2570 } |
|
2571 MPX_DEBUG1("CMPXPlaybackEngine::HandlePauseL(): exiting"); |
|
2572 } |
|
2573 |
|
2574 // ---------------------------------------------------------------------------- |
|
2575 // Handle stop command |
|
2576 // ---------------------------------------------------------------------------- |
|
2577 // |
|
2578 void CMPXPlaybackEngine::HandleStopL() |
|
2579 { |
|
2580 MPX_DEBUG1("CMPXPlaybackEngine::HandleStopL(): entering"); |
|
2581 iNextState = EPbStateStopped; |
|
2582 TRAP_IGNORE(DoStopL()); |
|
2583 if (iInitializer) |
|
2584 { |
|
2585 iInitializer->Close(); |
|
2586 } |
|
2587 MPX_DEBUG1("CMPXPlaybackEngine::HandleStopL(): exiting"); |
|
2588 } |
|
2589 |
|
2590 // ---------------------------------------------------------------------------- |
|
2591 // Stop playback |
|
2592 // ---------------------------------------------------------------------------- |
|
2593 // |
|
2594 void CMPXPlaybackEngine::DoStopL(TBool aSavePlaybackInfo) |
|
2595 { |
|
2596 MPX_DEBUG1("==>CMPXPlaybackEngine::DoStopL()"); |
|
2597 Suspend(); |
|
2598 if (iState == EPbStatePaused || iState == EPbStatePlaying || |
|
2599 iState == EPbStateInitialising) |
|
2600 { |
|
2601 if (aSavePlaybackInfo && (iState == EPbStatePaused || iState == EPbStatePlaying )) |
|
2602 { |
|
2603 TRAP_IGNORE(SavePlaybackInfoL()); // Leave when MMC eject and database already closed. |
|
2604 } |
|
2605 PluginL()->CommandL(EPbCmdStop); // Leave if router power down |
|
2606 } |
|
2607 MPX_DEBUG1("<==CMPXPlaybackEngine::DoStopL()"); |
|
2608 } |
|
2609 |
|
2610 // ---------------------------------------------------------------------------- |
|
2611 // Handle next track command |
|
2612 // ---------------------------------------------------------------------------- |
|
2613 // |
|
2614 void CMPXPlaybackEngine::HandleNextL( |
|
2615 TInt aOffset /*= 1*/, |
|
2616 TBool aIgnoreRepeat /*=EFalse*/ ) |
|
2617 { |
|
2618 MPX_ASSERT(aOffset>0); |
|
2619 MPX_DEBUG2("CMPXPlaybackEngine::HandleNextL(%d) entering", aOffset); |
|
2620 EndSeek(); |
|
2621 TBool next = ETrue; |
|
2622 TBool notify( ETrue ); |
|
2623 if (EPlayFromCollection == iPlaySource && iPlaylist) |
|
2624 { |
|
2625 // Ignore command if playlist empty |
|
2626 if ( iPlaylist->Count() <= 0 ) |
|
2627 { |
|
2628 next = EFalse; |
|
2629 notify = EFalse; |
|
2630 } |
|
2631 else |
|
2632 { |
|
2633 while (aOffset-->0) |
|
2634 { |
|
2635 if (!iPlaylist->Next( aIgnoreRepeat )) |
|
2636 { |
|
2637 iClientList->SendMsgL( |
|
2638 TMPXPlaybackMessage(TMPXPlaybackMessage:: |
|
2639 EReachedEndOfPlaylist)); |
|
2640 iNextState = EPbStateStopped; |
|
2641 if (iPlaylist->IsSingleItemPlaylist()) |
|
2642 { |
|
2643 next = EFalse; |
|
2644 } |
|
2645 break; |
|
2646 } |
|
2647 } |
|
2648 } |
|
2649 } |
|
2650 |
|
2651 // Check if repeat mode is on and playing from a file or URI |
|
2652 else if ( iProperties[EPbPropertyRepeatMode] != EPbRepeatOff ) |
|
2653 { |
|
2654 if ( EPlayFromFile == iPlaySource ) |
|
2655 { |
|
2656 TRAP_IGNORE( InitL( NULL, NULL, &iFile, iAccessPoint )); |
|
2657 } |
|
2658 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
2659 else if ( EPlayFromFile64 == iPlaySource ) |
|
2660 { |
|
2661 TRAP_IGNORE( Init64L( &iFile64, iAccessPoint )); |
|
2662 } |
|
2663 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
2664 else if ( EPlayFromUri == iPlaySource ) |
|
2665 { |
|
2666 TRAP_IGNORE( InitL( iUri, &( KNullDesC8 ), NULL, iAccessPoint )); |
|
2667 } |
|
2668 else |
|
2669 { |
|
2670 HandleStopL(); |
|
2671 } |
|
2672 next = EFalse; |
|
2673 } |
|
2674 else |
|
2675 { |
|
2676 HandleStopL(); |
|
2677 next = EFalse; |
|
2678 } |
|
2679 |
|
2680 if (next) |
|
2681 { |
|
2682 // query collection for next song |
|
2683 MediaFromCollectionL(); |
|
2684 } |
|
2685 else if ( notify ) |
|
2686 { // trigger UI to update duration |
|
2687 iClientList->SendMsgL( |
|
2688 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
2689 } |
|
2690 MPX_DEBUG1("CMPXPlaybackEngine::HandleNextL() exiting"); |
|
2691 } |
|
2692 |
|
2693 // ---------------------------------------------------------------------------- |
|
2694 // Handle previous command |
|
2695 // ---------------------------------------------------------------------------- |
|
2696 // |
|
2697 void CMPXPlaybackEngine::HandlePreviousL( |
|
2698 TInt aOffset /*= -1*/, |
|
2699 TBool aIgnoreRepeat /*=EFalse*/ ) |
|
2700 { |
|
2701 MPX_ASSERT(aOffset<0); |
|
2702 MPX_DEBUG2("CMPXPlaybackEngine::HandlePreviousL(%d) entering", aOffset); |
|
2703 EndSeek(); |
|
2704 if (EPlayFromCollection == iPlaySource && iPlaylist) |
|
2705 { |
|
2706 // Ignore command if playlist empty |
|
2707 if ( iPlaylist->Count() > 0 ) |
|
2708 { |
|
2709 // If first item in list and repeat is off, then replay the song |
|
2710 if ( 0 == iPlaylist->Index() && |
|
2711 CMPXCollectionPlaylist::ERepeatOff == iPlaylist->RepeatMode() ) |
|
2712 { |
|
2713 if ( EPbStatePlaying == iState || |
|
2714 EPbStatePaused == iState ) |
|
2715 { |
|
2716 HandleReplayL(); |
|
2717 } |
|
2718 } |
|
2719 else |
|
2720 { |
|
2721 aOffset = -aOffset; |
|
2722 while (aOffset-->0) |
|
2723 { |
|
2724 if (!iPlaylist->Previous( aIgnoreRepeat )) |
|
2725 { |
|
2726 HandleStopL(); |
|
2727 break; |
|
2728 } |
|
2729 } |
|
2730 MediaFromCollectionL(); |
|
2731 } |
|
2732 } |
|
2733 } |
|
2734 else |
|
2735 { |
|
2736 HandleStopL(); |
|
2737 } |
|
2738 MPX_DEBUG1("CMPXPlaybackEngine::HandlePreviousL() exiting"); |
|
2739 } |
|
2740 |
|
2741 // ---------------------------------------------------------------------------- |
|
2742 // Handle replay command |
|
2743 // ---------------------------------------------------------------------------- |
|
2744 // |
|
2745 void CMPXPlaybackEngine::HandleReplayL() |
|
2746 { |
|
2747 MPX_DEBUG1("CMPXPlaybackEngine::HandleReplayL(): entering"); |
|
2748 EndSeek(); |
|
2749 iProperties[EPbPropertyPosition] = 0; |
|
2750 if ( PluginL() ) |
|
2751 { |
|
2752 TMPXPlaybackState prevState( iState ); |
|
2753 if ( iState == EPbStatePlaying ) |
|
2754 { |
|
2755 // Need to send pause command to plugin first so that it will |
|
2756 // not keep playing the rest of it's buffer |
|
2757 MPX_DEBUG1("CMPXPlaybackEngine::HandleReplayL() send pause command"); |
|
2758 iState = EPbStatePaused; |
|
2759 PluginL()->CommandL(EPbCmdPause); |
|
2760 } |
|
2761 PluginL()->SetL(EPbPropertyPosition, |
|
2762 iProperties[EPbPropertyPosition]); |
|
2763 if ( prevState == EPbStatePlaying ) |
|
2764 { |
|
2765 PluginL()->CommandL(EPbCmdPlay); |
|
2766 } |
|
2767 } |
|
2768 MPX_DEBUG1("CMPXPlaybackEngine::HandleReplayL(): exiting"); |
|
2769 } |
|
2770 |
|
2771 // ---------------------------------------------------------------------------- |
|
2772 // Handle start seeking command |
|
2773 // ---------------------------------------------------------------------------- |
|
2774 // |
|
2775 void CMPXPlaybackEngine::HandleStartSeekL(TBool aForward) |
|
2776 { |
|
2777 MPX_DEBUG1("CMPXPlaybackEngine::HandleStartSeekL(): entering"); |
|
2778 if (iState==EPbStatePlaying || |
|
2779 iState==EPbStatePaused || |
|
2780 iState==EPbStateSeekingForward || |
|
2781 iState==EPbStateSeekingBackward) |
|
2782 { |
|
2783 Suspend(); |
|
2784 if (iState != EPbStateSeekingForward && |
|
2785 iState != EPbStateSeekingBackward) |
|
2786 { |
|
2787 iNextState = iState; |
|
2788 } |
|
2789 |
|
2790 SetStateL(aForward?EPbStateSeekingForward:EPbStateSeekingBackward); |
|
2791 |
|
2792 PluginL()->CommandL(EPbCmdPause); |
|
2793 |
|
2794 TCallBack cb(SeekTimerCallback,this); |
|
2795 iSeekStep = aForward ? KPbInitialSeekStepMilliSeconds : |
|
2796 -KPbInitialSeekStepMilliSeconds; |
|
2797 if ( iSeekTimer->IsActive() ) |
|
2798 iSeekTimer->Cancel(); |
|
2799 iSeekTimer->Start(KPbSeekIntervalMicroSeconds, |
|
2800 KPbSeekIntervalMicroSeconds, cb); |
|
2801 MPX_DEBUG2("CMPXPlaybackEngine sends msg EStateChanged to %d", iState); |
|
2802 iClientList->SendMsgL( |
|
2803 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
2804 } |
|
2805 MPX_DEBUG1("CMPXPlaybackEngine::HandleStartSeekL(): exiting"); |
|
2806 } |
|
2807 |
|
2808 // ---------------------------------------------------------------------------- |
|
2809 // Handle stop seeking command |
|
2810 // ---------------------------------------------------------------------------- |
|
2811 // |
|
2812 void CMPXPlaybackEngine::HandleStopSeekingL() |
|
2813 { |
|
2814 MPX_DEBUG1("CMPXPlaybackEngine::HandleStopSeekingL(): entering"); |
|
2815 |
|
2816 // Only perform actions if we are currently in seeking state |
|
2817 if (iState == EPbStateSeekingForward || |
|
2818 iState == EPbStateSeekingBackward) |
|
2819 { |
|
2820 EndSeek(); |
|
2821 if (EPbStateNotInitialised == iPluginState && |
|
2822 EPlayFromCollection == iPlaySource ) |
|
2823 { |
|
2824 iPreservedPosition = iProperties[EPbPropertyPosition]; |
|
2825 MediaFromCollectionL(); |
|
2826 } |
|
2827 else |
|
2828 { |
|
2829 PluginL()->SetL(EPbPropertyPosition,iProperties[EPbPropertyPosition]); |
|
2830 iState = iNextState; |
|
2831 switch ( iState ) |
|
2832 { |
|
2833 case EPbStatePlaying: |
|
2834 { |
|
2835 iClientList->SendMsgL( // update UI icons |
|
2836 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
2837 PluginL()->CommandL( EPbCmdPlay ); |
|
2838 break; |
|
2839 } |
|
2840 case EPbStatePaused: |
|
2841 { |
|
2842 iClientList->SendMsgL( // update UI icons |
|
2843 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged,iState)); |
|
2844 break; |
|
2845 } |
|
2846 default: |
|
2847 break; |
|
2848 } |
|
2849 } |
|
2850 } |
|
2851 MPX_DEBUG1("CMPXPlaybackEngine::HandleStopSeekingL(): exiting"); |
|
2852 } |
|
2853 |
|
2854 // ---------------------------------------------------------------------------- |
|
2855 // Handle increase volume command |
|
2856 // ---------------------------------------------------------------------------- |
|
2857 // |
|
2858 void CMPXPlaybackEngine::HandleIncreaseVolumeL() |
|
2859 { |
|
2860 TInt level( iProperties[EPbPropertyVolume] ); |
|
2861 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
2862 // if we already rounded up last time, don't have to increase, |
|
2863 // reset flag |
|
2864 if (!iVolRoundedUp) |
|
2865 { |
|
2866 level += iVolumeIncrement; |
|
2867 } |
|
2868 #else |
|
2869 level += iVolumeIncrement; |
|
2870 #endif |
|
2871 // Ensure that level is within min and max values |
|
2872 if (level > KPbPlaybackVolumeLevelMax) |
|
2873 { |
|
2874 level = KPbPlaybackVolumeLevelMax; |
|
2875 } |
|
2876 if (level < KPbPlaybackVolumeLevelMin) |
|
2877 { |
|
2878 level = KPbPlaybackVolumeLevelMin; |
|
2879 } |
|
2880 |
|
2881 SetL(EPbPropertyVolume, level); |
|
2882 } |
|
2883 |
|
2884 // ---------------------------------------------------------------------------- |
|
2885 // Handle decrease volume command |
|
2886 // ---------------------------------------------------------------------------- |
|
2887 // |
|
2888 void CMPXPlaybackEngine::HandleDecreaseVolumeL() |
|
2889 { |
|
2890 TInt level( iProperties[EPbPropertyVolume] - iVolumeIncrement ); |
|
2891 |
|
2892 // Ensure that level is within min and max values |
|
2893 if (level > KPbPlaybackVolumeLevelMax) |
|
2894 { |
|
2895 level = KPbPlaybackVolumeLevelMax; |
|
2896 } |
|
2897 if (level < KPbPlaybackVolumeLevelMin) |
|
2898 { |
|
2899 level = KPbPlaybackVolumeLevelMin; |
|
2900 } |
|
2901 |
|
2902 SetL(EPbPropertyVolume, level); |
|
2903 } |
|
2904 |
|
2905 // ---------------------------------------------------------------------------- |
|
2906 // Handle set volume command |
|
2907 // ---------------------------------------------------------------------------- |
|
2908 // |
|
2909 void CMPXPlaybackEngine::HandleSetVolumeL(TInt aVolume) |
|
2910 { |
|
2911 TInt level = aVolume; |
|
2912 |
|
2913 // Ensure that level is within min and max values |
|
2914 if (level > KPbPlaybackVolumeLevelMax) |
|
2915 { |
|
2916 level = KPbPlaybackVolumeLevelMax; |
|
2917 } |
|
2918 if (level < KPbPlaybackVolumeLevelMin) |
|
2919 { |
|
2920 level = KPbPlaybackVolumeLevelMin; |
|
2921 } |
|
2922 |
|
2923 SetL(EPbPropertyVolume, level); |
|
2924 } |
|
2925 |
|
2926 // ---------------------------------------------------------------------------- |
|
2927 // Handle mute command |
|
2928 // ---------------------------------------------------------------------------- |
|
2929 // |
|
2930 void CMPXPlaybackEngine::HandleMuteL(TBool aMute) |
|
2931 { |
|
2932 SetL(EPbPropertyMute, aMute); |
|
2933 } |
|
2934 |
|
2935 // ---------------------------------------------------------------------------- |
|
2936 // Handle close command |
|
2937 // ---------------------------------------------------------------------------- |
|
2938 // |
|
2939 void CMPXPlaybackEngine::HandleCloseL( TInt aData ) |
|
2940 { |
|
2941 MPX_DEBUG1("CMPXPlaybackEngine::HandleCloseL(): entering"); |
|
2942 if (iPluginHandler->Plugin()) |
|
2943 { |
|
2944 TRAP_IGNORE(DoStopL()); |
|
2945 iNextState = EPbStateNotInitialised; |
|
2946 TRAP_IGNORE(iPluginHandler->Plugin()->CommandL(EPbCmdClose, aData)); |
|
2947 DoClose(); |
|
2948 } |
|
2949 if (iInitializer) |
|
2950 { |
|
2951 iInitializer->Close(); |
|
2952 } |
|
2953 MPX_DEBUG1("CMPXPlaybackEngine::HandleCloseL(): exiting"); |
|
2954 } |
|
2955 |
|
2956 // ---------------------------------------------------------------------------- |
|
2957 // Handle a custom command |
|
2958 // ---------------------------------------------------------------------------- |
|
2959 // |
|
2960 void CMPXPlaybackEngine::HandleEffectL(TInt aData) |
|
2961 { |
|
2962 MPX_FUNC_EX("CMPXPlaybackEngine::HandleEffectL()"); |
|
2963 if(iPluginHandler->Plugin()) |
|
2964 { |
|
2965 iPluginHandler->Plugin()->CommandL(EPbApplyEffect, aData); |
|
2966 } |
|
2967 } |
|
2968 |
|
2969 // ---------------------------------------------------------------------------- |
|
2970 // Handle a custom command |
|
2971 // ---------------------------------------------------------------------------- |
|
2972 // |
|
2973 void CMPXPlaybackEngine::HandleDisableEffectL() |
|
2974 { |
|
2975 MPX_FUNC_EX("CMPXPlaybackEngine::HandleDisableEffectL()"); |
|
2976 if(iPluginHandler->Plugin()) |
|
2977 { |
|
2978 iPluginHandler->Plugin()->CommandL(EPbCmdDisableEffect); |
|
2979 } |
|
2980 } |
|
2981 |
|
2982 // ---------------------------------------------------------------------------- |
|
2983 // Handle request to close a specific item |
|
2984 // ---------------------------------------------------------------------------- |
|
2985 // |
|
2986 void CMPXPlaybackEngine::HandleCloseItemL( TInt aItemId ) |
|
2987 { |
|
2988 MPX_FUNC_EX("CMPXPlaybackEngine::HandleCloseItemL()"); |
|
2989 |
|
2990 if( iPlaylist ) |
|
2991 { |
|
2992 // If the item is currently in play, close playback or |
|
2993 // if item is currently in the initializer |
|
2994 if( iPlaylist->Path().Id().ApproxEqual( aItemId ) ) |
|
2995 { |
|
2996 HandleStopL(); |
|
2997 } |
|
2998 else if(iInitializer) |
|
2999 { |
|
3000 TInt nextIndex; |
|
3001 TBool repeatMode; |
|
3002 repeatMode = iPlaylist->RepeatMode(); |
|
3003 TBool nextFound = iPlaylist->NextIndex( repeatMode, nextIndex ); |
|
3004 TMPXItemId nextItemId = iPlaylist->Path().IdOfIndex( nextIndex ); |
|
3005 |
|
3006 if((iInitializer->CurrentInitItemId().iId2 == aItemId) || |
|
3007 ( iInitNext && nextFound && nextItemId.ApproxEqual( aItemId ))) |
|
3008 { |
|
3009 iInitializer->Close(); |
|
3010 } |
|
3011 } |
|
3012 } |
|
3013 } |
|
3014 |
|
3015 // ---------------------------------------------------------------------------- |
|
3016 // Sets the plug-in properties |
|
3017 // ---------------------------------------------------------------------------- |
|
3018 // |
|
3019 void CMPXPlaybackEngine::SetPropertiesL() |
|
3020 { |
|
3021 MPX_FUNC_EX("CMPXPlaybackEngine::SetPropertiesL()"); |
|
3022 iMaxSeekStep = iProperties[EPbPropertyDuration]/KPercentMultiplier*KPbMaxSeekStepPercent; |
|
3023 MPX_DEBUG2("CMPXPlaybackEngine::SetPropertiesL(): iMediaDuration = %d", iMediaDuration); |
|
3024 MPX_DEBUG2("CMPXPlaybackEngine::SetPropertiesL(): iProperties[EPbPropertyDuration] = %d", iProperties[EPbPropertyDuration]); |
|
3025 if ( Abs(iMediaDuration - iProperties[EPbPropertyDuration]) > |
|
3026 KPbDurationChangeThreshold ) |
|
3027 { |
|
3028 MPX_DEBUG1("CMPXPlaybackEngine::SetPropertiesL(): Duration not equal"); |
|
3029 // Set duration if it's different than what collection has |
|
3030 if ( iPlaylist) |
|
3031 { |
|
3032 if ( iPlaylist->Count() && !iPlaylist->EmbeddedPlaylist() ) |
|
3033 { |
|
3034 MPX_DEBUG1("CMPXPlaybackEngine::SetPropertiesL(): Setting duration"); |
|
3035 CMPXMedia* media( CreateMediaToSetLC( iPlaylist->Path() )); |
|
3036 |
|
3037 iMediaDuration = iProperties[EPbPropertyDuration]; |
|
3038 media->SetTObjectValueL( KMPXMediaGeneralDuration, |
|
3039 iProperties[EPbPropertyDuration] ); |
|
3040 iPlaylist->SetL( *media ); |
|
3041 CleanupStack::PopAndDestroy( media ); |
|
3042 } |
|
3043 } |
|
3044 } |
|
3045 } |
|
3046 |
|
3047 // ---------------------------------------------------------------------------- |
|
3048 // Stop seeking timer |
|
3049 // ---------------------------------------------------------------------------- |
|
3050 // |
|
3051 void CMPXPlaybackEngine::EndSeek() |
|
3052 { |
|
3053 if (iSeekTimer) |
|
3054 { |
|
3055 iSeekTimer->Cancel(); |
|
3056 } |
|
3057 } |
|
3058 |
|
3059 // ---------------------------------------------------------------------------- |
|
3060 // Set playback state |
|
3061 // ---------------------------------------------------------------------------- |
|
3062 // |
|
3063 void CMPXPlaybackEngine::SetStateL(TMPXPlaybackState aState) |
|
3064 { |
|
3065 MPX_DEBUG2("CMPXPlaybackEngine::SetStateL(%d): entering", aState); |
|
3066 |
|
3067 TMPXPlaybackMessage msg( TMPXPlaybackMessage::EStateChanged, |
|
3068 aState ); |
|
3069 SetStateL( msg ); |
|
3070 MPX_DEBUG1("CMPXPlaybackEngine::SetStateL(): exiting"); |
|
3071 } |
|
3072 |
|
3073 // ---------------------------------------------------------------------------- |
|
3074 // Set playback state |
|
3075 // ---------------------------------------------------------------------------- |
|
3076 // |
|
3077 void CMPXPlaybackEngine::SetStateL( TMPXPlaybackMessage& aMsg ) |
|
3078 { |
|
3079 MPX_DEBUG1("CMPXPlaybackEngine::SetStateL(aMsg): entering"); |
|
3080 |
|
3081 TMPXPlaybackState state( static_cast<TMPXPlaybackState>( aMsg.Type() )); |
|
3082 MPX_DEBUG2("CMPXPlaybackEngine::SetStateL(): state = %d", state); |
|
3083 |
|
3084 if ( state!=iState ) |
|
3085 { |
|
3086 iState = state; |
|
3087 iAutoResumeHandler->HandlePlaybackStateChange( iState ); |
|
3088 MPX_DEBUG2("CMPXPlaybackEngine sends msg EStateChanged to %d", iState); |
|
3089 iClientList->SendMsgL( aMsg ); |
|
3090 } |
|
3091 // Restart progress timer |
|
3092 if (EPbStatePlaying == iState && !iProgressTimer->IsActive()) |
|
3093 { |
|
3094 iProgressTimer->Start(ETwelveOClock,this); |
|
3095 } |
|
3096 MPX_DEBUG1("CMPXPlaybackEngine::SetStateL(aMsg): exiting"); |
|
3097 } |
|
3098 |
|
3099 // ---------------------------------------------------------------------------- |
|
3100 // Set player activated |
|
3101 // ---------------------------------------------------------------------------- |
|
3102 // |
|
3103 void CMPXPlaybackEngine::SetPlayerActivated(TBool aActive) |
|
3104 { |
|
3105 MPX_DEBUG3("CMPXPlaybackEngine::SetPlayerActivated old = %d, new = %d", |
|
3106 iPlayerActive, aActive); |
|
3107 if (iPlayerActive != aActive) |
|
3108 { |
|
3109 iPlayerActive = aActive; |
|
3110 // triggle clients to update playback state |
|
3111 TRAP_IGNORE(iClientList->SendMsgL( |
|
3112 TMPXPlaybackMessage(TMPXPlaybackMessage::EStateChanged, iState))); |
|
3113 MPX_DEBUG1("Playback Engine notify server active player chnaged."); |
|
3114 TRAP_IGNORE(iObserver.HandleActiveEngineL(this, iPlayerActive)); |
|
3115 } |
|
3116 MPX_DEBUG1("CMPXPlaybackEngine::SetPlayerActivated(): exiting"); |
|
3117 } |
|
3118 |
|
3119 // ---------------------------------------------------------------------------- |
|
3120 // Execute a async task |
|
3121 // ---------------------------------------------------------------------------- |
|
3122 // |
|
3123 void CMPXPlaybackEngine::ExecuteTask( |
|
3124 TInt aTask, |
|
3125 TInt aParamData, |
|
3126 TAny* aPtrData, |
|
3127 const CBufBase& aBuf, |
|
3128 TAny* aCallback, |
|
3129 CBase* aCObject1, |
|
3130 CBase* aCObject2) |
|
3131 { |
|
3132 TRAPD(err, ExecuteTaskL(aTask, aParamData, aPtrData, |
|
3133 aCallback, aBuf, aCObject1, aCObject2)); |
|
3134 if (KErrNone != err) |
|
3135 { |
|
3136 HandleError(aTask, err, aParamData); |
|
3137 } |
|
3138 } |
|
3139 |
|
3140 // ---------------------------------------------------------------------------- |
|
3141 // Indicates that a task was terminated with an error. |
|
3142 // This will be called in case of a plugin update/removal. |
|
3143 // ---------------------------------------------------------------------------- |
|
3144 // |
|
3145 void CMPXPlaybackEngine::HandleTaskError( |
|
3146 TInt aTask, |
|
3147 TAny* /*aPtrData*/, |
|
3148 TAny* /*aCallback*/, |
|
3149 TInt aError) |
|
3150 { |
|
3151 MPX_FUNC("CMPXCollectionClientContext::HandleTaskError"); |
|
3152 HandleError(aTask, aError); |
|
3153 } |
|
3154 |
|
3155 // ---------------------------------------------------------------------------- |
|
3156 // Execute a async task |
|
3157 // ---------------------------------------------------------------------------- |
|
3158 // |
|
3159 void CMPXPlaybackEngine::ExecuteTaskL( |
|
3160 TInt aTask, |
|
3161 TInt aParamData, |
|
3162 TAny* aPtrData, |
|
3163 TAny* aCallback, |
|
3164 const CBufBase& /*aBuf*/, |
|
3165 CBase* aCObject1, |
|
3166 CBase* /*aCObject2*/) |
|
3167 { |
|
3168 MPX_DEBUG5("-->CMPXPlaybackEngine::ExecuteTaskL 0x%08x cb 0x%08x (%d, %d)", |
|
3169 this, aCallback, aTask, aParamData); |
|
3170 if ( aTask != EHandleNext ) |
|
3171 { |
|
3172 ASSERT(aCallback); |
|
3173 iCallback = static_cast<MMPXPlaybackEngineObserver*>(aCallback); |
|
3174 } |
|
3175 CMPXPlaybackPlugin* p = aPtrData ? |
|
3176 static_cast<CMPXPlaybackPlugin*>(aPtrData) : |
|
3177 iPluginHandler->Plugin(); |
|
3178 switch(aTask) |
|
3179 { |
|
3180 case EProperty: |
|
3181 { |
|
3182 CheckPtrL(p); |
|
3183 p->PropertyL(static_cast<TMPXPlaybackProperty>(aParamData)); |
|
3184 break; |
|
3185 } |
|
3186 case EMedia: |
|
3187 { |
|
3188 iMediaAttrs.Reset(); |
|
3189 CMPXCommand* cmd( static_cast<CMPXAttributeSpecs*>(aCObject1)); |
|
3190 const TDesC& attr = cmd->ValueText( KMPXCommandMediaAttribute ); |
|
3191 TPtrC8 ptr = MPXUser::Ptr( attr ); |
|
3192 RDesReadStream readStream( ptr ); |
|
3193 CleanupClosePushL( readStream ); |
|
3194 // Internalize attributes |
|
3195 ::InternalizeL( iMediaAttrs, readStream ); |
|
3196 CleanupStack::PopAndDestroy( &readStream ); |
|
3197 CheckPtrL( p ); |
|
3198 TMPXPlaybackState state(State()); |
|
3199 if (( EPbStateInitialising == state || |
|
3200 EPbStatePlaying == state || |
|
3201 EPbStatePaused == state || |
|
3202 EPbStateStopped == state || |
|
3203 EPbStateBuffering == state || |
|
3204 EPbStateDownloading == state || |
|
3205 EPbStateInitialised == state )) |
|
3206 { |
|
3207 CMPXAttributeSpecs* specs( NULL ); |
|
3208 if ( cmd->IsSupported( KMPXCommandMediaAttributeSpecs ) ) |
|
3209 { |
|
3210 specs = cmd->Value<CMPXAttributeSpecs>( KMPXCommandMediaAttributeSpecs ); |
|
3211 User::LeaveIfNull(specs); |
|
3212 } |
|
3213 p->MediaL( iMediaAttrs.Array(), specs ); |
|
3214 } |
|
3215 else |
|
3216 { |
|
3217 CMPXMedia *media = CMPXMedia::NewL(); |
|
3218 CleanupStack::PushL(media); |
|
3219 media->SetTObjectValueL(KMPXMediaColDetailMediaNotAvailable, |
|
3220 ETrue); |
|
3221 HandleMedia(media, KErrNone); |
|
3222 CleanupStack::PopAndDestroy(media); |
|
3223 } |
|
3224 } |
|
3225 break; |
|
3226 case ESubPlayerNames: |
|
3227 { |
|
3228 CheckPtrL(p); |
|
3229 p->SubPlayerNamesL(); |
|
3230 break; |
|
3231 } |
|
3232 case EHandleNext: |
|
3233 { |
|
3234 HandleNextL(); |
|
3235 if( iPlaylist ) |
|
3236 { |
|
3237 iClientList->SendMsgL(TMPXPlaybackMessage( |
|
3238 TMPXPlaybackMessage::EMediaChanged)); |
|
3239 } |
|
3240 SetStateL( iState ); |
|
3241 iTaskQueue->CompleteTask(); |
|
3242 break; |
|
3243 } |
|
3244 default: |
|
3245 ASSERT(0); |
|
3246 } |
|
3247 MPX_DEBUG4("<--CMPXPlaybackEngine::ExecuteTaskL 0x%08x (%d, %d): Exiting", |
|
3248 this, aTask, aParamData); |
|
3249 } |
|
3250 |
|
3251 // ---------------------------------------------------------------------------- |
|
3252 // Error happens upon request |
|
3253 // ---------------------------------------------------------------------------- |
|
3254 // |
|
3255 void CMPXPlaybackEngine::HandleError( |
|
3256 TInt aTask, |
|
3257 TInt aError, |
|
3258 TInt aParamData /* = 0 */) |
|
3259 { |
|
3260 MPX_DEBUG3("-->CMPXPlaybackEngine::HandleError() 0x%08x: aError %d", this, aError); |
|
3261 switch (aTask) |
|
3262 { |
|
3263 case EProperty: |
|
3264 iCallback->HandleProperty( |
|
3265 static_cast<TMPXPlaybackProperty>(aParamData), |
|
3266 0,aError); |
|
3267 iCallback = NULL; |
|
3268 break; |
|
3269 case EMedia: |
|
3270 { |
|
3271 iCallback->HandleMedia(NULL, aError); |
|
3272 iCallback = NULL; |
|
3273 } |
|
3274 break; |
|
3275 case ESubPlayerNames: |
|
3276 { |
|
3277 TUid piid=TUid::Uid(aParamData); |
|
3278 iCallback->HandleSubPlayerNames(piid, NULL, ETrue, aError); |
|
3279 iCallback = NULL; |
|
3280 } |
|
3281 break; |
|
3282 default: |
|
3283 ASSERT(0); |
|
3284 break; |
|
3285 } |
|
3286 iTaskQueue->CompleteTask(); |
|
3287 MPX_DEBUG3("<--CMPXPlaybackEngine::HandleError() 0x%08x: aError %d", this, aError); |
|
3288 } |
|
3289 |
|
3290 // ---------------------------------------------------------------------------- |
|
3291 // Get command from state |
|
3292 // ---------------------------------------------------------------------------- |
|
3293 // |
|
3294 TMPXPlaybackCommand CMPXPlaybackEngine::CommandFromState( |
|
3295 TMPXPlaybackState aState ) |
|
3296 { |
|
3297 MPX_DEBUG2("CMPXPlaybackEngine::CommandFromState(): aState %d", aState); |
|
3298 TMPXPlaybackCommand cmd(EPbCmdStop); |
|
3299 switch ( aState ) |
|
3300 { |
|
3301 case EPbStatePlaying: |
|
3302 cmd = EPbCmdPlay; |
|
3303 break; |
|
3304 case EPbStatePaused: |
|
3305 cmd = EPbCmdPause; |
|
3306 break; |
|
3307 case EPbStateStopped: |
|
3308 cmd = EPbCmdStop; |
|
3309 break; |
|
3310 default: |
|
3311 break; |
|
3312 } |
|
3313 return cmd; |
|
3314 } |
|
3315 |
|
3316 // ---------------------------------------------------------------------------- |
|
3317 // Do close |
|
3318 // ---------------------------------------------------------------------------- |
|
3319 // |
|
3320 void CMPXPlaybackEngine::DoClose() |
|
3321 { |
|
3322 MPX_FUNC_EX("CMPXPlaybackEngine::DoClose()"); |
|
3323 if (iTaskQueue) |
|
3324 { |
|
3325 iTaskQueue->CancelRequests(); |
|
3326 } |
|
3327 |
|
3328 iAutoResumeHandler->CancelResumeTimer(); |
|
3329 |
|
3330 if (iProgressTimer) |
|
3331 { |
|
3332 iProgressTimer->Cancel(); |
|
3333 } |
|
3334 |
|
3335 if (iSeekTimer) |
|
3336 { |
|
3337 iSeekTimer->Cancel(); |
|
3338 } |
|
3339 |
|
3340 iCmdBuffer->ClearCommands(); |
|
3341 |
|
3342 iFile.Close(); |
|
3343 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
3344 iFile64.Close(); |
|
3345 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
3346 delete iPlaylist; |
|
3347 iPlaylist = NULL; |
|
3348 delete iUri; |
|
3349 iUri = NULL; |
|
3350 iItemId = KMPXInvalidItemId; |
|
3351 iPlaySource = EPlayNone; |
|
3352 iState = EPbStateNotInitialised; |
|
3353 iNextState = EPbStateNotInitialised; |
|
3354 } |
|
3355 |
|
3356 // ---------------------------------------------------------------------------- |
|
3357 // URI from collection |
|
3358 // ---------------------------------------------------------------------------- |
|
3359 // |
|
3360 void CMPXPlaybackEngine::MediaFromCollectionL() |
|
3361 { |
|
3362 MPX_FUNC_EX("CMPXPlaybackEngine::MediaFromCollectionL"); |
|
3363 if (iInitNext) |
|
3364 { |
|
3365 iInitializer->Init(*iPlaylist); |
|
3366 iInitializer->SetActiveL(); |
|
3367 } |
|
3368 else |
|
3369 { |
|
3370 RArray<TMPXAttribute> attrs; |
|
3371 CleanupClosePushL(attrs); |
|
3372 attrs.AppendL(KMPXMediaGeneralId); |
|
3373 attrs.AppendL(KMPXMediaGeneralUri); |
|
3374 attrs.AppendL(KMPXMediaGeneralMimeType); |
|
3375 attrs.AppendL(KMPXMediaGeneralLastPlaybackPosition); |
|
3376 attrs.AppendL(KMPXMediaGeneralFlags); |
|
3377 |
|
3378 if (iPlaylist) ///in some cases this could be empty |
|
3379 { |
|
3380 iPlaylist->MediaL(attrs.Array(),*this); |
|
3381 } |
|
3382 |
|
3383 CleanupStack::PopAndDestroy(&attrs); |
|
3384 } |
|
3385 } |
|
3386 |
|
3387 // ---------------------------------------------------------------------------- |
|
3388 // Save playback position |
|
3389 // ---------------------------------------------------------------------------- |
|
3390 // |
|
3391 void CMPXPlaybackEngine::SavePlaybackInfoL() |
|
3392 { |
|
3393 MPX_DEBUG1("CMPXPlaybackEngine::SavePlaybackInfoL() entering"); |
|
3394 |
|
3395 if ( iPlaylist) |
|
3396 { |
|
3397 if (iPlaylist->Count() && !iPlaylist->EmbeddedPlaylist()) |
|
3398 { |
|
3399 CMPXMedia* media( CreateMediaToSetLC( iPlaylist->Path() )); |
|
3400 |
|
3401 // Save position, if at the end, then save position is 0 |
|
3402 // Due to timer callbacks, the current position may not be exactly |
|
3403 // at the same value as the duration, thus must give it a |
|
3404 // threshold to be within. |
|
3405 TInt savePosition( iProperties[EPbPropertyPosition] ); |
|
3406 if ( Abs( iProperties[EPbPropertyDuration] - savePosition ) < |
|
3407 KPbPositionChangeThreshold ) |
|
3408 { |
|
3409 savePosition = 0; |
|
3410 } |
|
3411 media->SetTObjectValueL( KMPXMediaGeneralLastPlaybackPosition, |
|
3412 savePosition ); |
|
3413 iPlaylist->SetL( *media ); |
|
3414 CleanupStack::PopAndDestroy(media); |
|
3415 } |
|
3416 } |
|
3417 |
|
3418 MPX_DEBUG1("CMPXPlaybackEngine::SavePlaybackInfoL() exiting"); |
|
3419 } |
|
3420 |
|
3421 // ---------------------------------------------------------------------------- |
|
3422 // Increments play count |
|
3423 // ---------------------------------------------------------------------------- |
|
3424 // |
|
3425 void CMPXPlaybackEngine::SavePlaybackCompleteInfoL() |
|
3426 { |
|
3427 MPX_DEBUG1("CMPXPlaybackEngine::SavePlaybackCompleteInfoL() entering"); |
|
3428 |
|
3429 if ( iPlaylist ) |
|
3430 { |
|
3431 if ( iPlaylist->Count() && !iPlaylist->EmbeddedPlaylist() ) |
|
3432 { |
|
3433 CMPXMedia* media( CreateMediaToSetLC( iPlaylist->Path() )); |
|
3434 |
|
3435 // Increment play count |
|
3436 // Collection implementation will increment count by the |
|
3437 // value provided |
|
3438 media->SetTObjectValueL( KMPXMediaGeneralPlayCount, |
|
3439 1 ); |
|
3440 |
|
3441 // reset the last playback position to 0 |
|
3442 media->SetTObjectValueL( KMPXMediaGeneralLastPlaybackPosition, |
|
3443 0 ); |
|
3444 |
|
3445 // Set last play time |
|
3446 TTime now; |
|
3447 now.UniversalTime(); |
|
3448 media->SetTObjectValueL(KMPXMediaGeneralLastPlaybackTime, |
|
3449 now.Int64() ); |
|
3450 |
|
3451 iPlaylist->SetL( *media ); |
|
3452 CleanupStack::PopAndDestroy( media ); |
|
3453 } |
|
3454 } |
|
3455 |
|
3456 MPX_DEBUG1("CMPXPlaybackEngine::SavePlaybackCompleteInfoL() exiting"); |
|
3457 } |
|
3458 |
|
3459 // ---------------------------------------------------------------------------- |
|
3460 // Restore playback position if it was saved previously |
|
3461 // ---------------------------------------------------------------------------- |
|
3462 // |
|
3463 void CMPXPlaybackEngine::RestorePlaybackPositionAndStateL( |
|
3464 const CMPXMedia& aMedia ) |
|
3465 { |
|
3466 MPX_DEBUG1("CMPXPlaybackEngine::RestorePlaybackPositionAndStateL() entering"); |
|
3467 |
|
3468 // Restore Position |
|
3469 iProperties[EPbPropertyPosition] = 0; |
|
3470 if ( KErrNotFound != iPreservedPosition ) |
|
3471 { |
|
3472 iProperties[EPbPropertyPosition] = iPreservedPosition; |
|
3473 iPreservedPosition = KErrNotFound; |
|
3474 } |
|
3475 else |
|
3476 { |
|
3477 // Check media |
|
3478 if (aMedia.IsSupported(KMPXMediaGeneralLastPlaybackPosition)) |
|
3479 { |
|
3480 iProperties[EPbPropertyPosition] = |
|
3481 aMedia.ValueTObjectL<TInt>( KMPXMediaGeneralLastPlaybackPosition ); |
|
3482 } |
|
3483 } |
|
3484 |
|
3485 // Restore State |
|
3486 if ( EPbStateNotInitialised != iPreservedState ) |
|
3487 { |
|
3488 iNextState = iPreservedState; |
|
3489 iPreservedState = EPbStateNotInitialised; |
|
3490 } |
|
3491 |
|
3492 MPX_DEBUG1("CMPXPlaybackEngine::RestorePlaybackPositionAndStateL() exiting"); |
|
3493 } |
|
3494 |
|
3495 // ---------------------------------------------------------------------------- |
|
3496 // Sets the volume increment depending on accessory state |
|
3497 // ---------------------------------------------------------------------------- |
|
3498 // |
|
3499 void CMPXPlaybackEngine::SetVolumeIncrement( TMPXPlaybackAccessoryMode aMode ) |
|
3500 { |
|
3501 MPX_DEBUG2("CMPXPlaybackEngine::SetVolumeIncrement(%d) entering", aMode); |
|
3502 |
|
3503 switch ( aMode ) |
|
3504 { |
|
3505 #ifdef __ACCESSORY_FW |
|
3506 case EPbAccessoryWiredHeadset: |
|
3507 case EPbAccessoryHeadphones: |
|
3508 #else |
|
3509 case EPbAccessoryHeadset: |
|
3510 #endif // __ACCESSORY_FW |
|
3511 { |
|
3512 // twentysteps start |
|
3513 |
|
3514 // check whether we are playing WMA files, if so the increment has to be KMPXLargeVolumeIncrement |
|
3515 if(iUri) |
|
3516 { |
|
3517 //MPX_DEBUG1("still alive one !!!!"); |
|
3518 TParsePtrC parser(*iUri); |
|
3519 |
|
3520 MPX_DEBUG2("CMPXPlaybackEngine::SetVolumeIncrement(): iUri is %S", iUri); |
|
3521 |
|
3522 if (parser.Ext().CompareF(KWmaExtension) == 0 || parser.Ext().CompareF(KRaExtension) == 0 ) |
|
3523 { |
|
3524 iVolumeIncrement = KMPXLargeVolumeIncrement; |
|
3525 } |
|
3526 else |
|
3527 { |
|
3528 iVolumeIncrement = KMPXSmallVolumeIncrement; |
|
3529 } |
|
3530 } |
|
3531 else |
|
3532 { |
|
3533 MPX_DEBUG1("CMPXPlaybackEngine::SetVolumeIncrement iUri is NULL"); |
|
3534 iVolumeIncrement = KMPXSmallVolumeIncrement; |
|
3535 } |
|
3536 |
|
3537 MPX_DEBUG2("CMPXPlaybackEngine::SetVolumeIncrement(): Headset is inserted, increment is %d", iVolumeIncrement); |
|
3538 // twentysteps end |
|
3539 // uncomment this when twentysteps is removed iVolumeIncrement = KMPXSmallVolumeIncrement; |
|
3540 break; |
|
3541 } |
|
3542 default: |
|
3543 { |
|
3544 // for everything else check what is the current volume value |
|
3545 // and if an not an interval of KMPXLargeVolumeIncrement, |
|
3546 // which could be the case if the last |
|
3547 // time user listened to music and wired headset was plugged in, |
|
3548 // then convert the value used to an increment of KMPXLargeVolumeIncrement. |
|
3549 MPX_DEBUG2("CMPXPlaybackEngine::SetVolumeIncrement(): NOT a headset, increment is %d", KMPXLargeVolumeIncrement); |
|
3550 iVolumeIncrement = KMPXLargeVolumeIncrement; |
|
3551 if ( iProperties[EPbPropertyVolume] > KPbPlaybackVolumeLevelMin && |
|
3552 iProperties[EPbPropertyVolume] < KPbPlaybackVolumeLevelMax) |
|
3553 { |
|
3554 #if defined(__HIGH_RESOLUTION_VOLUME) |
|
3555 // if we will round up the volume to next increment of 10, set the flag |
|
3556 // so when the headset is unplugged, we just increment it again. |
|
3557 if (iProperties[EPbPropertyVolume] % KMPXLargeVolumeIncrement) |
|
3558 { |
|
3559 iVolRoundedUp = ETrue; |
|
3560 } |
|
3561 #endif |
|
3562 while ( iProperties[EPbPropertyVolume] % KMPXLargeVolumeIncrement && |
|
3563 iProperties[EPbPropertyVolume] <= KPbPlaybackVolumeLevelMax ) |
|
3564 { |
|
3565 // increase volume until it's a valid increment of KMPXLargeVolumeIncrement |
|
3566 iProperties[EPbPropertyVolume]++; |
|
3567 } |
|
3568 } |
|
3569 break; |
|
3570 } |
|
3571 } |
|
3572 |
|
3573 MPX_DEBUG1("CMPXPlaybackEngine::SetVolumeIncrement() exiting"); |
|
3574 } |
|
3575 |
|
3576 // ---------------------------------------------------------------------------- |
|
3577 // Marks the current item as corrupted |
|
3578 // ---------------------------------------------------------------------------- |
|
3579 // |
|
3580 void CMPXPlaybackEngine::MarkItemCorrupted( const TBool aCorrupted ) |
|
3581 { |
|
3582 MPX_DEBUG2("CMPXPlaybackEngine::MarkItemCorrupted(%d) entering", aCorrupted); |
|
3583 |
|
3584 TRAP_IGNORE( SetFlagBitsL( aCorrupted, KMPXMediaGeneralFlagsIsCorrupted )); |
|
3585 |
|
3586 MPX_DEBUG1("CMPXPlaybackEngine::MarkItemCorrupted() exiting"); |
|
3587 } |
|
3588 |
|
3589 // ---------------------------------------------------------------------------- |
|
3590 // Marks the current item as invalid |
|
3591 // ---------------------------------------------------------------------------- |
|
3592 // |
|
3593 void CMPXPlaybackEngine::MarkItemInvalid( const TBool aInvalid ) |
|
3594 { |
|
3595 MPX_DEBUG2("CMPXPlaybackEngine::MarkItemInvalid(%d) entering", aInvalid); |
|
3596 |
|
3597 TRAP_IGNORE( SetFlagBitsL( aInvalid, KMPXMediaGeneralFlagsIsInvalid )); |
|
3598 |
|
3599 MPX_DEBUG1("CMPXPlaybackEngine::MarkItemInvalid() exiting"); |
|
3600 } |
|
3601 |
|
3602 // ---------------------------------------------------------------------------- |
|
3603 // Marks the current item as DRM invalid |
|
3604 // ---------------------------------------------------------------------------- |
|
3605 // |
|
3606 void CMPXPlaybackEngine::MarkItemDrmInvalid( const TBool aDrmInvalid ) |
|
3607 { |
|
3608 MPX_DEBUG2("CMPXPlaybackEngine::MarkItemDrmInvalid(%d) entering", aDrmInvalid); |
|
3609 |
|
3610 TRAP_IGNORE( SetFlagBitsL( aDrmInvalid, KMPXMediaGeneralFlagsIsDrmLicenceInvalid )); |
|
3611 |
|
3612 MPX_DEBUG1("CMPXPlaybackEngine::MarkItemDrmInvalid() exiting"); |
|
3613 } |
|
3614 |
|
3615 // ---------------------------------------------------------------------------- |
|
3616 // Sets flag bits |
|
3617 // ---------------------------------------------------------------------------- |
|
3618 // |
|
3619 void CMPXPlaybackEngine::SetFlagBitsL( |
|
3620 const TBool aSet, |
|
3621 const TUint aFlag ) |
|
3622 { |
|
3623 MPX_DEBUG3("CMPXPlaybackEngine::SetFlagBitsL(%d, %d) entering", aSet, aFlag); |
|
3624 |
|
3625 if ( iPlaylist) |
|
3626 { |
|
3627 if (iPlaylist->Count() && !iPlaylist->EmbeddedPlaylist()) |
|
3628 { |
|
3629 CMPXMedia* media( CreateMediaToSetLC( iPlaylist->Path() )); |
|
3630 |
|
3631 // Set flag |
|
3632 TUint flag( 0 ); |
|
3633 if ( aSet ) |
|
3634 { |
|
3635 flag = KMPXMediaGeneralFlagsSetOrUnsetBit; |
|
3636 } |
|
3637 flag |= aFlag; |
|
3638 media->SetTObjectValueL( KMPXMediaGeneralFlags, |
|
3639 flag ); |
|
3640 iPlaylist->SetL( *media ); |
|
3641 CleanupStack::PopAndDestroy( media ); |
|
3642 } |
|
3643 } |
|
3644 |
|
3645 MPX_DEBUG1("CMPXPlaybackEngine::SetFlagBitsL() exiting"); |
|
3646 } |
|
3647 |
|
3648 // ---------------------------------------------------------------------------- |
|
3649 // Creates a CMPXMedia object to be used to Set attributes |
|
3650 // ---------------------------------------------------------------------------- |
|
3651 // |
|
3652 CMPXMedia* CMPXPlaybackEngine::CreateMediaToSetLC( const CMPXCollectionPath& aPath ) |
|
3653 { |
|
3654 MPX_DEBUG1("-->CMPXPlaybackEngine::CreateMediaToSetLC()"); |
|
3655 |
|
3656 // Create new Media object to set |
|
3657 CMPXMedia* media = CMPXMedia::NewL(); |
|
3658 CleanupStack::PushL(media); |
|
3659 media->SetTObjectValueL( KMPXMediaGeneralType, |
|
3660 EMPXItem ); |
|
3661 media->SetTObjectValueL( KMPXMediaGeneralCategory, |
|
3662 EMPXSong ); |
|
3663 media->SetTObjectValueL( KMPXMediaGeneralCollectionId, |
|
3664 aPath.Id( CMPXCollectionPath::ECollectionUid )); |
|
3665 |
|
3666 if (iItemId != KMPXInvalidItemId) |
|
3667 { |
|
3668 media->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, iItemId); |
|
3669 } |
|
3670 else if (iUri) |
|
3671 { |
|
3672 media->SetTextValueL( KMPXMediaGeneralUri, *iUri); |
|
3673 } |
|
3674 else |
|
3675 { |
|
3676 media->SetTObjectValueL<TMPXItemId>( KMPXMediaGeneralId , aPath.Id() ); |
|
3677 } |
|
3678 MPX_DEBUG1("<--CMPXPlaybackEngine::CreateMediaToSetLC()"); |
|
3679 return media; |
|
3680 } |
|
3681 |
|
3682 // ---------------------------------------------------------------------------- |
|
3683 // Sends a request to iMediaHelper to request media |
|
3684 // ---------------------------------------------------------------------------- |
|
3685 // |
|
3686 void CMPXPlaybackEngine::RequestMediaL() |
|
3687 { |
|
3688 MPX_FUNC( "CMPXPlaybackEngine::RequestMediaL" ); |
|
3689 CMPXCommand* cmd = CMPXCommand::NewL(); |
|
3690 CleanupStack::PushL( cmd ); |
|
3691 cmd->SetTObjectValueL<TInt>(KMPXCommandGeneralId, KMPXCommandContentIdMedia); |
|
3692 CBufBase* buf = CBufFlat::NewL( KMPXBufGranularity ); |
|
3693 CleanupStack::PushL( buf ); |
|
3694 |
|
3695 // Setup array buffer |
|
3696 RArray<TMPXAttribute> attrs; |
|
3697 CleanupClosePushL( attrs ); |
|
3698 attrs.AppendL( KMPXMediaGeneralBasic ); |
|
3699 attrs.AppendL( KMPXMediaGeneralUri ); |
|
3700 attrs.AppendL( KMPXMediaMusicAlbumArtFileName ); |
|
3701 attrs.AppendL( KMPXMediaMusicArtist ); |
|
3702 attrs.AppendL( KMPXMediaMusicAlbum ); |
|
3703 |
|
3704 RBufWriteStream writeStream( *buf ); |
|
3705 CleanupClosePushL( writeStream ); |
|
3706 // externalize attributes array |
|
3707 ::ExternalizeL(attrs.Array(), writeStream); |
|
3708 // Close and compress buffer |
|
3709 writeStream.CommitL(); |
|
3710 buf->Compress(); |
|
3711 CleanupStack::PopAndDestroy( &writeStream ); |
|
3712 CleanupStack::PopAndDestroy( &attrs ); |
|
3713 TPtrC ptr = MPXUser::Ptr( buf->Ptr( 0 ) ); |
|
3714 cmd->SetTextValueL( KMPXCommandMediaAttribute, ptr ); |
|
3715 |
|
3716 CMPXAttributeSpecs* attrSpecs = CMPXAttributeSpecs::NewL(); |
|
3717 CleanupStack::PushL(attrSpecs); |
|
3718 cmd->SetCObjectValueL<CMPXAttributeSpecs>( |
|
3719 KMPXCommandMediaAttributeSpecs, attrSpecs ); |
|
3720 CleanupStack::PopAndDestroy(attrSpecs); |
|
3721 |
|
3722 iMediaHelper->MediaL( iPlaylist->Path(), cmd, NULL, ETrue, iClientList ); |
|
3723 CleanupStack::PopAndDestroy( buf ); |
|
3724 // Onwership of media is passed to mediahelper class |
|
3725 CleanupStack::Pop( cmd ); |
|
3726 } |
|
3727 |
|
3728 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
3729 // ---------------------------------------------------------------------------- |
|
3730 // Initialises from file. |
|
3731 // ---------------------------------------------------------------------------- |
|
3732 // |
|
3733 EXPORT_C void CMPXPlaybackEngine::Init64L(const RFile64& aFile) |
|
3734 { |
|
3735 MPX_FUNC_EX("CMPXPlaybackEngine::Init64L(const RFile64& aFile)"); |
|
3736 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
3737 iInitNext=EFalse; |
|
3738 HandleCloseL(); |
|
3739 iPlaySource=EPlayFromFile64; |
|
3740 iNextState=EPbStateNotInitialised; |
|
3741 iFile64.Duplicate(aFile); |
|
3742 TRAPD( err, Init64L(&iFile64) ); |
|
3743 if ( KErrNotFound == err ) |
|
3744 { |
|
3745 // Mark item as Invalid |
|
3746 MarkItemInvalid( ETrue ); |
|
3747 User::Leave( err ); |
|
3748 } |
|
3749 } |
|
3750 |
|
3751 // ---------------------------------------------------------------------------- |
|
3752 // Initialises from file. |
|
3753 // ---------------------------------------------------------------------------- |
|
3754 // |
|
3755 EXPORT_C void CMPXPlaybackEngine::InitStreaming64L(const RFile64& aFile, const TInt aAccessPoint) |
|
3756 { |
|
3757 MPX_FUNC_EX("CMPXPlaybackEngine::InitStreaming64L(const RFile64& aFile, const TInt aAccessPoint)"); |
|
3758 iPluginUid = KNullUid; // Reset plugin uid for current item |
|
3759 iInitNext=EFalse; |
|
3760 HandleCloseL(); |
|
3761 iPlaySource=EPlayFromFile64; |
|
3762 iNextState=EPbStateNotInitialised; |
|
3763 iFile64.Duplicate(aFile); |
|
3764 iAccessPoint = aAccessPoint; |
|
3765 iAccessPointSet = ETrue; |
|
3766 TRAPD( err, Init64L(&iFile64,aAccessPoint)); |
|
3767 if ( KErrNotFound == err ) |
|
3768 { |
|
3769 // Mark item as Invalid |
|
3770 MarkItemInvalid( ETrue ); |
|
3771 User::Leave( err ); |
|
3772 } |
|
3773 } |
|
3774 |
|
3775 // ---------------------------------------------------------------------------- |
|
3776 // Initialise helper method |
|
3777 // ---------------------------------------------------------------------------- |
|
3778 // |
|
3779 void CMPXPlaybackEngine::Init64L(RFile64* aFile, TInt aAccessPoint) |
|
3780 { |
|
3781 MPX_FUNC_EX("CMPXPlaybackEngine::Init64L(RFile64* aFile,TInt aAccessPoint)"); |
|
3782 CMPXPlaybackPlugin* p( NULL ); |
|
3783 if ( iPluginHandler->Plugin() ) |
|
3784 { |
|
3785 TRAP_IGNORE(iPluginHandler->Plugin()->CommandL(EPbCmdClose)); |
|
3786 } |
|
3787 |
|
3788 if (aFile) |
|
3789 { |
|
3790 iPluginHandler->SelectPlayer64L(*aFile); |
|
3791 } |
|
3792 else |
|
3793 { // should never happen |
|
3794 ASSERT(0); |
|
3795 } |
|
3796 |
|
3797 p=iPluginHandler->Plugin(); |
|
3798 CheckPtrL(p); |
|
3799 |
|
3800 if (p->Uid()!=iPluginUid) |
|
3801 { // new plugin or new playlist |
|
3802 iPluginUid = p->Uid(); |
|
3803 iInitVolume = ETrue; |
|
3804 p->PropertyL( EPbPropertyVolume ); |
|
3805 iClientList->SendMsgL( |
|
3806 TMPXPlaybackMessage(TMPXPlaybackMessage::EPlayerChanged)); |
|
3807 } |
|
3808 // Stop and close opened file |
|
3809 TRAP_IGNORE(DoStopL(EFalse)); |
|
3810 TRAP_IGNORE(p->CommandL(EPbCmdClose)); |
|
3811 |
|
3812 // If playing from a playlist, send the index as a data |
|
3813 // parameter. This helps performance as the client |
|
3814 // doesn't need to request the index separately |
|
3815 TInt index( KErrNotFound ); |
|
3816 if ( EPlayFromCollection == iPlaySource ) |
|
3817 { |
|
3818 index = iPlaylist->Index(); |
|
3819 } |
|
3820 |
|
3821 TMPXPlaybackMessage msg( TMPXPlaybackMessage::EStateChanged, |
|
3822 EPbStateInitialising, |
|
3823 index ); |
|
3824 SetStateL( msg ); |
|
3825 iProperties[EPbPropertyPosition]=0; |
|
3826 |
|
3827 // Check if version2 interface is supported. |
|
3828 CDesCArray* interfaces = iPluginHandler->SupportedInterfacesL( p->Uid() ); |
|
3829 TBool version2InterfaceSupported = EFalse; |
|
3830 if (interfaces->MdcaCount()) |
|
3831 { |
|
3832 TInt pos(0); |
|
3833 version2InterfaceSupported = !interfaces->FindIsq(KMPXPlaybackPluginVersion2, pos); |
|
3834 } |
|
3835 delete interfaces; |
|
3836 |
|
3837 // cast the plugin to use our interface |
|
3838 if (version2InterfaceSupported) |
|
3839 { |
|
3840 CMPXPlaybackPluginVersion2* plugin = NULL; |
|
3841 plugin = static_cast<CMPXPlaybackPluginVersion2*>(p); |
|
3842 |
|
3843 // if cast was successful, then init streaming with access point |
|
3844 if (plugin) |
|
3845 { |
|
3846 if ( iAccessPointSet ) |
|
3847 { |
|
3848 plugin->InitStreaming64L( *aFile, aAccessPoint ); |
|
3849 } |
|
3850 else |
|
3851 { |
|
3852 plugin->Initialise64L( *aFile ); |
|
3853 } |
|
3854 } |
|
3855 else |
|
3856 { |
|
3857 MPX_DEBUG1("CMPXPlaybackEngine::Init64L(): -- failure to convert to expected interface"); |
|
3858 } |
|
3859 } |
|
3860 else |
|
3861 { |
|
3862 MPX_DEBUG1("CMPXPlaybackEngine::Init64L(): expected interface not supported"); |
|
3863 User::Leave( KErrNotFound ); |
|
3864 } |
|
3865 } |
|
3866 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API |
|
3867 |
|
3868 // End of file |