sysanadatacapture/piprofiler/piprofiler/engine/src/SamplerPluginLoader.cpp
changeset 2 6a82cd05fb1e
parent 1 3ff3fecb12fe
equal deleted inserted replaced
1:3ff3fecb12fe 2:6a82cd05fb1e
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include    "SamplerPluginLoader.h"
       
    21 #include	<piprofiler/EngineUIDs.h>
       
    22 #include    <UTF.H> // CnvUtfConverter
       
    23 #include  	<basched.h>
       
    24 
       
    25 // CONSTANTS
       
    26 const TInt KSamplerCaptionSize = 256;
       
    27 
       
    28 // ----------------------------------------------------------------------------
       
    29 // CSamplerPluginLoader::NewL
       
    30 //
       
    31 // EPOC two-phased constructor
       
    32 // ----------------------------------------------------------------------------
       
    33 //
       
    34 CSamplerPluginLoader* CSamplerPluginLoader::NewL()
       
    35     {
       
    36     CSamplerPluginLoader* self = new( ELeave ) CSamplerPluginLoader;
       
    37     CleanupStack::PushL( self );
       
    38     self->ConstructL( );
       
    39     CleanupStack::Pop( self );
       
    40     return self;
       
    41     }
       
    42 
       
    43 
       
    44 // ----------------------------------------------------------------------------
       
    45 // CSamplerPluginLoader::CSamplerPluginLoader
       
    46 //
       
    47 // C++ default constructor can NOT contain any code, that
       
    48 // might leave.
       
    49 // ----------------------------------------------------------------------------
       
    50 //
       
    51 CSamplerPluginLoader::CSamplerPluginLoader() : CActive( EPriorityStandard )
       
    52     {
       
    53     LOGSTRING( "CSamplerPluginLoader()::CSamplerPluginLoader()" );
       
    54     }
       
    55 
       
    56 
       
    57 // ----------------------------------------------------------------------------
       
    58 // CSamplerPluginLoader::ConstructL
       
    59 //
       
    60 // EPOC default constructor can leave.
       
    61 // ----------------------------------------------------------------------------
       
    62 //
       
    63 void CSamplerPluginLoader::ConstructL( )
       
    64     {
       
    65     LOGSTRING( "CSamplerPluginLoader()::ConstructL()" );
       
    66 
       
    67     // get list of implementations
       
    68     CSamplerPluginInterface::ListAllImplementationsL( iImplInfoArray );
       
    69 
       
    70     CActiveScheduler::Add( this );
       
    71     }
       
    72 
       
    73 // ----------------------------------------------------------------------------
       
    74 // CSamplerPluginLoader::~CSamplerPluginLoader
       
    75 //
       
    76 // Destructor
       
    77 // ----------------------------------------------------------------------------
       
    78 //
       
    79 CSamplerPluginLoader::~CSamplerPluginLoader()
       
    80     {
       
    81     LOGSTRING( "CSamplerPluginLoader()::~CSamplerPluginLoader()" );
       
    82 
       
    83     AbortAsyncLoad();
       
    84 
       
    85     Cancel();
       
    86     
       
    87     // reset ECOM implementation info array
       
    88     iImplInfoArray.ResetAndDestroy();   // This is needed
       
    89     iImplInfoArray.Close();
       
    90     }
       
    91 
       
    92 
       
    93 // ----------------------------------------------------------------------------
       
    94 // CSamplerPluginLoader::LoadAsync
       
    95 // ----------------------------------------------------------------------------
       
    96 //
       
    97 void CSamplerPluginLoader::LoadAsyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray )
       
    98     {
       
    99     iPluginArray = aPluginArray;
       
   100 
       
   101     // Reset iterator
       
   102     iImplInfoArrayIterator = 0;
       
   103 
       
   104     LOGSTRING2( "CSamplerPluginLoader()::Implementation info count: %d",
       
   105         iImplInfoArray.Count() );
       
   106 
       
   107     NotifyProgress();
       
   108 
       
   109     //Begin CActive asynchronous loop.
       
   110     CompleteOwnRequest();
       
   111     }
       
   112     
       
   113 
       
   114 // ----------------------------------------------------------------------------
       
   115 // CSamplerPluginLoader::LoadSyncL
       
   116 // ----------------------------------------------------------------------------
       
   117 //
       
   118 void CSamplerPluginLoader::LoadSyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray)
       
   119     {
       
   120     // cancel first active object from loading samplers dynamically
       
   121     Cancel();
       
   122     CSamplerPluginInterface* plugin = NULL;
       
   123     
       
   124     iPluginArray = aPluginArray;
       
   125 
       
   126     // Get a list of all implementations, even though we only want one specific
       
   127     // one. There appears to be no way to otherwise extract a specific implementation
       
   128     // info object :(
       
   129     // Search for the implementation that matches aImplementationUid
       
   130     const TInt impCount = iImplInfoArray.Count();
       
   131     for( TInt i=0; i<impCount; i++ )
       
   132         {
       
   133         const CImplementationInformation* info = iImplInfoArray[ i ];
       
   134             {
       
   135             TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); );
       
   136             if( ret == KErrNone )
       
   137                 {
       
   138                 // Plugin ownership is transfered to iPluginArray
       
   139                 InsertPluginInOrderL( plugin, iPluginArray );
       
   140                 }
       
   141             else
       
   142                 {
       
   143                 // Error note is displayed even if plugin is not loaded
       
   144                 LOGSTRING3("CSamplerPluginLoader::LoadSyncL() - plugin %S load failed, error %d", &info->iDisplayName(), ret);
       
   145                 }
       
   146             break;
       
   147             }
       
   148         }
       
   149 
       
   150     if  ( plugin == NULL )
       
   151         {
       
   152         User::Leave( KErrNotFound );
       
   153         }
       
   154     }
       
   155 
       
   156 
       
   157 // ----------------------------------------------------------------------------
       
   158 // CSamplerPluginLoader::AbortAsyncLoad
       
   159 // ----------------------------------------------------------------------------
       
   160 //
       
   161 void CSamplerPluginLoader::AbortAsyncLoad()
       
   162     {
       
   163     LOGSTRING( "CSamplerPluginLoader()::AbortAsyncLoad()" );
       
   164     Cancel();
       
   165     }
       
   166 
       
   167 
       
   168 // ----------------------------------------------------------------------------
       
   169 // CSamplerPluginLoader::RunL
       
   170 // ----------------------------------------------------------------------------
       
   171 //
       
   172 void CSamplerPluginLoader::RunL()
       
   173     {
       
   174     iRunLDebugCount++;
       
   175     LoadNextPluginL();
       
   176 
       
   177     // Check if there are still more plugins to be loaded:
       
   178     if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
       
   179         {
       
   180         NotifyProgress();
       
   181         // Continue CActive asynchronous loop.
       
   182         CompleteOwnRequest();
       
   183         }
       
   184     else
       
   185         {
       
   186         // All plugins loaded:
       
   187         LOGSTRING( "CSamplerPluginLoader()::Loading plugins finished." );
       
   188         NotifyFinished();
       
   189         }
       
   190     }
       
   191 
       
   192 
       
   193 // ---------------------------------------------------------------------------
       
   194 // CScGenreItemConstructionConductor::CompleteOwnRequest
       
   195 //
       
   196 // Issue request complete notification.
       
   197 // ---------------------------------------------------------------------------
       
   198 void CSamplerPluginLoader::CompleteOwnRequest()
       
   199     {
       
   200     TRequestStatus* status = &iStatus;
       
   201     User::RequestComplete( status, KErrNone );
       
   202     SetActive();
       
   203     }
       
   204 
       
   205 
       
   206 // ----------------------------------------------------------------------------
       
   207 // CSamplerPluginLoader::RunError
       
   208 // ----------------------------------------------------------------------------
       
   209 //
       
   210 TInt CSamplerPluginLoader::RunError( TInt aError )
       
   211     {
       
   212     // This method is called when a plugin loading fails.
       
   213     // Always "fake" the return value so that ActiveSchedule
       
   214     // keeps running and later plugins are continued to be loaded.
       
   215     // Check if still plugins to be loaded:
       
   216     LOGTEXT(_L("CSamplerPluginLoader::RunError() - error in loading plugin"));
       
   217     if( iImplInfoArrayIterator < iImplInfoArray.Count() )
       
   218         {
       
   219         NotifyProgress();
       
   220 
       
   221         //Continue CActive asynchronous loop.
       
   222         CompleteOwnRequest();
       
   223         }
       
   224     else // All plugins loaded:
       
   225         {
       
   226         NotifyFinished();
       
   227         }
       
   228 
       
   229     if ( aError == KLeaveExit )
       
   230         {
       
   231         return KLeaveExit;
       
   232         }
       
   233 
       
   234     return KErrNone;
       
   235     }
       
   236 
       
   237 
       
   238 // ----------------------------------------------------------------------------
       
   239 // CSamplerPluginLoader::DoCancel
       
   240 // ----------------------------------------------------------------------------
       
   241 //
       
   242 void CSamplerPluginLoader::DoCancel()
       
   243     {
       
   244 
       
   245     }
       
   246 
       
   247 
       
   248 // ----------------------------------------------------------------------------
       
   249 // CSamplerPluginLoader::NotifyProgress
       
   250 // ----------------------------------------------------------------------------
       
   251 //
       
   252 void CSamplerPluginLoader::NotifyProgress()
       
   253     {
       
   254     if( iObserver )
       
   255         {
       
   256         iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerSuccess);
       
   257         }
       
   258     }
       
   259 
       
   260 
       
   261 // ----------------------------------------------------------------------------
       
   262 // CSamplerPluginLoader::NotifyFinished
       
   263 // ----------------------------------------------------------------------------
       
   264 //
       
   265 void CSamplerPluginLoader::NotifyFinished()
       
   266     {
       
   267     if( iObserver )
       
   268         {
       
   269         iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerFinished );
       
   270         }
       
   271     }
       
   272 
       
   273 
       
   274 // ----------------------------------------------------------------------------
       
   275 // CSamplerPluginLoader::SetObserver
       
   276 // ----------------------------------------------------------------------------
       
   277 //
       
   278 void CSamplerPluginLoader::SetObserver(MSamplerPluginLoadObserver* aObserver)
       
   279     {
       
   280     LOGSTRING2("CSamplerPluginLoader()::Observer set:0x%X", aObserver);
       
   281     iObserver = aObserver;
       
   282     }
       
   283 
       
   284 
       
   285 // ----------------------------------------------------------------------------
       
   286 // CSamplerPluginLoader::ParseToUid
       
   287 // Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
       
   288 //
       
   289 // ----------------------------------------------------------------------------
       
   290 //
       
   291 TInt CSamplerPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
       
   292     {
       
   293     // Remove "0x" from the descriptor if it exists
       
   294     _LIT8(KHexPrefix, "0x");
       
   295 
       
   296     TPtrC8 pSource( aSource );
       
   297     const TInt prefixPosition = pSource.Find( KHexPrefix );
       
   298     if  ( prefixPosition != KErrNotFound )
       
   299         {
       
   300         pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
       
   301         }
       
   302 
       
   303     // Parse to integer
       
   304     TLex8 lex( pSource );
       
   305     TUint integer = 0;
       
   306 
       
   307     // Parse using TRadix::EHex as radix:
       
   308     const TInt err = lex.Val( integer, EHex );
       
   309     aTarget.iUid = integer;
       
   310 
       
   311     if( err != KErrNone )
       
   312         {
       
   313         // If parsing parent UID failed, do not load plugin:
       
   314         LOGSTRING2(
       
   315             "CSamplerPluginLoader()::Parsing parent UID failed. Error code:%d",
       
   316             err );
       
   317         }
       
   318     return err;
       
   319     }
       
   320 
       
   321 
       
   322 // ----------------------------------------------------------------------------
       
   323 // CSamplerPluginLoader::ParseOrderNumber
       
   324 //
       
   325 //
       
   326 // ----------------------------------------------------------------------------
       
   327 //
       
   328 TInt CSamplerPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
       
   329     {
       
   330     // Parse plugin's order number from opaque_data:
       
   331     TLex8 lex( aSource );
       
   332     const TInt orderErr = lex.Val( aOrderNumber );
       
   333     return orderErr;
       
   334     }
       
   335 
       
   336 // ----------------------------------------------------------------------------
       
   337 // CSamplerPluginLoader::LoadNextPluginL
       
   338 // Iterate through iImplInfoArray. Load the plugin if it is eligible for
       
   339 // loading. Loaded plugin is added to iPluginArray. Each time a plugin is
       
   340 // loaded, iObserver is notified.
       
   341 //
       
   342 // ----------------------------------------------------------------------------
       
   343 //
       
   344 void CSamplerPluginLoader::LoadNextPluginL()
       
   345     {
       
   346     // Iterate through iImplInfoArray. This loop continues between function
       
   347     // calls. Therefore member variable iImplInfoArrayIterator is used as a
       
   348     // counter. Loop will break when match is found and continues on next RunL.
       
   349     for( ; iImplInfoArrayIterator < iImplInfoArray.Count();  )
       
   350         {
       
   351         const CImplementationInformation* info =
       
   352             iImplInfoArray[ iImplInfoArrayIterator ];
       
   353 
       
   354         iImplInfoArrayIterator++;
       
   355 
       
   356 //        PrintInfoDebug( *info, iImplInfoArrayIterator, iImplInfoArray.Count() );
       
   357         LOGSTRING3("CSamplerPluginLoader() - iImplInfoArrayIterator %d, iImplInfoArray.Count() %d", 
       
   358                 iImplInfoArrayIterator, 
       
   359                 iImplInfoArray.Count() );
       
   360         
       
   361         // If this plugin is OK -> load it:
       
   362         LOGSTRING2( "CSamplerPluginLoader() %S eligible for parent",
       
   363                 &info->DisplayName());
       
   364         CSamplerPluginInterface* plugin = NULL;
       
   365         TInt error(KErrNone);
       
   366         // Create plugin. Trap leave for debugging purposes.
       
   367         TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
       
   368 
       
   369         if( error == KErrNone )
       
   370             {
       
   371             // Plugin ownership is transfered to iPluginArray
       
   372             InsertPluginInOrderL( plugin, iPluginArray );
       
   373             }
       
   374         else
       
   375             {
       
   376             // Error note is displayed even if plugin is not loaded
       
   377             LOGSTRING3("CSamplerPluginLoader::LoadNextPluginL() - plugin %S load failed, error %d", &info->iDisplayName(), error);
       
   378             }
       
   379         // Wait for next round
       
   380         break;
       
   381         }
       
   382     }
       
   383  
       
   384 // ----------------------------------------------------------------------------
       
   385 // CSamplerPluginLoader::CreatePluginInstanceL
       
   386 //
       
   387 //
       
   388 // ----------------------------------------------------------------------------
       
   389 //
       
   390 
       
   391 CSamplerPluginInterface& CSamplerPluginLoader::CreatePluginInstanceL(
       
   392     const CImplementationInformation& aImpInfo )
       
   393     {
       
   394     // Now we can load the plugin
       
   395     const TUid implUid = aImpInfo.ImplementationUid();
       
   396 
       
   397     CSamplerPluginInterface* plugin = CSamplerPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() );
       
   398     CleanupStack::PushL ( plugin );
       
   399 
       
   400     // Parse plugin's order number from opaque_data:
       
   401     TInt orderNumber(0);
       
   402     const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
       
   403 
       
   404     if  ( orderErr == KErrNone && orderNumber >= 0 )
       
   405         {
       
   406         	plugin->iOrder = orderNumber;
       
   407         }
       
   408     CleanupStack::Pop( plugin ); // CSamplerController is now responsible for this memory.
       
   409 
       
   410     return *plugin;
       
   411     }
       
   412 
       
   413 // ----------------------------------------------------------------------------
       
   414 // CSamplerPluginLoader::SortPluginsL
       
   415 //
       
   416 // ----------------------------------------------------------------------------
       
   417 //
       
   418 void CSamplerPluginLoader::SortPluginsL(
       
   419         CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
       
   420     {
       
   421     RPointerArray<CSamplerPluginInterface> plugins;
       
   422     TLinearOrder<CSamplerPluginInterface> order( CSamplerPluginLoader::Compare );
       
   423 
       
   424     // Insertion will also order
       
   425     for( TInt i = 0; i < aPlugins->Count(); i++ )
       
   426         {
       
   427         plugins.InsertInOrderL( (*aPlugins)[i], order );
       
   428         }
       
   429 
       
   430     // Replace original array content with sorted items
       
   431     aPlugins->Reset();
       
   432     for( TInt i = 0; i < plugins.Count(); i++ )
       
   433         {
       
   434         aPlugins->AppendL( plugins[i] );
       
   435         }
       
   436     }
       
   437 
       
   438 
       
   439 // ----------------------------------------------------------------------------
       
   440 // CSamplerPluginLoader::Compare
       
   441 //
       
   442 // Compare two plugins.
       
   443 // Precedence:
       
   444 // [1. plugin provider category]
       
   445 // 2. plugin order number
       
   446 // 3. plugin caption
       
   447 // Plugin provider gategory is currently disabled (not supported yet).
       
   448 // ----------------------------------------------------------------------------
       
   449 //
       
   450 TInt CSamplerPluginLoader::Compare( const CSamplerPluginInterface& aFirst,
       
   451                                const CSamplerPluginInterface& aSecond )
       
   452     {
       
   453     // compare indexes and sort
       
   454     return CompareIndex( aFirst, aSecond );
       
   455     }
       
   456 
       
   457 
       
   458 // ----------------------------------------------------------------------------
       
   459 // CSamplerPluginLoader::InsertPluginInOrderL
       
   460 //
       
   461 // ----------------------------------------------------------------------------
       
   462 //
       
   463 void CSamplerPluginLoader::InsertPluginInOrderL(
       
   464     CSamplerPluginInterface* aPlugin,
       
   465     CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
       
   466     {
       
   467     CSamplerPluginInterface* comparedPlugin;
       
   468     TInt comparison = 0;
       
   469     TBool inserted = EFalse;
       
   470 
       
   471     for( TInt i = 0; i < aPlugins->Count(); i++ )
       
   472         {
       
   473         comparedPlugin = (*aPlugins)[i];
       
   474         // Optimization: do not call time consuming Compare() multiple times!
       
   475         comparison = Compare( *aPlugin, *comparedPlugin );
       
   476         if( comparison < 0 )
       
   477             {
       
   478             aPlugins->InsertL( i, aPlugin );
       
   479             inserted = ETrue;
       
   480             break;
       
   481             }
       
   482         else if( comparison == 0 )
       
   483             {
       
   484             aPlugins->InsertL( i+1, aPlugin );
       
   485             inserted = ETrue;
       
   486             break;
       
   487             }
       
   488         }
       
   489     // Plugin was not before any other plugin - make sure it's appended
       
   490     if( !inserted )
       
   491         {
       
   492         aPlugins->AppendL( aPlugin );
       
   493         }
       
   494 
       
   495     #ifdef _GS_PLUGINLOADER_SORTING_TRACES
       
   496         PrintOrderTraces( aPlugins );
       
   497     #endif // _GS_PLUGINLOADER_SORTING_TRACES
       
   498 
       
   499     }
       
   500 
       
   501 // ----------------------------------------------------------------------------
       
   502 // CSamplerPluginLoader::CompareCategory
       
   503 //
       
   504 // ----------------------------------------------------------------------------
       
   505 //
       
   506 void CSamplerPluginLoader::PrintOrderTraces(
       
   507         CArrayPtrFlat<CSamplerPluginInterface>* aPlugins )
       
   508     {
       
   509     LOGSTRING( "---[CSamplerPluginLoader] Sorted list---" );
       
   510     HBufC* name = HBufC::New( KSamplerCaptionSize );
       
   511     TRAPD(err, CleanupStack::PushL( name ));
       
   512 
       
   513     if(err != KErrNone)
       
   514         return; // no memory
       
   515     
       
   516     TPtr ptr = name->Des();
       
   517     CSamplerPluginInterface* plg;
       
   518 
       
   519     for( TInt i = 0; i < aPlugins->Count(); i++ )
       
   520         {
       
   521         plg = aPlugins->At(i);
       
   522         plg->GetCaption( ptr, ECaptionLengthShort, -1 );
       
   523 
       
   524         }
       
   525     CleanupStack::PopAndDestroy( name );
       
   526 
       
   527     }
       
   528 
       
   529 // ----------------------------------------------------------------------------
       
   530 // CSamplerPluginLoader::CompareIndex
       
   531 // ----------------------------------------------------------------------------
       
   532 //
       
   533 TInt CSamplerPluginLoader::CompareIndex( const CSamplerPluginInterface& aFirst,
       
   534                                     const CSamplerPluginInterface& aSecond )
       
   535     {
       
   536     TInt comparison = KSamplerComparisonEqual;
       
   537     // The plugin having index is before the one not having one
       
   538 
       
   539     if( aFirst.iOrder  == KSamplerPluginNotIndexed &&
       
   540         aSecond.iOrder == KSamplerPluginNotIndexed )
       
   541         {
       
   542         // Neither have index -> equal
       
   543         comparison = KSamplerComparisonEqual;
       
   544         }
       
   545     else if( aFirst.iOrder == KSamplerPluginNotIndexed )
       
   546         {
       
   547         // The plugin having index is before the one not having one
       
   548         comparison = KSamplerComparisonAfter;
       
   549         }
       
   550     else if( aSecond.iOrder == KSamplerPluginNotIndexed )
       
   551         {
       
   552         // The plugin having index is before the one not having one
       
   553         comparison = KSamplerComparisonBefore;
       
   554         }
       
   555     else if( aFirst.iOrder < aSecond.iOrder )
       
   556         {
       
   557         // Compare actual index values
       
   558         comparison = KSamplerComparisonBefore;
       
   559         }
       
   560     else if( aFirst.iOrder > aSecond.iOrder )
       
   561         {
       
   562         // Compare actual index values
       
   563         comparison = KSamplerComparisonAfter;
       
   564         }
       
   565     return comparison;
       
   566     }
       
   567 
       
   568 //  End of File