photosgallery/viewframework/medialists/src/glxcache.cpp
changeset 0 4e91876724a2
child 9 6b87b143d312
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:    Cache implementation for media items sharing the same Id space
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "glxcache.h"
       
    22 
       
    23 #include <glxassert.h>
       
    24 #include <mpxmediadrmdefs.h>			// for DRM attributes
       
    25 #include <mpxmediacontainerdefs.h>
       
    26 #include <mpxmediacollectiondetaildefs.h>
       
    27 #include <glxthumbnailattributeinfo.h>
       
    28 #include <glxtracer.h>
       
    29 #include <lbsposition.h>				//for TCoordinate
       
    30 
       
    31 #include "glxcachemanager.h"
       
    32 #include "glxmedialist.h"
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // Constructor
       
    36 // -----------------------------------------------------------------------------
       
    37 //
       
    38 CGlxCache::CGlxCache( const TGlxIdSpaceId& aIdSpaceId, CGlxCacheManager* aCacheManager )
       
    39         : iIdSpaceId( aIdSpaceId ), iCacheManager(aCacheManager)
       
    40     {
       
    41     TRACER("CGlxCache::CGlxCache");
       
    42     }
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // Destructor
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CGlxCache::~CGlxCache()
       
    49     {
       
    50     TRACER("CGlxCache::Destructor");
       
    51     iItemPool.ResetAndDestroy();
       
    52     }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // IdSpaceId
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 TGlxIdSpaceId CGlxCache::IdSpaceId() const
       
    59     {
       
    60     TRACER("CGlxCache::IdSpaceId");
       
    61     
       
    62     return iIdSpaceId;
       
    63     }
       
    64     
       
    65 // -----------------------------------------------------------------------------
       
    66 // return a media object or null
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CGlxMedia* CGlxCache::Media( const TGlxMediaId& aId ) const
       
    70 	{
       
    71 	TRACER("CGlxCache::Media");
       
    72 	
       
    73     TInt index = iItemPool.FindInOrder(aId, (&MediaItemOrderByKey));
       
    74     if ( KErrNotFound != index )
       
    75         {
       
    76         return iItemPool[index];
       
    77         }
       
    78         
       
    79     return NULL;
       
    80     }
       
    81 
       
    82 // -----------------------------------------------------------------------------
       
    83 // FindItemForceCreateL
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 CGlxMedia* CGlxCache::FindItemForceCreateL( const TGlxMediaId& aId )
       
    87     {
       
    88     TRACER("CGlxCache::FindItemForceCreateL");
       
    89     
       
    90     CGlxMedia* media = Media( aId );
       
    91 
       
    92     if ( !media )
       
    93         {
       
    94         media = CreateItemL( aId );
       
    95         }
       
    96 
       
    97     return media;	
       
    98     }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 // CreateItemL
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 CGlxMedia* CGlxCache::CreateItemL(const TGlxMediaId& aId)
       
   105     {
       
   106     TRACER("CGlxCache::CreateItemL");
       
   107     
       
   108     CGlxMedia* item = NULL;
       
   109     
       
   110     iItemPool.ReserveL( iItemPool.Count() + 1 );
       
   111     item = new (ELeave) CGlxMedia(aId);
       
   112     TLinearOrder<CGlxMedia> orderer (&MediaItemOrderById);
       
   113     iItemPool.InsertInOrder(item, orderer);
       
   114 
       
   115 	// Safe to fail, since if the media objects is not used by any lists,
       
   116 	// garbage collection will simply delete it
       
   117 	RPointerArray<CGlxMediaList>& mediaLists = CGlxMediaList::MediaListsL();
       
   118 
       
   119 	TInt count = mediaLists.Count();
       
   120 	item->ReserveUsersL(count);
       
   121 	for (TInt i = 0; i < count; i++) 
       
   122 		{
       
   123 		mediaLists[i]->OfferMedia(iIdSpaceId, item);
       
   124 		}
       
   125 
       
   126     return item;    
       
   127     }
       
   128 
       
   129 // -----------------------------------------------------------------------------
       
   130 // MediaUpdatedL
       
   131 // -----------------------------------------------------------------------------
       
   132 //
       
   133 void CGlxCache::MediaUpdatedL(const CMPXMedia& aMedia)
       
   134     {
       
   135     TRACER("CGlxCache::MediaUpdatedL");
       
   136     
       
   137     if (aMedia.IsSupported(KMPXMediaArrayContents))
       
   138         {
       
   139         CMPXMediaArray* mediaArray = aMedia.ValueCObjectL<CMPXMediaArray>(KMPXMediaArrayContents);
       
   140         CleanupStack::PushL(mediaArray);
       
   141 
       
   142         TInt arrayCount = mediaArray->Count();
       
   143 		GLX_DEBUG2("CGlxCache::MediaUpdatedL() arrayCount=%d", arrayCount);
       
   144         for (TInt count = 0; count < arrayCount; ++count)
       
   145             {
       
   146             UpdateMediaL(*((*mediaArray)[count]));
       
   147             }
       
   148 
       
   149         CleanupStack::PopAndDestroy(mediaArray);
       
   150         }
       
   151     else
       
   152         {
       
   153         UpdateMediaL(aMedia);
       
   154         }
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // UpdateMediaL
       
   159 // -----------------------------------------------------------------------------
       
   160 void CGlxCache::UpdateMediaL(const CMPXMedia& aMedia)
       
   161     {
       
   162     TRACER("CGlxCache::UpdateMediaL");
       
   163     
       
   164     if ( !aMedia.IsSupported(KMPXMediaGeneralId) )
       
   165         {
       
   166         return;
       
   167         }
       
   168 	// Copy/synchronize attributes
       
   169     TGlxMediaId id ((TUint32)aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
   170 	GLX_DEBUG2("CGlxCache::UpdateMediaL() id=%d", id.Value());	
       
   171 	CGlxMedia* item = Media( id );
       
   172 
       
   173 	RArray<TMPXAttribute> newAttributes;
       
   174 	CleanupClosePushL(newAttributes);
       
   175 	
       
   176 	if (item != NULL)
       
   177 		{
       
   178 		GLX_DEBUG2("MGallery - CGlxCacheManager::HandleCollectionMediaL() existing item for item id %d", id.Value());
       
   179 		CopyNewAndModifiedL(*item, aMedia, newAttributes);
       
   180     	}
       
   181     else 
       
   182     	{
       
   183 		GLX_DEBUG2("MGallery - CGlxCacheManager::HandleCollectionMediaL() new item for item id %d", id.Value());
       
   184 
       
   185     	// This is a new item. Create a media object and offer it to all lists.
       
   186     	// If the item is no longer needed by any list, then this is ok, since
       
   187     	// garbage collection will delete the item
       
   188     	// Add in id order.        	
       
   189     	item = CreateItemL(id);
       
   190     	
       
   191 		CopyNewAndModifiedL(*item, aMedia, newAttributes);
       
   192     	}
       
   193 		
       
   194 	// Broadcast the new attributes to all observers of the item and the cache
       
   195 	if (newAttributes.Count() > 0)
       
   196 		{
       
   197 		TInt count = item->UserCount();
       
   198 		for (TInt i = 0; i < count; i++)
       
   199 			{
       
   200 			item->User( i ).HandleAttributesAvailableL( item->IndexInUser( i ), newAttributes );
       
   201 			}
       
   202 			
       
   203 	    // Broadcast to cache observers
       
   204 		// iCacheManager->BroadcastAttributesAvailableL(iIdSpaceId, id, newAttributes, item);
       
   205 		}
       
   206 
       
   207 	CleanupStack::PopAndDestroy(&newAttributes);
       
   208     }
       
   209 // -----------------------------------------------------------------------------
       
   210 // Deletes the media item
       
   211 // -----------------------------------------------------------------------------
       
   212 void CGlxCache::CleanupMedia(const TGlxMediaId& aMediaId)
       
   213 	{
       
   214 	TRACER("CGlxCache::CleanupMedia");
       
   215     GLX_DEBUG2("CGlxCache::CleanupMedia -  aMediaId = %d", aMediaId.Value());
       
   216     if(iCacheManager)
       
   217         {
       
   218         iCacheManager->CleanupMedia(aMediaId);
       
   219         }
       
   220 	}
       
   221     
       
   222 // -----------------------------------------------------------------------------
       
   223 // Handles modifications of item in cache
       
   224 // -----------------------------------------------------------------------------
       
   225 void CGlxCache::HandleItemModified(const TGlxMediaId& aId, const RArray<TMPXAttribute>& aAttributes)
       
   226 	{
       
   227 	TRACER("CGlxCache::HandleItemModified");
       
   228 	
       
   229 	TInt index = iItemPool.FindInOrder(aId, (&MediaItemOrderByKey));
       
   230 	if (index != KErrNotFound)
       
   231 		{
       
   232 		iItemPool[index]->HandleModified(aAttributes);
       
   233 		}
       
   234 	}
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // Copies new and modified attributes from the provided media object
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 void CGlxCache::CopyNewAndModifiedL(CGlxMedia& aTarget, const CMPXMedia& aSource, 
       
   241         RArray<TMPXAttribute>& aNewAttributes)
       
   242     {
       
   243     TRACER("CGlxCache::CopyNewAndModifiedL");
       
   244     
       
   245     /// @todo This is all temporary until global chunk based CMPXMedia is available
       
   246     TInt count = aSource.Count();
       
   247 	GLX_DEBUG2("CGlxCache::CopyNewAndModifiedL() Attribs count=%d", count);
       
   248     aNewAttributes.ReserveL( count );
       
   249 
       
   250     for (TInt i = 0; i < count; i++)
       
   251         {
       
   252         const TMPXAttribute& attrib = aSource.Attribute(i);
       
   253 
       
   254         if (attrib == KMPXMediaGeneralId)
       
   255             {
       
   256             // Ignore id
       
   257             __ASSERT_DEBUG((TUint32)aSource.ValueTObjectL<TMPXItemId>(attrib) == aTarget.Id().Value(), 
       
   258                            Panic(EGlxPanicIllegalArgument)); // aMedia relates to another media object than this
       
   259             }
       
   260         else 
       
   261             {
       
   262             if (!aTarget.IsSupported(attrib)) 
       
   263                 {
       
   264                 TMPXAttributeType type = aSource.Type(i);
       
   265 
       
   266                 if (type == EMPXTypeText) 
       
   267                     {
       
   268                     aTarget.SetTextValueL(attrib, aSource.ValueText(attrib));
       
   269                     }
       
   270                 else if (type == EMPXTypeCObject) 
       
   271                     {
       
   272                     if ( KGlxMediaIdThumbnail == attrib.ContentId() )
       
   273                         {
       
   274                         // This is a thumbnail
       
   275                         CFbsBitmap* thumbnail = iCacheManager->TempThumbnail();
       
   276 
       
   277                         if ( thumbnail && iCacheManager->TempThumbnailId() == aTarget.Id() )
       
   278                             {
       
   279                             // Add new thumbnail attribute
       
   280                             CGlxThumbnailAttribute* value =
       
   281                                 aSource.ValueNoNewLCObjectL<CGlxThumbnailAttribute>(attrib);
       
   282                             CleanupStack::PushL(value);
       
   283                             value->iBitmap = thumbnail;
       
   284                             GLX_DEBUG3("CGlxCache::CopyNewAndModifiedL() TN Attrib w(%d) h(%d)", 
       
   285 					        	thumbnail->SizeInPixels().iWidth, thumbnail->SizeInPixels().iHeight);
       
   286                             iCacheManager->SetTempThumbnailToNull();
       
   287                             aTarget.SetCObjectValueL(attrib, value);
       
   288                             CleanupStack::Pop(value);
       
   289                             }
       
   290                         }
       
   291                     else
       
   292                         {
       
   293                         __DEBUG_ONLY(Panic(EGlxPanicNotImplemented)); // Add support for the attribute here
       
   294                         }
       
   295                     }
       
   296                 else if (type == EMPXTypeTObject) 
       
   297                     {
       
   298                     if (attrib == KMPXMediaGeneralThumbnail1)
       
   299                         {
       
   300                         // Old thumbnail attribute - ignore
       
   301                         }
       
   302                     else if (attrib == KMPXMediaGeneralDate)
       
   303                         {
       
   304                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt64>(attrib));
       
   305                         }
       
   306                     else if (attrib == KGlxMediaGeneralLastModifiedDate)
       
   307                         {
       
   308                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt64>(attrib));
       
   309                         }
       
   310                     else if (attrib == KMPXMediaGeneralSize)
       
   311                         {
       
   312                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   313                         }
       
   314                     else if (attrib == KMPXMediaColDetailSpaceId)
       
   315                         {
       
   316                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TGlxIdSpaceId>(attrib));
       
   317                         }
       
   318                     else if (attrib == KMPXMediaGeneralType)
       
   319                         {
       
   320                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   321                         }
       
   322                     else if (attrib == KMPXMediaGeneralCategory)
       
   323                         {
       
   324                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   325                         }
       
   326                     else if (attrib == KMPXMediaGeneralCount)
       
   327                         {
       
   328                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   329                         }
       
   330                     else if (attrib == KGlxMediaGeneralDimensions)
       
   331                         {
       
   332                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TSize>(attrib));
       
   333                         }
       
   334                     else if (attrib == KGlxMediaGeneralLocation)
       
   335                         {
       
   336                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TCoordinate>(attrib));
       
   337                         }
       
   338                     else if (attrib == KMPXMediaGeneralDuration)
       
   339                         {
       
   340                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   341                         }  
       
   342                     else if (attrib == KMPXMediaDrmProtected)
       
   343                         {
       
   344                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TBool>(attrib));
       
   345                         }                         
       
   346                     else if (attrib == KGlxMediaGeneralDRMRightsValid)
       
   347                         {
       
   348                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TBool>(attrib));
       
   349                         }                         
       
   350                     else if (attrib == KGlxMediaGeneralSystemItem)
       
   351                         {
       
   352                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TBool>(attrib));
       
   353                         }
       
   354                     else if (attrib == KGlxMediaGeneralFramecount)
       
   355                         {
       
   356                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   357                         }				         				
       
   358                     else if(attrib == KGlxMediaGeneralSlideshowableContent)
       
   359                         {
       
   360                         aTarget.SetTObjectValueL(attrib, aSource.ValueTObjectL<TInt>(attrib));
       
   361                         }        				
       
   362                     else
       
   363                         {
       
   364                         __DEBUG_ONLY(Panic(EGlxPanicNotImplemented)); // Add support for the attribute here
       
   365                         }
       
   366                     }
       
   367                 else 
       
   368                     {
       
   369                     __DEBUG_ONLY(Panic(EGlxPanicNotImplemented)); 
       
   370                     }
       
   371 
       
   372                 aNewAttributes.AppendL(attrib);
       
   373                 }
       
   374             }
       
   375         }
       
   376     }
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // Delete
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 void CGlxCache::Delete( TInt aIndex ) 
       
   383     {
       
   384     TRACER("CGlxCache::Delete");
       
   385     
       
   386     GLX_ASSERT_DEBUG( 0 <= aIndex && aIndex < iItemPool.Count(), 
       
   387         Panic(EGlxPanicIllegalArgument), "deleting attribute out of bounds");
       
   388         
       
   389     CGlxMedia* media = iItemPool[aIndex];
       
   390     
       
   391     // Cleanup the media from all users, example texture manager
       
   392     CleanupMedia(media->Id());
       
   393     
       
   394     GLX_DEBUG2("MGallery - CGlxCache::Delete() for item id %d", media->Id().Value());
       
   395     // notify users that the media object is about to be deleted. This allows
       
   396     // users to remove their references
       
   397     // (loop does not t iterate indexes, since the contents of the User array 
       
   398     // will change during calls to RemoveReferences, as users are removed)
       
   399     
       
   400     // safety check that RemoveReference actually removed the reference
       
   401     __DEBUG_ONLY( TInt _maxLoopCount = 1000 );
       
   402     
       
   403     while ( media->UserCount() > 0 )
       
   404         {
       
   405         // The user must remove a reference and that will decrement the 
       
   406         // UserCount()
       
   407         media->User( 0 ).RemoveReference( media->IndexInUser( 0 ) );
       
   408         
       
   409         // protect against a bug that would cause hard-to-find infinite loop
       
   410         __DEBUG_ONLY( _maxLoopCount-- );
       
   411         GLX_ASSERT_DEBUG( _maxLoopCount != 0, Panic( EGlxPanicLogicError ),
       
   412             "infinite loop when removing a media object" );
       
   413         }
       
   414     
       
   415     delete media;
       
   416     iItemPool.Remove( aIndex );
       
   417     }
       
   418     
       
   419 // -----------------------------------------------------------------------------
       
   420 // Reserve space for a number of users, for all items in the cache
       
   421 // -----------------------------------------------------------------------------
       
   422 //
       
   423 void CGlxCache::ReserveUsersL(TInt aCount)
       
   424     {
       
   425     TRACER("CGlxCache::ReserveUsersL");
       
   426     
       
   427     TInt count = iItemPool.Count();
       
   428     for ( TInt i = 0; i < count ; ++i )
       
   429         {
       
   430         iItemPool[i]->ReserveUsersL( aCount );
       
   431         }
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // MediaItemOrderById
       
   436 // -----------------------------------------------------------------------------
       
   437 //
       
   438 TInt CGlxCache::MediaItemOrderById(const CGlxMedia& aItem1, const CGlxMedia& aItem2) 
       
   439 	{
       
   440 	TRACER("CGlxCache::MediaItemOrderById");
       
   441 	
       
   442 	// Cannot do aItem1.Id() - aItem2.Id(), since Id().Value() returns an unsigned value
       
   443 	TGlxMediaId id1 = aItem1.Id();
       
   444 	return MediaItemOrderByKey( &id1, aItem2 );
       
   445 	}
       
   446 
       
   447 // -----------------------------------------------------------------------------
       
   448 // MediaItemOrderByKey
       
   449 // -----------------------------------------------------------------------------
       
   450 //
       
   451 TInt CGlxCache::MediaItemOrderByKey(const TGlxMediaId* aMediaId, const CGlxMedia& aItem2) 
       
   452 	{
       
   453 	TRACER("CGlxCache::MediaItemOrderByKey");
       
   454 	
       
   455 	TGlxMediaId id2 = aItem2.Id();
       
   456 	if (*aMediaId < id2) 
       
   457 		{
       
   458 		return -1;
       
   459 		}
       
   460 		
       
   461 	if (*aMediaId > id2) 
       
   462 		{
       
   463 		return 1;
       
   464 		}
       
   465 
       
   466 	return 0;
       
   467 	}
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // Return count of media objects
       
   471 // -----------------------------------------------------------------------------
       
   472 //
       
   473 TInt CGlxCache::Count()
       
   474     {
       
   475     TRACER("CGlxCache::Count");
       
   476     
       
   477     return iItemPool.Count();
       
   478     }
       
   479     
       
   480 // -----------------------------------------------------------------------------
       
   481 // Return media object by index
       
   482 // -----------------------------------------------------------------------------
       
   483 //
       
   484 CGlxMedia& CGlxCache::Media( TInt aIndex )
       
   485     {
       
   486     TRACER("CGlxCache::Media");
       
   487     
       
   488     return *iItemPool[aIndex];
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // Return media index
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 TInt CGlxCache::FindMediaIndexInCache(TGlxMediaId aMediaId)
       
   496 	{
       
   497 	TRACER("CGlxCache::FindMediaIndexInCache");
       
   498 	 
       
   499 	return iItemPool.FindInOrder(aMediaId, (&MediaItemOrderByKey));
       
   500 	}
       
   501