--- a/gssettingsuis/Gs/GSFramework/src/GSPluginLoader.cpp Thu Aug 19 10:12:30 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,989 +0,0 @@
-/*
-* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: GS plugin loader.
-*
-*/
-
-
-// INCLUDE FILES
-#include <gspluginloader.h>
-#include <gsplugininterface.h>
-#include <gsprivatepluginproviderids.h>
-#include "GsLogger.h"
-#include "GSBaseDocument.h"
-#include "GSPluginWrapper.h"
-#include "GSPluginAndViewIdCache.h"
-#include <mgswatchdog.h>
-
-#include <aknViewAppUi.h>
-#include <AknIconArray.h>
-#include <aknlists.h> // CAknSingleLargeStyleListbox
-#include <eikclbd.h> // CColumnListBoxData
-#include <gulicon.h> // For CGulIcon
-#include <utf.h> // CnvUtfConverter
-#include <basched.h>
-#include <AknInfoPopupNoteController.h>
-
-//Flag for enabling/disablign compare by category feature
-#undef RD_GS_COMPARE_BY_CATEGORY
-
-// ================= MEMBER FUNCTIONS =======================
-
-#ifdef _DEBUG
- #pragma message("-----_DEBUG ACTIVATED IN GS!-----")
-#endif //_GEBUG
-
-#ifdef _GS_PERFORMANCE_TRACES
- #pragma message("-GS plugin load performance measurements activated-")
-#endif // _GS_PERFORMANCE_TRACES
-
-const TInt KGSCaptionSize = 256;
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::NewL
-//
-// EPOC two-phased constructor
-// ----------------------------------------------------------------------------
-//
-EXPORT_C CGSPluginLoader* CGSPluginLoader::NewL( CAknViewAppUi* aAppUi )
- {
- CGSPluginLoader* self = new( ELeave ) CGSPluginLoader;
- CleanupStack::PushL( self );
- self->ConstructL( aAppUi );
- CleanupStack::Pop( self );
- return self;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CGSPluginLoader
-//
-// C++ default constructor can NOT contain any code, that
-// might leave.
-//
-// Uses low priority for Active Object so that more bandwith is available for
-// the most important pluginloaders.
-// ----------------------------------------------------------------------------
-//
-CGSPluginLoader::CGSPluginLoader()
- : CActive( EPriorityLow ),
- iRequestedPriority( EPriorityLow )
- {
- __GSLOGSTRING( "[GSPlgLoader] CGSPluginLoader()" );
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::ConstructL
-//
-// EPOC default constructor can leave.
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::ConstructL( CAknViewAppUi* aAppUi )
- {
- __GSLOGSTRING( "[GSPlgLoader] ConstructL()" );
- iAppUi = aAppUi;
- iDocument = static_cast<CGSBaseDocument*>( iAppUi->Document() );
- iImplInfoArray = iDocument->GetImplInfo();
-
- CActiveScheduler* scheluder = CActiveScheduler::Current();
- __GSLOGSTRING1( "[GSPlgLoader] Current CActiveScheduler:0x%X", scheluder );
- __GSLOGSTRING1( "[GSPlgLoader] CActiveScheduler stackdepth: %d",
- scheluder->StackDepth() );
-
- CActiveScheduler::Add( this );
-
- iWatchDog = iDocument->WatchDog();
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::~CGSPluginLoader
-//
-// Destructor
-// ----------------------------------------------------------------------------
-//
-EXPORT_C CGSPluginLoader::~CGSPluginLoader()
- {
- __GSLOGSTRING( "[GSPlgLoader] ~CGSPluginLoader()" );
- AbortAsyncLoad();
- Cancel();
-
- if( iErrorPopup )
- {
- iErrorPopup->HideInfoPopupNote();
- delete iErrorPopup;
- iErrorPopup = NULL;
- }
- //iPluginArray is not owned and therefore not deleted.
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::LoadAsync
-//
-//
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::LoadAsyncL(
- TUid aInterfaceUid,
- TUid aParentUid,
- CArrayPtrFlat<CGSPluginInterface>* aPluginArray )
- {
- iPluginArray = aPluginArray;
- iParentUid = aParentUid;
-
- __GSLOGSTRING3(
- "[GSPlgLoader] LoadAsync(). aInterfaceUid:0x%X aParentUid:0x%X, aPluginArray:0x%X",
- aInterfaceUid, aParentUid, aPluginArray );
- // Reset iterator:
- iImplInfoArrayIterator = 0;
-
- __GSLOGSTRING1( "[GSPlgLoader] Implementation info count: %d",
- iImplInfoArray.Count() );
-
- NotifyProgress();
-
- //Begin CActive asynchronous loop.
- CompleteOwnRequest();
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::LoadSyncL
-//
-//
-// ----------------------------------------------------------------------------
-//
-CGSPluginInterface& CGSPluginLoader::LoadSyncL( TUid aInterfaceUid,
- TUid aImplementationUid )
- {
- Cancel();
- CGSPluginInterface* ret = NULL;
-
- // Get a list of all implementations, even though we only want one specific.
- // There appears to be no way to otherwise extract a specific implementation
- // info object :(
- // Search for the implementation that matches aImplementationUid
- const TInt impCount = iImplInfoArray.Count();
- for( TInt i=0; i<impCount; i++ )
- {
- const CImplementationInformation* info = iImplInfoArray[ i ];
- if ( info->ImplementationUid() == aImplementationUid )
- {
- ret = &CreatePluginInstanceL( *info );
- break;
- }
- }
-
- if ( !ret )
- {
- User::Leave( KErrNotFound );
- }
- return *ret;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::AbortAsyncLoad
-//
-//
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::AbortAsyncLoad()
- {
- __GSLOGSTRING( "[GSPlgLoader] AbortAsyncLoad()" );
- Cancel();
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::RunL
-//
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::RunL()
- {
- iRunLDebugCount++;
-
- // This must be done only in RunL or otherwise request might be
- // outstanding.
- if( iRequestedPriority != Priority() )
- {
- __GSLOGSTRING3(
- "[CGSPluginLoader::RunL] 0x%X original priority:%d requested priority:%d",
- iParentUid.iUid,
- Priority(),
- iRequestedPriority );
-
- SetPriority( iRequestedPriority );
- }
-
- LoadNextPluginL();
-
- // Check if there are still more plugins to be loaded:
- if ( iImplInfoArrayIterator < iImplInfoArray.Count() )
- {
- NotifyProgress();
- // Continue CActive asynchronous loop.
- CompleteOwnRequest();
- }
- else
- {
- // All plugins loaded:
- __GSLOGSTRING( "[GSPlgLoader] Loading plugins finished." );
- NotifyFinished();
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// CScGenreItemConstructionConductor::CompleteOwnRequest
-//
-// Issue request complete notification.
-// ---------------------------------------------------------------------------
-void CGSPluginLoader::CompleteOwnRequest()
- {
- TRequestStatus* status = &iStatus;
- User::RequestComplete( status, KErrNone );
- SetActive();
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::RunError
-//
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::RunError( TInt aError )
- {
- // This method is called when a plugin loading fails.
- // Always "fake" the return value so that ActiveSchedule
- // keeps running and later plugins are continued to be loaded.
- // Check if still plugins to be loaded:
- if( iImplInfoArrayIterator < iImplInfoArray.Count() )
- {
- NotifyProgress();
-
- //Continue CActive asynchronous loop.
- CompleteOwnRequest();
- }
- else // All plugins loaded:
- {
- NotifyFinished();
- }
-
- if ( aError == KLeaveExit )
- {
- return KLeaveExit;
- }
-
- return KErrNone;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::DoCancel
-//
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::DoCancel()
- {
-
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::NotifyProgress
-//
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::NotifyProgress()
- {
- if( iObserver )
- {
- iObserver->HandlePluginLoaded( MGSPluginLoadObserver::EGSSuccess);
- }
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::NotifyFinished
-//
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::NotifyFinished()
- {
-
- #ifdef _GS_PLUGINLOADER_FINAL_SORTING_TRACES
- TRAP_IGNORE( PrintOrderTracesL( iPluginArray ) );
- #endif // _GS_PLUGINLOADER_FINAL_SORTING_TRACES
-
- // I have finished loading: No need to keep me in the expensive scheduler
- // queue.
- Deque();
-
- if( iObserver )
- {
- iObserver->HandlePluginLoaded( MGSPluginLoadObserver::EGSFinished );
- }
-
- __GSLOGSTRING1( "[CGSPluginLoader::NotifyFinished] 0x%X",
- iParentUid.iUid );
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::SetObserver
-//
-//
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::SetObserver(MGSPluginLoadObserver* aObserver)
- {
- __GSLOGSTRING1("[GSPlgLoader] Observer set:0x%X", aObserver);
- iObserver = aObserver;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::ParseToUid
-// Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal.
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget )
- {
- // Remove "0x" from the descriptor if it exists
- _LIT8(KHexPrefix, "0x");
-
- TPtrC8 pSource( aSource );
- const TInt prefixPosition = pSource.Find( KHexPrefix );
- if ( prefixPosition != KErrNotFound )
- {
- pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) );
- }
-
- // Parse to integer
- TLex8 lex( pSource );
- TUint integer = 0;
-
- // Parse using TRadix::EHex as radix:
- const TInt err = lex.Val( integer, EHex );
- aTarget.iUid = integer;
-
- if( err != KErrNone )
- {
- // If parsing parent UID failed, do not load plugin:
- __GSLOGSTRING1(
- "[GSPlgLoader] Parsing parent UID failed. Error code:%d",
- err );
- }
- return err;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::ParseOrderNumber
-//
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber )
- {
- // Parse plugin's order number from opaque_data:
- TLex8 lex( aSource );
- const TInt orderErr = lex.Val( aOrderNumber );
- return orderErr;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::PrintInfoDebug
-// Print CImplementationInformation to log. Used for debugging.
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::PrintInfoDebugL( const CImplementationInformation& aInfo,
- TInt aIterator,
- TInt aPluginCount )
- {
-
-
- #pragma message("-CGSPluginLoader verbose traces activated-")
- __GSLOGSTRING2( "[GSPlgLoader::LoadNextPluginL] %d/%d",
- aIterator,
- aPluginCount);
-
- __GSLOGSTRING1( "[GSPlgLoader] --Plugin 0x%X info--", &aInfo);
- __GSLOGSTRING1( "[GSPlgLoader] DisplayName:%S", &aInfo.DisplayName() );
- __GSLOGSTRING1( "[GSPlgLoader] ImplementationUid:0x%X",
- aInfo.ImplementationUid() );
-
- const TInt KMaxEComDataLength = 256;
-
- HBufC* dataType = HBufC::New( KMaxEComDataLength );
- HBufC* opaqueData = HBufC::New( KMaxEComDataLength );
-
- dataType->Des().Copy( aInfo.DataType() );
- opaqueData->Des().Copy( aInfo.OpaqueData() );
- __GSLOGSTRING1( "[GSPlgLoader] DataType:%S", dataType );
- __GSLOGSTRING1( "[GSPlgLoader] OpaqueData:%S", opaqueData );
-
- delete opaqueData;
- delete dataType;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::LoadNextPluginL
-// Iterate through iImplInfoArray. Load the plugin if it is eligible for
-// loading. Loaded plugin is added to iPluginArray. Each time a plugin is
-// loaded, iObserver is notified.
-//
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::LoadNextPluginL()
- {
- // Iterate through iImplInfoArray. This loop continues between function
- // calls. Therefore member variable iImplInfoArrayIterator is used as a
- // counter. Loop will break when match is found and continues on next RunL.
- for( ; iImplInfoArrayIterator < iImplInfoArray.Count(); )
- {
- const CImplementationInformation* info =
- iImplInfoArray[ iImplInfoArrayIterator ];
-
- iImplInfoArrayIterator++;
-
- #ifdef _GS_PLUGINLOADER_VERBOSE_TRACES
- PrintInfoDebugL( *info, iImplInfoArrayIterator, iImplInfoArray.Count() );
- #endif //_GS_PLUGINLOADER_VERBOSE_TRACES
-
- // Parse parent UID from default_data:
- TUid parentUid;
- const TInt uidErr = ParseToUid( info->DataType(), parentUid );
-
- if( uidErr == KErrNone && iParentUid == parentUid )
- {
- // If this plugin is OK -> load it:
- __GSLOGSTRING2( "[GSPlgLoader] %S eligible for parent 0x%X",
- &info->DisplayName(), iParentUid.iUid );
- CGSPluginInterface* plugin = NULL;
- TInt error = KErrCancel;
- #ifdef GS_ENABLE_WATCH_DOG
- if( !iWatchDog->IsInBlackList( info->ImplementationUid() ) )
- #endif
- {
- // Only panics move quarantined plugins to blacklist. Leaving is
- // normal programmatic functionality and therefore does not move
- // plugin to blacklist.
- #ifdef GS_ENABLE_WATCH_DOG
- iWatchDog->QuarantineL( info->ImplementationUid() );
- #endif
-
- #ifdef _GS_PERFORMANCE_TRACES
- TTime timeStart;
- TTime timeEnd;
- timeStart.HomeTime();
- #endif //_GS_PERFORMANCE_TRACES
-
- // Create plugin. Trap leave for debugging purposes.
- TRAP( error, plugin = &CreatePluginInstanceL( *info ); );
-
- #ifdef _GS_PERFORMANCE_TRACES
- timeEnd.HomeTime();
- TTimeIntervalMicroSeconds funcDuration = timeEnd.MicroSecondsFrom( timeStart );
- __GSLOGSTRING2( "[GSPlgLoader::LoadNextPluginL/perf] %Ld (%S)", funcDuration, &info->DisplayName() );
- #endif //_GS_PERFORMANCE_TRACES
-
- #ifdef GS_ENABLE_WATCH_DOG
- TRAP_IGNORE( iWatchDog->RemoveFromQuarantineL( info->ImplementationUid() ); );
- #endif
- }
- if( error == KErrNone )
- {
- // Plugin ownership is transfered to iPluginArray
- InsertPluginInOrderL( plugin, iPluginArray );
- }
- else if( error == KLeaveExit )
- {
- __GSLOGSTRING( "[GSPlgLoader::LoadNextPluginL] LEAVE: KLeaveExit!!!" );
- // Must pass KLeaveExit through or otherwise Exit-command will
- // not be handled.
- User::Leave( KLeaveExit );
- }
- else
- {
- // Error note is displayed even if plugin is not loaded
- // -> plugin is in blacklist -> blacklist note displayed.
- #ifdef _DEBUG
- DisplayErrorPopupL( error, info );
- #endif //_DEBUG
- }
- // Wait for next round
- break;
- }
- }
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::DisplayErrorPopupL
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::DisplayErrorPopupL(
- TInt aError,
- const CImplementationInformation* aInfo )
- {
-
- // Log error:
- __GSLOGSTRING3( "[GSPlgLoader] %S (0x%X) loading failed with error code %d",
- &aInfo->DisplayName(),
- aInfo->ImplementationUid().iUid,
- aError );
-
- // Runtime info message used only in _DEBUG builds.
- // Buffer needs space for about 50 chars for debug text
- // + 8 chars for hex UID
- // + DisplayName().Length()
- // + error code 10 chars...
- HBufC* buf = HBufC::NewLC( 100 + aInfo->DisplayName().Length() );
- TPtr ptr = buf->Des();
-
- if( aError == KErrCancel )
- {
- _LIT( KDbgMsgBlacklisted, "Plugin in blacklist:\n%S (0x%X)" );
- ptr.Format( KDbgMsgBlacklisted,
- &aInfo->DisplayName(),
- aInfo->ImplementationUid().iUid );
- }
- else
- {
- _LIT( KDbgMsg, "Error:\n%S (0x%X)\nloading failed with error code %d" );
- ptr.Format( KDbgMsg,
- &aInfo->DisplayName(),
- aInfo->ImplementationUid().iUid,
- aError );
- }
- if( iErrorPopup )
- {
- delete iErrorPopup;
- iErrorPopup = NULL;
- }
- iErrorPopup = CAknInfoPopupNoteController::NewL();
- iErrorPopup->SetTextL( ptr );
- CleanupStack::PopAndDestroy( buf );
- iErrorPopup->ShowInfoPopupNote();
- }
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CreatePluginInstanceL
-//
-//
-// ----------------------------------------------------------------------------
-//
-CGSPluginInterface& CGSPluginLoader::CreatePluginInstanceL(
- const CImplementationInformation& aImpInfo )
- {
- // Create a wrapper for the plugin - this will take
- // care of cleaning up the plugin dll. This must be on
- // the cleanup stack above the plugin object itself - since
- // the cleanup stack will first delete the plugin, then the
- // plugin wrapper will be called to unload the ECOM plugin
- // dll itself.
- CGSPluginWrapper* wrapper = iDocument->NewPluginUnloadWrapperLC();
-
- // Now we can load the plugin
- const TUid implUid = aImpInfo.ImplementationUid();
-
- CGSPluginInterface* plugin = CGSPluginInterface::NewL( implUid,
- iAppUi );// Remove iAppUi
- CleanupStack::PushL ( plugin );
-
- // And now its okay to update the wrapper with the plugin's
- // ECOM destructor info.
- wrapper->SetDetails( plugin->iDtor_ID_Key );
-
- // If plugin's resource definition had a valid order number,
- // set it to plugin.
- //
- // If parent is GSAppsPlugin, this is where the ordering
- // could be changed to follow the to-be-implemented resource file
- // defining the plugin order.
-
- // Parse plugin's order number from opaque_data:
- TInt orderNumber = 0;
- const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber );
- if ( orderErr == KErrNone && orderNumber >= 0 )
- {
- plugin->iOrder = orderNumber;
- }
-
- // When a specific view has been activated externally to GS (e.g
- // whilst GS is not running) we have to load the view's plugin on-demand.
- // This means that the plugin is essentially free-floating and is not bound
- // to a parent's CGSParentPlugin::iPluginArray.
- //
- // In this situation, even though we have activated a specific view,
- // the plugin loader(s) continue to operate in the background.
- //
- // Eventually, as the loaders progress, a second attempt will occur to
- // load the same view (that was activated externally).
- //
- // In this situation, we discard the recently loaded instance of the plugin
- // and instead preserve the view that the user is (presumably) already using.
- //
- // However, we must ensure that we synchronous the parent's iPluginArray
- // with the pre-existing view instance.
- const TUid viewId = plugin->Id();
- CGSPluginAndViewIdCache& pluginViewIdCache = iDocument->PluginViewIdCache();
- const TBool isAlreadyLoaded = pluginViewIdCache.IsPluginLoaded( viewId );
-
- if ( !isAlreadyLoaded )
- {
- // Cache the view uid & ECOM plugin dll uid to enable us
- // to more quickly handle external view activation requests
- // when GS is not already running.
- pluginViewIdCache.RegisterViewAndImplementationAssociationL( viewId, implUid );
-
- // Prepare to register the plugin with the cache. Pushes a cleanup stack
- // item in case adding the view should leave.
- pluginViewIdCache.PrepareToRegisterPluginInstanceLC( viewId );
-
- // Add loaded view to appUi. At this point, the GS framework
- // is no longer responsible for the lifetime of the 'plugin'
- // object.
- //
- // However, to ensure sucessful cleanup of deleted
- // views, we have separated the ECOM plugin dll (controlled by
- // plugin->iDtor_ID_Key) to a separate object. This object is
- // owned by the loader.
- iAppUi->AddViewL( plugin );
-
- // Pop the cleanup item - all is well now.
- CleanupStack::Pop(); // cleanup item from PrepareToRegisterPluginInstanceLC
-
- CleanupStack::Pop( plugin ); // view framework is now responsible for this memory.
-
- // Document, when it is destroyed, will handle unloading of ECOM dll.
- CleanupStack::Pop( wrapper );
-
- // Also register that we have loaded an instance of the specified view
- // from a plugin.
- pluginViewIdCache.RegisterPluginInstanceL( viewId, *plugin );
- }
- else
- {
- // Plugin is already loaded, presumably due to external view activation
- // request.
- //
- // Discard "just loaded" instance and use the pre-loaded one instead.
- CleanupStack::PopAndDestroy( 2, wrapper );
- plugin = pluginViewIdCache.PluginInstance( viewId );
- }
-
- return *plugin;
- }
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::SortPluginsL
-//
-// ----------------------------------------------------------------------------
-//
-EXPORT_C void CGSPluginLoader::SortPluginsL(
- CArrayPtrFlat<CGSPluginInterface>* aPlugins )
- {
- RPointerArray<CGSPluginInterface> plugins;
- TLinearOrder<CGSPluginInterface> order( CGSPluginLoader::Compare );
-
- // Insertion will also order
- for( TInt i = 0; i < aPlugins->Count(); i++ )
- {
- plugins.InsertInOrderL( (*aPlugins)[i], order );
- }
-
- // Replace original array content with sorted items
- aPlugins->Reset();
- for( TInt i = 0; i < plugins.Count(); i++ )
- {
- aPlugins->AppendL( plugins[i] );
- }
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::Compare
-//
-// Compare two plugins.
-// Precedence:
-// [1. plugin provider category]
-// 2. plugin order number
-// 3. plugin caption
-// Plugin provider gategory is currently disabled (not supported yet).
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::Compare( const CGSPluginInterface& aFirst,
- const CGSPluginInterface& aSecond )
- {
- TInt comparison = CompareCategory( aFirst, aSecond );
- if( comparison == KGSComparisonEqual )
- {
- comparison = CompareIndex( aFirst, aSecond );
- if( comparison == KGSComparisonEqual )
- {
- comparison = CompareCaption( aFirst, aSecond );
- }
- }
- return comparison;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::InsertPluginInOrderL
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::InsertPluginInOrderL(
- CGSPluginInterface* aPlugin,
- CArrayPtrFlat<CGSPluginInterface>* aPlugins )
- {
- CGSPluginInterface* comparedPlugin;
- TInt comparison = 0;
- TBool inserted = EFalse;
-
- for( TInt i = 0; i < aPlugins->Count(); i++ )
- {
- comparedPlugin = (*aPlugins)[i];
- // Optimization: do not call time consuming Compare() multiple times!
- comparison = Compare( *aPlugin, *comparedPlugin );
- if( comparison < 0 )
- {
- aPlugins->InsertL( i, aPlugin );
- inserted = ETrue;
- break;
- }
- else if( comparison == 0 )
- {
- aPlugins->InsertL( i+1, aPlugin );
- inserted = ETrue;
- break;
- }
- }
- // Plugin was not before any other plugin - make sure it's appended
- if( !inserted )
- {
- aPlugins->AppendL( aPlugin );
- }
-
- #ifdef _GS_PLUGINLOADER_ITERATION_SORTING_TRACES
- PrintOrderTracesL( aPlugins );
- #endif // _GS_PLUGINLOADER_ITERATION_SORTING_TRACES
-
- }
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CompareCategory
-//
-// ----------------------------------------------------------------------------
-//
-void CGSPluginLoader::PrintOrderTracesL(
- CArrayPtrFlat<CGSPluginInterface>* aPlugins )
- {
- __GSLOGSTRING1( "---[CGSPluginLoader] Sorted list for 0x%X---", iParentUid.iUid );
- HBufC* name = HBufC::New( KGSCaptionSize );
- CleanupStack::PushL( name );
-
- TPtr ptr = name->Des();
- CGSPluginInterface* plg;
-
- for( TInt i = 0; i < aPlugins->Count(); i++ )
- {
- plg = (*aPlugins)[i];
- plg->GetCaptionL( ptr );
- __GSLOGSTRING4( "[CGSPluginLoader] Sorted list[%d] Category:%d (0x%X) %S",
- plg->iOrder,
- plg->PluginProviderCategory(),
- plg->Id().iUid,
- &ptr );
- }
- CleanupStack::PopAndDestroy( name );
-
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CompareCategory
-//
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::CompareCategory( const CGSPluginInterface& aFirst,
- const CGSPluginInterface& aSecond )
- {
-#ifdef RD_GS_COMPARE_BY_CATEGORY
- TInt comparison = KGSComparisonBefore;//KGSComparisonEqual;
-
- // Compare if a is before b:
- TInt a = aFirst.PluginProviderCategory();
- TInt b = aSecond.PluginProviderCategory();
-
- // Cannot use less/greater comparison because int values used in here
- // (KGSPluginProviderInternal) must not be revealed to 3rd parties.
- if( a != b )
- {
- switch ( a )
- {
-/* case KGSPluginProviderInternal:
- if( b != KGSPluginProviderInternal )
- {
- comparison = KGSComparisonAfter;
- }
- break;*/
- case CGSPluginInterface::EGSPluginProviderOEM:
- if( b == KGSPluginProviderInternal )
- {
- comparison = KGSComparisonAfter;
- }
- break;
- case CGSPluginInterface::EGSPluginProviderOperator:
- if( b == KGSPluginProviderInternal ||
- b == CGSPluginInterface::EGSPluginProviderOEM )
- {
- comparison = KGSComparisonAfter;
- }
- break;
- case CGSPluginInterface::EGSPluginProvider3rdParty:
- if( b == KGSPluginProviderInternal ||
- b == CGSPluginInterface::EGSPluginProviderOEM ||
- b == CGSPluginInterface::EGSPluginProviderOperator )
- {
- comparison = KGSComparisonAfter;
- }
- break;
- default:
- comparison = KGSComparisonBefore;
- break;
- }
- }
- else
- {
- comparison = KGSComparisonEqual;
- }
-
- return comparison;
-
-#else //RD_GS_COMPARE_BY_CATEGORY
- #pragma message("Comparing by category DISABLED")
- // Force comparison to equal so category comparison will not matter. If
- // comparison by gategory is needed, simply remove the line below:
- return KGSComparisonEqual;
-#endif //RD_GS_COMPARE_BY_CATEGORY
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CompareCaption
-//
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::CompareCaption( const CGSPluginInterface& aFirst,
- const CGSPluginInterface& aSecond )
- {
- HBufC* firstCaptionBuf = HBufC::New( KGSCaptionSize );
- HBufC* secondCaptionBuf = HBufC::New( KGSCaptionSize );
- TPtr firstCaption = firstCaptionBuf->Des();
- TPtr secondCaption = secondCaptionBuf->Des();
- TInt comparison = KGSComparisonEqual;
-
- TRAPD( err, aFirst.GetCaptionL( firstCaption ); );
- TRAPD( err2, aSecond.GetCaptionL( secondCaption ); );
-
- if( err == KErrNone && err2 == KErrNone )
- {
- // CompareC return value must be converted to KGSComparisonXXX value.
- TInt result = secondCaption.CompareC( firstCaption );
- if( result < 0 )
- {
- comparison = KGSComparisonAfter;
- }
- else if( result > 0 )
- {
- comparison = KGSComparisonBefore;
- }
- }
- delete firstCaptionBuf;
- delete secondCaptionBuf;
- return comparison;
- }
-
-
-// ----------------------------------------------------------------------------
-// CGSPluginLoader::CompareIndex
-//
-//
-// ----------------------------------------------------------------------------
-//
-TInt CGSPluginLoader::CompareIndex( const CGSPluginInterface& aFirst,
- const CGSPluginInterface& aSecond )
- {
- TInt comparison = KGSComparisonEqual;
-
- // The plugin having index is before the one not having one
-
- if( aFirst.iOrder == KGSPluginNotIndexed &&
- aSecond.iOrder == KGSPluginNotIndexed )
- {
- // Neither have index -> equal
- comparison = KGSComparisonEqual;
- }
- else if( aFirst.iOrder == KGSPluginNotIndexed )
- {
- // The plugin having index is before the one not having one
- comparison = KGSComparisonAfter;
- }
- else if( aSecond.iOrder == KGSPluginNotIndexed )
- {
- // The plugin having index is before the one not having one
- comparison = KGSComparisonBefore;
- }
- else if( aFirst.iOrder < aSecond.iOrder )
- {
- // Compare actual index values
- comparison = KGSComparisonBefore;
- }
- else if( aFirst.iOrder > aSecond.iOrder )
- {
- // Compare actual index values
- comparison = KGSComparisonAfter;
- }
-
- return comparison;
- }
-
-
-
-EXPORT_C void CGSPluginLoader::RequestPriority( CActive::TPriority aPriority )
- {
- iRequestedPriority = aPriority;
- }
-
-
-// End of File