mpx/commonframework/common/src/mpxpluginhandlerbase.cpp
changeset 0 a2952bb97e68
child 50 762d760dcfdf
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:  Base plugin handler
       
    15 *
       
    16 *  CMPXPluginHandlerBase instantiates and owns a CMPXPluginMonitor to monitor
       
    17 *  plugins for the designated plugin interface. When a plugin for that plugin
       
    18 *  interface is added/removed, PluginsChangedL is called. This base plugin
       
    19 *  handler provides a default implementation for PluginsChangedL which requests
       
    20 *  child class to perform plugin resolution.
       
    21 *
       
    22 *  CMPXPluginHandlerBase also provides plugin selection plugin APIs. These
       
    23 *  methods set up the selection criteria and then request child class to
       
    24 *  resolve these selection criteria to a plugin via ResolvePluginL.
       
    25 *
       
    26 *
       
    27 */
       
    28 
       
    29 
       
    30 
       
    31 #include <bamdesca.h>
       
    32 #include <badesca.h>
       
    33 #include <uri16.h>
       
    34 #include <apgcli.h>
       
    35 
       
    36 #include <mpxlog.h>
       
    37 #include <mpxuser.h>
       
    38 #include <mpxpluginmonitor.h>
       
    39 #include <mpxcmn.h>
       
    40 #include <mpxplugininfo.h>
       
    41 #include "mpxpluginhandlerobserver.h"
       
    42 #include "mpxpluginhandlerbase.h"
       
    43 
       
    44 // CONSTANTS
       
    45 
       
    46 // ============================ LOCAL FUNCTIONS ==============================
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 // Local function to cleanup an array
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 static void CleanupPluginInfoArray(
       
    53     TAny* item)
       
    54     {
       
    55     ((RPointerArray<CMPXPluginInfo>*)item)->ResetAndDestroy();
       
    56     ((RPointerArray<CMPXPluginInfo>*)item)->Close();
       
    57     }
       
    58 
       
    59 // ============================ MEMBER FUNCTIONS ==============================
       
    60 
       
    61 // ----------------------------------------------------------------------------
       
    62 // Constructor.
       
    63 // ----------------------------------------------------------------------------
       
    64 //
       
    65 EXPORT_C CMPXPluginHandlerBase::CMPXPluginHandlerBase(
       
    66     TUid aInterfaceUid,
       
    67     TPluginSelection aSelection,
       
    68     TInt aSelectionType,
       
    69     MMPXPluginHandlerObserver& aObserver,
       
    70     CMPXPluginMonitor* aPluginMonitor/*=NULL*/)
       
    71 :   iObserver(aObserver),
       
    72     iInterfaceUid(aInterfaceUid),
       
    73     iPluginMonitor(aPluginMonitor),
       
    74     iSelection(aSelection),
       
    75     iSelectedType(aSelectionType)
       
    76     {
       
    77     iOwnedPluginMonitor = iPluginMonitor ? EFalse : ETrue;
       
    78     }
       
    79 
       
    80 // ----------------------------------------------------------------------------
       
    81 // 2nd phase constructor.
       
    82 // ----------------------------------------------------------------------------
       
    83 //
       
    84 EXPORT_C void CMPXPluginHandlerBase::BaseConstructL()
       
    85     {
       
    86     CreatePluginListL();
       
    87     if (iOwnedPluginMonitor)
       
    88         {
       
    89         iPluginMonitor = CMPXPluginMonitor::NewL(iInterfaceUid);
       
    90         }
       
    91     iPluginMonitor->AddObserverL(*this);
       
    92     }
       
    93 
       
    94 // ----------------------------------------------------------------------------
       
    95 // Destructor.
       
    96 // ----------------------------------------------------------------------------
       
    97 //
       
    98 EXPORT_C CMPXPluginHandlerBase::~CMPXPluginHandlerBase()
       
    99     {
       
   100     if ( iPluginMonitor )
       
   101         {
       
   102         TRAP_IGNORE( iPluginMonitor->RemoveObserverL( *this ) );
       
   103         }
       
   104     if (iOwnedPluginMonitor)
       
   105         {
       
   106         delete iPluginMonitor;
       
   107         }
       
   108     delete iDataType;
       
   109     delete iScheme;
       
   110     delete iExt;
       
   111 
       
   112     iPluginInfoArray.ResetAndDestroy();
       
   113     }
       
   114 // ----------------------------------------------------------------------------
       
   115 // Select this specific plugin
       
   116 // ----------------------------------------------------------------------------
       
   117 //
       
   118 EXPORT_C void CMPXPluginHandlerBase::SelectPluginL(const TUid& aPluginUid)
       
   119     {
       
   120     MPX_DEBUG2("CMPXPluginHandlerBase::SelectPluginL(Uid 0x%08x)", aPluginUid.iUid);
       
   121 
       
   122     ClearSelectionCriteria();
       
   123 
       
   124     iSelection=ESelectionUid;
       
   125     iSelectedUid=aPluginUid;
       
   126 
       
   127     ResolvePluginL();
       
   128     MPX_DEBUG1("<--CMPXPluginHandlerBase::SelectPluginL() exits");
       
   129     }
       
   130 
       
   131 // ----------------------------------------------------------------------------
       
   132 // select the plugin with the specified name
       
   133 // ----------------------------------------------------------------------------
       
   134 //
       
   135 EXPORT_C void CMPXPluginHandlerBase::SelectPluginL(const TDesC& aPluginName)
       
   136     {
       
   137     MPX_DEBUG2("CMPXPluginHandlerBase::SelectPluginL(PluginName %S)", &aPluginName);
       
   138 
       
   139     SelectPluginL( PluginUid( aPluginName ) );
       
   140     MPX_DEBUG1("<--CMPXPluginHandlerBase::SelectPluginL() exits");
       
   141     }
       
   142 
       
   143 // ----------------------------------------------------------------------------
       
   144 // Set up selection criteria, e.g. data type, extension, and scheme and then
       
   145 // resolve plugin
       
   146 // ----------------------------------------------------------------------------
       
   147 //
       
   148 EXPORT_C void CMPXPluginHandlerBase::SelectPluginL(
       
   149     const TDesC& aUri,
       
   150     const TDesC8& aDataType)
       
   151     {
       
   152     MPX_FUNC("CMPXPluginHandlerBase::PluginL");
       
   153 
       
   154     delete iScheme;
       
   155     iScheme=NULL;
       
   156     delete iExt;
       
   157     iExt=NULL;
       
   158     delete iDataType;
       
   159     iDataType=NULL;
       
   160 
       
   161     TPtrC fullpath;
       
   162     TUriParser up;
       
   163     TParse fp;
       
   164     //
       
   165     // Is it a valid URI, or even full path (e.g. c:\\data\test.mp3")
       
   166     //
       
   167     if (up.Parse(aUri)==KErrNone)
       
   168         {
       
   169         const TDesC& uriScheme=up.Extract(EUriScheme);
       
   170         //
       
   171         // Could be just drive letter if path
       
   172         // which isn't really a scheme
       
   173         //
       
   174         if (uriScheme.Length()>1)
       
   175              {
       
   176              iScheme=MPXUser::Alloc8L(uriScheme);
       
   177              }
       
   178          else if (fp.Set(aUri,NULL,NULL)==KErrNone) // Must be a full path
       
   179              {
       
   180              fullpath.Set(fp.FullName());
       
   181              }
       
   182          else
       
   183              {
       
   184              User::Leave(KErrArgument);
       
   185              }
       
   186         //
       
   187         // Get the extension
       
   188         //
       
   189         iExt=MPXUser::Alloc8L(fp.Ext());
       
   190         }
       
   191     if (aDataType.Length())
       
   192         {
       
   193         iDataType=aDataType.AllocL();
       
   194         }
       
   195     else if (fullpath.Length())
       
   196         {
       
   197         RApaLsSession aps;
       
   198         TInt error  = aps.Connect(); // always fail in console test
       
   199         if (KErrNone == error)
       
   200             {
       
   201             CleanupClosePushL(aps);
       
   202             TDataType dataType;
       
   203             TUid ignore;
       
   204             if(aps.AppForDocument(fullpath,ignore,dataType)==KErrNone)
       
   205                 {
       
   206                 iDataType=dataType.Des8().AllocL();
       
   207                 }
       
   208             CleanupStack::PopAndDestroy(&aps);
       
   209             } // else APPARC is not working in Console environment,
       
   210               // Always find plugin by scheme & etension
       
   211         }
       
   212     else
       
   213         {
       
   214         if ( !iScheme ) // last valid case
       
   215             {
       
   216             User::Leave(KErrArgument);
       
   217             }
       
   218         }
       
   219 
       
   220     ResolvePluginL();
       
   221     }
       
   222 
       
   223 // ----------------------------------------------------------------------------
       
   224 // Select a plugin with the specific type
       
   225 // ----------------------------------------------------------------------------
       
   226 //
       
   227 EXPORT_C void CMPXPluginHandlerBase::SelectPluginL(TInt aPluginType)
       
   228     {
       
   229     MPX_DEBUG2("CMPXPluginHandlerBase::SelectPluginL(PluginType %x)", aPluginType);
       
   230 
       
   231     ClearSelectionCriteria();
       
   232     iSelectedType=aPluginType;
       
   233     ResolvePluginL();
       
   234     MPX_DEBUG1("<--CMPXPluginHandlerBase::SelectPluginL() exits");
       
   235     }
       
   236 
       
   237 // ----------------------------------------------------------------------------
       
   238 // select plug-in appropriate for a file
       
   239 // ----------------------------------------------------------------------------
       
   240 //
       
   241 EXPORT_C void CMPXPluginHandlerBase::SelectPluginL(const RFile& aFile)
       
   242     {
       
   243     MPX_FUNC("CMPXPluginHandlerBase::SelectPluginL(RFile)");
       
   244 
       
   245     TFileName fn;
       
   246     User::LeaveIfError(aFile.FullName(fn));
       
   247     SelectPluginL(fn, KNullDesC8);
       
   248     }
       
   249 
       
   250 // ----------------------------------------------------------------------------
       
   251 // CMPXPluginHandlerBase::UsePlugin
       
   252 // ----------------------------------------------------------------------------
       
   253 //
       
   254 EXPORT_C void CMPXPluginHandlerBase::UsePlugin(
       
   255     const TUid& aPluginUid)
       
   256     {
       
   257     MPX_FUNC_EX("CMPXPluginHandlerBase::UsePlugin");
       
   258 
       
   259     TInt index(IndexOf(aPluginUid));
       
   260     if (index != KErrNotFound)
       
   261         {
       
   262         iPluginInfoArray[index]->ReferenceCount()++;
       
   263         }
       
   264     }
       
   265 
       
   266 // ----------------------------------------------------------------------------
       
   267 // CMPXPluginHandlerBase::ReleasePlugin
       
   268 // ----------------------------------------------------------------------------
       
   269 //
       
   270 EXPORT_C TBool CMPXPluginHandlerBase::ReleasePlugin(
       
   271     const TUid& aPluginUid)
       
   272     {
       
   273     MPX_FUNC_EX("CMPXPluginHandlerBase::ReleasePlugin");
       
   274 
       
   275     TBool unload(EFalse);
       
   276     TInt index(IndexOf(aPluginUid));
       
   277     if (index != KErrNotFound)
       
   278         {
       
   279         TInt& refCount = iPluginInfoArray[index]->ReferenceCount();
       
   280         refCount--;
       
   281 
       
   282         if (!refCount)
       
   283             {
       
   284             UnloadPlugin(aPluginUid);
       
   285             unload = ETrue;
       
   286             }
       
   287         }
       
   288 
       
   289     return unload;
       
   290     }
       
   291 
       
   292 // ----------------------------------------------------------------------------
       
   293 // Get current selection criteria
       
   294 // ----------------------------------------------------------------------------
       
   295 //
       
   296 EXPORT_C void CMPXPluginHandlerBase::GetSelectionCriteria(
       
   297     TPluginSelection& aPluginSelection,
       
   298     TInt& aPluginType,
       
   299     TUid& aPluginUid,
       
   300     TPtrC8& aDataType,
       
   301     TPtrC8& aScheme,
       
   302     TPtrC8& aExtension)
       
   303     {
       
   304     aPluginSelection=iSelection;
       
   305     aPluginType=iSelectedType;
       
   306     aPluginUid=iSelectedUid;
       
   307 
       
   308     aDataType.Set(*iDataType);
       
   309     aScheme.Set(*iScheme);
       
   310     aExtension.Set(*iExt);
       
   311     }
       
   312 
       
   313 // ----------------------------------------------------------------------------
       
   314 // Clear current selection criteria
       
   315 // ----------------------------------------------------------------------------
       
   316 //
       
   317 EXPORT_C void CMPXPluginHandlerBase::ClearSelectionCriteria()
       
   318     {
       
   319     iSelection=ESelectionType;
       
   320     iSelectedType=0; // unknown type. this info is unknown
       
   321     iSelectedUid=KNullUid;
       
   322 
       
   323     delete iScheme;
       
   324     iScheme=NULL;
       
   325     delete iExt;
       
   326     iExt=NULL;
       
   327     delete iDataType;
       
   328     iDataType=NULL;
       
   329     }
       
   330 
       
   331 // ----------------------------------------------------------------------------
       
   332 // Resolve a plugin, based on properties (iDataType, iExt and iScheme)
       
   333 // and selection criteria. If selection is by type, then there is always a
       
   334 // plug-in resolved (if there are any of that type).
       
   335 // TO-DO: Room for optimisation
       
   336 // ----------------------------------------------------------------------------
       
   337 //
       
   338 EXPORT_C void CMPXPluginHandlerBase::DoResolvePluginL(
       
   339     TUid& aPluginUid,
       
   340     TInt& aIndex,
       
   341     TPtrC& aDisplayName,
       
   342     TInt& aPluginType)
       
   343     {
       
   344     MPX_DEBUG2("===>CMPXPluginHandlerBase::DoResolvePluginL 0x%08x", this);
       
   345     TInt index=KErrNotFound;
       
   346     if (iSelection==ESelectionUid)
       
   347         {
       
   348         index=IndexOf(iSelectedUid);
       
   349         }
       
   350     else // if (iSelection==ESelectionType)
       
   351         {
       
   352         TInt score=0;
       
   353         TInt maxScore=0;
       
   354 
       
   355         TInt count(iPluginInfoArray.Count());
       
   356         for(TInt i = 0; i < count; ++i)
       
   357             {
       
   358             // Must scan from beginning of plugin info array, because plugins
       
   359             // sorted by priority descendingly
       
   360             score=0;
       
   361 
       
   362             //
       
   363             // First, try scheme then data type, then extension
       
   364             // and total up the points
       
   365             //
       
   366             HBufC* hbuf = NULL;
       
   367             TInt pos(0);
       
   368             const CDesCArray& schemas = iPluginInfoArray[i]->SupportedSchemas();
       
   369             if (schemas.MdcaCount() && iScheme)
       
   370                 {
       
   371                 if (iScheme->Length())
       
   372                     {
       
   373                     hbuf = MPXUser::AllocL(*iScheme);
       
   374                     if (!schemas.FindIsq(*hbuf, pos))
       
   375                         { // schema supported by the plugin
       
   376                         score+=4;
       
   377                         }
       
   378                     delete hbuf;
       
   379                     hbuf=NULL;
       
   380                     }
       
   381                 } // else schema not supported
       
   382 
       
   383             if (iDataType)
       
   384                 {
       
   385                 hbuf = MPXUser::AllocL(*iDataType);
       
   386                 if (!iPluginInfoArray[i]->SupportedMimeTypes().FindIsq(*hbuf, pos))
       
   387                     { // mime type supported by the plugin
       
   388                     score+=3;
       
   389                     }
       
   390                 delete hbuf;
       
   391                 hbuf=NULL;
       
   392                 }
       
   393 
       
   394             if (iExt)
       
   395                 {
       
   396                 hbuf = MPXUser::AllocL(*iExt);
       
   397                 if (!iPluginInfoArray[i]->SupportedExtensions().FindIsq(*hbuf, pos))
       
   398                     { // extension supported by the plugin
       
   399                     score+=2;
       
   400                     }
       
   401                 delete hbuf;
       
   402                 hbuf=NULL;
       
   403                 }
       
   404 
       
   405             if (iSelectedType == iPluginInfoArray[i]->PluginType().iUid)
       
   406                 {
       
   407                 score+=1; // Just for being the right "type"
       
   408                 }
       
   409 
       
   410             if (score > maxScore)
       
   411                 {
       
   412                 maxScore=score;
       
   413                 index=i;
       
   414                 }
       
   415             }
       
   416         }
       
   417 
       
   418     if (index==KErrNotFound)
       
   419         {
       
   420         User::Leave(KErrNotSupported);
       
   421         }
       
   422 
       
   423     //
       
   424     // set return values
       
   425     //
       
   426     aPluginUid = iPluginInfoArray[index]->ImplementationUid();
       
   427     aIndex = index;
       
   428     aDisplayName.Set(iPluginInfoArray[index]->DisplayName());
       
   429     aPluginType = iPluginInfoArray[index]->PluginType().iUid;
       
   430 
       
   431 #ifdef _DEBUG
       
   432     PrintPluginInfo();
       
   433 #endif
       
   434 
       
   435     MPX_DEBUG5("<===CMPXPluginHandlerBase::DoResolvePluginL 0x%08x (aPluginUid 0x%08x, aIndex %d, aDisplayName %S)",
       
   436                this, aPluginUid.iUid, aIndex, &aDisplayName);
       
   437     }
       
   438 
       
   439 // ----------------------------------------------------------------------------
       
   440 // Handles request completion event
       
   441 // ----------------------------------------------------------------------------
       
   442 //
       
   443 EXPORT_C void CMPXPluginHandlerBase::PluginsChangedL()
       
   444     {
       
   445     MPX_DEBUG2("===> CMPXPluginHandlerBase::PluginsChangedL 0x%08x", this);
       
   446     CreatePluginListL();
       
   447     ResolvePluginL();
       
   448     MPX_DEBUG2("<=== CMPXPluginHandlerBase::PluginsChangedL 0x%08x", this);
       
   449     }
       
   450 
       
   451 // ----------------------------------------------------------------------------
       
   452 // Handles a plugin unload request
       
   453 // ----------------------------------------------------------------------------
       
   454 //
       
   455 EXPORT_C void CMPXPluginHandlerBase::HandlePluginUnload(
       
   456     const TUid& aPluginUid)
       
   457     {
       
   458     UnloadPlugin(aPluginUid);
       
   459     }
       
   460 
       
   461 // ----------------------------------------------------------------------------
       
   462 // Resolve a plugin
       
   463 // ----------------------------------------------------------------------------
       
   464 //
       
   465 EXPORT_C void CMPXPluginHandlerBase::ResolvePluginL()
       
   466     {
       
   467     // Do nothing in base class
       
   468     }
       
   469 
       
   470 // ----------------------------------------------------------------------------
       
   471 // CMPXPluginHandlerBase::IsPluginLoaded
       
   472 // This method had to be made virtual (and not pure virtual) because
       
   473 // the playlist engine instantiates the base class.
       
   474 // ----------------------------------------------------------------------------
       
   475 //
       
   476 EXPORT_C TBool CMPXPluginHandlerBase::IsPluginLoaded(
       
   477     const TUid& /* aPluginUid */)
       
   478     {
       
   479     return EFalse;
       
   480     }
       
   481 
       
   482 // ----------------------------------------------------------------------------
       
   483 // CMPXPluginHandlerBase::LoadPluginL
       
   484 // This method had to be made virtual (and not pure virtual) because
       
   485 // the playlist engine instantiates the base class.
       
   486 // ----------------------------------------------------------------------------
       
   487 //
       
   488 EXPORT_C void CMPXPluginHandlerBase::LoadPluginL(
       
   489     const TUid& /* aPluginUid */)
       
   490     {
       
   491     // do nothing
       
   492     }
       
   493 
       
   494 // ----------------------------------------------------------------------------
       
   495 // CMPXPluginHandlerBase::UnloadPlugin
       
   496 // This method had to be made virtual (and not pure virtual) because
       
   497 // the playlist engine instantiates the base class.
       
   498 // ----------------------------------------------------------------------------
       
   499 //
       
   500 EXPORT_C void CMPXPluginHandlerBase::UnloadPlugin(
       
   501     const TUid& /* aPluginUid */)
       
   502     {
       
   503     // do nothing
       
   504     }
       
   505 
       
   506 // ----------------------------------------------------------------------------
       
   507 // Return a new instance of the plugin info class
       
   508 // ----------------------------------------------------------------------------
       
   509 //
       
   510 EXPORT_C CMPXPluginInfo* CMPXPluginHandlerBase::ConstructPluginInfoLC(
       
   511                                      const CImplementationInformation& aData  )
       
   512     {
       
   513     return CMPXPluginInfo::NewLC( aData );
       
   514     }
       
   515 
       
   516 
       
   517 // ----------------------------------------------------------------------------
       
   518 // Return plugin name which supports the specified type
       
   519 // ----------------------------------------------------------------------------
       
   520 //
       
   521 EXPORT_C const TDesC& CMPXPluginHandlerBase::PluginName(
       
   522     TInt aPluginType) const
       
   523     {
       
   524     const TDesC* name=&KNullDesC;
       
   525     for ( TInt i=iPluginInfoArray.Count(); --i >= 0 ; )
       
   526         {
       
   527         if ( aPluginType == iPluginInfoArray[i]->PluginType().iUid )
       
   528             {
       
   529             name = &(iPluginInfoArray[i]->DisplayName());
       
   530             break;
       
   531             }
       
   532         }
       
   533     return *name;
       
   534     }
       
   535 
       
   536 // ----------------------------------------------------------------------------
       
   537 // Return plugin name which supports the specified uid
       
   538 // ----------------------------------------------------------------------------
       
   539 //
       
   540 EXPORT_C const TDesC& CMPXPluginHandlerBase::PluginName(const TUid& aUid) const
       
   541     {
       
   542     const TDesC* name=&KNullDesC;
       
   543     TInt index(IndexOf(aUid));
       
   544     MPX_ASSERT(KErrNotFound!=index && index<iPluginInfoArray.Count());
       
   545     name = &iPluginInfoArray[index]->DisplayName();
       
   546     return *name;
       
   547     }
       
   548 
       
   549 // ----------------------------------------------------------------------------
       
   550 // Return a list of plugin names
       
   551 // ----------------------------------------------------------------------------
       
   552 //
       
   553 EXPORT_C CDesCArray* CMPXPluginHandlerBase::PluginNamesL()
       
   554     {
       
   555     CDesCArray* desArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   556     CleanupStack::PushL(desArray);
       
   557     for(TInt i=iPluginInfoArray.Count(); --i>=0 ;)
       
   558         {
       
   559         HBufC* item = iPluginInfoArray[i]->DisplayName().AllocLC();
       
   560 
       
   561         //ignore leave when insert the same item
       
   562         TRAP_IGNORE(desArray->InsertIsqL(*item));
       
   563         CleanupStack::PopAndDestroy(item);
       
   564         }
       
   565     CleanupStack::Pop(desArray);
       
   566     return desArray;
       
   567     }
       
   568 
       
   569 // ----------------------------------------------------------------------------
       
   570 // returns a list of plugin types
       
   571 // ----------------------------------------------------------------------------
       
   572 //
       
   573 EXPORT_C void CMPXPluginHandlerBase::GetPluginTypes(RArray<TInt>& aTypes) const
       
   574     {
       
   575     aTypes.Reset();
       
   576     TInt count(iPluginInfoArray.Count());
       
   577     for(TInt i=0; i<count; ++i)
       
   578         {
       
   579         aTypes.Append(iPluginInfoArray[i]->PluginType().iUid);
       
   580         }
       
   581     }
       
   582 
       
   583 // ----------------------------------------------------------------------------
       
   584 // Return the list of UIDs of all plugins
       
   585 // ----------------------------------------------------------------------------
       
   586 //
       
   587 EXPORT_C void CMPXPluginHandlerBase::GetPluginUids(RArray<TUid>& aUids) const
       
   588     {
       
   589     aUids.Reset();
       
   590     TInt count(iPluginInfoArray.Count());
       
   591     for(TInt i=0; i<count; ++i)
       
   592         {
       
   593         aUids.Append(iPluginInfoArray[i]->ImplementationUid());
       
   594         }
       
   595     }
       
   596 
       
   597 // ----------------------------------------------------------------------------
       
   598 // Get plugin list with the specific type
       
   599 // ----------------------------------------------------------------------------
       
   600 //
       
   601 EXPORT_C void CMPXPluginHandlerBase::GetPluginUidsL(
       
   602     RArray<TUid>& aPlugins,
       
   603     TInt aPluginType) const
       
   604     {
       
   605     aPlugins.Reset();
       
   606     for(TInt i=iPluginInfoArray.Count(); --i>=0 ;)
       
   607         {
       
   608         if (aPluginType == iPluginInfoArray[i]->PluginType().iUid)
       
   609             {
       
   610             aPlugins.Append(iPluginInfoArray[i]->ImplementationUid());
       
   611             }
       
   612         }
       
   613     }
       
   614 
       
   615 // ----------------------------------------------------------------------------
       
   616 // Get plugin UID with the specified display name
       
   617 // ----------------------------------------------------------------------------
       
   618 //
       
   619 EXPORT_C TUid CMPXPluginHandlerBase::PluginUid(const TDesC& aPluginName) const
       
   620     {
       
   621     TUid uid( KNullUid );
       
   622 
       
   623     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   624         {
       
   625         if ( aPluginName.Compare(iPluginInfoArray[i]->DisplayName()) == 0 )
       
   626             {
       
   627             uid = iPluginInfoArray[i]->ImplementationUid();
       
   628             break;
       
   629             }
       
   630         }
       
   631 
       
   632     return uid;
       
   633     }
       
   634 
       
   635 // ----------------------------------------------------------------------------
       
   636 // returns the index of the specified plugin
       
   637 // ----------------------------------------------------------------------------
       
   638 //
       
   639 EXPORT_C TInt CMPXPluginHandlerBase::IndexOf(const TUid& aPluginUid) const
       
   640     {
       
   641     TInt ret(KErrNotFound);
       
   642     TInt count(iPluginInfoArray.Count());
       
   643     for(TInt i=0; i<count; ++i)
       
   644         {
       
   645         if (iPluginInfoArray[i]->ImplementationUid()==aPluginUid)
       
   646             {
       
   647             ret = i;
       
   648             break;
       
   649             }
       
   650         }
       
   651     return ret;
       
   652     }
       
   653 
       
   654 // ----------------------------------------------------------------------------
       
   655 // Return a list of mime types supported by the plugins
       
   656 // ----------------------------------------------------------------------------
       
   657 //
       
   658 EXPORT_C CDesCArray* CMPXPluginHandlerBase::SupportedMimeTypesL()
       
   659     {
       
   660     CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   661     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   662         {
       
   663         if( iPluginInfoArray[i] )
       
   664         	{
       
   665 			MPXUser::MergeArray(iPluginInfoArray[i]->SupportedMimeTypes(),
       
   666 				                *descArray);
       
   667         	}
       
   668         }
       
   669     return descArray;
       
   670     }
       
   671 
       
   672 // ----------------------------------------------------------------------------
       
   673 // Return a list of extensions supported by the plugins
       
   674 // ----------------------------------------------------------------------------
       
   675 //
       
   676 EXPORT_C CDesCArray* CMPXPluginHandlerBase::SupportedExtensionsL()
       
   677     {
       
   678     CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   679     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   680         {
       
   681         MPXUser::MergeArray(iPluginInfoArray[i]->SupportedExtensions(),
       
   682                             *descArray);
       
   683         }
       
   684     return descArray;
       
   685     }
       
   686 
       
   687 // ----------------------------------------------------------------------------
       
   688 // Get plugin type for a given implementation UID
       
   689 // ----------------------------------------------------------------------------
       
   690 //
       
   691 EXPORT_C TUid CMPXPluginHandlerBase::PluginType( const TUid& aUid ) const
       
   692     {
       
   693     TUid ret( KNullUid );
       
   694     TInt count( iPluginInfoArray.Count() );
       
   695     for( TInt i = 0; i < count; ++i )
       
   696         {
       
   697         if ( iPluginInfoArray[i]->ImplementationUid() == aUid )
       
   698             {
       
   699             ret = iPluginInfoArray[i]->PluginType();
       
   700             break;
       
   701             }
       
   702         }
       
   703     return ret;
       
   704     }
       
   705 
       
   706 // ----------------------------------------------------------------------------
       
   707 // Get supported app uid for a given implementation UID
       
   708 // ----------------------------------------------------------------------------
       
   709 //
       
   710 EXPORT_C TUid CMPXPluginHandlerBase::SupportedAppUid( const TUid& aUid ) const
       
   711     {
       
   712     TUid ret( KNullUid );
       
   713     TInt count( iPluginInfoArray.Count() );
       
   714     for( TInt i = 0; i < count; ++i )
       
   715         {
       
   716         if ( iPluginInfoArray[i]->ImplementationUid() == aUid )
       
   717             {
       
   718             ret = iPluginInfoArray[i]->SupportedAppUid();
       
   719             MPX_DEBUG2("SupportedAppUid = %d", ret);
       
   720             break;
       
   721             }
       
   722         }
       
   723     return ret;
       
   724     }
       
   725 
       
   726 // ----------------------------------------------------------------------------
       
   727 // Get plugin type for a given implementation UID
       
   728 // ----------------------------------------------------------------------------
       
   729 //
       
   730 EXPORT_C TUint CMPXPluginHandlerBase::PluginFlagsL( const TUid& aUid ) const
       
   731     {
       
   732     TUint ret( 0 );
       
   733     TInt count( iPluginInfoArray.Count() );
       
   734     TBool found( EFalse );
       
   735     for( TInt i = 0; !found && i < count; ++i )
       
   736         {
       
   737         if ( iPluginInfoArray[i]->ImplementationUid() == aUid )
       
   738             {
       
   739             ret = iPluginInfoArray[i]->Flags();
       
   740             found = ETrue;
       
   741             }
       
   742         }
       
   743     if ( !found )
       
   744         {
       
   745         User::Leave( KErrNotFound );
       
   746         }
       
   747     return ret;
       
   748     }
       
   749 
       
   750 // ----------------------------------------------------------------------------
       
   751 // Return a list of schemas supported by the plugins
       
   752 // ----------------------------------------------------------------------------
       
   753 //
       
   754 EXPORT_C CDesCArray* CMPXPluginHandlerBase::SupportedSchemasL()
       
   755     {
       
   756     CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   757     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   758         {
       
   759         MPXUser::MergeArray(iPluginInfoArray[i]->SupportedSchemas(),
       
   760                             *descArray);
       
   761         }
       
   762     return descArray;
       
   763     }
       
   764 
       
   765 // ----------------------------------------------------------------------------
       
   766 // Return a list of mime types supported by the plugins
       
   767 // ----------------------------------------------------------------------------
       
   768 //
       
   769 EXPORT_C CDesCArray* CMPXPluginHandlerBase::SupportedMimeTypesL(const TUid& aUid)
       
   770     {
       
   771     CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   772     CleanupStack::PushL(descArray);
       
   773     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   774         {
       
   775         if (aUid == iPluginInfoArray[i]->ImplementationUid())
       
   776             {
       
   777             MPXUser::CopyArrayL(iPluginInfoArray[i]->SupportedMimeTypes(),
       
   778                             *descArray);
       
   779             break;
       
   780             }
       
   781         }
       
   782     CleanupStack::Pop(descArray);
       
   783     return descArray;
       
   784     }
       
   785 
       
   786 // ----------------------------------------------------------------------------
       
   787 // Return a list of extensions supported by the plugins
       
   788 // ----------------------------------------------------------------------------
       
   789 //
       
   790 EXPORT_C CDesCArray* CMPXPluginHandlerBase::SupportedExtensionsL(const TUid& aUid)
       
   791     {
       
   792     CDesCArray* descArray = new(ELeave)CDesCArrayFlat(KMPXArrayGranularity);
       
   793     CleanupStack::PushL(descArray);
       
   794     for(TInt i=iPluginInfoArray.Count();--i>=0;)
       
   795         {
       
   796         if (aUid == iPluginInfoArray[i]->ImplementationUid())
       
   797             {
       
   798             MPXUser::CopyArrayL(iPluginInfoArray[i]->SupportedExtensions(),
       
   799                             *descArray);
       
   800             break;
       
   801             }
       
   802         }
       
   803     CleanupStack::Pop(descArray);
       
   804     return descArray;
       
   805     }
       
   806 
       
   807 // ----------------------------------------------------------------------------
       
   808 // Recreates the list of plugins. Handles the scenarios of plugin update,
       
   809 // addition and removal by comparing the previous list with the current one.
       
   810 // In case any change is detected to the plugin list the observer interface is
       
   811 // used to notify the owner.
       
   812 //
       
   813 // NOTE: ECOM takes care of versioning for us. When two plugins that implement
       
   814 // the same interface and have the same implementation UID are detected, it loads
       
   815 // the one with the higher version. There is no way to have two implementations
       
   816 // of the same interface that share the implementation UID returned by
       
   817 // REComSession::ListImplementationsL.
       
   818 // ----------------------------------------------------------------------------
       
   819 //
       
   820 EXPORT_C void CMPXPluginHandlerBase::CreatePluginListL()
       
   821     {
       
   822     MPX_DEBUG_THREAD("CMPXPluginHandlerBase::CreatePluginListL");
       
   823     // Get the current list of plugins that implement the interface
       
   824     // The ECOM versioning mechanism is appied here.
       
   825     // Auto destroy array, no need to call ResetAndDestroy and Close
       
   826     RMPXPointerArray<CImplementationInformation> implInfoArray;
       
   827     REComSession::ListImplementationsL(iInterfaceUid, implInfoArray);
       
   828 
       
   829     // Temporary array to store the new plugin infos.
       
   830     RPointerArray<CMPXPluginInfo> tempInfoArray;
       
   831     CleanupStack::PushL(TCleanupItem(CleanupPluginInfoArray, &tempInfoArray));
       
   832 
       
   833     // Reused variables
       
   834     CMPXPluginInfo* prevInfo(NULL);
       
   835     TBool loaded(EFalse);
       
   836 
       
   837     // Iterate the new plugins
       
   838     // It is expected that when the loop ends the temporary array will contain
       
   839     // all current plugins and iPluginInfoArray will contain the plugins that
       
   840     // have been removed
       
   841     TInt count(implInfoArray.Count());
       
   842     MPX_DEBUG3("CMPXPluginHandlerBase::CreatePluginListL numbers of the plugin 0x%08x %d",
       
   843                 this, count);
       
   844     TInt index(0);
       
   845     CMPXPluginInfo* info(NULL);
       
   846     for (; index < count; ++index)
       
   847         {
       
   848         // Convert to an internal plugin info instance
       
   849         info = ConstructPluginInfoLC(*implInfoArray[index]);
       
   850         const TUid& uid = info->ImplementationUid();
       
   851 
       
   852         // Check if the plugin existed in the previous list
       
   853         TInt prevIndex = IndexOf(uid);
       
   854         if (prevIndex != KErrNotFound)
       
   855             {
       
   856             // The plugin existed before the update
       
   857             prevInfo = iPluginInfoArray[prevIndex];
       
   858             MPX_DEBUG5("Process the existing plugin 0x%08x uid 0x%08x, old version %d new version %d",
       
   859                        this, uid.iUid, prevInfo->Version(), info->Version());
       
   860             // Copy the reference count
       
   861             info->ReferenceCount() = prevInfo->ReferenceCount();
       
   862 
       
   863             // Compare the versions
       
   864             if (prevInfo->Version() < info->Version())
       
   865                 {
       
   866                 // The plugin is being upgraded
       
   867                 loaded = IsPluginLoaded(uid);
       
   868 
       
   869                 // Generate an update start notification
       
   870                 iObserver.HandlePluginHandlerEvent(
       
   871                     MMPXPluginHandlerObserver::EPluginUpdateStart, uid, loaded,
       
   872                     info->Version());
       
   873 
       
   874                 // Check if this plugin was loaded. The plugin is still loaded if this is the first
       
   875                 // handler that got notified or it is already unloaded for any otehr handlers.
       
   876                 if (info->ReferenceCount())
       
   877                     {
       
   878                     if (loaded)
       
   879                         {
       
   880                         // Unload the old plugin version
       
   881                         MPX_DEBUG2("CMPXPluginHandlerBase::CreatePluginListL unload old plugin 0x%08x", this);
       
   882 
       
   883                         // The plugin is loaded - ask the monitor to tell all
       
   884                         // handler instances (including this one) to unload it.
       
   885                         // After the call below all plugin instances owned by
       
   886                         // all monitors are unloaded.
       
   887                         //
       
   888                         // Only make this call if the plugin is still loaded,
       
   889                         // i.e. from the first handler that detects the update.
       
   890                         iPluginMonitor->NotifyUnload(uid);
       
   891                         
       
   892                         // Necessary to ensure version upgrade of ECom plugins
       
   893                         // is successful. This call will unload any garbage
       
   894                         // plugins. 
       
   895                         REComSession::FinalClose();                       
       
   896                         }
       
   897 
       
   898                     MPX_DEBUG2("CMPXPluginHandlerBase::CreatePluginListL load new plugin 0x%08x", this);
       
   899                     // Load the new plugin version
       
   900                     LoadPluginL(uid);
       
   901                     MPX_DEBUG2("CMPXPluginHandlerBase::CreatePluginListL load new plugin finished 0x%08x", this);
       
   902                     }
       
   903 
       
   904                 // Generate an update end notification
       
   905                 iObserver.HandlePluginHandlerEvent(
       
   906                     MMPXPluginHandlerObserver::EPluginUpdateEnd, uid, loaded,
       
   907                     info->Version());
       
   908                 }
       
   909 
       
   910             // Delete the entry from the info array
       
   911             iPluginInfoArray.Remove(prevIndex);
       
   912             delete prevInfo;
       
   913             prevInfo = NULL;
       
   914             }
       
   915         else
       
   916             {
       
   917             MPX_DEBUG2("CMPXPluginHandlerBase::CreatePluginListL found new plugin 0x%08x", this);
       
   918             // A new plugin is being added
       
   919             iObserver.HandlePluginHandlerEvent(
       
   920                 MMPXPluginHandlerObserver::EPluginAdd, uid, EFalse, info->Version());
       
   921             }
       
   922 
       
   923         // Insert into the temporary array - order by priority, high priority first
       
   924         tempInfoArray.InsertInOrderAllowRepeatsL(info,
       
   925                                     CMPXPluginInfo::ComparePluginInfoByPriority);
       
   926 
       
   927         CleanupStack::Pop(info);
       
   928         }
       
   929 
       
   930     // What is left in iPluginInfoArray are removed plugins
       
   931     while (iPluginInfoArray.Count())
       
   932         {
       
   933         prevInfo = iPluginInfoArray[0];
       
   934         const TUid& uid = prevInfo->ImplementationUid();
       
   935 
       
   936         loaded = IsPluginLoaded(uid);
       
   937         MPX_DEBUG3("CMPXPluginHandlerBase::CreatePluginListL plugin removed 0x%08x uid  0x%08x",
       
   938                    this, uid.iUid);
       
   939         // Generate an remove notification
       
   940         iObserver.HandlePluginHandlerEvent(
       
   941             MMPXPluginHandlerObserver::EPluginRemove, uid, loaded,
       
   942             prevInfo->Version());
       
   943 
       
   944         // Check if the plugin is currently loaded
       
   945         if (loaded)
       
   946             {
       
   947             // Unload the plugin
       
   948             UnloadPlugin(uid);
       
   949             }
       
   950 
       
   951         iPluginInfoArray.Remove(0);
       
   952         delete prevInfo;
       
   953         prevInfo = NULL;
       
   954         }
       
   955 
       
   956     // iPluginInfoArray should be empty and the temp array should contain all new plugins
       
   957     // Copy the pointers to iPluginInfoArray - the ownership is transferred
       
   958     for (index = 0; index < count; ++index)
       
   959         {
       
   960         info = tempInfoArray[0];
       
   961         iPluginInfoArray.AppendL(info);
       
   962         tempInfoArray.Remove(0);
       
   963         // check if this plugin should be pre-loaded and not loaded yet
       
   964         if (info->Flags() & EMPXPluginFlagPreLoad && info->ReferenceCount() == 0)
       
   965             {
       
   966             // pre-load the plugin - have to go through SelectPluginL
       
   967             // to apply the reference counting consistently
       
   968             TRAP_IGNORE(SelectPluginL(info->ImplementationUid()));
       
   969             }
       
   970         }
       
   971 
       
   972     // Reset the temp array - this does not delete the plugin info instances pointed to
       
   973     // from the array - these were copied to iPluginInfoArray
       
   974     CleanupStack::Pop(); // TCleanupItem(CleanupPluginInfoArray, &tempInfoArray)
       
   975     tempInfoArray.Close();
       
   976     }
       
   977 
       
   978 // ----------------------------------------------------------------------------
       
   979 // CMPXPluginHandlerBase::SupportUids
       
   980 // ----------------------------------------------------------------------------
       
   981 //
       
   982 EXPORT_C TBool CMPXPluginHandlerBase::SupportUids(
       
   983     const TUid& aPluginId,
       
   984     const TArray<TUid>& aUids) const
       
   985     {
       
   986     TInt index(IndexOf(aPluginId));
       
   987     MPX_ASSERT(index!=KErrNotFound && index < iPluginInfoArray.Count());
       
   988     return iPluginInfoArray[index]->SupportUids(aUids);
       
   989     }
       
   990 
       
   991 // ----------------------------------------------------------------------------
       
   992 // Search a plugin by matching implementation id, supported id and plugin type
       
   993 // If two plugins get the same score, high priority plugin's implementation
       
   994 // uid will be returned
       
   995 // ----------------------------------------------------------------------------
       
   996 //
       
   997 EXPORT_C TUid CMPXPluginHandlerBase::FindPlugin(const TArray<TUid>& aUids) const
       
   998     {
       
   999 	MPX_DEBUG1("#### MPX Plugins ####");
       
  1000     TInt count(iPluginInfoArray.Count());
       
  1001     for (TInt index = 0; index < count; ++index)
       
  1002         {
       
  1003         CMPXPluginInfo* info = iPluginInfoArray[index];
       
  1004         const TDesC& name = info->DisplayName();
       
  1005         MPX_DEBUG5("%S [0x%08X] Priority: %d Ref Count: %d", &name, info->ImplementationUid(),
       
  1006             info->Priority(), info->ReferenceCount());
       
  1007         MPX_DEBUG2("Version %d", info->Version());
       
  1008         }
       
  1009 
       
  1010     TInt lastScore( 0 );
       
  1011     CMPXPluginInfo* mostPossiblePluginInfo( NULL );
       
  1012     TUid uid = TUid::Null();
       
  1013 
       
  1014     // Find the most suitable plugin
       
  1015     for ( TInt i = iPluginInfoArray.Count(); --i >= 0; )
       
  1016         {
       
  1017         TInt score( 0 );
       
  1018         CMPXPluginInfo* info = iPluginInfoArray[i];
       
  1019         const TArray<TUid> supportedUids = info->SupportedUids();
       
  1020 
       
  1021         for ( TInt j = aUids.Count(); --j >= 0; )
       
  1022             {
       
  1023             for (TInt k=supportedUids.Count(); --k >=0;)
       
  1024                 {
       
  1025                 if ( aUids[j] ==  supportedUids[k] )
       
  1026                    {
       
  1027                    // Five scores if in the supported uids list.
       
  1028                    score += 5;
       
  1029 
       
  1030                    // We now allow a UID to be repeated multiple times
       
  1031                    // for emphasized scoring.
       
  1032                    //break;
       
  1033                    }
       
  1034                 }
       
  1035             if (info->ImplementationUid() == aUids[j])
       
  1036                 {
       
  1037                 score += 100;
       
  1038                 }
       
  1039             if ( info->PluginType() == aUids[j])
       
  1040                 { // One more if match plugin type
       
  1041                 score++;
       
  1042                 }
       
  1043             }
       
  1044 
       
  1045         if ( score )
       
  1046             {
       
  1047             if ( lastScore < score )
       
  1048                 {
       
  1049                 lastScore = score;
       
  1050                 mostPossiblePluginInfo = info;
       
  1051                 }
       
  1052             else if ( lastScore == score )
       
  1053                 {
       
  1054                 // Use priority to determine if scores are the same
       
  1055                 // If same priorities are detected, the first found plugin
       
  1056                 // will be used.
       
  1057                 if (mostPossiblePluginInfo->Priority() < info->Priority())
       
  1058                     {
       
  1059                     mostPossiblePluginInfo = info;
       
  1060                     }
       
  1061                 } // else do nothing
       
  1062             }
       
  1063         }
       
  1064     if (mostPossiblePluginInfo)
       
  1065         {
       
  1066         uid =  mostPossiblePluginInfo->ImplementationUid();
       
  1067         }
       
  1068     return uid;
       
  1069     }
       
  1070 
       
  1071 #ifdef _DEBUG
       
  1072 
       
  1073 // ----------------------------------------------------------------------------
       
  1074 // CMPXPluginHandlerBase::PrintPluginInfo
       
  1075 // ----------------------------------------------------------------------------
       
  1076 //
       
  1077 void CMPXPluginHandlerBase::PrintPluginInfo()
       
  1078     {
       
  1079     MPX_DEBUG1("#### MPX Plugins ####");
       
  1080 
       
  1081     TInt count(iPluginInfoArray.Count());
       
  1082     for (TInt index = 0; index < count; ++index)
       
  1083         {
       
  1084         CMPXPluginInfo* info = iPluginInfoArray[index];
       
  1085         const TDesC& name = info->DisplayName();
       
  1086         MPX_DEBUG5("%S [0x%08X] Priority: %d Ref Count: %d", &name, info->ImplementationUid(),
       
  1087             info->Priority(), info->ReferenceCount());
       
  1088         MPX_DEBUG2("Version %d", info->Version());
       
  1089         }
       
  1090     }
       
  1091 
       
  1092 #endif
       
  1093 
       
  1094 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
  1095 // ----------------------------------------------------------------------------
       
  1096 // select plug-in appropriate for a file
       
  1097 // ----------------------------------------------------------------------------
       
  1098 //
       
  1099 EXPORT_C void CMPXPluginHandlerBase::SelectPlugin64L(const RFile64& aFile)
       
  1100     {
       
  1101     MPX_FUNC("CMPXPluginHandlerBase::SelectPlugin64L(RFile64)");
       
  1102 
       
  1103     TFileName fn;
       
  1104     User::LeaveIfError(aFile.FullName(fn));
       
  1105     SelectPluginL(fn, KNullDesC8);
       
  1106     }
       
  1107 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
  1108 
       
  1109 // End of file