|
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: Maintains sessions to paths |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <badesca.h> |
|
19 #include <mpxcollectionpath.h> |
|
20 #include <mpxclientlist.h> |
|
21 #include <mpxcollectionplugin.h> |
|
22 #include <mpxcollectionpath.h> |
|
23 #include <mpxcollectionframeworkdefs.h> |
|
24 #include <mpxcollectioncommanddefs.h> |
|
25 #include <mpxcommonframeworkdefs.h> |
|
26 #include <mpxcmn.h> |
|
27 #include <mpxmedia.h> |
|
28 #include <mpxmediaarray.h> |
|
29 #include <mpxmediageneraldefs.h> |
|
30 #include <mpxmediacontainerdefs.h> |
|
31 #include <mpxmessagegeneraldefs.h> |
|
32 #include <mpxmessagecontainerdefs.h> |
|
33 #include <mpxcollectionmessage.h> |
|
34 #include <mpxcollectionmessagedefs.h> |
|
35 #include <mpxcommandgeneraldefs.h> |
|
36 #include <mpxcollectionopenlresultdef.h> |
|
37 #include <mpxcommand.h> |
|
38 #include <mpxlog.h> |
|
39 #include <mpxsubscription.h> |
|
40 #include "mpxcollectionengineobserver.h" |
|
41 #include "mpxcollectionpluginhandler.h" |
|
42 #include "mpxcollectionengine.h" |
|
43 #include "mpxcollectioncache.h" |
|
44 #include "mpxcollectionclientcontext.h" |
|
45 |
|
46 // ---------------------------------------------------------------------------- |
|
47 // Helper. Sets next open mode on path |
|
48 // ---------------------------------------------------------------------------- |
|
49 // |
|
50 LOCAL_C void SetPathOpenMode(CMPXCollectionPath& aPath, TInt aMode) |
|
51 { |
|
52 TMPXOpenMode mode=static_cast<TMPXOpenMode>(aMode); |
|
53 if (aPath.Levels()) |
|
54 { |
|
55 aPath.Set(mode == EMPXOpenDefault ? aPath.OpenPreviousMode() : mode); |
|
56 } |
|
57 } |
|
58 |
|
59 // ---------------------------------------------------------------------------- |
|
60 // Helper. Returns whether next open mode is the same as previous open |
|
61 // request |
|
62 // ---------------------------------------------------------------------------- |
|
63 // |
|
64 LOCAL_C TBool OpenModeValid(const CMPXCollectionPath& aPath) |
|
65 { |
|
66 TMPXOpenMode next=aPath.OpenNextMode(); |
|
67 return (aPath.OpenPreviousMode() == next) || (next == EMPXOpenDefault); |
|
68 } |
|
69 |
|
70 // ============================ MEMBER FUNCTIONS ============================== |
|
71 |
|
72 // ---------------------------------------------------------------------------- |
|
73 // Two-phased constructor. |
|
74 // ---------------------------------------------------------------------------- |
|
75 // |
|
76 CMPXCollectionClientContext* CMPXCollectionClientContext::NewL( |
|
77 CMPXCollectionEngine& aEngine, |
|
78 CMPXCollectionCache& aCache, |
|
79 const TUid& aModeId) |
|
80 { |
|
81 CMPXCollectionClientContext* p = |
|
82 new(ELeave) CMPXCollectionClientContext(aEngine, aCache, aModeId); |
|
83 CleanupStack::PushL(p); |
|
84 p->ConstructL(); |
|
85 CleanupStack::Pop(p); |
|
86 return p; |
|
87 } |
|
88 |
|
89 // ---------------------------------------------------------------------------- |
|
90 // C++ constructor. |
|
91 // ---------------------------------------------------------------------------- |
|
92 // |
|
93 CMPXCollectionClientContext::CMPXCollectionClientContext( |
|
94 CMPXCollectionEngine& aEngine, |
|
95 CMPXCollectionCache& aCache, |
|
96 const TUid& aModeId) |
|
97 : iModeId(aModeId),iFocusItemId(KMPXInvalidItemId), |
|
98 iEngine(aEngine),iCache(aCache) |
|
99 { |
|
100 } |
|
101 |
|
102 // ---------------------------------------------------------------------------- |
|
103 // 2nd phase constructor. |
|
104 // ---------------------------------------------------------------------------- |
|
105 // |
|
106 void CMPXCollectionClientContext::ConstructL() |
|
107 { |
|
108 iClientList = CMPXClientList::NewL(); |
|
109 iBrowsePath = CMPXCollectionPath::NewL(); |
|
110 iMedia = CMPXMedia::NewL(); // empty media |
|
111 // initialize to null uid |
|
112 for (TInt index = 0; index < EContextCount; ++index) |
|
113 { |
|
114 iPluginUids.AppendL(KNullUid); |
|
115 } |
|
116 } |
|
117 |
|
118 // ---------------------------------------------------------------------------- |
|
119 // Destructor |
|
120 // ---------------------------------------------------------------------------- |
|
121 // |
|
122 CMPXCollectionClientContext::~CMPXCollectionClientContext() |
|
123 { |
|
124 MPX_DEBUG2("CMPXCollectionClientContext::~CMPXCollectionClientContext %08x", |
|
125 this); |
|
126 |
|
127 // Release all plugins this context has references on, this could result in the |
|
128 // plugin(s) being unloaded. |
|
129 for (TInt index = 0; index < EContextCount; ++index) |
|
130 { |
|
131 if (iPluginUids[index] != KNullUid) |
|
132 { |
|
133 iEngine.ReleasePlugin(iPluginUids[index]); |
|
134 } |
|
135 } |
|
136 |
|
137 delete iClientList; |
|
138 delete iBrowsePath; |
|
139 delete iMediaPath; |
|
140 delete iMedia; |
|
141 delete iFilter; |
|
142 iPluginUids.Close(); |
|
143 iUids.Close(); |
|
144 } |
|
145 |
|
146 // ---------------------------------------------------------------------------- |
|
147 // Open collection by path |
|
148 // ---------------------------------------------------------------------------- |
|
149 // |
|
150 EXPORT_C void CMPXCollectionClientContext::OpenL( |
|
151 CMPXCollectionPath* aPath, |
|
152 TInt aMode, |
|
153 MMPXCollectionEngineObserver* aCallback) |
|
154 { |
|
155 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 1 <--"); |
|
156 MPX_ASSERT(aPath); |
|
157 if (aPath->Levels() > 0) |
|
158 { |
|
159 // Increment the plugin reference count |
|
160 CMPXCollectionPlugin*plugin = iEngine.ResolvePluginL(*aPath); |
|
161 if (!plugin) |
|
162 { |
|
163 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 1 bad path plugin"); |
|
164 User::Leave(KErrArgument); |
|
165 } |
|
166 |
|
167 iEngine.CleanupPluginPushL(plugin); |
|
168 |
|
169 // Ownership of aPath transferred |
|
170 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 1 Add task"); |
|
171 plugin->AddTaskL(EMcsOpenPath, aCallback, this, |
|
172 aMode, NULL, plugin, aPath); |
|
173 |
|
174 // Pop the plugin |
|
175 iEngine.PluginPop(); |
|
176 } |
|
177 else |
|
178 { // Go back to root level |
|
179 MPX_DEBUG1("CMPXCollectionClientContext::OpenL restarting path"); |
|
180 iIndex=0; |
|
181 iFocusItemId = KMPXInvalidItemId; |
|
182 InitL(aCallback); |
|
183 } |
|
184 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 1 -->"); |
|
185 } |
|
186 |
|
187 // ---------------------------------------------------------------------------- |
|
188 // Open collection by index |
|
189 // ---------------------------------------------------------------------------- |
|
190 // |
|
191 EXPORT_C void CMPXCollectionClientContext::OpenL( |
|
192 TInt aIndex, |
|
193 TInt aMode, |
|
194 const TArray<TMPXAttribute>& aAttrs, |
|
195 MMPXCollectionEngineObserver* aCallback) |
|
196 { |
|
197 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 2 <--"); |
|
198 if (iBrowsePath->Levels()<=0) |
|
199 { |
|
200 User::Leave(KErrNotReady); |
|
201 } |
|
202 if (aIndex<0 || aIndex>=iBrowsePath->Count()) |
|
203 { |
|
204 User::Leave(KErrArgument); |
|
205 } |
|
206 iBrowsePath->Set(aIndex); |
|
207 // plugin not resolved yet |
|
208 if (iPluginUids[EContextBrowse] == KNullUid) |
|
209 { |
|
210 // Increment the new plugin reference count, decrement the old. |
|
211 // No need to push/release the plugin it is stored in a member |
|
212 // variable and will be released when that is overwritten. |
|
213 ResolvePluginL(*iBrowsePath, iPluginUids[EContextBrowse]); |
|
214 } |
|
215 |
|
216 if (iPluginUids[EContextBrowse] == KNullUid) |
|
217 { |
|
218 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 2 bad plugin"); |
|
219 User::Leave(KErrNotReady); |
|
220 } |
|
221 |
|
222 // add request to the queue |
|
223 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 2 Add task"); |
|
224 iBrowsePath->SetL(aAttrs); |
|
225 LoadedPlugin(EContextBrowse)->AddTaskL(EMcsOpenIndex, aCallback, this, |
|
226 aIndex, NULL, (TAny*)aMode); |
|
227 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 2 -->"); |
|
228 } |
|
229 |
|
230 // ---------------------------------------------------------------------------- |
|
231 // Open collection by uids |
|
232 // ---------------------------------------------------------------------------- |
|
233 // |
|
234 EXPORT_C void CMPXCollectionClientContext::OpenL( |
|
235 const TArray<TUid>& aUids, |
|
236 TInt aMode, |
|
237 MMPXCollectionEngineObserver* aCallback) |
|
238 { |
|
239 // Update path for open request |
|
240 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 3 <---"); |
|
241 SetPathOpenMode(*iBrowsePath,aMode); |
|
242 if (!MPXUser::CompareOrderedUidArrays(iUids.Array(), aUids)) |
|
243 { // the same context |
|
244 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 3 return Open"); |
|
245 aCallback->HandleOpen(iMedia, iIndex, ETrue, iMediaType); |
|
246 } |
|
247 else |
|
248 { // go back to root level |
|
249 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 3 Going to Root"); |
|
250 iUids.Reset(); |
|
251 ::CopyArrayL(aUids, iUids); |
|
252 iIndex=0; |
|
253 iFocusItemId = KMPXInvalidItemId; |
|
254 InitL(aCallback); |
|
255 } |
|
256 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 3 --->"); |
|
257 } |
|
258 |
|
259 // ---------------------------------------------------------------------------- |
|
260 // Request current content of browse context |
|
261 // ---------------------------------------------------------------------------- |
|
262 // |
|
263 EXPORT_C void CMPXCollectionClientContext::OpenL( |
|
264 TInt aMode, |
|
265 MMPXCollectionEngineObserver* aCallback) |
|
266 { |
|
267 // Update path for open request |
|
268 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 <---"); |
|
269 SetPathOpenMode(*iBrowsePath,aMode); |
|
270 if (iPluginUids[EContextBrowse] == KNullUid) |
|
271 {// No plug-in has been resolved |
|
272 if (iBrowsePath->Levels() == 0) |
|
273 // |
|
274 // Open called at root level: just need to list the plug-ins, |
|
275 // no need to resolve any plugin. Open request doesn't apply |
|
276 // at this level |
|
277 { |
|
278 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 InitL()"); |
|
279 iIndex=0; |
|
280 iFocusItemId = KMPXInvalidItemId; |
|
281 InitL(aCallback); |
|
282 } |
|
283 else if (OpenModeValid(*iBrowsePath) && !iPathUpdated) |
|
284 // |
|
285 // The existing media is still valid (no change |
|
286 // in the request for entries |
|
287 // |
|
288 { |
|
289 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 return media"); |
|
290 aCallback->HandleOpen(iMedia, |
|
291 iIndex, ETrue, |
|
292 iMediaType); |
|
293 } |
|
294 else // Open mode has changed and open NOT called at root level |
|
295 { |
|
296 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 add task different open mode"); |
|
297 ResolvePluginL(*iBrowsePath, iPluginUids[EContextBrowse]); // Find a plug-in |
|
298 if (iPluginUids[EContextBrowse] != KNullUid) |
|
299 { |
|
300 LoadedPlugin(EContextBrowse)->AddTaskL(EMcsOpen, aCallback, this); |
|
301 } |
|
302 } |
|
303 } |
|
304 else |
|
305 { |
|
306 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 add task"); |
|
307 LoadedPlugin(EContextBrowse)->AddTaskL(EMcsOpen, aCallback,this); |
|
308 } |
|
309 MPX_DEBUG1("CMPXCollectionClientContext::OpenL 4 --->"); |
|
310 } |
|
311 |
|
312 // ---------------------------------------------------------------------------- |
|
313 // Media request by collection path |
|
314 // ---------------------------------------------------------------------------- |
|
315 // |
|
316 EXPORT_C void CMPXCollectionClientContext::BackL( |
|
317 MMPXCollectionEngineObserver* aCallback) |
|
318 { |
|
319 MPX_DEBUG1("CMPXCollectionClientContext::BackL()"); |
|
320 if (iPluginUids[EContextBrowse]==KNullUid) |
|
321 { |
|
322 User::Leave(KErrNotReady); |
|
323 } |
|
324 |
|
325 MPX_DEBUG1("CMPXCollectionClientContext::BackL() -- Add task"); |
|
326 LoadedPlugin(EContextBrowse)->AddTaskL(EMcsBack, aCallback, this); |
|
327 } |
|
328 |
|
329 // ---------------------------------------------------------------------------- |
|
330 // MediaL command |
|
331 // ---------------------------------------------------------------------------- |
|
332 // |
|
333 EXPORT_C void CMPXCollectionClientContext::MediaL( |
|
334 const CMPXCommand& aCmd, |
|
335 MMPXCollectionEngineObserver* aCallback) |
|
336 { |
|
337 CMPXCollectionPath* path = |
|
338 aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCommandGeneralTargetIds); |
|
339 CleanupStack::PushL(path); |
|
340 |
|
341 // Increment the plugin reference count |
|
342 CMPXCollectionPlugin*plugin = iEngine.ResolvePluginL(*path); |
|
343 if (!plugin) |
|
344 { |
|
345 User::Leave(KErrArgument); |
|
346 } |
|
347 |
|
348 iEngine.CleanupPluginPushL(plugin); |
|
349 |
|
350 CMPXCommand* cmd = CMPXCommand::NewL(aCmd); // make a copy |
|
351 CleanupStack::PushL(cmd); |
|
352 |
|
353 plugin->AddTaskL(EMcsMediaByPath, aCallback, this, |
|
354 0, NULL, plugin, cmd, path); |
|
355 |
|
356 CleanupStack::Pop(cmd); // Ownership transferred to the task queue |
|
357 iEngine.PluginPop(); // Pop the plugin |
|
358 CleanupStack::Pop(path);// Ownership transferred to the task queue |
|
359 } |
|
360 |
|
361 // ---------------------------------------------------------------------------- |
|
362 // Add a media |
|
363 // ---------------------------------------------------------------------------- |
|
364 // |
|
365 EXPORT_C void CMPXCollectionClientContext::AddL(const CMPXMedia& aMedia) |
|
366 { |
|
367 DoUpdateMediaL( EMcsAddItem, aMedia ); |
|
368 } |
|
369 |
|
370 // ---------------------------------------------------------------------------- |
|
371 // Remove a media |
|
372 // ---------------------------------------------------------------------------- |
|
373 // |
|
374 EXPORT_C void CMPXCollectionClientContext::RemoveL(const CMPXMedia& aMedia) |
|
375 { |
|
376 DoUpdateMediaL( EMcsRemoveItem, aMedia ); |
|
377 } |
|
378 |
|
379 // ---------------------------------------------------------------------------- |
|
380 // Update a media |
|
381 // ---------------------------------------------------------------------------- |
|
382 // |
|
383 EXPORT_C void CMPXCollectionClientContext::SetL(const CMPXMedia& aMedia) |
|
384 { |
|
385 DoUpdateMediaL( EMcsSetMedia, aMedia ); |
|
386 } |
|
387 |
|
388 // ---------------------------------------------------------------------------- |
|
389 // Remove media by path |
|
390 // ---------------------------------------------------------------------------- |
|
391 // |
|
392 EXPORT_C void CMPXCollectionClientContext::RemoveL( |
|
393 CMPXCollectionPath* aPath, |
|
394 MMPXCollectionEngineObserver* aCallback) |
|
395 { |
|
396 TInt id(aPath->Id(CMPXCollectionPath::ECollectionUid)); |
|
397 |
|
398 // Increment the plugin reference count |
|
399 CMPXCollectionPlugin* plugin = iEngine.ResolvePluginL(TUid::Uid(id)); |
|
400 if (!plugin) |
|
401 { |
|
402 User::Leave(KErrArgument); |
|
403 } |
|
404 |
|
405 iEngine.CleanupPluginPushL(plugin); |
|
406 |
|
407 // Ownership of aPath transferred |
|
408 plugin->AddTaskL(EMcsRemovePath, aCallback, this, 0, NULL, plugin, aPath); |
|
409 |
|
410 iEngine.PluginPop(); |
|
411 } |
|
412 |
|
413 // ---------------------------------------------------------------------------- |
|
414 // Return current plugin id |
|
415 // ---------------------------------------------------------------------------- |
|
416 // |
|
417 EXPORT_C TUid CMPXCollectionClientContext::PluginId() const |
|
418 { |
|
419 return iPluginUids[EContextBrowse]; |
|
420 } |
|
421 |
|
422 // ---------------------------------------------------------------------------- |
|
423 // Handle async request from client |
|
424 // ---------------------------------------------------------------------------- |
|
425 // |
|
426 EXPORT_C const CMPXCollectionPath& CMPXCollectionClientContext::Path() const |
|
427 { |
|
428 return *iBrowsePath; |
|
429 } |
|
430 |
|
431 // ---------------------------------------------------------------------------- |
|
432 // Cancel request |
|
433 // ---------------------------------------------------------------------------- |
|
434 // |
|
435 EXPORT_C void CMPXCollectionClientContext::CancelRequest( |
|
436 MMPXCollectionEngineObserver* aCallback) |
|
437 { |
|
438 MPX_DEBUG3("CMPXCollectionClientContext::CancelRequest, this %08x, aCallback %08x", |
|
439 this, aCallback); |
|
440 iEngine.RemoveTask(aCallback); |
|
441 } |
|
442 |
|
443 // ---------------------------------------------------------------------------- |
|
444 // Add a client |
|
445 // ---------------------------------------------------------------------------- |
|
446 // |
|
447 EXPORT_C void CMPXCollectionClientContext::AddClientL( |
|
448 TThreadId aId, |
|
449 CMPXMessageQueue* aMsgQueue) |
|
450 { |
|
451 iClientList->AddClientL(aId, aMsgQueue); |
|
452 } |
|
453 |
|
454 // ---------------------------------------------------------------------------- |
|
455 // Remove a client |
|
456 // ---------------------------------------------------------------------------- |
|
457 // |
|
458 EXPORT_C void CMPXCollectionClientContext::RemoveClient( |
|
459 const CMPXMessageQueue& aMsgQueue) |
|
460 { |
|
461 MPX_DEBUG2("CMPXCollectionClientContext::RemoveClient with the message queue 0x%08x", |
|
462 &aMsgQueue); |
|
463 TInt index(iClientList->Find(aMsgQueue)); |
|
464 if (KErrNotFound != index) |
|
465 { |
|
466 iClientList->RemoveClient(index); |
|
467 } |
|
468 if (!iClientList->ClientCount()) |
|
469 { |
|
470 iEngine.RemoveContext(*this); |
|
471 } |
|
472 } |
|
473 |
|
474 // ---------------------------------------------------------------------------- |
|
475 // Gets the supported capabilities of the current browse plugin |
|
476 // ---------------------------------------------------------------------------- |
|
477 // |
|
478 EXPORT_C TCollectionCapability CMPXCollectionClientContext::GetCapabilities() |
|
479 { |
|
480 TCollectionCapability cap(0); |
|
481 if (iPluginUids[EContextBrowse]!=KNullUid) |
|
482 { |
|
483 LoadedPlugin(EContextBrowse)->GetCapabilities(); |
|
484 } |
|
485 return cap; |
|
486 } |
|
487 |
|
488 // ---------------------------------------------------------------------------- |
|
489 // Find all aSync |
|
490 // ---------------------------------------------------------------------------- |
|
491 // |
|
492 EXPORT_C void CMPXCollectionClientContext::FindAllL( |
|
493 const CMPXMedia& aMedia, |
|
494 CBufBase* aBuf, |
|
495 MMPXCollectionEngineObserver* aCallback) |
|
496 { |
|
497 CMPXCollectionPlugin* plugin(NULL); // Not owned |
|
498 |
|
499 // Increment the plugin reference count |
|
500 ResolvePluginL(aMedia, plugin); |
|
501 if (!plugin) |
|
502 { |
|
503 User::Leave(KErrNotFound); // found nothing |
|
504 } |
|
505 |
|
506 iEngine.CleanupPluginPushL(plugin); |
|
507 |
|
508 // Add the task |
|
509 CMPXMedia* media = CMPXMedia::NewL(aMedia); |
|
510 CleanupStack::PushL(media); |
|
511 plugin->AddTaskL(EMcsFindAll, aCallback, this, 0, aBuf, plugin, media); |
|
512 CleanupStack::Pop(media); // Ownership transferred |
|
513 |
|
514 iEngine.PluginPop(); |
|
515 } |
|
516 |
|
517 // ---------------------------------------------------------------------------- |
|
518 // Find all sync |
|
519 // ---------------------------------------------------------------------------- |
|
520 // |
|
521 EXPORT_C CMPXMedia* CMPXCollectionClientContext::FindAllSyncL( |
|
522 const CMPXMedia& aMedia, |
|
523 const CBufBase& aBuf) |
|
524 { |
|
525 CMPXCollectionPlugin* plugin(NULL); // Not owned |
|
526 |
|
527 // Increment the plugin reference count |
|
528 ResolvePluginL(aMedia, plugin); |
|
529 iEngine.CleanupPluginPushL(plugin); |
|
530 |
|
531 CMPXMedia* result(NULL); |
|
532 FindAllL(aMedia, aBuf, *plugin, &result, ETrue); |
|
533 |
|
534 // Synchronous call, safe to release the plugin |
|
535 CleanupStack::PopAndDestroy(); // plugin |
|
536 return result; |
|
537 } |
|
538 |
|
539 // ---------------------------------------------------------------------------- |
|
540 // Set filter |
|
541 // ---------------------------------------------------------------------------- |
|
542 // |
|
543 EXPORT_C void CMPXCollectionClientContext::SetFilterL(const CMPXFilter* aFilter) |
|
544 { |
|
545 delete iFilter; |
|
546 iFilter = NULL; |
|
547 iFilter = aFilter ? CMPXFilter::NewL(*aFilter) : NULL; |
|
548 } |
|
549 |
|
550 // ---------------------------------------------------------------------------- |
|
551 // Returns filter |
|
552 // ---------------------------------------------------------------------------- |
|
553 // |
|
554 EXPORT_C const CMPXFilter* CMPXCollectionClientContext::Filter() const |
|
555 { |
|
556 return iFilter; |
|
557 } |
|
558 |
|
559 // ---------------------------------------------------------------------------- |
|
560 // Handle a command |
|
561 // ---------------------------------------------------------------------------- |
|
562 // |
|
563 EXPORT_C void CMPXCollectionClientContext::CommandL( |
|
564 TMPXCollectionCommand aCmd, |
|
565 TInt aData) |
|
566 { |
|
567 switch( aCmd ) |
|
568 { |
|
569 case EMcCmdRemoveAll: |
|
570 case EMcCmdReCreateDB: // fall through |
|
571 case EMcCmdDbCorrupted: // fall through |
|
572 { |
|
573 TUid uid = TUid::Uid(aData); |
|
574 |
|
575 // Increment the plugin reference count |
|
576 CMPXCollectionPlugin* plugin = iEngine.ResolvePluginL( uid ); |
|
577 iEngine.CleanupPluginPushL(plugin); |
|
578 |
|
579 if( plugin ) |
|
580 { |
|
581 // The trap is needed to keep the plugin reference count in sync |
|
582 plugin->CommandL(aCmd); |
|
583 } |
|
584 |
|
585 CleanupStack::PopAndDestroy(); // plugin |
|
586 break; |
|
587 } |
|
588 case EMcCmdSelect: |
|
589 if (iBrowsePath->Levels()<=0) |
|
590 { |
|
591 User::Leave(KErrNotReady); |
|
592 } |
|
593 if (aData<0 || aData>=iBrowsePath->Count()) |
|
594 { |
|
595 User::Leave(KErrArgument); |
|
596 } |
|
597 iBrowsePath->Set(aData); |
|
598 iClientList->SendMsgL( |
|
599 TMPXCollectionMessage(TMPXCollectionMessage::EFocusChanged, |
|
600 aData, aData)); |
|
601 iIndex = aData; // iIndex will always be up to date |
|
602 iFocusItemId = iBrowsePath->Id(); |
|
603 break; |
|
604 case EMcCmdCollectionInit: |
|
605 case EMcCmdCollectionResyn: |
|
606 { |
|
607 TUid uid = TUid::Uid(aData); |
|
608 // Increment the plugin reference count |
|
609 CMPXCollectionPlugin* plugin = iEngine.ResolvePluginL(uid); |
|
610 if( !plugin ) |
|
611 { |
|
612 User::Leave(KErrArgument); |
|
613 } |
|
614 |
|
615 iEngine.CleanupPluginPushL(plugin); |
|
616 |
|
617 plugin->AddTaskL(EMcsCommand, NULL, this, aCmd, NULL, plugin); |
|
618 |
|
619 iEngine.PluginPop(); |
|
620 break; |
|
621 } |
|
622 default: |
|
623 { |
|
624 User::Leave(KErrNotSupported); |
|
625 break; |
|
626 } |
|
627 } |
|
628 } |
|
629 |
|
630 // ---------------------------------------------------------------------------- |
|
631 // Handle a command |
|
632 // ---------------------------------------------------------------------------- |
|
633 // |
|
634 EXPORT_C void CMPXCollectionClientContext::CommandL( |
|
635 const CMPXCommand& aCmd, |
|
636 MMPXCollectionEngineObserver* aCallback, |
|
637 const CMPXMessageQueue& aMsgQueue) |
|
638 { |
|
639 // Use the plugin id defined by the command object, |
|
640 // or the browse context if collection id not defined |
|
641 CMPXCollectionPlugin* plugin = NULL; |
|
642 if (aCmd.IsSupported(KMPXCommandGeneralCollectionId)) |
|
643 { |
|
644 TInt data = aCmd.ValueTObjectL<TInt>(KMPXCommandGeneralCollectionId); |
|
645 |
|
646 // Increment the plugin reference count |
|
647 plugin = iEngine.ResolvePluginL(TUid::Uid(data)); |
|
648 } |
|
649 if (!plugin && iPluginUids[EContextBrowse]!=KNullUid) |
|
650 { |
|
651 plugin = LoadedPlugin(EContextBrowse); |
|
652 |
|
653 // Increment the plugin reference count manually |
|
654 iEngine.UsePlugin(plugin->Uid()); |
|
655 } |
|
656 iEngine.CleanupPluginPushL(plugin); |
|
657 |
|
658 TBool async(ETrue); // by default command is asynchronous |
|
659 if (aCmd.IsSupported(KMPXCommandGeneralDoSync)) |
|
660 { // check if command is sync |
|
661 async=!(aCmd.ValueTObjectL<TBool>(KMPXCommandGeneralDoSync)); |
|
662 } |
|
663 |
|
664 if (async) |
|
665 { // Async, cmd ownership transferred |
|
666 if (!plugin) |
|
667 { |
|
668 User::Leave(KErrNotReady); |
|
669 } |
|
670 |
|
671 CMPXCommand* cmd = CMPXCommand::NewL(aCmd); |
|
672 CleanupStack::PushL(cmd); |
|
673 plugin->AddTaskL(EMcsCommandExt, aCallback, this, 0, |
|
674 NULL, plugin, cmd); |
|
675 CleanupStack::Pop(cmd); |
|
676 |
|
677 // Async, the plugin pointer passed through the task queue |
|
678 iEngine.PluginPop(); |
|
679 } |
|
680 else |
|
681 { |
|
682 DoHandleSyncCommandL(aCmd, aMsgQueue, plugin); |
|
683 CleanupStack::PopAndDestroy(); // plugin |
|
684 } |
|
685 } |
|
686 |
|
687 // ---------------------------------------------------------------------------- |
|
688 // Find a shareable client |
|
689 // ---------------------------------------------------------------------------- |
|
690 // |
|
691 TBool CMPXCollectionClientContext::HasShareableClient( |
|
692 TThreadId aId) |
|
693 { |
|
694 TBool ret(EFalse); |
|
695 if (iModeId != KMcModePlaylist) |
|
696 { |
|
697 if (iClientList->IsClient(aId) ) // Just look for same thread |
|
698 { |
|
699 ret = ETrue; |
|
700 } |
|
701 } |
|
702 return ret; |
|
703 } |
|
704 |
|
705 // ---------------------------------------------------------------------------- |
|
706 // Notifies all clients of events |
|
707 // ---------------------------------------------------------------------------- |
|
708 // |
|
709 void CMPXCollectionClientContext::NotifyL( TMPXCollectionBroadCastMsg aMsg, |
|
710 TInt aData ) |
|
711 { |
|
712 iClientList->SendMsgL( |
|
713 TMPXCollectionMessage(TMPXCollectionMessage::EBroadcastEvent, |
|
714 aMsg,aData)); |
|
715 } |
|
716 |
|
717 const TUid& CMPXCollectionClientContext::ModeId() const |
|
718 { |
|
719 return iModeId; |
|
720 } |
|
721 |
|
722 // ---------------------------------------------------------------------------- |
|
723 // Initialises from file. iFile is not owned here |
|
724 // ---------------------------------------------------------------------------- |
|
725 // |
|
726 void CMPXCollectionClientContext::OpenL() |
|
727 { |
|
728 if (iPathUpdated) |
|
729 { |
|
730 ReOpenL(); |
|
731 } |
|
732 else |
|
733 { |
|
734 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
735 MPX_ASSERT(plugin); |
|
736 plugin->CompleteTask(); |
|
737 if (plugin->Callback()) |
|
738 { |
|
739 plugin->Callback()->HandleOpen(iMedia, |
|
740 iIndex, ETrue,iMediaType); |
|
741 plugin->SetCallback( NULL ); // Reset current observer |
|
742 plugin->SetObserver(iEngine); |
|
743 } |
|
744 } |
|
745 } |
|
746 |
|
747 // ---------------------------------------------------------------------------- |
|
748 // Cancels all outstanding calls (tasks): plug-in should only have one |
|
749 // outstanding so that is canceled; the tasks are deleted and removed from the |
|
750 // queue |
|
751 // ---------------------------------------------------------------------------- |
|
752 // |
|
753 void CMPXCollectionClientContext::BackL() |
|
754 { |
|
755 TInt d=iBrowsePath->Levels(); |
|
756 if(d>1) |
|
757 { |
|
758 iPathUpdated = EFalse; |
|
759 // remove last item - the actual item selected |
|
760 iBrowsePath->Back(); |
|
761 // preserve focus, since we're rebuilding this level |
|
762 iIndex=iBrowsePath->Index(); |
|
763 iFocusItemId = iBrowsePath->Id(); |
|
764 ReOpenL(); |
|
765 } |
|
766 } |
|
767 |
|
768 // ---------------------------------------------------------------------------- |
|
769 // Re-open current level |
|
770 // ---------------------------------------------------------------------------- |
|
771 // |
|
772 void CMPXCollectionClientContext::ReOpenL() |
|
773 { |
|
774 // remove last item - go to the container which contained the item |
|
775 if (iBrowsePath->Levels()) |
|
776 { |
|
777 iBrowsePath->Back(); |
|
778 } |
|
779 if (iBrowsePath->Levels() == 0) |
|
780 { |
|
781 //Plugin must be resolved ealier |
|
782 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
783 plugin->CompleteTask(); |
|
784 InitL(plugin->Callback()); |
|
785 } |
|
786 else |
|
787 { |
|
788 DoPluginOpenL(); |
|
789 } |
|
790 } |
|
791 |
|
792 // ---------------------------------------------------------------------------- |
|
793 // Retrieve media info based on a find criteria |
|
794 // ---------------------------------------------------------------------------- |
|
795 // |
|
796 void CMPXCollectionClientContext::FindAllL( |
|
797 const CMPXMedia& aMedia, |
|
798 const CBufBase& aBuf, |
|
799 CMPXCollectionPlugin& aPlugin, |
|
800 CMPXMedia** aResult /*= NULL*/, |
|
801 TBool aSync /*= EFalse*/) |
|
802 { |
|
803 // Find critera and return attributes |
|
804 // |
|
805 RArray<TMPXAttribute> attrs; |
|
806 CleanupClosePushL(attrs); |
|
807 ::CreateFromBufferL(aBuf, attrs); |
|
808 |
|
809 // Do the query |
|
810 if (!aSync) |
|
811 { |
|
812 aPlugin.SetObserver(*this); |
|
813 aPlugin.FindAllL(aMedia,attrs.Array()); |
|
814 } |
|
815 else |
|
816 { |
|
817 *aResult = aPlugin.FindAllSyncL(aMedia,attrs.Array()); |
|
818 } |
|
819 CleanupStack::PopAndDestroy( &attrs ); |
|
820 } |
|
821 |
|
822 // ---------------------------------------------------------------------------- |
|
823 // CMPXCollectionClientContext::HandleMessage |
|
824 // ---------------------------------------------------------------------------- |
|
825 // |
|
826 void CMPXCollectionClientContext::HandleMessage( |
|
827 CMPXMessage* aMsg, |
|
828 TInt aError) |
|
829 { |
|
830 MPX_FUNC_EX("CMPXCollectionClientContext::HandleMessage"); |
|
831 DoHandleMessage(aMsg, aError, ETrue); |
|
832 } |
|
833 |
|
834 // ---------------------------------------------------------------------------- |
|
835 // CMPXCollectionClientContext::HandleMessage |
|
836 // ---------------------------------------------------------------------------- |
|
837 // |
|
838 void CMPXCollectionClientContext::DoHandleMessage( |
|
839 CMPXMessage* aMsg, |
|
840 TInt aError, |
|
841 TBool aNotifyOthers) |
|
842 { |
|
843 MPX_DEBUG3("-->CMPXCollectionClientContext::HandleMessage this %08x, %d", this, aNotifyOthers); |
|
844 if (!aMsg) |
|
845 { |
|
846 iClientList->SendMsg(aMsg, aError); |
|
847 if (aNotifyOthers) |
|
848 { |
|
849 iEngine.NotifyChange(*this, aMsg, aError); |
|
850 } |
|
851 } |
|
852 else |
|
853 { |
|
854 if (aMsg->IsSupported(KMPXMessageGeneralId)) |
|
855 { |
|
856 if (aMsg->IsSupported(KMPXMessageArrayContents)) |
|
857 { |
|
858 TBool pathUpdated(EFalse); |
|
859 const CMPXMessageArray* messageArray = |
|
860 aMsg->Value<CMPXMessageArray>(KMPXMessageArrayContents); |
|
861 if (messageArray) |
|
862 { |
|
863 TInt count = messageArray->Count(); |
|
864 |
|
865 MPX_DEBUG2("%d messages:", count); |
|
866 |
|
867 for (TInt i=0; i<count; i++) |
|
868 { |
|
869 const CMPXMessage* message =(*messageArray)[i]; |
|
870 if (message) |
|
871 { |
|
872 TRAP_IGNORE(DoHandleMessageL(*message, KErrNone)); |
|
873 pathUpdated |=iPathUpdated; |
|
874 } |
|
875 } |
|
876 iPathUpdated = pathUpdated; |
|
877 } |
|
878 // Notify other context, collection is changed. |
|
879 // Send the batched version |
|
880 // |
|
881 if (aNotifyOthers) |
|
882 { |
|
883 iEngine.NotifyChange(*this, |
|
884 const_cast<CMPXMessage*>(aMsg), |
|
885 aError); |
|
886 } |
|
887 } |
|
888 else |
|
889 { |
|
890 TRAP_IGNORE(DoHandleMessageL(*aMsg, aError)); |
|
891 |
|
892 // Notify other context, collection is changed. |
|
893 if (aNotifyOthers) |
|
894 { |
|
895 iEngine.NotifyChange(*this, aMsg, aError); |
|
896 } |
|
897 } |
|
898 |
|
899 // Broadcast change messages to the clients to handle |
|
900 // |
|
901 if( iModeId == KMcModePlaylist ) |
|
902 { |
|
903 // Playlist should not be handling msgs during refresh |
|
904 if( !iEngine.IsRefreshing() ) |
|
905 { |
|
906 iClientList->SendMsg( aMsg, aError ); |
|
907 } |
|
908 } |
|
909 else |
|
910 { |
|
911 // Other modes receive msg all the time |
|
912 iClientList->SendMsg( aMsg, aError ); |
|
913 } |
|
914 |
|
915 // Batched collection change messages and only send this once |
|
916 // Path changed isn't sent to the UI during refresh |
|
917 // |
|
918 if (iPathUpdated) |
|
919 { |
|
920 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleMessageL detected path changed"); |
|
921 MPX_DEBUG_PATH(*iBrowsePath); |
|
922 // notify clients to refresh |
|
923 TRAP_IGNORE(iClientList->SendMsgL( |
|
924 TMPXCollectionMessage(TMPXCollectionMessage::EPathChanged, |
|
925 EMcPathChangedByCollectionChange))); |
|
926 } |
|
927 } |
|
928 } |
|
929 |
|
930 MPX_DEBUG3("<--CMPXCollectionClientContext::HandleMessage this %08x, %d", this, aNotifyOthers); |
|
931 } |
|
932 |
|
933 // ---------------------------------------------------------------------------- |
|
934 // Handle collection item change message |
|
935 // ---------------------------------------------------------------------------- |
|
936 // |
|
937 void CMPXCollectionClientContext::DoHandleMessageL( |
|
938 const CMPXMessage& aMsg, |
|
939 TInt /*aError*/) |
|
940 { |
|
941 MPX_DEBUG2("-->CMPXCollectionClientContext::DoHandleMessageL this %08x", this); |
|
942 TInt browseLevels = iBrowsePath->Levels(); // browse depth |
|
943 |
|
944 if (aMsg.ValueTObjectL<TMPXMessageId>(KMPXMessageGeneralId)== |
|
945 KMPXMessageIdItemChanged) |
|
946 { |
|
947 if (!aMsg.IsSupported(KMPXMessageCollectionId) || |
|
948 !aMsg.IsSupported(KMPXMessageChangeEventType) || |
|
949 !aMsg.IsSupported(KMPXMessageMediaGeneralCategory) || |
|
950 !aMsg.IsSupported(KMPXMessageMediaGeneralId)) |
|
951 { |
|
952 User::Leave(KErrArgument); |
|
953 } |
|
954 |
|
955 TUid collectionId = aMsg.ValueTObjectL<TUid>(KMPXMessageCollectionId); |
|
956 |
|
957 TMPXChangeEventType changeType = |
|
958 aMsg.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType); |
|
959 |
|
960 TMPXGeneralCategory category = |
|
961 aMsg.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory); |
|
962 |
|
963 TMPXItemId itemId = aMsg.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId); |
|
964 |
|
965 TMPXItemId deprecatedId(0); |
|
966 if (aMsg.IsSupported(KMPXMessageMediaDeprecatedId)) |
|
967 { |
|
968 deprecatedId = aMsg.ValueTObjectL<TMPXItemId>(KMPXMessageMediaDeprecatedId); |
|
969 } |
|
970 |
|
971 MPX_DEBUG5("CMPXCollectionClientContext::DoHandleMessageL colId %08x, id %d, deprecatedId %d, type %d", |
|
972 collectionId.iUid, itemId.iId1, deprecatedId.iId1, changeType); |
|
973 |
|
974 |
|
975 if(!iEngine.IsRefreshing()) |
|
976 { |
|
977 // Invalidate path |
|
978 TInt pct = KErrNotFound; // path change type |
|
979 if (changeType == EMPXItemInserted && category != EMPXPlaylist) |
|
980 { |
|
981 pct = CMPXCollectionPath ::EAdded; |
|
982 } |
|
983 else if (changeType == EMPXItemModified && category != EMPXPlaylist) |
|
984 { |
|
985 pct = CMPXCollectionPath ::EModified; |
|
986 } |
|
987 else if (changeType == EMPXItemDeleted) |
|
988 { |
|
989 pct = CMPXCollectionPath ::EDeleted; |
|
990 } |
|
991 else if ((changeType == EMPXItemInserted || changeType == EMPXItemModified) && |
|
992 category == EMPXPlaylist) |
|
993 { |
|
994 pct = CMPXCollectionPath ::EGroupModified; |
|
995 } |
|
996 if( changeType == EMPXItemModified && category == EMPXCollection ) |
|
997 { |
|
998 // Overwrite previous type |
|
999 pct = CMPXCollectionPath ::EGroupModified; |
|
1000 } |
|
1001 |
|
1002 if (KErrNotFound != pct) |
|
1003 { // update browse path |
|
1004 CMPXCollectionPath::TMPXCollectionPathChange ct = |
|
1005 static_cast<CMPXCollectionPath::TMPXCollectionPathChange>(pct); |
|
1006 TInt pUpdated(CMPXCollectionPath::EPathUnchanged); |
|
1007 |
|
1008 // If browse context and browse context is being modified |
|
1009 // |
|
1010 if (iModeId != KMcModePlaylist && browseLevels && |
|
1011 iBrowsePath->Id(0) == collectionId.iUid ) |
|
1012 { // check the browse path |
|
1013 TInt tmpIndex(0); |
|
1014 |
|
1015 pUpdated = iBrowsePath->HandleChange( |
|
1016 collectionId, itemId, deprecatedId, ct, |
|
1017 tmpIndex); |
|
1018 |
|
1019 // Take the updated selection index only if it was affected |
|
1020 // We need to store the TMPXItemId for iIndex because |
|
1021 // a previous collection change would have removed the |
|
1022 // top level of the collection path |
|
1023 // |
|
1024 iPathUpdated = iPathUpdated || |
|
1025 (pUpdated != CMPXCollectionPath::EPathUnchanged); |
|
1026 if( pUpdated ) |
|
1027 { |
|
1028 // Only update the selection index if the itemid that |
|
1029 // was modified is equal to the one selected |
|
1030 // |
|
1031 // OR take in the index if clipped the collection path |
|
1032 // (pUpdated == KPathClipped ) |
|
1033 // |
|
1034 if( pUpdated == CMPXCollectionPath::EPathClipped ) |
|
1035 { |
|
1036 iIndex = tmpIndex; |
|
1037 iFocusItemId = KMPXInvalidItemId; |
|
1038 } |
|
1039 else if( iFocusItemId.ApproxEqual(itemId ) && |
|
1040 ( iFocusItemId != KMPXInvalidItemId ) ) |
|
1041 { |
|
1042 // Also make sure the index that came back from |
|
1043 // checking the collection path isn't -1 |
|
1044 // |
|
1045 // The only case where the selected item will shift |
|
1046 // is when we are deleting that item. updaing the item or adding |
|
1047 // an item to the current path should not move the focus to another |
|
1048 // item |
|
1049 // |
|
1050 if( tmpIndex != -1 && changeType == EMPXItemDeleted) |
|
1051 { |
|
1052 if( tmpIndex == iBrowsePath->Count()-1 ) |
|
1053 { |
|
1054 // Last item, focus on previous |
|
1055 iIndex = tmpIndex-1; |
|
1056 iFocusItemId = iBrowsePath->IdOfIndex( tmpIndex-1 ); |
|
1057 } |
|
1058 else |
|
1059 { |
|
1060 // Not last, focus on next |
|
1061 iFocusItemId = iBrowsePath->IdOfIndex( tmpIndex+1 ); |
|
1062 } |
|
1063 } |
|
1064 } |
|
1065 else if( iFocusItemId.ApproxEqual( deprecatedId ) && |
|
1066 changeType == EMPXItemModified ) |
|
1067 { |
|
1068 // If we are modifying the item id of an item currently in focus |
|
1069 // We move the focus to the new item id |
|
1070 // |
|
1071 iFocusItemId = itemId; |
|
1072 } |
|
1073 } |
|
1074 } |
|
1075 } |
|
1076 } |
|
1077 } |
|
1078 else |
|
1079 { |
|
1080 // do nothing |
|
1081 } |
|
1082 MPX_DEBUG2("<--CMPXCollectionClientContext::DoHandleMessageL this %08x", this); |
|
1083 } |
|
1084 |
|
1085 // ---------------------------------------------------------------------------- |
|
1086 // Handle open event |
|
1087 // ---------------------------------------------------------------------------- |
|
1088 // |
|
1089 void CMPXCollectionClientContext::HandleOpen( |
|
1090 CMPXMedia* aMedia, |
|
1091 TInt aErr) |
|
1092 { |
|
1093 MPX_FUNC("CMPXCollectionClientContext::HandleOpen with media returned"); |
|
1094 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
1095 MPX_ASSERT(plugin); |
|
1096 |
|
1097 // Callback and Task Completion |
|
1098 // |
|
1099 MMPXCollectionEngineObserver* callback(NULL); |
|
1100 TBool openTask(EFalse); |
|
1101 TInt task = plugin->Task(); |
|
1102 if( task == EMcsOpen || task == EMcsOpenPath || |
|
1103 task == EMcsBack || task == EMcsOpenIndex ) |
|
1104 { |
|
1105 callback = plugin->Callback(); |
|
1106 openTask = ETrue; |
|
1107 } |
|
1108 |
|
1109 // Cachable flag |
|
1110 // |
|
1111 TBool cache(EFalse); |
|
1112 if( iBrowsePath && |
|
1113 iBrowsePath->Levels() >= 1 ) |
|
1114 { |
|
1115 TMPXItemId id(iBrowsePath->Id(CMPXCollectionPath::ECollectionUid) ); |
|
1116 cache = iEngine.PluginCacheable( TUid::Uid( id ) ); |
|
1117 } |
|
1118 |
|
1119 TRAPD(err, DoHandleOpenL(aMedia, NULL, callback, aErr, cache, openTask)); |
|
1120 if (err && openTask) |
|
1121 { |
|
1122 HandleError(*plugin, err); |
|
1123 } |
|
1124 else if( openTask ) |
|
1125 { |
|
1126 plugin->CompleteTask(); |
|
1127 } |
|
1128 } |
|
1129 |
|
1130 // ---------------------------------------------------------------------------- |
|
1131 // Handle open event |
|
1132 // ---------------------------------------------------------------------------- |
|
1133 // |
|
1134 void CMPXCollectionClientContext::HandleOpen( |
|
1135 CMPXMedia* aMedia, |
|
1136 const CMPXCollectionPath* aPath, |
|
1137 TInt aErr) |
|
1138 { |
|
1139 MPX_FUNC("CMPXCollectionClientContext::HandleOpen with media returned"); |
|
1140 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
1141 MPX_ASSERT(plugin); |
|
1142 |
|
1143 // Callback and Task Completion |
|
1144 // |
|
1145 MMPXCollectionEngineObserver* p(NULL); |
|
1146 TBool openTask(EFalse); |
|
1147 TInt task = plugin->Task(); |
|
1148 if( task == EMcsOpen || task == EMcsOpenPath || |
|
1149 task == EMcsBack || task == EMcsOpenIndex ) |
|
1150 { |
|
1151 p = plugin->Callback(); |
|
1152 openTask = ETrue; |
|
1153 } |
|
1154 |
|
1155 // Cachable flag |
|
1156 // |
|
1157 TBool cache(EFalse); |
|
1158 if( iBrowsePath && |
|
1159 iBrowsePath->Levels() >= 1 ) |
|
1160 { |
|
1161 TMPXItemId id(iBrowsePath->Id(CMPXCollectionPath::ECollectionUid) ); |
|
1162 cache = iEngine.PluginCacheable( TUid::Uid( id ) ); |
|
1163 } |
|
1164 |
|
1165 // Handle OpenL for Media |
|
1166 // |
|
1167 TRAPD(err, DoHandleOpenL(aMedia, aPath, p, aErr, cache, openTask)); |
|
1168 if (err && openTask) |
|
1169 { |
|
1170 HandleError(*plugin, err); |
|
1171 } |
|
1172 else if( openTask ) |
|
1173 { |
|
1174 plugin->CompleteTask(); |
|
1175 } |
|
1176 } |
|
1177 |
|
1178 // ---------------------------------------------------------------------------- |
|
1179 // Handle open event |
|
1180 // ---------------------------------------------------------------------------- |
|
1181 // |
|
1182 void CMPXCollectionClientContext::DoHandleOpenL( |
|
1183 CMPXMedia* aMedia, |
|
1184 const CMPXCollectionPath* aPath, |
|
1185 MMPXCollectionEngineObserver* aCallback, |
|
1186 TInt aErr, |
|
1187 TBool aAddToCache, |
|
1188 TBool aOpenTask ) |
|
1189 { |
|
1190 MPX_FUNC("CMPXCollectionClientContext::DoHandleOpen with media returned"); |
|
1191 |
|
1192 // Make sure if we are updating the results the paths are aligned! |
|
1193 // |
|
1194 TBool openUpdate(EFalse); |
|
1195 if( !aOpenTask ) |
|
1196 { |
|
1197 openUpdate = ETrue; |
|
1198 iCacheMedia = ETrue; |
|
1199 if( aPath && |
|
1200 aPath->Levels() != iBrowsePath->Levels() ) |
|
1201 { |
|
1202 User::Leave( KErrArgument ); |
|
1203 } |
|
1204 } |
|
1205 |
|
1206 // Add to cache |
|
1207 // |
|
1208 if ( iBrowsePath->Levels() && aAddToCache && aMedia && iCacheMedia ) |
|
1209 { |
|
1210 // manage the priority |
|
1211 CMPXCollectionCache::TCachePriority priority(CMPXCollectionCache::EPriorityNormal); |
|
1212 if ((1 == iBrowsePath->Levels()) || |
|
1213 ((2 == iBrowsePath->Levels()) && ((iBrowsePath->Id(1)).iId1 == 0))) |
|
1214 { |
|
1215 priority = CMPXCollectionCache::EPriorityHigh; |
|
1216 } |
|
1217 |
|
1218 if( !aOpenTask ) |
|
1219 { |
|
1220 // Update the current browse path |
|
1221 // |
|
1222 CMPXCollectionPath* container = iBrowsePath->ContainerPathL(); |
|
1223 CleanupStack::PushL( container ); |
|
1224 |
|
1225 // Add the data to the generic cache and get the latest copy |
|
1226 // |
|
1227 aMedia = AddToCache( *container, |
|
1228 aMedia->Attributes(), |
|
1229 *aMedia, |
|
1230 ETrue, |
|
1231 priority); |
|
1232 CleanupStack::PopAndDestroy( container ); |
|
1233 } |
|
1234 else |
|
1235 { |
|
1236 AddToCache( *iBrowsePath, |
|
1237 aMedia->Attributes(), |
|
1238 *aMedia, |
|
1239 ETrue, |
|
1240 priority); |
|
1241 } |
|
1242 } |
|
1243 |
|
1244 // Current client context browse path media |
|
1245 // |
|
1246 iMediaType = KMPXCollectionEntries; |
|
1247 if (iMedia != aMedia) |
|
1248 { // new media |
|
1249 delete iMedia; |
|
1250 iMedia = NULL; |
|
1251 if (aMedia) |
|
1252 { |
|
1253 iMedia = CMPXMedia::NewL(*aMedia); |
|
1254 } |
|
1255 } |
|
1256 |
|
1257 TInt n(0); |
|
1258 if (aMedia && KErrNone == aErr) |
|
1259 { // Update the path |
|
1260 RArray<TInt> selectionIndicies; |
|
1261 CleanupClosePushL( selectionIndicies ); |
|
1262 |
|
1263 if (aPath) |
|
1264 { // Update path from aPath |
|
1265 if ( aMedia->IsSupported (KMPXCollectionOpenLAllResultRange)) |
|
1266 { |
|
1267 iBrowsePath->Back (); |
|
1268 RArray<TMPXItemId> ids; |
|
1269 CleanupClosePushL (ids); |
|
1270 RArray<TMPXOpenDataBlock> datablocks; |
|
1271 CleanupClosePushL (datablocks); |
|
1272 // De-serialize from global data, would be good to have global arrays |
|
1273 // |
|
1274 const TDesC |
|
1275 & buf = aMedia->ValueText (KMPXCollectionOpenLAllResultRange); |
|
1276 CBufBase* buffer(NULL); |
|
1277 MPXUser::CreateBufferL ( buf, buffer); |
|
1278 CleanupStack::PushL ( buffer); |
|
1279 ::CreateFromBufferL ( *buffer, datablocks); |
|
1280 CleanupStack::PopAndDestroy ( buffer); |
|
1281 |
|
1282 if ( aMedia->IsSupported (KMPXMediaArrayContents)) |
|
1283 { |
|
1284 const CMPXMediaArray |
|
1285 * mediaArray = aMedia->Value<CMPXMediaArray> (KMPXMediaArrayContents); |
|
1286 User::LeaveIfNull (const_cast<CMPXMediaArray*>(mediaArray)); |
|
1287 TInt dataCount = mediaArray->Count (); |
|
1288 TInt rangeCount = datablocks.Count (); |
|
1289 for (TInt index = 0; index < dataCount; ++index) |
|
1290 { |
|
1291 CMPXMedia* media = mediaArray->AtL(index); |
|
1292 |
|
1293 //Check range |
|
1294 TBool validItem(EFalse); |
|
1295 MPX_ASSERT(rangeCount > 0); |
|
1296 for (TInt rangeIndex = 0; rangeIndex < rangeCount; ++rangeIndex) |
|
1297 { |
|
1298 TInt offset = datablocks[rangeIndex].iOffset; |
|
1299 TInt size = datablocks[rangeIndex].iSize; |
|
1300 if ( (index >= offset) && (index < offset + size)) |
|
1301 { |
|
1302 validItem = ETrue; |
|
1303 break; |
|
1304 } |
|
1305 } |
|
1306 |
|
1307 if (validItem) |
|
1308 { |
|
1309 const TMPXItemId |
|
1310 id = media->ValueTObjectL<TMPXItemId> (KMPXMediaGeneralId); |
|
1311 ids.AppendL (id); |
|
1312 } |
|
1313 else |
|
1314 { |
|
1315 ids.AppendL (KMPXInvalidItemId); |
|
1316 } |
|
1317 } |
|
1318 iBrowsePath->AppendL (ids.Array ()); |
|
1319 } |
|
1320 CleanupStack::PopAndDestroy (&datablocks); |
|
1321 CleanupStack::PopAndDestroy (&ids); |
|
1322 } |
|
1323 else |
|
1324 { |
|
1325 delete iBrowsePath; |
|
1326 iBrowsePath = NULL; |
|
1327 iBrowsePath = CMPXCollectionPath::NewL ( *aPath); |
|
1328 } |
|
1329 } |
|
1330 else |
|
1331 { // Update path from media |
|
1332 RArray<TMPXItemId> ids; |
|
1333 CleanupClosePushL(ids); |
|
1334 if( aMedia->IsSupported(KMPXMediaArrayContents) ) |
|
1335 { |
|
1336 const CMPXMediaArray* mediaArray=aMedia->Value<CMPXMediaArray>( |
|
1337 KMPXMediaArrayContents); |
|
1338 User::LeaveIfNull(const_cast<CMPXMediaArray*>(mediaArray)); |
|
1339 n=mediaArray->Count(); |
|
1340 for (TInt i=0;i<n;++i) |
|
1341 { |
|
1342 CMPXMedia* media=mediaArray->AtL(i); |
|
1343 const TMPXItemId id=media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId); |
|
1344 ids.AppendL(id); |
|
1345 |
|
1346 // Try to look for the selection that we want |
|
1347 if( iFocusItemId == id ) |
|
1348 { |
|
1349 selectionIndicies.AppendL( i ); |
|
1350 } |
|
1351 } |
|
1352 } |
|
1353 |
|
1354 iBrowsePath->AppendL(ids.Array()); |
|
1355 CleanupStack::PopAndDestroy(&ids); |
|
1356 } |
|
1357 |
|
1358 // List of items |
|
1359 const TArray<TMPXItemId>& items = iBrowsePath->Items(); |
|
1360 |
|
1361 // OpenL Media has been updated, update the itemid |
|
1362 // based on the current index |
|
1363 if( openUpdate ) |
|
1364 { |
|
1365 // Check if we have item id first |
|
1366 // |
|
1367 if( iFocusItemId != KMPXInvalidItemId ) |
|
1368 { |
|
1369 TInt index = iBrowsePath->IndexOfId( iFocusItemId ); |
|
1370 if( index != KErrNotFound ) |
|
1371 { |
|
1372 iIndex = index; |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 // Then update based on index |
|
1377 if( iIndex >=0 && iIndex < iBrowsePath->Count() ) |
|
1378 { |
|
1379 iBrowsePath->Set(iIndex); |
|
1380 iFocusItemId = iBrowsePath->Id(); |
|
1381 } |
|
1382 } |
|
1383 else if( aMedia->IsSupported( KMPXCollectionOpenLResultRange ) ) |
|
1384 { |
|
1385 TMPXOpenDataBlock data = |
|
1386 aMedia->ValueTObjectL<TMPXOpenDataBlock>(KMPXCollectionOpenLResultRange); |
|
1387 if( iBrowsePath->Count() && |
|
1388 iIndex >= 0 && |
|
1389 iIndex < iBrowsePath->Count() ) |
|
1390 { |
|
1391 // If all blank items then we don't change index yet |
|
1392 // Wait until we have re-opened the partial data |
|
1393 if( data.iOffset != KErrNotFound ) |
|
1394 { |
|
1395 // Not supported, stay with current focus |
|
1396 iBrowsePath->Set(iIndex); |
|
1397 iFocusItemId = iBrowsePath->Id(); |
|
1398 } |
|
1399 } |
|
1400 } |
|
1401 // If this selection appears more than once, then we have to find |
|
1402 // the closest matching index to what we had before |
|
1403 // |
|
1404 // |
|
1405 else if( selectionIndicies.Count() > 1 && |
|
1406 iFocusItemId != KMPXInvalidItemId ) |
|
1407 { |
|
1408 TInt best(selectionIndicies[0]); |
|
1409 TInt idAppearance( selectionIndicies.Count() ); |
|
1410 for( TInt i=0; i<idAppearance; ++i ) |
|
1411 { |
|
1412 if( Abs(selectionIndicies[i]-iIndex) <= Abs(best-iIndex) ) |
|
1413 { |
|
1414 best = selectionIndicies[i]; |
|
1415 } |
|
1416 } |
|
1417 iIndex = best; |
|
1418 iBrowsePath->Set(iIndex); |
|
1419 } |
|
1420 // Always set by item id if we have it |
|
1421 // This is needed if an item was added to the current browse level |
|
1422 // We still want to select the item we were previously at |
|
1423 // |
|
1424 else if( iFocusItemId != KMPXInvalidItemId ) |
|
1425 { |
|
1426 TInt index = iBrowsePath->IndexOfId(iFocusItemId); |
|
1427 if (KErrNotFound != index) |
|
1428 { |
|
1429 iBrowsePath->Set(index); |
|
1430 } |
|
1431 else if( n > 0 ) // Focus item has been deleted, select next |
|
1432 { |
|
1433 // Bounds check for largest and smallest |
|
1434 if( iIndex >= n ) |
|
1435 { |
|
1436 iIndex = n-1; |
|
1437 } |
|
1438 if( iIndex < 0 ) |
|
1439 { |
|
1440 iIndex = 0; |
|
1441 } |
|
1442 iBrowsePath->Set(iIndex); |
|
1443 iFocusItemId = iBrowsePath->Id(); |
|
1444 } |
|
1445 iIndex = iBrowsePath->Index(); |
|
1446 } |
|
1447 else |
|
1448 { |
|
1449 // Bounds checking for iIndex |
|
1450 if( iIndex >= n && iIndex > 0 ) |
|
1451 { |
|
1452 iIndex = n-1; |
|
1453 |
|
1454 // Just in case if ids has 0 items |
|
1455 if( iIndex > 0 && iIndex < items.Count() ) |
|
1456 { |
|
1457 iFocusItemId = items[iIndex]; |
|
1458 } |
|
1459 } |
|
1460 |
|
1461 if (iBrowsePath->Levels()>0 && iIndex>=0 && |
|
1462 iIndex<iBrowsePath->Count()) |
|
1463 { |
|
1464 iBrowsePath->Set(iIndex); |
|
1465 } |
|
1466 iFocusItemId = iBrowsePath->Id(); |
|
1467 } |
|
1468 CleanupStack::PopAndDestroy(&selectionIndicies); |
|
1469 } |
|
1470 |
|
1471 TInt err; |
|
1472 if( !iPathUpdated ) |
|
1473 { |
|
1474 // Normal open mode |
|
1475 err = KErrNone == aErr ? KMPXPathUpdated : aErr; |
|
1476 } |
|
1477 else |
|
1478 { |
|
1479 // Updates open mode, should be returning entries |
|
1480 err = KErrNone == aErr ? KMPXCollectionEntries : aErr; |
|
1481 } |
|
1482 |
|
1483 // Should not be broadcasting container opened messages |
|
1484 // When we are only rebuilding the leaf level |
|
1485 // |
|
1486 if( !iPathUpdated && aOpenTask ) |
|
1487 { |
|
1488 if( err >= KErrNone) |
|
1489 { |
|
1490 iClientList->SendMsgL( |
|
1491 TMPXCollectionMessage(TMPXCollectionMessage::EPathChanged, |
|
1492 EMcPathChangedByOpen, |
|
1493 EMcContainerOpened)); |
|
1494 } |
|
1495 } |
|
1496 |
|
1497 iPathUpdated = EFalse; |
|
1498 |
|
1499 // Notes: there should no leave function called after aCallback->HandleOpen |
|
1500 if (aCallback) |
|
1501 { // Complete open with error or PathUpdated |
|
1502 aCallback->HandleOpen(iMedia, iIndex, ETrue, err); |
|
1503 if (iPluginUids[EContextBrowse]!=KNullUid) |
|
1504 { |
|
1505 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
1506 MPX_ASSERT(aCallback == plugin->Callback()); |
|
1507 plugin->SetCallback(NULL); |
|
1508 plugin->SetObserver(iEngine); |
|
1509 } |
|
1510 } |
|
1511 MPX_DEBUG_PATH(*iBrowsePath); |
|
1512 } |
|
1513 |
|
1514 // ---------------------------------------------------------------------------- |
|
1515 // Handle open event |
|
1516 // ---------------------------------------------------------------------------- |
|
1517 // |
|
1518 void CMPXCollectionClientContext::HandleOpen( |
|
1519 CMPXCollectionPath* aPath, |
|
1520 TInt aErr) |
|
1521 { |
|
1522 MPX_FUNC("CMPXCollectionClientContext::HandleOpen with path returned"); |
|
1523 TRAPD(err, DoHandleOpenL(aPath, aErr)); |
|
1524 if (err) |
|
1525 { |
|
1526 HandleError(*(LoadedPlugin(EContextBrowse)), err); |
|
1527 } |
|
1528 } |
|
1529 |
|
1530 // ---------------------------------------------------------------------------- |
|
1531 // Handle open event |
|
1532 // ---------------------------------------------------------------------------- |
|
1533 // |
|
1534 void CMPXCollectionClientContext::DoHandleOpenL( |
|
1535 CMPXCollectionPath* aPath, |
|
1536 TInt aErr) |
|
1537 { |
|
1538 MPX_FUNC("CMPXCollectionClientContext::DoHandleOpen with path returned"); |
|
1539 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
1540 MPX_ASSERT(plugin); |
|
1541 |
|
1542 plugin->CompleteTask(); |
|
1543 |
|
1544 if (iBrowsePath != aPath && KErrNone == aErr) |
|
1545 { |
|
1546 delete iBrowsePath; |
|
1547 iBrowsePath = NULL; |
|
1548 MPX_ASSERT(aPath); |
|
1549 iBrowsePath = CMPXCollectionPath::NewL(*aPath); |
|
1550 } |
|
1551 iMediaType = KMPXCollectionPath; |
|
1552 iIndex = iBrowsePath->Index(); |
|
1553 iFocusItemId = iBrowsePath->Id(); |
|
1554 |
|
1555 TInt err = KErrNone == aErr ? KMPXPathUpdated : aErr; |
|
1556 |
|
1557 // Complete msg |
|
1558 // Complete open with error or PathUpdated |
|
1559 plugin->Callback()->HandleOpen(iMedia, iIndex, ETrue, err); |
|
1560 plugin->SetCallback(NULL); |
|
1561 plugin->SetObserver(iEngine); |
|
1562 if (aPath->OpenNextMode() != EMPXOpenNoPlaylist) |
|
1563 // |
|
1564 // The request was NOT to play, but the plug-in returned |
|
1565 // the path implying that we should play; so we don't |
|
1566 // send it |
|
1567 // |
|
1568 { |
|
1569 iClientList->SendMsgL( |
|
1570 TMPXCollectionMessage(TMPXCollectionMessage::EPathChanged, |
|
1571 EMcPathChangedByOpen, |
|
1572 EMcItemOpened)); |
|
1573 } |
|
1574 |
|
1575 MPX_DEBUG_PATH(*iBrowsePath); |
|
1576 } |
|
1577 |
|
1578 // ---------------------------------------------------------------------------- |
|
1579 // Callback of retrieving extended media property |
|
1580 // ---------------------------------------------------------------------------- |
|
1581 // |
|
1582 void CMPXCollectionClientContext::HandleMedia( |
|
1583 CMPXMedia* aMedia, |
|
1584 TInt aError) |
|
1585 { |
|
1586 MPX_FUNC("CMPXCollectionClientContext::HandleMedia"); |
|
1587 |
|
1588 CMPXMedia* ret( aMedia ); |
|
1589 |
|
1590 TBool pluginCacheable(EFalse); |
|
1591 if( iMediaPath ) |
|
1592 { |
|
1593 TMPXItemId id(iMediaPath->Id(CMPXCollectionPath::ECollectionUid) ); |
|
1594 pluginCacheable = iEngine.PluginCacheable( TUid::Uid( id ) ); |
|
1595 |
|
1596 // if media returned was resulted from multiple selections we don't cache the |
|
1597 // results as it's very hard to reuse it anyway |
|
1598 if(iMediaPath->Selection().Count() > 0) |
|
1599 { |
|
1600 pluginCacheable = EFalse; |
|
1601 } |
|
1602 } |
|
1603 |
|
1604 // Cache the media |
|
1605 if ( !aError && aMedia && iCacheMedia && iMediaPath && pluginCacheable ) |
|
1606 { |
|
1607 TMPXItemId id( iMediaPath->Id( |
|
1608 CMPXCollectionPath::ECollectionUid )); |
|
1609 ret = AddToCache( *iMediaPath, aMedia->Attributes(), *aMedia ); |
|
1610 } |
|
1611 |
|
1612 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextMedia); |
|
1613 |
|
1614 plugin->CompleteTask(); |
|
1615 MPX_ASSERT(plugin->Callback()); |
|
1616 plugin->Callback()->HandleMedia(ret, aError); |
|
1617 plugin->SetCallback(NULL); // Reset current observer |
|
1618 plugin->SetObserver(iEngine); |
|
1619 } |
|
1620 |
|
1621 // ---------------------------------------------------------------------------- |
|
1622 // Callback of async CommandL |
|
1623 // ---------------------------------------------------------------------------- |
|
1624 // |
|
1625 void CMPXCollectionClientContext::HandleCommandComplete( |
|
1626 CMPXCommand* aCommandResult, |
|
1627 TInt aError) |
|
1628 { |
|
1629 MPX_FUNC_EX("CMPXCollectionClientContext::HandleCommandComplete"); |
|
1630 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextMedia); |
|
1631 |
|
1632 plugin->CompleteTask(); |
|
1633 MPX_ASSERT(plugin->Callback()); |
|
1634 plugin->Callback()->HandleCommandComplete(aCommandResult, aError); |
|
1635 plugin->SetCallback(NULL); // Reset current observer |
|
1636 plugin->SetObserver(iEngine); |
|
1637 } |
|
1638 |
|
1639 // ---------------------------------------------------------------------------- |
|
1640 // Handle find all |
|
1641 // ---------------------------------------------------------------------------- |
|
1642 // |
|
1643 void CMPXCollectionClientContext::HandleFindAll( |
|
1644 CMPXMedia* aMedia, |
|
1645 TInt aError) |
|
1646 { |
|
1647 MPX_FUNC("CMPXCollectionClientContext::HandleFindAll"); |
|
1648 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextMedia); |
|
1649 plugin->CompleteTask(); |
|
1650 MPX_ASSERT(plugin->Callback()); |
|
1651 plugin->Callback()->HandleFindAll(aMedia, aError); |
|
1652 plugin->SetCallback(NULL); // Reset current observer |
|
1653 plugin->SetObserver(iEngine); |
|
1654 } |
|
1655 |
|
1656 // ---------------------------------------------------------------------------- |
|
1657 // Handle delete all |
|
1658 // ---------------------------------------------------------------------------- |
|
1659 // |
|
1660 void CMPXCollectionClientContext::HandleRemove( |
|
1661 const CDesCArray& aUriArray, |
|
1662 TInt aError) |
|
1663 { |
|
1664 MPX_FUNC("CMPXCollectionClientContext::HandleRemove"); |
|
1665 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextRemove); |
|
1666 |
|
1667 plugin->CompleteTask(); |
|
1668 MPX_ASSERT(plugin->Callback()); |
|
1669 plugin->Callback()->HandleRemove(aUriArray, aError); |
|
1670 plugin->SetCallback(NULL); // Reset current observer |
|
1671 plugin->SetObserver(iEngine); |
|
1672 } |
|
1673 |
|
1674 // ---------------------------------------------------------------------------- |
|
1675 // Execute a async task |
|
1676 // ---------------------------------------------------------------------------- |
|
1677 // |
|
1678 void CMPXCollectionClientContext::ExecuteTask( |
|
1679 TInt aTask, |
|
1680 TInt aParamData, |
|
1681 TAny* aPtrData, |
|
1682 const CBufBase& aBuf, |
|
1683 TAny* aCallback, |
|
1684 CBase* aCObject1, |
|
1685 CBase* aCObject2) |
|
1686 { |
|
1687 MPX_DEBUG2("-->CMPXCollectionClientContext::ExecuteTask %d", aTask); |
|
1688 CMPXCollectionPlugin* plugin(NULL); |
|
1689 TRAPD(err, ExecuteTaskL(aTask, aParamData, aPtrData, aCallback, aBuf, |
|
1690 aCObject1,aCObject2,plugin)); |
|
1691 if (KErrNone !=err) |
|
1692 { |
|
1693 HandleError(*plugin, err, EFalse); |
|
1694 } |
|
1695 MPX_DEBUG1("<--CMPXCollectionClientContext::ExecuteTask"); |
|
1696 } |
|
1697 |
|
1698 // ---------------------------------------------------------------------------- |
|
1699 // Indicates that a task was terminated with an error |
|
1700 // ---------------------------------------------------------------------------- |
|
1701 // |
|
1702 void CMPXCollectionClientContext::HandleTaskError( |
|
1703 TInt aTask, |
|
1704 TAny* aPtrData, |
|
1705 TAny* aCallback, |
|
1706 TInt aError) |
|
1707 { |
|
1708 MPX_FUNC_EX("CMPXCollectionClientContext::HandleTaskError"); |
|
1709 CMPXCollectionPlugin* plugin(NULL); |
|
1710 switch (aTask) |
|
1711 { |
|
1712 case EMcsOpen: |
|
1713 case EMcsBack: |
|
1714 case EMcsOpenIndex: |
|
1715 plugin = LoadedPlugin(EContextBrowse); |
|
1716 plugin->SetObserver(*this); |
|
1717 plugin->SetCallback( |
|
1718 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1719 HandleError(*plugin, aError, EFalse); |
|
1720 break; |
|
1721 case EMcsOpenPath: |
|
1722 case EMcsMediaByPath: |
|
1723 case EMcsCommandExt: |
|
1724 case EMcsRemovePath: |
|
1725 case EMcsFindAll: |
|
1726 case EMcsCommand: |
|
1727 plugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1728 plugin->SetCallback( |
|
1729 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1730 HandleError(*plugin, aError, ETrue); |
|
1731 break; |
|
1732 default: |
|
1733 break; |
|
1734 } |
|
1735 } |
|
1736 |
|
1737 // ---------------------------------------------------------------------------- |
|
1738 // Initialize before first open |
|
1739 // ---------------------------------------------------------------------------- |
|
1740 // |
|
1741 void CMPXCollectionClientContext::InitL(MMPXCollectionEngineObserver* aCallback) |
|
1742 { |
|
1743 MPX_DEBUG1("CMPXCollectionClientContext::InitL() <---"); |
|
1744 delete iMedia; |
|
1745 iMedia = NULL; |
|
1746 delete iBrowsePath; |
|
1747 iBrowsePath = NULL; |
|
1748 RArray<TInt> supportedIds; |
|
1749 CleanupClosePushL(supportedIds); |
|
1750 supportedIds.AppendL(KMPXMediaIdContainer); |
|
1751 supportedIds.AppendL(KMPXMediaIdGeneral); |
|
1752 iMedia=CMPXMedia::NewL(supportedIds.Array()); |
|
1753 iBrowsePath = CMPXCollectionPath::NewL(); |
|
1754 CleanupStack::PopAndDestroy(&supportedIds); |
|
1755 |
|
1756 iEngine.ListPluginsL(*iMedia, iUids.Array()); |
|
1757 if (iPluginUids[EContextBrowse]!=KNullUid ) |
|
1758 { |
|
1759 MPX_DEBUG1("CMPXCollectionClientContext::InitL() Collection changed"); |
|
1760 iClientList->SendMsgL( |
|
1761 TMPXCollectionMessage(TMPXCollectionMessage::ECollectionChanged,0,0)); |
|
1762 } |
|
1763 |
|
1764 // sets the browse plugin to NULL |
|
1765 SetPlugin(EContextBrowse, NULL); |
|
1766 |
|
1767 // Update collection path, and buffer, send path update msg, |
|
1768 // complete request |
|
1769 TRAPD(err, DoHandleOpenL(iMedia, NULL, aCallback, KErrNone, ETrue, ETrue)); |
|
1770 if (err) |
|
1771 { |
|
1772 MPX_DEBUG2("CMPXCollectionClientContext::InitL() Complete Open %i", err); |
|
1773 aCallback->HandleOpen(iMedia, // Not used |
|
1774 iIndex, |
|
1775 ETrue, err); |
|
1776 } |
|
1777 MPX_DEBUG1("CMPXCollectionClientContext::InitL() --->"); |
|
1778 } |
|
1779 |
|
1780 // ---------------------------------------------------------------------------- |
|
1781 // Execute a async task |
|
1782 // ---------------------------------------------------------------------------- |
|
1783 // |
|
1784 void CMPXCollectionClientContext::ExecuteTaskL( |
|
1785 TInt aTask, |
|
1786 TInt aParamData, |
|
1787 TAny* aPtrData, |
|
1788 TAny* aCallback, |
|
1789 const CBufBase& aBuf, |
|
1790 CBase* aCObject1, |
|
1791 CBase* aCObject2, |
|
1792 CMPXCollectionPlugin*& aPlugin) |
|
1793 { |
|
1794 MPX_DEBUG4("CMPXCollectionClientContext::ExecuteTaskL 0x%08x, task %d, aParam %d", |
|
1795 this, aTask, aParamData); |
|
1796 switch (aTask) |
|
1797 { |
|
1798 case EMcsOpen: |
|
1799 { |
|
1800 aPlugin = LoadedPlugin(EContextBrowse); |
|
1801 aPlugin->SetObserver(*this); |
|
1802 aPlugin->SetCallback( |
|
1803 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1804 OpenL(); |
|
1805 break; |
|
1806 } |
|
1807 case EMcsOpenPath: |
|
1808 { |
|
1809 // Set plugin first for handling error |
|
1810 TUid oldUid = iPluginUids[EContextBrowse]; |
|
1811 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1812 // Set plugin and task pointer for browse context |
|
1813 SetPlugin(EContextBrowse, aPlugin); |
|
1814 iPathUpdated = EFalse; |
|
1815 aPlugin->SetObserver(*this); |
|
1816 aPlugin->SetCallback( |
|
1817 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1818 CMPXCollectionPath* path = static_cast<CMPXCollectionPath*>(aCObject1); |
|
1819 delete iBrowsePath; |
|
1820 iBrowsePath = NULL; |
|
1821 iBrowsePath = CMPXCollectionPath::NewL(*path); |
|
1822 SetPathOpenMode(*iBrowsePath, static_cast<TMPXOpenMode>(aParamData)); |
|
1823 |
|
1824 // If the browsing plugin is changing, need to broadcast the |
|
1825 // collection changed message |
|
1826 if (iPluginUids[EContextBrowse] != oldUid) |
|
1827 { |
|
1828 // no leave before plugin API OpenL |
|
1829 TRAP_IGNORE(iClientList->SendMsgL( |
|
1830 TMPXCollectionMessage( |
|
1831 TMPXCollectionMessage::ECollectionChanged,0,iPluginUids[EContextBrowse].iUid))); |
|
1832 } |
|
1833 iIndex=0; |
|
1834 iFocusItemId = KMPXInvalidItemId; |
|
1835 DoPluginOpenL(); |
|
1836 break; |
|
1837 } |
|
1838 case EMcsOpenIndex: |
|
1839 { |
|
1840 // Internalize mode |
|
1841 TInt mode = (TInt)aPtrData; |
|
1842 aPlugin = LoadedPlugin(EContextBrowse); |
|
1843 aPlugin->SetObserver(*this); |
|
1844 aPlugin->SetCallback( |
|
1845 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1846 iBrowsePath->Set(aParamData); |
|
1847 SetPathOpenMode(*iBrowsePath,static_cast<TMPXOpenMode>(mode)); |
|
1848 iIndex=0; |
|
1849 iFocusItemId = KMPXInvalidItemId; |
|
1850 DoPluginOpenL(); |
|
1851 break; |
|
1852 } |
|
1853 case EMcsBack: |
|
1854 { |
|
1855 aPlugin = LoadedPlugin(EContextBrowse); |
|
1856 aPlugin->SetObserver(*this); |
|
1857 aPlugin->SetCallback( |
|
1858 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1859 BackL(); |
|
1860 break; |
|
1861 } |
|
1862 case EMcsMediaByPath: |
|
1863 { |
|
1864 // Setup plugin first for handle error |
|
1865 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1866 SetPlugin(EContextMedia, aPlugin); |
|
1867 |
|
1868 aPlugin->SetObserver(*this); |
|
1869 aPlugin->SetCallback( |
|
1870 static_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1871 // Media path |
|
1872 CMPXCommand* cmd = reinterpret_cast<CMPXCommand*>(aCObject1); |
|
1873 MPX_ASSERT(cmd->IsSupported(KMPXCommandGeneralTargetIds)); |
|
1874 MPX_ASSERT(cmd->IsSupported(KMPXCommandMediaAttributeSpecs)); |
|
1875 CMPXCollectionPath* path = reinterpret_cast<CMPXCollectionPath*>(aCObject2); |
|
1876 CMPXAttributeSpecs* specs = |
|
1877 cmd->Value<CMPXAttributeSpecs>(KMPXCommandMediaAttributeSpecs); |
|
1878 User::LeaveIfNull(specs); |
|
1879 CMPXAttributeSpecs* filter = |
|
1880 cmd->Value<CMPXAttributeSpecs>(KMPXCommandMediaFilter); |
|
1881 User::LeaveIfNull(filter); |
|
1882 TCapabilitySet caps = cmd->ValueTObjectL<TCapabilitySet>(KMPXCommandMediaCapbilitySet); |
|
1883 // Ask plugin for media |
|
1884 DoPluginMediaL( *path, caps, *specs, *filter ); |
|
1885 break; |
|
1886 } |
|
1887 case EMcsRemovePath: |
|
1888 { |
|
1889 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1890 // set the remove plugin |
|
1891 SetPlugin(EContextRemove, aPlugin); |
|
1892 |
|
1893 aPlugin->SetObserver(*this); |
|
1894 CMPXCollectionPath* path = |
|
1895 reinterpret_cast<CMPXCollectionPath*>(aCObject1); |
|
1896 aPlugin->SetCallback( |
|
1897 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1898 aPlugin->RemoveL( *path ); |
|
1899 break; |
|
1900 } |
|
1901 case EMcsFindAll: |
|
1902 { |
|
1903 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1904 // set the media plugin |
|
1905 SetPlugin(EContextMedia, aPlugin); |
|
1906 |
|
1907 aPlugin->SetCallback( |
|
1908 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback)); |
|
1909 CMPXMedia* media = static_cast<CMPXMedia*>(aCObject1); |
|
1910 FindAllL(*media, aBuf, *aPlugin); |
|
1911 break; |
|
1912 } |
|
1913 case EMcsCommand: |
|
1914 { |
|
1915 TMPXCollectionCommand cmd = |
|
1916 static_cast<TMPXCollectionCommand>( aParamData ); |
|
1917 switch( cmd ) |
|
1918 { |
|
1919 case EMcCmdCollectionInit: |
|
1920 case EMcCmdCollectionResyn: |
|
1921 // Decrement the old plugin reference count |
|
1922 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1923 SetPlugin(EContextMedia, aPlugin); |
|
1924 |
|
1925 if( aPlugin ) |
|
1926 { |
|
1927 aPlugin->SetObserver(*this); |
|
1928 aPlugin->CommandL( cmd ); |
|
1929 aPlugin->SetObserver(iEngine); |
|
1930 aPlugin->CompleteTask(); |
|
1931 } |
|
1932 break; |
|
1933 default: |
|
1934 MPX_ASSERT(0); |
|
1935 break; |
|
1936 } |
|
1937 break; |
|
1938 } |
|
1939 case EMcsCommandExt: |
|
1940 { |
|
1941 CMPXCommand* cmd = reinterpret_cast<CMPXCommand*>(aCObject1); |
|
1942 aPlugin = reinterpret_cast<CMPXCollectionPlugin*>(aPtrData); |
|
1943 MMPXCollectionEngineObserver* callback = |
|
1944 reinterpret_cast<MMPXCollectionEngineObserver*>(aCallback); |
|
1945 if( cmd->IsSupported( KMPXCommandGeneralId) ) |
|
1946 { |
|
1947 TMPXCommandId commandId = cmd->ValueTObjectL<TMPXCommandId>(KMPXCommandGeneralId); |
|
1948 // Decrement the old plugin reference count |
|
1949 SetPlugin(EContextMedia, aPlugin); |
|
1950 aPlugin->SetCallback( callback ); |
|
1951 |
|
1952 if( commandId == KMPXCommandIdCollectionSelect ) |
|
1953 { |
|
1954 // Decrement the old plugin reference count |
|
1955 // |
|
1956 DoHandleSelectCommandL( *cmd ); |
|
1957 aPlugin->SetCallback( NULL ); |
|
1958 aPlugin->CompleteTask(); |
|
1959 callback->HandleCommandComplete( NULL, KErrNone ); |
|
1960 } |
|
1961 else |
|
1962 { |
|
1963 aPlugin->SetObserver(*this); |
|
1964 aPlugin->CommandL(*cmd); |
|
1965 } |
|
1966 } |
|
1967 else |
|
1968 { |
|
1969 aPlugin->CompleteTask(); |
|
1970 callback->HandleCommandComplete( NULL, KErrArgument ); // return error message |
|
1971 } |
|
1972 break; |
|
1973 } |
|
1974 default: |
|
1975 break; |
|
1976 } |
|
1977 } |
|
1978 |
|
1979 // ---------------------------------------------------------------------------- |
|
1980 // Error happens upon request |
|
1981 // ---------------------------------------------------------------------------- |
|
1982 // |
|
1983 void CMPXCollectionClientContext::HandleError( |
|
1984 CMPXCollectionPlugin& aPlugin, |
|
1985 TInt aError, |
|
1986 TBool aUnusePlugin/*=EFalse*/) |
|
1987 { |
|
1988 TInt task(aPlugin.Task()); |
|
1989 MPX_DEBUG3("CMPXCollectionClientContext::HandleError %d, task %d", |
|
1990 aError, task); |
|
1991 switch (task) |
|
1992 { |
|
1993 case EMcsOpen: |
|
1994 case EMcsOpenPath: |
|
1995 case EMcsBack: |
|
1996 case EMcsOpenIndex: |
|
1997 aPlugin.Callback()->HandleOpen(iMedia, // Not used |
|
1998 iIndex, |
|
1999 ETrue, aError); |
|
2000 aPlugin.CompleteTask(); |
|
2001 aPlugin.SetCallback(NULL); // Reset current observer |
|
2002 aPlugin.SetObserver(iEngine); |
|
2003 break; |
|
2004 case EMcsMediaByPath: |
|
2005 aPlugin.Callback()->HandleMedia(iMedia, aError); |
|
2006 aPlugin.CompleteTask(); |
|
2007 aPlugin.SetCallback(NULL); // Reset current observer |
|
2008 aPlugin.SetObserver(iEngine); |
|
2009 break; |
|
2010 case EMcsCommandExt: |
|
2011 aPlugin.Callback()->HandleCommandComplete(iMedia, aError); |
|
2012 aPlugin.CompleteTask(); |
|
2013 aPlugin.SetCallback(NULL); // Reset current observer |
|
2014 aPlugin.SetObserver(iEngine); |
|
2015 break; |
|
2016 case EMcsRemovePath: |
|
2017 { |
|
2018 CDesCArray* dummy(NULL); // object will not be dereferenced in callback |
|
2019 aPlugin.Callback()->HandleRemove(*dummy, aError); |
|
2020 aPlugin.SetCallback(NULL); // Reset current observer |
|
2021 aPlugin.SetObserver(iEngine); |
|
2022 aPlugin.CompleteTask(); |
|
2023 } |
|
2024 break; |
|
2025 case EMcsFindAll: |
|
2026 aPlugin.Callback()->HandleFindAll(iMedia, aError); |
|
2027 aPlugin.SetCallback(NULL); // Reset current observer |
|
2028 aPlugin.SetObserver(iEngine); |
|
2029 aPlugin.CompleteTask(); |
|
2030 break; |
|
2031 case EMcsCommand: |
|
2032 { |
|
2033 // At least complete the task to not jam up the task queue |
|
2034 aPlugin.SetCallback(NULL); // Reset current observer |
|
2035 aPlugin.SetObserver(iEngine); |
|
2036 aPlugin.CompleteTask(); |
|
2037 break; |
|
2038 } |
|
2039 default: |
|
2040 break; |
|
2041 } |
|
2042 if (aUnusePlugin) |
|
2043 { |
|
2044 iEngine.ReleasePlugin(aPlugin.Uid()); |
|
2045 } |
|
2046 MPX_DEBUG1("<--CMPXCollectionClientContext::HandleError"); |
|
2047 } |
|
2048 |
|
2049 // ---------------------------------------------------------------------------- |
|
2050 // Error happens upon request |
|
2051 // ---------------------------------------------------------------------------- |
|
2052 // |
|
2053 void CMPXCollectionClientContext::ResolvePluginL( |
|
2054 const CMPXCollectionPath& aPath, |
|
2055 TUid& aUid) |
|
2056 { |
|
2057 CMPXCollectionPlugin* p= iEngine.LoadedPlugin(aUid); // Save old plugin |
|
2058 // Resolve new plugin |
|
2059 CMPXCollectionPlugin* plugin=iEngine.ResolvePluginL(aPath); |
|
2060 // Update with new Uid |
|
2061 aUid = plugin->Uid(); |
|
2062 if (p != plugin && &aPath == iBrowsePath) |
|
2063 { |
|
2064 // browsing plugin changed |
|
2065 iClientList->SendMsgL(TMPXCollectionMessage( |
|
2066 TMPXCollectionMessage::ECollectionChanged,0,aUid.iUid)); |
|
2067 } |
|
2068 |
|
2069 if (p) |
|
2070 { |
|
2071 // Make sure we decrement the reference count for the old plugin |
|
2072 iEngine.ReleasePlugin(p->Uid()); |
|
2073 } |
|
2074 } |
|
2075 |
|
2076 // ---------------------------------------------------------------------------- |
|
2077 // resolve plugin for FindAllL |
|
2078 // ---------------------------------------------------------------------------- |
|
2079 // |
|
2080 void CMPXCollectionClientContext::ResolvePluginL( |
|
2081 const CMPXMedia& aMedia, |
|
2082 CMPXCollectionPlugin*& aPlugin) |
|
2083 { |
|
2084 // We have to be finding from the same context as browse |
|
2085 // if we are from MPX UI |
|
2086 // |
|
2087 if (iPluginUids[EContextBrowse]!=KNullUid) |
|
2088 { |
|
2089 aPlugin = LoadedPlugin(EContextBrowse); |
|
2090 |
|
2091 // Increment the reference count manually |
|
2092 iEngine.UsePlugin(aPlugin->Uid()); |
|
2093 } |
|
2094 else // browse context does not exist |
|
2095 { |
|
2096 if (aMedia.IsSupported(KMPXMediaGeneralCollectionId)) |
|
2097 { |
|
2098 TUid col = aMedia.ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId); |
|
2099 |
|
2100 // Increment the plugin reference count |
|
2101 aPlugin = iEngine.ResolvePluginL(col); |
|
2102 } |
|
2103 else if (aMedia.IsSupported(KMPXMediaGeneralUri)) |
|
2104 { |
|
2105 const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri); |
|
2106 |
|
2107 // Increment the plugin reference count |
|
2108 aPlugin = iEngine.ResolvePluginL(uri); |
|
2109 } |
|
2110 else |
|
2111 { |
|
2112 // Unable to find a collection plugin |
|
2113 User::Leave(KErrNotSupported); |
|
2114 } |
|
2115 } |
|
2116 } |
|
2117 |
|
2118 // ---------------------------------------------------------------------------- |
|
2119 // CMPXCollectionClientContext::SetPlugin |
|
2120 // ---------------------------------------------------------------------------- |
|
2121 // |
|
2122 void CMPXCollectionClientContext::SetPlugin( |
|
2123 TContextType aType, |
|
2124 CMPXCollectionPlugin* aPlugin) |
|
2125 { |
|
2126 if (iPluginUids[aType]!=KNullUid) |
|
2127 { |
|
2128 iEngine.ReleasePlugin(iPluginUids[aType]); |
|
2129 } |
|
2130 if (aPlugin) |
|
2131 { |
|
2132 iPluginUids[aType] = aPlugin->Uid(); |
|
2133 } |
|
2134 else |
|
2135 { |
|
2136 iPluginUids[aType] = KNullUid; |
|
2137 } |
|
2138 } |
|
2139 |
|
2140 // ---------------------------------------------------------------------------- |
|
2141 // Add a media object to the collection |
|
2142 // ---------------------------------------------------------------------------- |
|
2143 // |
|
2144 void CMPXCollectionClientContext::DoUpdateMediaL( TInt aOp, const CMPXMedia& aMedia ) |
|
2145 { |
|
2146 // Media object can be a single "item" or a list of "items" |
|
2147 // |
|
2148 TMPXGeneralType type = EMPXNoType; |
|
2149 if (aMedia.IsSupported(KMPXMediaGeneralType)) |
|
2150 { |
|
2151 type = aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType); |
|
2152 } |
|
2153 else |
|
2154 { |
|
2155 User::Leave(KErrArgument); |
|
2156 } |
|
2157 |
|
2158 if ( type == EMPXGroup ) |
|
2159 { |
|
2160 // Group has to have a "container" |
|
2161 MPX_ASSERT(aMedia.IsSupported(KMPXMediaArrayContents)); |
|
2162 const CMPXMediaArray* array = |
|
2163 aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents); |
|
2164 User::LeaveIfNull(const_cast<CMPXMediaArray*>(array)); |
|
2165 TInt count = array->Count(); |
|
2166 for( TInt i=0; i<count; ++i ) |
|
2167 { |
|
2168 DoUpdateMediaL( aOp, *(array->AtL(i)) ); |
|
2169 } |
|
2170 } |
|
2171 else if ( type == EMPXItem ) |
|
2172 { |
|
2173 DoHandleItemL( aOp, aMedia ); |
|
2174 } |
|
2175 else |
|
2176 { |
|
2177 // How do we handle "group" artists? |
|
2178 User::Leave( KErrNotSupported ); |
|
2179 } |
|
2180 } |
|
2181 |
|
2182 // ---------------------------------------------------------------------------- |
|
2183 // Add the media object to the correct plugin |
|
2184 // ---------------------------------------------------------------------------- |
|
2185 // |
|
2186 void CMPXCollectionClientContext::DoHandleItemL( TInt aOp, const CMPXMedia& aMedia) |
|
2187 { |
|
2188 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL <---"); |
|
2189 |
|
2190 // Find the correct plugin. |
|
2191 // The code below increments the plugin reference count |
|
2192 CMPXCollectionPlugin* plugin(NULL); |
|
2193 if (aMedia.IsSupported(KMPXMediaGeneralCollectionId)) |
|
2194 { |
|
2195 const TUid& uid = aMedia.ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId); |
|
2196 MPX_DEBUG2("CMPXCollectionClientContext::DoHandleItemL Collection %i", uid.iUid); |
|
2197 |
|
2198 // Increment the plugin reference count |
|
2199 plugin = iEngine.ResolvePluginL( uid ); |
|
2200 } |
|
2201 else if (aMedia.IsSupported(KMPXMediaGeneralUri)) |
|
2202 { |
|
2203 const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri); |
|
2204 MPX_DEBUG2("CMPXCollectionClientContext::DoHandleItemL Collection %S", &uri); |
|
2205 |
|
2206 // Increment the plugin reference count |
|
2207 plugin = iEngine.ResolvePluginL( uri ); |
|
2208 } |
|
2209 else |
|
2210 { |
|
2211 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL Cannot resolve a plugin"); |
|
2212 User::Leave(KErrNotSupported); |
|
2213 } |
|
2214 |
|
2215 if( !plugin ) |
|
2216 { |
|
2217 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL Cannot resolve a plugin"); |
|
2218 User::Leave(KErrNotSupported); |
|
2219 } |
|
2220 |
|
2221 iEngine.CleanupPluginPushL(plugin); |
|
2222 |
|
2223 switch( aOp ) |
|
2224 { |
|
2225 case EMcsAddItem: |
|
2226 { |
|
2227 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL Add"); |
|
2228 |
|
2229 plugin->SetObserver(*this); |
|
2230 plugin->AddL( aMedia ); |
|
2231 plugin->SetObserver(iEngine); |
|
2232 break; |
|
2233 } |
|
2234 case EMcsRemoveItem: |
|
2235 { |
|
2236 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL Remove"); |
|
2237 plugin->SetObserver(*this); |
|
2238 plugin->RemoveL( aMedia ); |
|
2239 plugin->SetObserver(iEngine); |
|
2240 break; |
|
2241 } |
|
2242 case EMcsSetMedia: |
|
2243 { |
|
2244 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL Set"); |
|
2245 plugin->SetObserver(*this); |
|
2246 plugin->SetL( aMedia ); |
|
2247 plugin->SetObserver(iEngine); |
|
2248 break; |
|
2249 } |
|
2250 default: |
|
2251 { |
|
2252 User::Leave(KErrNotSupported); |
|
2253 break; |
|
2254 } |
|
2255 } // switch |
|
2256 |
|
2257 CleanupStack::PopAndDestroy(); // plugin |
|
2258 |
|
2259 MPX_DEBUG1("CMPXCollectionClientContext::DoHandleItemL --->"); |
|
2260 } |
|
2261 |
|
2262 // ---------------------------------------------------------------------------- |
|
2263 // Handle a synchorouns command to the collection |
|
2264 // ---------------------------------------------------------------------------- |
|
2265 // |
|
2266 void CMPXCollectionClientContext::DoHandleSyncCommandL( |
|
2267 const CMPXCommand& aCmd, |
|
2268 const CMPXMessageQueue& aMsgQueue, |
|
2269 CMPXCollectionPlugin* aPlugin/*=NULL*/) |
|
2270 { |
|
2271 // Only process the command if the command id has been defined, |
|
2272 // otherwise leave with KErrArgument |
|
2273 if (aCmd.IsSupported(KMPXCommandGeneralId)) |
|
2274 { |
|
2275 TMPXCommandId commandId = aCmd.ValueTObjectL<TMPXCommandId>(KMPXCommandGeneralId); |
|
2276 switch( commandId ) |
|
2277 { |
|
2278 case KMPXCommandIdCollectionSelect: |
|
2279 { |
|
2280 DoHandleSelectCommandL( aCmd ); |
|
2281 break; |
|
2282 } |
|
2283 |
|
2284 case KMPXCommandSubscriptionAdd: |
|
2285 { |
|
2286 TInt index( iClientList->Find( aMsgQueue )); |
|
2287 CMPXMediaArray* items( |
|
2288 aCmd.Value<CMPXMediaArray>( KMPXCommandSubscriptionAddItems )); |
|
2289 User::LeaveIfNull(items); |
|
2290 CMPXSubscription* subscription( CMPXSubscription::NewL( *items )); |
|
2291 CleanupStack::PushL(subscription); |
|
2292 iClientList->AddSubscriptionL( index, subscription ); // ownership transferred |
|
2293 CleanupStack::Pop(subscription); |
|
2294 break; |
|
2295 } |
|
2296 case KMPXCommandSubscriptionRemove: |
|
2297 { |
|
2298 TInt index( iClientList->Find( aMsgQueue )); |
|
2299 CMPXMediaArray* items( |
|
2300 aCmd.Value<CMPXMediaArray>( KMPXCommandSubscriptionAddItems )); |
|
2301 User::LeaveIfNull(items); |
|
2302 CMPXSubscription* subscription( CMPXSubscription::NewL( *items )); |
|
2303 CleanupStack::PushL(subscription); |
|
2304 iClientList->RemoveSubscriptionL( index, *subscription ); |
|
2305 CleanupStack::PopAndDestroy(subscription); |
|
2306 break; |
|
2307 } |
|
2308 case KMPXCommandSubscriptionRemoveAll: |
|
2309 { |
|
2310 TInt index( iClientList->Find( aMsgQueue )); |
|
2311 iClientList->RemoveAllSubscriptionsL( index ); |
|
2312 break; |
|
2313 } |
|
2314 |
|
2315 case KMPXCommandIdCollectionPrepareDelete: |
|
2316 { |
|
2317 if (aCmd.IsSupported (KMPXCommandCollectionPrepareRemovePath)) |
|
2318 { |
|
2319 CMPXCollectionPath |
|
2320 * path = aCmd.ValueCObjectL<CMPXCollectionPath> (KMPXCommandCollectionPrepareRemovePath); |
|
2321 CleanupStack::PushL(path); |
|
2322 iEngine.ResetCacheL(*path); |
|
2323 CleanupStack::PopAndDestroy(path); |
|
2324 } |
|
2325 break; |
|
2326 } |
|
2327 |
|
2328 default: |
|
2329 { |
|
2330 MPX_ASSERT(aPlugin); |
|
2331 aPlugin->SetObserver(*this); |
|
2332 TRAPD( err, aPlugin->CommandL( const_cast<CMPXCommand&>(aCmd) ) ); |
|
2333 aPlugin->SetObserver(iEngine); |
|
2334 User::LeaveIfError( err ); |
|
2335 break; |
|
2336 } |
|
2337 } |
|
2338 } |
|
2339 else |
|
2340 { |
|
2341 User::Leave(KErrArgument); |
|
2342 } |
|
2343 } |
|
2344 |
|
2345 // ---------------------------------------------------------------------------- |
|
2346 // CMPXCollectionClientContext::DoHandleSelectCommandL |
|
2347 // ---------------------------------------------------------------------------- |
|
2348 // |
|
2349 void CMPXCollectionClientContext::DoHandleSelectCommandL(const CMPXCommand& aCmd) |
|
2350 { |
|
2351 TInt index(iIndex); |
|
2352 |
|
2353 // Selecting a new index |
|
2354 if( aCmd.IsSupported(KMPXCommandCollectionSelectIndex) ) |
|
2355 { |
|
2356 index = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionSelectIndex); |
|
2357 if (iBrowsePath->Levels()<=0) |
|
2358 { |
|
2359 User::Leave(KErrNotReady); |
|
2360 } |
|
2361 if (index<0 || index>=iBrowsePath->Count()) |
|
2362 { |
|
2363 User::Leave(KErrArgument); |
|
2364 } |
|
2365 iBrowsePath->Set(index); |
|
2366 } |
|
2367 // Re-select the current index |
|
2368 else |
|
2369 { |
|
2370 TInt count = iBrowsePath->Count(); |
|
2371 |
|
2372 if( iFocusItemId != KMPXInvalidItemId ) |
|
2373 { |
|
2374 TInt index = iBrowsePath->IndexOfId(iFocusItemId); |
|
2375 if (KErrNotFound != index) |
|
2376 { |
|
2377 iBrowsePath->Set(index); |
|
2378 } |
|
2379 else if( count > 0 ) // Focus item has been deleted, select next |
|
2380 { |
|
2381 // Bounds check for largest and smallest |
|
2382 if( iIndex >= count ) |
|
2383 { |
|
2384 iIndex = count-1; |
|
2385 } |
|
2386 if( iIndex < 0 ) |
|
2387 { |
|
2388 iIndex = 0; |
|
2389 } |
|
2390 iBrowsePath->Set(iIndex); |
|
2391 iFocusItemId = iBrowsePath->Id(); |
|
2392 } |
|
2393 iIndex = iBrowsePath->Index(); |
|
2394 } |
|
2395 else |
|
2396 { |
|
2397 // Bounds checking for iIndex |
|
2398 if( iIndex >= count && iIndex > 0 ) |
|
2399 { |
|
2400 iIndex = count-1; |
|
2401 |
|
2402 // Just in case if ids has 0 items |
|
2403 if( iIndex > 0 && iIndex < count ) |
|
2404 { |
|
2405 iFocusItemId = iBrowsePath->IdOfIndex(iIndex); |
|
2406 } |
|
2407 } |
|
2408 |
|
2409 if (iBrowsePath->Levels()>0 && iIndex>=0 && |
|
2410 iIndex<iBrowsePath->Count()) |
|
2411 { |
|
2412 iBrowsePath->Set(iIndex); |
|
2413 } |
|
2414 iFocusItemId = iBrowsePath->Id(); |
|
2415 } |
|
2416 } |
|
2417 iClientList->SendMsgL( |
|
2418 TMPXCollectionMessage(TMPXCollectionMessage::EFocusChanged, |
|
2419 index, index)); |
|
2420 iIndex = index; // iIndex will always be up to date |
|
2421 iFocusItemId = iBrowsePath->Id(); |
|
2422 } |
|
2423 |
|
2424 // ---------------------------------------------------------------------------- |
|
2425 // CMPXCollectionClientContext::DoPluginOpenL |
|
2426 // ---------------------------------------------------------------------------- |
|
2427 // |
|
2428 void CMPXCollectionClientContext::DoPluginOpenL() |
|
2429 { |
|
2430 MPX_FUNC("CMPXCollectionClientContext::DoPluginOpenL()"); |
|
2431 TBool callOpen(ETrue); |
|
2432 MPX_ASSERT(iPluginUids[EContextBrowse]!=KNullUid); |
|
2433 TBool pluginCacheable(EFalse); |
|
2434 if( iBrowsePath ) |
|
2435 { |
|
2436 TMPXItemId id(iBrowsePath->Id(CMPXCollectionPath::ECollectionUid) ); |
|
2437 pluginCacheable = iEngine.PluginCacheable( TUid::Uid( id ) ); |
|
2438 } |
|
2439 |
|
2440 // Check for open playlist only mode. If in that mode, do not return the media |
|
2441 // from the cache but call the plugin to open, as that will callback a |
|
2442 // different HandleOpenL() with the collection path instead. |
|
2443 TMPXOpenMode mode( iBrowsePath->OpenNextMode() ); |
|
2444 CMPXCollectionPlugin* plugin = LoadedPlugin(EContextBrowse); |
|
2445 if ( !iFilter && mode != EMPXOpenPlaylistOnly ) |
|
2446 { |
|
2447 // try to get the results from the cache only if the plugin is cacheable |
|
2448 if ( pluginCacheable ) |
|
2449 { |
|
2450 CMPXMedia* results( iCache.GetL( *iBrowsePath, |
|
2451 iBrowsePath->OpenAttributes(), |
|
2452 ETrue )); |
|
2453 if (results) |
|
2454 { |
|
2455 MPX_DEBUG1("CMPXCollectionClientContext::DoPluginOpenL(): Results found in cache"); |
|
2456 MMPXCollectionEngineObserver* callback = plugin->Callback(); |
|
2457 plugin->CompleteTask(); |
|
2458 TRAPD(err, DoHandleOpenL(results, NULL, callback, KErrNone, EFalse, ETrue)); |
|
2459 if (err) |
|
2460 { |
|
2461 HandleError(*plugin, err); |
|
2462 } |
|
2463 |
|
2464 callOpen = EFalse; |
|
2465 } |
|
2466 } |
|
2467 } |
|
2468 |
|
2469 if (callOpen) |
|
2470 { |
|
2471 if ( pluginCacheable ) |
|
2472 { |
|
2473 iCacheMedia = AttributesCacheableL( iBrowsePath->OpenAttributes(), *iBrowsePath ); |
|
2474 } |
|
2475 plugin->OpenL(*iBrowsePath, iBrowsePath->OpenAttributes(), iFilter); |
|
2476 } |
|
2477 } |
|
2478 |
|
2479 // ---------------------------------------------------------------------------- |
|
2480 // CMPXCollectionClientContext::DoPluginMediaL |
|
2481 // ---------------------------------------------------------------------------- |
|
2482 // |
|
2483 void CMPXCollectionClientContext::DoPluginMediaL( |
|
2484 CMPXCollectionPath& aPath, |
|
2485 const TCapabilitySet& aCaps, |
|
2486 CMPXAttributeSpecs& aSpecs, |
|
2487 CMPXFilter& aFilter) |
|
2488 { |
|
2489 MPX_FUNC("CMPXCollectionClientContext::DoPluginMediaL()"); |
|
2490 TBool callMedia(ETrue); |
|
2491 delete iMediaPath; |
|
2492 iMediaPath = NULL; |
|
2493 |
|
2494 TMPXItemId id(aPath.Id(CMPXCollectionPath::ECollectionUid) ); |
|
2495 TBool pluginCacheable( iEngine.PluginCacheable( TUid::Uid( id ) )); |
|
2496 |
|
2497 // try to get the results from the cache only if |
|
2498 // the plugin is cacheable |
|
2499 CMPXMedia* results( NULL ); |
|
2500 if ( pluginCacheable ) |
|
2501 { |
|
2502 results = iCache.GetL( aPath, aPath.OpenAttributes() ); |
|
2503 |
|
2504 if (results) |
|
2505 { |
|
2506 // Check if the attribute specs match |
|
2507 if ( aSpecs.Count() > 0 ) |
|
2508 { |
|
2509 /* |
|
2510 // need to check if requested attribute specs |
|
2511 // match what we have cached |
|
2512 if ( results->IsSupported( KMPXCommandMediaAttributeSpecs )) |
|
2513 { |
|
2514 CMPXAttributeSpecs* specs( results->Value<CMPXAttributeSpecs>( |
|
2515 KMPXCommandMediaAttributeSpecs )); |
|
2516 User::LeaveIfNull(specs); |
|
2517 if ( *specs == *aSpecs ) |
|
2518 { |
|
2519 callMedia = EFalse; |
|
2520 } |
|
2521 } |
|
2522 */ |
|
2523 } |
|
2524 else |
|
2525 { |
|
2526 // Else client did not specify attribute specs, so we can return |
|
2527 // the match |
|
2528 callMedia = EFalse; |
|
2529 } |
|
2530 } |
|
2531 } |
|
2532 |
|
2533 if ( callMedia ) |
|
2534 { |
|
2535 iMediaPath = CMPXCollectionPath::NewL( aPath ); |
|
2536 |
|
2537 if ( pluginCacheable ) |
|
2538 { |
|
2539 iCacheMedia = AttributesCacheableL( aPath.OpenAttributes(), aPath ); |
|
2540 } |
|
2541 LoadedPlugin(EContextMedia)->MediaL( aPath, |
|
2542 aPath.OpenAttributes(), |
|
2543 aCaps, |
|
2544 &aSpecs, |
|
2545 &aFilter); |
|
2546 } |
|
2547 else |
|
2548 { |
|
2549 HandleMedia( results, KErrNone ); |
|
2550 } |
|
2551 } |
|
2552 |
|
2553 |
|
2554 // ---------------------------------------------------------------------------- |
|
2555 // CMPXCollectionClientContext::AttributesCacheableL |
|
2556 // ---------------------------------------------------------------------------- |
|
2557 // |
|
2558 TBool CMPXCollectionClientContext::AttributesCacheableL( |
|
2559 const TArray<TMPXAttribute>& aAttrs, |
|
2560 const CMPXCollectionPath& aPath ) |
|
2561 { |
|
2562 MPX_DEBUG1("-->CMPXCollectionClientContext::AttributesCacheableL"); |
|
2563 |
|
2564 TMPXItemId id( aPath.Id( CMPXCollectionPath::ECollectionUid )); |
|
2565 const TArray<TUid>& nonCacheAttrs( iEngine.PluginNonCacheableAttributesL( TUid::Uid( id ))); |
|
2566 |
|
2567 TBool found( EFalse ); |
|
2568 TInt nonCacheCount( nonCacheAttrs.Count() ); |
|
2569 for ( TInt i = 0; i < nonCacheCount && !found; i++ ) |
|
2570 { |
|
2571 TInt attrCount( aAttrs.Count() ); |
|
2572 for ( TInt j = 0; j < attrCount && !found; j++ ) |
|
2573 { |
|
2574 TMPXAttribute att( aAttrs[j] ); |
|
2575 if ( nonCacheAttrs[i] == TUid::Uid( att.ContentId() )) |
|
2576 { |
|
2577 found = ETrue; |
|
2578 } |
|
2579 } |
|
2580 } |
|
2581 MPX_DEBUG1("<--CMPXCollectionClientContext::AttributesCacheableL"); |
|
2582 return !found; |
|
2583 } |
|
2584 |
|
2585 // ---------------------------------------------------------------------------- |
|
2586 // CMPXCollectionClientContext::AddToCache |
|
2587 // ---------------------------------------------------------------------------- |
|
2588 // |
|
2589 CMPXMedia* CMPXCollectionClientContext::AddToCache( |
|
2590 const CMPXCollectionPath& aPath, |
|
2591 const TArray<TMPXAttribute>& aAttrs, |
|
2592 CMPXMedia& aResults, |
|
2593 TBool aMediaFromOpenL, |
|
2594 CMPXCollectionCache::TCachePriority aPriority /* = EPriorityNormal */) |
|
2595 { |
|
2596 CMPXMedia* ret( &aResults ); |
|
2597 TRAP_IGNORE(ret = iCache.AddL(aPath, aAttrs, aResults, aMediaFromOpenL, aPriority)); |
|
2598 return ret; |
|
2599 } |
|
2600 |
|
2601 // ---------------------------------------------------------------------------- |
|
2602 // CMPXCollectionClientContext::LoadedPlugin |
|
2603 // ---------------------------------------------------------------------------- |
|
2604 // |
|
2605 CMPXCollectionPlugin* CMPXCollectionClientContext::LoadedPlugin(TContextType aType) |
|
2606 { |
|
2607 MPX_ASSERT(iPluginUids[aType]!=KNullUid); |
|
2608 CMPXCollectionPlugin* plugin(iEngine.LoadedPlugin(iPluginUids[aType])); |
|
2609 MPX_ASSERT(plugin); |
|
2610 return plugin; |
|
2611 } |
|
2612 |
|
2613 // End of file |