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