mpx/collectionframework/collectionengine/src/mpxcollectionengine.cpp
changeset 0 a2952bb97e68
child 4 d45095c2f4f3
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Manages collection information for the clients
       
    15 *
       
    16 */
       
    17 
       
    18 #include <driveinfo.h>
       
    19 #include <sysutil.h> 
       
    20 
       
    21 #include <mpxprivatecrkeys.h>
       
    22 #include <mpxcollectionpath.h>
       
    23 #include <mpxcollectionobserver.h>
       
    24 #include <mpxclientlist.h>
       
    25 #include <mpxcmn.h>
       
    26 #include <mpxcollectiontype.h>
       
    27 #include <mpxmediageneraldefs.h>
       
    28 #include <mpxmediacontainerdefs.h>
       
    29 #include <mpxmedia.h>
       
    30 #include <mpxmediaarray.h>
       
    31 #include <mpxpluginmonitor.h>
       
    32 #include <mpxcollectionmessage.h>
       
    33 #include <mpxcollectionplugin.hrh>
       
    34 #include <mpxcollectionplugin.h>
       
    35 #include <mpxcollectionmessagedefs.h>
       
    36 #include <mpxmessagegeneraldefs.h>
       
    37 #include <mpxmessagecontainerdefs.h>
       
    38 #include <mpxmessagepluginupdatedefs.h>
       
    39 
       
    40 #include "mpxcollectionpluginhandler.h"
       
    41 #include "mpxcollectioncache.h"
       
    42 #include "mpxcollectionengine.h"
       
    43 
       
    44 // CONSTANTS
       
    45 const TInt KMPXMaxCacheSizeRatio = 70;
       
    46 // ============================ LOCAL FUNCTIONS ==============================
       
    47 
       
    48 /**
       
    49 * Container class for the plugin reference counting mechanism.
       
    50 * Instances of this class are pushed onto the engine internal stack.
       
    51 */
       
    52 class TReleaseInfo
       
    53     {
       
    54     public:
       
    55         TReleaseInfo(CMPXCollectionPluginHandler* aHandler,
       
    56             CMPXCollectionPlugin* aPlugin);
       
    57 
       
    58     public:
       
    59         // Not owned
       
    60         CMPXCollectionPluginHandler* iHandler;
       
    61         CMPXCollectionPlugin* iPlugin;
       
    62     };
       
    63 
       
    64 // ----------------------------------------------------------------------------
       
    65 // Constructor.
       
    66 // ----------------------------------------------------------------------------
       
    67 //
       
    68 TReleaseInfo::TReleaseInfo(
       
    69     CMPXCollectionPluginHandler* aHandler,
       
    70     CMPXCollectionPlugin* aPlugin) :
       
    71     iHandler(aHandler),
       
    72     iPlugin(aPlugin)
       
    73     {
       
    74     }
       
    75 
       
    76 // ============================ MEMBER FUNCTIONS ==============================
       
    77 
       
    78 // ----------------------------------------------------------------------------
       
    79 // Two-phased constructor.
       
    80 // ----------------------------------------------------------------------------
       
    81 //
       
    82 EXPORT_C CMPXCollectionEngine* CMPXCollectionEngine::NewL()
       
    83     {
       
    84     CMPXCollectionEngine* p=new(ELeave)CMPXCollectionEngine();
       
    85     CleanupStack::PushL(p);
       
    86     p->ConstructL();
       
    87     CleanupStack::Pop(p);
       
    88     return p;
       
    89     }
       
    90 
       
    91 // ----------------------------------------------------------------------------
       
    92 // Constructor.
       
    93 // ----------------------------------------------------------------------------
       
    94 //
       
    95 CMPXCollectionEngine::CMPXCollectionEngine()
       
    96     {
       
    97     }
       
    98 
       
    99 // ----------------------------------------------------------------------------
       
   100 // 2nd phase constructor.
       
   101 // ----------------------------------------------------------------------------
       
   102 //
       
   103 void CMPXCollectionEngine::ConstructL()
       
   104     {
       
   105     iPluginHandler=CMPXCollectionPluginHandler::NewL(*this, *this);
       
   106     iCache = CMPXCollectionCache::NewL(KMPXMaxCacheSizeRatio);
       
   107     }
       
   108 
       
   109 // ----------------------------------------------------------------------------
       
   110 // Destructor
       
   111 // ----------------------------------------------------------------------------
       
   112 //
       
   113 EXPORT_C CMPXCollectionEngine::~CMPXCollectionEngine()
       
   114     {
       
   115     iCleanupStack.Close();
       
   116 
       
   117     iContexts.ResetAndDestroy();
       
   118     iContexts.Close();
       
   119     delete iPluginHandler;
       
   120     delete iCache;
       
   121     }
       
   122 
       
   123 // ----------------------------------------------------------------------------
       
   124 // Session Initialiser
       
   125 // ----------------------------------------------------------------------------
       
   126 //
       
   127 EXPORT_C CMPXCollectionClientContext& CMPXCollectionEngine::SessionInitL(
       
   128     const TUid& aModeId,
       
   129     TThreadId aClientId,
       
   130     CMPXMessageQueue* aMsgQueue)
       
   131     {
       
   132     CMPXCollectionClientContext* context(NULL);
       
   133 
       
   134     if (aModeId == KMcModeDefault)
       
   135         {
       
   136         // Connects the client to the collection path in its thread, or
       
   137         // creates one if it doesn't exist
       
   138         context = FindDefaultContext(aClientId);
       
   139         if (context)
       
   140             {
       
   141             MPX_DEBUG1("CMPXCollectionEngine add client into the default context");
       
   142             }
       
   143         else
       
   144             {
       
   145             // Creates a isolated collection path.
       
   146             context = CreateNewContextL(KMcModeIsolated);
       
   147             MPX_DEBUG1("CMPXCollectionEngine add client into the isolated context");
       
   148             }
       
   149         }
       
   150      else if (aModeId == KMcModeIsolated || aModeId == KMcModePlaylist)
       
   151         {
       
   152         // Creates a isolated collection path.
       
   153         context = CreateNewContextL(aModeId);
       
   154         MPX_DEBUG1("CMPXCollectionEngine add client into the isolated/playlist context");
       
   155         }
       
   156      else
       
   157         // Connects to the collection context of an application, or creates
       
   158         // it if it doesn't exist
       
   159         {
       
   160         for (TInt i=0;i<iContexts.Count();++i)
       
   161             {
       
   162             if (iContexts[i]->ModeId() == aModeId)
       
   163                 {
       
   164                 context = iContexts[i];
       
   165                 break;
       
   166                 }
       
   167             }
       
   168 
       
   169         if (!context)
       
   170             {
       
   171             // Create the application context
       
   172             context = CreateNewContextL(aModeId);
       
   173             }
       
   174 
       
   175         MPX_DEBUG1("CMPXCollectionEngine add client into the application context");
       
   176         }
       
   177     context->AddClientL(aClientId, aMsgQueue);
       
   178     MPX_DEBUG3("CMPXCollectionEngine::SessionInitL return context 0x%08x with mode 0x%08x",
       
   179                context, context->ModeId().iUid);
       
   180     return *context;
       
   181     }
       
   182 
       
   183 // ----------------------------------------------------------------------------
       
   184 // Notifies all contexts of an event
       
   185 // ----------------------------------------------------------------------------
       
   186 //
       
   187 EXPORT_C void CMPXCollectionEngine::NotifyL( TMPXCollectionBroadCastMsg aMsg,
       
   188                                              TInt aData )
       
   189     {
       
   190     MPX_FUNC("CMPXCollectionEngine::NotifyL");
       
   191 
       
   192     TInt command = KErrNotSupported;
       
   193     TInt data = 0;
       
   194     TBool clearCache ( EFalse );
       
   195     switch( aMsg )
       
   196         {
       
   197         case EMcMsgFormatStart:
       
   198         case EMcMsgDiskRemoved:
       
   199         case EMcMsgUSBMassStorageStart:
       
   200             {
       
   201             command = EMcCloseCollection;
       
   202             data = aData;
       
   203 
       
   204             // Clear the cache
       
   205             clearCache = ETrue;
       
   206             break;
       
   207             }
       
   208         case EMcMsgFormatEnd:
       
   209         case EMcMsgDiskInserted:
       
   210         case EMcMsgUSBMassStorageEnd:
       
   211             {
       
   212             command = EMcReOpenCollection;
       
   213             data = aData;
       
   214             
       
   215             // Clear the cache
       
   216         	clearCache = ETrue;
       
   217             break;
       
   218             }
       
   219         case EMcMsgUSBMTPStart:
       
   220             {
       
   221             iRefreshing = ETrue;
       
   222             command = EMcCmdMtpStart;
       
   223             break;
       
   224             }
       
   225         case EMcMsgUSBMTPEnd:
       
   226             {
       
   227             iRefreshing = EFalse;
       
   228             command = EMcCmdMtpEnd;
       
   229             // Clear the cache
       
   230             clearCache = ETrue;
       
   231             break;
       
   232             }
       
   233         case EMcMsgRefreshStart:
       
   234             {
       
   235             iRefreshing = ETrue;
       
   236             command = EMcRefreshStarted;
       
   237             break;
       
   238             }
       
   239         case EMcMsgRefreshEnd:
       
   240             {
       
   241             iRefreshing = EFalse;
       
   242             command = EMcRefreshEnded;
       
   243             
       
   244             // Clear the cache
       
   245             clearCache = ETrue;
       
   246             break;
       
   247             }
       
   248 
       
   249         default:
       
   250             break;
       
   251         }
       
   252     if( command != KErrNotSupported )
       
   253         {
       
   254         TArray<CMPXCollectionPlugin*> plugins = iPluginHandler->LoadedPlugins();
       
   255         for( TInt i=0; i<plugins.Count(); ++i )
       
   256             {
       
   257             CMPXCollectionPlugin* plugin = plugins[i];
       
   258             TRAP_IGNORE(plugin->CommandL( (TMPXCollectionCommand)command, data));
       
   259             }
       
   260         }
       
   261 
       
   262     if( clearCache )
       
   263     	{
       
   264         RFs rfs;
       
   265         User::LeaveIfError( rfs.Connect() );        
       
   266         DriveInfo::TDriveArray driveArray;
       
   267         User::LeaveIfError ( DriveInfo::GetUserVisibleDrives( rfs, driveArray ) );
       
   268         TInt count( driveArray.Count () );
       
   269         TBool diskFull( EFalse );
       
   270         for ( TInt i = 0; i < count; ++i )
       
   271             {
       
   272             TRAP_IGNORE( diskFull = SysUtil::DiskSpaceBelowCriticalLevelL( &rfs, 0,
       
   273             		driveArray[i] ) );
       
   274             if ( diskFull )
       
   275                 {
       
   276                 MPX_DEBUG2("CMPXCollectionEngine::NotifyL: Disk full, driveArray[i] = %d ", driveArray[i] );
       
   277                 break;
       
   278                 }
       
   279             } 
       
   280         if( !diskFull )
       
   281         	{
       
   282         	iCache->Reset();
       
   283         	}
       
   284         rfs.Close();
       
   285     	}
       
   286     
       
   287     TInt count = iContexts.Count();
       
   288     for( TInt i=0; i<count; ++i )
       
   289         {
       
   290         CMPXCollectionClientContext* context;
       
   291         context = iContexts[i];
       
   292         context->NotifyL( aMsg, aData );
       
   293         }
       
   294     }
       
   295 
       
   296 // ----------------------------------------------------------------------------
       
   297 // Retrieves all of the supported types in the collection
       
   298 // ----------------------------------------------------------------------------
       
   299 //
       
   300 EXPORT_C void CMPXCollectionEngine::GetSupportedTypesL(
       
   301                                     RPointerArray<CMPXCollectionType>& aArray )
       
   302     {
       
   303     RArray<TUid> uids;
       
   304     CleanupClosePushL(uids);
       
   305     iPluginHandler->GetPluginUids(uids);
       
   306 
       
   307     for (TInt i=0; i<uids.Count();++i)
       
   308         {
       
   309         const TUid& uid = uids[i];
       
   310         CDesCArray* mimetypes =
       
   311                 iPluginHandler->SupportedMimeTypesL(uid);
       
   312         CleanupStack::PushL(mimetypes);
       
   313         CDesCArray* extensions =
       
   314                 iPluginHandler->SupportedExtensionsL(uid);
       
   315         CleanupStack::PushL(extensions);
       
   316         CMPXCollectionType* type = new(ELeave)CMPXCollectionType(
       
   317                                                             uid,
       
   318                                                             mimetypes,
       
   319                                                             extensions);
       
   320         CleanupStack::Pop(extensions);
       
   321         CleanupStack::Pop(mimetypes);
       
   322         CleanupStack::PushL(type);
       
   323         aArray.AppendL( type );
       
   324         CleanupStack::Pop(type);
       
   325         }
       
   326     CleanupStack::PopAndDestroy(&uids);
       
   327     }
       
   328 
       
   329 // ----------------------------------------------------------------------------
       
   330 // Virtual collection ID to implementation ID lookup
       
   331 // ----------------------------------------------------------------------------
       
   332 //
       
   333 EXPORT_C TUid CMPXCollectionEngine::LookupCollectionPluginID( const TUid aUid )
       
   334     {
       
   335     // Lookup virtual ID and map it to an implementation ID
       
   336     TUid realId = TUid::Uid(0);
       
   337     if( aUid == KLocalCollection )
       
   338         {
       
   339         realId = TUid::Uid(0x101FFC3A);
       
   340         }
       
   341     else if( aUid == KPodcastCollection )
       
   342         {
       
   343         realId = TUid::Uid(0x101FFC3C);
       
   344         }
       
   345     else if( aUid == KInMemoryCollection )
       
   346         {
       
   347         realId = TUid::Uid(0x101FFCD8);
       
   348         }
       
   349     else
       
   350         {
       
   351         realId=TUid::Null();
       
   352         }
       
   353 
       
   354     return realId;
       
   355     }
       
   356 
       
   357 // ----------------------------------------------------------------------------
       
   358 // Resolve a collection plugin UID
       
   359 // ----------------------------------------------------------------------------
       
   360 //
       
   361 EXPORT_C TUid CMPXCollectionEngine::ResolvePluginUid(const TArray<TUid>& aAry)
       
   362     {
       
   363     // Resolve the plugin ID using the plugin handler
       
   364     //
       
   365     return iPluginHandler->FindPlugin( aAry );
       
   366     }
       
   367 
       
   368 // ----------------------------------------------------------------------------
       
   369 // Gets a list of the plugins available by name.
       
   370 // ----------------------------------------------------------------------------
       
   371 //
       
   372 void CMPXCollectionEngine::ListPluginsL(
       
   373     CMPXMedia& aEntries,
       
   374     const TArray<TUid>& aSupportedUids)
       
   375     {
       
   376     MPX_FUNC("CMPXCollectionEngine::ListPluginsL");
       
   377 
       
   378 #ifdef _DEBUG
       
   379     for (TInt ii=0; ii < aSupportedUids.Count(); ++ii)
       
   380         {
       
   381         MPX_DEBUG2("Supported uid 0x%08x", aSupportedUids[ii]);
       
   382         }
       
   383 #endif
       
   384     RArray<TInt> supportedIds;
       
   385     CleanupClosePushL(supportedIds);
       
   386     supportedIds.AppendL(KMPXMediaIdGeneral);
       
   387 
       
   388     CMPXMediaArray* array=CMPXMediaArray::NewL();
       
   389     CleanupStack::PushL(array);
       
   390 
       
   391     RArray<TUid> pluginList;
       
   392     CleanupClosePushL(pluginList);
       
   393     iPluginHandler->GetPluginUids(pluginList);
       
   394     RArray<TInt> pluginTypes;
       
   395     CleanupClosePushL(pluginTypes);
       
   396     iPluginHandler->GetPluginTypes(pluginTypes);
       
   397     TInt count=pluginList.Count();
       
   398     MPX_ASSERT(pluginTypes.Count() >= count);
       
   399     TInt arrayCount(0);
       
   400     for(TInt i = 0;i < count ;i++)
       
   401         {
       
   402         // Show only visible plugins
       
   403         //
       
   404         if(pluginTypes[i] != EMPXCollectionPluginHidden &&
       
   405            iPluginHandler->SupportUids(pluginList[i], aSupportedUids))
       
   406             {
       
   407             CMPXMedia* entry=CMPXMedia::NewL(supportedIds.Array());
       
   408             CleanupStack::PushL(entry);
       
   409             entry->SetTextValueL(KMPXMediaGeneralTitle,
       
   410                                  iPluginHandler->PluginName(pluginList[i]));
       
   411             entry->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup);
       
   412             entry->SetTObjectValueL(KMPXMediaGeneralCategory,
       
   413                                     EMPXCollection);
       
   414             entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
   415                                                 TMPXItemId(pluginList[i].iUid));
       
   416             array->AppendL(entry);
       
   417             CleanupStack::Pop(entry);
       
   418             ++arrayCount;
       
   419             }
       
   420         }
       
   421     aEntries.SetCObjectValueL(KMPXMediaArrayContents,array);
       
   422     aEntries.SetTObjectValueL(KMPXMediaArrayCount,arrayCount);
       
   423     CleanupStack::PopAndDestroy(&pluginTypes);
       
   424     CleanupStack::PopAndDestroy(&pluginList);
       
   425     CleanupStack::PopAndDestroy(array);
       
   426     CleanupStack::PopAndDestroy(&supportedIds);
       
   427     }
       
   428 
       
   429 // ----------------------------------------------------------------------------
       
   430 // Find a plugin from collection path
       
   431 // ----------------------------------------------------------------------------
       
   432 //
       
   433 CMPXCollectionPlugin* CMPXCollectionEngine::ResolvePluginL(
       
   434     const CMPXCollectionPath& aPath)
       
   435     {
       
   436     return ResolvePluginL(TUid::Uid(aPath.Id(CMPXCollectionPath::ECollectionUid)));
       
   437     }
       
   438 
       
   439 // ----------------------------------------------------------------------------
       
   440 // Find a plugin from collection uid
       
   441 // ----------------------------------------------------------------------------
       
   442 //
       
   443 CMPXCollectionPlugin* CMPXCollectionEngine::ResolvePluginL(
       
   444     const TUid& aUid)
       
   445     {
       
   446     iPluginHandler->SelectPluginL(aUid);
       
   447     return iPluginHandler->Plugin();
       
   448     }
       
   449 
       
   450 // ----------------------------------------------------------------------------
       
   451 // Find a plugin from uri
       
   452 // ----------------------------------------------------------------------------
       
   453 //
       
   454 CMPXCollectionPlugin* CMPXCollectionEngine::ResolvePluginL(
       
   455     const TDesC& aUri)
       
   456     {
       
   457     iPluginHandler->ClearSelectionCriteria();
       
   458     iPluginHandler->SelectPluginL(aUri, KNullDesC8);
       
   459     return iPluginHandler->Plugin();
       
   460     }
       
   461 
       
   462 // ----------------------------------------------------------------------------
       
   463 // CMPXCollectionEngine::UsePlugin
       
   464 // ----------------------------------------------------------------------------
       
   465 //
       
   466 void CMPXCollectionEngine::UsePlugin(
       
   467     const TUid& aPluginUid)
       
   468     {
       
   469     iPluginHandler->UsePlugin(aPluginUid);
       
   470     }
       
   471 
       
   472 // ----------------------------------------------------------------------------
       
   473 // CMPXCollectionEngine::ReleasePlugin
       
   474 // ----------------------------------------------------------------------------
       
   475 //
       
   476 TBool CMPXCollectionEngine::ReleasePlugin(
       
   477     const TUid& aPluginUid )
       
   478     {
       
   479     MPX_FUNC("CMPXCollectionEngine::ReleasePlugin");
       
   480     TBool unloaded(iPluginHandler->ReleasePlugin(aPluginUid));
       
   481     if (unloaded)
       
   482         {
       
   483         HandlePluginUnloaded(aPluginUid);
       
   484         }
       
   485     return unloaded;
       
   486     }
       
   487 
       
   488 // ----------------------------------------------------------------------------
       
   489 // CMPXCollectionEngine::CleanupPluginPushL
       
   490 //
       
   491 // Pushes the plugin release information onto the cleanup stack. Both the plugin
       
   492 // handler and the plugin itself have to be pushed and therefore cannot use the
       
   493 // cleanup stack alone. Even if it would create a dynamic TReleaseInfo instance
       
   494 // and push that onto the cleanup stack, CleanupStack::Pop would not take care
       
   495 // of deleting it and therefore a separate stack has to be used for the release
       
   496 // info.
       
   497 // ----------------------------------------------------------------------------
       
   498 //
       
   499 void CMPXCollectionEngine::CleanupPluginPushL(
       
   500     CMPXCollectionPlugin* aPlugin)
       
   501     {
       
   502     MPX_FUNC("CMPXCollectionEngine::CleanupPluginPushL");
       
   503 
       
   504     // add the release information to the internal stack
       
   505     iCleanupStack.AppendL(TReleaseInfo(iPluginHandler, aPlugin));
       
   506 
       
   507     // push a pointer to the engine onto the cleanup stack
       
   508     CleanupStack::PushL(TCleanupItem(ReleasePlugin, this));
       
   509     }
       
   510 
       
   511 // ----------------------------------------------------------------------------
       
   512 // CMPXCollectionEngine::PluginPop
       
   513 //
       
   514 // Has to be called instead of CleanupStack::Pop for cleaning up correctly
       
   515 // ----------------------------------------------------------------------------
       
   516 //
       
   517 void CMPXCollectionEngine::PluginPop()
       
   518     {
       
   519     MPX_FUNC("CMPXCollectionEngine::PluginPop");
       
   520 
       
   521     // remove from the cleanup stack
       
   522     CleanupStack::Pop(this);
       
   523 
       
   524     // remove from the internal stack
       
   525     iCleanupStack.Remove(iCleanupStack.Count() - 1);
       
   526     }
       
   527 
       
   528 // ----------------------------------------------------------------------------
       
   529 // CMPXCollectionEngine::HandlePluginHandlerEvent
       
   530 // ----------------------------------------------------------------------------
       
   531 //
       
   532 void CMPXCollectionEngine::HandlePluginHandlerEvent(
       
   533     TPluginHandlerEvents aEvent,
       
   534     const TUid& aPluginUid,
       
   535     TBool aLoaded,
       
   536     TInt aData)
       
   537     {
       
   538     MPX_FUNC("CMPXCollectionEngine::HandlePluginHandlerEvent");
       
   539 
       
   540     switch (aEvent)
       
   541         {
       
   542         case MMPXPluginHandlerObserver::EPluginAdd:
       
   543             {
       
   544             TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginAdd, aPluginUid,
       
   545                 aLoaded, aData));
       
   546             break;
       
   547             }
       
   548         case MMPXPluginHandlerObserver::EPluginUpdateStart:
       
   549             {
       
   550             // Handling the unloading of the previous plugin version and the loading
       
   551             // of the new plugin version is synchronous and therefore new requests
       
   552             // will not be processed by the server/engine in between EPluginUpdateStart
       
   553             // and EPluginUpdateEnd.
       
   554             //
       
   555             // If the plugin handler would unload/load plugins asynchronously then a
       
   556             // mechanism must be created where the engine does not accept requests for
       
   557             // the plugin that is being updated for the duration of the update.
       
   558 
       
   559             // Send update start message
       
   560             TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginUpdateStart, aPluginUid,
       
   561                 aLoaded, aData));
       
   562 
       
   563             // Cancel all outstanding requests for the plugin
       
   564             CMPXCollectionPlugin* plugin = iPluginHandler->LoadedPlugin(aPluginUid);
       
   565             if (plugin)
       
   566                 {
       
   567                 plugin->CompleteAllTasks(KErrNotReady);
       
   568                 }
       
   569             break;
       
   570             }
       
   571         case MMPXPluginHandlerObserver::EPluginUpdateEnd:
       
   572             {
       
   573             TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginUpdateEnd, aPluginUid,
       
   574                 aLoaded, aData));
       
   575             break;
       
   576             }
       
   577         case MMPXPluginHandlerObserver::EPluginRemove:
       
   578             {
       
   579             TRAP_IGNORE(SendPluginHandlerMessageL(KMPXMessagePluginRemove, aPluginUid,
       
   580                 aLoaded));
       
   581 
       
   582             // Cancel all outstanding requests for the plugin
       
   583             CMPXCollectionPlugin* plugin = iPluginHandler->LoadedPlugin(aPluginUid);
       
   584             if (plugin)
       
   585                 {
       
   586                 plugin->CompleteAllTasks(KErrNotReady);
       
   587                 }
       
   588             break;
       
   589             }
       
   590         default:
       
   591             {
       
   592             // ignore the event
       
   593             break;
       
   594             }
       
   595         }
       
   596     }
       
   597 
       
   598 // ----------------------------------------------------------------------------
       
   599 // CMPXCollectionPluginHandler::LoadedPlugin
       
   600 // ----------------------------------------------------------------------------
       
   601 //
       
   602 CMPXCollectionPlugin* CMPXCollectionEngine::LoadedPlugin(const TUid& aUid)
       
   603     {
       
   604     return iPluginHandler->LoadedPlugin(aUid);
       
   605     }
       
   606 
       
   607 // ----------------------------------------------------------------------------
       
   608 // CMPXCollectionEngine::ReleasePlugin
       
   609 //
       
   610 // Executed when the cleanup stack item is destroyed as a result of
       
   611 // CleanupStack::PopAndDestroy being called. This could either be called
       
   612 // manually or as a result of a leave being generated and trapped. When this
       
   613 // method is called the cleanup stack item is already removed from the cleanup
       
   614 // stack and therefore it only has to take care of removing the local item.
       
   615 //
       
   616 // This is a static method.
       
   617 // ----------------------------------------------------------------------------
       
   618 //
       
   619 void CMPXCollectionEngine::ReleasePlugin(
       
   620     TAny* aEngine)
       
   621     {
       
   622     MPX_FUNC("CMPXCollectionEngine::ReleasePlugin");
       
   623 
       
   624     // get the engine instance
       
   625     CMPXCollectionEngine* engine = static_cast<CMPXCollectionEngine*>(aEngine);
       
   626 
       
   627     // last pushed release info
       
   628     TReleaseInfo& relInfo = engine->iCleanupStack[engine->iCleanupStack.Count() - 1];
       
   629 
       
   630     if (relInfo.iPlugin)
       
   631         {
       
   632         // release the plugin
       
   633         TUid uid(relInfo.iPlugin->Uid());
       
   634         TBool unloaded(relInfo.iHandler->ReleasePlugin(uid));
       
   635         if (unloaded)
       
   636             {
       
   637             engine->HandlePluginUnloaded(uid);
       
   638             }
       
   639         }
       
   640 
       
   641     // remove the item from the local stack
       
   642     engine->iCleanupStack.Remove(engine->iCleanupStack.Count() - 1);
       
   643     }
       
   644 
       
   645 // ----------------------------------------------------------------------------
       
   646 // Find the cachable attribute of a plugin
       
   647 // ----------------------------------------------------------------------------
       
   648 //
       
   649 TBool CMPXCollectionEngine::PluginCacheable( const TUid& aUid )
       
   650     {
       
   651     return iPluginHandler->PluginCachable( aUid );
       
   652     }
       
   653 
       
   654 // ----------------------------------------------------------------------------
       
   655 // Find the non-cacaheable attributes of a plugin
       
   656 // ----------------------------------------------------------------------------
       
   657 //
       
   658 const TArray<TUid> CMPXCollectionEngine::PluginNonCacheableAttributesL( const TUid& aUid )
       
   659     {
       
   660     return iPluginHandler->NonCacheableAttributesL( aUid );
       
   661     }
       
   662 
       
   663 
       
   664 // ----------------------------------------------------------------------------
       
   665 // Create a new client context object
       
   666 // ----------------------------------------------------------------------------
       
   667 //
       
   668 CMPXCollectionClientContext* CMPXCollectionEngine::CreateNewContextL(
       
   669     const TUid& aModeId)
       
   670     {
       
   671     CMPXCollectionClientContext* context =
       
   672             CMPXCollectionClientContext::NewL(*this, *iCache, aModeId);
       
   673     CleanupStack::PushL(context);
       
   674     iContexts.AppendL(context);
       
   675     CleanupStack::Pop(context);
       
   676     return context;
       
   677     }
       
   678 
       
   679 // ----------------------------------------------------------------------------
       
   680 // Find a shareable client context object created in the same thread
       
   681 // ----------------------------------------------------------------------------
       
   682 //
       
   683 CMPXCollectionClientContext* CMPXCollectionEngine::FindDefaultContext(
       
   684     TThreadId aClientTid)
       
   685     {
       
   686     CMPXCollectionClientContext* context(NULL);
       
   687 
       
   688     for (TInt i=0;i<iContexts.Count();++i)
       
   689         {
       
   690         if (iContexts[i]->HasShareableClient(aClientTid))
       
   691             {
       
   692             context = iContexts[i];
       
   693             break;
       
   694             }
       
   695         }
       
   696     return context;
       
   697     }
       
   698 
       
   699 // ----------------------------------------------------------------------------
       
   700 // Handle a change message
       
   701 // ----------------------------------------------------------------------------
       
   702 //
       
   703 void CMPXCollectionEngine::DoNotifyChangeL( const CMPXMessage& aMessage )
       
   704     {
       
   705     TInt msgGeneralId(0);
       
   706     if( aMessage.IsSupported(KMPXMessageGeneralId) )
       
   707         {
       
   708         msgGeneralId = aMessage.ValueTObjectL<TMPXMessageId>(KMPXMessageGeneralId);
       
   709         }
       
   710 
       
   711     // Only handle change messages to invalidate the collection cache
       
   712     //
       
   713     if( msgGeneralId == KMPXMessageIdItemChanged)
       
   714         {
       
   715         MPX_DEBUG1("CMPXCollectionEngine::DoNotifyChangeL -- KMPXMessageIdItemChanged");
       
   716 
       
   717         // Multiple messages
       
   718         //
       
   719         if( aMessage.IsSupported(KMPXMessageArrayContents) )
       
   720             {
       
   721             const CMPXMessageArray* messageArray =
       
   722                     aMessage.Value<CMPXMessageArray>(KMPXMessageArrayContents);
       
   723             User::LeaveIfNull(const_cast<CMPXMessageArray*>(messageArray));
       
   724             TInt count(messageArray->Count());
       
   725             for(TInt i=0; i<count; ++i )
       
   726                 {
       
   727                 TBool invalidated = DoNotifySingleChangeL(*(messageArray->AtL(i)));
       
   728                 if( invalidated )
       
   729                     {
       
   730                     // Cache got cleared, no need to process other messages
       
   731                     break;
       
   732                     }
       
   733                 }
       
   734             }
       
   735         // Single message
       
   736         //
       
   737         else
       
   738             {
       
   739             DoNotifySingleChangeL(aMessage);
       
   740             }
       
   741         }
       
   742     }
       
   743 
       
   744 // ----------------------------------------------------------------------------
       
   745 // Handle a single change message
       
   746 // ----------------------------------------------------------------------------
       
   747 //
       
   748 TBool CMPXCollectionEngine::DoNotifySingleChangeL( const CMPXMessage& aMessage )
       
   749     {
       
   750     TBool invalidated(EFalse);
       
   751 
       
   752     // Get the change message data
       
   753     //
       
   754     if( aMessage.IsSupported(KMPXMessageCollectionId) )
       
   755         {
       
   756         TUid collectionId( aMessage.ValueTObjectL<TUid>(KMPXMessageCollectionId) );
       
   757 
       
   758         if( PluginCacheable( collectionId ) )
       
   759             {
       
   760             TMPXChangeEventType changeType =
       
   761                 aMessage.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType);
       
   762 
       
   763             // If item was inserted, we wipe out everything from that collection
       
   764             //
       
   765             if( changeType == EMPXItemInserted )
       
   766                 {
       
   767                 // Remove all cached nodes from a plugin
       
   768                 //
       
   769                 iCache->HandleChangeL( collectionId, TMPXItemId(collectionId.iUid) );
       
   770                 invalidated = ETrue;
       
   771                 }
       
   772             else if ( aMessage.IsSupported( KMPXMessageMediaDeprecatedId ) )
       
   773                 {
       
   774                 iCache->HandleChangeL( collectionId,
       
   775                       aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaDeprecatedId) );
       
   776                 }
       
   777             else if ( aMessage.IsSupported( KMPXMessageMediaGeneralId ) )
       
   778                 {
       
   779                 iCache->HandleChangeL( collectionId,
       
   780                         aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId) );
       
   781                 }
       
   782             }
       
   783         }
       
   784 
       
   785     return invalidated;
       
   786     }
       
   787 
       
   788 // ----------------------------------------------------------------------------
       
   789 // Retrieves all of the supported types in the collection
       
   790 // ----------------------------------------------------------------------------
       
   791 //
       
   792 void CMPXCollectionEngine::RemoveContext(
       
   793     const CMPXCollectionClientContext& aContext)
       
   794     {
       
   795     MPX_DEBUG2("CMPXCollectionEngine::RemoveContext %08x", &aContext);
       
   796     TRAP_IGNORE(::DeleteL(&aContext, iContexts));
       
   797     }
       
   798 
       
   799 // ----------------------------------------------------------------------------
       
   800 // Notify collection changes
       
   801 // ----------------------------------------------------------------------------
       
   802 //
       
   803 void CMPXCollectionEngine::NotifyChange(
       
   804     const CMPXCollectionClientContext& aNotifier,
       
   805     CMPXMessage* aMessage,
       
   806     TInt aError)
       
   807     {
       
   808     MPX_FUNC("CMPXCollectionEngine::NotifyChange");
       
   809     for (TInt i=0; i<iContexts.Count(); ++i)
       
   810         {
       
   811         CMPXCollectionClientContext* context = iContexts[i];
       
   812         if (context != &aNotifier)
       
   813             {
       
   814             context->DoHandleMessage(aMessage, aError, EFalse);
       
   815             }
       
   816         }
       
   817 
       
   818     if( aMessage && !iRefreshing )
       
   819         {
       
   820         TRAP_IGNORE( DoNotifyChangeL( *aMessage ) );
       
   821         }
       
   822     }
       
   823 
       
   824 // ----------------------------------------------------------------------------
       
   825 // Remove tasks of a client which is the observer of tasks
       
   826 // ----------------------------------------------------------------------------
       
   827 //
       
   828 void CMPXCollectionEngine::RemoveTask(TAny* aCallback)
       
   829     {
       
   830     iPluginHandler->RemoveTask(aCallback);
       
   831     }
       
   832 
       
   833 // ----------------------------------------------------------------------------
       
   834 // CMPXCollectionEngine::HandlePluginUnloaded
       
   835 // Called when a plugin is unloaded. Could be used to cleanup other references
       
   836 // to the plugin, like the generic cache.
       
   837 // ----------------------------------------------------------------------------
       
   838 //
       
   839 void CMPXCollectionEngine::HandlePluginUnloaded(
       
   840     const TUid& aUid )
       
   841     {
       
   842     TRAP_IGNORE( DoHandlePluginUnloadedL( aUid ) );
       
   843     }
       
   844 
       
   845 // ----------------------------------------------------------------------------
       
   846 // CMPXCollectionEngine::DoHandlePluginUnloadedL
       
   847 // Called when a plugin is unloaded. Could be used to cleanup other references
       
   848 // to the plugin, like the generic cache.
       
   849 // ----------------------------------------------------------------------------
       
   850 //
       
   851 void CMPXCollectionEngine::DoHandlePluginUnloadedL(
       
   852     const TUid& aUid)
       
   853     {
       
   854     // Construct a plugin level path
       
   855     // This should remove all levels after this path
       
   856     //
       
   857     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   858     CleanupStack::PushL( path );
       
   859     path->AppendL( aUid.iUid );
       
   860     iCache->RemoveL( *path );
       
   861     CleanupStack::PopAndDestroy( path );
       
   862     }
       
   863 
       
   864 // ----------------------------------------------------------------------------
       
   865 // CMPXCollectionEngine::SendPluginHandlerMessageL
       
   866 // ----------------------------------------------------------------------------
       
   867 //
       
   868 void CMPXCollectionEngine::SendPluginHandlerMessageL(
       
   869     TInt aMessageId,
       
   870     const TUid& aPluginUid,
       
   871     TBool aLoaded,
       
   872     TInt aVersion /* = 0 */)
       
   873     {
       
   874     MPX_FUNC("CMPXCollectionEngine::SendPluginHandlerMessageL");
       
   875     MPX_DEBUG5("Message id 0x%08x, plugin id 0x%08x Loaded %d Version %d",
       
   876                aMessageId,aPluginUid.iUid,aLoaded,aVersion);
       
   877     CMPXMessage* msg = CMPXMedia::NewL();
       
   878     CleanupStack::PushL(msg);
       
   879 
       
   880     msg->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, aMessageId);
       
   881     msg->SetTObjectValueL<TUid>(KMPXAttrPluginId, aPluginUid);
       
   882     msg->SetTObjectValueL<TBool>(KMPXAttrPluginLoaded, aLoaded);
       
   883     if (aVersion > 0)
       
   884         {
       
   885         msg->SetTObjectValueL<TInt>(KMPXAttrPluginVersion, aVersion);
       
   886         }
       
   887 
       
   888     HandleMessage(msg, KErrNone);
       
   889 
       
   890     CleanupStack::PopAndDestroy(msg);
       
   891     }
       
   892 
       
   893 // ----------------------------------------------------------------------------
       
   894 // Resets the content of the cache related to specified client context path
       
   895 // ----------------------------------------------------------------------------
       
   896 // 
       
   897 void CMPXCollectionEngine::ResetCacheL(CMPXCollectionPath& aPath)
       
   898     {
       
   899     MPX_FUNC("CMPXCollectionEngine::ResetCache");
       
   900     CMPXCollectionPath* newPath = CMPXCollectionPath::NewL();
       
   901     CleanupStack::PushL(newPath);
       
   902     newPath->AppendL(aPath.Id(0).iId1);
       
   903     iCache->RemoveL(*newPath);
       
   904     CleanupStack::PopAndDestroy(newPath);
       
   905     }
       
   906 // End of file