photosgallery/viewframework/medialists/src/glxcachemanager.cpp
changeset 0 4e91876724a2
child 1 9ba538e329bd
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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:    Manager of media item cache
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "glxcachemanager.h"
       
    22 
       
    23 #include <mpxcollectionutility.h>
       
    24 #include <glxtracer.h>
       
    25 #include <glxthumbnailattributeinfo.h>
       
    26 #include <glxthumbnail.h>
       
    27 #include <glxsingletonstore.h>
       
    28 #include <glximageviewermanager.h>
       
    29 
       
    30 #include "glxcache.h"
       
    31 #include "glxerrormanager.h"
       
    32 #include "glxgarbagecollector.h"
       
    33 #include "glxmedialist.h"
       
    34 #include <hal.h>
       
    35 #include <glxcollectionpluginimageviewer.hrh>
       
    36 #include <mpxmediacollectiondetaildefs.h>
       
    37 #include <mpxmediadrmdefs.h>
       
    38 #include <f32file.h>
       
    39 #include <lbsposition.h>
       
    40 #include <apgcli.h>
       
    41 #include <glxappui.h>
       
    42 #include <aknViewAppUi.h>
       
    43 #include <caf/content.h>
       
    44 #include <caf/attributeset.h>
       
    45 #include <DRMHelper.h>
       
    46 
       
    47 #ifdef USE_S60_TNM
       
    48 #include <thumbnaildata.h>
       
    49 const TInt KMaxGridThumbnailWidth = 200;
       
    50 _LIT(KFileIdentifier, ":\\");
       
    51 #endif
       
    52 
       
    53 /// How long to wait before rechecking for cleared temporary errors
       
    54 /// @todo Find optimal value for this
       
    55 const TInt KGlxTemporaryErrorRecheckPeriodInSeconds = 5;
       
    56 
       
    57 const TInt KGlxLowerMemoryLimitForCleanUp = 15000000;
       
    58 const TInt KGlxUpperMemoryLimitForCleanUp = 25000000;
       
    59 const TInt KGlxNoOfPagesToFlushInCriticalLowMemory = 4;
       
    60 // -----------------------------------------------------------------------------
       
    61 // InstanceL
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 CGlxCacheManager* CGlxCacheManager::InstanceL()
       
    65 	{
       
    66 	TRACER("CGlxCacheManager::InstanceL");
       
    67 	
       
    68 	return CGlxSingletonStore::InstanceL(&NewL);
       
    69 	}
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // NewL
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 CGlxCacheManager* CGlxCacheManager::NewL()
       
    76     {
       
    77     TRACER("CGlxCacheManager::NewL");
       
    78     
       
    79     CGlxCacheManager* self = new( ELeave ) CGlxCacheManager();
       
    80     CleanupStack::PushL( self );
       
    81     self->ConstructL();
       
    82     CleanupStack::Pop(self);
       
    83     return self;
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // Close
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 void CGlxCacheManager::Close()
       
    91 	{
       
    92 	TRACER("CGlxCacheManager::Close");
       
    93 	
       
    94 	CGlxSingletonStore::Close(this);
       
    95 	}
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // Constructor
       
    99 // -----------------------------------------------------------------------------
       
   100 //
       
   101 CGlxCacheManager::CGlxCacheManager()
       
   102     {
       
   103     TRACER("CGlxCacheManager::Default Constructor");
       
   104     
       
   105     }
       
   106     
       
   107 // -----------------------------------------------------------------------------
       
   108 // ConstructL
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 void CGlxCacheManager::ConstructL()
       
   112     {
       
   113     TRACER("CGlxCacheManager::ConstructL");
       
   114     
       
   115     iGarbageCollector = CGlxGarbageCollector::NewL( iCaches );
       
   116     iTempErrorTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   117     iSchedulerWait = new (ELeave) CActiveSchedulerWait();
       
   118     iMaintainCacheCallback = new ( ELeave )
       
   119 	    CAsyncCallBack( TCallBack( MaintainCacheL, this ), CActive::EPriorityStandard );
       
   120 	    
       
   121 #ifdef USE_S60_TNM
       
   122     iTnEngine = CThumbnailManager::NewL( *this);
       
   123     iTnEngine->SetDisplayModeL( EColor64K );
       
   124 #endif
       
   125     iImageViewerInstance = CGlxImageViewerManager::InstanceL();
       
   126     }
       
   127         
       
   128 // -----------------------------------------------------------------------------
       
   129 // Destructor
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 CGlxCacheManager::~CGlxCacheManager()
       
   133 	{
       
   134 	TRACER("CGlxCacheManager::Destructor");
       
   135 	
       
   136     delete iSchedulerWait;
       
   137  	iObserverList.ResetAndDestroy();
       
   138  	iCaches.ResetAndDestroy();
       
   139  	delete iTempThumbnail;
       
   140  	iRequestedItemIds.Reset();
       
   141  	iRequestedAttrs.Reset();
       
   142  	iRequestedItemIndexes.Reset();
       
   143     if(iReader)
       
   144         {
       
   145         delete iReader;
       
   146         }
       
   147 
       
   148  	delete iGarbageCollector;
       
   149 
       
   150     if (iTempErrorTimer)
       
   151         {
       
   152 		iTempErrorTimer->Cancel();	
       
   153 		delete iTempErrorTimer;
       
   154         }
       
   155 
       
   156 #ifdef USE_S60_TNM
       
   157     GLX_DEBUG2("CGlxCacheManager::~CGlxCacheManager() TN Ids count()=%d",
       
   158 										 iThumbnailRequestIds.Count());
       
   159     for (TInt i = 0; i < iThumbnailRequestIds.Count(); i++)
       
   160         {
       
   161         iTnEngine->CancelRequest(iThumbnailRequestIds[i].iId);
       
   162         }
       
   163 	iThumbnailRequestIds.Reset();
       
   164     delete iTnEngine;
       
   165     delete iMPXMedia;
       
   166 #endif
       
   167     
       
   168     delete iMaintainCacheCallback;
       
   169     if ( NULL != iImageViewerInstance)
       
   170         {
       
   171         iImageViewerInstance->DeleteInstance();
       
   172         }
       
   173 	}
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // HandleWindowChangedL
       
   177 // From MVieMediaItemListManager
       
   178 // The list calls this function to hint the list manager, that the items 
       
   179 // the list contains might not all be loaded, and it would be nice if the list
       
   180 // manager could load the missing items to the cache.
       
   181 // -----------------------------------------------------------------------------
       
   182 //
       
   183 void CGlxCacheManager::HandleWindowChangedL(CGlxMediaList* /*aList*/) 
       
   184 	{
       
   185 	TRACER("CGlxCacheManager::HandleWindowChangedL");
       
   186 	
       
   187 	GLX_LOG_INFO("---- MGallery - CGlxCacheManager::HandleWindowChangedL()---- ");
       
   188     
       
   189     iMaintainCacheCallback->CallBack();
       
   190     // Its Better if we are not Cleaning Cache here; Instaed Can Do inside MainTainCache
       
   191     //MaintainCacheL();
       
   192     //iGarbageCollector->Cleanup();
       
   193     }
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 // CancelPreviousRequest
       
   197 // This API cancels the pending attributes and thumbnail request  
       
   198 // when the media item in focus is NULL
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 void CGlxCacheManager::CancelPreviousRequest()
       
   202 	{
       
   203 	TRACER("CGlxCacheManager::CancelPreviousRequest");		
       
   204 	
       
   205 	// iRequestOwner is NULL, if there are no pending attribute/thumbnail request
       
   206 	// If no pending request, do nothing, else cancel the the pending requests
       
   207 	if(iRequestOwner)
       
   208 		{		
       
   209 		MMPXCollection& collection = iRequestOwner->Collection();
       
   210 		// Cancel the pending attribute request
       
   211 		collection.CancelRequest();	
       
   212 		
       
   213 		GLX_DEBUG2("CGlxCacheManager::CancelPreviousRequest() iThumbnailRequestIds.Count() %d", iThumbnailRequestIds.Count());
       
   214 		
       
   215 		// Check if any thumbnail requests are pending and cancel the requests.		
       
   216 		for (TInt i = 0; i < iThumbnailRequestIds.Count(); i++)
       
   217 			{ 			
       
   218 			iTnEngine->CancelRequest(iThumbnailRequestIds[i].iId);									
       
   219 			}
       
   220 		iThumbnailRequestIds.Reset();		
       
   221 		iRequestOwner = NULL;
       
   222 		}
       
   223 	}
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // HandleGarbageCollection
       
   227 // Garbage Collection Quick or with Timer
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 void CGlxCacheManager::HandleGarbageCollectionL(TBool aStart)
       
   231     {
       
   232     TRACER("CGlxCacheManager::HandleGarbageCollection");
       
   233     TInt freeMemory = 0;
       
   234        
       
   235        HAL::Get( HALData::EMemoryRAMFree, freeMemory );
       
   236            
       
   237        if(aStart)
       
   238            {
       
   239            if(freeMemory < KGlxLowerMemoryLimitForCleanUp)
       
   240                {
       
   241                // 2 page - 30 Items for Flush
       
   242                TInt count = 2;  
       
   243                if(freeMemory < (KGlxLowerMemoryLimitForCleanUp/2))
       
   244                    {
       
   245                    // If Memory is below this limit it's ok i can wait for 60 items to clean-up
       
   246                    count = KGlxNoOfPagesToFlushInCriticalLowMemory;
       
   247                    }
       
   248                // Cancel Clean-up before Flush Page; Clean-up will be starting just after Flush page
       
   249                iGarbageCollector->CancelCleanup(); 
       
   250                iGarbageCollector->FlushPagesL(count);
       
   251                iGarbageCollector->CleanupL();
       
   252                iCleanUpOnGoing = ETrue;         // Clean up is Started now i can call CancelClean-up to Stop Clean Up
       
   253                }
       
   254            else if((freeMemory < KGlxUpperMemoryLimitForCleanUp) && !iCleanUpOnGoing)
       
   255                {
       
   256                iGarbageCollector->CleanupL();
       
   257                iCleanUpOnGoing = ETrue;         // Clean up is Started now i can call CancelClean-up to Stop Clean Up
       
   258                }
       
   259            // This is Added to Keep Assure Clean-up is not going to Disturb normal Flow if there is Enough Memory
       
   260            // We Remove this Code After Evaluation of Use of this Code
       
   261            else if(iCleanUpOnGoing)
       
   262                {
       
   263                iGarbageCollector->CancelCleanup();
       
   264                iCleanUpOnGoing = EFalse;
       
   265                }
       
   266                
       
   267            }
       
   268        else if(freeMemory < KGlxLowerMemoryLimitForCleanUp)
       
   269            {
       
   270            // 2 page - 30 Items for Flush
       
   271            TInt count = 2;
       
   272            if(freeMemory < (KGlxLowerMemoryLimitForCleanUp/2))
       
   273                {
       
   274                // If Memory is below this limit it's ok i can wait for 60 items to clean-up
       
   275                count = KGlxNoOfPagesToFlushInCriticalLowMemory;
       
   276                }
       
   277            // Cancel Clean-up before Flush Page; Clean-up will be starting just after Flush page
       
   278            iGarbageCollector->CancelCleanup();
       
   279            iGarbageCollector->FlushPagesL(count);
       
   280            iGarbageCollector->CleanupL();
       
   281            iCleanUpOnGoing = ETrue;          // Clean up is Started now i can call CancelClean-up to Stop Clean Up
       
   282         }
       
   283     else if(iCleanUpOnGoing)
       
   284         {
       
   285         iGarbageCollector->CancelCleanup();
       
   286         iCleanUpOnGoing = EFalse;
       
   287         }
       
   288     }
       
   289 		
       
   290 // -----------------------------------------------------------------------------
       
   291 // Match
       
   292 // return ETrue if path levels match
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 TBool CGlxCacheManager::Match(const CMPXCollectionPath& aPath1, 
       
   296 		const CMPXCollectionPath& aPath2)
       
   297 	{
       
   298 	TRACER("CGlxCacheManager::Match");
       
   299 	
       
   300 	TInt levels1 = aPath1.Levels();
       
   301 	TInt levels2 = aPath2.Levels();
       
   302 	
       
   303 	// Paths must be as deep to match
       
   304 	if (levels1 != levels2) 
       
   305 		{
       
   306 		return EFalse; 
       
   307 		}
       
   308 		
       
   309 	// Check if all levels match
       
   310 	for (TInt i = 0; i < levels1; i++) 
       
   311 		{
       
   312 		if (aPath1.Index(i) != aPath2.Index(i))
       
   313 			{
       
   314 			return EFalse;
       
   315 			}
       
   316 		}
       
   317 		
       
   318 	return ETrue;
       
   319 	}
       
   320 	
       
   321 // -----------------------------------------------------------------------------
       
   322 // HandleCollectionMediaL
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 void CGlxCacheManager::HandleCollectionMediaL(const TGlxIdSpaceId& aIdSpaceId, const CMPXMedia& aMedia, TInt aError)
       
   326     {
       
   327     TRACER("CGlxCacheManager::HandleCollectionMediaL");
       
   328     
       
   329     iRequestOwner = NULL;
       
   330 
       
   331     if ( KErrNone == aError )
       
   332         {
       
   333         // Update the cache
       
   334         CGlxCache* cache = FindCacheForceCreateL(aIdSpaceId);
       
   335         cache->MediaUpdatedL(aMedia);
       
   336         }
       
   337     else
       
   338         {
       
   339         RPointerArray< MGlxMediaUser > users;
       
   340         CleanupClosePushL( users );
       
   341         
       
   342         // Record the error on all requested attributes
       
   343         TInt idCount = iRequestedItemIds.Count();
       
   344         
       
   345         for( TInt idIndex = 0; idIndex < idCount; idIndex++ )
       
   346             {
       
   347             CGlxMedia* item = MediaForceCreateL(aIdSpaceId, iRequestedItemIds[idIndex]);
       
   348             GlxErrorManager::SetAttributeErrorL(item, iRequestedAttrs, aError);
       
   349             
       
   350             // Keep track of media lists to notify later
       
   351             TInt userCount = item->UserCount();
       
   352             for ( TInt userIndex = 0; userIndex < userCount; userIndex++ )
       
   353                 {
       
   354                 users.InsertInAddressOrder( &item->User( userIndex ) );
       
   355                 }
       
   356             }
       
   357 
       
   358         // Notify all affected users of error
       
   359         TInt userCount = users.Count();
       
   360         for ( TInt i = 0; i < userCount; i++ )
       
   361             {
       
   362             users[ i ]->HandleError( aError );
       
   363             }
       
   364 
       
   365         CleanupStack::PopAndDestroy( &users );
       
   366         }
       
   367     
       
   368     MaintainCacheL();
       
   369     }
       
   370 
       
   371 // -----------------------------------------------------------------------------
       
   372 // FindCacheForceCreateL
       
   373 // -----------------------------------------------------------------------------
       
   374 //
       
   375 CGlxCache* CGlxCacheManager::FindCacheForceCreateL(const TGlxIdSpaceId& aIdSpaceId)
       
   376     {
       
   377     TRACER("CGlxCacheManager::FindCacheForceCreateL");
       
   378     
       
   379     CGlxCache* cache = NULL;
       
   380 
       
   381     // Look for existing cache
       
   382     TInt index = iCaches.FindInOrder(aIdSpaceId, (&CacheOrderByKey));
       
   383     if ( KErrNotFound == index )
       
   384         {
       
   385         // Not found: create one
       
   386     	TLinearOrder<CGlxCache> orderer (&CacheOrderById);
       
   387         cache = new (ELeave) CGlxCache(aIdSpaceId, this);
       
   388 
       
   389         CleanupStack::PushL(cache);
       
   390         iCaches.InsertInOrderL(cache, orderer);
       
   391         CleanupStack::Pop(cache);
       
   392         }
       
   393     else
       
   394         {
       
   395         cache = iCaches[index];
       
   396         }
       
   397 
       
   398     return cache;
       
   399     }
       
   400     
       
   401 // -----------------------------------------------------------------------------
       
   402 // Media
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 CGlxMedia* CGlxCacheManager::Media( const TGlxIdSpaceId& aIdSpaceId, 
       
   406         const TGlxMediaId& aMediaId ) const
       
   407     {
       
   408     TRACER("CGlxCacheManager::Media");
       
   409     
       
   410     // Look for the correct subcache
       
   411     TInt index = iCaches.FindInOrder( aIdSpaceId, &CacheOrderByKey );
       
   412     
       
   413     if ( KErrNotFound == index )
       
   414         {
       
   415         // No caches exist with this space id
       
   416         return NULL;
       
   417         }
       
   418     else
       
   419         {
       
   420         return iCaches[index]->Media( aMediaId );
       
   421         }
       
   422     }
       
   423     
       
   424 // -----------------------------------------------------------------------------
       
   425 // MediaForceCreateL
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 CGlxMedia* CGlxCacheManager::MediaForceCreateL(const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aMediaId)
       
   429     {
       
   430     TRACER("CGlxCacheManager::MediaForceCreateL");
       
   431     
       
   432     CGlxCache* cache = FindCacheForceCreateL(aIdSpaceId);
       
   433     return cache->FindItemForceCreateL(aMediaId);
       
   434     }
       
   435     
       
   436 // -----------------------------------------------------------------------------
       
   437 // AddObserverL
       
   438 // -----------------------------------------------------------------------------
       
   439 //
       
   440 void CGlxCacheManager::AddObserverL(MGlxCacheObserver* aObserver)
       
   441     {
       
   442     TRACER("CGlxCacheManager::AddObserverL");
       
   443     
       
   444     if ( aObserver )
       
   445         {
       
   446         if ( KErrNotFound == iObserverList.Find( aObserver ))
       
   447             {
       
   448             iObserverList.AppendL(aObserver);
       
   449             }
       
   450         }
       
   451     }
       
   452     
       
   453 // -----------------------------------------------------------------------------
       
   454 // RemoveObserver
       
   455 // -----------------------------------------------------------------------------
       
   456 //
       
   457 void CGlxCacheManager::RemoveObserver(MGlxCacheObserver* aObserver)
       
   458     {
       
   459     TRACER("CGlxCacheManager::RemoveObserver");
       
   460     
       
   461     if ( aObserver )
       
   462         {
       
   463         TInt index = iObserverList.Find( aObserver );
       
   464         if ( KErrNotFound != index )
       
   465             {
       
   466             iObserverList.Remove(index);
       
   467             }
       
   468         }
       
   469     }
       
   470 
       
   471 // ---------------------------------------------------------------------------
       
   472 // Refresh
       
   473 // ---------------------------------------------------------------------------
       
   474 //
       
   475 void CGlxCacheManager::RefreshL()
       
   476     {
       
   477     TRACER("CGlxCacheManager::Refresh");
       
   478     
       
   479     if ( !iRequestOwner )
       
   480         {
       
   481         // Currently idle, so trigger timer immediately to begin refresh
       
   482         iTempErrorTimer->Cancel();
       
   483         iTempErrorTimer->Start( 0, 0,
       
   484                             TCallBack( TempErrorTimerCallbackL, this ) );
       
   485         
       
   486         HandleGarbageCollectionL(ETrue);  // Clean-up is needed here; Considering Current Memory Condition
       
   487         }
       
   488     }
       
   489 
       
   490 // -----------------------------------------------------------------------------
       
   491 // MaintainCache
       
   492 // -----------------------------------------------------------------------------
       
   493 //
       
   494 TInt CGlxCacheManager::MaintainCacheL(TAny* aPtr)
       
   495     {
       
   496     TRACER("CGlxCacheManager::MaintainCache");
       
   497     
       
   498     CGlxCacheManager* self
       
   499                     = reinterpret_cast<CGlxCacheManager*>( aPtr );
       
   500     self->MaintainCacheL();
       
   501     
       
   502     // Clean-up is needed here; Considering Current Memory Condition
       
   503     // For Every HandleWindowChangedL; We Should not do Clean-up 
       
   504     self->HandleGarbageCollectionL(ETrue);  
       
   505     return 0;
       
   506     }
       
   507     
       
   508 // -----------------------------------------------------------------------------
       
   509 // MaintainCacheL
       
   510 // -----------------------------------------------------------------------------
       
   511 //
       
   512 void CGlxCacheManager::MaintainCacheL() 
       
   513     {
       
   514     TRACER("CGlxCacheManager::MaintainCacheL");
       
   515     
       
   516 	// Handle lists in priority order: all data for the highest priority list 
       
   517 	// is retrieved before the data for a lower priority list. NOTE: This
       
   518 	// may need to be changed, since it might not always lead to the best
       
   519 	// user experienced. (It may be sensible to retrieve item properties
       
   520 	// for a lower priority list before all thumbnails for a higher priority 
       
   521 	// list, but this probably depends on the speed of the data sources.
       
   522 	// It might be wise to decouple the contexts from the media lists
       
   523 
       
   524     if (!iRequestOwner)
       
   525         {
       
   526         iTempError = EFalse;
       
   527         iTempErrorTimer->Cancel();
       
   528 
       
   529     	RPointerArray<CGlxMediaList>& mediaLists = CGlxMediaList::MediaListsL();
       
   530      	iRequestedItemIds.Reset();
       
   531      	iRequestedAttrs.Reset();
       
   532     	iRequestedItemIndexes.Reset();
       
   533     	
       
   534     	TInt listCount = mediaLists.Count();
       
   535 
       
   536     	// Request attributes in the fetch contexts
       
   537         for (TInt listIndex = 0; listIndex < listCount && !iRequestOwner; listIndex++)      
       
   538             {
       
   539             CGlxMediaList* list = mediaLists[listIndex];
       
   540 
       
   541     		CMPXAttributeSpecs* attrSpecs = NULL;
       
   542 
       
   543     		list->AttributeRequestL(iRequestedItemIndexes, iRequestedItemIds, iRequestedAttrs, attrSpecs );
       
   544     		CleanupStack::PushL(attrSpecs);
       
   545 
       
   546             TInt itemIdsCount = iRequestedItemIds.Count();
       
   547             if (itemIdsCount > 0)
       
   548                 {
       
   549                 if (attrSpecs)
       
   550                     {
       
   551                     GLX_DEBUG2("CGlxCacheManager::MaintainCacheL() attrSpecs->Count() %d", attrSpecs->Count());
       
   552                     }
       
   553                 
       
   554                 TGlxMediaId itemId = iRequestedItemIds[0];
       
   555 
       
   556                 CMPXCollectionPath* path = RequestAsPathLC( *list );
       
   557 
       
   558                 // Add request for id, if does not exist already. Id is used to 
       
   559                 // identify which media object the attribute belongs to when
       
   560                 // it is returned
       
   561                 TIdentityRelation<TMPXAttribute> match (&TMPXAttribute::Match);
       
   562                 if (iRequestedAttrs.Find(KMPXMediaGeneralId, match) == KErrNotFound) 
       
   563                     {
       
   564                     iRequestedAttrs.AppendL(KMPXMediaGeneralId);
       
   565                     }
       
   566 
       
   567                 // Create the empty bitmap, if the request is for a bitmap
       
   568                 TIdentityRelation<TMPXAttribute> matchContent(&TMPXAttribute::MatchContentId);
       
   569                 TMPXAttribute tnAttr(KGlxMediaIdThumbnail, 0);
       
   570                 if (iRequestedAttrs.Find(tnAttr, matchContent) != KErrNotFound) 
       
   571                     {
       
   572 #ifdef USE_S60_TNM
       
   573 					if (iRequestedItemIndexes.Count())
       
   574 						{
       
   575                         // Cancel Clean-up is needed here;
       
   576                         HandleGarbageCollectionL(EFalse);                           
       
   577 						
       
   578 			            TSize tnSize;
       
   579 						const TMPXAttributeData sizeAttrib = { KGlxMediaIdThumbnail , KGlxAttribSpecThumbnailSize };
       
   580       					if (attrSpecs && attrSpecs->IsSupported(sizeAttrib))
       
   581                         	{
       
   582 				    		tnSize = attrSpecs->ValueTObjectL<TSize>(sizeAttrib);
       
   583                         	}
       
   584 
       
   585 						const TGlxMedia& item = list->Item( iRequestedItemIndexes[0] );
       
   586       					TBool priority = ETrue;
       
   587       					const TMPXAttributeData priorityAttrib = { KGlxMediaIdThumbnail , KGlxAttribSpecThumbnailQualityOverSpeed };
       
   588       					if (attrSpecs && attrSpecs->IsSupported(priorityAttrib))
       
   589       					    {
       
   590       					    priority = attrSpecs->ValueTObjectL<TBool>(priorityAttrib);
       
   591       					    }
       
   592       					
       
   593 						TGlxIdSpaceId spaceId = list->IdSpaceId(iRequestedItemIndexes[0]);	
       
   594 #ifdef MEDIA_ID_BASED_TN_FETCH_ENABLED
       
   595 	               	 	GLX_DEBUG2("CGlxCacheManager::MaintainCacheL() requesting TN attribute (Medialist) itemId %d", itemId.Value());
       
   596 						if (item.Uri().Find(KFileIdentifier) != KErrNotFound ||
       
   597 						    item.Uri().Length() == 0 && itemId.Value())
       
   598 #else
       
   599 	               	 	GLX_DEBUG1("CGlxCacheManager::MaintainCacheL() requesting TN attribute (Medialist) Uri");
       
   600 						if (item.Uri().Find(KFileIdentifier) != KErrNotFound)
       
   601 #endif
       
   602 							{
       
   603 #ifdef _DEBUG
       
   604 							iStartTime.HomeTime(); // Get home time
       
   605 #endif							
       
   606 						    if (tnSize.iWidth < KMaxGridThumbnailWidth)
       
   607 						    	{
       
   608 						    	iTnEngine->SetFlagsL(CThumbnailManager::ECropToAspectRatio);
       
   609 							    iTnEngine->SetThumbnailSizeL(EGridThumbnailSize);
       
   610 							    GLX_DEBUG1("MaintainCacheL() - Fetch TN attrib - EGridThumbnailSize");
       
   611 						    	}
       
   612 						    else
       
   613 							    {
       
   614 							    iTnEngine->SetFlagsL(CThumbnailManager::EDefaultFlags);
       
   615 							    iTnEngine->SetThumbnailSizeL(EFullScreenThumbnailSize);
       
   616                                 GLX_DEBUG1("MaintainCacheL() - Fetch TN attrib - EFullScreenThumbnailSize");							    
       
   617 							    }
       
   618 						    
       
   619 						    if (priority)
       
   620 						        {
       
   621 						        iTnEngine->SetQualityPreferenceL(CThumbnailManager::EOptimizeForQuality);
       
   622                                 GLX_DEBUG1("MaintainCacheL() - Fetch TN attrib - EOptimizeForQuality");                                
       
   623 						        }
       
   624 						    else
       
   625 						        {
       
   626 						        iTnEngine->SetQualityPreferenceL(CThumbnailManager::EOptimizeForQualityWithPreview);
       
   627                                 GLX_DEBUG1("MaintainCacheL() - Fetch TN attrib - EOptimizeForQualityWithPreview");                                
       
   628                                 }
       
   629                             
       
   630                             if (list->Collection().UidL().iUid == KGlxCollectionPluginImageViewerImplementationUid)
       
   631                                 {
       
   632                                 RDebug::Printf("void CGlxCacheManager::MaintainCacheL:ABC: IV TN");
       
   633                                 _LIT( KPrivateFolder, "\\Private\\" );    // Platsec private folder  
       
   634                                 TParsePtrC parse( item.Uri() );
       
   635                                 if( parse.PathPresent() &&
       
   636                                     parse.Path().Length() > KPrivateFolder().Length() &&
       
   637                                     parse.Path().Left( KPrivateFolder().Length() ).CompareF( KPrivateFolder ) == 0 )
       
   638                                     {
       
   639                                     RDebug::Printf("void CGlxCacheManager::MaintainCacheL:ABC: In if");
       
   640                                     GLX_DEBUG1("KGlxCollectionPluginImageViewerImplementationUid - Fetch (Private) TN!");
       
   641                                     CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(iImageViewerInstance->ImageFileHandle());
       
   642                                     iThumbnailRequestIds.AppendL(TLoadingTN(iTnEngine->GetThumbnailL(*source), spaceId, tnSize, itemId));
       
   643                                     CleanupStack::PopAndDestroy();
       
   644                                     
       
   645                                     }
       
   646                                 else
       
   647                                     {
       
   648                                     RDebug::Printf("void CGlxCacheManager::MaintainCacheL:ABC: In else");
       
   649                                     GLX_DEBUG1("KGlxCollectionPluginImageViewerImplementationUid - Fetch TN!");
       
   650                                     CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(item.Uri(), 0);
       
   651                                     iThumbnailRequestIds.AppendL(TLoadingTN(iTnEngine->GetThumbnailL(*source), spaceId, tnSize, itemId));
       
   652                                     CleanupStack::PopAndDestroy();
       
   653                                     }
       
   654                                 }
       
   655                             else
       
   656                                 {
       
   657 #ifdef MEDIA_ID_BASED_TN_FETCH_ENABLED
       
   658 						    iThumbnailRequestIds.AppendL(TLoadingTN(iTnEngine->GetThumbnailL(itemId.Value()), spaceId, tnSize, itemId));
       
   659 #else
       
   660 						    CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(item.Uri(), 0);
       
   661 						    iThumbnailRequestIds.AppendL(TLoadingTN(iTnEngine->GetThumbnailL(*source), spaceId, tnSize, itemId));
       
   662 						    CleanupStack::PopAndDestroy();
       
   663 #endif
       
   664                                 }
       
   665 		                    iThumbnailId = itemId;
       
   666 							}
       
   667 						else
       
   668 							{
       
   669 		                    delete iTempThumbnail;
       
   670 		                    iTempThumbnail = NULL;
       
   671 		                    iTempThumbnail = new (ELeave) CFbsBitmap;
       
   672 		                    User::LeaveIfError(iTempThumbnail->Create(TSize(), KGlxThumbnailDisplayMode));
       
   673 		                    iThumbnailId = itemId;
       
   674 	               		 	GLX_DEBUG2("CGlxCacheManager::MaintainCacheL() requesting TN (DataSourceMde) attribute itemId %d", itemId.Value());
       
   675 
       
   676 		                    // Set bitmap handle in attribute spec
       
   677 		                    if (attrSpecs)
       
   678 		                        {
       
   679 		                        TMPXAttribute thHandleAttrSpec(KGlxMediaIdThumbnail, KGlxAttribSpecThumbnailBitmapHandle);
       
   680 		                        attrSpecs->SetTObjectValueL<TInt>(thHandleAttrSpec, iTempThumbnail->Handle());
       
   681 		                        }
       
   682 
       
   683 		                    // Cancel Clean-up is needed here;
       
   684 		                    // This is Going to Highly Used Call
       
   685 		                    // Can Think about an Ulternative.
       
   686 		                    HandleGarbageCollectionL(EFalse);
       
   687 
       
   688 			                GLX_DEBUG3("MGallery - CGlxCacheManager::MaintainCacheL() requesting attribute for list %x and item %d", list, itemId.Value());
       
   689 
       
   690 			                // Use list's isolated collection
       
   691 			                MMPXCollection& collection = list->Collection();
       
   692 
       
   693 			    			// Issue the request
       
   694 			    			collection.MediaL(*path, iRequestedAttrs.Array(), attrSpecs);
       
   695 							}
       
   696 						}
       
   697                     }
       
   698                 else
       
   699                 	{
       
   700 	                GLX_DEBUG3("MGallery - CGlxCacheManager::MaintainCacheL() requesting attribute for list %x and item %d", list, itemId.Value());
       
   701 
       
   702 	                // Use list's isolated collection
       
   703 	                MMPXCollection& collection = list->Collection();
       
   704                     if (collection.UidL().iUid == KGlxCollectionPluginImageViewerImplementationUid)
       
   705                         {
       
   706                         TInt mediaCnt = list->Count();
       
   707                         
       
   708  
       
   709                         
       
   710                         GLX_DEBUG3("Image Viewer Collection - Attrib population! mediaCnt=%d, Media Id=%d",
       
   711                                 mediaCnt, itemId.Value());
       
   712                         
       
   713                         delete iMPXMedia;
       
   714                         iMPXMedia = NULL;
       
   715 
       
   716                         TFileName fileName;
       
   717                         fileName.Append(iImageViewerInstance->ImageUri()->Des());
       
   718                             
       
   719                         iMPXMedia = CMPXMedia::NewL();
       
   720                         if(!iReader)
       
   721                             {
       
   722                             iReader = CGlxImageReader::NewL(*this);
       
   723                             iSchedulerWait->Start();
       
   724                             }
       
   725 
       
   726                         for ( TInt i = 0; i < iRequestedAttrs.Count(); i++ )
       
   727                             {
       
   728                             if ( iRequestedAttrs[i] == KMPXMediaGeneralId )
       
   729                                 {
       
   730                                 iMPXMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, 
       
   731                                         (TMPXItemId)itemId.Value());
       
   732                                 }
       
   733                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralType )
       
   734                                 {
       
   735                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem);
       
   736                                 }
       
   737                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralCategory )
       
   738                                 {
       
   739                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXImage);
       
   740                                 }                           
       
   741                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralUri )
       
   742                                 {
       
   743                                 iMPXMedia->SetTextValueL(KMPXMediaGeneralUri, fileName);
       
   744                                 }
       
   745                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralTitle )
       
   746                                 {
       
   747                                 TParsePtrC parser(fileName);
       
   748                                 iMPXMedia->SetTextValueL(KMPXMediaGeneralTitle, parser.Name());
       
   749                                 }
       
   750                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralDate )
       
   751                                 {
       
   752                                 TTime time;
       
   753                                 time.HomeTime();
       
   754                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralDate, time.Int64());
       
   755                                 }
       
   756                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralLastModifiedDate )
       
   757                                 {
       
   758                                 TTime time;
       
   759                                 time.HomeTime();
       
   760                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralLastModifiedDate, time.Int64());
       
   761                                 }
       
   762                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralSize )
       
   763                                 {
       
   764                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralSize, 1000);
       
   765                                 }
       
   766                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralDrive )
       
   767                                 {
       
   768                                 TParsePtrC parser(fileName);
       
   769                                 iMPXMedia->SetTextValueL(KMPXMediaGeneralDrive, parser.Drive());
       
   770                                 }
       
   771                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralMimeType )
       
   772                                 {
       
   773                                 TDataType dataType;
       
   774                                 GetMimeType(fileName, dataType);
       
   775                                 iMPXMedia->SetTextValueL(KMPXMediaGeneralMimeType, dataType.Des());
       
   776                                 }
       
   777                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralDuration )
       
   778                                 {
       
   779                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralDuration, 0);
       
   780                                 }
       
   781                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralSystemItem)
       
   782                                 {
       
   783                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralSystemItem, EFalse);
       
   784                                 }
       
   785                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralDimensions )
       
   786                                 {
       
   787                                 //need to fetch the original file dimensions
       
   788                                 TSize dimensions(iImgSz.iWidth,iImgSz.iHeight);
       
   789 
       
   790                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralDimensions, dimensions);
       
   791                                 }
       
   792                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralFramecount )
       
   793                                 {
       
   794                                 TInt fcount = 1;
       
   795                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralFramecount, fcount);
       
   796                                 }
       
   797                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralComment )
       
   798                                 {
       
   799                                 iMPXMedia->SetTextValueL(KMPXMediaGeneralComment, KNullDesC); 
       
   800                                 }
       
   801                             else if (iRequestedAttrs[i] == KMPXMediaDrmProtected )
       
   802                                 {
       
   803                                 iMPXMedia->SetTObjectValueL(KMPXMediaDrmProtected, EFalse); 
       
   804                                 }
       
   805                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralDRMRightsValid )            
       
   806                                 {
       
   807                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralDRMRightsValid,
       
   808                                             EGlxDrmRightsValidityUnknown); 
       
   809                                 }
       
   810                             else if ( iRequestedAttrs[i] == KMPXMediaGeneralCount )
       
   811                                 {
       
   812                                 iMPXMedia->SetTObjectValueL(KMPXMediaGeneralCount, 1);
       
   813                                 }
       
   814                             else if ( iRequestedAttrs[i] == KMPXMediaColDetailSpaceId )
       
   815                                 {
       
   816                                 TGlxIdSpaceId spaceId = list->IdSpaceId(iRequestedItemIndexes[0]);
       
   817                                 iMPXMedia->SetTObjectValueL(KMPXMediaColDetailSpaceId, spaceId.Value());
       
   818                                 }
       
   819                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralSlideshowableContent )
       
   820                                 {
       
   821                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralSlideshowableContent, -1);
       
   822                                 }
       
   823                             else if ( iRequestedAttrs[i] == KGlxMediaGeneralLocation)
       
   824                                 {
       
   825                                 // Set the attribute to a TCoordinate initialised to NaN. 
       
   826                                 iMPXMedia->SetTObjectValueL(KGlxMediaGeneralLocation, TCoordinate());
       
   827                                 }
       
   828                             else
       
   829                                 {
       
   830                                 User::Leave(KErrNotSupported);
       
   831                                 }
       
   832                             }
       
   833                         
       
   834                         HandleGarbageCollectionL(EFalse);
       
   835                         CleanupStack::PopAndDestroy(path);
       
   836                         iRequestOwner = list;
       
   837                         CleanupStack::PopAndDestroy(attrSpecs); 
       
   838                         TGlxIdSpaceId spaceId = list->IdSpaceId(iRequestedItemIndexes[0]);
       
   839                         HandleCollectionMediaL(spaceId, *iMPXMedia, KErrNone);
       
   840                         return;
       
   841                         }
       
   842                     else
       
   843                         {
       
   844                     // Issue the request
       
   845                     collection.MediaL(*path, iRequestedAttrs.Array(), attrSpecs);
       
   846                         }
       
   847                     }
       
   848 #else // USE_S60_TNM
       
   849                     delete iTempThumbnail;
       
   850                     iTempThumbnail = NULL;
       
   851                     iTempThumbnail = new (ELeave) CFbsBitmap;
       
   852                     User::LeaveIfError(iTempThumbnail->Create(TSize(), KGlxThumbnailDisplayMode));
       
   853                     iThumbnailId = itemId;
       
   854 
       
   855                     // Set bitmap handle in attribute spec
       
   856                     if (attrSpecs)
       
   857                         {
       
   858                         TMPXAttribute thHandleAttrSpec(KGlxMediaIdThumbnail, KGlxAttribSpecThumbnailBitmapHandle);
       
   859                         attrSpecs->SetTObjectValueL<TInt>(thHandleAttrSpec, iTempThumbnail->Handle());
       
   860                         }
       
   861                     // Cancel Clean-up is needed here;
       
   862                     // This is Going to Highly Used Call
       
   863                     // Can Think about an Ulternative.
       
   864                     HandleGarbageCollectionL(EFalse);
       
   865                     }
       
   866 
       
   867                 GLX_DEBUG3("MGallery - CGlxCacheManager::MaintainCacheL() requesting attribute for list %x and item %d", list, itemId.Value());
       
   868 
       
   869                 // Use list's isolated collection
       
   870                 MMPXCollection& collection = list->Collection();
       
   871 
       
   872     			// Issue the request
       
   873     			collection.MediaL(*path, iRequestedAttrs.Array(), attrSpecs);
       
   874 #endif
       
   875     			CleanupStack::PopAndDestroy(path);
       
   876     			
       
   877     			iRequestOwner = list;
       
   878     			}		
       
   879     			
       
   880     		CleanupStack::PopAndDestroy(attrSpecs);	
       
   881     		}
       
   882     		
       
   883         if ( !iRequestOwner )
       
   884             {
       
   885             if ( iTempError )
       
   886                 {
       
   887                 // Reawaken in a while to check again
       
   888                 StartTempErrorTimer();
       
   889                 }
       
   890             }
       
   891     	}
       
   892     }
       
   893 
       
   894 // -----------------------------------------------------------------------------
       
   895 // BroadcastAttributesAvailableL
       
   896 // -----------------------------------------------------------------------------
       
   897 //
       
   898 void CGlxCacheManager::BroadcastAttributesAvailableL(const TGlxIdSpaceId& aIdSpaceId, 
       
   899                     const TGlxMediaId& aMediaId, 
       
   900                     const RArray<TMPXAttribute>& aAttributes, 
       
   901                     const CGlxMedia* aMedia)
       
   902    {
       
   903    TRACER("CGlxCacheManager::BroadcastAttributesAvailableL");
       
   904    
       
   905     TInt count = iObserverList.Count();
       
   906     TInt i;
       
   907     for ( i = 0; i < count; i++ )
       
   908         {
       
   909         iObserverList[i]->HandleAttributesAvailableL(aIdSpaceId, aMediaId, aAttributes, aMedia);
       
   910         }
       
   911    }
       
   912 
       
   913 /**
       
   914  * Cleanup the media of the given media id: broadcast this to all observers
       
   915  * @param aMediaId The media id of the item
       
   916  */ 
       
   917 void CGlxCacheManager::CleanupMedia(const TGlxMediaId& aMediaId)
       
   918 	{
       
   919 	TRACER("CGlxCacheManager::CleanupMedia");
       
   920     TInt count = iObserverList.Count();
       
   921     GLX_DEBUG2("CGlxCacheManager::CleanupMedia -  aMediaId = %d", aMediaId.Value());
       
   922     TInt i;
       
   923     for ( i = 0; i < count; i++ )
       
   924         {
       
   925         iObserverList[i]->CleanupMedia(aMediaId);
       
   926         }
       
   927    }
       
   928 
       
   929 // -----------------------------------------------------------------------------
       
   930 // Handles modification of item in a cache
       
   931 // -----------------------------------------------------------------------------
       
   932 void CGlxCacheManager::HandleItemModified(const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aMediaId, const RArray<TMPXAttribute>& aAttributes)
       
   933 	{
       
   934 	TRACER("CGlxCacheManager::HandleItemModified");
       
   935 	
       
   936 	// Look for the correct subcache
       
   937 	TInt index = iCaches.FindInOrder(aIdSpaceId, (&CacheOrderByKey));
       
   938 	if (index != KErrNotFound)
       
   939 		{
       
   940 		iCaches[index]->HandleItemModified(aMediaId, aAttributes);
       
   941 		}
       
   942 	}
       
   943 
       
   944 // -----------------------------------------------------------------------------
       
   945 // CacheOrderById
       
   946 // -----------------------------------------------------------------------------
       
   947 //
       
   948 TInt CGlxCacheManager::CacheOrderById(const CGlxCache& aItem1, const CGlxCache& aItem2) 
       
   949 	{
       
   950 	TRACER("CGlxCacheManager::CacheOrderById");
       
   951 	
       
   952 	// Cannot do aItem1.IdSpaceId() - aItem2.IdSpaceId(), since IdSpaceId().Value() returns an unsigned value
       
   953 	TGlxIdSpaceId id1 = aItem1.IdSpaceId();
       
   954 	TGlxIdSpaceId id2 = aItem2.IdSpaceId();
       
   955 	if (id1 < id2) 
       
   956 		{
       
   957 		return -1;
       
   958 		}
       
   959 		
       
   960 	if (id1 > id2) 
       
   961 		{
       
   962 		return 1;
       
   963 		}
       
   964 
       
   965 	return 0;
       
   966 	}
       
   967 
       
   968 // -----------------------------------------------------------------------------
       
   969 // CacheOrderByKey
       
   970 // -----------------------------------------------------------------------------
       
   971 //
       
   972 TInt CGlxCacheManager::CacheOrderByKey(const TGlxIdSpaceId* aIdSpaceId, const CGlxCache& aItem2) 
       
   973 	{
       
   974 	TRACER("CGlxCacheManager::CacheOrderByKey");
       
   975 	
       
   976 	TGlxIdSpaceId id2 = aItem2.IdSpaceId();
       
   977 	if (*aIdSpaceId < id2) 
       
   978 		{
       
   979 		return -1;
       
   980 		}
       
   981 		
       
   982 	if (*aIdSpaceId > id2) 
       
   983 		{
       
   984 		return 1;
       
   985 		}
       
   986 
       
   987 	return 0;
       
   988 	}
       
   989 
       
   990 // -----------------------------------------------------------------------------
       
   991 // TempThumbnail
       
   992 // -----------------------------------------------------------------------------
       
   993 //
       
   994 CFbsBitmap* CGlxCacheManager::TempThumbnail()
       
   995     {
       
   996     TRACER("CGlxCacheManager::TempThumbnail");
       
   997     
       
   998     return iTempThumbnail;
       
   999     }
       
  1000     
       
  1001 // -----------------------------------------------------------------------------
       
  1002 // TempThumbnailId
       
  1003 // -----------------------------------------------------------------------------
       
  1004 //
       
  1005 TGlxMediaId CGlxCacheManager::TempThumbnailId()
       
  1006     {
       
  1007     TRACER("CGlxCacheManager::TempThumbnailId");
       
  1008     
       
  1009     return iThumbnailId;
       
  1010     }
       
  1011 
       
  1012 // -----------------------------------------------------------------------------
       
  1013 // SetTempThumbnail
       
  1014 // -----------------------------------------------------------------------------
       
  1015 //
       
  1016 void CGlxCacheManager::SetTempThumbnailToNull()
       
  1017     {
       
  1018     TRACER("CGlxCacheManager::SetTempThumbnailToNull");
       
  1019     
       
  1020     iTempThumbnail = NULL;
       
  1021     }
       
  1022 
       
  1023 // -----------------------------------------------------------------------------
       
  1024 // ErrorsOnRequestedItemsL
       
  1025 // -----------------------------------------------------------------------------
       
  1026 //
       
  1027 TBool CGlxCacheManager::ErrorsOnRequestedItemsL()
       
  1028     {
       
  1029     TRACER("CGlxCacheManager::ErrorsOnRequestedItemsL");
       
  1030     
       
  1031     TBool errorFound = EFalse;
       
  1032     
       
  1033     TInt itemCount = iRequestedItemIds.Count();
       
  1034     TInt attrCount = iRequestedAttrs.Count();
       
  1035     
       
  1036     for ( TInt itemIndex = 0; itemIndex < itemCount && !errorFound; itemIndex++ )
       
  1037         {
       
  1038         CGlxMedia* media = Media(iRequestedItemsIdSpace, iRequestedItemIds[itemIndex]);
       
  1039         
       
  1040         if ( media )
       
  1041             {
       
  1042             for ( TInt attrIndex = 0; attrIndex < attrCount && !errorFound; attrIndex++ )
       
  1043                 {
       
  1044                 errorFound = (KErrNone != GlxErrorManager::HasAttributeErrorL(media, iRequestedAttrs[attrIndex]));
       
  1045                 }
       
  1046             }
       
  1047         }
       
  1048     
       
  1049     return errorFound;
       
  1050     }
       
  1051     
       
  1052 // -----------------------------------------------------------------------------
       
  1053 // Caches
       
  1054 // -----------------------------------------------------------------------------
       
  1055 //
       
  1056 const RPointerArray<CGlxCache>& CGlxCacheManager::Caches()
       
  1057     {
       
  1058     TRACER("CGlxCacheManager::Caches");
       
  1059     
       
  1060     return iCaches;
       
  1061     }
       
  1062 
       
  1063 // -----------------------------------------------------------------------------
       
  1064 // SetTemporaryErrorFlag
       
  1065 // -----------------------------------------------------------------------------
       
  1066 //
       
  1067 void CGlxCacheManager::SetTemporaryErrorFlag()
       
  1068     {
       
  1069     TRACER("CGlxCacheManager::SetTemporaryErrorFlag");
       
  1070     
       
  1071     iTempError = ETrue;
       
  1072     }
       
  1073     
       
  1074 // -----------------------------------------------------------------------------
       
  1075 // StartTempErrorTimer
       
  1076 // -----------------------------------------------------------------------------
       
  1077 //
       
  1078 void CGlxCacheManager::StartTempErrorTimer()
       
  1079     {
       
  1080     TRACER("CGlxCacheManager::StartTempErrorTimer");
       
  1081     
       
  1082     iTempErrorTimer->Cancel();
       
  1083 	iTempErrorTimer->Start(
       
  1084 		TTimeIntervalMicroSeconds32(KGlxTemporaryErrorRecheckPeriodInSeconds * 1000000),
       
  1085 		TTimeIntervalMicroSeconds32(KGlxTemporaryErrorRecheckPeriodInSeconds * 1000000),
       
  1086 		TCallBack(&CGlxCacheManager::TempErrorTimerCallbackL,(TAny *)this));
       
  1087 	}
       
  1088 
       
  1089 // -----------------------------------------------------------------------------
       
  1090 // TempErrorTimerCallbackL
       
  1091 // -----------------------------------------------------------------------------
       
  1092 //
       
  1093 TInt CGlxCacheManager::TempErrorTimerCallbackL(TAny* aPtr)
       
  1094     {
       
  1095     TRACER("CGlxCacheManager::TempErrorTimerCallback");
       
  1096     
       
  1097 	CGlxCacheManager* self = (CGlxCacheManager*) aPtr;
       
  1098 	
       
  1099 	if ( self )
       
  1100 	    {
       
  1101     	self->TempErrorTimerCompleteL();
       
  1102     	}
       
  1103 
       
  1104     return 0;
       
  1105     }
       
  1106 
       
  1107 // -----------------------------------------------------------------------------
       
  1108 // TempErrorTimerComplete
       
  1109 // -----------------------------------------------------------------------------
       
  1110 //
       
  1111 void CGlxCacheManager::TempErrorTimerCompleteL()
       
  1112     {
       
  1113     TRACER("CGlxCacheManager::TempErrorTimerComplete");
       
  1114     
       
  1115     iTempErrorTimer->Cancel();
       
  1116     TRAPD(err, MaintainCacheL());
       
  1117     
       
  1118     // If MaintainCacheL leaves, force gabage collection to start and restart timer
       
  1119     if ( KErrNone != err )
       
  1120         {
       
  1121         if ( KErrNoMemory == err )
       
  1122             {
       
  1123             //iGarbageCollector->Cleanup();
       
  1124             HandleGarbageCollectionL(ETrue);
       
  1125             }
       
  1126             
       
  1127         if ( !iRequestOwner )
       
  1128             {
       
  1129             StartTempErrorTimer();
       
  1130             }
       
  1131         }
       
  1132     }
       
  1133     
       
  1134 // -----------------------------------------------------------------------------
       
  1135 // Create a path with the request items
       
  1136 // -----------------------------------------------------------------------------
       
  1137 //
       
  1138 inline CMPXCollectionPath* CGlxCacheManager::RequestAsPathLC(const CGlxMediaList& aList)
       
  1139     {
       
  1140     TRACER("CGlxCacheManager::RequestAsPathLC");
       
  1141     
       
  1142     CMPXCollectionPath* path = aList.PathLC( NGlxListDefs::EPathParent );
       
  1143 
       
  1144     RArray<TMPXItemId> mpxIds;
       
  1145     CleanupClosePushL( mpxIds );
       
  1146 
       
  1147     TInt itemIdsCount = iRequestedItemIds.Count();
       
  1148 
       
  1149     // Reserve space for all items
       
  1150     mpxIds.ReserveL( itemIdsCount );
       
  1151 
       
  1152     for (TInt i = 0; i < itemIdsCount; ++i)
       
  1153         {
       
  1154         mpxIds.AppendL( iRequestedItemIds[ i ].Value() );
       
  1155         }
       
  1156 
       
  1157     path->AppendL( mpxIds.Array() );
       
  1158     path->SelectAllL();
       
  1159 
       
  1160     CleanupStack::PopAndDestroy( &mpxIds );
       
  1161 
       
  1162     return path;
       
  1163     }
       
  1164 
       
  1165 // -----------------------------------------------------------------------------
       
  1166 // HandleListDeleted
       
  1167 // -----------------------------------------------------------------------------
       
  1168 void CGlxCacheManager::HandleListDeleted(CGlxMediaList* aList)
       
  1169     {
       
  1170     TRACER("CGlxCacheManager::HandleListDeleted");
       
  1171     
       
  1172     if (iRequestOwner == aList)
       
  1173         {
       
  1174         iRequestOwner = NULL;
       
  1175 
       
  1176         TRAP_IGNORE( MaintainCacheL() );
       
  1177         }
       
  1178     }
       
  1179 
       
  1180 // -----------------------------------------------------------------------------
       
  1181 // Inform cache manager to reserve users for an item, for a particular cache
       
  1182 // -----------------------------------------------------------------------------
       
  1183 //
       
  1184 void CGlxCacheManager::ReserveUsersL(const TGlxIdSpaceId& aIdSpaceId, TInt aCount)
       
  1185     {
       
  1186     TRACER("CGlxCacheManager::ReserveUsersL");
       
  1187     
       
  1188     // Look for existing cache
       
  1189     TInt index = iCaches.FindInOrder( aIdSpaceId, ( &CacheOrderByKey ) );
       
  1190     if (index != KErrNotFound)
       
  1191         {
       
  1192         iCaches[index]->ReserveUsersL( aCount );
       
  1193         }
       
  1194     }
       
  1195 //OOM 
       
  1196 // -----------------------------------------------------------------------------
       
  1197 // Start cache cleanup on Low memory event from OOM
       
  1198 // -----------------------------------------------------------------------------
       
  1199 //   
       
  1200 void CGlxCacheManager::ReleaseRAML(TBool aFlushOnRequest)
       
  1201 {
       
  1202     TRACER("CGlxCacheManager::ReleaseRAM");
       
  1203     if(aFlushOnRequest)
       
  1204         {
       
  1205         HandleGarbageCollectionL(aFlushOnRequest);        
       
  1206         }
       
  1207 	else
       
  1208 	{
       
  1209 		iGarbageCollector->CleanupL(); 	 				
       
  1210 	} 	
       
  1211 }
       
  1212 // -----------------------------------------------------------------------------
       
  1213 // Force a cleanup on particular media id : remove all attributes
       
  1214 // -----------------------------------------------------------------------------
       
  1215 // 
       
  1216 void CGlxCacheManager::ForceCleanupMedia(TGlxIdSpaceId aSpaceId, 
       
  1217                                           TGlxMediaId aMediaId)
       
  1218     {
       
  1219     TRACER("CGlxCacheManager::ForceCleanupMedia");  
       
  1220     TInt spaceIdIndex = iCaches.FindInOrder( aSpaceId, &CacheOrderByKey );
       
  1221     if ( KErrNotFound != spaceIdIndex )
       
  1222         {
       
  1223         if ( iCaches[spaceIdIndex]->Media( aMediaId ) )
       
  1224             {            
       
  1225             TInt mediaIdIndex = iCaches[spaceIdIndex]->FindMediaIndexInCache(aMediaId);
       
  1226             if ( KErrNotFound != mediaIdIndex )
       
  1227             	{
       
  1228             	iCaches[spaceIdIndex]->Delete(mediaIdIndex);
       
  1229             	}
       
  1230             }
       
  1231         }
       
  1232     }
       
  1233 
       
  1234 // -----------------------------------------------------------------------------
       
  1235 // Stop cache cleanup on good memory event from OOM
       
  1236 // -----------------------------------------------------------------------------
       
  1237 //
       
  1238 void CGlxCacheManager::StopRAMReleaseL()
       
  1239 {
       
  1240     TRACER("CGlxCacheManager::StopRAMRelease");
       
  1241     iGarbageCollector->CancelCleanup(); 		
       
  1242 
       
  1243 }
       
  1244 //OOM
       
  1245 
       
  1246 #ifdef USE_S60_TNM
       
  1247 // -----------------------------------------------------------------------------
       
  1248 // CGlxCacheManager::FindLoadingById()
       
  1249 // -----------------------------------------------------------------------------
       
  1250 //
       
  1251 TInt CGlxCacheManager::FindLoadingById(TThumbnailRequestId aId, TBool aRemove)
       
  1252     {
       
  1253     TRACER("CGlxCacheManager::FindLoadingById");
       
  1254     TInt index = KErrNotFound;
       
  1255     for(TInt i = 0; i < iThumbnailRequestIds.Count(); ++i)
       
  1256         {
       
  1257         if(iThumbnailRequestIds[i].iId == aId)
       
  1258             {
       
  1259             index = i;
       
  1260             if(aRemove)
       
  1261                 {
       
  1262                 iThumbnailRequestIds.Remove(i);
       
  1263                 }
       
  1264             break;
       
  1265             }
       
  1266         }
       
  1267     return index;
       
  1268     }
       
  1269 
       
  1270 // -----------------------------------------------------------------------------
       
  1271 // CGlxCacheManager::ThumbnailPreviewReady()
       
  1272 // -----------------------------------------------------------------------------
       
  1273 //
       
  1274 void CGlxCacheManager::ThumbnailPreviewReady(MThumbnailData& aThumbnail,
       
  1275         TThumbnailRequestId aId)
       
  1276     {
       
  1277     TRACER("CGlxCacheManager::ThumbnailPreviewReady");
       
  1278     TInt error = KErrNotSupported;
       
  1279     if (aThumbnail.Bitmap() != NULL)
       
  1280          {
       
  1281 		 GLX_DEBUG1("CGlxCacheManager::ThumbnailPreviewReady preview aval");
       
  1282          error = KErrNone;
       
  1283          }
       
  1284     ThumbnailReadyL(error, aThumbnail, aId, EFalse);
       
  1285     }
       
  1286 
       
  1287 // -----------------------------------------------------------------------------
       
  1288 // CGlxCacheManager::ThumbnailReady()
       
  1289 // -----------------------------------------------------------------------------
       
  1290 //
       
  1291 void CGlxCacheManager::ThumbnailReady(TInt aError,
       
  1292         MThumbnailData& aThumbnail, TThumbnailRequestId aId)
       
  1293     {
       
  1294     TRACER("CGlxCacheManager::ThumbnailReady");
       
  1295     GLX_DEBUG2("CGlxCacheManager::ThumbnailReady aError=%d", aError);
       
  1296     ThumbnailReadyL(aError, aThumbnail, aId, ETrue);
       
  1297     }
       
  1298 
       
  1299 // -----------------------------------------------------------------------------
       
  1300 // CGlxCacheManager::ThumbnailReadyL()
       
  1301 // -----------------------------------------------------------------------------
       
  1302 //
       
  1303 void CGlxCacheManager::ThumbnailReadyL(TInt aError, MThumbnailData& aThumbnail, 
       
  1304                                        TThumbnailRequestId aId, TBool aQuality)
       
  1305     {
       
  1306     TRACER("CGlxCacheManager::ThumbnailReadyL");
       
  1307     GLX_DEBUG3("CGlxCacheManager::ThumbnailReadyL aError=%d, aQuality=%d",
       
  1308                                 aError, aQuality);
       
  1309 
       
  1310 #ifdef _DEBUG
       
  1311     iStopTime.HomeTime(); // Get home time
       
  1312     GLX_DEBUG2("=>CGlxCacheManager::ThumbnailReadyL - TN Fetch took <%d> us", 
       
  1313                     (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64());
       
  1314 #endif
       
  1315     
       
  1316 	TInt reqIndex = FindLoadingById(aId, EFalse);
       
  1317 		
       
  1318     if (reqIndex == KErrNotFound)
       
  1319         {
       
  1320 		return;
       
  1321         }
       
  1322 
       
  1323     delete iMPXMedia;
       
  1324     iMPXMedia = NULL;
       
  1325         
       
  1326     iMPXMedia = CMPXMedia::NewL();
       
  1327     if (aError == KErrNone)
       
  1328         {
       
  1329         delete iTempThumbnail;
       
  1330         iTempThumbnail = NULL;
       
  1331         iTempThumbnail = aThumbnail.DetachBitmap();
       
  1332 
       
  1333         CGlxThumbnailAttribute* tnAttribute = new (ELeave) CGlxThumbnailAttribute;
       
  1334         CleanupStack::PushL(tnAttribute);
       
  1335         tnAttribute->iDimensions = iThumbnailRequestIds[reqIndex].iSize;
       
  1336 	    tnAttribute->iThumbnailQuality = aQuality;
       
  1337                 
       
  1338         iMPXMedia->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, 
       
  1339 						iThumbnailRequestIds[reqIndex].iThumbnailId.Value());
       
  1340         TUint attributeId = GlxFullThumbnailAttributeId(aQuality, 
       
  1341 								iThumbnailRequestIds[reqIndex].iSize.iWidth, 
       
  1342 								iThumbnailRequestIds[reqIndex].iSize.iHeight);
       
  1343         iMPXMedia->SetNoNewLCObjectL(
       
  1344                TMPXAttribute(KGlxMediaIdThumbnail, attributeId), tnAttribute);
       
  1345         CleanupStack::PopAndDestroy(tnAttribute);
       
  1346 
       
  1347         HandleCollectionMediaL(iThumbnailRequestIds[reqIndex].iSpaceId,
       
  1348                                                     *iMPXMedia, aError);
       
  1349         }
       
  1350     else
       
  1351         {
       
  1352         HandleCollectionMediaL(iThumbnailRequestIds[reqIndex].iSpaceId, 
       
  1353 													*iMPXMedia, aError);
       
  1354         }
       
  1355     
       
  1356     if (aQuality)
       
  1357         {
       
  1358         FindLoadingById(aId, ETrue);
       
  1359         }   
       
  1360     }
       
  1361 #endif
       
  1362 
       
  1363 void CGlxCacheManager::GetMimeType(TFileName& aFileName, TDataType& aMimeType)
       
  1364     {
       
  1365     RApaLsSession session;
       
  1366     User::LeaveIfError( session.Connect() );
       
  1367     CleanupClosePushL( session );
       
  1368 
       
  1369     TUid uid;
       
  1370     User::LeaveIfError( session.AppForDocument( aFileName, uid, aMimeType ) );
       
  1371     CleanupStack::PopAndDestroy(); // session
       
  1372 
       
  1373     }
       
  1374 void CGlxCacheManager::ImageReadyL(const TInt& aError, const TSize aSz)
       
  1375     {
       
  1376     if(iSchedulerWait)
       
  1377         {
       
  1378         iSchedulerWait->AsyncStop();    
       
  1379         }    
       
  1380     iImgSz = aSz;
       
  1381     }