emailcontacts/contactactionservice/src/cfsccontactactionpluginengine.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2008 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:  Implementation of the class CFscContactActionPluginEngine.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include "emailtrace.h"
       
    21 #include <e32std.h>
       
    22 
       
    23 #include "fsccontactactionserviceuids.hrh"
       
    24 #include "cfsccontactactionpluginengine.h"
       
    25 #include "cfscactionutils.h"
       
    26 #include "mfsccontactaction.h"
       
    27 #include "cfsccontactactionplugin.h"
       
    28 #include "tfsccontactactionqueryresult.h"
       
    29 #include "mfsccontactactionpluginengineobserver.h"
       
    30 
       
    31 // ======== LOCAL FUNCTIONS ========
       
    32 
       
    33 // ======== MEMBER FUNCTIONS ========
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // Two-phased constructor.
       
    37 // ---------------------------------------------------------------------------
       
    38 //
       
    39 CFscContactActionPluginEngine* CFscContactActionPluginEngine::NewL(
       
    40     CVPbkContactManager& aContactManager )
       
    41     {
       
    42     FUNC_LOG;
       
    43 
       
    44     CFscContactActionPluginEngine* self = 
       
    45         new ( ELeave ) CFscContactActionPluginEngine( aContactManager );
       
    46     CleanupStack::PushL( self );
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop( self );
       
    49         
       
    50     return self;
       
    51     }
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // Destructor.
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 CFscContactActionPluginEngine::~CFscContactActionPluginEngine()
       
    58     {
       
    59     FUNC_LOG;
       
    60     ReleasePlugins();
       
    61     iActionPlugins.Close();
       
    62     delete iActionUtils;
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // Detect and load plugins.
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 void CFscContactActionPluginEngine::LoadPluginsL()
       
    70     {
       
    71     FUNC_LOG;
       
    72     
       
    73     if ( iPluginsLoaded )
       
    74         {
       
    75         // Realease plugins before reloading
       
    76         ReleasePlugins();
       
    77         }
       
    78         
       
    79     RImplInfoPtrArray implArray;
       
    80     TUid pluginIfUid = { KFscContactActionPluginIfUid };
       
    81     REComSession::ListImplementationsL( pluginIfUid, implArray );
       
    82         
       
    83     //Create implementations
       
    84     CFscContactActionPlugin* plugin = NULL;
       
    85     TInt implArrayCount = implArray.Count();
       
    86     for ( TInt i = 0; i < implArrayCount; i++ )
       
    87         {
       
    88         TRAPD( error,
       
    89             {
       
    90             plugin = CFscContactActionPlugin::NewL( 
       
    91                 implArray[i]->ImplementationUid(), iPluginParams );
       
    92             CleanupStack::PushL( plugin );
       
    93             iActionPlugins.AppendL( plugin );    
       
    94             CleanupStack::Pop( plugin );
       
    95             });
       
    96         if ( error )
       
    97             {
       
    98                      
       
    99             // Leave only if no memory. This way unstable plugins can not make 
       
   100             // service totaly unusable
       
   101             if ( error == KErrNoMemory )
       
   102                 {
       
   103                 User::Leave( error );
       
   104                 }
       
   105             }
       
   106         plugin = NULL;
       
   107         }
       
   108         
       
   109     implArray.ResetAndDestroy();
       
   110     iPluginsLoaded = ETrue;
       
   111     
       
   112     
       
   113     }
       
   114 
       
   115 // ---------------------------------------------------------------------------
       
   116 // Release loaded plugins.
       
   117 // ---------------------------------------------------------------------------
       
   118 //
       
   119 void CFscContactActionPluginEngine::ReleasePlugins()
       
   120     {
       
   121 	FUNC_LOG;
       
   122     iActionPlugins.ResetAndDestroy();
       
   123     iPluginsLoaded = EFalse;
       
   124     REComSession::FinalClose();
       
   125     }
       
   126     
       
   127 // ---------------------------------------------------------------------------
       
   128 // Query state of plugins.
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 TBool CFscContactActionPluginEngine::PluginsLoaded()
       
   132     {
       
   133 	FUNC_LOG;
       
   134     return iPluginsLoaded;
       
   135     }    
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // Method for quering actions for contacts and groups.
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 void CFscContactActionPluginEngine::QueryActionsL( 
       
   142     CFscContactActionList& aActionList, MFscContactSet& aContactSet,
       
   143     TBool aStopWhenOneActionFound, TUint64 aActionTypeFlags, 
       
   144     TInt aMinPriority, MFscContactActionPluginEngineObserver* aObserver )
       
   145     {
       
   146 	FUNC_LOG;
       
   147     switch ( iLastEvent )
       
   148         {
       
   149         case ECasEventIdle:
       
   150             {
       
   151             iActionList = &aActionList;
       
   152             iContactSet = &aContactSet;
       
   153             iStopWhenOneActionFound = aStopWhenOneActionFound;
       
   154             iActionTypeFlags = aActionTypeFlags; 
       
   155             iMinPriority = aMinPriority;
       
   156             iObserver = aObserver;
       
   157             iCurrentActionPlugin = 0;
       
   158             iCurrentAction = 0;
       
   159             //iLastEvent = ECasEventBeforePriorityForContactSet;
       
   160             // break; - no break here so we can go further when method 
       
   161             // called for 1st time.
       
   162             }
       
   163         
       
   164         case ECasEventBeforePriorityForContactSet:
       
   165             {
       
   166             TBool asyncStarted = EFalse;
       
   167             // Loop plugins
       
   168             while ( iCurrentActionPlugin < iActionPlugins.Count() 
       
   169                     && !asyncStarted )
       
   170                 {
       
   171                 //Loop actions of single plugin
       
   172                 CFscContactActionPlugin* plugin = 
       
   173                     iActionPlugins[ iCurrentActionPlugin ];
       
   174                 
       
   175                 const CArrayFix<TUid>* actionList = plugin->ActionList();
       
   176                 TInt actionCount = 
       
   177                     ( actionList != NULL ) ? actionList->Count() : 0;
       
   178                 
       
   179                 while ( iCurrentAction < actionCount && !asyncStarted )
       
   180                     {
       
   181                     TUid uid = ( *actionList )[ iCurrentAction ];
       
   182                     TUint64 actionType = plugin->GetActionL( uid ).Type();
       
   183                     if ( aActionTypeFlags & actionType )
       
   184                         { 
       
   185                         if( actionType == KFscAtComSendCalReq )
       
   186                             {
       
   187                             // skip adding "Send metting request" option
       
   188                             ++iCurrentAction;
       
   189                             continue;
       
   190                             }
       
   191                         asyncStarted = ETrue;
       
   192                         //Check action's priority for given contact set
       
   193                         plugin->PriorityForContactSetL( uid, aContactSet,
       
   194                             iContactActionQueryResult.iActionMenuVisibility,
       
   195                             iContactActionQueryResult.iOptionsMenuVisibility, 
       
   196                             this );
       
   197                         }
       
   198                     
       
   199                     if ( !asyncStarted )
       
   200                         {
       
   201                         ++iCurrentAction;
       
   202                         }
       
   203                     }
       
   204                 
       
   205                 if ( !asyncStarted )
       
   206                     {
       
   207                     iCurrentAction = 0;
       
   208                     ++iCurrentActionPlugin;
       
   209                     }
       
   210                 }
       
   211             
       
   212             if ( !asyncStarted )
       
   213                 {
       
   214                 // inform observer that method finished
       
   215                 iObserver->QueryActionsComplete();
       
   216                 iLastEvent = ECasEventIdle;
       
   217                 }
       
   218             
       
   219             break;
       
   220             }
       
   221             
       
   222         case ECasEventAfterPriorityForContactSet:
       
   223             {
       
   224             // here we have to do the same as in 
       
   225             // ECasEventBeforePriorityForContactSet event
       
   226             // because GetActionL returns const reference which we can't hold 
       
   227             // in class' data.
       
   228             CFscContactActionPlugin* plugin = 
       
   229                 iActionPlugins[ iCurrentActionPlugin ];
       
   230             
       
   231             const CArrayFix<TUid>* actionList = plugin->ActionList();
       
   232             TInt actionCount = 
       
   233                 ( actionList != NULL ) ? actionList->Count() : 0;
       
   234             
       
   235             TUid uid = ( *actionList )[ iCurrentAction ];
       
   236             const MFscContactAction& action = plugin->GetActionL( uid );
       
   237             
       
   238             // Add action if given minimum priority is exceeded
       
   239             if ( action.Type() != KFscAtComSendCalReq &&
       
   240                  iContactActionQueryResult.iPriority >= aMinPriority &&
       
   241                  iContactActionQueryResult.iActionMenuVisibility.iVisibility != 
       
   242                  TFscContactActionVisibility::EFscActionHidden )
       
   243                 {
       
   244                 iContactActionQueryResult.iAction = &action;
       
   245                 iActionList->AppendL( iContactActionQueryResult );
       
   246                 }
       
   247             
       
   248             // if only one action is needed we stop method execution
       
   249             if ( iStopWhenOneActionFound && iActionList->Count() )
       
   250                 {
       
   251                 iLastEvent = ECasEventIdle;
       
   252                 iObserver->QueryActionsComplete();
       
   253                 }
       
   254             else
       
   255                 {
       
   256                 // get next action
       
   257                 if ( iCurrentAction < actionCount )
       
   258                     {
       
   259                     iCurrentAction++;
       
   260                     }
       
   261                 else
       
   262                     {
       
   263                     // no more actions for current plugin
       
   264                     iCurrentAction = 0;
       
   265                     iCurrentActionPlugin++;
       
   266                     }
       
   267                 
       
   268                 // if needed run for next plugin
       
   269                 if ( iCurrentActionPlugin < iActionPlugins.Count() )
       
   270                     {
       
   271                     iLastEvent = ECasEventBeforePriorityForContactSet;
       
   272                     QueryActionsL( *iActionList, *iContactSet, 
       
   273                         iStopWhenOneActionFound, iActionTypeFlags, 
       
   274                         iMinPriority, iObserver );
       
   275                     }
       
   276                 else
       
   277                     {
       
   278                     // inform observer that method finished
       
   279                     iLastEvent = ECasEventIdle;
       
   280                     iObserver->QueryActionsComplete();
       
   281                     }
       
   282                 }
       
   283                         
       
   284             break;
       
   285             }
       
   286             
       
   287         case ECasEventCanceledPriorityForContactSet:
       
   288             {
       
   289             // PriorityforContactSet was cancelled
       
   290             iLastEvent = ECasEventIdle;
       
   291             iCurrentActionPlugin = 0;
       
   292             iCurrentAction = 0;
       
   293             iActionList->Reset();
       
   294             break;
       
   295             }
       
   296             
       
   297         default:
       
   298             {
       
   299             // we shouldn't be here
       
   300             iObserver->QueryActionsFailed( KErrArgument );
       
   301             iLastEvent = ECasEventIdle;
       
   302             break;
       
   303             }
       
   304         }
       
   305     }
       
   306 
       
   307 // ---------------------------------------------------------------------------
       
   308 // Cancels async method QueryActionsL.
       
   309 // ---------------------------------------------------------------------------
       
   310 //
       
   311 void CFscContactActionPluginEngine::CancelQueryActions()
       
   312     {
       
   313 	FUNC_LOG;
       
   314     TInt err = KErrNone;
       
   315     if ( iActionPlugins.Count() > iCurrentActionPlugin )
       
   316         {
       
   317         iActionPlugins[ iCurrentActionPlugin ]->CancelPriorityForContactSet();
       
   318         iLastEvent = ECasEventCanceledPriorityForContactSet;
       
   319         TRAP( err, QueryActionsL( *iActionList, *iContactSet, 
       
   320                     iStopWhenOneActionFound, iActionTypeFlags, iMinPriority, 
       
   321                     iObserver ) );        
       
   322         }
       
   323     
       
   324     if ( err!= KErrNone )
       
   325         {
       
   326         iObserver->QueryActionsFailed( err );
       
   327         iLastEvent = ECasEventIdle;
       
   328         }
       
   329     }
       
   330 
       
   331 // ---------------------------------------------------------------------------
       
   332 // Called when PriorityForContactSetL method is complete.
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 void CFscContactActionPluginEngine::PriorityForContactSetComplete( 
       
   336     TInt aPriority )
       
   337     {
       
   338 	FUNC_LOG;
       
   339     iContactActionQueryResult.iPriority = aPriority;
       
   340     iLastEvent = ECasEventAfterPriorityForContactSet;
       
   341     TRAPD(err, QueryActionsL( *iActionList, *iContactSet, 
       
   342             iStopWhenOneActionFound, iActionTypeFlags, iMinPriority, 
       
   343             iObserver ) );
       
   344     if ( err!= KErrNone )
       
   345     	{
       
   346     	iLastEvent = ECasEventIdle;
       
   347     	iObserver->QueryActionsFailed( err );
       
   348     	}
       
   349     }
       
   350 
       
   351 // ---------------------------------------------------------------------------
       
   352 // Called when PriorityForContactSetL method failed.
       
   353 // ---------------------------------------------------------------------------
       
   354 //
       
   355 void CFscContactActionPluginEngine::PriorityForContactSetFailed( 
       
   356     TInt aError )
       
   357     {
       
   358 	FUNC_LOG;
       
   359     iLastEvent = ECasEventIdle;
       
   360     iObserver->QueryActionsFailed( aError );
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // Execute action. Aynchronous method.
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CFscContactActionPluginEngine::ExecuteL( 
       
   368     TUid aActionUid, MFscContactSet& aContactSet,
       
   369     MFscContactActionPluginEngineObserver* aObserver )
       
   370     {
       
   371 	FUNC_LOG;
       
   372     iObserver = aObserver;
       
   373         
       
   374     // Loop plugins
       
   375     TBool found = EFalse;
       
   376     for ( iCurrentActionPlugin = 0; 
       
   377           iCurrentActionPlugin < iActionPlugins.Count() && !found; 
       
   378           iCurrentActionPlugin++ )
       
   379         {
       
   380         // Loop actions
       
   381         const CArrayFix<TUid>* actionList = 
       
   382             iActionPlugins[ iCurrentActionPlugin ]->ActionList();
       
   383         
       
   384         TInt actionCount = 
       
   385             ( actionList != NULL) ? actionList->Count() : 0;
       
   386         for ( TInt j = 0; j < actionCount && !found; j++)
       
   387             {
       
   388             if ( ( *actionList )[j] == aActionUid )
       
   389                 {
       
   390                 found = ETrue;
       
   391                 
       
   392                 // Action found -> Execute
       
   393                 iActionPlugins[ iCurrentActionPlugin ]->ExecuteL( 
       
   394                     aActionUid, aContactSet, this );
       
   395                     
       
   396                 }
       
   397             }// Loop actions
       
   398         } // Loop plugins
       
   399         
       
   400     if ( !found )
       
   401         {
       
   402         ExecuteFailed( KErrNotFound );
       
   403         }
       
   404         
       
   405     }
       
   406 
       
   407 // ---------------------------------------------------------------------------
       
   408 // Cancels async method ExecuteL.
       
   409 // ---------------------------------------------------------------------------
       
   410 //
       
   411 void CFscContactActionPluginEngine::CancelExecute()
       
   412     {
       
   413 	FUNC_LOG;
       
   414     iActionPlugins[ iCurrentActionPlugin ]->CancelExecute();
       
   415     }
       
   416 
       
   417 // ---------------------------------------------------------------------------
       
   418 // Called when ExecuteL method is complete.
       
   419 // ---------------------------------------------------------------------------
       
   420 //
       
   421 void CFscContactActionPluginEngine::ExecuteComplete()
       
   422     {
       
   423 	FUNC_LOG;
       
   424     iObserver->ExecuteComplete();
       
   425     }
       
   426        
       
   427 // ---------------------------------------------------------------------------
       
   428 // Called when ExecuteL method failed.
       
   429 // ---------------------------------------------------------------------------
       
   430 //
       
   431 void CFscContactActionPluginEngine::ExecuteFailed( TInt aError )
       
   432     {
       
   433 	FUNC_LOG;
       
   434     iObserver->ExecuteFailed( aError );
       
   435     }
       
   436 
       
   437 // ---------------------------------------------------------------------------
       
   438 // Constructor.
       
   439 // ---------------------------------------------------------------------------
       
   440 //
       
   441 CFscContactActionPluginEngine::CFscContactActionPluginEngine(
       
   442     CVPbkContactManager& aContactManager )
       
   443     : iContactManager( aContactManager ),
       
   444     iPluginParams( NULL ),
       
   445     iLastEvent( ECasEventIdle )
       
   446     {
       
   447 	FUNC_LOG;
       
   448     }
       
   449 
       
   450 // ---------------------------------------------------------------------------
       
   451 // Second phase constructor.
       
   452 // ---------------------------------------------------------------------------
       
   453 //
       
   454 void CFscContactActionPluginEngine::ConstructL()
       
   455     {
       
   456 	FUNC_LOG;
       
   457     iActionUtils = CFscActionUtils::NewL( iContactManager );
       
   458     iPluginParams = TFscContactActionPluginParams( iActionUtils );
       
   459     }   
       
   460