--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contextframework/cfw/src/cfcontextsourcemanager/CFContextSourceManager.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,1085 @@
+/*
+* Copyright (c) 2006-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: CFContextSourceManager class implementation.
+*
+*/
+
+
+
+#include <ecom/ecom.h>
+#include <centralrepository.h>
+#include <bautils.h>
+#include <cfcontextsourceupgrade.h>
+#include <cfcontextsourceinterface.h>
+#include <cfcontextsourcecommand.h>
+#include <cfcontextsubscriptionlistener.h>
+
+#include "CFContextSourceManager.h"
+#include "cfcontextsourcesettingsmanager.h"
+#include "ContextFrameworkPrivateCRKeys.h"
+#include "cfcontextsourceplugin.h"
+#include "cfextendedcontextinterface.h"
+#include "cfcontextsourcesettingarray.h"
+#include "cftrace.h"
+
+// CONSTANTS
+
+const TInt KUIDNameStartPos = 1;
+const TInt KUIDNameEndPos = 8;
+
+// Drive letter hard coded since context source plug-in settings
+// can only exist in ROM or RAM
+_LIT( KSettingsPathRom, "Z:\\Private\\10282BC4\\Settings\\" );
+_LIT( KSettingsPathRam, "C:\\Private\\10282BC4\\Settings\\" );
+
+// Folder extension
+_LIT( KFolderExt, "\\" );
+
+// Setting file extension
+_LIT( KSettingExtension, "*.xml" );
+
+// Separates SID from filename for client installed settings
+_LIT( KUnderscore, "_" );
+
+
+/**
+ * Information about a client acting as a context source.
+ * This info is used to keep track of clients acting as context sources to
+ * enable sending them context source commands.
+ *
+ * @lib CFContextSourceManager
+ * @since S60 5.0
+ */
+NONSHARABLE_CLASS( TCFClientContextSourceInfo )
+{
+public: // Constructors
+
+ TCFClientContextSourceInfo() : iSource( NULL ), iClientSid( KNullUid )
+ {
+ FUNC_LOG;
+ }
+
+ TCFClientContextSourceInfo( MCFContextSource* aSource, const TUid& aSid )
+ : iSource( aSource ), iClientSid( aSid )
+ {
+ FUNC_LOG;
+ }
+
+public: // Data
+
+ /**
+ * Context source interface pointer; not owned.
+ */
+ MCFContextSource* iSource;
+
+ /**
+ * Client's secure id (from client thread).
+ */
+ TUid iClientSid;
+};
+
+// ============================= LOCAL FUNCTIONS ==============================
+
+/**
+* Clenup operation for RImplInfoPtrArray
+*/
+LOCAL_C void CleanUpImplInfoArray( TAny* aParams )
+ {
+ RImplInfoPtrArray* array = static_cast<RImplInfoPtrArray*>( aParams );
+ array->ResetAndDestroy();
+ }
+
+/**
+* Push operations
+*/
+LOCAL_C void CleanupResetAndDestroyPushL( RImplInfoPtrArray& aArray )
+ {
+ TCleanupItem item( CleanUpImplInfoArray, &aArray );
+ CleanupStack::PushL( item );
+ }
+
+/**
+* Orders client countext source infos based on their uids.
+* @param aFirst First context source info.
+* @param aSecond Second context source info.
+* @return Zero if the uid of the first and second are equal. Negative value
+* if the uid of the first is less than the uid of the second. Positive
+* value if the uid of the first is greater than the uid of the second.
+*/
+LOCAL_C TInt ClientContextSourceInfoUidOrder(
+ const TCFClientContextSourceInfo& aFirst,
+ const TCFClientContextSourceInfo& aSecond )
+ {
+ TInt orderValue = 1;
+
+ if ( aFirst.iClientSid == aSecond.iClientSid )
+ {
+ orderValue = 0;
+ }
+ else if ( aFirst.iClientSid.iUid < aSecond.iClientSid.iUid )
+ {
+ orderValue = -1;
+ }
+
+ return orderValue;
+ }
+
+/**
+* Context loader information.
+*/
+NONSHARABLE_CLASS( TCFLoaderInfo )
+ {
+ public:
+
+ TCFLoaderInfo( CImplementationInformation& aImplementationInfo,
+ CCFContextSourceManager& aManager ):
+ iImplUid( aImplementationInfo.ImplementationUid() ),
+ iImplVersion( aImplementationInfo.Version() ),
+ iManager( aManager )
+ {
+ }
+
+ public:
+ TUid iImplUid;
+ TInt iImplVersion;
+ CCFContextSourceManager& iManager;
+ };
+
+/**
+* Context source information.
+*/
+NONSHARABLE_CLASS( TCFContextSourceInfo )
+ {
+ public:
+
+ TCFContextSourceInfo( CImplementationInformation& aImplInfo,
+ CCFContextSourcePlugIn* aPlugIn ):
+ iImplUid( aImplInfo.ImplementationUid() ), iImplVersion( aImplInfo.Version() ),
+ iPlugIn( aPlugIn ), iMissing( ETrue )
+ {
+ }
+
+ TCFContextSourceInfo( TUid aImplUid,
+ TInt aImplVersion,
+ CCFContextSourcePlugIn* aPlugIn ):
+ iImplUid( aImplUid ),
+ iImplVersion( aImplVersion ),
+ iPlugIn( aPlugIn ),
+ iMissing( ETrue )
+ {
+ }
+
+ public:
+
+ TUid iImplUid;
+ TInt iImplVersion;
+ CCFContextSourcePlugIn* iPlugIn;
+ TBool iMissing;
+ };
+
+// ============================= MEMBER FUNCTIONS =============================
+
+EXPORT_C CCFContextSourceManager* CCFContextSourceManager::NewL(
+ MCFExtendedContextInterface& aCF,
+ RFs& aFs )
+ {
+ FUNC_LOG;
+
+ CCFContextSourceManager* self =
+ CCFContextSourceManager::NewLC( aCF, aFs );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+EXPORT_C CCFContextSourceManager* CCFContextSourceManager::NewLC(
+ MCFExtendedContextInterface& aCF,
+ RFs& aFs )
+ {
+ FUNC_LOG;
+
+ CCFContextSourceManager* self =
+ new( ELeave ) CCFContextSourceManager( aCF, aFs );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+EXPORT_C CCFContextSourceManager::~CCFContextSourceManager()
+ {
+ FUNC_LOG;
+
+ iClientContextSources.Close();
+
+ // Delete plug-ins
+ TInt count = iPlugIns.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ CCFContextSourcePlugIn* plugIn = iPlugIns[i].iPlugIn;
+ ReleasePlugIn( plugIn );
+ }
+ iPlugIns.Close();
+ delete iSettingsManager;
+
+ iLoaders.ResetAndDestroy();
+ }
+
+CCFContextSourceManager::CCFContextSourceManager(
+ MCFExtendedContextInterface& aCF,
+ RFs& aFs ):
+ iCF( aCF ),
+ iFs( aFs )
+ {
+ FUNC_LOG;
+
+ // Nothing to do
+ }
+
+void CCFContextSourceManager::ConstructL()
+ {
+ FUNC_LOG;
+
+ iSettingsManager = CCFContextSourceSettingsManager::NewL( iFs );
+ }
+
+void CCFContextSourceManager::SetEventHandler( MCFStarterEventHandler& aEventHandler )
+ {
+ FUNC_LOG;
+ iEventHandler = &aEventHandler;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::InstallSettingL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCFContextSourceManager::InstallSettingL( RFile& aSettingFile,
+ const TUid& aContextSourceUid,
+ RThread& aClientThread )
+ {
+ FUNC_LOG;
+
+ // Get plugin.
+ MCFContextSourceUpgrade* sourceUpgrade = PlugInL( aContextSourceUid );
+
+ // Parse setting file.
+ CCFContextSourceSettingArray* settings
+ = CCFContextSourceSettingArray::NewLC(); // CLEANUP<< settings
+ RFile parseFile;
+ User::LeaveIfError( parseFile.Duplicate( aSettingFile ) );
+ // parseFile handle closed by the parser.
+ iSettingsManager->ParseSettingsL( parseFile, *settings );
+
+ // Check setting validity from plugin.
+ TInt err = sourceUpgrade->CheckValidity( aClientThread, *settings );
+ CleanupStack::PopAndDestroy( settings ); // CLEANUP>> settings
+ ERROR( err, "CCFContextSourceManager::InstallSettingL - Context source CheckSecurity for new settings failed" );
+ User::LeaveIfError( err );
+
+ // Copy the setting file.
+ CopySettingFileL( aSettingFile, aContextSourceUid, aClientThread );
+
+ // Read all settings and give them to the plugin.
+ CCFContextSourceSettingArray* settingArray
+ = PlugInSettingsL( aContextSourceUid );
+ // Ownership of settingArray is transferred to plugin.
+ sourceUpgrade->UpdateSettingsL( settingArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::UninstallSettingL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCFContextSourceManager::UninstallSettingL(
+ const TDesC& aSettingFilename,
+ const TUid& aContextSourceUid,
+ RThread& aClientThread )
+ {
+ FUNC_LOG;
+
+ // Get plugin.
+ MCFContextSourceUpgrade* sourceUpgrade = PlugInL( aContextSourceUid );
+
+ // Delete the setting file.
+ DeleteSettingFileL( aSettingFilename, aContextSourceUid, aClientThread );
+
+ // Read all settings and give them to the plugin.
+ CCFContextSourceSettingArray* settingArray
+ = PlugInSettingsL( aContextSourceUid );
+ // Ownership of settingArray is transferred to plugin.
+ sourceUpgrade->UpdateSettingsL( settingArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::UninstallSettingsL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCFContextSourceManager::UninstallSettingsL(
+ const TUid& aContextSourceUid,
+ RThread& aClientThread )
+ {
+ FUNC_LOG;
+
+ // Get plugin.
+ MCFContextSourceUpgrade* sourceUpgrade = PlugInL( aContextSourceUid );
+
+ // Delete all setting files installed by the client.
+ DeleteSettingFileL( KSettingExtension, aContextSourceUid, aClientThread );
+
+ // Read all settings and give them to the plugin.
+ CCFContextSourceSettingArray* settingArray
+ = PlugInSettingsL( aContextSourceUid );
+ // Ownership of settingArray is transferred to plugin.
+ sourceUpgrade->UpdateSettingsL( settingArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::HandleContextSourceCommandL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCFContextSourceManager::HandleContextSourceCommandL(
+ const CCFContextSourceCommand& aCommand )
+ {
+ FUNC_LOG;
+
+ const TUid sourceUid = aCommand.SourceUid();
+ // Find plugin.
+ CCFContextSourcePlugIn* plugIn = NULL;
+ for( TInt i = 0; i < iPlugIns.Count(); ++i )
+ {
+ if( iPlugIns[ i ].iImplUid == sourceUid )
+ {
+ plugIn = iPlugIns[ i ].iPlugIn;
+ break;
+ }
+ }
+
+ MCFContextSource* contextSource = NULL;
+ if ( plugIn )
+ {
+ // Check plugin's support for MCFContextSource extension.
+ contextSource = reinterpret_cast< MCFContextSource* >(
+ plugIn->Extension( KCFContextSourceInterfaceUid ) );
+ if ( !contextSource )
+ {
+ User::Leave( KErrExtensionNotSupported );
+ }
+ }
+ else
+ {
+ TLinearOrder< TCFClientContextSourceInfo > uidOrder(
+ ClientContextSourceInfoUidOrder );
+ TCFClientContextSourceInfo clientInfo;
+ clientInfo.iClientSid = sourceUid;
+ TInt pos = iClientContextSources.FindInOrder( clientInfo, uidOrder );
+ if ( pos == KErrNotFound )
+ {
+ User::Leave( KErrBadHandle );
+ }
+ contextSource = iClientContextSources[ pos ].iSource;
+ }
+
+ // Process source command
+ if ( contextSource )
+ {
+ contextSource->HandleCommand( aCommand );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::RegisterClientContextSource
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CCFContextSourceManager::RegisterClientContextSource(
+ MCFContextSource* aPublisher,
+ const TUid& aPublisherUid )
+ {
+ FUNC_LOG;
+
+ TLinearOrder< TCFClientContextSourceInfo > uidOrder(
+ ClientContextSourceInfoUidOrder );
+ TCFClientContextSourceInfo clientInfo( aPublisher, aPublisherUid );
+
+ TInt err = iClientContextSources.InsertInOrder( clientInfo, uidOrder );
+ if ( err == KErrAlreadyExists )
+ {
+ err = KErrNone;
+ }
+
+ ERROR( err, "CCFContextSourceManager::RegisterContextSourceClient - Failed" );
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::DeregisterClientContextSource
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCFContextSourceManager::DeregisterClientContextSource(
+ const MCFContextSource& aPublisher )
+ {
+ FUNC_LOG;
+
+ for ( TInt i = 0; i < iClientContextSources.Count(); ++i )
+ {
+ if ( &aPublisher == iClientContextSources[ i ].iSource )
+ {
+ iClientContextSources.Remove( i );
+ break; // Stop, no duplicate entries are allowed.
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::InitializePhaseL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::InitializePhaseL(
+ CCFPhaseBase::TCFPhaseId aPhase )
+ {
+ FUNC_LOG;
+
+ switch( aPhase )
+ {
+ case CCFPhaseBase::ECFDeviceStarting:
+ {
+ InitDeviceStartingPhaseL();
+ break;
+ }
+ case CCFPhaseBase::ECFLoadingPlugins:
+ {
+ InitLoadingPluginsPhaseL();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::UpdatePlugInsL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::UpdatePlugInsL()
+ {
+ FUNC_LOG;
+
+ // List all plugins
+ RImplInfoPtrArray implInfoArray;
+ CleanupResetAndDestroyPushL( implInfoArray );
+ REComSession::ListImplementationsL( KContextSourcePlugInInterface,
+ implInfoArray );
+ RemoveBlackListed( implInfoArray );
+
+ // Check if the update is install or uninstall based
+ TInt allCount = implInfoArray.Count();
+ TInt loadedCount = iPlugIns.Count();
+ INFO_1( "Found %d context source plug-in implementations from ecom", allCount );
+ INFO_1( "%d context source plug-ins currently loaded", loadedCount );
+
+ // Check if there were plugins installed
+ if( allCount >= loadedCount )
+ {
+ for( TInt i = iPlugIns.Count() - 1; i >= 0; i-- )
+ {
+ TCFContextSourceInfo& pluginInfo = iPlugIns[i];
+ for( TInt ii = 0; ii < implInfoArray.Count(); ii++ )
+ {
+ CImplementationInformation* implInfo = implInfoArray[ii];
+ if( implInfo->ImplementationUid() == pluginInfo.iImplUid )
+ {
+ TInt oldVer = pluginInfo.iImplVersion;
+ TInt newVer = implInfo->Version();
+
+ // Check if the version has increased
+ if( newVer > oldVer )
+ {
+ // Delete old plugin
+ ReleasePlugIn( pluginInfo.iPlugIn );
+ iPlugIns.Remove( i );
+
+ // Clean up garbage
+ REComSession::FinalClose();
+
+ // Load the new version
+ TRAPD( err, LoadPluginL( implInfo->ImplementationUid(), implInfo->Version() ) );
+ ERROR_3( err, "Upgrade of new version of context source plugin [%x], oldVer: [%d], newVer: [%d] failed",
+ implInfo->ImplementationUid().iUid, oldVer, newVer );
+ if( err == KErrNone )
+ {
+ INFO_3( "Upgraded new version of context source plugin [%x], oldVer: [%d], newVer: [%d]",
+ implInfo->ImplementationUid().iUid, oldVer, newVer );
+ }
+ }
+
+ delete implInfo;
+ implInfoArray.Remove( ii );
+ break;
+ }
+ }
+ }
+
+ // Check if the installed plugin was not an updgrade but a new plugin
+ for( TInt i = 0; i < implInfoArray.Count(); i++ )
+ {
+ CImplementationInformation* implInfo = implInfoArray[i];
+
+ // Prepare loaders
+ PrepareLoaderL( implInfo );
+ }
+ // Execute loaders
+ ExecuteLoaders();
+ }
+
+ // Check if there were plugins unistalled
+ else
+ {
+ for( TInt i = 0; i < iPlugIns.Count(); i++ )
+ {
+ TCFContextSourceInfo& pluginInfo = iPlugIns[i];
+ pluginInfo.iMissing = ETrue;
+ }
+
+ // Check that which plugins are missing
+ for( TInt i = 0; i < implInfoArray.Count(); i++ )
+ {
+ CImplementationInformation* implInfo = implInfoArray[i];
+ for( TInt i = 0; i < iPlugIns.Count(); i++ )
+ {
+ TCFContextSourceInfo& pluginInfo = iPlugIns[i];
+ if( pluginInfo.iImplUid == implInfo->ImplementationUid() )
+ {
+ pluginInfo.iMissing = EFalse;
+ break;
+ }
+ }
+ }
+
+ // Delete missing plugins
+ for( TInt i = iPlugIns.Count() - 1; i >= 0; i-- )
+ {
+ TCFContextSourceInfo& pluginInfo = iPlugIns[i];
+ if( pluginInfo.iMissing )
+ {
+ INFO_2( "Removed uninstalled context source plugin [%x], ver: [%d]",
+ pluginInfo.iImplUid.iUid, pluginInfo.iImplVersion );
+
+ ReleasePlugIn( pluginInfo.iPlugIn );
+ iPlugIns.Remove( i );
+
+ // Clean up garbage
+ REComSession::FinalClose();
+ }
+ }
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &implInfoArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::PrepareLoaderL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::PrepareLoaderL( CImplementationInformation* aImplementationInfo )
+ {
+ FUNC_LOG;
+
+ TCFLoaderInfo* loaderInfo = new(ELeave)TCFLoaderInfo( *aImplementationInfo, *this );
+ CleanupStack::PushL( loaderInfo );
+ TCallBack cb( LoaderCallBack, loaderInfo );
+ CAsyncCallBack* loader = new( ELeave ) CAsyncCallBack( cb, CActive::EPriorityStandard );
+ CleanupStack::PushL( loader );
+ iLoaders.AppendL( loader );
+ CleanupStack::Pop( loader );
+ CleanupStack::Pop( loaderInfo );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::ExecuteLoaders
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::ExecuteLoaders()
+ {
+ FUNC_LOG;
+
+ for( TInt i = 0; i < iLoaders.Count(); i++ )
+ {
+ CAsyncCallBack* loader = iLoaders[i];
+ loader->CallBack();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::LoaderCallBack
+// ---------------------------------------------------------------------------
+//
+TInt CCFContextSourceManager::LoaderCallBack( TAny* aLoaderInfo )
+ {
+ FUNC_LOG;
+
+ TCFLoaderInfo* loaderInfo = static_cast<TCFLoaderInfo*>( aLoaderInfo );
+ CCFContextSourceManager& manager = loaderInfo->iManager;
+
+ TRAPD( err, manager.LoadPluginL( loaderInfo->iImplUid,
+ loaderInfo->iImplVersion ));
+
+ if( err == KErrNone )
+ {
+ INFO_2( "Loaded context source plugin [%x], ver: [%d]",
+ loaderInfo->iImplUid.iUid, loaderInfo->iImplVersion );
+ }
+ else
+ {
+ ERROR_2( err, "Failed to load context source plugin [%x], ver: [%d]",
+ loaderInfo->iImplUid.iUid, loaderInfo->iImplVersion );
+ }
+
+ manager.iLoadedCount++;
+
+ if( manager.iLoadedCount == manager.iLoaders.Count() )
+ {
+ manager.iLoaders.ResetAndDestroy();
+ manager.iLoadedCount = 0;
+
+ if( manager.iEventHandler )
+ {
+ manager.iEventHandler->HandleEvent( MCFStarterEventHandler::EContextSourcePluginsLoaded );
+ }
+ }
+ delete loaderInfo;
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::CreateAndInitializePlugInL
+// ---------------------------------------------------------------------------
+//
+CCFContextSourcePlugIn* CCFContextSourceManager::CreateAndInitializePlugInL(
+ const TUid& aImplementationUid,
+ TContextSourceInitParams& aParams )
+ {
+ FUNC_LOG;
+
+ // Create plug-in
+ CCFContextSourcePlugIn* plugIn = CCFContextSourcePlugIn::NewL(
+ aImplementationUid,
+ &aParams );
+ CleanupStack::PushL( plugIn );
+
+ // Handle settings
+ CCFContextSourceSettingArray* settings
+ = PlugInSettingsL( aImplementationUid );
+
+ if ( settings->Count() )
+ {
+ // Forward settings to plug-in
+ // Plug-in takes ownership of the array.
+ plugIn->HandleSettingL( settings );
+ }
+ else
+ {
+ // Manager owns the array, cleanup now.
+ delete settings;
+ settings = NULL;
+ }
+
+ // Define context
+ plugIn->DefineContextsL();
+
+ // Initialize
+ plugIn->InitializeL();
+
+ // Cleanup
+ CleanupStack::Pop( plugIn );
+
+ return plugIn;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::InitDeviceStartingPhaseL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::InitDeviceStartingPhaseL()
+ {
+ FUNC_LOG;
+
+ // List all plugins
+ RImplInfoPtrArray implInfoArray;
+ CleanupResetAndDestroyPushL( implInfoArray );
+ REComSession::ListImplementationsL( KContextSourcePlugInInterface,
+ implInfoArray );
+
+ // Load context source manager configuration cenrep
+ CRepository* cenRep = CRepository::NewLC( KCRUidCFContextSourceConf );
+ TInt count = 0;
+ TInt err = cenRep->Get( KContextSourceNumberOfMandatoryPlugIns, count );
+ if( err == KErrNone && count )
+ {
+ INFO_1( "Found %d context source plug-in implementations from cenrep", count );
+ TUint32 key = KContextSourceNumberOfMandatoryPlugIns + 1;
+ for( TInt i = 0; i < count; i++ )
+ {
+ TInt uid = 0;
+
+ // Ignore first key
+ err = cenRep->Get( key + i, uid );
+ if( err == KErrNone && uid )
+ {
+ CImplementationInformation* info = NULL;
+ for( TInt ii = 0; ii < implInfoArray.Count(); ii++ )
+ {
+ info = implInfoArray[ii];
+ if( info->ImplementationUid() == TUid::Uid( uid ) )
+ {
+ break;
+ }
+ info = NULL;
+ }
+ if( info )
+ {
+ TRAPD( err, LoadPluginL( info->ImplementationUid(), info->Version() ) );
+ if( err == KErrNone )
+ {
+ INFO_2( "Loaded context source plugin [%x], ver: [%d]",
+ info->ImplementationUid().iUid, info->Version() );
+ }
+ else
+ {
+ ERROR_2( err, "Failed to load context source plugin [%x], ver: [%d]",
+ info->ImplementationUid().iUid, info->Version() );
+ }
+ }
+ }
+ else
+ {
+ INFO_2( "UID 0x%08x skipped, error code %d", uid, err );
+ }
+ }
+ }
+
+ // Clean up
+ CleanupStack::PopAndDestroy( cenRep );
+ CleanupStack::PopAndDestroy( &implInfoArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::InitLoadingPluginsPhaseL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::InitLoadingPluginsPhaseL()
+ {
+ FUNC_LOG;
+
+ UpdatePlugInsL();
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::LoadPluginL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::LoadPluginL( TUid aUid,
+ TInt aImplVersion )
+ {
+ FUNC_LOG;
+
+ INFO_2( "Loading context source plug-in with UID [%x], version [%d]",
+ aUid.iUid,
+ aImplVersion );
+ HEAP_2( "Before loading context source plug-in with UID [%x], version [%d]",
+ aUid.iUid,
+ aImplVersion );
+ TContextSourceInitParams initParams( static_cast<MCFContextInterface&>( iCF ) );
+ CCFContextSourcePlugIn* plugIn = NULL;
+ TRAPD( err, plugIn = CreateAndInitializePlugInL( aUid,
+ initParams ) );
+ if( err == KErrNone )
+ {
+ // Plug-in loaded succesfully, store it
+ TCFContextSourceInfo info( aUid, aImplVersion, plugIn );
+ TInt err = iPlugIns.Append( info );
+ if( err != KErrNone )
+ {
+ ERROR_1( err, "Context source plug-in: %x could not be appended in array",
+ aUid.iUid );
+ ReleasePlugIn( plugIn );
+ }
+ else
+ {
+ INFO_1( "Context source plug-in: %x succesfully loaded",
+ aUid.iUid );
+ }
+ }
+ else
+ {
+ ERROR_2( err, "Context source plug-in %x load error: %d",
+ aUid.iUid,
+ err );
+
+ err = AddToBlackList( aUid );
+ ERROR( err, "Failed to add UID to blacklist" );
+ }
+
+ HEAP_2( "After loading context source plug-in with UID [%x], version [%d]",
+ aUid.iUid,
+ aImplVersion );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::ConfigureRomSettingFolder
+// ---------------------------------------------------------------------------
+//
+TBool CCFContextSourceManager::ConfigureRomSettingFolder( TDes& aFile,
+ const TUid& aUid )
+ {
+ FUNC_LOG;
+
+ // Check rom
+ // '[12345678]' -> 'z:\private\10282BC4\Settings\12345678\'
+ aFile.Copy( KSettingsPathRom );
+ aFile.Append( aUid.Name().Mid(
+ KUIDNameStartPos,
+ KUIDNameEndPos ) );
+ aFile.Append( KFolderExt );
+
+ return BaflUtils::PathExists( iFs, aFile );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::ConfigureRamSettingFolder
+// ---------------------------------------------------------------------------
+//
+TBool CCFContextSourceManager::ConfigureRamSettingFolder( TDes& aFile,
+ const TUid& aUid )
+ {
+ FUNC_LOG;
+
+ // Check rom
+ // '[12345678]' -> 'c:\private\10282BC4\Settings\12345678\'
+ aFile.Copy( KSettingsPathRam );
+ aFile.Append( aUid.Name().Mid(
+ KUIDNameStartPos,
+ KUIDNameEndPos ) );
+ aFile.Append( KFolderExt );
+
+ return BaflUtils::PathExists( iFs, aFile );
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::ParsePlugInSettingsL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::ParsePlugInSettingsL( const TDesC& aFolder,
+ CCFContextSourceSettingArray& aSettings )
+ {
+ CDir* dirList = NULL;
+ TInt err = iFs.GetDir( aFolder,
+ KEntryAttMaskSupported,
+ ESortByName,
+ dirList );
+ if( err == KErrNone )
+ {
+ CleanupStack::PushL( dirList );
+ TInt count = dirList->Count();
+ INFO_1( "Found %d setting files", count );
+
+ HBufC* file = HBufC::NewLC( KMaxFileName );
+ TPtr filePtr = file->Des();
+ for( TInt i = 0; i < count; i++ )
+ {
+ // Configure full file path
+ filePtr.Copy( aFolder.Left(
+ aFolder.Length() - KSettingExtension().Length() ) );
+ filePtr.Append( (*dirList)[i].iName );
+ INFO_1( "Parsing setting file '%S'", &(*dirList)[i].iName );
+
+ // Parse settings
+ iSettingsManager->ParseSettingsL( filePtr, aSettings );
+ }
+
+ CleanupStack::PopAndDestroy( file );
+ CleanupStack::PopAndDestroy( dirList );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::PlugInSettingsL
+// ---------------------------------------------------------------------------
+//
+CCFContextSourceSettingArray* CCFContextSourceManager::PlugInSettingsL(
+ const TUid& aImplementationUid )
+ {
+ // Get settings for the plugin.
+ CCFContextSourceSettingArray* settings
+ = CCFContextSourceSettingArray::NewLC(); // CLEANUP<< settings
+ HBufC* settingFile = HBufC::NewLC( KMaxFileName ); // CLEANUP<< settingFile
+ TPtr settingFilePtr = settingFile->Des();
+ if( ConfigureRomSettingFolder( settingFilePtr, aImplementationUid ) )
+ {
+ INFO_1( "Found context source ROM setting folder '%S'", &settingFilePtr );
+ // Setting folder found, parse settings.
+ settingFilePtr.Append( KSettingExtension );
+ ParsePlugInSettingsL( settingFilePtr, *settings );
+ }
+
+ if( ConfigureRamSettingFolder( settingFilePtr, aImplementationUid ) )
+ {
+ INFO_1( "Found context source RAM setting folder '%S'", &settingFilePtr );
+ // Setting folder found, parse settings.
+ settingFilePtr.Append( KSettingExtension );
+ ParsePlugInSettingsL( settingFilePtr, *settings );
+ }
+
+ CleanupStack::PopAndDestroy( settingFile ); // CLEANUP>> settingFile
+ CleanupStack::Pop( settings ); // CLEANUP>> settings
+ return settings;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::PlugInL
+// ---------------------------------------------------------------------------
+//
+MCFContextSourceUpgrade* CCFContextSourceManager::PlugInL(
+ const TUid& aContextSourceUid ) const
+ {
+ FUNC_LOG;
+
+ // Find plugin.
+ CCFContextSourcePlugIn* plugIn = NULL;
+ for( TInt i = 0; i < iPlugIns.Count(); ++i )
+ {
+ if( iPlugIns[ i ].iImplUid == aContextSourceUid )
+ {
+ plugIn = iPlugIns[ i ].iPlugIn;
+ break;
+ }
+ }
+ if ( !plugIn )
+ {
+ User::Leave( KErrBadHandle );
+ }
+
+ // Check plugin's support for MCFContextSourceUpgrade extension.
+ MCFContextSourceUpgrade* contextSourceUpgrade =
+ ( MCFContextSourceUpgrade* )plugIn->Extension(
+ KCFContextSourceUpgradeUid );
+ if ( !contextSourceUpgrade )
+ {
+ User::Leave( KErrExtensionNotSupported );
+ }
+
+ return contextSourceUpgrade;
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::CopySettingFileL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::CopySettingFileL( const RFile& aSettingFile,
+ const TUid& aContextSourceUid,
+ RThread& aClientThread )
+ {
+ FUNC_LOG;
+
+ HBufC* settingFile = HBufC::NewLC( KMaxFileName ); // CLEANUP<< settingFile
+ TPtr settingFilePtr = settingFile->Des();
+
+ ConfigureRamSettingFolder( settingFilePtr, aContextSourceUid );
+
+ HBufC* filename = HBufC::NewLC( KMaxFileName ); // CLEANUP<< filename
+ TPtr filenamePtr = filename->Des();
+
+ User::LeaveIfError( aSettingFile.Name( filenamePtr ) );
+
+ TUid clientSid( aClientThread.SecureId() );
+ settingFilePtr.Append( clientSid.Name().Mid( KUIDNameStartPos,
+ KUIDNameEndPos ) );
+ settingFilePtr.Append( KUnderscore );
+ settingFilePtr.Append( filenamePtr );
+ BaflUtils::EnsurePathExistsL( iFs, settingFilePtr );
+
+ CleanupStack::PopAndDestroy( filename ); // CLEANUP>> filename
+
+ CFileMan* fileMan = CFileMan::NewL( iFs );
+ CleanupStack::PushL( fileMan ); // CLEANUP<< fileMan
+
+ TInt err = fileMan->Copy( aSettingFile, settingFilePtr );
+ ERROR( err, "CCFContextSourceManager::CopySettingFileL - Copying setting file failed" );
+ User::LeaveIfError( err );
+ TInt clearMask = KEntryAttReadOnly | KEntryAttHidden | KEntryAttSystem;
+ err = fileMan->Attribs( settingFilePtr, 0, clearMask, 0 );
+ User::LeaveIfError( err );
+
+ CleanupStack::PopAndDestroy( fileMan ); // CLEANUP>> fileMan
+ CleanupStack::PopAndDestroy( settingFile ); // CLEANUP>> settingFile
+ }
+
+// ---------------------------------------------------------------------------
+// CCFContextSourceManager::DeleteSettingFileL
+// ---------------------------------------------------------------------------
+//
+void CCFContextSourceManager::DeleteSettingFileL( const TDesC& aSettingFile,
+ const TUid& aContextSourceUid,
+ RThread& aClientThread )
+ {
+ FUNC_LOG;
+
+ HBufC* settingFile = HBufC::NewLC( KMaxFileName ); // CLEANUP<< settingFile
+ TPtr settingFilePtr = settingFile->Des();
+
+ ConfigureRamSettingFolder( settingFilePtr, aContextSourceUid );
+
+ TUid clientSid( aClientThread.SecureId() );
+ settingFilePtr.Append( clientSid.Name().Mid( KUIDNameStartPos,
+ KUIDNameEndPos ) );
+ settingFilePtr.Append( KUnderscore );
+ settingFilePtr.Append( aSettingFile );
+
+ TInt err = BaflUtils::DeleteFile( iFs, settingFilePtr );
+ ERROR( err, "CCFContextSourceManager::DeleteSettingFileL - Deleting setting file(s) failed" );
+ User::LeaveIfError( err );
+
+ CleanupStack::PopAndDestroy( settingFile ); // CLEANUP>> settingFile
+ }
+
+//------------------------------------------------------------------------------
+// CCFContextSourceManager::ReleasePlugIn
+//------------------------------------------------------------------------------
+//
+void CCFContextSourceManager::ReleasePlugIn( CCFContextSourcePlugIn*& aPlugIn )
+ {
+ FUNC_LOG;
+
+ // Deregister publisher
+ TAny* extension = aPlugIn->Extension( KCFContextSourceInterfaceUid );
+ if( extension )
+ {
+ MCFContextSource* contextSource =
+ reinterpret_cast<MCFContextSource*>( extension );
+ iCF.DeregisterPublisher( *contextSource );
+ }
+ // Unsubscribe all contexts if the plug-in is uninstalled
+ extension = aPlugIn->Extension( KCFSubscriptionListenerInterfaceUid );
+ if( extension )
+ {
+ MCFContextSubscriptionListener* interface =
+ static_cast<MCFContextSubscriptionListener*>( extension );
+ iCF.UnsubscribeContexts( *interface );
+ }
+ delete aPlugIn;
+ aPlugIn = NULL;
+ }