|
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: File containing application list classes |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 //INCLUDES: |
|
20 #define __E32SVR_H__ |
|
21 #include "tsfswdatalist.h" |
|
22 #include "tsfswengine.h" |
|
23 #include <mmf/common/mmfcontrollerpluginresolver.h> // for CleanupResetAndDestroyPushL |
|
24 #include <featmgr.h> |
|
25 #include <apgwgnam.h> |
|
26 #include <AknsUtils.h> |
|
27 #include <gulicon.h> |
|
28 #include <e32debug.h> |
|
29 #include <bitstd.h> |
|
30 #include <AknIconUtils.h> // avkon |
|
31 #include <APGICNFL.H> // fbsbitmap |
|
32 #include <akniconsrvclient.h> |
|
33 |
|
34 // size for the created app icons |
|
35 const TInt KAppIconWidth = 128; |
|
36 const TInt KAppIconHeight = 128; |
|
37 |
|
38 //uids to be hidden |
|
39 const TUid KHsApplicationUid = {0x20022F35}; |
|
40 const TUid KTelephoneUid = {0x100058B3}; |
|
41 |
|
42 // ================= MEMBER FUNCTIONS ======================= |
|
43 |
|
44 // -------------------------------------------------------------------------- |
|
45 // CTsFswDataList::NewL |
|
46 // -------------------------------------------------------------------------- |
|
47 // |
|
48 CTsFswDataList* CTsFswDataList::NewL(CTsFswEngine& aEngine) |
|
49 { |
|
50 CTsFswDataList* self = new (ELeave) CTsFswDataList(aEngine); |
|
51 CleanupStack::PushL (self ); |
|
52 self->ConstructL ( ); |
|
53 CleanupStack::Pop ( self ); |
|
54 return self; |
|
55 } |
|
56 |
|
57 // -------------------------------------------------------------------------- |
|
58 // CTsFswDataList::CTsFswDataList |
|
59 // -------------------------------------------------------------------------- |
|
60 // |
|
61 CTsFswDataList::CTsFswDataList(CTsFswEngine& aEngine) : |
|
62 iEngine(aEngine) |
|
63 { |
|
64 } |
|
65 |
|
66 // -------------------------------------------------------------------------- |
|
67 // CTsFswDataList::~CTsFswDataList |
|
68 // -------------------------------------------------------------------------- |
|
69 // |
|
70 CTsFswDataList::~CTsFswDataList( ) |
|
71 { |
|
72 iData.ResetAndDestroy(); |
|
73 iAppArcSession.Close(); |
|
74 iWsSession.Close(); |
|
75 iHiddenUids.Close(); |
|
76 RFbsSession::Disconnect(); |
|
77 RAknIconSrvClient::Disconnect(); |
|
78 } |
|
79 |
|
80 // -------------------------------------------------------------------------- |
|
81 // CTsFswDataList::ConstructL |
|
82 // -------------------------------------------------------------------------- |
|
83 // |
|
84 void CTsFswDataList::ConstructL( ) |
|
85 { |
|
86 User::LeaveIfError( iWsSession.Connect() ); |
|
87 User::LeaveIfError( iAppArcSession.Connect() ); |
|
88 iHiddenUids.AppendL( KHsApplicationUid ); |
|
89 iHiddenUids.AppendL( KTelephoneUid ); |
|
90 User::LeaveIfError(RFbsSession::Connect()); |
|
91 RAknIconSrvClient::Connect(); |
|
92 } |
|
93 |
|
94 // -------------------------------------------------------------------------- |
|
95 // CTsFswDataList::FswDataL |
|
96 // -------------------------------------------------------------------------- |
|
97 // |
|
98 const RTsFswArray& CTsFswDataList::FswDataL() |
|
99 { |
|
100 // check the dirty flag and refresh if needed |
|
101 if ( iTaskListDirty ) |
|
102 { |
|
103 CollectTasksL(); |
|
104 // dirty flag is cleared in the above call |
|
105 } |
|
106 |
|
107 return iData; |
|
108 } |
|
109 |
|
110 // -------------------------------------------------------------------------- |
|
111 // CTsFswDataList::CollectTasksL |
|
112 // -------------------------------------------------------------------------- |
|
113 // |
|
114 TBool CTsFswDataList::CollectTasksL() |
|
115 { |
|
116 // clear dirty flag |
|
117 iTaskListDirty = EFalse; |
|
118 TBool changed = EFalse; |
|
119 |
|
120 RTsFswArray newAppsList; |
|
121 |
|
122 CleanupResetAndDestroyPushL(newAppsList); |
|
123 |
|
124 CollectAppsL(newAppsList); |
|
125 |
|
126 changed |= FitDataToListL(newAppsList, EFalse); |
|
127 |
|
128 CleanupStack::PopAndDestroy( &newAppsList ); |
|
129 |
|
130 return changed; |
|
131 } |
|
132 |
|
133 |
|
134 // -------------------------------------------------------------------------- |
|
135 // CTsFswDataList::SetDirty() |
|
136 // -------------------------------------------------------------------------- |
|
137 // |
|
138 void CTsFswDataList::SetDirty() |
|
139 { |
|
140 iTaskListDirty = ETrue; |
|
141 } |
|
142 |
|
143 // -------------------------------------------------------------------------- |
|
144 // CTsFswDataList::SetAppDataRefreshNeeded() |
|
145 // -------------------------------------------------------------------------- |
|
146 // |
|
147 void CTsFswDataList::SetAppDataRefreshNeeded() |
|
148 { |
|
149 iAppDataRefreshNeeded = ETrue; |
|
150 } |
|
151 |
|
152 // -------------------------------------------------------------------------- |
|
153 // CTsFswDataList::MoveEntryAtStart |
|
154 // -------------------------------------------------------------------------- |
|
155 // |
|
156 void CTsFswDataList::MoveEntryAtStart(TInt aAppId, TBool /*aWidget*/) |
|
157 { |
|
158 TInt appId(0); |
|
159 //check embeded case |
|
160 |
|
161 TInt wgId(0); |
|
162 CApaWindowGroupName::FindByAppUid(TUid::Uid(aAppId), iWsSession, wgId); |
|
163 TInt parentWgId = FindMostTopParentWgId( wgId ); |
|
164 if( parentWgId != KErrNotFound ) |
|
165 { |
|
166 TUid appUid = TUid::Uid(0); |
|
167 AppUidForWgId(parentWgId, appUid); |
|
168 appId = appUid.iUid; |
|
169 } |
|
170 |
|
171 |
|
172 if( !appId ) |
|
173 { |
|
174 appId = aAppId; |
|
175 } |
|
176 |
|
177 for ( TInt i = 0; i < iData.Count(); ++i ) |
|
178 { |
|
179 if( iData[i]->AppUid().iUid == appId ) |
|
180 { |
|
181 CTsFswEntry* entry = iData[i]; |
|
182 iData.Remove(i); |
|
183 iData.Insert(entry, 0); |
|
184 iOrderChanged = ETrue; |
|
185 break; |
|
186 } |
|
187 } |
|
188 } |
|
189 |
|
190 // -------------------------------------------------------------------------- |
|
191 // CTsFswDataList:: |
|
192 // -------------------------------------------------------------------------- |
|
193 // |
|
194 void CTsFswDataList::CollectAppsL(RTsFswArray& aAppsList) |
|
195 { |
|
196 |
|
197 |
|
198 // update app data if needed |
|
199 // (usually on startup and when new apps might have been installed) |
|
200 if ( iAppDataRefreshNeeded ) |
|
201 { |
|
202 |
|
203 iAppArcSession.GetAllApps(); |
|
204 iAppDataRefreshNeeded = EFalse; |
|
205 } |
|
206 |
|
207 // get all window groups |
|
208 RArray<RWsSession::TWindowGroupChainInfo> allWgIds; |
|
209 CleanupClosePushL( allWgIds ); |
|
210 User::LeaveIfError( iWsSession.WindowGroupList( 0, &allWgIds ) ); |
|
211 |
|
212 TInt count = allWgIds.Count(); |
|
213 for ( TInt i = 0; i < count; ++i ) |
|
214 { |
|
215 // ignore uninteresting entries (e.g. embedded apps) |
|
216 if ( allWgIds[i].iParentId > 0 ) |
|
217 { |
|
218 continue; |
|
219 } |
|
220 |
|
221 // get window group name |
|
222 TInt wgId = allWgIds[i].iId; |
|
223 CApaWindowGroupName* windowName = |
|
224 CApaWindowGroupName::NewLC( iWsSession, wgId ); |
|
225 TUid appUid = windowName->AppUid(); |
|
226 |
|
227 // ignore entries with null uid |
|
228 if ( !appUid.iUid ) |
|
229 { |
|
230 CleanupStack::PopAndDestroy( windowName ); |
|
231 continue; |
|
232 } |
|
233 |
|
234 // add item to task list if it is not hidden |
|
235 if ( !windowName->Hidden() && !IsHiddenUid(appUid) ) |
|
236 { |
|
237 AddEntryL(wgId, appUid, windowName, aAppsList, EFalse); |
|
238 } |
|
239 CleanupStack::PopAndDestroy( windowName ); |
|
240 } |
|
241 CleanupStack::PopAndDestroy( &allWgIds ); |
|
242 } |
|
243 |
|
244 // -------------------------------------------------------------------------- |
|
245 // CTsFswDataList::AddEntryL |
|
246 // -------------------------------------------------------------------------- |
|
247 // |
|
248 TBool CTsFswDataList::AddEntryL( TInt aWgId, const TUid& aAppUid, |
|
249 CApaWindowGroupName* aWgName, RTsFswArray& aNewList, |
|
250 TBool /*aIsWidget*/ ) |
|
251 { |
|
252 TBool changed = EFalse; |
|
253 CTsFswEntry* entry = CTsFswEntry::NewLC(); |
|
254 entry->SetWgId( aWgId ); |
|
255 entry->SetAppUid( aAppUid ); |
|
256 |
|
257 // check if present in old list and if yes then take some of the old data |
|
258 TBool found = ConsiderOldDataL( *entry, aAppUid, changed, aNewList ); |
|
259 |
|
260 // if not present previously then find out app name |
|
261 // and check if screenshot is already available |
|
262 if ( !found ) |
|
263 { |
|
264 // when adding a new entry to the list it is changed for sure |
|
265 changed = ETrue; |
|
266 HBufC* name = FindAppNameLC( aWgName, aAppUid, aWgId ); |
|
267 if ( name ) |
|
268 { |
|
269 entry->SetAppNameL( *name ); |
|
270 } |
|
271 CleanupStack::PopAndDestroy( name ); |
|
272 |
|
273 if ( aWgName ) |
|
274 { |
|
275 entry->SetCloseableApp( !aWgName->IsSystem() ); |
|
276 } |
|
277 CFbsBitmap* iconBitmap = NULL; |
|
278 CFbsBitmap* iconMask = NULL; |
|
279 GetAppIconL(aAppUid, iconBitmap, iconMask); |
|
280 //transfer ownership to entry |
|
281 entry->SetAppIcon( iconBitmap, iconMask ); |
|
282 } |
|
283 |
|
284 // add to new list, ownership is transferred |
|
285 aNewList.AppendL( entry ); |
|
286 CleanupStack::Pop( entry ); |
|
287 return changed; |
|
288 } |
|
289 |
|
290 // -------------------------------------------------------------------------- |
|
291 // CTsFswDataList::ConsiderOldDataL |
|
292 // -------------------------------------------------------------------------- |
|
293 // |
|
294 TBool CTsFswDataList::ConsiderOldDataL( CTsFswEntry& aEntry, |
|
295 const TUid& aAppUid, |
|
296 TBool& aChanged, |
|
297 RTsFswArray& aNewList ) |
|
298 { |
|
299 for ( TInt entryIdx = 0, oldCount = iData.Count(); |
|
300 entryIdx < oldCount; ++entryIdx ) |
|
301 { |
|
302 // Enough to check appuid, no need to bother with wgid as the |
|
303 // screenshot handle is up-to-date or will be updated later anyway. |
|
304 if ( iData[entryIdx]->AppUid() == aAppUid ) |
|
305 { |
|
306 iData[entryIdx]->SetWgId( aEntry.WgId()); |
|
307 // if positions do not match then the list is different than before |
|
308 if ( entryIdx != aNewList.Count() ) |
|
309 { |
|
310 aChanged = ETrue; |
|
311 } |
|
312 CTsFswEntry* oldEntry = iData[entryIdx]; |
|
313 aEntry.SetAppNameL( oldEntry->AppName() ); |
|
314 aEntry.SetCloseableApp( oldEntry->CloseableApp() ); |
|
315 return ETrue; |
|
316 } |
|
317 } |
|
318 return EFalse; |
|
319 } |
|
320 |
|
321 |
|
322 // -------------------------------------------------------------------------- |
|
323 // CTsFswDataList::FindParentWgId |
|
324 // -------------------------------------------------------------------------- |
|
325 // |
|
326 TInt CTsFswDataList::FindParentWgId( TInt aWgId ) |
|
327 { |
|
328 TInt parent( KErrNotFound ); |
|
329 RArray<RWsSession::TWindowGroupChainInfo> allWgIds; |
|
330 // Ask for window group list from RWsSession |
|
331 TInt error = iWsSession.WindowGroupList( 0, &allWgIds ); |
|
332 if ( !error ) |
|
333 { |
|
334 TInt count( allWgIds.Count() ); |
|
335 for ( TInt i( 0 ); i < count; i++ ) |
|
336 { |
|
337 RWsSession::TWindowGroupChainInfo info = allWgIds[i]; |
|
338 if ( info.iId == aWgId && info.iParentId > 0) |
|
339 { |
|
340 parent = info.iParentId; |
|
341 break; |
|
342 } |
|
343 } |
|
344 } |
|
345 allWgIds.Close(); |
|
346 return parent; |
|
347 } |
|
348 |
|
349 // -------------------------------------------------------------------------- |
|
350 // CTsFswDataList::FindMostTopParentWgId |
|
351 // -------------------------------------------------------------------------- |
|
352 // |
|
353 TInt CTsFswDataList::FindMostTopParentWgId( TInt aWgId ) |
|
354 { |
|
355 TInt parent( KErrNotFound ); |
|
356 parent = FindParentWgId( aWgId ); |
|
357 if( parent != KErrNotFound) |
|
358 { |
|
359 TInt topParent = FindMostTopParentWgId(parent); |
|
360 if( topParent != KErrNotFound ) |
|
361 { |
|
362 parent = topParent; |
|
363 } |
|
364 } |
|
365 return parent; |
|
366 } |
|
367 |
|
368 // -------------------------------------------------------------------------- |
|
369 // CTsFswDataList::FindAppNameLC |
|
370 // -------------------------------------------------------------------------- |
|
371 // |
|
372 HBufC* CTsFswDataList::FindAppNameLC( CApaWindowGroupName* aWindowName, |
|
373 const TUid& aAppUid, |
|
374 TInt aWgId ) |
|
375 { |
|
376 //Retrieve the app name |
|
377 TApaAppInfo info; |
|
378 iAppArcSession.GetAppInfo( info, aAppUid ); |
|
379 TPtrC caption = info.iShortCaption; |
|
380 |
|
381 HBufC* tempName = 0; |
|
382 if ( !caption.Length() && aWindowName ) // if not set - use thread name instead |
|
383 { |
|
384 if ( aWindowName->Caption().Length() ) |
|
385 { |
|
386 tempName = aWindowName->Caption().AllocL(); |
|
387 //put on cleanupstack after the if |
|
388 } |
|
389 else |
|
390 { |
|
391 TThreadId threadId; |
|
392 TInt err = iWsSession.GetWindowGroupClientThreadId( |
|
393 aWgId, threadId ); |
|
394 if ( err == KErrNone ) |
|
395 { |
|
396 RThread thread; |
|
397 CleanupClosePushL( thread ); |
|
398 err = thread.Open ( threadId ); |
|
399 if ( err==KErrNone ) |
|
400 { |
|
401 tempName = thread.Name().AllocL(); // codescanner::forgottoputptroncleanupstack |
|
402 // tempName put on cleanupstack after the if |
|
403 } |
|
404 CleanupStack::PopAndDestroy( &thread ); |
|
405 } |
|
406 } |
|
407 } |
|
408 else |
|
409 { |
|
410 tempName = caption.AllocL(); |
|
411 //put on cleanupstack after the if |
|
412 } |
|
413 CleanupStack::PushL( tempName ); |
|
414 return tempName; |
|
415 } |
|
416 |
|
417 |
|
418 // -------------------------------------------------------------------------- |
|
419 // CTsFswDataList::FitDataToListL |
|
420 // -------------------------------------------------------------------------- |
|
421 // |
|
422 TBool CTsFswDataList::FitDataToListL(RTsFswArray& aListToFit, |
|
423 TBool /*aConsiderWidgets*/) |
|
424 { |
|
425 TBool changed = EFalse; |
|
426 TInt listCount = aListToFit.Count(); |
|
427 TInt dataCount = iData.Count(); |
|
428 |
|
429 |
|
430 //remove items that dont't exists in newly collected list |
|
431 for (TInt i = dataCount -1; i >= 0; --i) |
|
432 { |
|
433 if ( !CheckIfExists(*iData[i], aListToFit) ) |
|
434 { |
|
435 delete iData[i]; |
|
436 iData.Remove(i); |
|
437 changed = ETrue; |
|
438 } |
|
439 } |
|
440 |
|
441 //add new item at start |
|
442 //for (TInt i = 0; i < aListToFit.Count(); ++i) |
|
443 for (TInt i = aListToFit.Count()-1; i >= 0; --i) |
|
444 { |
|
445 if (!CheckIfExists(*aListToFit[i], iData)) |
|
446 { |
|
447 iData.Insert(aListToFit[i], 0); |
|
448 aListToFit[i] = 0; |
|
449 changed = ETrue; |
|
450 } |
|
451 } |
|
452 changed = changed || iOrderChanged; |
|
453 iOrderChanged = EFalse; |
|
454 return changed; |
|
455 } |
|
456 |
|
457 // -------------------------------------------------------------------------- |
|
458 // CTsFswDataList::CheckIfExists |
|
459 // -------------------------------------------------------------------------- |
|
460 // |
|
461 TBool CTsFswDataList::CheckIfExists(const CTsFswEntry& aEntry, |
|
462 const RTsFswArray& aList) const |
|
463 { |
|
464 TBool exists(EFalse); |
|
465 TInt dataCount = aList.Count(); |
|
466 for (TInt entryIdx = 0; entryIdx < dataCount; ++entryIdx) |
|
467 { |
|
468 if (aList[entryIdx]->AppUid() == aEntry.AppUid()) |
|
469 { |
|
470 exists = ETrue; |
|
471 break; |
|
472 } |
|
473 } |
|
474 return exists; |
|
475 } |
|
476 |
|
477 // -------------------------------------------------------------------------- |
|
478 // CTsFswDataList::AppUidForWgId |
|
479 // -------------------------------------------------------------------------- |
|
480 // |
|
481 TInt CTsFswDataList::AppUidForWgId( TInt aWgId, TUid& aUid ) |
|
482 { |
|
483 TRAPD(err, aUid = AppUidForWgIdL( aWgId ) ); |
|
484 return err; |
|
485 } |
|
486 |
|
487 // -------------------------------------------------------------------------- |
|
488 // CTsFswDataList::AppUidForWgIdL |
|
489 // -------------------------------------------------------------------------- |
|
490 // |
|
491 TUid CTsFswDataList::AppUidForWgIdL( TInt aWgId ) |
|
492 { |
|
493 CApaWindowGroupName* windowName = |
|
494 CApaWindowGroupName::NewLC( iWsSession, aWgId ); |
|
495 TUid appUid = windowName->AppUid(); |
|
496 CleanupStack::PopAndDestroy( windowName ); |
|
497 return appUid; |
|
498 } |
|
499 |
|
500 // -------------------------------------------------------------------------- |
|
501 // CTsFswDataList::GetAppIconL |
|
502 // -------------------------------------------------------------------------- |
|
503 // |
|
504 void CTsFswDataList::GetAppIconL( const TUid& aAppUid, |
|
505 CFbsBitmap*& aBitmap, CFbsBitmap*& aMask ) |
|
506 { |
|
507 aBitmap = aMask = NULL; |
|
508 |
|
509 TSize size( KAppIconWidth, KAppIconHeight ); |
|
510 CApaMaskedBitmap* apaMaskedBitmap = CApaMaskedBitmap::NewLC(); |
|
511 TInt err = iAppArcSession.GetAppIcon( aAppUid, size, *apaMaskedBitmap ); |
|
512 TInt iconsCount(0); |
|
513 if ( err == KErrNone ) |
|
514 { |
|
515 err = iAppArcSession.NumberOfOwnDefinedIcons(aAppUid, iconsCount); |
|
516 } |
|
517 |
|
518 if ( (err == KErrNone) && (iconsCount>0) ) |
|
519 { |
|
520 aBitmap = static_cast<CFbsBitmap*>(apaMaskedBitmap); |
|
521 TInt maskHandle = apaMaskedBitmap->Mask()->Handle(); |
|
522 aMask = new (ELeave) CFbsBitmap; |
|
523 aMask->Duplicate( maskHandle ); |
|
524 CleanupStack::Pop( apaMaskedBitmap ); |
|
525 } |
|
526 else |
|
527 { |
|
528 CleanupStack::PopAndDestroy( apaMaskedBitmap ); |
|
529 HBufC* fileNameFromApparc = NULL; |
|
530 TInt err = iAppArcSession.GetAppIcon(aAppUid,fileNameFromApparc); |
|
531 if ( err == KErrNone ) |
|
532 { |
|
533 CleanupStack::PushL(fileNameFromApparc); |
|
534 CFbsBitmap *bitamp(0); |
|
535 CFbsBitmap *mask(0); |
|
536 TInt bitmapIndex = 0; |
|
537 TInt maskIndex = 1; |
|
538 // it will change bitmap ids if it is mif (checking inside) |
|
539 AknIconUtils::ValidateLogicalAppIconId( *fileNameFromApparc, bitmapIndex, maskIndex ); |
|
540 AknIconUtils::CreateIconLC( bitamp, mask, fileNameFromApparc->Des(), bitmapIndex, maskIndex ); |
|
541 |
|
542 if (AknIconUtils::IsMifFile(*fileNameFromApparc)) \ |
|
543 { |
|
544 AknIconUtils::DisableCompression(bitamp); |
|
545 AknIconUtils::SetSize(bitamp, TSize(KAppIconWidth, KAppIconHeight), EAspectRatioPreservedAndUnusedSpaceRemoved); |
|
546 // bitmap and icon, AknsUtils::CreateIconLC doesn't specify the order |
|
547 CleanupStack::Pop(2); |
|
548 aBitmap = bitamp; |
|
549 aMask = mask; |
|
550 } |
|
551 else |
|
552 { |
|
553 CleanupStack::PopAndDestroy(2); |
|
554 } |
|
555 CleanupStack::PopAndDestroy(fileNameFromApparc); |
|
556 } |
|
557 } |
|
558 } |
|
559 |
|
560 // -------------------------------------------------------------------------- |
|
561 // CTsFswDataList::GetAppIconL |
|
562 // -------------------------------------------------------------------------- |
|
563 // |
|
564 TBool CTsFswDataList::IsHiddenUid( TUid aUid ) |
|
565 { |
|
566 TInt result = iHiddenUids.Find( aUid ); |
|
567 return result >= 0 ? ETrue : EFalse; |
|
568 } |
|
569 |
|
570 // end of file |