|
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 |