|
1 /* |
|
2 * Copyright (c) 2007-2008 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: Utility that contains HUI related slideshow code |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDES |
|
22 #include "shwthumbnailloader.h" |
|
23 |
|
24 // DEPENDENCIES |
|
25 #include <mpxattributespecs.h> |
|
26 #include <mpxmediadrmdefs.h> |
|
27 #include <glxlog.h> |
|
28 #include <glxtracer.h> |
|
29 |
|
30 #include <glxmedialistiterator.h> |
|
31 #include <mglxmedialistobserver.h> |
|
32 #include <mglxmedialist.h> |
|
33 #include <glxthumbnailcontext.h> |
|
34 #include <glxattributecontext.h> |
|
35 #include <glxmediageneraldefs.h> |
|
36 #include <glxattributeretriever.h> |
|
37 |
|
38 #include "shwslideshowenginepanic.h" |
|
39 #include "shwthumbnailcontext.h" |
|
40 #include "shwcallback.h" |
|
41 |
|
42 #include "shwconstants.h" // for context priorities |
|
43 |
|
44 using namespace NShwSlideshow; |
|
45 |
|
46 /** |
|
47 * CShwThumbnailLoaderImpl |
|
48 * Implementation dependencies for the thumbnail loading |
|
49 */ |
|
50 NONSHARABLE_CLASS( CShwThumbnailLoader::CShwThumbnailLoaderImpl ) |
|
51 : public CBase, |
|
52 public MGlxMediaListObserver |
|
53 { |
|
54 public: |
|
55 |
|
56 /** |
|
57 * Constructor |
|
58 * inlined as only ever called inside this cpp |
|
59 * @param aMedialist the media list |
|
60 */ |
|
61 inline CShwThumbnailLoaderImpl( |
|
62 MGlxMediaList& aMedialist, |
|
63 MShwThumbnailLoadObserver& aErrorHandler ); |
|
64 |
|
65 /** |
|
66 * Destructor. |
|
67 * inlined as only ever called inside this cpp |
|
68 */ |
|
69 inline ~CShwThumbnailLoaderImpl(); |
|
70 |
|
71 /** |
|
72 * 2nd phase constructor |
|
73 * inlined as only ever called inside this cpp |
|
74 */ |
|
75 inline void ConstructL(); |
|
76 |
|
77 /** |
|
78 * @ref CShwThumbnailLoader::LoadAndNotifyL |
|
79 * inlined as only ever called inside this cpp |
|
80 */ |
|
81 inline void LoadAndNotifyL( TInt aIndex, TSize aSize ); |
|
82 |
|
83 /** |
|
84 * @ref CShwThumbnailLoader::Unload |
|
85 * inlined as only ever called inside this cpp |
|
86 */ |
|
87 inline void Unload( TInt aIndex ); |
|
88 |
|
89 /** |
|
90 * @ref CShwThumbnailLoader::ImageSizeL |
|
91 * inlined as only ever called inside this cpp |
|
92 */ |
|
93 inline TSize ImageSizeL( TInt aIndex ); |
|
94 |
|
95 public: // from MGlxMediaListObserver |
|
96 |
|
97 /// @ref MGlxMediaListObserver::HandleItemAddedL |
|
98 void HandleItemAddedL( |
|
99 TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList ); |
|
100 /// @ref MGlxMediaListObserver::HandleMediaL |
|
101 void HandleMediaL( |
|
102 TInt aListIndex, MGlxMediaList* aList ); |
|
103 /// @ref MGlxMediaListObserver::HandleItemRemovedL |
|
104 void HandleItemRemovedL( |
|
105 TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList ); |
|
106 /// @ref MGlxMediaListObserver::HandleItemModifiedL |
|
107 void HandleItemModifiedL( |
|
108 const RArray<TInt>& aItemIndexes, MGlxMediaList* aList ); |
|
109 /// @ref MGlxMediaListObserver::HandleAttributesAvailableL |
|
110 void HandleAttributesAvailableL( |
|
111 TInt aItemIndex, |
|
112 const RArray<TMPXAttribute>& aAttributes, |
|
113 MGlxMediaList* aList ); |
|
114 /// @ref MGlxMediaListObserver::HandleFocusChangedL |
|
115 void HandleFocusChangedL( |
|
116 NGlxListDefs::TFocusChangeType aType, |
|
117 TInt aNewIndex, |
|
118 TInt aOldIndex, |
|
119 MGlxMediaList* aList ); |
|
120 /// @ref MGlxMediaListObserver::HandleItemSelectedL |
|
121 void HandleItemSelectedL( |
|
122 TInt aIndex, TBool aSelected, MGlxMediaList* aList ); |
|
123 /// @ref MGlxMediaListObserver::HandleMessageL |
|
124 void HandleMessageL( |
|
125 const CMPXMessage& aMessage, MGlxMediaList* aList ); |
|
126 /// @ref MGlxMediaListObserver::HandleError |
|
127 void HandleError( TInt aError ); |
|
128 |
|
129 private: // Implementation |
|
130 |
|
131 // implementation of the error handler |
|
132 inline void DoHandleErrorL(); |
|
133 // Helper functions to find an element in the array given an index |
|
134 // used in three places, load, unload and handleattributes available |
|
135 // @param the index of the element to find |
|
136 // @return the index of the element in the array, KErrNotFound otherwise |
|
137 inline TInt Find( TInt aIndex ); |
|
138 // @return the context if found, NULL otherwise |
|
139 inline CShwThumbnailContext* FindContext( TInt aIndex ); |
|
140 // Helper function to create the size context |
|
141 inline void AddSizeContextL(); |
|
142 /// Helper function to notify client of successfull or failed thumbnail load |
|
143 inline void NofifyClientIfInterestedL( TInt aIndex, TBool aSuccess ); |
|
144 // Helper function to remove high quality context from given index |
|
145 inline void RemoveHighQualityContext( TInt aIndex ); |
|
146 |
|
147 public: // TCallBack API |
|
148 |
|
149 // Helper function to notify thumbnail completion asynchronously |
|
150 inline TInt CompletedNotifyL(); |
|
151 // Helper function to notify thumbnail failure asynchronously |
|
152 inline TInt ErrorNotifyL(); |
|
153 // Helper function to handle the error |
|
154 inline TInt AsyncErrorHandleL(); |
|
155 |
|
156 private: // Implementation & Data |
|
157 |
|
158 /// Ref: the media list |
|
159 MGlxMediaList& iMedialist; |
|
160 /// Ref: the error handler |
|
161 MShwThumbnailLoadObserver& iThumbnailObserver; |
|
162 /// Own: the array for the thumbnail notifications |
|
163 RArray< TInt > iNotificationIndexes; |
|
164 /// Own: the array for already completed indexes |
|
165 RArray< TInt > iCompletedIndexes; |
|
166 /// Own: the array for already faulty indexes |
|
167 RArray< TInt > iErrorIndexes; |
|
168 /// Own: the array of high quality contexts |
|
169 RPointerArray< CShwThumbnailContext > iHighQualityContexts; |
|
170 /// Own: the size context |
|
171 CGlxDefaultAttributeContext* iSizeContext; |
|
172 /// Own: async callback needed in case image is already loaded |
|
173 CAsyncCallBack* iCompletedCallBack; |
|
174 /// Own: async callback needed in case image had already an error |
|
175 CAsyncCallBack* iErrorCallBack; |
|
176 /// Own: async callback for showing the out of memory system dialog |
|
177 CAsyncCallBack* iErrorHandlerCallBack; |
|
178 /// Own: the error code |
|
179 TInt iError; |
|
180 |
|
181 }; |
|
182 |
|
183 // ----------------------------------------------------------------------------- |
|
184 // C++ Constructor. Save a few bits of rom with inlining |
|
185 // ----------------------------------------------------------------------------- |
|
186 inline CShwThumbnailLoader::CShwThumbnailLoader() |
|
187 { |
|
188 } |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // NewL. Static construction |
|
192 // ----------------------------------------------------------------------------- |
|
193 CShwThumbnailLoader* CShwThumbnailLoader::NewL( |
|
194 MGlxMediaList& aMedialist, MShwThumbnailLoadObserver& aErrorHandler ) |
|
195 { |
|
196 TRACER("CShwThumbnailLoader::NewLs"); |
|
197 GLX_LOG_INFO( "CShwThumbnailLoader::NewL" ); |
|
198 CShwThumbnailLoader* self = new( ELeave ) CShwThumbnailLoader; |
|
199 CleanupStack::PushL( self ); |
|
200 |
|
201 // 2nd phase >> |
|
202 // create implementation |
|
203 self->iImpl = |
|
204 new( ELeave ) CShwThumbnailLoaderImpl( aMedialist, aErrorHandler ); |
|
205 // call 2nd phase |
|
206 self->iImpl->ConstructL(); |
|
207 // << 2nd phase |
|
208 |
|
209 // pop the stack |
|
210 CleanupStack::Pop( self ); |
|
211 return self; |
|
212 } |
|
213 |
|
214 // ----------------------------------------------------------------------------- |
|
215 // Destructor |
|
216 // ----------------------------------------------------------------------------- |
|
217 CShwThumbnailLoader::~CShwThumbnailLoader() |
|
218 { |
|
219 TRACER("CShwThumbnailLoader::~CShwThumbnailLoader"); |
|
220 GLX_LOG_INFO( "CShwThumbnailLoader::~CShwThumbnailLoader" ); |
|
221 delete iImpl; |
|
222 } |
|
223 |
|
224 // ----------------------------------------------------------------------------- |
|
225 // LoadThumbnailAndNotifyL. |
|
226 // ----------------------------------------------------------------------------- |
|
227 void CShwThumbnailLoader::LoadAndNotifyL( TInt aIndex, TSize aSize ) |
|
228 { |
|
229 TRACER("CShwThumbnailLoader::LoadAndNotifyL"); |
|
230 GLX_LOG_INFO( "CShwThumbnailLoader::LoadAndNotifyL" ); |
|
231 // forward |
|
232 iImpl->LoadAndNotifyL( aIndex, aSize ); |
|
233 } |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // Unload. |
|
237 // ----------------------------------------------------------------------------- |
|
238 void CShwThumbnailLoader::Unload( TInt aIndex ) |
|
239 { |
|
240 TRACER("CShwThumbnailLoader::Unload"); |
|
241 GLX_LOG_INFO( "CShwThumbnailLoader::Unload" ); |
|
242 // forward |
|
243 iImpl->Unload( aIndex ); |
|
244 } |
|
245 |
|
246 // ----------------------------------------------------------------------------- |
|
247 // CShwThumbnailLoaderImpl::ImageSizeL. |
|
248 // ----------------------------------------------------------------------------- |
|
249 TSize CShwThumbnailLoader::ImageSizeL( TInt aIndex ) |
|
250 { |
|
251 TRACER("CShwThumbnailLoader::ImageSizeL"); |
|
252 GLX_LOG_INFO( "CShwThumbnailLoader::ImageSizeL" ); |
|
253 // forward |
|
254 return iImpl->ImageSizeL( aIndex ); |
|
255 } |
|
256 |
|
257 // ----------------------------------------------------------------------------- |
|
258 // CShwThumbnailLoaderImpl::C++ Constructor. Save a few bits of rom with inlining |
|
259 // ----------------------------------------------------------------------------- |
|
260 inline CShwThumbnailLoader::CShwThumbnailLoaderImpl::CShwThumbnailLoaderImpl( |
|
261 MGlxMediaList& aMedialist, MShwThumbnailLoadObserver& aErrorHandler ) |
|
262 : iMedialist( aMedialist ), |
|
263 iThumbnailObserver( aErrorHandler ) |
|
264 { |
|
265 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::CShwThumbnailLoaderImpl()"); |
|
266 } |
|
267 |
|
268 // ----------------------------------------------------------------------------- |
|
269 // CShwThumbnailLoaderImpl::Destructor. |
|
270 // ----------------------------------------------------------------------------- |
|
271 inline CShwThumbnailLoader::CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl() |
|
272 { |
|
273 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl()"); |
|
274 GLX_LOG_INFO( "CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl" ); |
|
275 // delete asynch callbacks, delete also cancels them |
|
276 delete iCompletedCallBack; |
|
277 delete iErrorCallBack; |
|
278 delete iErrorHandlerCallBack; |
|
279 |
|
280 // size context, remove NULL does nothing |
|
281 iMedialist.RemoveContext( iSizeContext ); |
|
282 delete iSizeContext; |
|
283 |
|
284 // Remove all contexts from the media list |
|
285 TInt count = iHighQualityContexts.Count(); |
|
286 while ( count-- > 0 ) |
|
287 { |
|
288 // get the fetch context so that we can remove it from the media list |
|
289 MGlxFetchContext* context = iHighQualityContexts[ count ]->Context(); |
|
290 // high quality context, remove NULL does nothing |
|
291 iMedialist.RemoveContext( context ); |
|
292 }; |
|
293 // delete the contexts array, this deletes the CShwThumbnailContexts |
|
294 iHighQualityContexts.ResetAndDestroy(); |
|
295 |
|
296 // remove us from media list observers |
|
297 iMedialist.RemoveMediaListObserver( this ); |
|
298 |
|
299 // close notification indexes array |
|
300 iNotificationIndexes.Close(); |
|
301 // close also the already completed indexes array |
|
302 iCompletedIndexes.Close(); |
|
303 // close also the errornous indexes array |
|
304 iErrorIndexes.Close(); |
|
305 } |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // CShwThumbnailLoaderImpl::ConstructL |
|
309 // ----------------------------------------------------------------------------- |
|
310 inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL() |
|
311 { |
|
312 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL"); |
|
313 GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL" ); |
|
314 // retrieve the size of images with own context |
|
315 AddSizeContextL(); |
|
316 |
|
317 // add us as media list observer |
|
318 iMedialist.AddMediaListObserverL( this ); |
|
319 |
|
320 // create async callback object to give |
|
321 // callbacks once scheduler runs, give this high priority so that it |
|
322 // is faster than the timers we have |
|
323 iCompletedCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); |
|
324 // set the callback |
|
325 iCompletedCallBack->Set( |
|
326 TShwCallBack< CShwThumbnailLoaderImpl, CompletedNotifyL >( this ) ); |
|
327 |
|
328 // create async callback to give error callbacks once scheduler runs |
|
329 iErrorCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); |
|
330 // set the callback |
|
331 iErrorCallBack->Set( |
|
332 TShwCallBack< CShwThumbnailLoaderImpl, ErrorNotifyL >( this ) ); |
|
333 |
|
334 // create async callback to give callback once we run onto errors |
|
335 iErrorHandlerCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); |
|
336 // set the callback |
|
337 iErrorHandlerCallBack->Set( |
|
338 TShwCallBack< CShwThumbnailLoaderImpl, AsyncErrorHandleL >( this ) ); |
|
339 } |
|
340 |
|
341 // ----------------------------------------------------------------------------- |
|
342 // CShwThumbnailLoaderImpl::ImageSizeL. |
|
343 // ----------------------------------------------------------------------------- |
|
344 inline TSize CShwThumbnailLoader::CShwThumbnailLoaderImpl::ImageSizeL( |
|
345 TInt aIndex ) |
|
346 { |
|
347 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ImageSizeL"); |
|
348 GLX_LOG_INFO1( "CShwThumbnailLoader::ImageSizeL for index %d", aIndex ); |
|
349 |
|
350 // default to KErrNotFound |
|
351 TSize size( KErrNotFound, KErrNotFound ); |
|
352 |
|
353 // get the media item |
|
354 TGlxMedia item = iMedialist.Item( aIndex ); |
|
355 // get its dimensions, if they are not available, size is not modified |
|
356 // if size is not available, GetDimensions returns EFalse |
|
357 if( !item.GetDimensions( size ) ) |
|
358 { |
|
359 // size was not available so try to fetch it with attribute retriever |
|
360 (void)GlxAttributeRetriever::RetrieveL( |
|
361 *iSizeContext, iMedialist, |
|
362 EFalse /*aShowDialog*/ ); |
|
363 // get the media item again since its just a copy and the old one |
|
364 // might not have had the CGlxMedia* set |
|
365 item = iMedialist.Item( aIndex ); |
|
366 // cast to (void) tells the compiler we ignore |
|
367 // the fetcher error as there is nothing to do if the fetch fails |
|
368 // in that case the size will be (KErrNotFound,KErrNotFound) |
|
369 // try getting the dimensions again |
|
370 (void)item.GetDimensions( size ); |
|
371 } |
|
372 |
|
373 GLX_LOG_INFO2( |
|
374 "CShwThumbnailLoader::ImageSizeL (%d,%d)", size.iWidth, size.iHeight ); |
|
375 |
|
376 return size; |
|
377 } |
|
378 |
|
379 // ----------------------------------------------------------------------------- |
|
380 // CShwThumbnailLoaderImpl::LoadAndNotifyL. |
|
381 // ----------------------------------------------------------------------------- |
|
382 inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::LoadAndNotifyL( |
|
383 TInt aIndex, TSize aSize ) |
|
384 { |
|
385 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::LoadAndNotifyL"); |
|
386 GLX_LOG_INFO1( "CShwThumbnailLoader::LoadAndNotifyL %d", aIndex ); |
|
387 |
|
388 // check whether a context already exists for this index |
|
389 CShwThumbnailContext* context = FindContext( aIndex ); |
|
390 if( !context ) |
|
391 { |
|
392 // create new context for the index with the given size |
|
393 context = CShwThumbnailContext::NewLC( aIndex, aSize ); |
|
394 iHighQualityContexts.AppendL( context ); |
|
395 CleanupStack::Pop( context ); |
|
396 // add the context to the medialist with priority |
|
397 iMedialist.AddContextL( |
|
398 context->Context(), KHighQualityContextPriority ); |
|
399 } |
|
400 |
|
401 // add the index to notifications array so that we know to give |
|
402 // either success or error notification once for the request |
|
403 // Note that we can have multiple requests for same index |
|
404 iNotificationIndexes.InsertInOrderAllowRepeatsL( aIndex ); |
|
405 |
|
406 // need to check if the thumbnail is already loaded |
|
407 // when request count is zero (KErrNone) the thumbnail is fully loaded |
|
408 TInt requestCount = context->RequestCountL( &iMedialist ); |
|
409 if( requestCount == KErrNone ) |
|
410 { |
|
411 // thumbnail is already there |
|
412 // we cant give the callback right away as the client is expecting |
|
413 // this method to be always asynchronous |
|
414 GLX_LOG_INFO1( |
|
415 "CShwThumbnailLoader::Thumbnail already loaded %d", aIndex ); |
|
416 // insert index to completed array |
|
417 // Note that we can have multiple requests for same index |
|
418 iCompletedIndexes.InsertInOrderAllowRepeatsL( aIndex ); |
|
419 // cancel the old callback |
|
420 iCompletedCallBack->Cancel(); |
|
421 // make the callback |
|
422 iCompletedCallBack->CallBack(); |
|
423 } |
|
424 else if ( requestCount < KErrNone ) |
|
425 { |
|
426 // thumbnail had already and error |
|
427 GLX_LOG_INFO2( |
|
428 "CShwThumbnailLoader::Thumbnail error %d at index, %d", |
|
429 requestCount, aIndex ); |
|
430 // we cant give the callback right away as the client is expecting |
|
431 // this method to be always asynchronous |
|
432 // Note that we can have multiple requests for same index |
|
433 iErrorIndexes.InsertInOrderAllowRepeatsL( aIndex ); |
|
434 // cancel the old callback |
|
435 iErrorCallBack->Cancel(); |
|
436 // make the callback |
|
437 iErrorCallBack->CallBack(); |
|
438 } |
|
439 } |
|
440 |
|
441 // ----------------------------------------------------------------------------- |
|
442 // CShwThumbnailLoaderImpl::Unload |
|
443 // ----------------------------------------------------------------------------- |
|
444 inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::Unload( TInt aIndex ) |
|
445 { |
|
446 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::Unload"); |
|
447 GLX_LOG_INFO1( "CShwThumbnailLoader::Unload %d", aIndex ); |
|
448 |
|
449 // client is no longer interested on this indes so remove it from the |
|
450 // notifications |
|
451 TInt index; |
|
452 while( ( index = iNotificationIndexes.Find( aIndex ) ) != KErrNotFound ) |
|
453 { |
|
454 // remove the index from array |
|
455 iNotificationIndexes.Remove( index ); |
|
456 } |
|
457 |
|
458 // remove context for this index |
|
459 RemoveHighQualityContext( aIndex ); |
|
460 } |
|
461 |
|
462 // ----------------------------------------------------------------------------- |
|
463 // CShwThumbnailLoaderImpl::HandleItemAddedL. |
|
464 // ----------------------------------------------------------------------------- |
|
465 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemAddedL( |
|
466 TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/ ) |
|
467 { |
|
468 } |
|
469 |
|
470 // ----------------------------------------------------------------------------- |
|
471 // CShwThumbnailLoaderImpl::HandleMediaL. |
|
472 // ----------------------------------------------------------------------------- |
|
473 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleMediaL( |
|
474 TInt /*aListIndex*/, MGlxMediaList* /*aList*/ ) |
|
475 { |
|
476 } |
|
477 // ----------------------------------------------------------------------------- |
|
478 // CShwThumbnailLoaderImpl::HandleItemRemovedL. |
|
479 // ----------------------------------------------------------------------------- |
|
480 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL( |
|
481 TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/ ) |
|
482 { |
|
483 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL"); |
|
484 GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL" ); |
|
485 // check if we still got some items to show |
|
486 if( iMedialist.Count() < 1 ) |
|
487 { |
|
488 // the media list is empty so call our error handler |
|
489 iThumbnailObserver.HandleMediaListEmpty(); |
|
490 } |
|
491 } |
|
492 |
|
493 // ----------------------------------------------------------------------------- |
|
494 // CShwThumbnailLoaderImpl::HandleItemModifiedL. |
|
495 // ----------------------------------------------------------------------------- |
|
496 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemModifiedL( |
|
497 const RArray<TInt>& /*aItemIndexes*/, MGlxMediaList* /*aList*/ ) |
|
498 { |
|
499 } |
|
500 |
|
501 // ----------------------------------------------------------------------------- |
|
502 // CShwThumbnailLoaderImpl::HandleAttributesAvailableL. |
|
503 // ----------------------------------------------------------------------------- |
|
504 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL( |
|
505 TInt aItemIndex, const RArray<TMPXAttribute>& aAttributes/**/, |
|
506 MGlxMediaList* /*aList*/ ) |
|
507 { |
|
508 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL"); |
|
509 GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL" ); |
|
510 //done to verify context availability |
|
511 TInt attributeCount = aAttributes.Count(); |
|
512 for(TInt i = 0; i < attributeCount; i++ ) |
|
513 { |
|
514 TMPXAttribute attr = aAttributes[i]; |
|
515 } |
|
516 |
|
517 GLX_LOG_INFO1( |
|
518 "CShwThumbnailLoader::HandleAttributesAvailableL %d", aItemIndex ); |
|
519 // check if the thumbnail was fully loaded, first find the related context |
|
520 CShwThumbnailContext* context = FindContext( aItemIndex ); |
|
521 if( context ) |
|
522 { |
|
523 // was there an error? |
|
524 TInt requestCount = context->RequestCountL( &iMedialist ); |
|
525 if ( requestCount == KErrNone ) |
|
526 { |
|
527 // no error, notify client |
|
528 GLX_LOG_INFO1( |
|
529 "CShwThumbnailLoader::Thumbnail loaded %d", aItemIndex ); |
|
530 // notidy client of success if it is interested on this index |
|
531 NofifyClientIfInterestedL( aItemIndex, ETrue ); |
|
532 } |
|
533 else if ( requestCount < 0 ) |
|
534 { |
|
535 GLX_LOG_INFO1( |
|
536 "CShwThumbnailLoader::Thumbnail load failed %d", aItemIndex ); |
|
537 // remove the context since there is an error in loading it |
|
538 // need to remove first as error handler may add new contexts |
|
539 RemoveHighQualityContext( aItemIndex ); |
|
540 // notidy client of error if it is interested on this index |
|
541 NofifyClientIfInterestedL( aItemIndex, EFalse ); |
|
542 } |
|
543 } |
|
544 } |
|
545 |
|
546 // ----------------------------------------------------------------------------- |
|
547 // CShwThumbnailLoaderImpl::HandleFocusChangedL. |
|
548 // ----------------------------------------------------------------------------- |
|
549 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleFocusChangedL( |
|
550 NGlxListDefs::TFocusChangeType /*aType*/, TInt /*aNewIndex*/, |
|
551 TInt /*aOldIndex*/, MGlxMediaList* /*aList*/ ) |
|
552 { |
|
553 } |
|
554 |
|
555 // ----------------------------------------------------------------------------- |
|
556 // CShwThumbnailLoaderImpl::HandleItemSelectedL. |
|
557 // ----------------------------------------------------------------------------- |
|
558 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemSelectedL( |
|
559 TInt /*aIndex*/, TBool /*aSelected*/, MGlxMediaList* /*aList*/ ) |
|
560 { |
|
561 } |
|
562 |
|
563 // ----------------------------------------------------------------------------- |
|
564 // CShwThumbnailLoaderImpl::HandleMessageL. |
|
565 // ----------------------------------------------------------------------------- |
|
566 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleMessageL( |
|
567 const CMPXMessage& /*aMessage*/, MGlxMediaList* /*aList*/ ) |
|
568 { |
|
569 } |
|
570 |
|
571 // ----------------------------------------------------------------------------- |
|
572 // CShwThumbnailLoaderImpl::HandleError. |
|
573 // ----------------------------------------------------------------------------- |
|
574 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError( |
|
575 TInt aError ) |
|
576 { |
|
577 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError"); |
|
578 GLX_LOG_INFO1( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError %d", aError ); |
|
579 // need to remember the error |
|
580 iError = aError; |
|
581 // make asynch callback since we cant leave, this is the perfect way to |
|
582 // handle error as the real processing will be in RunL so it can leave and |
|
583 // can show a system error note. It is safe to call CallBack even is previous |
|
584 // one did not complete |
|
585 iErrorHandlerCallBack->CallBack(); |
|
586 } |
|
587 |
|
588 // ----------------------------------------------------------------------------- |
|
589 // CShwThumbnailLoaderImpl::DoHandleErrorL. |
|
590 // ----------------------------------------------------------------------------- |
|
591 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::DoHandleErrorL() |
|
592 { |
|
593 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::DoHandleErrorL"); |
|
594 GLX_LOG_INFO1( "CShwThumbnailLoader::DoHandleError %d", iError ); |
|
595 // variable to tell if the error was in some of our fetch contexts |
|
596 TBool errorInHighQualityContexts = EFalse; |
|
597 // check if it was any of our high quality fetch contexts |
|
598 TInt count = iHighQualityContexts.Count(); |
|
599 // ask all high quality contexts |
|
600 while ( count-- > 0 ) |
|
601 { |
|
602 CShwThumbnailContext* context = iHighQualityContexts[ count ]; |
|
603 // need to TRAP in case RequestCountL leaves, since if it does |
|
604 // we need to tell our observer that there is a problem |
|
605 // requestCount needs to be volatile so that it does get |
|
606 // optimized to a register and get its initial value returned in leave |
|
607 volatile TInt requestCount = KErrNone; |
|
608 TRAPD( error, requestCount = context->RequestCountL( &iMedialist ) ); |
|
609 // ask if this context had an error or RequestCountL did leave |
|
610 if( ( requestCount < KErrNone )|| |
|
611 ( error != KErrNone ) ) |
|
612 { |
|
613 // take the index as cant use context once it is removed |
|
614 TInt index = context->Index(); |
|
615 // remove the context since there is an error in loading it |
|
616 // need to remove first as error handler may add new contexts |
|
617 RemoveHighQualityContext( index ); |
|
618 // notidy client of error if it is interested on this index |
|
619 NofifyClientIfInterestedL( index, EFalse ); |
|
620 // set the flag to tell that there was an error in context |
|
621 errorInHighQualityContexts = ETrue; |
|
622 } |
|
623 } |
|
624 // check if it was out of memory and in our contexts |
|
625 if( KErrNoMemory == iError && errorInHighQualityContexts ) |
|
626 { |
|
627 // just leave with KErrNoMemory, system will then show the dialog |
|
628 User::Leave( KErrNoMemory ); |
|
629 } |
|
630 } |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // CShwThumbnailLoaderImpl::Find. |
|
634 // ----------------------------------------------------------------------------- |
|
635 inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::Find( TInt aIndex ) |
|
636 { |
|
637 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::Find"); |
|
638 GLX_LOG_INFO1( "CShwThumbnailLoader::Find %d", aIndex ); |
|
639 // take the count |
|
640 TInt index = iHighQualityContexts.Count(); |
|
641 // browse through all indexes ( count-1 -> 0 ) |
|
642 while ( index-- > 0 ) |
|
643 { |
|
644 // does the index belong to the array? |
|
645 CShwThumbnailContext* context = iHighQualityContexts[ index ]; |
|
646 if ( context->Index() == aIndex ) |
|
647 { |
|
648 break; |
|
649 } |
|
650 } |
|
651 // if match was not found, index is -1 which is KErrNotFound |
|
652 return index; |
|
653 } |
|
654 |
|
655 // ----------------------------------------------------------------------------- |
|
656 // CShwThumbnailLoaderImpl::FindContext. |
|
657 // ----------------------------------------------------------------------------- |
|
658 inline CShwThumbnailContext* |
|
659 CShwThumbnailLoader::CShwThumbnailLoaderImpl::FindContext( TInt aIndex ) |
|
660 { |
|
661 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::FindContext"); |
|
662 GLX_LOG_INFO1( "CShwThumbnailLoader::FindContext %d", aIndex ); |
|
663 // by default return NULL |
|
664 CShwThumbnailContext* context = NULL; |
|
665 // reuse the Find |
|
666 TInt index = Find( aIndex ); |
|
667 // if it was found |
|
668 if( index != KErrNotFound ) |
|
669 { |
|
670 // set the context |
|
671 context = iHighQualityContexts[ index ]; |
|
672 } |
|
673 // and return it |
|
674 return context; |
|
675 } |
|
676 |
|
677 // ----------------------------------------------------------------------------- |
|
678 // CShwThumbnailLoaderImpl::AddSizeContextL |
|
679 // ----------------------------------------------------------------------------- |
|
680 inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::AddSizeContextL() |
|
681 { |
|
682 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::AddSizeContextL"); |
|
683 GLX_LOG_INFO( "CShwThumbnailLoader::FindContext "); |
|
684 // Create the fetch context to retrieve the attribute |
|
685 iSizeContext = CGlxDefaultAttributeContext::NewL(); |
|
686 // Set the range offsets relative to the focus item |
|
687 // e.g. 0, 1, [2], 3, 4. Focus @ 2 => frontOffset = 2, rearOffset = 2 |
|
688 iSizeContext->SetRangeOffsets( KSizeContextOffset, KSizeContextOffset ); |
|
689 |
|
690 // Add the size attribute to the context |
|
691 iSizeContext->AddAttributeL( KGlxMediaGeneralDimensions ); |
|
692 |
|
693 // Add Drm attribute to the context, |
|
694 // By default Drm attrib would be ETrue if not fetched already and |
|
695 // shall result in reduced thumbnail size request |
|
696 iSizeContext->AddAttributeL(KMPXMediaDrmProtected); |
|
697 |
|
698 // add the context with its priority |
|
699 iMedialist.AddContextL( iSizeContext, KSizeContextPriority ); |
|
700 } |
|
701 |
|
702 // ----------------------------------------------------------------------------- |
|
703 // CShwThumbnailLoaderImpl::NofifyClientIfInterestedL. |
|
704 // ----------------------------------------------------------------------------- |
|
705 void CShwThumbnailLoader::CShwThumbnailLoaderImpl::NofifyClientIfInterestedL( |
|
706 TInt aIndex, TBool aSuccess ) |
|
707 { |
|
708 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::NofifyClientIfInterestedL"); |
|
709 GLX_LOG_INFO1( "CShwThumbnailLoaderImpl::NofifyClientIfInterestedL %d", aIndex ); |
|
710 // go through all the notification indexes |
|
711 TInt arrayIndex = iNotificationIndexes.Find( aIndex ); |
|
712 if( KErrNotFound != arrayIndex ) |
|
713 { |
|
714 // need to remove the index first as handle may insert new ones |
|
715 // remove the index from array so we dont call twice |
|
716 iNotificationIndexes.Remove( arrayIndex ); |
|
717 if( aSuccess ) |
|
718 { |
|
719 // let the client know that the thumbnail is there |
|
720 iThumbnailObserver.HandleThumbnailLoadedL( aIndex ); |
|
721 } |
|
722 else |
|
723 { |
|
724 // let the client know that there was an error |
|
725 iThumbnailObserver.HandleThumbnailLoadFailureL( aIndex ); |
|
726 } |
|
727 } |
|
728 } |
|
729 |
|
730 // ----------------------------------------------------------------------------- |
|
731 // CShwThumbnailLoaderImpl::RemoveHighQualityContext |
|
732 // ----------------------------------------------------------------------------- |
|
733 inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl:: |
|
734 RemoveHighQualityContext( TInt aIndex ) |
|
735 { |
|
736 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::RemoveHighQualityContext"); |
|
737 GLX_LOG_INFO1( "CShwThumbnailLoaderImpl::RemoveHighQualityContext %d", aIndex ); |
|
738 // Is there a context for this index? |
|
739 TInt arrayIndex = Find( aIndex ); |
|
740 if( KErrNotFound != arrayIndex ) |
|
741 { |
|
742 // get the context |
|
743 CShwThumbnailContext* context = iHighQualityContexts[ arrayIndex ]; |
|
744 // remove the context from the media list |
|
745 iMedialist.RemoveContext( context->Context() ); |
|
746 // and remove the context from the array |
|
747 iHighQualityContexts.Remove( arrayIndex ); |
|
748 // finally delete the context |
|
749 delete context; |
|
750 } |
|
751 } |
|
752 |
|
753 // ----------------------------------------------------------------------------- |
|
754 // CShwThumbnailLoaderImpl::CompletedNotifyL |
|
755 // ----------------------------------------------------------------------------- |
|
756 inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::CompletedNotifyL() |
|
757 { |
|
758 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::CompletedNotifyL"); |
|
759 GLX_LOG_INFO( "CShwThumbnailLoader::CompletedNotifyL" ); |
|
760 // then we need to also remove all notifications for the given index |
|
761 TInt count = iCompletedIndexes.Count(); |
|
762 while( count-- > 0 ) |
|
763 { |
|
764 // take the index |
|
765 TInt index = iCompletedIndexes[ count ]; |
|
766 // remove the index from array before calling observer as observer |
|
767 // may add new indexes to the array |
|
768 iCompletedIndexes.Remove( count ); |
|
769 // notidy client of success if it is interested on this index |
|
770 NofifyClientIfInterestedL( index, ETrue ); |
|
771 } |
|
772 // need to return value to please TCallBack API |
|
773 return KErrNone; |
|
774 } |
|
775 |
|
776 // ----------------------------------------------------------------------------- |
|
777 // CShwThumbnailLoaderImpl::ErrorNotifyL |
|
778 // ----------------------------------------------------------------------------- |
|
779 inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::ErrorNotifyL() |
|
780 { |
|
781 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ErrorNotifyL"); |
|
782 GLX_LOG_INFO( "CShwThumbnailLoader::ErrorNotifyL" ); |
|
783 // then we need to also remove all notifications for the given index |
|
784 TInt count = iErrorIndexes.Count(); |
|
785 while( count-- > 0 ) |
|
786 { |
|
787 // take the index |
|
788 TInt index = iErrorIndexes[ count ]; |
|
789 // remove the index from array before calling observer as observer |
|
790 // may add new indexes to the array |
|
791 iErrorIndexes.Remove( count ); |
|
792 // remove the context since there is an error in loading it |
|
793 // need to remove first as error handler may add new contexts |
|
794 RemoveHighQualityContext( index ); |
|
795 // notidy client of error if it is interested on this index |
|
796 NofifyClientIfInterestedL( index, EFalse ); |
|
797 } |
|
798 // need to return value to please TCallBack API |
|
799 return KErrNone; |
|
800 } |
|
801 |
|
802 // ----------------------------------------------------------------------------- |
|
803 // CShwThumbnailLoaderImpl::AsyncErrorHandleL |
|
804 // ----------------------------------------------------------------------------- |
|
805 inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::AsyncErrorHandleL() |
|
806 { |
|
807 TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::AsyncErrorHandleL"); |
|
808 GLX_LOG_INFO( "CShwThumbnailLoader::AsyncErrorHandleL" ); |
|
809 // handle the error |
|
810 DoHandleErrorL(); |
|
811 // need to return value to please TCallBack API |
|
812 return KErrNone; |
|
813 } |