1 /* |
|
2 * Copyright (c) 2005-2006 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: Shortcut plug-in engine class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <coemain.h> // For CCoeEnv |
|
20 #include <centralrepository.h> // For CRepository |
|
21 #include <w32std.h> // For RWsSession |
|
22 #include <apgtask.h> // For TApaTaskList |
|
23 #include <viewcli.h> // For CVwsSessionWrapper |
|
24 #include <vwsdef.h> // For TVwsViewId |
|
25 #include <e32property.h> // For RProperty |
|
26 #include <utf.h> // For CnvUtfConverter |
|
27 #include <bautils.h> |
|
28 #include <featmgr.h> |
|
29 #include <activefavouritesdbnotifier.h> // For CActiveFavouritesDbNotifier |
|
30 #include <pathinfo.h> |
|
31 #include <data_caging_path_literals.hrh> |
|
32 #include <AknSgcc.h> // for fast swap |
|
33 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
34 #include <viewclipartner.h> |
|
35 #endif |
|
36 |
|
37 |
|
38 #include <ctsydomainpskeys.h> |
|
39 #include <UikonInternalPSKeys.h> |
|
40 #include <menu2internalcrkeys.h> |
|
41 #include <activeidle2internalpskeys.h> |
|
42 #include <activeidle2domaincrkeys.h> |
|
43 #include <activeidle2domainpskeys.h> |
|
44 #include <aipspropertyobserver.h> |
|
45 |
|
46 #include <aiscuttexts.rsg> |
|
47 #include "caiscutengine.h" |
|
48 #include "aiscutpluginprivatecrkeys.h" |
|
49 #include "aiscutcontentmodel.h" |
|
50 #include "caiscutplugin.h" |
|
51 #include "caiscutshortcut.h" |
|
52 #include "caiscutshortcutinfo.h" |
|
53 #include "aidefaultshortcut.h" |
|
54 #include "aiscutappuidparser.h" |
|
55 #include "aiscutrepositorywatcher.h" |
|
56 #include "aiscuttargetshutter.h" |
|
57 #include "aiscutdefs.h" |
|
58 #include "aiscutfactory.h" |
|
59 |
|
60 #include <keylockpolicyapi.h> |
|
61 #include "debug.h" |
|
62 /** |
|
63 * Timer delay for access check retry. Two seconds. |
|
64 */ |
|
65 const TInt KScutAccessCheckRetryDelay = 2000000; |
|
66 const TUid KVoiceCallUidViewId = { 0x10282D81 }; |
|
67 const TUid KVideoCallUid = { 0x101F8681 }; |
|
68 |
|
69 _LIT(KScutTextsResourceFileName, "aiscuttexts.rsc"); |
|
70 _LIT8(KScutDirectOpen, "?open"); |
|
71 |
|
72 // ======== LOCAL FUNCTIONS ======== |
|
73 |
|
74 LOCAL_C TInt CompareKey(const TUint32& aLeft, const TUint32& aRight) |
|
75 { |
|
76 TUint32 left = aLeft & (KScutBitMaskThemeDefault & KScutBitMaskLocked); |
|
77 TUint32 right = aRight & (KScutBitMaskThemeDefault & KScutBitMaskLocked); |
|
78 |
|
79 if (left < right) |
|
80 { |
|
81 return -1; |
|
82 } |
|
83 else if (left > right) |
|
84 { |
|
85 return 1; |
|
86 } |
|
87 |
|
88 return 0; |
|
89 } |
|
90 |
|
91 static TInt IntFromDesc( const TDesC &aParam ) |
|
92 { |
|
93 TInt err = KErrArgument; |
|
94 if (aParam.Length() > 0) |
|
95 { |
|
96 _LIT(KHexPrefix, "0x"); |
|
97 const TInt prefixLen = 2; |
|
98 |
|
99 TRadix radix(EDecimal); |
|
100 TPtrC ptr(aParam); |
|
101 |
|
102 if (aParam.Left(prefixLen).CompareC(KHexPrefix) == 0) |
|
103 { |
|
104 // Strip the '0x' prefix. |
|
105 ptr.Set(aParam.Right(aParam.Length() - prefixLen)); |
|
106 |
|
107 radix = EHex; |
|
108 } |
|
109 |
|
110 TLex lexer(ptr); |
|
111 TUint32 id; |
|
112 |
|
113 err = lexer.Val(id, radix); |
|
114 if ( err == KErrNone ) |
|
115 { |
|
116 return id; |
|
117 } |
|
118 else |
|
119 { |
|
120 return err; |
|
121 } |
|
122 } |
|
123 return err; |
|
124 } |
|
125 // --------------------------------------------------------------------------- |
|
126 // Timer callback. |
|
127 // --------------------------------------------------------------------------- |
|
128 // |
|
129 TInt DelayedCheckCallBack(TAny* aEngine) |
|
130 { |
|
131 if (aEngine) |
|
132 { |
|
133 static_cast<CAiScutEngine*>(aEngine)->RetryAccessCheck(); |
|
134 } |
|
135 |
|
136 return KErrNone; |
|
137 } |
|
138 |
|
139 // ======== MEMBER FUNCTIONS ======== |
|
140 |
|
141 // --------------------------------------------------------------------------- |
|
142 // |
|
143 // --------------------------------------------------------------------------- |
|
144 // |
|
145 CAiScutEngine::CAiScutEngine(CAiScutPlugin& aPlugin) |
|
146 : |
|
147 iPlugin(aPlugin), |
|
148 iResourceLoaderTexts(*CCoeEnv::Static()), |
|
149 iResourceLoaderSendUi(*CCoeEnv::Static()) |
|
150 { |
|
151 } |
|
152 |
|
153 // --------------------------------------------------------------------------- |
|
154 // |
|
155 // --------------------------------------------------------------------------- |
|
156 // |
|
157 void CAiScutEngine::ConstructL() |
|
158 { |
|
159 FeatureManager::InitializeLibL(); |
|
160 |
|
161 User::LeaveIfError(iApaSession.Connect()); |
|
162 User::LeaveIfError(iBookmarkSess.Connect()); |
|
163 User::LeaveIfError(iBookmarkDb.Open(iBookmarkSess, KBrowserBookmarks)); |
|
164 |
|
165 iVwsSession = CVwsSessionWrapper::NewL(); |
|
166 iRepository = CRepository::NewL(KCRUidShortcutItems); |
|
167 |
|
168 iHiddenAppsRepository = CRepository::NewL(KCRUidMenu); |
|
169 |
|
170 // Create message server session because it may be needed during shortcut |
|
171 // creation for checking mailbox access. |
|
172 iMsvSession = CMsvSession::OpenAsObserverL(*this); |
|
173 |
|
174 iEnv = CCoeEnv::Static(); |
|
175 |
|
176 TParsePtrC driveParse(PathInfo::RomRootPath()); |
|
177 TFileName resourceName(driveParse.Drive()); |
|
178 TParse parse; |
|
179 parse.Set(KScutTextsResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL); |
|
180 resourceName.Append(parse.FullName()); |
|
181 iResourceLoaderTexts.OpenL(resourceName); |
|
182 |
|
183 TFileName resourceName2(driveParse.Drive()); |
|
184 TParse parse2; |
|
185 parse2.Set(KSendNormResource, &KDC_RESOURCE_FILES_DIR, NULL); |
|
186 resourceName2.Append(parse2.FullName()); |
|
187 iResourceLoaderSendUi.OpenL(resourceName2); |
|
188 |
|
189 LoadAppTitleListL(); |
|
190 |
|
191 // Engine should still remain alive even though shortcut construction failed |
|
192 // because LaunchByValue must still be possible. |
|
193 TRAP_IGNORE(CreateShortcutsL()); |
|
194 |
|
195 // Close message server session for now. It's opened again in Resume if needed. |
|
196 delete iMsvSession; |
|
197 iMsvSession = NULL; |
|
198 |
|
199 iKeyEventObserver = AiUtility::CreatePSPropertyObserverL( |
|
200 TCallBack(HandlePSCommand, this), |
|
201 KUidSystemCategory, KPSUidShortcutCmd); |
|
202 |
|
203 iCallStateObserver = AiUtility::CreatePSPropertyObserverL( |
|
204 TCallBack(CallStateChangeCallback, this), |
|
205 KPSUidCtsyCallInformation, KCTsyCallState); |
|
206 |
|
207 iKeylockApi = CKeyLockPolicyApi::NewL( EPolicyActivateKeyguard ); |
|
208 if ( !iKeylockApi->HasConfiguration() ) |
|
209 { |
|
210 delete iKeylockApi; |
|
211 iKeylockApi = NULL; |
|
212 } |
|
213 CRepository* repository = CRepository::NewLC(TUid::Uid(KCRUidActiveIdleLV)); |
|
214 |
|
215 repository->Get(KAIFirstKeyLockKey, iFirstLockKey); |
|
216 repository->Get(KAISecondKeyLockKey, iSecondLockKey); |
|
217 repository->Get(KAIKeyLockTimeout, iDelayTimerDelay); |
|
218 CleanupStack::PopAndDestroy(repository); |
|
219 // convert micro to milliseconds |
|
220 const TInt KUsInMs = 1000; |
|
221 iDelayTimerDelay = KUsInMs * iDelayTimerDelay; |
|
222 iDelayTimer = CPeriodic::NewL (CActive::EPriorityStandard ); |
|
223 } |
|
224 |
|
225 TInt CAiScutEngine::DelayTimerCallBack (TAny *aSelf ) |
|
226 { |
|
227 CAiScutEngine* self = static_cast<CAiScutEngine*>(aSelf ); |
|
228 TInt err = KErrNone; |
|
229 if (self ) |
|
230 { |
|
231 self->iDelayTimer->Cancel(); |
|
232 TRAP(err, |
|
233 self->HandleLaunchByIndexL( *(self->iDelayedLaunchCmd) ); |
|
234 ); |
|
235 |
|
236 } |
|
237 return err; |
|
238 } |
|
239 |
|
240 void CAiScutEngine::DelayedLaunchByIndexL( const TDesC &aParam ) |
|
241 { |
|
242 delete iDelayedLaunchCmd; |
|
243 iDelayedLaunchCmd = NULL; |
|
244 iDelayedLaunchCmd = aParam.AllocL(); |
|
245 iDelayTimer->Cancel(); |
|
246 iDelayTimer->Start( iDelayTimerDelay, |
|
247 iDelayTimerDelay, |
|
248 TCallBack( DelayTimerCallBack, this )); |
|
249 } |
|
250 |
|
251 // --------------------------------------------------------------------------- |
|
252 // |
|
253 // --------------------------------------------------------------------------- |
|
254 // |
|
255 CAiScutEngine* CAiScutEngine::NewL(CAiScutPlugin& aPlugin) |
|
256 { |
|
257 CAiScutEngine* self = new (ELeave) CAiScutEngine(aPlugin); |
|
258 CleanupStack::PushL(self); |
|
259 self->ConstructL(); |
|
260 CleanupStack::Pop(self); |
|
261 return self; |
|
262 } |
|
263 |
|
264 // --------------------------------------------------------------------------- |
|
265 // |
|
266 // --------------------------------------------------------------------------- |
|
267 // |
|
268 CAiScutEngine::~CAiScutEngine() |
|
269 { |
|
270 #ifdef __WEB_WIDGETS |
|
271 if( iWidgetRegistryConnected ) |
|
272 { |
|
273 iWidgetRegistry.Disconnect(); |
|
274 } |
|
275 #endif |
|
276 delete iKeylockApi; |
|
277 delete iSettingsNotifier; |
|
278 delete iRepository; |
|
279 |
|
280 delete iHiddenAppsNotifier; |
|
281 delete iHiddenAppsRepository; |
|
282 |
|
283 iHiddenApps.Close(); |
|
284 |
|
285 delete iAppNotifier; |
|
286 delete iTimer; |
|
287 delete iMsvSession; |
|
288 delete iVwsSession; |
|
289 delete iScutShutter; |
|
290 |
|
291 Release(iKeyEventObserver); |
|
292 Release(iCallStateObserver); |
|
293 |
|
294 iShortcuts.ResetAndDestroy(); |
|
295 iThemeShortcuts.ResetAndDestroy(); |
|
296 iDefaultUsed.Close(); |
|
297 |
|
298 delete iBookmarkDbObserver; |
|
299 iBookmarkDb.Close(); |
|
300 iBookmarkSess.Close(); |
|
301 |
|
302 iApaSession.Close(); |
|
303 |
|
304 while(iAppTitleList.Count()) |
|
305 { |
|
306 delete iAppTitleList[0].iLongTitle; |
|
307 delete iAppTitleList[0].iShortTitle; |
|
308 delete iAppTitleList[0].iSkeyTitle; |
|
309 delete iAppTitleList[0].iMskTitle; |
|
310 iAppTitleList.Remove(0); |
|
311 } |
|
312 iAppTitleList.Close(); |
|
313 |
|
314 iResourceLoaderTexts.Close(); |
|
315 iResourceLoaderSendUi.Close(); |
|
316 |
|
317 delete iDelayTimer; |
|
318 delete iDelayedLaunchCmd; |
|
319 iIcons.Close(); |
|
320 FeatureManager::UnInitializeLib(); |
|
321 } |
|
322 |
|
323 // --------------------------------------------------------------------------- |
|
324 // From class MMsvSessionObserver. |
|
325 // Handles an event from the message server. |
|
326 // --------------------------------------------------------------------------- |
|
327 // |
|
328 void CAiScutEngine::HandleSessionEventL( |
|
329 TMsvSessionEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/) |
|
330 { |
|
331 switch (aEvent) |
|
332 { |
|
333 case EMsvEntriesCreated: |
|
334 case EMsvEntriesDeleted: |
|
335 case EMsvEntriesChanged: |
|
336 if (iShortcuts.Count() > 0) |
|
337 { |
|
338 MergeShortcuts(EScutMailbox, ETrue); |
|
339 CheckAccessAndPublish(EScutCheckMailbox, EFalse); |
|
340 } |
|
341 break; |
|
342 |
|
343 default: |
|
344 break; |
|
345 } |
|
346 } |
|
347 |
|
348 // --------------------------------------------------------------------------- |
|
349 // From class MApaAppListServObserver. |
|
350 // Handles a change in the application list. |
|
351 // --------------------------------------------------------------------------- |
|
352 // |
|
353 void CAiScutEngine::HandleAppListEvent(TInt /*aEvent*/) |
|
354 { |
|
355 TRAP_IGNORE( CheckForThemeDefaultReinstalledL() ); |
|
356 MergeShortcuts(EScutAnyType, ETrue); |
|
357 CheckAccessAndPublish(EScutCheckApp, ETrue); |
|
358 } |
|
359 |
|
360 // --------------------------------------------------------------------------- |
|
361 // Resumes the engine. |
|
362 // --------------------------------------------------------------------------- |
|
363 // |
|
364 void CAiScutEngine::ResumeL(TBool aPublishAll, TAiTransitionReason /*aReason*/) |
|
365 { |
|
366 // Merge shortcuts and start notifiers only if we have publishable shortcuts. |
|
367 if (iShortcuts.Count() > 0) |
|
368 { |
|
369 if (!iSettingsNotifier) |
|
370 { |
|
371 iSettingsNotifier = CAiScutRepositoryWatcher::NewL( |
|
372 KCRUidShortcutItems, |
|
373 TCallBack(HandleShortcutsChanged, this), |
|
374 iRepository); |
|
375 } |
|
376 |
|
377 if (!iHiddenAppsNotifier) |
|
378 { |
|
379 iHiddenAppsNotifier = CAiScutRepositoryWatcher::NewL( |
|
380 KCRUidMenu, |
|
381 KMenuHideApplication, |
|
382 CCenRepNotifyHandler::EStringKey, |
|
383 TCallBack(HandleHiddenAppsChanged, this), |
|
384 iHiddenAppsRepository); |
|
385 } |
|
386 } |
|
387 #ifdef __WEB_WIDGETS |
|
388 if( !iWidgetRegistryConnected ) |
|
389 { |
|
390 TInt cError = iWidgetRegistry.Connect(); |
|
391 if( cError == KErrNone ) |
|
392 { |
|
393 iWidgetRegistryConnected = ETrue; |
|
394 } |
|
395 } |
|
396 #endif |
|
397 |
|
398 GetHiddenAppsL(); |
|
399 |
|
400 MergeShortcutsL(EScutAnyType, EFalse); |
|
401 |
|
402 // Call state check must be done always because RSK "Back" |
|
403 // must be published when theme is changed during phone call, too. |
|
404 HandleCallStateChange(); |
|
405 |
|
406 CheckAccessAndPublish(EScutCheckAll, aPublishAll); |
|
407 |
|
408 if (iShortcuts.Count() > 0) |
|
409 { |
|
410 iSettingsNotifier->StartListeningL(); |
|
411 |
|
412 iHiddenAppsNotifier->StartListeningL(); |
|
413 |
|
414 if (!iAppNotifier) |
|
415 { |
|
416 iAppNotifier = CApaAppListNotifier::NewL(this, CActive::EPriorityStandard); |
|
417 } |
|
418 } |
|
419 } |
|
420 |
|
421 // --------------------------------------------------------------------------- |
|
422 // Suspends the engine. |
|
423 // --------------------------------------------------------------------------- |
|
424 // |
|
425 void CAiScutEngine::Suspend() |
|
426 { |
|
427 delete iMsvSession; // This is to stop receiving message server events. |
|
428 iMsvSession = NULL; |
|
429 |
|
430 delete iSettingsNotifier; |
|
431 iSettingsNotifier = NULL; |
|
432 |
|
433 delete iHiddenAppsNotifier; |
|
434 iHiddenAppsNotifier = NULL; |
|
435 |
|
436 delete iAppNotifier; |
|
437 iAppNotifier = NULL; |
|
438 |
|
439 delete iTimer; |
|
440 iTimer = NULL; |
|
441 |
|
442 delete iScutShutter; |
|
443 iScutShutter = NULL; |
|
444 |
|
445 if (iBookmarkDbObserver) |
|
446 { |
|
447 iBookmarkDbObserver->Cancel(); |
|
448 } |
|
449 delete iBookmarkDbObserver; |
|
450 iBookmarkDbObserver = NULL; |
|
451 #ifdef __WEB_WIDGETS |
|
452 if( iWidgetRegistryConnected ) |
|
453 { |
|
454 TInt cError = iWidgetRegistry.Disconnect(); |
|
455 if( cError == KErrNone ) |
|
456 { |
|
457 iWidgetRegistryConnected = EFalse; |
|
458 } |
|
459 } |
|
460 #endif |
|
461 } |
|
462 |
|
463 // --------------------------------------------------------------------------- |
|
464 // |
|
465 // --------------------------------------------------------------------------- |
|
466 // |
|
467 TInt CAiScutEngine::HandleShortcutsChanged(TAny* aPtr) |
|
468 { |
|
469 __PRINTS("XAI: CAiScutEngine::HandleShortcutsChanged"); |
|
470 CAiScutEngine* self = static_cast<CAiScutEngine*>(aPtr); |
|
471 |
|
472 if (self) |
|
473 { |
|
474 self->MergeShortcuts(EScutAnyType, ETrue); |
|
475 self->CheckAccessAndPublish(EScutCheckAll, EFalse); |
|
476 } |
|
477 |
|
478 return KErrNone; |
|
479 } |
|
480 |
|
481 // --------------------------------------------------------------------------- |
|
482 // |
|
483 // --------------------------------------------------------------------------- |
|
484 // |
|
485 TInt CAiScutEngine::HandleHiddenAppsChanged(TAny* aPtr) |
|
486 { |
|
487 CAiScutEngine* self = static_cast<CAiScutEngine*>(aPtr); |
|
488 |
|
489 if (self) |
|
490 { |
|
491 TRAP_IGNORE(self->GetHiddenAppsL()); |
|
492 self->MergeShortcuts(EScutAnyType, ETrue); |
|
493 self->CheckAccessAndPublish(EScutCheckAll, EFalse); |
|
494 } |
|
495 |
|
496 return KErrNone; |
|
497 } |
|
498 |
|
499 // --------------------------------------------------------------------------- |
|
500 // |
|
501 // --------------------------------------------------------------------------- |
|
502 // |
|
503 TBool CAiScutEngine::IsLockKey( TInt aScanCode, TScutLockKey aLockKey ) const |
|
504 { |
|
505 TBool returnValue = EFalse; |
|
506 if ( iKeylockApi ) |
|
507 { |
|
508 TInt index = 0; |
|
509 TUint32 priKey = 0; |
|
510 TUint32 secKey = 0; |
|
511 TInt err = KErrNone; |
|
512 // Loop through all the combinations in order |
|
513 // to find wether this key is part of the locking |
|
514 // process or not (1st or 2nd key) |
|
515 while( !returnValue ) |
|
516 { |
|
517 err = iKeylockApi->GetKeyCombination(index, priKey, secKey); |
|
518 if ( err == KErrNone ) |
|
519 { |
|
520 switch( aLockKey ) |
|
521 { |
|
522 case EScutFirstLockKey: |
|
523 returnValue = (priKey == aScanCode); |
|
524 break; |
|
525 case EScutSecondLockKey: |
|
526 returnValue = (secKey == aScanCode); |
|
527 break; |
|
528 default: |
|
529 returnValue = EFalse; |
|
530 break; |
|
531 } |
|
532 } |
|
533 else // no more combinations |
|
534 { |
|
535 break; |
|
536 } |
|
537 ++index; |
|
538 } |
|
539 return returnValue; |
|
540 } |
|
541 switch( aLockKey ) |
|
542 { |
|
543 case EScutFirstLockKey: |
|
544 returnValue = iFirstLockKey == aScanCode; |
|
545 break; |
|
546 case EScutSecondLockKey: |
|
547 returnValue = iSecondLockKey == aScanCode; |
|
548 break; |
|
549 default: |
|
550 returnValue = EFalse; |
|
551 break; |
|
552 } |
|
553 return returnValue; |
|
554 } |
|
555 |
|
556 |
|
557 |
|
558 // --------------------------------------------------------------------------- |
|
559 // |
|
560 // --------------------------------------------------------------------------- |
|
561 // |
|
562 TBool CAiScutEngine::IsHidden(const TUid& aAppUid) const |
|
563 { |
|
564 if (iHiddenApps.Find(aAppUid) == KErrNotFound) |
|
565 { |
|
566 return EFalse; |
|
567 } |
|
568 |
|
569 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::IsHidden (0x%x) ETrue"), aAppUid); |
|
570 return ETrue; |
|
571 } |
|
572 |
|
573 // --------------------------------------------------------------------------- |
|
574 // Handles an event sent by the AI framework. |
|
575 // --------------------------------------------------------------------------- |
|
576 // |
|
577 void CAiScutEngine::HandleAiEventL(TInt aEvent, const TDesC& aParam) |
|
578 { |
|
579 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleAiEventL( %d, '%S' ) alive = %d"), aEvent, &aParam, iPlugin.IsAlive()); |
|
580 |
|
581 TUid appUid = KNullUid; |
|
582 iFirstLockKeyPressed = EFalse; |
|
583 iSoftkeyAppRunning = EFalse; |
|
584 |
|
585 if (aParam.Compare(KLeftSoftkey) == 0) |
|
586 { |
|
587 if ( IsLockKey( EStdKeyDevice0, EScutFirstLockKey) || IsLockKey( EStdKeyDevice0 , EScutSecondLockKey)) |
|
588 { |
|
589 // Raise the first lock key pressed flag |
|
590 // only when this is raised, keylock skip causes scut launch |
|
591 iFirstLockKeyPressed = ETrue; |
|
592 appUid = SoftkeyUid(KLeftSoftkeyId); |
|
593 } |
|
594 } |
|
595 |
|
596 if (aParam.Compare(KRightSoftkey) == 0) |
|
597 { |
|
598 if ( IsLockKey( EStdKeyDevice1 , EScutFirstLockKey) || IsLockKey( EStdKeyDevice1 , EScutSecondLockKey)) |
|
599 { |
|
600 // Raise the first lock key pressed flag |
|
601 // only when this is raised, keylock skip causes scut launch |
|
602 iFirstLockKeyPressed = ETrue; |
|
603 appUid = SoftkeyUid(KRightSoftkeyId); |
|
604 } |
|
605 } |
|
606 |
|
607 if (iFirstLockKeyPressed && appUid != KNullUid) |
|
608 { |
|
609 TApaTaskList taskList(iEnv->WsSession()); |
|
610 TApaTask task(taskList.FindApp(appUid)); |
|
611 |
|
612 if (task.Exists()) |
|
613 { |
|
614 if (IsHiddenFromFSW(appUid)) |
|
615 iSoftkeyAppRunning = EFalse; |
|
616 else |
|
617 iSoftkeyAppRunning = ETrue; |
|
618 } |
|
619 } |
|
620 |
|
621 if (IsDelayRequired(appUid)) |
|
622 { |
|
623 DelayedLaunchByIndexL( aParam ); |
|
624 return; |
|
625 } |
|
626 |
|
627 if( iActiveCall && aParam.Compare( KRightSoftkey ) == 0 ) |
|
628 { |
|
629 ActivateTopMostApp(); |
|
630 return; |
|
631 } |
|
632 |
|
633 switch( aEvent ) |
|
634 { |
|
635 case EAiScutEventLaunchByIndex: |
|
636 HandleLaunchByIndexL(aParam); |
|
637 break; |
|
638 |
|
639 case EAiScutEventLaunchByValue: |
|
640 HandleLaunchByValueL(aParam); |
|
641 break; |
|
642 |
|
643 case EAiScutEventShowSettings: |
|
644 ShowSettingsL(aParam); |
|
645 break; |
|
646 |
|
647 case EAiScutEventShowSetting: |
|
648 ShowSettingL(aParam); |
|
649 break; |
|
650 |
|
651 case EAiScutEventLaunchFastswap: |
|
652 OpenFastSwap(); |
|
653 break; |
|
654 |
|
655 case EAiScutEventLaunchByIndexAlternate: |
|
656 HandleLaunchByIndexAlternateL(aParam); |
|
657 break; |
|
658 |
|
659 default: |
|
660 break; |
|
661 } |
|
662 |
|
663 } |
|
664 |
|
665 // --------------------------------------------------------------------------- |
|
666 // Called by the timer. Retries the access check for shortcuts. |
|
667 // --------------------------------------------------------------------------- |
|
668 // |
|
669 void CAiScutEngine::RetryAccessCheck() |
|
670 { |
|
671 CheckAccessAndPublish(EScutCheckAll, iPublishAll); |
|
672 |
|
673 // One retry is enough. |
|
674 iTimer->Cancel(); |
|
675 delete iTimer; |
|
676 iTimer = NULL; |
|
677 } |
|
678 |
|
679 // --------------------------------------------------------------------------- |
|
680 // |
|
681 // --------------------------------------------------------------------------- |
|
682 // |
|
683 TBool CAiScutEngine::IsNonNative(const TUid& aUid) |
|
684 { |
|
685 TBool ret = EFalse; |
|
686 |
|
687 const TUid KMidletAppType = { 0x10210E26 }; |
|
688 TUid typeuid = KNullUid; |
|
689 |
|
690 if (KErrNone == iApaSession.GetAppType(typeuid, aUid)) |
|
691 { |
|
692 if (typeuid == KMidletAppType) |
|
693 { |
|
694 ret = ETrue; |
|
695 } |
|
696 } |
|
697 |
|
698 #ifdef __WEB_WIDGETS |
|
699 if (IsWidget(aUid)) |
|
700 { |
|
701 ret = ETrue; |
|
702 } |
|
703 #endif |
|
704 |
|
705 return ret; |
|
706 } |
|
707 |
|
708 #ifdef __WEB_WIDGETS |
|
709 TBool CAiScutEngine::IsWidget(const TUid& aUid) |
|
710 { |
|
711 if( iWidgetRegistryConnected ) |
|
712 { |
|
713 return iWidgetRegistry.IsWidget(aUid); |
|
714 } |
|
715 else |
|
716 { |
|
717 return EFalse; |
|
718 } |
|
719 } |
|
720 #endif |
|
721 |
|
722 // --------------------------------------------------------------------------- |
|
723 // Creates the default shortcuts. |
|
724 // --------------------------------------------------------------------------- |
|
725 // |
|
726 void CAiScutEngine::CreateShortcutsL() |
|
727 { |
|
728 TInt scIndex = 0; |
|
729 |
|
730 iShortcuts.ResetAndDestroy(); |
|
731 |
|
732 RArray<TUint32> keys; |
|
733 CleanupClosePushL(keys); |
|
734 // Find the keys that define theme-default shortcut settings. |
|
735 iRepository->FindL(KScutCenRepKeyThemeDefault, KScutCenRepKeyMask, keys); |
|
736 |
|
737 |
|
738 TLinearOrder<TUint32> order(CompareKey); |
|
739 keys.Sort(order); |
|
740 |
|
741 HBufC* buffer = HBufC::NewLC(NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
742 TPtr bufferPtr = buffer->Des(); |
|
743 |
|
744 if (iSettingsNotifier) |
|
745 { |
|
746 iSettingsNotifier->StopListening(); |
|
747 } |
|
748 if (iHiddenAppsNotifier) |
|
749 { |
|
750 iHiddenAppsNotifier->StopListening(); |
|
751 } |
|
752 |
|
753 for (TInt i = 0; i < keys.Count(); ++i) |
|
754 { |
|
755 TUint32 key = keys[i]; |
|
756 if (iRepository->Get(key, bufferPtr) == KErrNone) |
|
757 { |
|
758 // Strip off the default-setting-bit, it's not part of the shortcut id. |
|
759 key &= KScutBitMaskThemeDefault; |
|
760 |
|
761 // Parse the icon from the URL and fetch the icon to our icon array |
|
762 // The actual icon => shortcut matching and overriding is done in |
|
763 // CheckAccessAndPublishL() just before publishing |
|
764 iParser.Parse(bufferPtr); |
|
765 TAiScutIcon icon = iParser.Icon(); |
|
766 if ( icon.iType != EScutIconNone ) |
|
767 { |
|
768 AddOverrideIcon( icon ); |
|
769 } |
|
770 // Keys over 0x20000000 means that they are just icon overrides |
|
771 if ( !(key & KScutFlagBitIconOverride ) ) |
|
772 { |
|
773 key &= KScutMaskAdditionalSetting; |
|
774 // Ignore possible errors during shortcut construction |
|
775 // and simply try to move on to the next shortcut. |
|
776 CAiScutShortcut* shortcut = NULL; |
|
777 TRAPD(err, shortcut = AiScutFactory::CreateAiScutShortcutL(key, bufferPtr, *this)); |
|
778 if (err == KErrNone) |
|
779 { |
|
780 // If shortcut is not accessible, replace it with platform default. |
|
781 TBool access = EFalse; |
|
782 if (shortcut) |
|
783 { |
|
784 // Append theme default to our array, incase of uninstall/reinstall/mem card removal |
|
785 // restoration is required. |
|
786 CAiScutShortcutInfo* shortcutInfo = NULL; |
|
787 TRAP_IGNORE(shortcutInfo = CAiScutShortcutInfo::NewL(key | KScutFlagBitThemeDefault, |
|
788 bufferPtr)); |
|
789 if ( shortcutInfo ) |
|
790 { |
|
791 iThemeShortcuts.Append(shortcutInfo); |
|
792 } |
|
793 |
|
794 TScutDefault usedDefault = EScutDefaultToPlatform; |
|
795 |
|
796 TRAP_IGNORE(access = shortcut->CheckAccessL(EScutCheckAll)); |
|
797 if (!access) |
|
798 { |
|
799 HBufC* target = HBufC::NewLC(NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
800 TPtr targetPtr = target->Des(); |
|
801 TUid dummy; |
|
802 |
|
803 // Get the default shortcut definition for index 'scIndex'. |
|
804 // uid is ignored. |
|
805 TAiDefaultShortcut::GetDefaultShortcut(key, dummy, targetPtr); |
|
806 |
|
807 delete shortcut; |
|
808 shortcut = NULL; |
|
809 TRAP(err, shortcut = AiScutFactory::CreateAiScutShortcutL(key, targetPtr, *this)); |
|
810 |
|
811 if (err == KErrNone) |
|
812 { |
|
813 // Add the bit that indicates this is a default shortcut setting. |
|
814 key |= KScutFlagBitThemeDefault; |
|
815 iRepository->Set(key, targetPtr); |
|
816 |
|
817 // Try to locate a icon override from the default |
|
818 // definition |
|
819 iParser.Parse( targetPtr ); |
|
820 TAiScutIcon tIcon = iParser.Icon(); |
|
821 if ( tIcon.iType != EScutIconNone ) |
|
822 { |
|
823 AddOverrideIcon( tIcon ); |
|
824 } |
|
825 } |
|
826 CleanupStack::PopAndDestroy( target ); |
|
827 } |
|
828 else |
|
829 { |
|
830 usedDefault = EScutDefaultToTheme; |
|
831 } |
|
832 |
|
833 scIndex++; |
|
834 |
|
835 if (shortcut) // This test ensures that the creation right above went well. |
|
836 { |
|
837 iDefaultUsed.Append(usedDefault); |
|
838 err = iShortcuts.Append(shortcut); |
|
839 |
|
840 if (err != KErrNone) |
|
841 { |
|
842 delete shortcut; |
|
843 shortcut = NULL; |
|
844 } |
|
845 } |
|
846 } |
|
847 } |
|
848 } |
|
849 } |
|
850 } |
|
851 |
|
852 if (iSettingsNotifier) |
|
853 { |
|
854 iSettingsNotifier->StartListeningL(); |
|
855 } |
|
856 if (iHiddenAppsNotifier) |
|
857 { |
|
858 iHiddenAppsNotifier->StartListeningL(); |
|
859 } |
|
860 |
|
861 CleanupStack::PopAndDestroy(buffer); |
|
862 CleanupStack::PopAndDestroy(&keys); |
|
863 } |
|
864 |
|
865 // --------------------------------------------------------------------------- |
|
866 // Check whether theme default sc was reinstalled. |
|
867 // --------------------------------------------------------------------------- |
|
868 // |
|
869 void CAiScutEngine::CheckForThemeDefaultReinstalledL() |
|
870 { |
|
871 HBufC* buffer = HBufC::NewLC(NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
872 TPtr bufferPtr = buffer->Des(); |
|
873 |
|
874 if (iSettingsNotifier) |
|
875 { |
|
876 iSettingsNotifier->StopListening(); |
|
877 } |
|
878 if (iHiddenAppsNotifier) |
|
879 { |
|
880 iHiddenAppsNotifier->StopListening(); |
|
881 } |
|
882 |
|
883 TInt count = iThemeShortcuts.Count(); |
|
884 for (TInt i = 0; (i < count) && |
|
885 (i < iDefaultUsed.Count()) && |
|
886 (i < iShortcuts.Count()); |
|
887 ++i) |
|
888 { |
|
889 if (iDefaultUsed[i] == EScutDefaultToPlatform || |
|
890 iDefaultUsed[i] == EScutUserDefined) |
|
891 { |
|
892 bufferPtr.Zero(); |
|
893 CAiScutShortcut*& shortcut = iShortcuts[i]; |
|
894 // Strip off the default-setting-bit, it's not part of the shortcut id. |
|
895 TUint32 scutKey = iThemeShortcuts[i]->Id() & KScutBitMaskThemeDefault; |
|
896 bufferPtr.Append(iThemeShortcuts[i]->Target()); |
|
897 CAiScutShortcut* newScut = NULL; |
|
898 TRAPD(err, newScut = AiScutFactory::CreateAiScutShortcutL(scutKey, bufferPtr, *this)); |
|
899 if (err == KErrNone) |
|
900 { |
|
901 delete shortcut; |
|
902 shortcut = NULL; |
|
903 shortcut = newScut; |
|
904 // Add the bit that indicates this is a default shortcut setting. |
|
905 scutKey |= KScutFlagBitThemeDefault; |
|
906 iRepository->Set(scutKey, bufferPtr); |
|
907 } |
|
908 iDefaultUsed[i] = EScutDefaultToTheme; |
|
909 // Recheck access |
|
910 shortcut->CheckAccessL(EScutCheckAll); |
|
911 } |
|
912 } |
|
913 if (iSettingsNotifier) |
|
914 { |
|
915 iSettingsNotifier->StartListeningL(); |
|
916 } |
|
917 if (iHiddenAppsNotifier) |
|
918 { |
|
919 iHiddenAppsNotifier->StartListeningL(); |
|
920 } |
|
921 |
|
922 CleanupStack::PopAndDestroy(buffer); |
|
923 } |
|
924 |
|
925 // --------------------------------------------------------------------------- |
|
926 // Merges the user defined shortcuts with the defaults and checks shortcut access. |
|
927 // --------------------------------------------------------------------------- |
|
928 // |
|
929 void CAiScutEngine::MergeShortcuts(TShortcutType aType, TBool aRecreateAll) |
|
930 { |
|
931 TRAP_IGNORE(MergeShortcutsL(aType, aRecreateAll)); |
|
932 } |
|
933 |
|
934 // --------------------------------------------------------------------------- |
|
935 // Merges the user defined shortcuts with the defaults. |
|
936 // --------------------------------------------------------------------------- |
|
937 // |
|
938 void CAiScutEngine::MergeShortcutsL(TShortcutType aType, TBool aRecreateAll) |
|
939 { |
|
940 RArray<TUint32> keys; |
|
941 CleanupClosePushL(keys); |
|
942 |
|
943 // Find the keys that define user defined shortcut settings. |
|
944 iRepository->FindL(KScutCenRepKeyUserDefined, KScutCenRepKeyMask, keys); |
|
945 |
|
946 HBufC* buffer = HBufC::NewLC( |
|
947 NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
948 TPtr bufferPtr = buffer->Des(); |
|
949 |
|
950 for (TInt i = 0; i < iShortcuts.Count(); ++i) |
|
951 { |
|
952 CAiScutShortcut* shortcut = iShortcuts[i]; |
|
953 if (aType == EScutAnyType || shortcut->Type() == aType) |
|
954 { |
|
955 |
|
956 TInt keyIndex = keys.Find(shortcut->Id()); |
|
957 if (keyIndex != KErrNotFound) |
|
958 { |
|
959 // Set the new user target. |
|
960 if (keys.Count() > keyIndex && keyIndex >= 0 && |
|
961 iRepository->Get(keys[keyIndex], bufferPtr) == KErrNone) |
|
962 { |
|
963 iParser.Parse(bufferPtr); |
|
964 TAiScutIcon icon = iParser.Icon(); |
|
965 if ( icon.iType != EScutIconNone ) |
|
966 { |
|
967 AddOverrideIcon( icon ); |
|
968 } |
|
969 if ( aRecreateAll || |
|
970 buffer->CompareC( shortcut->ActiveDefinition() ) != 0 ) |
|
971 { |
|
972 shortcut->DeleteUserTarget(); |
|
973 shortcut->SetUserTarget(bufferPtr); |
|
974 } |
|
975 if (i < iDefaultUsed.Count()) |
|
976 { |
|
977 iDefaultUsed[i] = EScutUserDefined; |
|
978 } |
|
979 } |
|
980 } |
|
981 } |
|
982 } |
|
983 |
|
984 CleanupStack::PopAndDestroy(buffer); |
|
985 CleanupStack::PopAndDestroy(&keys); |
|
986 } |
|
987 |
|
988 // --------------------------------------------------------------------------- |
|
989 // Checks shortcut accessibility. |
|
990 // --------------------------------------------------------------------------- |
|
991 // |
|
992 void CAiScutEngine::CheckAccessAndPublish(TInt aCheckType, TBool aPublishAll) |
|
993 { |
|
994 TRAPD(err, CheckAccessAndPublishL(aCheckType, aPublishAll)); |
|
995 |
|
996 if (err == KErrNotReady) |
|
997 { |
|
998 // Access check failed, create a timer to try again later. |
|
999 iTimer = CPeriodic::New(CActive::EPriorityStandard); |
|
1000 iTimer->Start(KScutAccessCheckRetryDelay, KScutAccessCheckRetryDelay, |
|
1001 TCallBack(DelayedCheckCallBack)); |
|
1002 } |
|
1003 } |
|
1004 |
|
1005 // --------------------------------------------------------------------------- |
|
1006 // Tells each shortcut to check whether or not its target is accessible. |
|
1007 // --------------------------------------------------------------------------- |
|
1008 // |
|
1009 void CAiScutEngine::CheckAccessAndPublishL(TInt aCheckType, TBool aPublishAll) |
|
1010 { |
|
1011 __PRINTS("XAI: CheckAccessAndPublishL"); |
|
1012 if (!iMsvSession && IsMsvSessionNeeded()) |
|
1013 { |
|
1014 iMsvSession = CMsvSession::OpenAsObserverL(*this); |
|
1015 } |
|
1016 |
|
1017 if (!iBookmarkDbObserver && IsBookmarkObserverNeeded()) |
|
1018 { |
|
1019 iBookmarkDbObserver = |
|
1020 new (ELeave) CActiveFavouritesDbNotifier(iBookmarkDb, *this); |
|
1021 if (! iBookmarkDbObserver->IsActive()) |
|
1022 { |
|
1023 iBookmarkDbObserver->Start(); |
|
1024 } |
|
1025 } |
|
1026 |
|
1027 iPublishAll = aPublishAll; |
|
1028 |
|
1029 TInt count = iShortcuts.Count(); |
|
1030 for (TInt i = 0; i < count; ++i) |
|
1031 { |
|
1032 CAiScutShortcut*& shortcut = iShortcuts[i]; |
|
1033 |
|
1034 // Check shortcut access and publish it if its target has changed. |
|
1035 // When the plug-in is being resumed, all shortcuts are published. |
|
1036 // Non-visible and locked shortcuts are never published. |
|
1037 if ( !shortcut->CheckAccessL(aCheckType) ) |
|
1038 { |
|
1039 HBufC* target = HBufC::NewLC(NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
1040 TPtr targetPtr = target->Des(); |
|
1041 TUid dummy; |
|
1042 // Get the default shortcut definition from cenrep using key 'key'. |
|
1043 // uid is ignored. |
|
1044 TUint32 key = shortcut->Id(); |
|
1045 TAiDefaultShortcut::GetDefaultShortcut(key, dummy, targetPtr); |
|
1046 delete shortcut; |
|
1047 shortcut = NULL; |
|
1048 TRAPD(err, shortcut = AiScutFactory::CreateAiScutShortcutL(key, targetPtr, *this)); |
|
1049 if (err == KErrNone) |
|
1050 { |
|
1051 // Add the bit that indicates this is a default shortcut setting. |
|
1052 key |= KScutFlagBitThemeDefault; |
|
1053 iRepository->Set(key, targetPtr); |
|
1054 |
|
1055 // Try to locate a icon override from the default |
|
1056 // definition |
|
1057 iParser.Parse( targetPtr ); |
|
1058 TAiScutIcon tIcon = iParser.Icon(); |
|
1059 if ( tIcon.iType != EScutIconNone ) |
|
1060 { |
|
1061 AddOverrideIcon( tIcon ); |
|
1062 } |
|
1063 } |
|
1064 CleanupStack::PopAndDestroy( target ); |
|
1065 if (i < iDefaultUsed.Count()) |
|
1066 { |
|
1067 iDefaultUsed[i] = EScutDefaultToPlatform; |
|
1068 } |
|
1069 // Recheck access |
|
1070 shortcut->CheckAccessL(aCheckType); |
|
1071 } |
|
1072 |
|
1073 TBool targetChanged = shortcut->IsTargetChanged(); |
|
1074 TInt32 id = shortcut->Id(); |
|
1075 TBool nonVisible = (0 != (id & KScutFlagBitNonVisible)); |
|
1076 |
|
1077 if (aCheckType == EScutCheckBkm && shortcut->Type() == EScutBookmark) |
|
1078 { |
|
1079 targetChanged = ETrue; |
|
1080 } |
|
1081 |
|
1082 shortcut->SetToBePublished( |
|
1083 (targetChanged || iPublishAll) && |
|
1084 !nonVisible |
|
1085 ); |
|
1086 |
|
1087 // Assign overridden icons to shortcuts if needed |
|
1088 for ( TInt j = 0; j < iIcons.Count(); j++) |
|
1089 { |
|
1090 // Check that the appuid and type matches |
|
1091 if ( shortcut->AppUid() == iIcons[j].iAppUid && |
|
1092 shortcut->Type() == iIcons[j].iShortcutType ) |
|
1093 { |
|
1094 // We need to check also the view id / bkm id if present or otherwise all bookmarks |
|
1095 // app views would be overridden |
|
1096 if ( iIcons[j].iViewId.iUid <= 0 || |
|
1097 iIcons[j].iViewId == shortcut->AdditionalUid() ) |
|
1098 { |
|
1099 shortcut->SetIcon(iIcons[j]); |
|
1100 } |
|
1101 } |
|
1102 } |
|
1103 |
|
1104 __PRINT( __DBG_FORMAT( "XAI: id = 0x%x, type = %d, publish = %d"), |
|
1105 shortcut->Id(), shortcut->Type(), shortcut->NeedsToBePublished()); |
|
1106 } |
|
1107 |
|
1108 iPlugin.PublishShortcutsL(iShortcuts); |
|
1109 } |
|
1110 |
|
1111 // --------------------------------------------------------------------------- |
|
1112 // Finds the shortcut object with the given id. |
|
1113 // --------------------------------------------------------------------------- |
|
1114 // |
|
1115 TInt CAiScutEngine::FindShortcutIndex(TInt32 aId) |
|
1116 { |
|
1117 for (TInt i = 0; i < iShortcuts.Count(); ++i) |
|
1118 { |
|
1119 if (iShortcuts[i]->Id() == aId) |
|
1120 { |
|
1121 return i; |
|
1122 } |
|
1123 } |
|
1124 |
|
1125 return KErrNotFound; |
|
1126 } |
|
1127 |
|
1128 // --------------------------------------------------------------------------- |
|
1129 // Handles the shortcut launch by index. |
|
1130 // --------------------------------------------------------------------------- |
|
1131 // |
|
1132 void CAiScutEngine::HandleLaunchByIndexL(const TDesC& aParam) |
|
1133 { |
|
1134 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleLaunchByIndexL ('%S')"), &aParam); |
|
1135 if (aParam.Length() > 0) |
|
1136 { |
|
1137 _LIT(KHexPrefix, "0x"); |
|
1138 const TInt prefixLen = 2; |
|
1139 |
|
1140 TRadix radix(EDecimal); |
|
1141 TPtrC ptr(aParam); |
|
1142 |
|
1143 if (aParam.Left(prefixLen).CompareC(KHexPrefix) == 0) |
|
1144 { |
|
1145 // Strip the '0x' prefix. |
|
1146 ptr.Set(aParam.Right(aParam.Length() - prefixLen)); |
|
1147 |
|
1148 radix = EHex; |
|
1149 } |
|
1150 |
|
1151 TLex lexer(ptr); |
|
1152 TUint32 id; |
|
1153 if (lexer.Val(id, radix) == KErrNone) |
|
1154 { |
|
1155 TInt idx = FindShortcutIndex(id); |
|
1156 if (idx != KErrNotFound && idx >= 0 && iShortcuts.Count() > idx) |
|
1157 { |
|
1158 iShortcuts[idx]->LaunchL(); |
|
1159 } |
|
1160 } |
|
1161 } |
|
1162 } |
|
1163 // --------------------------------------------------------------------------- |
|
1164 // Handles the shortcut launch by index. |
|
1165 // --------------------------------------------------------------------------- |
|
1166 // |
|
1167 void CAiScutEngine::HandleLaunchByIndexAlternateL(const TDesC& aParam) |
|
1168 /** |
|
1169 * These are the cases at the moment that are handled here. |
|
1170 * 1) Appshell targeted => Fastswap opened |
|
1171 */ |
|
1172 { |
|
1173 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleLaunchByIndexAlternateL ('%S')"), &aParam); |
|
1174 TInt index = IntFromDesc( aParam ); |
|
1175 TInt idx = FindShortcutIndex( index ); |
|
1176 if (idx != KErrNotFound && idx >= 0 && iShortcuts.Count() > idx) |
|
1177 { |
|
1178 CAiScutShortcut *scut = iShortcuts[idx]; |
|
1179 // Open fastswap in case appshell was targeted with alternate launch |
|
1180 if ( scut->AppUid() == KScutAppShellUid ) |
|
1181 { |
|
1182 OpenFastSwap(); |
|
1183 return; |
|
1184 } |
|
1185 // add other special cases here |
|
1186 /*if ( index == EAiScutSoftKeyLeft ) |
|
1187 { |
|
1188 // do something |
|
1189 }*/ |
|
1190 } |
|
1191 } |
|
1192 |
|
1193 // --------------------------------------------------------------------------- |
|
1194 // Handles the shortcut launch by value. |
|
1195 // --------------------------------------------------------------------------- |
|
1196 // |
|
1197 void CAiScutEngine::HandleLaunchByValueL(const TDesC& aParam) |
|
1198 { |
|
1199 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleLaunchByIndexL ('%S')"), &aParam); |
|
1200 |
|
1201 if (aParam.Length() > 0) |
|
1202 { |
|
1203 CAiScutShortcut* shortcut = AiScutFactory::CreateAiScutShortcutLC(0x0, aParam, *this); |
|
1204 shortcut->CheckAccessL(EScutCheckAll); |
|
1205 shortcut->LaunchL(); |
|
1206 CleanupStack::PopAndDestroy(shortcut); |
|
1207 } |
|
1208 } |
|
1209 |
|
1210 // --------------------------------------------------------------------------- |
|
1211 // Shows the plug-in settings dialog. |
|
1212 // --------------------------------------------------------------------------- |
|
1213 // |
|
1214 void CAiScutEngine::ShowSettingsL(const TDesC& aParam) |
|
1215 { |
|
1216 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::ShowSettingsL ('%S')"), &aParam); |
|
1217 |
|
1218 _LIT(KGeneralSettings, "localapp:0x100058EC?view=0x102750FC"); |
|
1219 |
|
1220 CAiScutShortcut* shortcut = CAiScutShortcut::NewLC(0x0, KGeneralSettings, *this); |
|
1221 shortcut->CheckAccessL(EScutCheckAll); |
|
1222 |
|
1223 if (aParam.Length() > 0) |
|
1224 { |
|
1225 HBufC8* param = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aParam); |
|
1226 CleanupStack::PushL(param); |
|
1227 |
|
1228 const TDesC8& msg(*param); |
|
1229 |
|
1230 shortcut->LaunchL(msg); |
|
1231 |
|
1232 CleanupStack::PopAndDestroy(param); |
|
1233 } |
|
1234 else |
|
1235 { |
|
1236 shortcut->LaunchL(KNullDesC8); |
|
1237 } |
|
1238 |
|
1239 |
|
1240 CleanupStack::PopAndDestroy(shortcut); |
|
1241 } |
|
1242 |
|
1243 // --------------------------------------------------------------------------- |
|
1244 // Shows the plug-in setting. |
|
1245 // --------------------------------------------------------------------------- |
|
1246 // |
|
1247 void CAiScutEngine::ShowSettingL(const TDesC& aParam) |
|
1248 { |
|
1249 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::ShowSettingL ('%S')"), &aParam); |
|
1250 |
|
1251 _LIT(KGeneralSettings, "localapp:0x100058EC?view=0x102750FC"); |
|
1252 |
|
1253 CAiScutShortcut* shortcut = CAiScutShortcut::NewLC(0x0, KGeneralSettings, *this); |
|
1254 shortcut->CheckAccessL(EScutCheckAll); |
|
1255 |
|
1256 if (aParam.Length() > 0) |
|
1257 { |
|
1258 HBufC8* param = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aParam); |
|
1259 CleanupStack::PushL(param); |
|
1260 |
|
1261 HBufC8* param2 = HBufC8::NewLC(param->Des().Length()+KScutDirectOpen.iTypeLength); |
|
1262 param2->Des().Copy(param->Des()); |
|
1263 param2->Des().Append(KScutDirectOpen); |
|
1264 const TDesC8& msg(*param2); |
|
1265 |
|
1266 shortcut->LaunchL(msg); |
|
1267 |
|
1268 CleanupStack::PopAndDestroy(param2); |
|
1269 CleanupStack::PopAndDestroy(param); |
|
1270 } |
|
1271 else |
|
1272 { |
|
1273 shortcut->LaunchL(KNullDesC8); |
|
1274 } |
|
1275 |
|
1276 |
|
1277 CleanupStack::PopAndDestroy(shortcut); |
|
1278 } |
|
1279 |
|
1280 // --------------------------------------------------------------------------- |
|
1281 // Opens the fastswap window |
|
1282 // --------------------------------------------------------------------------- |
|
1283 // |
|
1284 void CAiScutEngine::OpenFastSwap() |
|
1285 { |
|
1286 RAknUiServer* uiServer = CAknSgcClient::AknSrv(); |
|
1287 if ( uiServer ) |
|
1288 { |
|
1289 uiServer->MakeTaskListVisible( ETrue ); |
|
1290 } |
|
1291 } |
|
1292 |
|
1293 |
|
1294 |
|
1295 // --------------------------------------------------------------------------- |
|
1296 // Handles PS commands from WSPlugin. |
|
1297 // --------------------------------------------------------------------------- |
|
1298 // |
|
1299 TInt CAiScutEngine::HandlePSCommand(TAny* aAny) |
|
1300 { |
|
1301 CAiScutEngine* self = reinterpret_cast< CAiScutEngine* >(aAny); |
|
1302 TInt err = KErrNone; |
|
1303 if (self) |
|
1304 { |
|
1305 TRAP(err, self->DoHandlePSCommandL()); |
|
1306 } |
|
1307 |
|
1308 return err; |
|
1309 } |
|
1310 |
|
1311 // --------------------------------------------------------------------------- |
|
1312 // Handles call state changes. |
|
1313 // --------------------------------------------------------------------------- |
|
1314 // |
|
1315 TInt CAiScutEngine::CallStateChangeCallback(TAny* /*aAny*/) |
|
1316 { |
|
1317 return KErrNone; |
|
1318 } |
|
1319 |
|
1320 // --------------------------------------------------------------------------- |
|
1321 // |
|
1322 // --------------------------------------------------------------------------- |
|
1323 // |
|
1324 TUid CAiScutEngine::SoftkeyUid(TUint32 aSoftkeyId) |
|
1325 { |
|
1326 TUid uid = KNullUid; |
|
1327 |
|
1328 TInt idx = FindShortcutIndex(aSoftkeyId); |
|
1329 if (idx != KErrNotFound && idx >= 0 && iShortcuts.Count() > idx) |
|
1330 { |
|
1331 uid = iShortcuts[idx]->AppUid(); |
|
1332 |
|
1333 __PRINT( __DBG_FORMAT( "XAI: SoftkeyUid %d app uid = 0x%x"), idx, uid.iUid); |
|
1334 } |
|
1335 |
|
1336 return uid; |
|
1337 } |
|
1338 |
|
1339 // --------------------------------------------------------------------------- |
|
1340 // |
|
1341 // --------------------------------------------------------------------------- |
|
1342 // |
|
1343 TBool CAiScutEngine::IsDelayRequired(TUid aAppUid) |
|
1344 { |
|
1345 // softkey delay is reuired for these applications because of problems |
|
1346 // in killing them immediatly after keylock activation. |
|
1347 if (aAppUid.iUid == KScutBrowserUidValue || |
|
1348 aAppUid.iUid == KScutOperatorMenuUidValue || |
|
1349 aAppUid.iUid == KScutVideoServicesUidValue || |
|
1350 IsNonNative( aAppUid ) |
|
1351 ) |
|
1352 { |
|
1353 return ETrue; |
|
1354 } |
|
1355 |
|
1356 return EFalse; |
|
1357 } |
|
1358 |
|
1359 // --------------------------------------------------------------------------- |
|
1360 // Handles PS commands from WSPlugin. |
|
1361 // --------------------------------------------------------------------------- |
|
1362 // |
|
1363 void CAiScutEngine::DoHandlePSCommandL() |
|
1364 { |
|
1365 TBuf<RProperty::KMaxPropertySize> command; |
|
1366 TUint32 lockKeyId = 0; |
|
1367 iKeyEventObserver->Get(command); |
|
1368 |
|
1369 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::DoHandlePSCommandL command = '%S'"), &command); |
|
1370 |
|
1371 TUid appUid = KNullUid; |
|
1372 |
|
1373 if (iFirstLockKey == EStdKeyDevice0) |
|
1374 { |
|
1375 appUid = SoftkeyUid(KLeftSoftkeyId); |
|
1376 lockKeyId = KLeftSoftkeyId; |
|
1377 } |
|
1378 |
|
1379 if (iFirstLockKey == EStdKeyDevice1) |
|
1380 { |
|
1381 appUid = SoftkeyUid(KRightSoftkeyId); |
|
1382 lockKeyId = KRightSoftkeyId; |
|
1383 } |
|
1384 |
|
1385 if (iFirstLockKeyPressed && command.Compare(KAiPSEnableKeyLock) == 0) |
|
1386 { |
|
1387 if (appUid != KNullUid) |
|
1388 { |
|
1389 TBool isDialog = EFalse; |
|
1390 TInt idx = 0; |
|
1391 delete iScutShutter; |
|
1392 iScutShutter = NULL; |
|
1393 |
|
1394 // In case new message shortcut in lockkey |
|
1395 // we need to dismiss the dialog |
|
1396 if ( lockKeyId > 0 ) |
|
1397 { |
|
1398 idx = FindShortcutIndex( lockKeyId ); |
|
1399 if (idx != KErrNotFound) |
|
1400 { |
|
1401 switch (iShortcuts[idx]->Type()) |
|
1402 { |
|
1403 case EScutNewMsgType: |
|
1404 isDialog = ETrue; |
|
1405 break; |
|
1406 default: |
|
1407 isDialog = EFalse; |
|
1408 break; |
|
1409 } |
|
1410 } |
|
1411 |
|
1412 } |
|
1413 iDelayTimer->Cancel(); |
|
1414 iScutShutter = CAiScutTargetShutter::NewL(iEnv, appUid, iSoftkeyAppRunning, isDialog); |
|
1415 iScutShutter->StartL(); |
|
1416 } |
|
1417 } |
|
1418 |
|
1419 if (command.Compare(KAiPSSkipKeyLock) == 0) |
|
1420 { |
|
1421 iDelayTimer->Cancel(); |
|
1422 return ; |
|
1423 } |
|
1424 else if (command.Compare(KAiPSKeyLockTimeout) == 0) |
|
1425 { |
|
1426 if (iFirstLockKeyPressed) |
|
1427 { |
|
1428 iFirstLockKeyPressed = EFalse; |
|
1429 |
|
1430 if (iFirstLockKey == EStdKeyDevice0) |
|
1431 { |
|
1432 if (IsDelayRequired(appUid)) |
|
1433 { |
|
1434 HandleLaunchByIndexL(KLeftSoftkey); |
|
1435 } |
|
1436 return ; |
|
1437 } |
|
1438 |
|
1439 if (iFirstLockKey == EStdKeyDevice1) |
|
1440 { |
|
1441 if (IsDelayRequired(appUid)) |
|
1442 { |
|
1443 HandleLaunchByIndexL(KRightSoftkey); |
|
1444 } |
|
1445 return ; |
|
1446 } |
|
1447 } |
|
1448 return ; |
|
1449 } |
|
1450 |
|
1451 if (FeatureManager::FeatureSupported(KFeatureIdKeypadNoVoiceKey) && |
|
1452 command.Compare(KAiPSSkipNameDialer) == 0) |
|
1453 { |
|
1454 HandleLaunchByIndexL(KRightSoftkey); |
|
1455 return ; |
|
1456 } |
|
1457 |
|
1458 HandleLaunchByValueL(command); |
|
1459 } |
|
1460 |
|
1461 // --------------------------------------------------------------------------- |
|
1462 // Handles call state changes. |
|
1463 // --------------------------------------------------------------------------- |
|
1464 // |
|
1465 void CAiScutEngine::HandleCallStateChange() |
|
1466 { |
|
1467 TInt value = 0; |
|
1468 TInt err = iCallStateObserver->Get(value); |
|
1469 iActiveCall = (value > EPSCTsyCallStateNone) && err == KErrNone; |
|
1470 |
|
1471 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleCallStateChange = %d"), value); |
|
1472 __PRINT( __DBG_FORMAT( "XAI: iActiveCall = %d"), iActiveCall); |
|
1473 |
|
1474 for (TInt i = 0; i < iShortcuts.Count(); ++i) |
|
1475 { |
|
1476 iShortcuts[i]->SetCallState(iActiveCall); |
|
1477 } |
|
1478 } |
|
1479 |
|
1480 // --------------------------------------------------------------------------- |
|
1481 // Activates TopMost Application |
|
1482 // --------------------------------------------------------------------------- |
|
1483 // |
|
1484 void CAiScutEngine::ActivateTopMostApp() |
|
1485 { |
|
1486 // Phone Topmost app as default |
|
1487 TInt idleAppUid = 0; |
|
1488 TInt topMostAppId = 0; |
|
1489 |
|
1490 RProperty::Get(KPSUidAiInformation, KActiveIdleUid, idleAppUid); |
|
1491 |
|
1492 RProperty property; |
|
1493 TInt err = property.Attach(KPSUidUikon, KUikVideoCallTopApp); |
|
1494 |
|
1495 if (err == KErrNone) |
|
1496 { |
|
1497 property.Get(topMostAppId); |
|
1498 } |
|
1499 |
|
1500 property.Close(); |
|
1501 |
|
1502 __PRINT( __DBG_FORMAT( "XAI: ActivateTopMostApp idle uid = 0x%x topmost = 0x%x"), idleAppUid, topMostAppId); |
|
1503 |
|
1504 TUid appId(TUid::Uid(topMostAppId)); |
|
1505 |
|
1506 if(appId == KVideoCallUid) |
|
1507 { |
|
1508 const TVwsViewId viewId(appId, appId); |
|
1509 err = iVwsSession->CreateActivateViewEvent(viewId, KNullUid, KNullDesC8()); |
|
1510 |
|
1511 __PRINT( __DBG_FORMAT( "XAI: CreateActivateViewEvent = %d"), err); |
|
1512 } |
|
1513 else |
|
1514 { |
|
1515 const TVwsViewId viewId(appId, KVoiceCallUidViewId); |
|
1516 err = iVwsSession->CreateActivateViewEvent(viewId, KVoiceCallUidViewId, KNullDesC8()); |
|
1517 |
|
1518 __PRINT( __DBG_FORMAT( "XAI: CreateActivateViewEvent = %d"), err); |
|
1519 } |
|
1520 |
|
1521 } |
|
1522 |
|
1523 // --------------------------------------------------------------------------- |
|
1524 // From class MFavouritesDbObserver. |
|
1525 // Handles database event. |
|
1526 // --------------------------------------------------------------------------- |
|
1527 // |
|
1528 void CAiScutEngine::HandleFavouritesDbEventL(RDbNotifier::TEvent aEvent) |
|
1529 { |
|
1530 __PRINT( __DBG_FORMAT( "XAI: CAiScutEngine::HandleFavouritesDbEventL aEvent = %d"), aEvent); |
|
1531 |
|
1532 if (aEvent == RDbNotifier::ECommit) |
|
1533 { |
|
1534 MergeShortcuts(EScutBookmark, ETrue); |
|
1535 CheckAccessAndPublish(EScutCheckBkm, EFalse); |
|
1536 } |
|
1537 } |
|
1538 |
|
1539 // --------------------------------------------------------------------------- |
|
1540 // |
|
1541 // --------------------------------------------------------------------------- |
|
1542 // |
|
1543 TBool CAiScutEngine::IsMsvSessionNeeded() |
|
1544 { |
|
1545 TInt count = iShortcuts.Count(); |
|
1546 |
|
1547 for (TInt i = 0; i < count; ++i) |
|
1548 { |
|
1549 CAiScutShortcut* shortcut = iShortcuts[i]; |
|
1550 TShortcutType type = shortcut->Type(); |
|
1551 |
|
1552 if (type == EScutNewMessage || |
|
1553 type == EScutNewEmail || |
|
1554 type == EScutNewSyncMLMail || |
|
1555 type == EScutNewPostcard || |
|
1556 type == EScutNewAudioMsg || |
|
1557 type == EScutNewMsgType || |
|
1558 type == EScutMailbox) |
|
1559 { |
|
1560 return ETrue; |
|
1561 } |
|
1562 } |
|
1563 |
|
1564 return EFalse; |
|
1565 } |
|
1566 |
|
1567 // --------------------------------------------------------------------------- |
|
1568 // |
|
1569 // --------------------------------------------------------------------------- |
|
1570 // |
|
1571 TBool CAiScutEngine::IsBookmarkObserverNeeded() |
|
1572 { |
|
1573 TInt count = iShortcuts.Count(); |
|
1574 |
|
1575 for (TInt i = 0; i < count; ++i) |
|
1576 { |
|
1577 CAiScutShortcut* shortcut = iShortcuts[i]; |
|
1578 if (shortcut->Type() == EScutBookmark) |
|
1579 { |
|
1580 return ETrue; |
|
1581 } |
|
1582 } |
|
1583 |
|
1584 return EFalse; |
|
1585 } |
|
1586 |
|
1587 // --------------------------------------------------------------------------- |
|
1588 // |
|
1589 // --------------------------------------------------------------------------- |
|
1590 // |
|
1591 TBool CAiScutEngine::GetAppTitle( |
|
1592 const TUid& aAppUid, const TUid& aViewId, TDes& aTitle, TAiScutAppTitleType aType) |
|
1593 { |
|
1594 TBool ret = EFalse; |
|
1595 TInt count = iAppTitleList.Count(); |
|
1596 |
|
1597 for (TInt i = 0; i < count; i++) |
|
1598 { |
|
1599 TAiScutAppTitleEntry entry = iAppTitleList[i]; |
|
1600 |
|
1601 if (entry.iAppUid == aAppUid && entry.iViewId == aViewId) |
|
1602 { |
|
1603 switch (aType) |
|
1604 { |
|
1605 case EAiScutLongTitle: |
|
1606 if (entry.iLongTitle) |
|
1607 { |
|
1608 aTitle = *entry.iLongTitle; |
|
1609 ret = ETrue; |
|
1610 } |
|
1611 break; |
|
1612 |
|
1613 case EAiScutShortTitle: |
|
1614 if (entry.iShortTitle) |
|
1615 { |
|
1616 aTitle = *entry.iShortTitle; |
|
1617 ret = ETrue; |
|
1618 } |
|
1619 break; |
|
1620 |
|
1621 case EAiScutSkeyTitle: |
|
1622 if (entry.iSkeyTitle) |
|
1623 { |
|
1624 aTitle = *entry.iSkeyTitle; |
|
1625 ret = ETrue; |
|
1626 } |
|
1627 break; |
|
1628 |
|
1629 case EAiScutMskTitle: |
|
1630 if (entry.iMskTitle) |
|
1631 { |
|
1632 aTitle = *entry.iMskTitle; |
|
1633 ret = ETrue; |
|
1634 } |
|
1635 break; |
|
1636 default : |
|
1637 break; |
|
1638 } |
|
1639 |
|
1640 break; // break the for loop |
|
1641 } |
|
1642 } |
|
1643 |
|
1644 if (! ret) __PRINT( __DBG_FORMAT( "XAI: GetAppTitle NOT found for uid = 0x%x"), aAppUid); |
|
1645 |
|
1646 return ret; |
|
1647 } |
|
1648 |
|
1649 // --------------------------------------------------------------------------- |
|
1650 // |
|
1651 // --------------------------------------------------------------------------- |
|
1652 // |
|
1653 void CAiScutEngine::LoadAppTitleListL() |
|
1654 { |
|
1655 TResourceReader reader; |
|
1656 iEnv->CreateResourceReaderLC(reader, R_SCUT_APP_TITLE_LIST); |
|
1657 |
|
1658 TInt items = reader.ReadInt16(); |
|
1659 |
|
1660 __PRINT( __DBG_FORMAT( "XAI: LoadAppTitleListL items = %d"), items); |
|
1661 |
|
1662 TUid appuid; |
|
1663 TUid viewid; |
|
1664 |
|
1665 for (TInt i = 0; i < items; i++) |
|
1666 { |
|
1667 appuid.iUid = reader.ReadInt32(); |
|
1668 viewid.iUid = reader.ReadInt32(); |
|
1669 |
|
1670 HBufC16* longTitle = reader.ReadHBufC16L(); |
|
1671 CleanupStack::PushL(longTitle); |
|
1672 |
|
1673 HBufC16* shortTitle = reader.ReadHBufC16L(); |
|
1674 CleanupStack::PushL(shortTitle); |
|
1675 |
|
1676 HBufC16* skeyTitle = reader.ReadHBufC16L(); |
|
1677 CleanupStack::PushL(skeyTitle); |
|
1678 |
|
1679 HBufC16* mskTitle = reader.ReadHBufC16L(); |
|
1680 CleanupStack::PushL(mskTitle); |
|
1681 |
|
1682 TAiScutAppTitleEntry entry; |
|
1683 |
|
1684 entry.iAppUid = appuid; |
|
1685 entry.iViewId = viewid; |
|
1686 entry.iLongTitle = longTitle; |
|
1687 entry.iShortTitle = shortTitle; |
|
1688 entry.iSkeyTitle = skeyTitle; |
|
1689 entry.iMskTitle = mskTitle; |
|
1690 |
|
1691 User::LeaveIfError(iAppTitleList.Append(entry)); |
|
1692 |
|
1693 // Title names are deleted in destructor. |
|
1694 CleanupStack::Pop(4, longTitle); |
|
1695 } |
|
1696 |
|
1697 CleanupStack::PopAndDestroy(); // reader |
|
1698 } |
|
1699 |
|
1700 // --------------------------------------------------------------------------- |
|
1701 // |
|
1702 // --------------------------------------------------------------------------- |
|
1703 // |
|
1704 void CAiScutEngine::GetHiddenAppsL() |
|
1705 { |
|
1706 HBufC* buffer = HBufC::NewLC( |
|
1707 NCentralRepositoryConstants::KMaxUnicodeStringLength); |
|
1708 TPtr bufferPtr = buffer->Des(); |
|
1709 |
|
1710 iHiddenAppsRepository->Get(KMenuHideApplication, bufferPtr); |
|
1711 |
|
1712 __PRINT( __DBG_FORMAT( "XAI: CAiScutSettingsModel::GetHiddenAppsL '%S' "), buffer); |
|
1713 |
|
1714 iHiddenApps.Reset(); |
|
1715 TAiScutAppUidParser uidParser(bufferPtr, iHiddenApps); |
|
1716 uidParser.ParseL(); |
|
1717 |
|
1718 CleanupStack::PopAndDestroy(buffer); |
|
1719 } |
|
1720 |
|
1721 // --------------------------------------------------------------------------- |
|
1722 // |
|
1723 // --------------------------------------------------------------------------- |
|
1724 // |
|
1725 TBool CAiScutEngine::IsHiddenFromFSW( const TUid& aAppUid ) |
|
1726 { |
|
1727 const TUid KPSUidUikon = { 0x101F8773 }; |
|
1728 const TUint32 KUikAppHiddenList = 0x00000010; |
|
1729 const TInt KMaxHiddenApps = 25; |
|
1730 |
|
1731 TBuf16 <2*KMaxHiddenApps> retrievedList; |
|
1732 TInt err = RProperty::Get( KPSUidUikon, KUikAppHiddenList, |
|
1733 retrievedList ); |
|
1734 TInt i = 0; |
|
1735 |
|
1736 TUint32 listValue; |
|
1737 while( i < KMaxHiddenApps && KErrNone == err ) |
|
1738 { |
|
1739 // 32-bit uid values are retrieved in two 16-bit parts |
|
1740 listValue = retrievedList[2*i] << 16; |
|
1741 listValue += retrievedList[2*i+1]; |
|
1742 |
|
1743 if ( listValue ) |
|
1744 { |
|
1745 TUid t ( KNullUid ); |
|
1746 t.iUid = listValue; |
|
1747 if( t == aAppUid ) |
|
1748 { |
|
1749 return ETrue; |
|
1750 } |
|
1751 } |
|
1752 else |
|
1753 { |
|
1754 err = KErrEof; |
|
1755 return EFalse; |
|
1756 } |
|
1757 i++; |
|
1758 } |
|
1759 return EFalse; |
|
1760 } |
|
1761 // --------------------------------------------------------------------------- |
|
1762 // Adds an override icon to iIcons array in case the same icon |
|
1763 // isn't there already |
|
1764 // --------------------------------------------------------------------------- |
|
1765 // |
|
1766 TInt CAiScutEngine::AddOverrideIcon( TAiScutIcon &aIcon ) |
|
1767 { |
|
1768 TBool foundExisting = EFalse; |
|
1769 |
|
1770 for ( TInt i = 0; i < iIcons.Count(); i++) |
|
1771 { |
|
1772 if ( aIcon.iAppUid == iIcons[i].iAppUid && |
|
1773 aIcon.iShortcutType == iIcons[i].iShortcutType && |
|
1774 aIcon.iViewId == iIcons[i].iViewId && |
|
1775 aIcon.iDestination == iIcons[i].iDestination ) |
|
1776 { |
|
1777 foundExisting = ETrue; |
|
1778 break; |
|
1779 } |
|
1780 } |
|
1781 if ( !foundExisting ) |
|
1782 { |
|
1783 return iIcons.Append( aIcon ); |
|
1784 } |
|
1785 return KErrNone; |
|
1786 } |
|
1787 // End of File. |
|