diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfoperationpluginservices/cfoperationpluginmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/cfoperationpluginservices/cfoperationpluginmanager.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,561 @@ +/* +* Copyright (c) 2008-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 +#include +#include + +#include "cfoperationpluginmanager.h" +#include "ContextFrameworkPrivateCRKeys.h" +#include "cfoperationplugin.h" +#include "cfoperationservices.h" +#include "cftrace.h" +#include "CFScriptEngineInterface.h" + +// ============================= LOCAL FUNCTIONS ============================== + +/** +* Clenup operation for RImplInfoPtrArray +*/ +LOCAL_C void CleanUpImplInfoArray( TAny* aParams ) + { + RImplInfoPtrArray* array = static_cast( aParams ); + array->ResetAndDestroy(); + } + +/** +* Push operations +*/ +LOCAL_C void CleanupResetAndDestroyPushL( RImplInfoPtrArray& aArray ) + { + TCleanupItem item( CleanUpImplInfoArray, &aArray ); + CleanupStack::PushL( item ); + } + +/** +* Operation plug-in information. +*/ +NONSHARABLE_CLASS( TCFOperationPluginInfo ) + { + public: + + TCFOperationPluginInfo( CImplementationInformation& aImplInfo, + CCFOperationPlugIn* aPlugIn ): + iImplUid( aImplInfo.ImplementationUid() ), + iImplVersion( aImplInfo.Version() ), + iMissing( EFalse ), + iPlugIn( aPlugIn ) + { + } + + public: + + TUid iImplUid; + TInt iImplVersion; + TBool iMissing; + CCFOperationPlugIn* iPlugIn; + }; + +// ============================= MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::NewL +// --------------------------------------------------------------------------- +// +EXPORT_C CCFOperationPluginManager* CCFOperationPluginManager::NewL( + MCFScriptEngineInterface& aScriptEngine ) + { + FUNC_LOG; + + CCFOperationPluginManager* self = + CCFOperationPluginManager::NewLC( aScriptEngine ); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::NewLC +// --------------------------------------------------------------------------- +// +EXPORT_C CCFOperationPluginManager* CCFOperationPluginManager::NewLC( + MCFScriptEngineInterface& aScriptEngine ) + { + FUNC_LOG; + + CCFOperationPluginManager* self = + new( ELeave ) CCFOperationPluginManager( aScriptEngine ); + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::~CCFOperationPluginManager +// --------------------------------------------------------------------------- +// +EXPORT_C CCFOperationPluginManager::~CCFOperationPluginManager() + { + FUNC_LOG; + + // Delete plug-ins + TInt count = iPlugIns.Count(); + for( TInt i = 0; i < count; i++ ) + { + delete iPlugIns[i].iPlugIn; + } + iPlugIns.Close(); + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::CCFOperationPluginManager +// --------------------------------------------------------------------------- +// +CCFOperationPluginManager::CCFOperationPluginManager( + MCFScriptEngineInterface& aScriptEngine ): + iScriptEngine( aScriptEngine ) + { + FUNC_LOG; + + // Nothing to do + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::ConstructL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::ConstructL() + { + FUNC_LOG; + + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::InitializePhaseL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::InitializePhaseL( + CCFPhaseBase::TCFPhaseId aPhase ) + { + FUNC_LOG; + + switch( aPhase ) + { + case CCFPhaseBase::ECFDeviceStarting: + { + InitDeviceStartingPhaseL(); + break; + } + case CCFPhaseBase::ECFLoadingPlugins: + { + InitLoadingPluginsPhaseL(); + break; + } + default: + { + break; + } + } + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::SetEventHandler +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::SetEventHandler( MCFStarterEventHandler& /*aEventHandler*/ ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::CreateAndInitializePlugInL +// --------------------------------------------------------------------------- +// +CCFOperationPlugIn* CCFOperationPluginManager::CreateAndInitializePlugInL( + const TUid& aImplementationUid, TOperationPluginInitParams& aParams ) + { + FUNC_LOG; + + // Create plug-in + CCFOperationPlugIn* plugIn = CCFOperationPlugIn::NewL( + aImplementationUid, + &aParams ); + CleanupStack::PushL( plugIn ); + + // Cleanup + CleanupStack::Pop( plugIn ); + + return plugIn; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::InitDeviceStartingPhaseL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::InitDeviceStartingPhaseL() + { + FUNC_LOG; + + INFO( "Checking plug-ins in [Init Device Starting] phase." ); + UpdatePlugInsL(); + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::InitLoadingPluginsPhaseL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::InitLoadingPluginsPhaseL() + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::LoadPluginL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::LoadPluginL( + CImplementationInformation& aImplInfo ) + { + FUNC_LOG; + + INFO_2( "Loading operation plug-in with UID [%x], version [%d]", + aImplInfo.ImplementationUid().iUid, aImplInfo.Version() ); + + HEAP_2( "Before loading operation plug-in with UID [%x], version [%d]", + aImplInfo.ImplementationUid().iUid, aImplInfo.Version() ); + + TOperationPluginInitParams initParams; + CCFOperationPlugIn* plugIn = NULL; + TRAPD( err, plugIn = CreateAndInitializePlugInL( + aImplInfo.ImplementationUid(), + initParams ) ); + if( err == KErrNone ) + { + // Plug-in loaded succesfully, store it + TCFOperationPluginInfo info( aImplInfo, plugIn ); + TInt err = iPlugIns.Append( info ); + if( err != KErrNone ) + { + ERROR_1( err, "Operation plug-in: [%x] could not be appended in array", + aImplInfo.ImplementationUid().iUid ); + delete plugIn; + plugIn = NULL; + } + else + { + INFO_1( "Operation plug-in: [%x] succesfully loaded", + aImplInfo.ImplementationUid().iUid ); + } + } + else + { + ERROR_2( err, "Operation plug-in [%x] load error: [%d]", + aImplInfo.ImplementationUid().iUid, err ); + + err = AddToBlackList( aImplInfo.ImplementationUid() ); + ERROR( err, "Failed to add UID to blacklist" ); + } + + HEAP_2( "After loading operation plug-in with UID [%x], version [%d]", + aImplInfo.ImplementationUid().iUid, aImplInfo.Version() ); + } + + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::UpdatePlugInsL +// --------------------------------------------------------------------------- +// +void CCFOperationPluginManager::UpdatePlugInsL() + { + FUNC_LOG; + + // List all plugins + RImplInfoPtrArray implInfoArray; + CleanupResetAndDestroyPushL( implInfoArray ); + REComSession::ListImplementationsL( KOperationPlugInInterface, + implInfoArray ); + RemoveBlackListed( implInfoArray ); + + // Check if the update is install or uninstall based + TInt allCount = implInfoArray.Count(); + TInt loadedCount = iPlugIns.Count(); + INFO_1( "Found %d operation plug-in implementations from ecom", allCount ); + INFO_1( "%d operation plug-ins currently loaded", loadedCount ); + + // Check if there were plugins installed + if( allCount >= loadedCount ) + { + for( TInt i = iPlugIns.Count() - 1; i >= 0; i-- ) + { + TCFOperationPluginInfo& 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 ) + { + // Remove scripts which have a dependency to the provider + // which is being deleted + TInt err = iScriptEngine.RemoveScriptByProviderUid( + pluginInfo.iImplUid, ETrue ); + INFO_2( "Remove script by provider [%x] completed with code [%d]", + pluginInfo.iImplUid.iUid, err ); + + // Delete old plugin + ReleasePlugIn( pluginInfo.iPlugIn ); + iPlugIns.Remove( i ); + + // Clean up old implementation + REComSession::FinalClose(); + + // Load the new version + TRAP( err, LoadPluginL( *implInfo ) ); + ERROR_3( err, "Upgrade of new version of operation plugin [%x], oldVer: [%d], newVer: [%d] failed", + implInfo->ImplementationUid().iUid, oldVer, newVer ); + if( err == KErrNone ) + { + INFO_3( "Upgraded new version of operation plugin [%x], oldVer: [%d], newVer: [%d]", + implInfo->ImplementationUid().iUid, oldVer, newVer ); + + // Rollback removed scripts + iScriptEngine.RollbackScripts(); + } + } + + 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]; + TRAPD( err, LoadPluginL( *implInfo ) ); + if( err == KErrNone ) + { + INFO_2( "Loaded operation plugin [%x], ver: [%d]", + implInfo->ImplementationUid().iUid, implInfo->Version() ); + } + else + { + ERROR_2( err, "Failed to load operation plugin [%x], ver: [%d]", + implInfo->ImplementationUid().iUid, implInfo->Version() ); + } + } + } + + // Check if there were plugins unistalled + else + { + for( TInt i = 0; i < iPlugIns.Count(); i++ ) + { + TCFOperationPluginInfo& 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++ ) + { + TCFOperationPluginInfo& pluginInfo = iPlugIns[i]; + if( pluginInfo.iImplUid == implInfo->ImplementationUid() ) + { + pluginInfo.iMissing = EFalse; + break; + } + } + } + + // Delete missing plugins + for( TInt i = iPlugIns.Count() - 1; i >= 0; i-- ) + { + TCFOperationPluginInfo& pluginInfo = iPlugIns[i]; + if( pluginInfo.iMissing ) + { + // Remove scripts which have a dependency to the provider + // which is being deleted + TInt err = iScriptEngine.RemoveScriptByProviderUid( + pluginInfo.iImplUid, ETrue ); + INFO_2( "Remove script by provider [%x] completed with code [%d]", + pluginInfo.iImplUid.iUid, err ); + + // Release plug-in + ReleasePlugIn( pluginInfo.iPlugIn ); + INFO_2( "Removed uninstalled operation plugin [%x], ver: [%d]", + pluginInfo.iImplUid.iUid, pluginInfo.iImplVersion ); + iPlugIns.Remove( i ); + + // Clean up old implementation + REComSession::FinalClose(); + + // Rollback removed scripts since we might have uninstalled + // plug-in which original version is in rom + iScriptEngine.RollbackScripts(); + } + } + } + + // Cleanup + CleanupStack::PopAndDestroy( &implInfoArray ); + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::ParseScriptRootL +// --------------------------------------------------------------------------- +// +CCFScriptRoot* CCFOperationPluginManager::ParseScriptRootL( + CCFOperationNode* aParent, + CMDXMLNode& aNode, + MCFOperationServices& aOperationServices, + TUid& aUid ) + { + CCFScriptRoot* root = DoParseScriptRootL( + aParent, aNode, aOperationServices, aUid ); + if ( root ) + { + return root; + } + + // Operation not found, check new plugins. + UpdatePlugInsL(); + + root = DoParseScriptRootL( + aParent, aNode, aOperationServices, aUid ); + if ( root ) + { + return root; + } + + // Generate error info to log. + + return NULL; + } + +// --------------------------------------------------------------------------- +// CCFOperationPluginManager::ParseL +// --------------------------------------------------------------------------- +// +CCFOperationNode* CCFOperationPluginManager::ParseL( CCFOperationNode* aParent, + CMDXMLNode& aDOMNode, + MCFOperationServices& aOperationServices, + TUid& aUid ) + { + CCFOperationNode* node = DoParseL( + aParent, aDOMNode, aOperationServices, aUid ); + if ( node ) + { + return node; + } + + // Operation not found, check new plugins. + UpdatePlugInsL(); + + node = DoParseL( + aParent, aDOMNode, aOperationServices, aUid ); + if ( node ) + { + return node; + } + + // Generate error info to log. + + return NULL; + } + +//------------------------------------------------------------------------------ +// CCFOperationPluginManager::ReleasePlugIn +//------------------------------------------------------------------------------ +// +void CCFOperationPluginManager::ReleasePlugIn( CCFOperationPlugIn*& aPlugIn ) + { + FUNC_LOG; + + delete aPlugIn; + aPlugIn = NULL; + } + +//------------------------------------------------------------------------------ +// CCFOperationPluginManager::DoParseL +//------------------------------------------------------------------------------ +// +CCFOperationNode* CCFOperationPluginManager::DoParseL( CCFOperationNode* aParent, + CMDXMLNode& aDOMNode, + MCFOperationServices& aOperationServices, + TUid& aUid ) + { + FUNC_LOG; + + CCFOperationNode* node = NULL; + for ( TInt i = 0; i < iPlugIns.Count(); i++ ) + { + CCFOperationPlugIn* plugin = iPlugIns[ i ].iPlugIn; + node = plugin->ParseL( + aParent, aDOMNode, aOperationServices ); + if( node ) + { + // Node found - break + aUid = iPlugIns[i].iImplUid; + break; + } + } + + return node; + } + +//------------------------------------------------------------------------------ +// CCFOperationPluginManager::DoParseScriptRootL +//------------------------------------------------------------------------------ +// +CCFScriptRoot* CCFOperationPluginManager::DoParseScriptRootL( + CCFOperationNode* aParent, + CMDXMLNode& aDOMNode, + MCFOperationServices& aOperationServices, + TUid& aUid ) + { + FUNC_LOG; + + CCFScriptRoot* root = NULL; + for ( TInt i = 0; i < iPlugIns.Count(); i++ ) + { + CCFOperationPlugIn* plugin = iPlugIns[ i ].iPlugIn; + root = plugin->ParseScriptRootL( + aParent, aDOMNode, aOperationServices ); + if( root ) + { + // Root found - break + aUid = iPlugIns[i].iImplUid; + break; + } + } + + return root; + } + +// End of file