|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // aplappinforeader.cpp |
|
15 // |
|
16 |
|
17 #include "aplapplist.h" |
|
18 #include "aplapplistitem.h" |
|
19 #include "aplappinforeader.h" |
|
20 #include <apgaplst.h> |
|
21 #include <bautils.h> |
|
22 #include "APGICNFL.H" |
|
23 #include "APFDEF.H" |
|
24 #include "../apgrfx/apprivate.h" // KUidPrefixedNonNativeRegistrationResourceFile |
|
25 #include <barsc2.h> |
|
26 #include <barsread2.h> |
|
27 #include <e32uid.h> |
|
28 #include "../apgrfx/APGSTD.H" // EPanicNullPointer |
|
29 #include "../apgrfx/apsecutils.h" // CApaSecurityUtils |
|
30 |
|
31 const TUint KResourceOffsetMask = 0xFFFFF000; |
|
32 |
|
33 _LIT(KAppBinaryPathAndExtension, "\\sys\\bin\\.exe"); |
|
34 const TInt KAppRegistrationInfoResourceId = 1; |
|
35 |
|
36 // The 2nd UID that defines a resource file as being an application registration resource file. |
|
37 const TUid KUidAppRegistrationFile = {0x101F8021}; |
|
38 |
|
39 // |
|
40 // Local functions |
|
41 // |
|
42 |
|
43 extern void CleanupServiceArray(TAny* aServiceArray); // Implemented in AplAppList.cpp |
|
44 |
|
45 // ApaUtils |
|
46 |
|
47 TBool ApaUtils::TypeUidIsForRegistrationFile(const TUidType& aUidType) |
|
48 { // static |
|
49 return (aUidType[1].iUid==KUidAppRegistrationFile.iUid || |
|
50 aUidType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile); |
|
51 } |
|
52 |
|
53 |
|
54 // |
|
55 // CApaAppInfoReader |
|
56 // |
|
57 |
|
58 // The behaviour of the Take-methods of this class is a little non-standard, as it |
|
59 // transfers ownership of the pointer owned by a CApaAppInfoReader derived object |
|
60 // to the caller. This means that this function is only designed to be called once. |
|
61 // Doing things this way provides a small performance optimisation by enabling the caller |
|
62 // to delete it's stored pointer, and replace it with one returned by this function, |
|
63 // instead of having to copy the object (copying could be expensive for the methods |
|
64 // of this class that need to return arrays). |
|
65 |
|
66 |
|
67 CApaAppInfoReader* CApaAppInfoReader::NewL(RFs& aFs, const TDesC& aRegistrationFileName, TUid aAppUid) |
|
68 { |
|
69 CApaAppInfoReader* self = new(ELeave) CApaAppInfoReader(aFs, aRegistrationFileName, aAppUid); |
|
70 CleanupStack::PushL(self); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop(self); |
|
73 return self; |
|
74 } |
|
75 |
|
76 CApaAppInfoReader::CApaAppInfoReader(RFs& aFs, const TDesC& aRegistrationFileName, TUid aAppUid) : |
|
77 iFs(aFs), |
|
78 iAppUid(aAppUid), |
|
79 iTimeStamp(0), |
|
80 iDefaultScreenNumber(0), |
|
81 iNonMbmIconFile(EFalse), |
|
82 iLocalisableResourceFileTimeStamp(0), |
|
83 iApplicationLanguage(ELangNone), |
|
84 iIndexOfFirstOpenService(KErrNotFound), |
|
85 iRegistrationFileName(aRegistrationFileName) |
|
86 { |
|
87 } |
|
88 |
|
89 void CApaAppInfoReader::ConstructL() |
|
90 { |
|
91 iIconLoader = CApaIconLoader::NewL(iFs); |
|
92 } |
|
93 |
|
94 CApaAppInfoReader::~CApaAppInfoReader() |
|
95 { |
|
96 delete iAppBinaryFullName; |
|
97 delete iCaption; |
|
98 delete iShortCaption; |
|
99 delete iIcons; |
|
100 if (iViewDataArray) |
|
101 iViewDataArray->ResetAndDestroy(); |
|
102 |
|
103 delete iViewDataArray; |
|
104 delete iOwnedFileArray; |
|
105 delete iIconFileName; |
|
106 delete iLocalisableResourceFileName; |
|
107 |
|
108 if (iServiceArray) |
|
109 { |
|
110 CleanupServiceArray(iServiceArray); |
|
111 iServiceArray = NULL; |
|
112 } |
|
113 |
|
114 delete iOpaqueData; |
|
115 delete iIconLoader; |
|
116 } |
|
117 |
|
118 HBufC* CApaAppInfoReader::AppBinaryFullName() |
|
119 { |
|
120 HBufC* fileName = iAppBinaryFullName; |
|
121 iAppBinaryFullName = NULL; // ownership transferred to caller |
|
122 return fileName; |
|
123 } |
|
124 |
|
125 TUidType CApaAppInfoReader::AppBinaryUidType() const |
|
126 { |
|
127 return iAppBinaryUidType; |
|
128 } |
|
129 |
|
130 TTime CApaAppInfoReader::TimeStamp() const |
|
131 { |
|
132 return iTimeStamp; |
|
133 } |
|
134 |
|
135 TTime CApaAppInfoReader::IconFileTimeStamp() const |
|
136 { |
|
137 return iIconFileTimeStamp; |
|
138 } |
|
139 |
|
140 void CApaAppInfoReader::Capability(TDes8& aCapabilityBuf) const |
|
141 { |
|
142 TApaAppCapabilityBuf buf(iCapability); |
|
143 TApaAppCapability::CopyCapability(aCapabilityBuf, buf); |
|
144 } |
|
145 |
|
146 TUint CApaAppInfoReader::DefaultScreenNumber() const |
|
147 { |
|
148 return iDefaultScreenNumber; |
|
149 } |
|
150 |
|
151 HBufC* CApaAppInfoReader::Caption() |
|
152 { |
|
153 HBufC* caption = iCaption; |
|
154 iCaption = NULL; // ownership transferred to caller |
|
155 return caption; |
|
156 } |
|
157 |
|
158 HBufC* CApaAppInfoReader::ShortCaption() |
|
159 { |
|
160 HBufC* shortCaption = iShortCaption; |
|
161 iShortCaption = NULL; // ownership transferred to caller |
|
162 return shortCaption; |
|
163 } |
|
164 |
|
165 CApaAppIconArray* CApaAppInfoReader::Icons() |
|
166 { |
|
167 CApaAppIconArray* icons = iIcons; |
|
168 iIcons = NULL; // ownership transferred to caller |
|
169 return icons; |
|
170 } |
|
171 |
|
172 TInt CApaAppInfoReader::NumOfAppIcons() const |
|
173 { |
|
174 return iNumOfAppIcons; |
|
175 } |
|
176 |
|
177 CArrayPtrFlat<CApaAppViewData>* CApaAppInfoReader::Views() |
|
178 { |
|
179 CArrayPtrFlat<CApaAppViewData>* viewDataArray = iViewDataArray; |
|
180 iViewDataArray = NULL; // ownership transferred to caller |
|
181 return viewDataArray; |
|
182 } |
|
183 |
|
184 CDesCArray* CApaAppInfoReader::OwnedFiles() |
|
185 { |
|
186 CDesCArray* ownedFileArray = iOwnedFileArray; |
|
187 iOwnedFileArray = NULL; // ownership transferred to caller |
|
188 return ownedFileArray; |
|
189 } |
|
190 |
|
191 HBufC* CApaAppInfoReader::IconFileName() |
|
192 { |
|
193 HBufC* iconFileName = iIconFileName; |
|
194 iIconFileName = NULL; // ownership transferred to caller |
|
195 return iconFileName; |
|
196 } |
|
197 |
|
198 TBool CApaAppInfoReader::NonMbmIconFile() const |
|
199 { |
|
200 return iNonMbmIconFile; |
|
201 } |
|
202 |
|
203 HBufC* CApaAppInfoReader::LocalisableResourceFileName() |
|
204 { |
|
205 HBufC* localisableResourceFileName = iLocalisableResourceFileName; |
|
206 iLocalisableResourceFileName = NULL; // ownership transferred to caller |
|
207 return localisableResourceFileName; |
|
208 } |
|
209 |
|
210 TTime CApaAppInfoReader::LocalisableResourceFileTimeStamp() const |
|
211 { |
|
212 return iLocalisableResourceFileTimeStamp; |
|
213 } |
|
214 |
|
215 TLanguage CApaAppInfoReader::AppLanguage() const |
|
216 { |
|
217 return iApplicationLanguage; |
|
218 } |
|
219 |
|
220 CArrayFixFlat<TApaAppServiceInfo>* CApaAppInfoReader::ServiceArray(TInt& aIndexOfFirstOpenService) |
|
221 { |
|
222 CArrayFixFlat<TApaAppServiceInfo>* serviceArray = iServiceArray; |
|
223 iServiceArray = NULL; |
|
224 aIndexOfFirstOpenService = iIndexOfFirstOpenService; |
|
225 return serviceArray; |
|
226 } |
|
227 |
|
228 HBufC8* CApaAppInfoReader::OpaqueData() |
|
229 { |
|
230 HBufC8* opaqueData = iOpaqueData; |
|
231 iOpaqueData = NULL; |
|
232 return opaqueData; |
|
233 } |
|
234 |
|
235 CApaIconLoader* CApaAppInfoReader::IconLoader() |
|
236 { |
|
237 CApaIconLoader* iconLoader = iIconLoader; |
|
238 iIconLoader = NULL; // ownership transferred to caller |
|
239 return iconLoader; |
|
240 } |
|
241 |
|
242 // reads as much info as it can |
|
243 // at least captions and icons must be setup on return from this method (using defaults if necessary) |
|
244 TBool CApaAppInfoReader::ReadL() |
|
245 { |
|
246 TEntry entry; |
|
247 User::LeaveIfError(iFs.Entry(iRegistrationFileName, entry)); |
|
248 iTimeStamp = entry.iModified; |
|
249 |
|
250 TUint fileOffset = 0; |
|
251 TInt fileLength = 0; |
|
252 TUid firstUid(KExecutableImageUid); |
|
253 TUid middleUid(KUidApp); |
|
254 |
|
255 // in the case of a non-native application, the resource file |
|
256 // has been padded with the application type uid |
|
257 |
|
258 if (TParsePtrC(iRegistrationFileName).Path().CompareF(KLitPathForNonNativeResourceAndIconFiles)==0) |
|
259 { |
|
260 fileOffset = sizeof(TCheckedUid); |
|
261 fileLength = entry.iSize-fileOffset; |
|
262 firstUid = KNullUid; |
|
263 middleUid = entry[1]; |
|
264 if (middleUid == KNullUid) |
|
265 User::Leave(KErrCorrupt); |
|
266 } |
|
267 |
|
268 // set the TUidType for the app binary |
|
269 // cannot read the TEntry info from the app binary because it's in \sys\bin |
|
270 iAppBinaryUidType = TUidType(firstUid, middleUid, iAppUid); |
|
271 |
|
272 CResourceFile* registrationFile = CResourceFile::NewLC(iFs, iRegistrationFileName, fileOffset, fileLength); |
|
273 RResourceReader resourceReader; |
|
274 resourceReader.OpenLC(registrationFile, KAppRegistrationInfoResourceId); |
|
275 |
|
276 TRAPD(err, ReadMandatoryInfoL(resourceReader)); |
|
277 if (err) |
|
278 { |
|
279 CleanupStack::PopAndDestroy(); // resourceReader |
|
280 CleanupStack::PopAndDestroy(registrationFile); |
|
281 return EFalse; // might have read something, but failed to setup enough info to make it worthwhile trying to read any more |
|
282 } |
|
283 |
|
284 CResourceFile* localisableFile = NULL; |
|
285 TUint localisableResourceId = 1; // only initialising this here to keep the compiler happy, as it's concerned that the variable might be used without having been initialised. The variable should be initialised later, before it's used |
|
286 TRAP(err, ReadNonLocalisableInfoL(resourceReader, localisableFile, localisableResourceId)); |
|
287 |
|
288 if (!err) |
|
289 TRAP(err, ReadNonLocalisableOptionalInfoL(resourceReader, registrationFile, localisableFile)); |
|
290 |
|
291 TBool useDefaultIcons = ETrue; |
|
292 if (!err && localisableFile) |
|
293 TRAP(err, ReadLocalisableInfoL(*localisableFile, localisableResourceId, useDefaultIcons)); |
|
294 |
|
295 delete localisableFile; |
|
296 localisableFile = NULL; |
|
297 |
|
298 // if anything went wrong, we tell the caller that the read was unsuccessful. Some |
|
299 // of the members of this class may contain data which is not complete, but this doesn't matter |
|
300 // because the caller shouldn't try to access the data if the read was unsuccessful |
|
301 const TBool readSuccessful = (err == KErrNone); |
|
302 |
|
303 if (useDefaultIcons) |
|
304 { |
|
305 delete iIcons; |
|
306 iIcons = NULL; |
|
307 TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL()); |
|
308 } |
|
309 |
|
310 CleanupStack::PopAndDestroy(); // resourceReader |
|
311 CleanupStack::PopAndDestroy(registrationFile); |
|
312 return readSuccessful; |
|
313 } |
|
314 |
|
315 |
|
316 // this method reads the minimum information required to register an app |
|
317 // if this fails (Leaves), we say the read has been unsuccessful |
|
318 void CApaAppInfoReader::ReadMandatoryInfoL(RResourceReader& aResourceReader) |
|
319 { |
|
320 aResourceReader.ReadUint32L(); // skip over LONG reserved_long |
|
321 aResourceReader.ReadUint32L(); // skip over LLINK reserved_llink |
|
322 |
|
323 // read LTEXT app_file |
|
324 const TPtrC appFile(aResourceReader.ReadTPtrCL()); |
|
325 TParse parse; // this object gets used for 2 purposes: first to check that a TParsePtrC can be created over "appFile" without it panicking, and second to construct iAppBinaryFullName |
|
326 User::LeaveIfError(parse.SetNoWild(appFile, NULL, NULL)); // do this before creating a TParsePtrC, since TParsePtrC's constructor panics if it fails (which would provide an easy way for malware to kill the Apparc server) |
|
327 const TParsePtrC appFileParser(appFile); |
|
328 |
|
329 // read LONG attributes |
|
330 iCapability.iAttributes = aResourceReader.ReadUint32L(); |
|
331 |
|
332 if (!appFileParser.NamePresent()) |
|
333 User::Leave(KErrCorrupt); |
|
334 |
|
335 const TPtrC appNameWithoutExtension(appFileParser.Name()); |
|
336 const TPtrC registrationFileDrive(TParsePtrC(iRegistrationFileName).Drive()); |
|
337 |
|
338 if (iCapability.iAttributes & TApaAppCapability::ENonNative) |
|
339 { |
|
340 if (!appFileParser.PathPresent() || !appFileParser.ExtPresent()) |
|
341 User::Leave(KErrCorrupt); |
|
342 |
|
343 const TPtrC appFilePath(appFileParser.Path()); |
|
344 const TPtrC appFileNameAndExt(appFileParser.NameAndExt()); |
|
345 TPtrC appFileDrive(registrationFileDrive); |
|
346 if (appFileParser.DrivePresent()) |
|
347 appFileDrive.Set(appFileParser.Drive()); |
|
348 |
|
349 User::LeaveIfError(parse.SetNoWild(appFileDrive, &appFilePath, &appFileNameAndExt)); |
|
350 } |
|
351 else if (iCapability.iAttributes & TApaAppCapability::EBuiltAsDll) |
|
352 { |
|
353 User::Leave(KErrNotSupported); // legacy dll-style app |
|
354 } |
|
355 else |
|
356 { |
|
357 // exe-style app |
|
358 User::LeaveIfError(parse.SetNoWild(registrationFileDrive, &KAppBinaryPathAndExtension, &appNameWithoutExtension)); |
|
359 } |
|
360 |
|
361 iAppBinaryFullName = parse.FullName().AllocL(); |
|
362 } |
|
363 |
|
364 |
|
365 HBufC* CApaAppInfoReader::CreateFullIconFileNameL(const TDesC& aIconFileName) const |
|
366 { |
|
367 HBufC* filename = NULL; |
|
368 if (aIconFileName.Length() == 0) |
|
369 return NULL; |
|
370 /* |
|
371 * aIconFileName may contain a valid string in some format (for eg. URI format) other than path to a regular file on disk |
|
372 * and that can be a mbm or non-mbm file. Such a filename will be reported as invalid filename by iFs.IsValidName() method. |
|
373 * aIconFileName will be returned since it is a valid string. |
|
374 */ |
|
375 if(!iFs.IsValidName(aIconFileName)) |
|
376 { |
|
377 filename = aIconFileName.AllocL(); |
|
378 return filename; |
|
379 } |
|
380 |
|
381 TParsePtrC parsePtr(aIconFileName); |
|
382 if (parsePtr.IsWild() || !parsePtr.PathPresent() || !parsePtr.NamePresent()) |
|
383 return NULL; |
|
384 |
|
385 // check for fully qualified icon filename |
|
386 if (parsePtr.DrivePresent() && BaflUtils::FileExists(iFs, aIconFileName)) |
|
387 filename = aIconFileName.AllocL(); |
|
388 else |
|
389 { |
|
390 // check for icon file on same drive as localisable resource file |
|
391 TParse parse; |
|
392 TPtrC localisableResourceFileDrive = TParsePtrC(*iLocalisableResourceFileName).Drive(); |
|
393 TInt ret = parse.SetNoWild(localisableResourceFileDrive, &aIconFileName, NULL); |
|
394 if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName())) |
|
395 filename = parse.FullName().AllocL(); |
|
396 else |
|
397 { |
|
398 TPtrC registrationFileDrive = TParsePtrC(iRegistrationFileName).Drive(); |
|
399 if (TInt(TDriveUnit(registrationFileDrive)) != TInt(TDriveUnit(localisableResourceFileDrive))) |
|
400 { |
|
401 // check for icon file on same drive as registration file |
|
402 ret = parse.SetNoWild(registrationFileDrive, &aIconFileName, NULL); |
|
403 if (ret == KErrNone && BaflUtils::FileExists(iFs, parse.FullName())) |
|
404 filename = parse.FullName().AllocL(); |
|
405 } |
|
406 } |
|
407 } |
|
408 |
|
409 return filename; |
|
410 } |
|
411 |
|
412 void CApaAppInfoReader::ReadLocalisableInfoL(const CResourceFile& aResourceFile, TUint aResourceId, TBool& aUseDefaultIcons) |
|
413 { |
|
414 RResourceReader resourceReader; |
|
415 resourceReader.OpenLC(&aResourceFile, aResourceId); |
|
416 |
|
417 resourceReader.ReadUint32L(); // skip over LONG reserved_long |
|
418 resourceReader.ReadUint32L(); // skip over LLINK reserved_llink |
|
419 |
|
420 // read LTEXT short_caption |
|
421 iShortCaption = resourceReader.ReadHBufCL(); |
|
422 |
|
423 resourceReader.ReadUint32L(); // skip over LONG reserved_long |
|
424 resourceReader.ReadUint32L(); // skip over LLINK reserved_llink |
|
425 |
|
426 // read LTEXT caption |
|
427 iCaption = resourceReader.ReadHBufCL(); |
|
428 |
|
429 // read WORD number_of_icons |
|
430 const TInt numOfIcons = resourceReader.ReadInt16L(); |
|
431 iNumOfAppIcons = numOfIcons; |
|
432 |
|
433 // read LTEXT icon_file |
|
434 TPtrC iconFile = resourceReader.ReadTPtrCL(); |
|
435 |
|
436 ASSERT(!iIconFileName); |
|
437 iIconFileName = CreateFullIconFileNameL(iconFile); |
|
438 if (iIconFileName) |
|
439 { |
|
440 TEntry entry; |
|
441 TInt ret = iFs.Entry(*iIconFileName, entry); |
|
442 if (KErrNone == ret) |
|
443 iIconFileTimeStamp = entry.iModified; |
|
444 |
|
445 |
|
446 aUseDefaultIcons = EFalse; |
|
447 if (iFs.IsValidName(*iIconFileName)) |
|
448 { |
|
449 RFile file; |
|
450 TInt fileSize( 0 ); |
|
451 User::LeaveIfError( file.Open(iFs, *iIconFileName, EFileShareReadersOnly )); |
|
452 CleanupClosePushL( file ); |
|
453 User::LeaveIfError( file.Size( fileSize ) ); |
|
454 CleanupStack::PopAndDestroy();//file |
|
455 if ( fileSize > 0 ) |
|
456 { |
|
457 if(FileIsMbmWithGenericExtensionL(*iIconFileName)) |
|
458 { |
|
459 if (numOfIcons > 0) |
|
460 { |
|
461 CApaAppIconArray* iconArray = CApaAppIconArray::NewAppIconsL(numOfIcons, *iIconFileName, *iIconLoader); |
|
462 delete iIcons; |
|
463 iIcons = iconArray; |
|
464 } |
|
465 else |
|
466 { |
|
467 aUseDefaultIcons = ETrue; |
|
468 } |
|
469 } |
|
470 else |
|
471 { |
|
472 iNonMbmIconFile = ETrue; |
|
473 } |
|
474 } |
|
475 //File is of size 0 with Valid filename |
|
476 else |
|
477 { |
|
478 aUseDefaultIcons = ETrue; |
|
479 } |
|
480 } |
|
481 //If the filename is not a valid name then the file is treated as a non-mbm file. |
|
482 else |
|
483 { |
|
484 iNonMbmIconFile = ETrue; |
|
485 } |
|
486 } |
|
487 |
|
488 // read LEN WORD STRUCT view_list[] |
|
489 const TInt numOfViews = resourceReader.ReadInt16L(); |
|
490 if (numOfViews > 0) |
|
491 iViewDataArray = new(ELeave) CArrayPtrFlat<CApaAppViewData>(1); |
|
492 |
|
493 for(TInt view = 0; view < numOfViews; ++view) |
|
494 { |
|
495 CApaAppViewData* viewData = CApaAppViewData::NewLC(); |
|
496 resourceReader.ReadUint32L(); // skip over LONG reserved_long |
|
497 resourceReader.ReadUint32L(); // skip over LLINK reserved_llink |
|
498 |
|
499 // read LONG uid |
|
500 const TUid viewUid = {resourceReader.ReadInt32L()}; |
|
501 viewData->SetUid(viewUid); |
|
502 // read LONG screen_mode |
|
503 const TInt screenMode = {resourceReader.ReadInt32L()}; |
|
504 viewData->SetScreenMode(screenMode); |
|
505 |
|
506 resourceReader.ReadUint32L(); // skip over LONG reserved_long |
|
507 resourceReader.ReadUint32L(); // skip over LLINK reserved_llink |
|
508 |
|
509 // read LTEXT caption |
|
510 TPtrC viewCaption = resourceReader.ReadTPtrCL(); |
|
511 viewData->SetCaptionL(viewCaption); |
|
512 // read WORD number_of_icons |
|
513 const TInt numOfViewIcons = resourceReader.ReadInt16L(); |
|
514 viewData->SetNumOfViewIcons(numOfViewIcons); |
|
515 |
|
516 // read LTEXT icon_file |
|
517 TPtrC viewIconFile = resourceReader.ReadTPtrCL(); |
|
518 HBufC* const fullViewIconFileName = CreateFullIconFileNameL(viewIconFile); |
|
519 if (fullViewIconFileName) |
|
520 { |
|
521 CleanupStack::PushL(fullViewIconFileName); |
|
522 viewIconFile.Set(*fullViewIconFileName); |
|
523 viewData->SetIconFileNameL(viewIconFile); |
|
524 |
|
525 if (iFs.IsValidName(viewIconFile)) |
|
526 { |
|
527 if(!FileIsMbmWithGenericExtensionL(viewIconFile)) |
|
528 viewData->SetNonMbmIconFile(ETrue); |
|
529 } |
|
530 else //If the filename is not a valid name then the file is treated as a non-mbm file. |
|
531 viewData->SetNonMbmIconFile(ETrue); |
|
532 } |
|
533 else |
|
534 { |
|
535 viewIconFile.Set(KNullDesC); |
|
536 if (numOfViewIcons > 0 && iIconFileName) |
|
537 viewIconFile.Set(*iIconFileName); // default to app icon filename |
|
538 } |
|
539 if (numOfViewIcons > 0 && iFs.IsValidName(viewIconFile) && FileIsMbmWithGenericExtensionL(viewIconFile)) |
|
540 { |
|
541 CApaAppIconArray* iconArray = CApaAppIconArray::NewViewIconsL(numOfViewIcons, viewIconFile, *iIconLoader); |
|
542 viewData->SetIconArray(iconArray); |
|
543 iconArray = NULL; |
|
544 } |
|
545 |
|
546 if (fullViewIconFileName) |
|
547 CleanupStack::PopAndDestroy(fullViewIconFileName); |
|
548 |
|
549 iViewDataArray->AppendL(viewData); |
|
550 CleanupStack::Pop(viewData); |
|
551 } |
|
552 |
|
553 // Read LTEXT group_name |
|
554 // If a localised group name has been specified, it overrides |
|
555 // The group name (if any), specified by APP_REGISTRATION_INFO |
|
556 |
|
557 TApaAppGroupName groupName; |
|
558 TRAPD(ret, (groupName = resourceReader.ReadTPtrCL())); |
|
559 if (ret != KErrNone) |
|
560 { |
|
561 if (ret != KErrEof) |
|
562 User::Leave(ret); |
|
563 } |
|
564 else |
|
565 { |
|
566 if (groupName.Length() > 0) |
|
567 iCapability.iGroupName = groupName; |
|
568 } |
|
569 |
|
570 CleanupStack::PopAndDestroy(&resourceReader); |
|
571 } |
|
572 |
|
573 /*An MBM file may have a generic icon extension. In this case, as a way to check whether the file is an MBM one, |
|
574 it is necessary to read the content of the fist four 32bit words of it and find out whether these words correspond to |
|
575 KWriteonceFileStoreUid, KMultiBitmapFileImageUid, zero and KMultiBitmapFileImageChecksum respectively (defined in graphics/gditools/bmconv/bmconv.h). |
|
576 So the file is opened and the first 4 32 bit words are extracted and compared with the header information of standard MBM file. |
|
577 If they match, the function returns ETrue, else it returns EFalse */ |
|
578 TBool CApaAppInfoReader::FileIsMbmWithGenericExtensionL(const TDesC& aFileName) |
|
579 { |
|
580 if (aFileName.Length() > 0) |
|
581 { |
|
582 //open a file in Share mode - this will allow other methods to access it too |
|
583 RFile file; |
|
584 RFs fs; |
|
585 User::LeaveIfError(fs.Connect()); |
|
586 CleanupClosePushL(fs); |
|
587 User::LeaveIfError(file.Open(fs,aFileName,EFileShareReadersOnly)); |
|
588 //this is done beacuse the file can also be accessed by applist at the same time |
|
589 //buffer stores the 16 bytes of the file |
|
590 CleanupClosePushL(file); |
|
591 TBuf8<16> buffer; |
|
592 User::LeaveIfError(file.Read(buffer,16)); |
|
593 CleanupStack::PopAndDestroy();//file |
|
594 CleanupStack::PopAndDestroy(&fs);//fs |
|
595 //we use a constant pointer to the buffer to read header info |
|
596 TPtrC8 filePointer(buffer); |
|
597 |
|
598 /*The first 16 bytes of an MBM file are the same for any generic MBM file. |
|
599 These are : |
|
600 KWriteOnceFileStoreUid = 0x10000037(Emulator MBM file) 0x10000041(ROM image) |
|
601 KMultiBitMapFileImageUid = 0x10000042(Emulator MBM file) 0x00000001(ROM image) |
|
602 Zero = 0x00000000(Emulator MBM file) 0x0000000C(ROM image) |
|
603 checksum = 0x47396439(Emulator MBM file) 0x10000040(ROM image) |
|
604 The first 16 bytes of the given file is compared with these standard values to ascertain it is MBM file*/ |
|
605 if((filePointer[3]==0x10)&&(filePointer[2]==0x00)&&(filePointer[1]==0x00)&&(filePointer[0]==0x37)) |
|
606 {//KWriteOnceFileStoreUid = 0x10000037 |
|
607 if((filePointer[7]==0x10)&&(filePointer[6]==0x00)&&(filePointer[5]==0x00)&&(filePointer[4]==0x42)) |
|
608 {//KMultiBitMapFileImageUid = 0x10000042 |
|
609 if((filePointer[11]==0x00)&&(filePointer[10]==0x00)&&(filePointer[9]==0x00)&&(filePointer[8]==0x00)) |
|
610 {//Zero = 0x00000000) |
|
611 if((filePointer[15]==0x47)&&(filePointer[14]==0x39)&&(filePointer[13]==0x64)&&(filePointer[12]==0x39)) |
|
612 {//checksum = 0x47396439 |
|
613 return ETrue; |
|
614 } |
|
615 } |
|
616 } |
|
617 } |
|
618 //Else Check for ROM Image MBM file's header |
|
619 else if((filePointer[3]==0x10)&&(filePointer[2]==0x00)&&(filePointer[1]==0x00)&&(filePointer[0]==0x41)) |
|
620 {//KWriteOnceFileStoreUid = 0x10000041 |
|
621 if((filePointer[7]==0x00)&&(filePointer[6]==0x00)&&(filePointer[5]==0x00)&&(filePointer[4]==0x01)) |
|
622 {//KMultiBitMapFileImageUid = 0x00000001 |
|
623 if((filePointer[11]==0x00)&&(filePointer[10]==0x00)&&(filePointer[9]==0x00)&&(filePointer[8]==0x0C)) |
|
624 {//Zero = 0x0000000C) |
|
625 if((filePointer[15]==0x10)&&(filePointer[14]==0x00)&&(filePointer[13]==0x00)&&(filePointer[12]==0x40)) |
|
626 {//checksum = 0x10000040 |
|
627 return ETrue; |
|
628 } |
|
629 } |
|
630 } |
|
631 } |
|
632 } |
|
633 return EFalse; |
|
634 } |
|
635 |
|
636 HBufC8* CApaAppInfoReader::ReadOpaqueDataL(TUint aResourceId, const CResourceFile* aRegistrationFile, CResourceFile* aLocalisableResourceFile) |
|
637 { // static |
|
638 HBufC8* opaqueData = NULL; |
|
639 if (aResourceId == 0) |
|
640 opaqueData = HBufC8::NewL(0); |
|
641 else |
|
642 { |
|
643 if (aResourceId & KResourceOffsetMask) |
|
644 { |
|
645 // expecting opaque data to be in the localisable resource file |
|
646 if (aLocalisableResourceFile) |
|
647 { |
|
648 aLocalisableResourceFile->ConfirmSignatureL(); |
|
649 opaqueData = aLocalisableResourceFile->AllocReadLC(aResourceId); |
|
650 CleanupStack::Pop(opaqueData); |
|
651 } |
|
652 else |
|
653 opaqueData = HBufC8::NewL(0); |
|
654 } |
|
655 else |
|
656 { |
|
657 // expecting opaque data to be in the registration file |
|
658 __ASSERT_ALWAYS(aRegistrationFile, Panic(EPanicNullPointer)); |
|
659 opaqueData = aRegistrationFile->AllocReadLC(aResourceId); //lint !e613 Suppress ossible use of null pointer |
|
660 CleanupStack::Pop(opaqueData); |
|
661 } |
|
662 } |
|
663 |
|
664 return opaqueData; |
|
665 } |
|
666 |
|
667 void CApaAppInfoReader::ReadNonLocalisableOptionalInfoL(RResourceReader& aResourceReader, const CResourceFile* aRegistrationFile, CResourceFile* aLocalisableResourceFile) |
|
668 { |
|
669 // read LEN WORD STRUCT service_list[] |
|
670 TInt serviceCount = 0; |
|
671 // service information was not present in the first release of the registration file |
|
672 // APP_REGISTRATION_INFO resource struct |
|
673 // this method must not leave if the registration file doesn't contain service information, so the |
|
674 // following call to ReadInt16L is trapped to ensure this method doesn't leave just because |
|
675 // there is no more information in the resource to read (KErrEof) |
|
676 TRAPD(err, serviceCount = aResourceReader.ReadInt16L()); |
|
677 if (err) |
|
678 { |
|
679 if (err == KErrEof) |
|
680 return; // end of resource reached |
|
681 |
|
682 User::Leave(err); |
|
683 } |
|
684 |
|
685 if (!iServiceArray && serviceCount > 0) |
|
686 iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4); |
|
687 |
|
688 while (serviceCount--) |
|
689 { |
|
690 const TUid serviceUid = {aResourceReader.ReadUint32L()}; |
|
691 |
|
692 if ((serviceUid == KOpenServiceUid) && (iOpenServiceIsLegacy)) |
|
693 { |
|
694 ASSERT(iIndexOfFirstOpenService == 0); |
|
695 // If we found an Open service in the SERVICE_INFO declaration |
|
696 // then we must ignore the legacy one |
|
697 (*iServiceArray)[0].Release(); |
|
698 iServiceArray->Delete(0); |
|
699 iOpenServiceIsLegacy = EFalse; |
|
700 iIndexOfFirstOpenService = KErrNotFound; |
|
701 } |
|
702 |
|
703 CArrayFixFlat<TDataTypeWithPriority>* mimeTypesSupported = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(5); |
|
704 CleanupStack::PushL(mimeTypesSupported); |
|
705 ReadMimeTypesSupportedL(aResourceReader, *mimeTypesSupported); |
|
706 |
|
707 const TUint resourceId = aResourceReader.ReadUint32L(); |
|
708 HBufC8* opaqueData = NULL; |
|
709 opaqueData = ReadOpaqueDataL(resourceId, aRegistrationFile, aLocalisableResourceFile); |
|
710 CleanupStack::PushL(opaqueData); |
|
711 |
|
712 TApaAppServiceInfo serviceInfo(serviceUid, mimeTypesSupported, opaqueData); // takes ownership of opaqueData |
|
713 iServiceArray->AppendL(serviceInfo); |
|
714 CleanupStack::Pop(opaqueData); |
|
715 CleanupStack::Pop(mimeTypesSupported); |
|
716 if ((serviceUid == KOpenServiceUid) && (iIndexOfFirstOpenService < 0)) |
|
717 iIndexOfFirstOpenService = iServiceArray->Count() - 1; |
|
718 } |
|
719 |
|
720 // read LLINK opaque_data |
|
721 const TUint resourceId = aResourceReader.ReadUint32L(); |
|
722 delete iOpaqueData; |
|
723 iOpaqueData = NULL; |
|
724 iOpaqueData = ReadOpaqueDataL(resourceId, aRegistrationFile, aLocalisableResourceFile); |
|
725 } |
|
726 |
|
727 void CApaAppInfoReader::ReadNonLocalisableInfoL(RResourceReader& aResourceReader, CResourceFile*& aLocalisableResourceFile, TUint& aLocalisableResourceId) |
|
728 { |
|
729 ASSERT(aLocalisableResourceFile == NULL); |
|
730 |
|
731 // read LTEXT localisable_resource_file |
|
732 TPtrC localisableResourceFileName(aResourceReader.ReadTPtrCL()); |
|
733 if (localisableResourceFileName.Length() > 0 && iFs.IsValidName(localisableResourceFileName)) |
|
734 { |
|
735 // determine the language specific name of the localisable resource file |
|
736 TParse parse; |
|
737 TParsePtrC parsePtr(iRegistrationFileName); |
|
738 User::LeaveIfError(parse.SetNoWild(parsePtr.Drive(), &KAppResourceFileExtension, &localisableResourceFileName)); |
|
739 TFileName resourceFileName(parse.FullName()); |
|
740 BaflUtils::NearestLanguageFileV2(iFs, resourceFileName, iApplicationLanguage); |
|
741 iLocalisableResourceFileName = resourceFileName.AllocL(); |
|
742 |
|
743 TEntry entry; |
|
744 User::LeaveIfError(iFs.Entry(*iLocalisableResourceFileName, entry)); |
|
745 iLocalisableResourceFileTimeStamp = entry.iModified; |
|
746 |
|
747 |
|
748 // open the localisable resource file |
|
749 aLocalisableResourceFile = CResourceFile::NewL(iFs, resourceFileName, 0, 0); |
|
750 } |
|
751 |
|
752 // read LONG localisable_resource_id |
|
753 aLocalisableResourceId = aResourceReader.ReadUint32L(); |
|
754 if (aLocalisableResourceFile && (aLocalisableResourceId & KResourceOffsetMask)) |
|
755 aLocalisableResourceFile->ConfirmSignatureL(); |
|
756 |
|
757 iCapability.iAppIsHidden = aResourceReader.ReadInt8L(); |
|
758 iCapability.iEmbeddability = static_cast<TApaAppCapability::TEmbeddability>(aResourceReader.ReadInt8L()); |
|
759 iCapability.iSupportsNewFile = aResourceReader.ReadInt8L(); |
|
760 iCapability.iLaunchInBackground = aResourceReader.ReadInt8L(); |
|
761 iCapability.iGroupName = aResourceReader.ReadTPtrCL(); |
|
762 |
|
763 // read BYTE default_screen_number |
|
764 iDefaultScreenNumber = aResourceReader.ReadUint8L(); |
|
765 |
|
766 //read the datatypes |
|
767 CArrayFixFlat<TDataTypeWithPriority>* datatypes = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(5); |
|
768 CleanupStack::PushL(datatypes); |
|
769 ReadMimeTypesSupportedL(aResourceReader, *datatypes); |
|
770 //dataTypes is deleted if |
|
771 // A. There are no legacy datatypes |
|
772 // B. Control panel plugin apps are not allowed to register MIME types.If they happen to have any, these datatypes should be ignored. |
|
773 if ((iCapability.iAttributes & TApaAppCapability::EControlPanelItem) || (datatypes->Count() == 0)) |
|
774 CleanupStack::PopAndDestroy(datatypes); |
|
775 else |
|
776 { |
|
777 ASSERT(!iServiceArray); |
|
778 iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4); |
|
779 HBufC8* opaqueData = HBufC8::NewL(0); |
|
780 CleanupStack::PushL(opaqueData); |
|
781 TApaAppServiceInfo serviceInfo(KOpenServiceUid, datatypes, opaqueData); |
|
782 iServiceArray->AppendL(serviceInfo); |
|
783 CleanupStack::Pop(opaqueData); |
|
784 CleanupStack::Pop(datatypes); |
|
785 iIndexOfFirstOpenService = 0; |
|
786 iOpenServiceIsLegacy = ETrue; |
|
787 } |
|
788 |
|
789 // read LEN WORD STRUCT file_ownership_list[] |
|
790 const TInt fileOwnershipArraySize = aResourceReader.ReadInt16L(); |
|
791 if (fileOwnershipArraySize > 0) |
|
792 iOwnedFileArray = new(ELeave) CDesCArraySeg(1); |
|
793 |
|
794 for (TInt i=0; i < fileOwnershipArraySize; i++) |
|
795 { |
|
796 TPtrC fileNamePtr = aResourceReader.ReadTPtrCL(); |
|
797 iOwnedFileArray->AppendL(fileNamePtr); |
|
798 } |
|
799 } |
|
800 |
|
801 void CApaAppInfoReader::ReadMimeTypesSupportedL(RResourceReader& aResourceReader, |
|
802 CArrayFixFlat<TDataTypeWithPriority>& aMimeTypesSupported) |
|
803 { |
|
804 // read LEN WORD STRUCT datatype_list[] |
|
805 const TInt dataTypeArraySize = aResourceReader.ReadInt16L(); |
|
806 if (dataTypeArraySize <= 0) |
|
807 return; |
|
808 |
|
809 for (TInt i=0; i < dataTypeArraySize; i++) |
|
810 { |
|
811 TDataTypePriority priority = static_cast<TDataTypePriority>(aResourceReader.ReadInt32L()); |
|
812 |
|
813 //Check for data priority of UnTrusted apps however the trusted apps will not have any restrictions |
|
814 //over the data priority. |
|
815 //If an untrusted app has write device data capability (i.e. still has priority = KDataTypePrioritySystem), |
|
816 //do not restrict to KDataTypeUnTrustedPriorityThreshold |
|
817 if (priority > KDataTypeUnTrustedPriorityThreshold || priority == KDataTypePrioritySystem ) |
|
818 { |
|
819 ReadAppSecurityInfo(); |
|
820 |
|
821 if (priority == KDataTypePrioritySystem) |
|
822 { |
|
823 // Check that the app has capability WriteDeviceData |
|
824 if (!iHasWriteDeviceDataCap) |
|
825 priority = KDataTypePriorityNormal; |
|
826 } |
|
827 else |
|
828 { |
|
829 //data priority for UnTrusted apps would be capped if it is greater than the threshold priority i.e, KMaxTInt16. |
|
830 TInt match=iRegistrationFileName.MatchF(KLitPathForUntrustedRegistrationResourceFiles); |
|
831 if (match != KErrNotFound && !iIsSidTrusted) |
|
832 { |
|
833 //if registration file is in import directory and |
|
834 //its sid is in unprotected range - downgrade the priority |
|
835 priority = KDataTypeUnTrustedPriorityThreshold; |
|
836 } |
|
837 } |
|
838 } |
|
839 |
|
840 TPtrC8 dataTypePtr = aResourceReader.ReadTPtrC8L(); |
|
841 TDataType dataType(dataTypePtr); |
|
842 TDataTypeWithPriority dataTypeWithPriority(dataType, priority); |
|
843 aMimeTypesSupported.AppendL(dataTypeWithPriority); |
|
844 } |
|
845 } |
|
846 |
|
847 // This method can be used to check whether app has a WriteDeviceCap |
|
848 // and its sid is trusted |
|
849 void CApaAppInfoReader::ReadAppSecurityInfo() |
|
850 { |
|
851 if (!iSecurityInfoHasBeenRead) |
|
852 { |
|
853 __ASSERT_DEBUG( iAppBinaryFullName, Panic(EPanicNullPointer) ); |
|
854 const TInt err = CApaSecurityUtils::CheckAppSecurity( *iAppBinaryFullName, |
|
855 iHasWriteDeviceDataCap, iIsSidTrusted); |
|
856 if ( KErrNone != err ) |
|
857 { |
|
858 iHasWriteDeviceDataCap = EFalse; |
|
859 iIsSidTrusted = EFalse; |
|
860 } |
|
861 |
|
862 iSecurityInfoHasBeenRead = ETrue; |
|
863 } |
|
864 } |
|
865 |
|
866 // |
|
867 // Class CApaIconLoader |
|
868 // |
|
869 |
|
870 CApaIconLoader* CApaIconLoader::NewL(RFs& aFs) |
|
871 { |
|
872 CApaIconLoader* self = NewLC(aFs); |
|
873 CleanupStack::Pop(self); |
|
874 return self; |
|
875 } |
|
876 |
|
877 CApaIconLoader* CApaIconLoader::NewLC(RFs& aFs) |
|
878 { |
|
879 CApaIconLoader* self = new(ELeave) CApaIconLoader(aFs); |
|
880 CleanupStack::PushL(self); |
|
881 self->ConstructL(); |
|
882 return self; |
|
883 } |
|
884 |
|
885 CApaIconLoader::CApaIconLoader(RFs& aFs) : iFs(aFs) |
|
886 { |
|
887 } |
|
888 |
|
889 void CApaIconLoader::ConstructL() |
|
890 { |
|
891 } //lint !e1762 Suppress member function could be made const |
|
892 |
|
893 |
|
894 CApaIconLoader::~CApaIconLoader() |
|
895 { |
|
896 TInt arrayCount = iIconIndexArray.Count(); |
|
897 while (--arrayCount >= 0) |
|
898 delete (iIconIndexArray[arrayCount].iFileName); |
|
899 |
|
900 iIconIndexArray.Close(); |
|
901 iIconArrays.Close(); |
|
902 } |
|
903 |
|
904 void CApaIconLoader::AddIconArrayL(const CApaAppIconArray& aIcons) |
|
905 { |
|
906 iIconArrays.AppendL(&aIcons); |
|
907 } |
|
908 |
|
909 void CApaIconLoader::LoadAllIconsL() |
|
910 { |
|
911 const TInt iconArraysCount = iIconArrays.Count(); |
|
912 CleanupClosePushL(iIconArrays); |
|
913 for (TInt ii = 0; ii <iconArraysCount; ++ii) |
|
914 iIconArrays[ii]->LoadIconsL(); |
|
915 CleanupStack::PopAndDestroy(&iIconArrays); |
|
916 } |
|
917 |
|
918 // given an mbm filename, returns the next index to read from the file |
|
919 // always set aUseCache to EFalse on first call in a sequence of calls |
|
920 TInt CApaIconLoader::IconIndexL(const TDesC& aFileName, TBool& aUseCache) |
|
921 { |
|
922 if (aUseCache) |
|
923 { |
|
924 TInt ret = iIconIndexArray[iCachedArrayIndex].iIndex++; |
|
925 return ret; |
|
926 } |
|
927 else |
|
928 aUseCache = ETrue; |
|
929 |
|
930 // if filename in array, get the next index |
|
931 TInt ret = 0; |
|
932 const TInt arrayCount = iIconIndexArray.Count(); |
|
933 TInt arrayIndex; |
|
934 for (arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++) |
|
935 { |
|
936 __ASSERT_DEBUG(iIconIndexArray[arrayIndex].iFileName, Panic(EDPanicInvalidIconIndexArray)); |
|
937 if (iIconIndexArray[arrayIndex].iFileName->CompareF(aFileName) == 0) |
|
938 { |
|
939 ret = iIconIndexArray[arrayIndex].iIndex++; |
|
940 iCachedArrayIndex = arrayIndex; |
|
941 break; |
|
942 } |
|
943 } |
|
944 |
|
945 if (arrayIndex >= arrayCount) |
|
946 { |
|
947 // filename not found, add it to array |
|
948 TKeyValuePair keyValuePair; |
|
949 keyValuePair.iFileName = aFileName.AllocL(); |
|
950 keyValuePair.iIndex = 0; |
|
951 ret = keyValuePair.iIndex++; |
|
952 User::LeaveIfError(iIconIndexArray.Append(keyValuePair)); |
|
953 iCachedArrayIndex = arrayCount; |
|
954 } |
|
955 |
|
956 return ret; |
|
957 } |
|
958 |
|
959 |
|
960 |
|
961 // returns EFalse if there was an error obtaining aMbmFileName's entry information, |
|
962 // otherwise returns ETrue. |
|
963 // Leaves if an error occurs while trying to populate aIcons or sort icons |
|
964 TBool CApaIconLoader::LoadIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CArrayPtr<CApaMaskedBitmap>& aIcons) |
|
965 { |
|
966 TEntry entry; |
|
967 TInt error=iFs.Entry(aMbmFileName,entry); |
|
968 if (error!=KErrNone) |
|
969 return EFalse; |
|
970 |
|
971 TInt iconIndex; |
|
972 TInt fileIndex; |
|
973 TBool useCache = EFalse; |
|
974 |
|
975 // create link to CApaAppList which owns this object as it has a separate share protected RFs |
|
976 // which can be used to load bitmap icons |
|
977 CApaAppList* const appList = CApaAppList::Self(); |
|
978 |
|
979 RFile mbmFile; |
|
980 CleanupClosePushL(mbmFile); |
|
981 User::LeaveIfError(mbmFile.Open(appList->ShareProtectedFileServer(), aMbmFileName, EFileShareReadersOnly)); |
|
982 |
|
983 for(iconIndex=0; iconIndex<aNumOfIcons; ++iconIndex) |
|
984 { |
|
985 CApaMaskedBitmap* bitmap = CApaMaskedBitmap::NewLC(); |
|
986 fileIndex = IconIndexL(aMbmFileName, useCache); |
|
987 User::LeaveIfError(bitmap->Load(mbmFile, 2*fileIndex)); |
|
988 User::LeaveIfError((bitmap->Mask())->Load(mbmFile,2*fileIndex+1)); |
|
989 aIcons.AppendL(bitmap); |
|
990 CleanupStack::Pop(bitmap); |
|
991 } |
|
992 |
|
993 CleanupStack::PopAndDestroy(&mbmFile); // close mbmFile |
|
994 |
|
995 // now sort them in ascending order of size |
|
996 TInt numberOfIcons = aIcons.Count(); |
|
997 // create a new array that we can sort by area, populated from aIcons |
|
998 RPointerArray<CApaMaskedBitmap> ptrArray(numberOfIcons); |
|
999 CleanupClosePushL(ptrArray); |
|
1000 TLinearOrder<CApaMaskedBitmap> order(CApaIconLoader::CompareIcons); |
|
1001 for (iconIndex=0; iconIndex<numberOfIcons; iconIndex++) |
|
1002 User::LeaveIfError(ptrArray.InsertInOrderAllowRepeats(aIcons[iconIndex], order)); |
|
1003 |
|
1004 // copy the sorted icon pointers back into aIcons - must not Leave inside the loop below |
|
1005 for (iconIndex=0; iconIndex<numberOfIcons; iconIndex++) |
|
1006 aIcons[iconIndex]=ptrArray[iconIndex]; |
|
1007 |
|
1008 CleanupStack::PopAndDestroy(&ptrArray); |
|
1009 |
|
1010 return ETrue; |
|
1011 } |
|
1012 |
|
1013 TInt CApaIconLoader::CompareIcons(const CApaMaskedBitmap& aFirst, const CApaMaskedBitmap& aSecond) |
|
1014 { // static |
|
1015 TSize sizeFirst = aFirst.SizeInPixels(); |
|
1016 TInt areaFirst = sizeFirst.iWidth*sizeFirst.iHeight; |
|
1017 TSize sizeSecond = aSecond.SizeInPixels(); |
|
1018 TInt areaSecond = sizeSecond.iWidth*sizeSecond.iHeight; |
|
1019 return areaFirst - areaSecond; |
|
1020 } |
|
1021 |
|
1022 // |
|
1023 // Class CApaAppIconArray |
|
1024 // |
|
1025 |
|
1026 CApaAppIconArray* CApaAppIconArray::NewL() |
|
1027 { |
|
1028 return new(ELeave) CApaAppIconArray(); |
|
1029 } |
|
1030 |
|
1031 /* public factory functions */ |
|
1032 CApaAppIconArray* CApaAppIconArray::NewAppIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader) |
|
1033 { |
|
1034 return NewL(aNumOfIcons,aMbmFileName,aIconLoader,ETrue); |
|
1035 } |
|
1036 |
|
1037 CApaAppIconArray* CApaAppIconArray::NewViewIconsL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader) |
|
1038 { |
|
1039 return NewL(aNumOfIcons,aMbmFileName,aIconLoader,EFalse); |
|
1040 } |
|
1041 |
|
1042 CApaAppIconArray* CApaAppIconArray::NewDefaultIconsL() |
|
1043 { |
|
1044 CApaAppIconArray* self = NewL(); |
|
1045 CleanupStack::PushL(self); |
|
1046 self->GetDefaultIconsL(); |
|
1047 CleanupStack::Pop(self); |
|
1048 return self; |
|
1049 } |
|
1050 |
|
1051 CApaAppIconArray* CApaAppIconArray::NewRealDefaultIconsLC(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader) |
|
1052 { |
|
1053 return NewLC(aNumOfIcons,aMbmFileName,aIconLoader,EFalse); |
|
1054 } |
|
1055 |
|
1056 /* real NewL and NewLC, private */ |
|
1057 CApaAppIconArray* CApaAppIconArray::NewL(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons) |
|
1058 { |
|
1059 CApaAppIconArray* self = NewLC(aNumOfIcons,aMbmFileName,aIconLoader,aFallbackToDefaultIcons); |
|
1060 CleanupStack::Pop(self); |
|
1061 return self; |
|
1062 } |
|
1063 |
|
1064 CApaAppIconArray* CApaAppIconArray::NewLC(TInt aNumOfIcons, const TDesC& aMbmFileName, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons) |
|
1065 { |
|
1066 CApaAppIconArray* self = new(ELeave) CApaAppIconArray(aNumOfIcons,aIconLoader,aFallbackToDefaultIcons); |
|
1067 CleanupStack::PushL(self); |
|
1068 self->ConstructL(aMbmFileName); |
|
1069 return self; |
|
1070 } |
|
1071 |
|
1072 CApaAppIconArray::CApaAppIconArray() |
|
1073 { |
|
1074 } |
|
1075 |
|
1076 CApaAppIconArray::CApaAppIconArray(TInt aNumOfIcons, CApaIconLoader& aIconLoader, TBool aFallbackToDefaultIcons) : |
|
1077 iNumOfIcons(aNumOfIcons), |
|
1078 iIconLoader(&aIconLoader), |
|
1079 iFallbackToDefaultIcons(aFallbackToDefaultIcons) |
|
1080 { |
|
1081 } |
|
1082 |
|
1083 void CApaAppIconArray::ConstructL(const TDesC& aMbmFileName) |
|
1084 { |
|
1085 iMbmFileName = aMbmFileName.AllocL(); |
|
1086 ASSERT(iIconLoader); |
|
1087 iIconLoader->AddIconArrayL(*this); |
|
1088 } |
|
1089 |
|
1090 CApaAppIconArray::~CApaAppIconArray() |
|
1091 { |
|
1092 if(iDefaultIconsUsed) |
|
1093 { |
|
1094 ASSERT(iDefaultIconsProvider); |
|
1095 if(iDefaultIconsProvider) |
|
1096 iDefaultIconsProvider->ReleaseDefaultIconArray(); |
|
1097 } |
|
1098 |
|
1099 delete iMbmFileName; |
|
1100 if (iIcons) |
|
1101 { |
|
1102 iIcons->ResetAndDestroy(); |
|
1103 delete iIcons; |
|
1104 } |
|
1105 |
|
1106 iDefaultIconsProvider = NULL; |
|
1107 iIconLoader = NULL; |
|
1108 } |
|
1109 |
|
1110 // returns EFalse if there was an error obtaining iMbmFileName's entry information, |
|
1111 // otherwise returns ETrue or leaves with a system-wide error code |
|
1112 TBool CApaAppIconArray::LoadIconsL() |
|
1113 { |
|
1114 ASSERT(iIconLoader); |
|
1115 ASSERT(!iDefaultIconsUsed); |
|
1116 ASSERT(!iIcons); |
|
1117 iIcons = new(ELeave) CArrayPtrFlat<CApaMaskedBitmap>(5); |
|
1118 TBool badMbmEntryInfo = EFalse; |
|
1119 TRAPD(err,badMbmEntryInfo = !iIconLoader->LoadIconsL(iNumOfIcons,*iMbmFileName,*iIcons)); |
|
1120 |
|
1121 // We'll be called by the iconLoader at most once, and after we've been called, |
|
1122 // it might be destroyed. So we shouldn't keep a pointer to it anymore. |
|
1123 iIconLoader = NULL; |
|
1124 |
|
1125 if ((badMbmEntryInfo || err != KErrNone) && iFallbackToDefaultIcons) |
|
1126 GetDefaultIconsL(); |
|
1127 else if (badMbmEntryInfo) |
|
1128 return EFalse; |
|
1129 else if (err != KErrNone) |
|
1130 User::Leave(err); |
|
1131 |
|
1132 return ETrue; |
|
1133 } |
|
1134 |
|
1135 CApaMaskedBitmap* CApaAppIconArray::IconBySize(const TSize& aSize) const |
|
1136 { |
|
1137 if(iDefaultIconsUsed) |
|
1138 return DefaultIcons().IconBySize(aSize); |
|
1139 else if(iIcons == NULL && iIconLoader == NULL) |
|
1140 { |
|
1141 // Then we've been created with the default constructor, just pretend |
|
1142 // there's no icon of the right size |
|
1143 return NULL; |
|
1144 } |
|
1145 else if(iIcons == NULL) |
|
1146 { |
|
1147 // Arriving here means the the icons need loading but havn't been loaded yet. |
|
1148 TRAPD(err, iIconLoader->LoadAllIconsL()); |
|
1149 if (err != KErrNone) |
|
1150 return NULL; |
|
1151 } |
|
1152 |
|
1153 const TInt count = iIcons->Count(); |
|
1154 CApaMaskedBitmap* bmp=NULL; |
|
1155 for (TInt ii=0;ii<count;ii++) |
|
1156 { |
|
1157 if ((*iIcons)[ii]->SizeInPixels()==aSize) |
|
1158 bmp=(*iIcons)[ii]; |
|
1159 } |
|
1160 |
|
1161 if (!bmp) |
|
1162 {// if the exact size has not been found get one with nearest but smaller area |
|
1163 TInt differenceOfClosest=KMaxTInt; |
|
1164 TInt indexOfClosest=KMaxTInt; |
|
1165 TInt reqArea=aSize.iHeight*aSize.iWidth; |
|
1166 TSize bmpSize; |
|
1167 TInt difference; |
|
1168 for (TInt jj=0;jj<count;jj++) |
|
1169 { |
|
1170 bmpSize=(*iIcons)[jj]->SizeInPixels(); |
|
1171 difference=reqArea-bmpSize.iHeight*bmpSize.iWidth; |
|
1172 if (difference<differenceOfClosest && difference>=0) |
|
1173 { |
|
1174 differenceOfClosest=difference; |
|
1175 indexOfClosest=jj; |
|
1176 } |
|
1177 } |
|
1178 |
|
1179 if (indexOfClosest<KMaxTInt) |
|
1180 bmp=(*iIcons)[indexOfClosest]; |
|
1181 } |
|
1182 |
|
1183 return bmp; |
|
1184 } |
|
1185 |
|
1186 CArrayFixFlat<TSize>* CApaAppIconArray::IconSizesL() const |
|
1187 { |
|
1188 if(iDefaultIconsUsed) |
|
1189 return DefaultIcons().IconSizesL(); |
|
1190 else if(iIcons == NULL && iIconLoader == NULL) |
|
1191 return new(ELeave)CArrayFixFlat<TSize>(1); |
|
1192 else if(iIcons == NULL) |
|
1193 { |
|
1194 // Arriving here means the the icons need loading but havn't been loaded yet. |
|
1195 TRAPD(err, iIconLoader->LoadAllIconsL()); |
|
1196 if (err != KErrNone) |
|
1197 return new(ELeave)CArrayFixFlat<TSize>(1); |
|
1198 } |
|
1199 |
|
1200 const TInt count=iIcons->Count(); |
|
1201 CArrayFixFlat<TSize>* arrayOfSizes=new(ELeave)CArrayFixFlat<TSize>(1); |
|
1202 CleanupStack::PushL(arrayOfSizes); |
|
1203 for(TInt ii=0;ii<count;ii++) |
|
1204 arrayOfSizes->AppendL((*iIcons)[ii]->SizeInPixels()); |
|
1205 |
|
1206 CleanupStack::Pop(arrayOfSizes); |
|
1207 return arrayOfSizes; |
|
1208 } |
|
1209 |
|
1210 TInt CApaAppIconArray::Count() const |
|
1211 { |
|
1212 if(iDefaultIconsUsed) |
|
1213 return DefaultIcons().Count(); |
|
1214 else if(iIcons == NULL && iIconLoader == NULL) |
|
1215 return 0; |
|
1216 else if(iIcons == NULL) |
|
1217 { |
|
1218 // Arriving here means the the icons need loading but havn't been loaded yet. |
|
1219 TRAPD(err, iIconLoader->LoadAllIconsL()); |
|
1220 if (err != KErrNone) |
|
1221 return 0; |
|
1222 } |
|
1223 |
|
1224 return iIcons->Count(); |
|
1225 } |
|
1226 |
|
1227 TBool CApaAppIconArray::DefaultIconsUsed() const |
|
1228 { |
|
1229 return iDefaultIconsUsed; |
|
1230 } |
|
1231 |
|
1232 CApaMaskedBitmap* CApaAppIconArray::operator[](TInt aIndex) const |
|
1233 { |
|
1234 if(iDefaultIconsUsed) |
|
1235 return DefaultIcons()[aIndex]; |
|
1236 else if(iIcons == NULL && iIconLoader == NULL) |
|
1237 { |
|
1238 Panic(EPanicIndexOutOfRange); |
|
1239 return NULL; |
|
1240 } |
|
1241 else if(iIcons == NULL) |
|
1242 { |
|
1243 // Arriving here means the the icons need loading but havn't been loaded yet. |
|
1244 TRAPD(err, iIconLoader->LoadAllIconsL()); |
|
1245 if (err != KErrNone) |
|
1246 return NULL; |
|
1247 } |
|
1248 |
|
1249 return (*iIcons)[aIndex]; |
|
1250 } |
|
1251 |
|
1252 TBool CApaAppIconArray::AreAppIconsLoaded() const |
|
1253 { |
|
1254 if (iDefaultIconsUsed) |
|
1255 return ETrue; |
|
1256 |
|
1257 if (iNumOfIcons > 0 && !iIcons) |
|
1258 return EFalse; |
|
1259 |
|
1260 return ETrue; |
|
1261 } |
|
1262 |
|
1263 TBool CApaAppIconArray::AreViewIconsLoaded() const |
|
1264 { |
|
1265 if (iNumOfIcons > 0 && !iIcons ) |
|
1266 return EFalse; |
|
1267 |
|
1268 return ETrue; |
|
1269 } |
|
1270 |
|
1271 void CApaAppIconArray::GetDefaultIconsL() |
|
1272 { |
|
1273 ASSERT(!iDefaultIconsUsed); |
|
1274 iDefaultIconsProvider = CApaAppList::Self(); |
|
1275 ASSERT(iDefaultIconsProvider); |
|
1276 iDefaultIconsProvider->AcquireDefaultIconArrayL(); |
|
1277 iDefaultIconsUsed = ETrue; |
|
1278 delete iMbmFileName; |
|
1279 iMbmFileName = NULL; |
|
1280 if (iIcons) |
|
1281 { |
|
1282 iIcons->ResetAndDestroy(); |
|
1283 delete iIcons; |
|
1284 iIcons = NULL; |
|
1285 } |
|
1286 } |
|
1287 |
|
1288 const CApaAppIconArray& CApaAppIconArray::DefaultIcons() const |
|
1289 { |
|
1290 ASSERT(iDefaultIconsUsed && iDefaultIconsProvider); |
|
1291 return iDefaultIconsProvider->DefaultIconArray(); |
|
1292 } |
|
1293 |
|
1294 |
|
1295 |
|
1296 |