--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailcontacts/contactactionservice/src/cfsccontactactionpluginengine.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,460 @@
+/*
+* Copyright (c) 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: Implementation of the class CFscContactActionPluginEngine.
+*
+*/
+
+
+// INCLUDES
+#include "emailtrace.h"
+#include <e32std.h>
+
+#include "fsccontactactionserviceuids.hrh"
+#include "cfsccontactactionpluginengine.h"
+#include "cfscactionutils.h"
+#include "mfsccontactaction.h"
+#include "cfsccontactactionplugin.h"
+#include "tfsccontactactionqueryresult.h"
+#include "mfsccontactactionpluginengineobserver.h"
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CFscContactActionPluginEngine* CFscContactActionPluginEngine::NewL(
+ CVPbkContactManager& aContactManager )
+ {
+ FUNC_LOG;
+
+ CFscContactActionPluginEngine* self =
+ new ( ELeave ) CFscContactActionPluginEngine( aContactManager );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CFscContactActionPluginEngine::~CFscContactActionPluginEngine()
+ {
+ FUNC_LOG;
+ ReleasePlugins();
+ iActionPlugins.Close();
+ delete iActionUtils;
+ }
+
+// ---------------------------------------------------------------------------
+// Detect and load plugins.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::LoadPluginsL()
+ {
+ FUNC_LOG;
+
+ if ( iPluginsLoaded )
+ {
+ // Realease plugins before reloading
+ ReleasePlugins();
+ }
+
+ RImplInfoPtrArray implArray;
+ TUid pluginIfUid = { KFscContactActionPluginIfUid };
+ REComSession::ListImplementationsL( pluginIfUid, implArray );
+
+ //Create implementations
+ CFscContactActionPlugin* plugin = NULL;
+ TInt implArrayCount = implArray.Count();
+ for ( TInt i = 0; i < implArrayCount; i++ )
+ {
+ TRAPD( error,
+ {
+ plugin = CFscContactActionPlugin::NewL(
+ implArray[i]->ImplementationUid(), iPluginParams );
+ CleanupStack::PushL( plugin );
+ iActionPlugins.AppendL( plugin );
+ CleanupStack::Pop( plugin );
+ });
+ if ( error )
+ {
+
+ // Leave only if no memory. This way unstable plugins can not make
+ // service totaly unusable
+ if ( error == KErrNoMemory )
+ {
+ User::Leave( error );
+ }
+ }
+ plugin = NULL;
+ }
+
+ implArray.ResetAndDestroy();
+ iPluginsLoaded = ETrue;
+
+
+ }
+
+// ---------------------------------------------------------------------------
+// Release loaded plugins.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::ReleasePlugins()
+ {
+ FUNC_LOG;
+ iActionPlugins.ResetAndDestroy();
+ iPluginsLoaded = EFalse;
+ REComSession::FinalClose();
+ }
+
+// ---------------------------------------------------------------------------
+// Query state of plugins.
+// ---------------------------------------------------------------------------
+//
+TBool CFscContactActionPluginEngine::PluginsLoaded()
+ {
+ FUNC_LOG;
+ return iPluginsLoaded;
+ }
+
+// ---------------------------------------------------------------------------
+// Method for quering actions for contacts and groups.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::QueryActionsL(
+ CFscContactActionList& aActionList, MFscContactSet& aContactSet,
+ TBool aStopWhenOneActionFound, TUint64 aActionTypeFlags,
+ TInt aMinPriority, MFscContactActionPluginEngineObserver* aObserver )
+ {
+ FUNC_LOG;
+ switch ( iLastEvent )
+ {
+ case ECasEventIdle:
+ {
+ iActionList = &aActionList;
+ iContactSet = &aContactSet;
+ iStopWhenOneActionFound = aStopWhenOneActionFound;
+ iActionTypeFlags = aActionTypeFlags;
+ iMinPriority = aMinPriority;
+ iObserver = aObserver;
+ iCurrentActionPlugin = 0;
+ iCurrentAction = 0;
+ //iLastEvent = ECasEventBeforePriorityForContactSet;
+ // break; - no break here so we can go further when method
+ // called for 1st time.
+ }
+
+ case ECasEventBeforePriorityForContactSet:
+ {
+ TBool asyncStarted = EFalse;
+ // Loop plugins
+ while ( iCurrentActionPlugin < iActionPlugins.Count()
+ && !asyncStarted )
+ {
+ //Loop actions of single plugin
+ CFscContactActionPlugin* plugin =
+ iActionPlugins[ iCurrentActionPlugin ];
+
+ const CArrayFix<TUid>* actionList = plugin->ActionList();
+ TInt actionCount =
+ ( actionList != NULL ) ? actionList->Count() : 0;
+
+ while ( iCurrentAction < actionCount && !asyncStarted )
+ {
+ TUid uid = ( *actionList )[ iCurrentAction ];
+ TUint64 actionType = plugin->GetActionL( uid ).Type();
+ if ( aActionTypeFlags & actionType )
+ {
+ if( actionType == KFscAtComSendCalReq )
+ {
+ // skip adding "Send metting request" option
+ ++iCurrentAction;
+ continue;
+ }
+ asyncStarted = ETrue;
+ //Check action's priority for given contact set
+ plugin->PriorityForContactSetL( uid, aContactSet,
+ iContactActionQueryResult.iActionMenuVisibility,
+ iContactActionQueryResult.iOptionsMenuVisibility,
+ this );
+ }
+
+ if ( !asyncStarted )
+ {
+ ++iCurrentAction;
+ }
+ }
+
+ if ( !asyncStarted )
+ {
+ iCurrentAction = 0;
+ ++iCurrentActionPlugin;
+ }
+ }
+
+ if ( !asyncStarted )
+ {
+ // inform observer that method finished
+ iObserver->QueryActionsComplete();
+ iLastEvent = ECasEventIdle;
+ }
+
+ break;
+ }
+
+ case ECasEventAfterPriorityForContactSet:
+ {
+ // here we have to do the same as in
+ // ECasEventBeforePriorityForContactSet event
+ // because GetActionL returns const reference which we can't hold
+ // in class' data.
+ CFscContactActionPlugin* plugin =
+ iActionPlugins[ iCurrentActionPlugin ];
+
+ const CArrayFix<TUid>* actionList = plugin->ActionList();
+ TInt actionCount =
+ ( actionList != NULL ) ? actionList->Count() : 0;
+
+ TUid uid = ( *actionList )[ iCurrentAction ];
+ const MFscContactAction& action = plugin->GetActionL( uid );
+
+ // Add action if given minimum priority is exceeded
+ if ( action.Type() != KFscAtComSendCalReq &&
+ iContactActionQueryResult.iPriority >= aMinPriority &&
+ iContactActionQueryResult.iActionMenuVisibility.iVisibility !=
+ TFscContactActionVisibility::EFscActionHidden )
+ {
+ iContactActionQueryResult.iAction = &action;
+ iActionList->AppendL( iContactActionQueryResult );
+ }
+
+ // if only one action is needed we stop method execution
+ if ( iStopWhenOneActionFound && iActionList->Count() )
+ {
+ iLastEvent = ECasEventIdle;
+ iObserver->QueryActionsComplete();
+ }
+ else
+ {
+ // get next action
+ if ( iCurrentAction < actionCount )
+ {
+ iCurrentAction++;
+ }
+ else
+ {
+ // no more actions for current plugin
+ iCurrentAction = 0;
+ iCurrentActionPlugin++;
+ }
+
+ // if needed run for next plugin
+ if ( iCurrentActionPlugin < iActionPlugins.Count() )
+ {
+ iLastEvent = ECasEventBeforePriorityForContactSet;
+ QueryActionsL( *iActionList, *iContactSet,
+ iStopWhenOneActionFound, iActionTypeFlags,
+ iMinPriority, iObserver );
+ }
+ else
+ {
+ // inform observer that method finished
+ iLastEvent = ECasEventIdle;
+ iObserver->QueryActionsComplete();
+ }
+ }
+
+ break;
+ }
+
+ case ECasEventCanceledPriorityForContactSet:
+ {
+ // PriorityforContactSet was cancelled
+ iLastEvent = ECasEventIdle;
+ iCurrentActionPlugin = 0;
+ iCurrentAction = 0;
+ iActionList->Reset();
+ break;
+ }
+
+ default:
+ {
+ // we shouldn't be here
+ iObserver->QueryActionsFailed( KErrArgument );
+ iLastEvent = ECasEventIdle;
+ break;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels async method QueryActionsL.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::CancelQueryActions()
+ {
+ FUNC_LOG;
+ TInt err = KErrNone;
+ if ( iActionPlugins.Count() > iCurrentActionPlugin )
+ {
+ iActionPlugins[ iCurrentActionPlugin ]->CancelPriorityForContactSet();
+ iLastEvent = ECasEventCanceledPriorityForContactSet;
+ TRAP( err, QueryActionsL( *iActionList, *iContactSet,
+ iStopWhenOneActionFound, iActionTypeFlags, iMinPriority,
+ iObserver ) );
+ }
+
+ if ( err!= KErrNone )
+ {
+ iObserver->QueryActionsFailed( err );
+ iLastEvent = ECasEventIdle;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Called when PriorityForContactSetL method is complete.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::PriorityForContactSetComplete(
+ TInt aPriority )
+ {
+ FUNC_LOG;
+ iContactActionQueryResult.iPriority = aPriority;
+ iLastEvent = ECasEventAfterPriorityForContactSet;
+ TRAPD(err, QueryActionsL( *iActionList, *iContactSet,
+ iStopWhenOneActionFound, iActionTypeFlags, iMinPriority,
+ iObserver ) );
+ if ( err!= KErrNone )
+ {
+ iLastEvent = ECasEventIdle;
+ iObserver->QueryActionsFailed( err );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Called when PriorityForContactSetL method failed.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::PriorityForContactSetFailed(
+ TInt aError )
+ {
+ FUNC_LOG;
+ iLastEvent = ECasEventIdle;
+ iObserver->QueryActionsFailed( aError );
+ }
+
+// ---------------------------------------------------------------------------
+// Execute action. Aynchronous method.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::ExecuteL(
+ TUid aActionUid, MFscContactSet& aContactSet,
+ MFscContactActionPluginEngineObserver* aObserver )
+ {
+ FUNC_LOG;
+ iObserver = aObserver;
+
+ // Loop plugins
+ TBool found = EFalse;
+ for ( iCurrentActionPlugin = 0;
+ iCurrentActionPlugin < iActionPlugins.Count() && !found;
+ iCurrentActionPlugin++ )
+ {
+ // Loop actions
+ const CArrayFix<TUid>* actionList =
+ iActionPlugins[ iCurrentActionPlugin ]->ActionList();
+
+ TInt actionCount =
+ ( actionList != NULL) ? actionList->Count() : 0;
+ for ( TInt j = 0; j < actionCount && !found; j++)
+ {
+ if ( ( *actionList )[j] == aActionUid )
+ {
+ found = ETrue;
+
+ // Action found -> Execute
+ iActionPlugins[ iCurrentActionPlugin ]->ExecuteL(
+ aActionUid, aContactSet, this );
+
+ }
+ }// Loop actions
+ } // Loop plugins
+
+ if ( !found )
+ {
+ ExecuteFailed( KErrNotFound );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// Cancels async method ExecuteL.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::CancelExecute()
+ {
+ FUNC_LOG;
+ iActionPlugins[ iCurrentActionPlugin ]->CancelExecute();
+ }
+
+// ---------------------------------------------------------------------------
+// Called when ExecuteL method is complete.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::ExecuteComplete()
+ {
+ FUNC_LOG;
+ iObserver->ExecuteComplete();
+ }
+
+// ---------------------------------------------------------------------------
+// Called when ExecuteL method failed.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::ExecuteFailed( TInt aError )
+ {
+ FUNC_LOG;
+ iObserver->ExecuteFailed( aError );
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CFscContactActionPluginEngine::CFscContactActionPluginEngine(
+ CVPbkContactManager& aContactManager )
+ : iContactManager( aContactManager ),
+ iPluginParams( NULL ),
+ iLastEvent( ECasEventIdle )
+ {
+ FUNC_LOG;
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionPluginEngine::ConstructL()
+ {
+ FUNC_LOG;
+ iActionUtils = CFscActionUtils::NewL( iContactManager );
+ iPluginParams = TFscContactActionPluginParams( iActionUtils );
+ }
+