localisation/apparchitecture/apgrfx/APGAPLSTV2.CPP
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
equal deleted inserted replaced
0:e8c1ea2c6496 1:8758140453c0
       
     1 // Copyright (c) 2006-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 "APGAPLST.H"
       
    17 #include "APGSTD.H" 
       
    18 #include "APFDEF.H"
       
    19 #include "../apparc/TRACE.H"
       
    20 #include "apgnotif.h"
       
    21 #include "../apfile/aprfndr.h"
       
    22 #include <e32math.h>
       
    23 #include <bautils.h>
       
    24 #include <s32mem.h>
       
    25 #include "APGPRIV.H"
       
    26 #include "APGAIR.H"
       
    27 #include "APGICNFL.H"
       
    28 #include "apprivate.h"
       
    29 #include <e32uid.h>
       
    30 #ifdef SYMBIAN_BAFL_SYSUTIL
       
    31 #include <bafl/sysutil.h>
       
    32 #endif
       
    33 
       
    34 
       
    35 // Delays in the pseudo idle object that builds the application list
       
    36 //
       
    37 
       
    38 const TInt KIdleStartDelay=0;
       
    39 const TInt KMaxOpaqueDataLength = 0x1000; // maximum length of opaque data that can be passed between client and apparc server via a TApaAppServiceInfo object - this can be increased in future if needed
       
    40 const TInt KBufferExpansionGranularity = 0x100;
       
    41 const TInt KNumberOfIconsInDefaultMbm = 3;
       
    42 const TInt KAppListToFileStartDelay = 60000000;
       
    43 #ifdef SYMBIAN_BAFL_SYSUTIL
       
    44 const TInt KInfoBufLength=KSysUtilVersionTextLength;
       
    45 //This file is used for storing the rom version. If actual rom version differs from the one stored here the applist is not restored.
       
    46 //This file is versioned to avoid a data compatability break on adding further information to this file.
       
    47 //On adding further info to this file, KROMVersionCacheFileMajorVersion or KROMVersionCacheFileMinorVersion or KROMVersionCacheFileBuildVersion needs to be incremented appropriately.
       
    48 _LIT(KROMVersionStringCacheFileName, "ROMVersionCache.bin");
       
    49 const TInt8 KROMVersionCacheFileMajorVersion=1;
       
    50 const TInt8 KROMVersionCacheFileMinorVersion=0;
       
    51 const TInt16 KROMVersionCacheFileBuildVersion=0;
       
    52 #endif
       
    53 
       
    54 //
       
    55 // Class CApaLangChangeMonitor
       
    56 //
       
    57 
       
    58 NONSHARABLE_CLASS(CApaAppList::CApaLangChangeMonitor) : public CActive
       
    59 		{
       
    60 	/**
       
    61 	Utility class used to monitor locale/language change event.
       
    62 	@internalComponent
       
    63 	*/
       
    64 	public:
       
    65 		static CApaLangChangeMonitor* NewL(CApaAppList& aAppList);
       
    66 		~CApaLangChangeMonitor();
       
    67 		void Start();
       
    68 		
       
    69 	private:
       
    70 		CApaLangChangeMonitor(CApaAppList& aAppList);
       
    71 		void ConstructL();
       
    72 		
       
    73 	private:	//from CActive
       
    74 		void RunL();
       
    75 		void DoCancel();
       
    76 		TInt RunError(TInt aError);
       
    77 		
       
    78 	private:
       
    79 		RChangeNotifier iLangNotifier;
       
    80 		CApaAppList& iAppList;
       
    81 		TLanguage iPrevLanguage;
       
    82 		};
       
    83 
       
    84 		
       
    85 //
       
    86 // Local functions
       
    87 //
       
    88 
       
    89 void CleanupServiceArray(TAny* aServiceArray)
       
    90 	{
       
    91 	__ASSERT_DEBUG(aServiceArray, Panic(EPanicNullPointer));
       
    92 	CArrayFixFlat<TApaAppServiceInfo>* serviceArray = static_cast<CArrayFixFlat<TApaAppServiceInfo>*>(aServiceArray);
       
    93 	TInt serviceCount = serviceArray->Count();
       
    94 	if (serviceCount > 0)
       
    95 		{
       
    96 		for (TInt i = serviceCount - 1; i >= 0; i--)
       
    97 			{
       
    98 			(*serviceArray)[i].Release();
       
    99 			}
       
   100 		}
       
   101 	delete serviceArray;
       
   102 	serviceArray = 0;
       
   103 	}
       
   104 
       
   105 
       
   106 //
       
   107 // Class CApaAppViewData
       
   108 //
       
   109 
       
   110 CApaAppViewData::~CApaAppViewData()
       
   111 	{
       
   112 	delete iIcons;
       
   113 	delete iCaption;
       
   114 	delete iIconFileName;
       
   115 	}
       
   116 
       
   117 CApaAppViewData::CApaAppViewData()
       
   118 	: iNonMbmIconFile(EFalse)
       
   119 	{
       
   120 	}
       
   121 
       
   122 void CApaAppViewData::ConstructL()
       
   123 	{
       
   124 	iIcons=CApaAppIconArray::NewL();
       
   125 	}
       
   126 
       
   127 CApaAppViewData* CApaAppViewData::NewLC()
       
   128 	{
       
   129 	CApaAppViewData* self=new(ELeave) CApaAppViewData();
       
   130 	CleanupStack::PushL(self);
       
   131 	self->ConstructL();
       
   132 	return self;	
       
   133 	}
       
   134 
       
   135 void CApaAppViewData::SetUid(TUid aUid)
       
   136 	{
       
   137 	iUid=aUid;
       
   138 	}
       
   139 
       
   140 void CApaAppViewData::SetScreenMode(TInt aScreenMode)
       
   141 	{
       
   142 	iScreenMode=aScreenMode;
       
   143 	}
       
   144 
       
   145 EXPORT_C TInt CApaAppViewData::ScreenMode() const
       
   146 	{
       
   147 	return iScreenMode;
       
   148 	}
       
   149 
       
   150 void CApaAppViewData::SetCaptionL(const TDesC& aCaption)
       
   151 	{
       
   152 	HBufC* newCaption=aCaption.AllocL();
       
   153 	delete(iCaption); // after the AllocL succeeds
       
   154 	iCaption=newCaption;
       
   155 	}
       
   156 
       
   157 void CApaAppViewData::SetIconArray(CApaAppIconArray* aIcons)
       
   158 	{
       
   159 	delete iIcons;
       
   160 	iIcons = aIcons;
       
   161 	}
       
   162 
       
   163 void CApaAppViewData::SetIconFileNameL(const TDesC& aFileName)
       
   164 	{
       
   165 	HBufC* fileName = aFileName.AllocL();
       
   166 	delete iIconFileName; // after the AllocL succeeds
       
   167 	iIconFileName = fileName;
       
   168 	}
       
   169 
       
   170 void CApaAppViewData::SetNumOfViewIcons(TInt aNumOfViewIcons)
       
   171 	{
       
   172 	iNumOfViewIcons = aNumOfViewIcons;
       
   173 	}
       
   174 
       
   175 void CApaAppViewData::SetNonMbmIconFile(TBool aNonMbmIconFile)
       
   176 	{
       
   177 	iNonMbmIconFile = aNonMbmIconFile;
       
   178 	}
       
   179 
       
   180 EXPORT_C TUid CApaAppViewData::Uid() const
       
   181 	{
       
   182 	return iUid;
       
   183 	}
       
   184 
       
   185 EXPORT_C CApaMaskedBitmap* CApaAppViewData::Icon(const TSize& aSize) const
       
   186 	{
       
   187 	return iIcons->IconBySize(aSize);
       
   188 	}
       
   189 
       
   190 EXPORT_C CArrayFixFlat<TSize>* CApaAppViewData::IconSizesL() const
       
   191 	{
       
   192 	return iIcons->IconSizesL();
       
   193 	}
       
   194 
       
   195 EXPORT_C TPtrC CApaAppViewData::IconFileName() const
       
   196 	{
       
   197 	if (iIconFileName)
       
   198 		{
       
   199 		return *iIconFileName;
       
   200 		}
       
   201 	else
       
   202 		{
       
   203 		return TPtrC(KNullDesC);
       
   204 		}
       
   205 	}
       
   206 
       
   207 EXPORT_C TBool CApaAppViewData::NonMbmIconFile() const
       
   208 	{
       
   209 	return iNonMbmIconFile;
       
   210 	}
       
   211 
       
   212 
       
   213 //
       
   214 // class CApaAppEntry
       
   215 //
       
   216 
       
   217 CApaAppEntry* CApaAppEntry::NewL(const TApaAppEntry& aAppEntry)
       
   218 	{ // static
       
   219 	CApaAppEntry* self=new(ELeave) CApaAppEntry(aAppEntry.iUidType);
       
   220 	CleanupStack::PushL(self);
       
   221 	self->ConstructL(aAppEntry.iFullName);
       
   222 	CleanupStack::Pop(self);
       
   223 	return self;
       
   224 	}
       
   225 
       
   226 CApaAppEntry::~CApaAppEntry()
       
   227 	{
       
   228 	delete iFullName;
       
   229 	}
       
   230 
       
   231 void CApaAppEntry::Get(TApaAppEntry& aAppEntry) const
       
   232 	{
       
   233 	aAppEntry.iFullName=*iFullName;
       
   234 	aAppEntry.iUidType=iUidType;
       
   235 	}
       
   236 
       
   237 CApaAppEntry::CApaAppEntry(const TUidType& aUidType)
       
   238 	: iUidType(aUidType)
       
   239 	{
       
   240 	}
       
   241 
       
   242 void CApaAppEntry::ConstructL(const TDesC& aFileName)
       
   243 	{
       
   244 	iFullName=aFileName.AllocL();
       
   245 	}
       
   246 
       
   247 
       
   248 //
       
   249 // class TApaAppServiceInfo
       
   250 //
       
   251 
       
   252 TApaAppServiceInfo::TApaAppServiceInfo()
       
   253 	: iUid(KNullUid),
       
   254 	  iDataTypes(0),
       
   255 	  iOpaqueData(NULL)
       
   256 	{
       
   257 	}
       
   258 
       
   259 TApaAppServiceInfo::TApaAppServiceInfo(TUid aUid, 
       
   260 	CArrayFixFlat<TDataTypeWithPriority>* aDataTypes, HBufC8* aOpaqueData)
       
   261 	: iUid(aUid),
       
   262 	  iDataTypes(aDataTypes),
       
   263 	  iOpaqueData(aOpaqueData)
       
   264 	{
       
   265 	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
       
   266 	__ASSERT_DEBUG(iOpaqueData, Panic(EPanicNullPointer));
       
   267 	}
       
   268 
       
   269 void TApaAppServiceInfo::ExternalizeL(RWriteStream& aStream) const
       
   270 	{
       
   271 	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
       
   272 	__ASSERT_DEBUG(iOpaqueData, Panic(EPanicNullPointer));
       
   273 	aStream << iUid;
       
   274 	aStream << *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
       
   275 	aStream << *iOpaqueData;//lint !e613 Possible use of null pointer - Asserted above
       
   276 	}
       
   277 
       
   278 void TApaAppServiceInfo::InternalizeL(RReadStream& aStream)
       
   279 	{
       
   280 	aStream >> iUid;
       
   281 	iDataTypes = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
       
   282 	aStream >> *iDataTypes;
       
   283 	iOpaqueData = HBufC8::NewL(aStream, KMaxOpaqueDataLength);
       
   284 	}
       
   285 
       
   286 void TApaAppServiceInfo::Release()
       
   287 	{
       
   288 	if (iDataTypes)
       
   289 		{
       
   290 		iDataTypes->Reset();
       
   291 		delete iDataTypes;		
       
   292 		}
       
   293 	if (iOpaqueData)
       
   294 		{
       
   295 		delete iOpaqueData;
       
   296 		iOpaqueData = NULL;
       
   297 		}
       
   298 	}
       
   299 
       
   300 CArrayFixFlat<TDataTypeWithPriority>& TApaAppServiceInfo::DataTypes()
       
   301 	{
       
   302 	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));
       
   303 	return *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
       
   304 	}
       
   305 
       
   306 /** Returns the service UID.
       
   307 
       
   308 Note that some APIs may store a UID other than a service UID
       
   309 in a TApaAppServiceInfo object. Such APIs clearly state what
       
   310 the UID represents.
       
   311 
       
   312 @return the service UID.
       
   313 */
       
   314 EXPORT_C TUid TApaAppServiceInfo::Uid() const
       
   315 	{
       
   316 	return iUid;
       
   317 	}
       
   318 	
       
   319 EXPORT_C const CArrayFixFlat<TDataTypeWithPriority>& TApaAppServiceInfo::DataTypes() const
       
   320 	{
       
   321 	__ASSERT_DEBUG(iDataTypes, Panic(EPanicNullPointer));	
       
   322 	return *iDataTypes; //lint !e613 Possible use of null pointer - Asserted above
       
   323 	}
       
   324 
       
   325 /** Returns the service implementation's opaque data.
       
   326 
       
   327 For each service UID registered by an application, the associated
       
   328 opaque data indicates how the service is implemented by that application.
       
   329 
       
   330 The meaning of the opaque data is not known to the framework, it will vary
       
   331 according to the service.
       
   332 
       
   333 For some services the opaque data may be a name intended for user display,
       
   334 for others it may be structured data that the service's client-side code can interpret.
       
   335 
       
   336 @return the service implementation's opaque data.
       
   337 */
       
   338 EXPORT_C const TDesC8& TApaAppServiceInfo::OpaqueData() const
       
   339 	{
       
   340 	if (iOpaqueData)
       
   341 		{
       
   342 		return *iOpaqueData;
       
   343 		}
       
   344 	return KNullDesC8;
       
   345 	}
       
   346 
       
   347 //
       
   348 // class CApaAppServiceInfoArray
       
   349 //
       
   350 
       
   351 CApaAppServiceInfoArray::CApaAppServiceInfoArray()
       
   352 	{
       
   353 	}
       
   354 
       
   355 //
       
   356 // class CApaAppServiceInfoArrayWrapper
       
   357 //
       
   358 
       
   359 CApaAppServiceInfoArrayWrapper* CApaAppServiceInfoArrayWrapper::NewL(CArrayFix<TApaAppServiceInfo>* aServiceInfoArray)
       
   360 	{
       
   361 	CApaAppServiceInfoArrayWrapper* self = new CApaAppServiceInfoArrayWrapper(aServiceInfoArray);
       
   362 	if (!self)
       
   363 		{
       
   364 		CleanupServiceArray(aServiceInfoArray);
       
   365 		User::LeaveNoMemory();
       
   366 		}
       
   367 	return self;
       
   368 	}
       
   369 
       
   370 CApaAppServiceInfoArrayWrapper::CApaAppServiceInfoArrayWrapper(CArrayFix<TApaAppServiceInfo>* aServiceInfoArray)
       
   371 	: iServiceInfoArray(aServiceInfoArray)
       
   372 	{
       
   373 	}
       
   374 
       
   375 CApaAppServiceInfoArrayWrapper::~CApaAppServiceInfoArrayWrapper()
       
   376 	{
       
   377 	CleanupServiceArray(iServiceInfoArray);
       
   378 	iServiceInfoArray = NULL;
       
   379 	}
       
   380 
       
   381 TArray<TApaAppServiceInfo> CApaAppServiceInfoArrayWrapper::Array()
       
   382 	{
       
   383 	return iServiceInfoArray->Array();
       
   384 	}
       
   385 
       
   386 
       
   387 //
       
   388 // Class CApaAppData
       
   389 //
       
   390 
       
   391 EXPORT_C CApaAppData* CApaAppData::NewL(const TApaAppEntry& aAppEntry, RFs& aFs)
       
   392 	{
       
   393 	CApaAppData* self=new(ELeave) CApaAppData(aFs);
       
   394 	CleanupStack::PushL(self);
       
   395 	self->ConstructL(aAppEntry);
       
   396 	CleanupStack::Pop(); // self
       
   397 	return self;
       
   398 	}
       
   399 
       
   400 CApaAppData::CApaAppData(RFs& aFs)
       
   401 	:iCaption(NULL), iShortCaption(NULL), 
       
   402 	iIsPresent(CApaAppData::EIsPresent), iFs(aFs),
       
   403 	iNonMbmIconFile(EFalse),
       
   404 	iApplicationLanguage(ELangNone), iIndexOfFirstOpenService(-1),
       
   405 	iNonNativeApplicationType(TUid::Null()),
       
   406 	iShortCaptionFromResourceFile(NULL)
       
   407 	{
       
   408 	}
       
   409 
       
   410 void CApaAppData::ConstructL(const TApaAppEntry& aAppEntry)
       
   411 	{
       
   412 	iUidType = aAppEntry.iUidType; // if the 2nd UID is KUidAppRegistrationFile, iUidType will be updated in StoreApplicationInformation to reflect the TUidType for the application binary
       
   413 	if (ApaUtils::HandleAsRegistrationFile(aAppEntry.iUidType))
       
   414 		{
       
   415 		iRegistrationFile = aAppEntry.iFullName.AllocL();
       
   416 		}
       
   417 	else
       
   418 		{
       
   419 		iFullName = aAppEntry.iFullName.AllocL();
       
   420 		}
       
   421 
       
   422 	iCapabilityBuf.FillZ(iCapabilityBuf.MaxLength());
       
   423 	iIcons = CApaAppIconArray::NewL();
       
   424 	iViewDataArray=new(ELeave) CArrayPtrFlat<CApaAppViewData>(1);
       
   425 	iOwnedFileArray=new(ELeave) CDesCArraySeg(1);
       
   426 	User::LeaveIfError(StoreApplicationInformation());
       
   427 	}
       
   428 
       
   429 // Return a standard error code
       
   430 // The value returned only reflect the caption status
       
   431 // If there is errors setting up captions the old values are retained
       
   432 // All other errors are silently ignored
       
   433 // General notes:
       
   434 // 1. This method is deliberately very similar to the old CApaAppData::GetAifData
       
   435 //    in order to maintain behavioural compatibility for V1 apps
       
   436 // 2. Be very careful in this method, because it can be called on a newly constructed object,
       
   437 //    or on an existing object, so don't assume member data pointers will be NULL
       
   438 TInt CApaAppData::StoreApplicationInformation()
       
   439 	{
       
   440 	HBufC* caption = NULL;
       
   441 	HBufC* shortCaption = NULL;
       
   442 
       
   443 	iTimeStamp = TTime(0); // cannot init in constructor because this function can be called on an existing CApaAppData object
       
   444 
       
   445 	CApaAppInfoReader* appInfoReader = NULL;
       
   446 	TBool readSuccessful = EFalse;
       
   447 	TBool isNonNativeApp = EFalse;
       
   448 	if (iRegistrationFile != NULL)
       
   449 		{
       
   450 		if (TParsePtrC(*iRegistrationFile).Path().CompareF(KLitPathForNonNativeResourceAndIconFiles)==0)
       
   451 			{
       
   452 			isNonNativeApp = ETrue;
       
   453 			}
       
   454 
       
   455 		TRAPD(err,appInfoReader = CApaAppInfoReaderV2::NewL(iFs, *iRegistrationFile, iUidType[2]));
       
   456 		if(err != KErrNone)
       
   457 			{
       
   458 			appInfoReader = NULL;
       
   459 			}
       
   460 
       
   461 		if (appInfoReader == NULL)
       
   462 			{
       
   463 			if (iFullName == NULL)
       
   464 				{
       
   465 				// assume that if iFullName is NULL, this method has been called as part
       
   466 				// of constructing a new app data object. The CApaAppInfoReader derived object
       
   467 				// could not be created, therefore we have no way to determine the full filename
       
   468 				// of the app binary, so give up
       
   469 				return KErrNoMemory;
       
   470 				}
       
   471 			}
       
   472 		else
       
   473 			{
       
   474 			readSuccessful = appInfoReader->Read();
       
   475 			HBufC* appBinaryFullName=appInfoReader->AppBinaryFullName();
       
   476 			if (appBinaryFullName)
       
   477 				{
       
   478 				delete iFullName;
       
   479 				iFullName = appBinaryFullName;
       
   480 				}
       
   481 			if (iFullName == NULL)
       
   482 				{
       
   483 				delete appInfoReader;
       
   484 				return KErrNoMemory;
       
   485 				}
       
   486 			// if this object has just been constructed, iUidType is currently the TUidType
       
   487 			// of the registration file, it should be the TUidType of the app binary file
       
   488 			TUidType uidType = appInfoReader->AppBinaryUidType();
       
   489 			if (uidType[1].iUid != KNullUid.iUid)
       
   490 				{
       
   491 				iUidType = uidType;
       
   492 				}
       
   493 			}
       
   494 		}
       
   495 
       
   496 	if (appInfoReader != NULL)
       
   497 		{
       
   498 		// must get captions regardless of value of readSuccessful,
       
   499 		// because the V1 reader might have read captions
       
   500 		// this is done to maintain behavioural compatibility with V1
       
   501 		caption = appInfoReader->Caption();
       
   502 		shortCaption = appInfoReader->ShortCaption();
       
   503 
       
   504 		CApaAppIconArray* icons = appInfoReader->Icons();
       
   505 		if(icons)
       
   506 			{
       
   507 			delete iIcons;
       
   508 			iIcons = icons;
       
   509 			iIconLoader = appInfoReader->IconLoader();
       
   510 			}
       
   511 		else
       
   512 			{			
       
   513 			TRAPD(err, icons = CApaAppIconArray::NewL());
       
   514 			if(err == KErrNone)
       
   515 				{
       
   516 				delete iIcons;
       
   517 				iIcons = icons;
       
   518 				}
       
   519 			}
       
   520 		iTimeStamp = appInfoReader->TimeStamp();
       
   521 		delete iLocalisableResourceFileName;
       
   522 		iLocalisableResourceFileName = appInfoReader->LocalisableResourceFileName();
       
   523 		iLocalisableResourceFileTimeStamp = appInfoReader->LocalisableResourceFileTimeStamp();
       
   524 
       
   525 		if (isNonNativeApp)
       
   526 			{
       
   527 			// In the case of a non-native app, the resource file has been prefixed with a
       
   528 			// TCheckedUid, the second of whose UIDs is the non-native application type uid.
       
   529 			TEntry entry;
       
   530 			const TInt error=iFs.Entry(*iRegistrationFile, entry);
       
   531 			if (error!=KErrNone)
       
   532 				{
       
   533 				delete appInfoReader;
       
   534 				return error;
       
   535 				}
       
   536 			__ASSERT_DEBUG(entry.iType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile, Panic(EPanicUnexpectedUid));
       
   537 			iNonNativeApplicationType=entry.iType[1];
       
   538 			}
       
   539 
       
   540 		delete iOpaqueData;
       
   541 		iOpaqueData = appInfoReader->OpaqueData();
       
   542 
       
   543 		if (readSuccessful)
       
   544 			{
       
   545 			appInfoReader->Capability(iCapabilityBuf);
       
   546 
       
   547 			iDefaultScreenNumber = appInfoReader->DefaultScreenNumber();
       
   548 
       
   549 			delete iIconFileName;
       
   550 			iIconFileName = appInfoReader->IconFileName();
       
   551 			iIconFileTimeStamp = appInfoReader->IconFileTimeStamp();
       
   552 			iNonMbmIconFile = appInfoReader->NonMbmIconFile();
       
   553 			iNumOfAppIcons = appInfoReader->NumOfAppIcons();
       
   554 			iApplicationLanguage = appInfoReader->AppLanguage();
       
   555 					
       
   556 			// views
       
   557 			iViewDataArray->ResetAndDestroy();
       
   558 			CArrayPtrFlat<CApaAppViewData>* viewDataArray = appInfoReader->Views();
       
   559 			if (viewDataArray)
       
   560 				{
       
   561 				delete iViewDataArray;
       
   562 				iViewDataArray = viewDataArray;
       
   563 				
       
   564 				if(!iIconLoader && ViewMbmIconsRequireLoading())
       
   565 				    {
       
   566 				    //if VIEW_DATA contains a MBM icon we need to initialize iIconLoader
       
   567 				    iIconLoader = appInfoReader->IconLoader();
       
   568 				    }
       
   569 				}
       
   570 
       
   571 			// owned files
       
   572 			iOwnedFileArray->Reset();
       
   573 			CDesCArray* ownedFileArray = appInfoReader->OwnedFiles();
       
   574 			if (ownedFileArray)
       
   575 				{
       
   576 				delete iOwnedFileArray;
       
   577 				iOwnedFileArray = ownedFileArray;
       
   578 				}
       
   579 			
       
   580 			UpdateServiceArray(appInfoReader->ServiceArray(iIndexOfFirstOpenService));
       
   581 			}
       
   582 		delete appInfoReader;
       
   583 		}
       
   584 
       
   585 	if (!caption)
       
   586 		{
       
   587 		TParsePtrC parse (*iFullName);
       
   588 		caption = parse.Name().Alloc();
       
   589 		}
       
   590 
       
   591 	// Put the captions into place
       
   592 	if (caption)
       
   593 		{
       
   594 		if (!shortCaption)
       
   595 			{
       
   596 			shortCaption = caption->Alloc();
       
   597 			if (!shortCaption)
       
   598 				{
       
   599 				delete caption;
       
   600 				caption = NULL;
       
   601 				}
       
   602 			}
       
   603 		}
       
   604 	if (caption)
       
   605 		{
       
   606 		delete iCaption;
       
   607 		iCaption = caption;
       
   608 		delete iShortCaption;
       
   609 		iShortCaption = shortCaption;
       
   610 		}
       
   611 
       
   612 	return caption ? KErrNone : KErrNoMemory;
       
   613 	}
       
   614 
       
   615 EXPORT_C CApaAppData::~CApaAppData()
       
   616 // Just delete components, NOT iNext (next CApaAppData in the list).
       
   617 	{
       
   618 	delete iSuccessor;
       
   619 	delete iCaption;
       
   620 	delete iShortCaption;
       
   621 	delete iFullName;
       
   622 	delete iShortCaptionFromResourceFile;
       
   623 	delete iCaptionFromResourceFile;
       
   624 	delete iIcons;
       
   625 	delete iIconLoader;
       
   626 	if(iViewDataArray)
       
   627 		{
       
   628 		iViewDataArray->ResetAndDestroy();
       
   629 		delete iViewDataArray;
       
   630 		}
       
   631 	delete iOwnedFileArray;
       
   632 	delete iIconFileName;
       
   633 	delete iIconFileNameFromResourceFile;
       
   634 	delete iLocalisableResourceFileName;
       
   635 	if (iServiceArray)
       
   636 		{
       
   637 		CleanupServiceArray(iServiceArray);
       
   638 		iServiceArray = NULL;
       
   639 		}
       
   640 	delete iOpaqueData;
       
   641 	delete iRegistrationFile;
       
   642 	iNext = NULL;
       
   643 	}
       
   644 
       
   645 void CApaAppData::UpdateServiceArray(CArrayFixFlat<TApaAppServiceInfo>* aNewServiceArray)
       
   646 	{
       
   647 	// clear out any existing service info
       
   648 	if (iServiceArray)
       
   649 		{
       
   650 		CleanupServiceArray(iServiceArray);
       
   651 		iServiceArray = NULL;
       
   652 		}
       
   653 	// store new service array
       
   654 	iServiceArray = aNewServiceArray;
       
   655 	}
       
   656 	
       
   657 TDataTypePriority CApaAppData::DataType(const TDataType& aDataType, const CArrayFixFlat<TDataTypeWithPriority>& aDataTypeArray) const
       
   658 	{
       
   659 	TInt count=aDataTypeArray.Count();
       
   660 	for (TInt ii=0;ii<count;ii++)
       
   661 		{
       
   662 		const TDataTypeWithPriority& type=aDataTypeArray[ii];
       
   663 		if (type.iDataType==aDataType)
       
   664 			{
       
   665 			return type.iPriority;
       
   666 			}
       
   667 		else
       
   668 			{
       
   669 			TPtrC8 src=type.iDataType.Des8();
       
   670 			TPtrC8 trg=aDataType.Des8();
       
   671 			if (src.Match(trg)==0 || trg.Match(src)==0)
       
   672 				{
       
   673 				if (type.iPriority == KDataTypePrioritySystem)
       
   674 					{
       
   675 					// This is more or less a magic number so don't decrement
       
   676 					return KDataTypePrioritySystem;
       
   677 					}
       
   678 				else
       
   679 					{
       
   680 					return (TInt16)(type.iPriority-1);
       
   681 					}
       
   682 				}
       
   683 			}
       
   684 		}
       
   685 	return KDataTypePriorityNotSupported;
       
   686 	}
       
   687 
       
   688 /**
       
   689  * Returns the CApaMaskedBitmap of size aSize for the application associated
       
   690  * with this CApaAppData. If the icons for the application are not yet loaded then it would be loaded first.
       
   691  * If there is not a bitmap of exact size aSize then 
       
   692  * the icon closest to but smaller than the one asked for is returned, or NULL if
       
   693  * none is smaller.
       
   694  * 
       
   695  * @since Uikon1.2
       
   696  */
       
   697 EXPORT_C CApaMaskedBitmap* CApaAppData::Icon(TSize aSize) const
       
   698 	{
       
   699 	return iIcons->IconBySize(aSize);
       
   700 	}
       
   701 
       
   702 /**
       
   703  * Returns a pointer to the small, medium or large application icon for aIconIndex equal to 0, 1 or 2 respectively.
       
   704  * Panics if aIconIndex is not one of these three values.
       
   705  *
       
   706  * This method is superseded by an overload which returns the icon by finding the closest match to a specified size.
       
   707  *
       
   708  * @deprecated
       
   709  */
       
   710 EXPORT_C CApaMaskedBitmap* CApaAppData::Icon(TInt aIconIndex) const
       
   711 	{
       
   712 	__ASSERT_DEBUG(aIconIndex>-1 && aIconIndex<3, Panic(EDPanicBadIconSize)); //only support old behaviour
       
   713 	TSize sizeExpected;
       
   714 	switch(aIconIndex)
       
   715 		{
       
   716 	case KApaIconIndexSmall:
       
   717 		sizeExpected=TSize(24,24);
       
   718 		break;
       
   719 	case KApaIconIndexMedium:
       
   720 		sizeExpected=TSize(32,32);
       
   721 		break;
       
   722 	case KApaIconIndexLarge:
       
   723 		sizeExpected=TSize(48,48);
       
   724 		break;
       
   725 	default:
       
   726 		break;
       
   727 		}
       
   728 	return Icon(sizeExpected);
       
   729 	}
       
   730 
       
   731 void CApaAppData::LoadIconsL()
       
   732 	{
       
   733 	iIconLoader->LoadAllIconsL();
       
   734 	}
       
   735 
       
   736 EXPORT_C CArrayFixFlat<TSize>* CApaAppData::IconSizesL()const
       
   737 /** Gets the sizes of icons available for the application. 
       
   738 * If the icons for the application are not yet loaded then it would be loaded first.
       
   739 
       
   740 @return A pointer to an array of the icon sizes. The caller takes ownership. */
       
   741 	{
       
   742 	return iIcons->IconSizesL();
       
   743 	}
       
   744 
       
   745 EXPORT_C TApaAppEntry CApaAppData::AppEntry() const
       
   746 /** Constructs an application entry based on this object.
       
   747 
       
   748 @return The application entry. */
       
   749 	{
       
   750 	return TApaAppEntry(iUidType,*iFullName);
       
   751 	}
       
   752 
       
   753 
       
   754 EXPORT_C void CApaAppData::Capability(TDes8& aCapabilityBuf)const
       
   755 /** Gets the application's capabilities.
       
   756 
       
   757 @param aCapabilityBuf On return, contains the application's capabilities, 
       
   758 specified as a TApaAppCapabilityBuf object. */
       
   759 	{
       
   760 	TApaAppCapability::CopyCapability(aCapabilityBuf,iCapabilityBuf);
       
   761 	}
       
   762 
       
   763 /**
       
   764  * Returns a pointer to the array of view data objects current for this application. Does not imply transfer of ownership.
       
   765  *
       
   766  * @since App-Framework_6.1
       
   767  */
       
   768 EXPORT_C CArrayPtrFlat<CApaAppViewData>* CApaAppData::Views() const
       
   769 	{
       
   770 	return iViewDataArray;
       
   771 	}
       
   772 
       
   773 /**
       
   774  * Returns a pointer to the array of files for which this application claims ownership. Does not imply transfer of ownership.
       
   775  *
       
   776  * @since App-Framework_6.1
       
   777  */
       
   778 EXPORT_C CDesCArray* CApaAppData::OwnedFiles() const
       
   779 	{
       
   780 	return iOwnedFileArray;
       
   781 	}
       
   782 
       
   783 TBool CApaAppData::Update()
       
   784 // returns true if changes were made to the cached data
       
   785 	{
       
   786 	__APA_PROFILE_START(17);
       
   787 	TBool changed=EFalse;
       
   788 
       
   789 	// Get app info file entry
       
   790 	TEntry entry;
       
   791 	TInt ret;
       
   792 	if (iRegistrationFile != NULL)
       
   793 		{
       
   794 		ret = iFs.Entry(*iRegistrationFile, entry);
       
   795 		if (ret==KErrNone && entry.iModified!=iTimeStamp)
       
   796 			{
       
   797 			// assume registration file may have changed
       
   798 			changed = ETrue;
       
   799 			}
       
   800 		else
       
   801 			{
       
   802 			if (iLocalisableResourceFileName)
       
   803 				{
       
   804 				// see if localisable resource information might have changed
       
   805 				TParse parse;
       
   806 				ret = parse.SetNoWild(KAppResourceFileExtension, iLocalisableResourceFileName, NULL);
       
   807 				if (ret == KErrNone)
       
   808 					{
       
   809 					TFileName resourceFileName(parse.FullName());
       
   810 					BaflUtils::NearestLanguageFile(iFs, resourceFileName);
       
   811 					if (resourceFileName.CompareF(*iLocalisableResourceFileName)!=0)
       
   812 						{
       
   813 						changed = ETrue;
       
   814 						}
       
   815 					else
       
   816 						{
       
   817 						ret = iFs.Entry(*iLocalisableResourceFileName, entry);
       
   818 						if ((ret==KErrNotFound && iLocalisableResourceFileTimeStamp!=TTime(0)) ||
       
   819 							(ret==KErrNone && entry.iModified!=iLocalisableResourceFileTimeStamp))
       
   820 							{
       
   821 							changed = ETrue;
       
   822 							}
       
   823 						}
       
   824 					}
       
   825 				}
       
   826 			}
       
   827 		}
       
   828 	if (changed)
       
   829 		{
       
   830 		// re-read data
       
   831 		// Ignore result, nothing we can do in case failure
       
   832 		// and the old values should be preserved
       
   833 #ifdef SYMBIAN_APPARC_APPINFO_CACHE
       
   834 		const TInt ignore = StoreApplicationInformation();
       
   835 #else
       
   836         const TInt ignore = StoreApplicationInformation(aDefaultAppIconFileName);
       
   837 #endif // SYMBIAN_APPARC_APPINFO_CACHE
       
   838 		} //lint !e529 Symbol 'ignore' not subsequently referenced
       
   839 		
       
   840 	else 
       
   841 		{
       
   842 		if (iIconFileName)
       
   843 			{
       
   844 			ret = iFs.Entry(*iIconFileName, entry);
       
   845 			// See if the icon file has been "modified"
       
   846 			// It could have been replaced with a differnt version, deleted or added 
       
   847 			// if the icon file specified in the resource was missing
       
   848 			if ((ret==KErrNotFound && iIconFileTimeStamp!=TTime(0)) ||
       
   849 					(ret==KErrNone && entry.iModified!=iIconFileTimeStamp))
       
   850 					{
       
   851 					// Assume the icon file has changed
       
   852 					iIconFileTimeStamp = entry.iModified;
       
   853 					changed = ETrue;
       
   854 					}
       
   855 			}
       
   856 		}
       
   857 
       
   858 	__APA_PROFILE_END(17);
       
   859 	return changed;
       
   860 	}
       
   861 
       
   862 EXPORT_C TDataTypePriority CApaAppData::DataType(const TDataType& aDataType) const
       
   863 // returns the priority of the data type
       
   864 /** If the application supports the specified data type, the function returns 
       
   865 the priority with which it should be selected for handling it.
       
   866 
       
   867 If the application does not support the specified data type, 
       
   868 KDataTypePriorityNotSupported is returned.
       
   869 
       
   870 Note that the function supports wildcard matching, using "*" and "?". In the case 
       
   871 of a wildcard match, the priority value returned is reduced by 1, so that in this 
       
   872 case, the application could never have the maximum priority 
       
   873 (KDataTypePriorityUserSpecified).
       
   874 
       
   875 @param aDataType The data type of interest.
       
   876 @return The priority with which the application should be selected for handling 
       
   877 the specified data type, or KDataTypePriorityNotSupported if the data type is 
       
   878 not supported. */
       
   879 	{
       
   880 	if (iIndexOfFirstOpenService >= 0)
       
   881 		{
       
   882 		const CArrayFixFlat<TDataTypeWithPriority>& dataTypeArray = 
       
   883 			(*iServiceArray)[iIndexOfFirstOpenService].DataTypes();
       
   884 		return DataType(aDataType, dataTypeArray);
       
   885 		}
       
   886 	return KDataTypePriorityNotSupported;
       
   887 	}
       
   888 
       
   889 
       
   890 EXPORT_C TBool CApaAppData::IsPending() const
       
   891 /* Returns true if the app info is not yet updated by the current scan. */
       
   892 	{
       
   893 	return (iIsPresent==CApaAppData::EPresentPendingUpdate 
       
   894 		|| iIsPresent==CApaAppData::ENotPresentPendingUpdate);
       
   895 	}
       
   896 
       
   897 EXPORT_C TBool CApaAppData::CanUseScreenMode(TInt aScreenMode)
       
   898 /** Tests whether the specified screen mode is valid for any of 
       
   899 this application's views. If the app has no views, the function 
       
   900 assumes that only the default screen mode (at screen mode index 
       
   901 zero) is allowed. This function is used by CApaAppList to create 
       
   902 a list of valid applications.
       
   903 
       
   904 @param aScreenMode The index of the screen mode.
       
   905 @return True if screen mode is valid, otherwise false. */
       
   906 	{
       
   907 	const TInt count=iViewDataArray->Count();
       
   908 	// If there are no views, assume only the default screen mode is allowed
       
   909 	TBool ret=(count==0 && aScreenMode==0);
       
   910 	for(TInt ii=0;ii<count;ii++)
       
   911 		{
       
   912 		const CApaAppViewData* data=(*iViewDataArray)[ii];
       
   913 		if(data->ScreenMode()==aScreenMode)
       
   914 			{
       
   915 			ret=ETrue;
       
   916 			break;
       
   917 			}
       
   918 		}
       
   919 	return ret;
       
   920 	}
       
   921 
       
   922 EXPORT_C void CApaAppData::GetIconInfo(TInt& aIconCount, TInt& aDefaultIconsUsed) const
       
   923 /** Gets icon information for the app. If the icons for the application are not yet loaded then it would be loaded first.
       
   924 
       
   925 @param aIconCount On return, this contains the number of app icons
       
   926 @param aDefaultIconsUsed On return, this indicates whether the default icons have been used
       
   927 */
       
   928 	{
       
   929 	aIconCount = iIcons->Count();
       
   930 	aDefaultIconsUsed = iIcons->DefaultIconsUsed();
       
   931 	}
       
   932 
       
   933 /** Gets the default screen number used by the application.
       
   934 
       
   935 A device may have more than once screen. This function
       
   936 returns the number associated with the screen which will
       
   937 be the default screen used by the application.
       
   938 
       
   939 @return The default screen number
       
   940 */
       
   941 EXPORT_C TUint CApaAppData::DefaultScreenNumber() const
       
   942 	{
       
   943 	return iDefaultScreenNumber;
       
   944 	}
       
   945 
       
   946 /** Returns true if app info was provided by a registration file
       
   947 
       
   948 @return true if app info was provided by a registration file
       
   949 */
       
   950 EXPORT_C TBool CApaAppData::RegistrationFileUsed() const
       
   951 	{
       
   952 	return iRegistrationFile != NULL;
       
   953 	}
       
   954 
       
   955 /** Returns the full filename of the registration resource file
       
   956 
       
   957 @return The full path and filename of the registration resource file.
       
   958 @internalTechnology
       
   959 */
       
   960 EXPORT_C TPtrC CApaAppData::RegistrationFileName() const
       
   961 	{
       
   962 	if (iRegistrationFile)
       
   963 		{
       
   964 		return *iRegistrationFile;
       
   965 		}
       
   966 	else
       
   967 		{
       
   968 		return TPtrC(KNullDesC);
       
   969 		}
       
   970 	}
       
   971 
       
   972 
       
   973 /** Returns the full filename of the localisable resource file
       
   974 
       
   975 @return The full path and filename of the localisable resource file.
       
   976 @internalTechnology
       
   977 */
       
   978 EXPORT_C TPtrC CApaAppData::LocalisableResourceFileName() const
       
   979 	{
       
   980 	if (iLocalisableResourceFileName)
       
   981 		{
       
   982 		return *iLocalisableResourceFileName;
       
   983 		}
       
   984 	else
       
   985 		{
       
   986 		return TPtrC(KNullDesC);
       
   987 		}
       
   988 	}
       
   989 
       
   990 
       
   991 /** Returns the non-native application opaque data
       
   992 
       
   993 @return The non-native application opaque data.
       
   994 @internalComponent
       
   995 */
       
   996 EXPORT_C TPtrC8 CApaAppData::OpaqueData() const
       
   997 	{
       
   998 	if (iOpaqueData)
       
   999 		{
       
  1000 		return *iOpaqueData;
       
  1001 		}
       
  1002 	else
       
  1003 		{
       
  1004 		return TPtrC8(KNullDesC8);
       
  1005 		}
       
  1006 	}
       
  1007 
       
  1008 EXPORT_C TUid CApaAppData::NonNativeApplicationType() const
       
  1009 /** @internalComponent */
       
  1010 	{
       
  1011 	return iNonNativeApplicationType;
       
  1012 	}
       
  1013 
       
  1014 /** Returns the full filename of the file containing application icons
       
  1015 
       
  1016 @return The full path and filename of the icon file.
       
  1017 */
       
  1018 EXPORT_C TPtrC CApaAppData::IconFileName() const
       
  1019 	{
       
  1020 	if (iIconFileName)
       
  1021 		{
       
  1022 		return *iIconFileName;
       
  1023 		}
       
  1024 	else
       
  1025 		{
       
  1026 		return TPtrC(KNullDesC);
       
  1027 		}
       
  1028 	}
       
  1029 
       
  1030 /** Returns true if the application provides a non-MBM icon filename.
       
  1031 
       
  1032 If this function returns false, this does not necessarily mean
       
  1033 an MBM icon filename is provided.
       
  1034 
       
  1035 @return true if the application provides a non-MBM icon filename.
       
  1036 */
       
  1037 EXPORT_C TBool CApaAppData::NonMbmIconFile() const
       
  1038 	{
       
  1039 	return iNonMbmIconFile;
       
  1040 	}
       
  1041 
       
  1042 
       
  1043 /** Determines the current language the application is using to display its
       
  1044 user interface.
       
  1045 @return The current language.
       
  1046 */	
       
  1047 EXPORT_C TLanguage CApaAppData::ApplicationLanguage() const
       
  1048 	{
       
  1049 	return iApplicationLanguage;
       
  1050 	}
       
  1051 
       
  1052 /** Returns true if the application implements the specified service.
       
  1053 @param aServiceUid The service UID.
       
  1054 @return true if the application implements the specified service.
       
  1055 @internalComponent
       
  1056 */
       
  1057 EXPORT_C TBool CApaAppData::ImplementsService(TUid aServiceUid) const
       
  1058 	{
       
  1059 	if (iServiceArray)
       
  1060 		{
       
  1061 		TInt count = iServiceArray->Count();
       
  1062 		for (TInt i = count-1; i >= 0; i--)
       
  1063 			{
       
  1064 			if ((*iServiceArray)[i].Uid() == aServiceUid)
       
  1065 				{
       
  1066 				return ETrue;
       
  1067 				}
       
  1068 			}
       
  1069 		}
       
  1070 	return EFalse;
       
  1071 	}
       
  1072 	
       
  1073 /** Checks if the application implements the specified service and if the 
       
  1074 service explicitly supports the datatype. Explicitly means that the datatype is
       
  1075 listed in the service's list of datatype in the registration file and is
       
  1076 not the general datatype associated with the application (aka the Open service).
       
  1077 @param aServiceUid The service UID.
       
  1078 @param aDataType The datattype
       
  1079 @return The priority. KDataTypePriorityNotSupported if the app doesn't support
       
  1080 this service with this datatype.
       
  1081 @internalComponent
       
  1082 */
       
  1083 TInt CApaAppData::ImplementsServiceWithDataType(TUid aServiceUid, const TDataType& aDataType) const
       
  1084 	{
       
  1085 	TInt result = KDataTypePriorityNotSupported;
       
  1086 	if (iServiceArray)
       
  1087 		{
       
  1088 		TInt count = iServiceArray->Count();
       
  1089 		for (TInt i = count-1; i >= 0; i--)
       
  1090 			{
       
  1091 			// There can be more than one instance of a given service so we iterate
       
  1092 			// through the whole service list even if we have already found a suitable
       
  1093 			// service.
       
  1094 			if ((*iServiceArray)[i].Uid() == aServiceUid)
       
  1095 				{
       
  1096 				const CArrayFixFlat<TDataTypeWithPriority>& datatypes =
       
  1097 					(*iServiceArray)[i].DataTypes();
       
  1098 				TInt priority = DataType(aDataType, datatypes);
       
  1099 				if (priority > result)
       
  1100 					{
       
  1101 					result = priority;
       
  1102 					}
       
  1103 				}
       
  1104 			}
       
  1105 		}
       
  1106 	return result;
       
  1107 	}
       
  1108 
       
  1109 EXPORT_C void CApaAppData::SetShortCaptionL(const TDesC& aShortCaption)
       
  1110 	{
       
  1111 	if(iShortCaption->Compare(aShortCaption) != 0)
       
  1112 		{
       
  1113 		HBufC* newShortCaption=aShortCaption.AllocL();
       
  1114 		if (!iShortCaptionFromResourceFile)
       
  1115 			{ // store the rsc file caption into iShortCaptionFromResourceFile so that it can be externalized.
       
  1116 			iShortCaptionFromResourceFile = iShortCaption;
       
  1117 			}
       
  1118 		else
       
  1119 			{
       
  1120 			delete iShortCaption;
       
  1121 			}
       
  1122 		iShortCaption = newShortCaption;
       
  1123 		}
       
  1124 	}
       
  1125 
       
  1126 /** Sets the caption of the application. If the caption is from central repository,
       
  1127  it overrides tha value from the resource file.  
       
  1128 */
       
  1129 EXPORT_C void CApaAppData::SetCaptionL(const TDesC& aCaption)
       
  1130 	{
       
  1131 	if(iCaption->Compare(aCaption) != 0)
       
  1132 		{
       
  1133 		HBufC* newCaption=aCaption.AllocL();
       
  1134 		if (!iCaptionFromResourceFile)
       
  1135 			{ // store the rsc file caption into iCaptionFromResourceFile so that it can be externalized.
       
  1136 			iCaptionFromResourceFile = iCaption;
       
  1137 			}
       
  1138 		else
       
  1139 			{
       
  1140 			delete iCaption;
       
  1141 			}
       
  1142 		iCaption = newCaption;
       
  1143 		}
       
  1144 	}
       
  1145 
       
  1146 /** Sets the icon details of an application. If these details are from the central repository,
       
  1147  it overrides the value in the resource file and loads it.
       
  1148 */
       
  1149 EXPORT_C void CApaAppData::SetIconsL(const TDesC& aFileName, TInt aNumIcons)
       
  1150 	{
       
  1151 	if (iIconFileName && 
       
  1152 		iIconFileName->Compare(aFileName) == 0 &&
       
  1153 		iNumOfAppIcons == aNumIcons)
       
  1154 		return;
       
  1155 
       
  1156 	if (!iIconFileNameFromResourceFile)
       
  1157 		{
       
  1158 	 	iNumOfAppIconsFromResourceFile = iNumOfAppIcons;
       
  1159 	 	iIconFileNameFromResourceFile = iIconFileName;
       
  1160 	 	iIconFileName = NULL;
       
  1161 	 	iNonMbmIconFileFromResourceFile = iNonMbmIconFile;
       
  1162 	 	iIconFileTimeStampFromResourceFile = iIconFileTimeStamp;
       
  1163 		}
       
  1164 		
       
  1165 	iNonMbmIconFile = !CApaAppInfoReaderV2::FileIsMbm(aFileName);
       
  1166 	iNumOfAppIcons = aNumIcons;
       
  1167 	
       
  1168 	if (aFileName != KNullDesC)
       
  1169 		{
       
  1170 		iIconFileName = aFileName.AllocL();
       
  1171 		if (!iNonMbmIconFile)
       
  1172 			{
       
  1173 			if (iNumOfAppIcons > 0)
       
  1174 				{
       
  1175 				// Creates an Application Icon Array
       
  1176 				CApaAppIconArray* icons = CApaAppIconArray::NewAppIconsL(iNumOfAppIcons, *iIconFileName, *iIconLoader);
       
  1177 				delete iIcons;
       
  1178 				iIcons = icons;
       
  1179 				}
       
  1180 			}
       
  1181 		else
       
  1182 			{	// Creates an Empty Icon Array if application has Non-Mbm Icons
       
  1183 			CApaAppIconArray* icons = CApaAppIconArray::NewL();
       
  1184 			delete iIcons;
       
  1185 			iIcons = icons;
       
  1186 			}
       
  1187 		}
       
  1188 	else
       
  1189 		{
       
  1190 		CApaAppIconArray* icons = CApaAppIconArray::NewDefaultIconsL();
       
  1191 		delete iIcons;
       
  1192 		iIcons = icons;
       
  1193 		}
       
  1194 	}
       
  1195 
       
  1196 void CApaAppData::SetAppPending()
       
  1197 	{
       
  1198 	if (iIsPresent == CApaAppData::ENotPresent 
       
  1199 		|| iIsPresent == CApaAppData::ENotPresentPendingUpdate)
       
  1200 		{
       
  1201 		iIsPresent = CApaAppData::ENotPresentPendingUpdate;
       
  1202 		}
       
  1203 	else
       
  1204 		{
       
  1205 		iIsPresent = CApaAppData::EPresentPendingUpdate;
       
  1206 		}
       
  1207 	}
       
  1208 
       
  1209 //
       
  1210 // Class CApaAppList
       
  1211 //
       
  1212 
       
  1213 EXPORT_C CApaAppList* CApaAppList::NewL(RFs& aFs,CApaAppRegFinder* aAppRegFinder, TBool aLoadMbmIconsOnDemand, TInt aIdlePeriodicDelay)
       
  1214 	{
       
  1215 	CApaAppList* self=new CApaAppList(aFs, aAppRegFinder, aLoadMbmIconsOnDemand, aIdlePeriodicDelay);
       
  1216 	if (!self)
       
  1217 		{
       
  1218 		delete aAppRegFinder;
       
  1219 		User::LeaveNoMemory();
       
  1220 		}
       
  1221 	else
       
  1222 		{
       
  1223 		CleanupStack::PushL(self);
       
  1224 		self->ConstructL();
       
  1225 		CleanupStack::Pop(self);
       
  1226 		}
       
  1227 	return self;
       
  1228 	}
       
  1229 
       
  1230 CApaAppList::CApaAppList(RFs& aFs, CApaAppRegFinder* aAppRegFinder, TBool aLoadMbmIconsOnDemand, TInt aIdlePeriodicDelay)
       
  1231 	:iFs(aFs),
       
  1232 	iFlags(0),
       
  1233 	iAppRegFinder(aAppRegFinder),
       
  1234 	iIdlePeriodicDelay(aIdlePeriodicDelay),
       
  1235 	iLoadMbmIconsOnDemand(aLoadMbmIconsOnDemand),
       
  1236     iUninstalledApps(NULL)	
       
  1237 	{
       
  1238 	}
       
  1239 
       
  1240 void CApaAppList::ConstructL()
       
  1241 	{
       
  1242 	User::LeaveIfError(iFsShareProtected.Connect());
       
  1243 	User::LeaveIfError(iFsShareProtected.ShareProtected());
       
  1244 	User::LeaveIfError(Dll::SetTls(this));
       
  1245 	
       
  1246 	//Start language change monitor.
       
  1247 	iAppLangMonitor = CApaLangChangeMonitor::NewL(*this);
       
  1248 	GetAppsListCachePathL();
       
  1249 	}
       
  1250 	
       
  1251 EXPORT_C CApaAppList::~CApaAppList()
       
  1252 /** Frees all resources prior to destruction, including the application data list. */
       
  1253 	{
       
  1254 	iValidFirstAppData = NULL;
       
  1255 	DeleteAppData();
       
  1256 
       
  1257 	iAppData = NULL;
       
  1258 	iObserver = NULL;
       
  1259 	iFsShareProtected.Close();
       
  1260 
       
  1261 	delete iDefaultIconArray;
       
  1262 	delete iDefaultAppIconMbmFileName;
       
  1263 	delete iAppRegFinder;
       
  1264 	delete iAppIdler;
       
  1265 	delete iAppListStorer;
       
  1266 	delete iAppIconLoader;
       
  1267 	delete iAppLangMonitor;
       
  1268 	iAppsListCacheFileName.Close();
       
  1269 	iAppsListCacheBackUpFileName.Close();
       
  1270 	iAppsListCachePath.Close();
       
  1271 	}
       
  1272 
       
  1273 // Stop scanning applications if and uninstallation has started	
       
  1274 EXPORT_C void CApaAppList::StopScan(TBool aNNAInstall)
       
  1275 	{
       
  1276 	if (aNNAInstall)
       
  1277 		{
       
  1278 		iNNAInstallation = ETrue;
       
  1279 		}
       
  1280 	if (iAppIdler)
       
  1281 		{
       
  1282 		delete iAppIdler;
       
  1283 		iAppIdler=NULL;
       
  1284 		}
       
  1285 	UndoSetPending(iAppData);
       
  1286 	}
       
  1287 	
       
  1288 // Allow scanning when uninstallation is complete
       
  1289 EXPORT_C void CApaAppList::RestartScanL()
       
  1290 	{
       
  1291 	TRAP_IGNORE(PurgeL());
       
  1292 	StartIdleUpdateL();
       
  1293 	}
       
  1294 	
       
  1295 EXPORT_C TBool CApaAppList::AppListUpdatePending()
       
  1296 	{
       
  1297 	return iNNAInstallation;
       
  1298 	}
       
  1299 
       
  1300 void CApaAppList::UndoSetPending(CApaAppData* aAppData)
       
  1301 	// Reset all apps to pevious pending state so they don't get purged
       
  1302 	{
       
  1303   	for (; aAppData; aAppData = aAppData->iNext)
       
  1304 		{
       
  1305 		if (aAppData->iIsPresent == CApaAppData::EPresentPendingUpdate)
       
  1306 			{
       
  1307 			aAppData->iIsPresent = CApaAppData::EIsPresent;
       
  1308 			}
       
  1309 		}
       
  1310 	}
       
  1311 
       
  1312 EXPORT_C void CApaAppList::StartIdleUpdateL()
       
  1313 /** Updates the list asynchronously, using an idle time active object, 
       
  1314 and no observer. When the update is finished, the resulting app 
       
  1315 list is stored. */
       
  1316 	{
       
  1317 	// find the default icons (.mbm file) for applications, wrt current locale
       
  1318 	CreateDefaultAppIconFileNameL();
       
  1319 
       
  1320 	// File operation is abandoned if it is in progress.
       
  1321 	if (iAppListStorer && iAppListStorer->IsActive())
       
  1322 		{
       
  1323 		delete iAppListStorer;
       
  1324 		iAppListStorer = NULL;
       
  1325 		}
       
  1326 
       
  1327 	// Stops icon loading if it is in progress.
       
  1328 	if (iAppIconLoader && iAppIconLoader->IsActive())
       
  1329 		{
       
  1330 		delete iAppIconLoader;
       
  1331 		iAppIconLoader = NULL;
       
  1332 		}
       
  1333 
       
  1334 	// DEF076594 - if changing locale, need to update the default icons here
       
  1335 	// If updating the default icons array fails, the array is left in the state
       
  1336 	// it was in before the call.
       
  1337 	if(iDefaultIconArray)
       
  1338 		{
       
  1339 		TRAP_IGNORE(UpdateDefaultIconsL());
       
  1340 		}
       
  1341 
       
  1342 	// start to scan.
       
  1343 	if (iAppIdler)
       
  1344 		{
       
  1345 		delete iAppIdler;
       
  1346 		iAppIdler=NULL;
       
  1347 		}
       
  1348 		
       
  1349 	// DEF072701
       
  1350 	// When performing the update scan let the idle object have lower priority.
       
  1351 	if (IsFirstScanComplete())
       
  1352 		{
       
  1353 		iAppIdler=CPeriodic::NewL(CActive::EPriorityLow);
       
  1354 		}
       
  1355 	else
       
  1356 		{
       
  1357 		iAppIdler=CPeriodic::NewL(CActive::EPriorityStandard);
       
  1358 		}
       
  1359 	SetPending(iAppData);
       
  1360 	iAppRegFinder->FindAllAppsL();
       
  1361  
       
  1362  	// DEF072701
       
  1363  	// If this is the first scan i.e the boot scan then it may take some time. Thus
       
  1364  	// the periodic delay value should be used so that this process will stop periodically 
       
  1365  	// to allow time for other processes.
       
  1366  	// If this is just a re-scan it should take much less time. Therefore it should just
       
  1367  	// be completed in one go rather than periodically delayed. Thus the delay value
       
  1368  	// should be set to 0.
       
  1369 	iAppIdler->Start(KIdleStartDelay, IsFirstScanComplete()? 0 : iIdlePeriodicDelay, TCallBack(IdleUpdateCallbackL, this));
       
  1370 	}
       
  1371 
       
  1372 EXPORT_C void CApaAppList::StartIdleUpdateL(MApaAppListObserver* aObserver)
       
  1373 /** Updates the list asynchronously, using an idle time active object 
       
  1374 and an observer. When the update is finished, the resulting app list 
       
  1375 is stored and the observer is notified with an MApaAppListServObserver::EAppListChanged 
       
  1376 message, if the list changed.
       
  1377 @param aObserver Observer to be notified when the update has finished. */
       
  1378 	{
       
  1379 	iObserver=aObserver;
       
  1380 
       
  1381 	// Rename Appslist.bin file to AppsList_Backup.bin, so that it can be renamed back, if rescan/update scan does not change applist.
       
  1382 	TInt replaceError = iFs.Replace(iAppsListCacheFileName, iAppsListCacheBackUpFileName);
       
  1383 	if (replaceError != KErrNone)
       
  1384 		{
       
  1385 		iFs.Delete(iAppsListCacheFileName);
       
  1386 		}
       
  1387 	StartIdleUpdateL();
       
  1388 	}
       
  1389 
       
  1390 void CApaAppList::CreateDefaultAppIconFileNameL()
       
  1391 	{
       
  1392 	TFileName tempFileName(KDefaultAppIconMbm);
       
  1393 	BaflUtils::NearestLanguageFile(iFs, tempFileName);
       
  1394 	delete iDefaultAppIconMbmFileName;
       
  1395 	iDefaultAppIconMbmFileName = NULL;
       
  1396 	iDefaultAppIconMbmFileName = tempFileName.AllocL();
       
  1397 	}
       
  1398 
       
  1399 EXPORT_C void CApaAppList::InitListL(MApaAppListObserver* aObserver)
       
  1400 /** It Restores the data present in the AppsList.bin file and updates the applist. 
       
  1401  * If Restore operation fails then it 
       
  1402  * starts updating the list asynchronously, by calling StartIdleUpdateL().
       
  1403 
       
  1404 @param aObserver Observer to be notified when the update has finished. */
       
  1405 	{
       
  1406 	DeleteAppsListBackUpAndTempFiles();
       
  1407 	TInt ret = KErrGeneral;
       
  1408 //#ifndef __WINS__ // on the emulator, don't read app list from file, as doing so means apps
       
  1409                  // built while the emulator isn't running won't appear in the list
       
  1410 	TRAP(ret, RestoreL());
       
  1411 //#endif
       
  1412 	if (ret != KErrNone)
       
  1413 		{
       
  1414 		// There was an error during restore, so update the list asynchronously.
       
  1415 		DeleteAppData();
       
  1416 		iFs.Delete(iAppsListCacheFileName);
       
  1417 		StartIdleUpdateL(aObserver);
       
  1418 		}
       
  1419 	else
       
  1420 		{
       
  1421 		iObserver = aObserver;
       
  1422 		if (iLoadMbmIconsOnDemand)
       
  1423 			{
       
  1424 			InitiateStoringOfAppList();
       
  1425 			}
       
  1426 		else
       
  1427 			{
       
  1428 			StartIconLoadingL();
       
  1429 			}
       
  1430 		}
       
  1431 	}
       
  1432 
       
  1433 void CApaAppList::StartIconLoadingL()
       
  1434 	{
       
  1435 	iAppIconLoader = new(ELeave) CApaIdleIconLoader(iAppData, iFs, *this);
       
  1436 	iAppIconLoader->Start();
       
  1437 	}
       
  1438 
       
  1439 void CApaAppList::ScanRemovableDrivesAndUpdateL()
       
  1440 /** Rename Appslist.bin file to AppsList_Backup.bin, so that it can be renamed back, 
       
  1441      if the update scan on removable media drives does not change applist. */
       
  1442 	{
       
  1443 	const RArray<TDriveUnitInfo>& listOfRemovableMediaDrives = iAppRegFinder->DriveList();
       
  1444 	const TInt count = listOfRemovableMediaDrives.Count();
       
  1445 
       
  1446 	// Removable media scan would take place only if removable drives are present.
       
  1447 	if (count)
       
  1448 		{
       
  1449 		CApaAppData* appData = iAppData;
       
  1450 		while (appData)
       
  1451 			{
       
  1452 			for (TInt driveIndex = 0; driveIndex < count; ++driveIndex)
       
  1453 				{
       
  1454 				if (TParsePtrC(*appData->iRegistrationFile).Drive() == listOfRemovableMediaDrives[driveIndex].iDriveUnit.Name())
       
  1455 					{
       
  1456 					appData->SetAppPending();
       
  1457 					break;
       
  1458 					}
       
  1459 				}
       
  1460 			appData = appData->iNext;
       
  1461 			}
       
  1462 
       
  1463 		while (IdleUpdateL())
       
  1464 			{ // It updates the removable media apps present in AppList if it has changed.
       
  1465 
       
  1466 			};
       
  1467 		}
       
  1468 	}
       
  1469 
       
  1470 void CApaAppList::DeleteAppsListBackUpAndTempFiles()
       
  1471 /** Deletes all files inside AppsListCache folder except AppsList.bin */
       
  1472 	{
       
  1473 	_LIT(KTemp, "AppsList.bin");
       
  1474 	CDir* cache = NULL;
       
  1475 	TInt ret = iFs.GetDir(iAppsListCachePath, KEntryAttNormal, ESortNone, cache);
       
  1476 	if (ret == KErrNone)
       
  1477 		{
       
  1478 		const TInt count = cache->Count();
       
  1479 		for (TInt i = 0; i < count; ++i)
       
  1480 			{
       
  1481 			TBufC<KMaxFileName> cacheFileName = (*cache)[i].iName;
       
  1482 	#if defined (SYMBIAN_BAFL_SYSUTIL)
       
  1483 				if ((cacheFileName.Match(KTemp) == KErrNotFound) && (cacheFileName.Match(KROMVersionStringCacheFileName) == KErrNotFound)) 
       
  1484 	#else
       
  1485 				if ((cacheFileName.Match(KTemp) == KErrNotFound)) 
       
  1486 	#endif
       
  1487 				{
       
  1488 				TFileName fileNameToDelete;
       
  1489 				fileNameToDelete.Append(iAppsListCachePath);
       
  1490 				fileNameToDelete.Append(cacheFileName);
       
  1491 				iFs.Delete(fileNameToDelete);
       
  1492 				}
       
  1493 			}
       
  1494 		delete cache;
       
  1495 		}
       
  1496 	}
       
  1497 
       
  1498 void CApaAppList::RestoreL()
       
  1499 /** It restores the data present in the AppsList.bin file */
       
  1500 	{
       
  1501 	RFileReadStream theReadStream;
       
  1502 	User::LeaveIfError(theReadStream.Open(iFs, iAppsListCacheFileName, EFileRead));
       
  1503 	CleanupClosePushL(theReadStream);
       
  1504 	
       
  1505 	TLanguage appListFileLanguage = (TLanguage)theReadStream.ReadInt32L();
       
  1506 	if (appListFileLanguage != User::Language())
       
  1507 		{
       
  1508 		User::Leave(KErrNotSupported);
       
  1509 		}
       
  1510 		
       
  1511 #if defined (SYMBIAN_BAFL_SYSUTIL)
       
  1512 	//Build the filename for the cache file
       
  1513 	TInt maxSizeofFileName = iAppsListCachePath.Length() + KROMVersionStringCacheFileName().Length();
       
  1514 	RBuf romVersionCacheFileName;
       
  1515 	romVersionCacheFileName.CreateL(maxSizeofFileName);
       
  1516 	romVersionCacheFileName.CleanupClosePushL();
       
  1517 	romVersionCacheFileName.Append(iAppsListCachePath);
       
  1518 	romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
       
  1519 	
       
  1520 	RFileReadStream romVerStream;
       
  1521 	User::LeaveIfError(romVerStream.Open(iFs,romVersionCacheFileName,EFileRead));
       
  1522 	CleanupClosePushL(romVerStream);
       
  1523 	
       
  1524 	TVersion actualROMVersionCacheFileVersion(KROMVersionCacheFileMajorVersion, KROMVersionCacheFileMinorVersion, KROMVersionCacheFileBuildVersion);
       
  1525 	TVersionName actualROMVersionCacheFileVersionName = actualROMVersionCacheFileVersion.Name();
       
  1526 	
       
  1527 	//read the rom file version
       
  1528 	TInt8 romVersionCacheFileMajorVersion = romVerStream.ReadInt8L();
       
  1529 	TInt8 romVersionCacheFileMinorVersion = romVerStream.ReadInt8L();
       
  1530 	TInt16 romVersionCacheFileBuildVersion = romVerStream.ReadInt16L();
       
  1531 	TVersion romVersionCacheFileVersion(romVersionCacheFileMajorVersion, romVersionCacheFileMinorVersion, romVersionCacheFileBuildVersion);
       
  1532 	TVersionName romVersionCacheFileVersionName = romVersionCacheFileVersion.Name();
       
  1533 	
       
  1534 	//If persisted file version differs from what apparc can handle, recreate rom version file and applist.bin
       
  1535 	if (romVersionCacheFileVersionName.Compare(actualROMVersionCacheFileVersionName) != 0)
       
  1536 		{
       
  1537 		User::Leave(KErrGeneral);
       
  1538 		}
       
  1539 		
       
  1540 	//Read the length & value of software version from it.
       
  1541 	TBuf<KInfoBufLength> softwareVersion;
       
  1542 	TUint32 length = romVerStream.ReadUint32L();
       
  1543 	if (length>KInfoBufLength)
       
  1544 		{
       
  1545 		//File must be corrupt, an attempt to read will panic
       
  1546 		User::Leave(KErrCorrupt);
       
  1547 		}	
       
  1548 	romVerStream.ReadL(softwareVersion, length);
       
  1549 
       
  1550 	//the persisted version has been successfully read
       
  1551 	//read the actual current version string
       
  1552 	TBuf<KInfoBufLength> actualSoftwareVersion;
       
  1553 	TInt err = SysUtil::GetSWVersion(actualSoftwareVersion); //use the SysUtil implementation
       
  1554 	if(err == KErrNone)
       
  1555 		{
       
  1556 		if (softwareVersion.Compare(actualSoftwareVersion) != 0)
       
  1557 			{
       
  1558 			//Leave if the current version is different from the previous stored version and recreate applist.
       
  1559 #ifdef _DEBUG
       
  1560 			RDebug::Print(_L("!!Firmware update detected!! Rebuilding AppList"));
       
  1561 #endif
       
  1562 			User::Leave(KErrGeneral);
       
  1563 			}
       
  1564 		}
       
  1565 	else
       
  1566 		{
       
  1567 		//Leave if any error reading the version information, except if file is not present
       
  1568 		if (err != KErrPathNotFound && err != KErrNotFound)
       
  1569 			{
       
  1570 #ifdef _DEBUG
       
  1571 			RDebug::Print(_L("!!Error %d reading Firmware version.  Rebuilding AppList"),err);
       
  1572 #endif
       
  1573 			User::Leave(err);
       
  1574 			}
       
  1575 		}
       
  1576 	CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
       
  1577 #endif
       
  1578 	
       
  1579 	// Create Default Icon File Name
       
  1580 	CreateDefaultAppIconFileNameL();
       
  1581 	
       
  1582 	TInt ret = KErrNone;
       
  1583 	while (ret == KErrNone)
       
  1584 		{
       
  1585 		CApaAppData* const pApp = new (ELeave) CApaAppData(iFs);
       
  1586 		CleanupStack::PushL(pApp);
       
  1587 
       
  1588 		// Restore entries till we leave
       
  1589 		TRAP(ret, pApp->InternalizeL(theReadStream));
       
  1590 		
       
  1591 		if (ret != KErrNone && ret != KErrEof)
       
  1592 			{
       
  1593 			User::Leave(ret);
       
  1594 			}
       
  1595 		// Check that the app has not been added to the list twice
       
  1596 		if (ret == KErrNone && !AppDataByUid(pApp->iUidType[2]))
       
  1597 			{
       
  1598 			AddToList(pApp);
       
  1599 			CleanupStack::Pop(pApp);
       
  1600 			}
       
  1601 		else
       
  1602 			{ // Delete pApp if an End of File condition is reached or the app has been added to the list twice
       
  1603 			CleanupStack::PopAndDestroy(pApp);
       
  1604 			}
       
  1605 		}	
       
  1606 	// Close the stream;
       
  1607 	CleanupStack::PopAndDestroy(&theReadStream);
       
  1608 
       
  1609 	iFs.Rename(iAppsListCacheFileName, iAppsListCacheBackUpFileName);
       
  1610 	iAppRegFinder->FindAllRemovableMediaAppsL();	// Builds the Removable Media Drive List
       
  1611 
       
  1612 	iFlags |= ENotifyUpdateOnFirstScanComplete;
       
  1613 
       
  1614 	// It runs an update scan on removable media apps.
       
  1615 	ScanRemovableDrivesAndUpdateL();
       
  1616 	}
       
  1617 
       
  1618 EXPORT_C TBool CApaAppList::IsLanguageChangePending() const
       
  1619 /** Returns ETrue if a language change event is received and a re-scan is in progress otherwise EFalse. */
       
  1620 	{
       
  1621 	return (iFlags & ELangChangePending);
       
  1622 	}
       
  1623 
       
  1624 void CApaAppData::InternalizeL(RReadStream& aReadStream)
       
  1625 /** Internalizes the appdata from the AppsList.bin file */
       
  1626 	{
       
  1627 	TUint highTime = aReadStream.ReadUint32L();
       
  1628 	TUint lowTime = aReadStream.ReadUint32L();
       
  1629 	iTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));
       
  1630 
       
  1631 	highTime = aReadStream.ReadUint32L();
       
  1632 	lowTime = aReadStream.ReadUint32L();
       
  1633 	iIconFileTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));
       
  1634 	iCaption = HBufC::NewL(aReadStream, KMaxFileName);	// Caption
       
  1635 	iShortCaption = HBufC::NewL(aReadStream, KMaxFileName);	// Shortcaption
       
  1636 	iFullName = HBufC::NewL(aReadStream, KMaxFileName);		// Filename of application binary
       
  1637 
       
  1638 	TUid uid1;
       
  1639 	uid1.iUid = aReadStream.ReadUint32L();
       
  1640 	TUid uid2;
       
  1641 	uid2.iUid = aReadStream.ReadUint32L();	
       
  1642 	TUid uid3;
       
  1643 	uid3.iUid = aReadStream.ReadUint32L();
       
  1644 	iUidType = TUidType(uid1, uid2, uid3);	// Application UID
       
  1645 	
       
  1646 	aReadStream >> iCapabilityBuf;
       
  1647 
       
  1648 	iRegistrationFile = HBufC::NewL(aReadStream, KMaxFileName);	// Registration Filename
       
  1649 		
       
  1650 	iDefaultScreenNumber = aReadStream.ReadUint32L();	// Default Screen number
       
  1651 	
       
  1652 	iNumOfAppIcons = aReadStream.ReadInt32L();	// No. of icons
       
  1653 
       
  1654 	iNonMbmIconFile = aReadStream.ReadUint32L();
       
  1655 
       
  1656 	HBufC* iconFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Icon Filename
       
  1657 	if (*iconFileName != KNullDesC)
       
  1658 		{
       
  1659 		iIconFileName = iconFileName;
       
  1660 		if (!iNonMbmIconFile)
       
  1661 			{
       
  1662 			if (iNumOfAppIcons > 0)
       
  1663 				{ // Create IconLoader to load icons
       
  1664 				iIconLoader = CApaIconLoader::NewL(iFs);
       
  1665 				// Creates an Application Icon Array
       
  1666 				iIcons = CApaAppIconArray::NewAppIconsL(iNumOfAppIcons, *iIconFileName, *iIconLoader);
       
  1667 				}
       
  1668 			else
       
  1669 			    TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL()); // Creates and Loads Default Icons.
       
  1670 			}
       
  1671 		else
       
  1672 			{	// Creates an Empty Icon Array if application has Non-Mbm Icons
       
  1673 			iIcons = CApaAppIconArray::NewL();
       
  1674 			}
       
  1675 		}
       
  1676 	else
       
  1677 		{
       
  1678 		delete iconFileName;
       
  1679 		TRAP_IGNORE(iIcons = CApaAppIconArray::NewDefaultIconsL()); // Creates and Loads Default Icons.
       
  1680 		}
       
  1681 
       
  1682 	HBufC* localisableResourceFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Registration Filename
       
  1683 	if (*localisableResourceFileName != KNullDesC)
       
  1684 		{
       
  1685 		iLocalisableResourceFileName = localisableResourceFileName;
       
  1686 		}
       
  1687 	else
       
  1688 		{
       
  1689 		delete localisableResourceFileName;
       
  1690 		}	
       
  1691 
       
  1692 	highTime = aReadStream.ReadUint32L();
       
  1693 	lowTime = aReadStream.ReadUint32L();
       
  1694 	iLocalisableResourceFileTimeStamp = TTime(MAKE_TINT64(highTime, lowTime));	// Localisable file timestamp
       
  1695 
       
  1696 	iApplicationLanguage = (TLanguage)aReadStream.ReadInt32L();	// Application Language
       
  1697 
       
  1698 	iIndexOfFirstOpenService = aReadStream.ReadUint32L();		// Index of first open service
       
  1699 
       
  1700 	iNonNativeApplicationType.iUid = aReadStream.ReadUint32L();
       
  1701 
       
  1702 	HBufC8* opaqueData = HBufC8::NewL(aReadStream, KMaxFileName);	// Opaque Data
       
  1703 	if (*opaqueData != KNullDesC8)
       
  1704 		{
       
  1705 		iOpaqueData = opaqueData;
       
  1706 		}
       
  1707 	else
       
  1708 		{
       
  1709 		delete opaqueData;
       
  1710 		}
       
  1711 
       
  1712 	iViewDataArray = new(ELeave) CArrayPtrFlat<CApaAppViewData>(1);	// ViewDataArray
       
  1713 	const TInt viewCount = aReadStream.ReadInt32L();
       
  1714 	TInt i;	
       
  1715 	for (i = 0; i < viewCount; ++i)
       
  1716 		{
       
  1717 		CApaAppViewData* pView = CApaAppViewData::NewLC();
       
  1718 
       
  1719 		pView->iCaption = HBufC::NewL(aReadStream, KMaxFileName);
       
  1720 		pView->iNumOfViewIcons = aReadStream.ReadUint32L();
       
  1721 		pView->iNonMbmIconFile = aReadStream.ReadUint32L();
       
  1722 		HBufC* iconFileName = HBufC::NewL(aReadStream, KMaxFileName);	// Icon Filename		
       
  1723 		if (*iconFileName != KNullDesC)
       
  1724 			{
       
  1725 			pView->iIconFileName = iconFileName;
       
  1726 			if (!pView->iNonMbmIconFile)
       
  1727 				{
       
  1728 				if (pView->iNumOfViewIcons > 0)
       
  1729 					{
       
  1730 					if (!iIconLoader)
       
  1731 						{	// Create Icon Loader if it was not done for App or any of the previous views for the App.
       
  1732 						iIconLoader = CApaIconLoader::NewL(iFs);
       
  1733 						}
       
  1734 					// Creates an Application View Icon Array
       
  1735 					CApaAppIconArray* iconViewArray = CApaAppIconArray::NewViewIconsL(pView->iNumOfViewIcons, *pView->iIconFileName, *iIconLoader);
       
  1736 					pView->SetIconArray(iconViewArray);
       
  1737 					}
       
  1738 				}
       
  1739 			}
       
  1740 		else
       
  1741 			{
       
  1742 			delete iconFileName;
       
  1743 			}
       
  1744 		pView->iScreenMode = aReadStream.ReadUint32L();
       
  1745 		pView->iUid.iUid = aReadStream.ReadUint32L();
       
  1746 
       
  1747 		iViewDataArray->AppendL(pView);
       
  1748 		CleanupStack::Pop(pView);
       
  1749 		}
       
  1750 
       
  1751 	iServiceArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(1);
       
  1752 	const TInt serviceCount = aReadStream.ReadUint32L();
       
  1753 
       
  1754 	for (i = 0; i < serviceCount; ++i)
       
  1755 		{
       
  1756 		TApaAppServiceInfo serviceInfo ;
       
  1757 		aReadStream >> serviceInfo;
       
  1758 		iServiceArray->AppendL(serviceInfo);
       
  1759 		}
       
  1760 
       
  1761 	iOwnedFileArray = new(ELeave) CDesCArraySeg(1);
       
  1762 	const TInt fileCount = aReadStream.ReadUint32L();	
       
  1763 	for (i = 0; i < fileCount; ++i)
       
  1764 		{
       
  1765 		TFileName ownedFile;
       
  1766 		aReadStream >> ownedFile;
       
  1767 		iOwnedFileArray->AppendL(ownedFile);
       
  1768 		}
       
  1769 	}
       
  1770 
       
  1771 TBool CApaAppData::ViewMbmIconsRequireLoading() const
       
  1772 	{
       
  1773 	const TInt count = iViewDataArray->Count();
       
  1774 	for (TInt i = 0; i < count; ++i)
       
  1775 		{
       
  1776 		const CApaAppViewData* const viewData = iViewDataArray->At(i);
       
  1777 		if ((!viewData->iNonMbmIconFile) && (!viewData->iIcons->AreViewIconsLoaded()))
       
  1778 			{
       
  1779 			return ETrue;
       
  1780 			}
       
  1781 		}
       
  1782 	return EFalse;
       
  1783 	}
       
  1784 	
       
  1785 TBool CApaAppData::MbmIconsRequireLoading() const
       
  1786 	{
       
  1787 	if (!iNonMbmIconFile)
       
  1788 		{
       
  1789 		if (!iIcons->AreAppIconsLoaded())
       
  1790 			{
       
  1791 			return ETrue;
       
  1792 			}
       
  1793 		}
       
  1794 
       
  1795 	if (ViewMbmIconsRequireLoading())
       
  1796 		{// if a view has mbm icons, and its not yet loaded we should load its icons.
       
  1797 		return ETrue;
       
  1798 		}
       
  1799 	return EFalse; // icons were loaded already so no need to load them again.
       
  1800 	}
       
  1801 
       
  1802 void CApaAppData::ExternalizeL(RWriteStream& aWriteStream) const
       
  1803 	{
       
  1804 	aWriteStream.WriteUint32L(I64HIGH(iTimeStamp.Int64()));
       
  1805 	aWriteStream.WriteUint32L(I64LOW(iTimeStamp.Int64()));
       
  1806 
       
  1807 	if (iIconFileNameFromResourceFile)
       
  1808 		{
       
  1809 		aWriteStream.WriteUint32L(I64HIGH(iIconFileTimeStampFromResourceFile.Int64()));
       
  1810 	    aWriteStream.WriteUint32L(I64LOW(iIconFileTimeStampFromResourceFile.Int64()));
       
  1811 		}
       
  1812 	else
       
  1813 		{
       
  1814 	aWriteStream.WriteUint32L(I64HIGH(iIconFileTimeStamp.Int64()));
       
  1815 	aWriteStream.WriteUint32L(I64LOW(iIconFileTimeStamp.Int64()));
       
  1816 		}
       
  1817 		
       
  1818 	if (iCaptionFromResourceFile)	// Caption present in the resource file would be externalized if the one in applist has dynamically changed
       
  1819 		{
       
  1820 		aWriteStream << *iCaptionFromResourceFile;
       
  1821 		}
       
  1822 	else
       
  1823 		{
       
  1824 		aWriteStream << *iCaption;
       
  1825 		}
       
  1826 		
       
  1827 	if (iShortCaptionFromResourceFile)	// Short caption present in the resource file would be externalized if the one in applist has dynamically changed
       
  1828 		{
       
  1829 		aWriteStream << *iShortCaptionFromResourceFile;
       
  1830 		}
       
  1831 	else
       
  1832 		{
       
  1833 		aWriteStream << *iShortCaption;
       
  1834 		}
       
  1835 	aWriteStream << *iFullName;	// FullName
       
  1836 
       
  1837 	TInt i;
       
  1838 	for (i = 0; i < 3; ++i)
       
  1839 		{
       
  1840 		aWriteStream << iUidType[i];	// Uid Type
       
  1841 		}
       
  1842 
       
  1843 	aWriteStream << iCapabilityBuf;
       
  1844 	aWriteStream << RegistrationFileName();	// Registration filename
       
  1845 	aWriteStream.WriteUint32L(iDefaultScreenNumber);	// Default screen number
       
  1846 
       
  1847 	if (iIconFileNameFromResourceFile)
       
  1848 		{
       
  1849 		aWriteStream.WriteUint32L(iNumOfAppIconsFromResourceFile);	// number of icons
       
  1850 
       
  1851 		aWriteStream.WriteUint32L(iNonMbmIconFileFromResourceFile);
       
  1852 
       
  1853 		aWriteStream << *iIconFileNameFromResourceFile;
       
  1854 		}
       
  1855 	else
       
  1856 		{
       
  1857 	aWriteStream.WriteUint32L(iNumOfAppIcons);	// number of icons
       
  1858 
       
  1859 	aWriteStream.WriteUint32L(iNonMbmIconFile);
       
  1860 
       
  1861 	aWriteStream << IconFileName();
       
  1862 		}
       
  1863 
       
  1864 	aWriteStream << LocalisableResourceFileName();
       
  1865 
       
  1866 	aWriteStream.WriteUint32L(I64HIGH(iLocalisableResourceFileTimeStamp.Int64()));
       
  1867 	aWriteStream.WriteUint32L(I64LOW(iLocalisableResourceFileTimeStamp.Int64()));
       
  1868 
       
  1869 	aWriteStream.WriteInt32L(iApplicationLanguage);
       
  1870 
       
  1871 	aWriteStream.WriteUint32L(iIndexOfFirstOpenService);
       
  1872 
       
  1873 	aWriteStream.WriteUint32L(iNonNativeApplicationType.iUid);
       
  1874 
       
  1875 	aWriteStream << OpaqueData();
       
  1876 	
       
  1877 	TInt count = iViewDataArray->Count();
       
  1878 	aWriteStream.WriteUint32L(count);
       
  1879 
       
  1880 	for (i = 0; i < count; ++i)
       
  1881 		{
       
  1882 		const CApaAppViewData* const viewData = iViewDataArray->At(i);
       
  1883 		aWriteStream << *(viewData->iCaption);
       
  1884 		aWriteStream.WriteUint32L(viewData->iNumOfViewIcons);
       
  1885 		aWriteStream.WriteUint32L(viewData->iNonMbmIconFile);
       
  1886 		aWriteStream << viewData->IconFileName();		
       
  1887 		aWriteStream.WriteUint32L(viewData->iScreenMode);
       
  1888 		aWriteStream.WriteUint32L(viewData->iUid.iUid);
       
  1889 		}
       
  1890 
       
  1891 	// TApaAppServiceInfo service array
       
  1892 	if (iServiceArray)
       
  1893 		{
       
  1894 		count = iServiceArray->Count();
       
  1895 		aWriteStream.WriteUint32L(count);
       
  1896 		for (i = 0; i < count; ++i)
       
  1897 			{
       
  1898 			aWriteStream << iServiceArray->At(i);
       
  1899 			}
       
  1900 		}
       
  1901 	else
       
  1902 		{
       
  1903 		aWriteStream.WriteUint32L(NULL);
       
  1904 		}
       
  1905 
       
  1906 	if (iOwnedFileArray)
       
  1907 		{
       
  1908 		count = iOwnedFileArray->MdcaCount();
       
  1909 		aWriteStream.WriteUint32L(count);
       
  1910 		for (i = 0; i < count; ++i)
       
  1911 			{
       
  1912 			aWriteStream << (*iOwnedFileArray)[i];
       
  1913 			}
       
  1914 		}
       
  1915 	else
       
  1916 		{
       
  1917 		aWriteStream.WriteUint32L(0);
       
  1918 		}
       
  1919 	}
       
  1920 
       
  1921 TInt CApaAppList::IdleUpdateCallbackL(TAny* aObject)
       
  1922 	{
       
  1923 	CApaAppList* self=REINTERPRET_CAST(CApaAppList*,aObject);
       
  1924 	const TBool moreToCome=self->IdleUpdateL();
       
  1925 	if (moreToCome==EFalse)
       
  1926 		{
       
  1927 		//Reset language change flag if scanning is over.
       
  1928 		if (self->IsLanguageChangePending())
       
  1929 			{
       
  1930 			self->iFlags &= ~ELangChangePending;
       
  1931 			}
       
  1932 		self->StopIdler();
       
  1933 		if (self->iLoadMbmIconsOnDemand)
       
  1934 			{
       
  1935 			self->InitiateStoringOfAppList();
       
  1936 			}
       
  1937 		else
       
  1938 			{
       
  1939 			self->StartIconLoadingL();
       
  1940 			}
       
  1941 		}
       
  1942 	return moreToCome;
       
  1943 	}
       
  1944 
       
  1945 void CApaAppList::StoreL()
       
  1946 	{
       
  1947 	iAppListStorer = CApaAppListStorer::NewL(iAppData, iFs, *this);
       
  1948 	iAppListStorer->StartL(KAppListToFileStartDelay);
       
  1949 	}
       
  1950 
       
  1951 void CApaAppList::NotifyObserver()
       
  1952 	{
       
  1953 	if (iObserver)
       
  1954 		{
       
  1955 		if (iFlags & EAppListHasChanged || iFlags & ENotifyUpdateOnFirstScanComplete)
       
  1956 			{
       
  1957 			// NotifyUpdate will notify clients for both list update and scan complete.
       
  1958 			iObserver->NotifyUpdate(MApaAppListServObserver::EAppListChanged);
       
  1959 			}
       
  1960 		else
       
  1961 			{
       
  1962 			// NotifyScanComplete will notify clients for scan complete.
       
  1963 			iObserver->NotifyScanComplete();
       
  1964 			}
       
  1965 		iObserver=NULL;
       
  1966 		}
       
  1967 	}
       
  1968 
       
  1969 void CApaAppList::StopIdler()
       
  1970 	{
       
  1971  	delete iAppIdler;
       
  1972 	iAppIdler=NULL;
       
  1973 	}
       
  1974 
       
  1975 TInt CApaAppList::IdleUpdateL()
       
  1976 // returns ETrue if there is more scanning to be done.
       
  1977 	{
       
  1978 	TBool more=EFalse;
       
  1979 	TApaAppEntry currentApp = TApaAppEntry();
       
  1980 	TRAPD(err,more=iAppRegFinder->NextL(currentApp, iForcedRegistrations));
       
  1981 	if (err!=KErrNone)
       
  1982 		{
       
  1983 		if (iFlags & ENotifyUpdateOnFirstScanComplete)
       
  1984 			{
       
  1985 			User::Leave(err);
       
  1986 			}
       
  1987 		return more;
       
  1988 		}
       
  1989 	TBool hasChanged=EFalse;
       
  1990 	if (more)
       
  1991 		{
       
  1992 		TRAPD(err,UpdateNextAppL(currentApp,hasChanged));
       
  1993 		if (err!=KErrNone)
       
  1994 			{
       
  1995 			SetNotFound(iAppData,hasChanged);
       
  1996 			if (iFlags & ENotifyUpdateOnFirstScanComplete)
       
  1997 				{
       
  1998 				User::Leave(err);
       
  1999 				}	
       
  2000 			more=EFalse; // abandon ship
       
  2001 			}
       
  2002 		}
       
  2003 	else
       
  2004 		{
       
  2005 		SetNotFound(iAppData,hasChanged);
       
  2006 		PurgeL();
       
  2007 		}
       
  2008 
       
  2009 	if (hasChanged)
       
  2010 		{
       
  2011 		iFlags |= EAppListHasChanged;
       
  2012 		}
       
  2013 	return more;
       
  2014 	}
       
  2015 
       
  2016 EXPORT_C TBool CApaAppList::IsIdleUpdateComplete() const
       
  2017 /** Tests whether an asynchronous update of the list is currently in progress.
       
  2018 
       
  2019 @return True if no asynchronous update of the list is currently in progress, 
       
  2020 otherwise false. */
       
  2021 	{
       
  2022 	return iAppIdler == NULL;
       
  2023 	}
       
  2024 
       
  2025 void CApaAppList::SetPending(CApaAppData* aAppData)
       
  2026 	// set all apps to pending update - we'll find them again as we scan
       
  2027 	{
       
  2028   	for (; aAppData; aAppData = aAppData->iNext)
       
  2029 		{
       
  2030 		aAppData->SetAppPending();
       
  2031 		}
       
  2032 	}
       
  2033 
       
  2034 void CApaAppList::SetNotFound(CApaAppData* aAppData, TBool& aHasChanged)
       
  2035 	// mark any unfound apps not present
       
  2036 	{
       
  2037 	while (aAppData)
       
  2038 		{
       
  2039 		if (aAppData->IsPending())
       
  2040 			{
       
  2041 			aAppData->iIsPresent = CApaAppData::ENotPresent;
       
  2042 			aHasChanged = ETrue;
       
  2043 			}
       
  2044 		aAppData = aAppData->iNext;
       
  2045 		}
       
  2046 	}
       
  2047 
       
  2048 void CApaAppList::AddToList( CApaAppData* aAppData )
       
  2049 {
       
  2050 	__ASSERT_DEBUG(aAppData, Panic(EPanicNullPointer));
       
  2051 	aAppData->iNext=iAppData;
       
  2052 	iAppData=aAppData;
       
  2053 }
       
  2054 
       
  2055 void CApaAppList::UpdateNextAppL(const TApaAppEntry& aAppEntry,TBool& aHasChanged)
       
  2056 	{
       
  2057 	CApaAppData* appData=AppDataByUid(aAppEntry.iUidType[2]);
       
  2058 	if (appData==NULL)
       
  2059 		{// not in list, so add it at the start
       
  2060 		TRAPD(err,appData=CApaAppData::NewL(aAppEntry, iFs));
       
  2061 		if (err==KErrNone)
       
  2062 			{
       
  2063 			AddToList( appData );
       
  2064 			aHasChanged=ETrue;
       
  2065 			}
       
  2066 		}
       
  2067 	else if (appData->IsPending())
       
  2068 		{ // not found yet during current scan - we may need to override this one
       
  2069 		
       
  2070 		// On a system which scans for registration .RSC files (V2 apps) first, followed by
       
  2071 		// .APP files (V1 apps), it's valid for a V1 app to override a V2 app (if the V2 app
       
  2072 		// has just been removed). If this is the case, assume it's ok to compare the V1 .APP filename,
       
  2073 		// with the V2 .RSC filename as their filenames will never match (which is what we want in this case).
       
  2074 		TPtrC currentFileName;
       
  2075 		if (appData->RegistrationFileUsed())
       
  2076 			{
       
  2077 			currentFileName.Set(*appData->iRegistrationFile);
       
  2078 			}
       
  2079 		else
       
  2080 			{
       
  2081 			currentFileName.Set(*appData->iFullName);
       
  2082 			}
       
  2083 		if (aAppEntry.iFullName.CompareF(currentFileName)!=0)
       
  2084 			{
       
  2085 			delete appData->iSuccessor;
       
  2086 			appData->iSuccessor = NULL;
       
  2087 			appData->iSuccessor = CApaAppEntry::NewL(aAppEntry);
       
  2088 
       
  2089 
       
  2090 			appData->iIsPresent = CApaAppData::ESuperseded;
       
  2091 			aHasChanged=ETrue;
       
  2092 			}
       
  2093 		else
       
  2094 			{
       
  2095 			if (appData->Update()
       
  2096 				|| appData->iIsPresent==CApaAppData::ENotPresentPendingUpdate) 
       
  2097 				{
       
  2098 				aHasChanged=ETrue; 
       
  2099 				}
       
  2100 			appData->iIsPresent = CApaAppData::EIsPresent;
       
  2101 			}
       
  2102 		}
       
  2103 	}
       
  2104 
       
  2105 /**
       
  2106 @internalComponent
       
  2107 */
       
  2108 EXPORT_C CApaAppData* CApaAppList::FindAndAddSpecificAppL(CApaAppRegFinder* aFinder, TUid aAppUid)
       
  2109 	{
       
  2110 //Scans and adds the specified application to the app list if found
       
  2111 	__ASSERT_DEBUG(aFinder, Panic(EPanicNullPointer));
       
  2112 	TBool found = EFalse;
       
  2113 	TApaAppEntry appEntry;
       
  2114 	aFinder->FindAllAppsL();
       
  2115 	while (aFinder->NextL(appEntry, iForcedRegistrations))
       
  2116 		{
       
  2117 		if (appEntry.iUidType[2] == aAppUid)
       
  2118 			{
       
  2119 			found = ETrue;
       
  2120 			break;
       
  2121 			}
       
  2122 		}
       
  2123 	
       
  2124 	CApaAppData* app = NULL;
       
  2125 	if (found)
       
  2126 		{
       
  2127 		// add the app to the list
       
  2128 		TBool hasChanged = EFalse;
       
  2129 		CApaAppData* prevFirstAppInList = iAppData;
       
  2130 		UpdateNextAppL(appEntry, hasChanged);
       
  2131 		if (iAppData != prevFirstAppInList)
       
  2132 			{
       
  2133 			// assume the new app was added to the list
       
  2134 			app = iAppData;
       
  2135 			}
       
  2136 		if (hasChanged)
       
  2137 			{
       
  2138 			iFlags |= EAppListHasChanged;
       
  2139 			}
       
  2140 		}
       
  2141 	return app;
       
  2142 	}
       
  2143 
       
  2144 EXPORT_C void CApaAppList::PurgeL()
       
  2145 /** Removes any applications from the list if they are no longer present 
       
  2146 on the phone. It updates applications that have been 
       
  2147 superceded. */
       
  2148 	{
       
  2149 	CApaAppData* appData=iAppData;
       
  2150 	CApaAppData* prev=NULL;
       
  2151 	while (appData)
       
  2152 		{
       
  2153 		CApaAppData* next=appData->iNext;
       
  2154 		if (appData->iIsPresent==CApaAppData::ENotPresent)
       
  2155 			{
       
  2156 			if (prev)
       
  2157 				prev->iNext=next;
       
  2158 			else
       
  2159 				iAppData=next;
       
  2160  
       
  2161 			//Add uninstalled application UID to a list
       
  2162             if(iUninstalledApps==NULL)
       
  2163                 iUninstalledApps=new(ELeave) CArrayFixFlat<TUid>(1);
       
  2164             
       
  2165             iUninstalledApps->AppendL(appData->AppEntry().iUidType[2]);
       
  2166  			
       
  2167 			delete appData;
       
  2168 			}
       
  2169 		else if (appData->iIsPresent==CApaAppData::ESuperseded)
       
  2170 			{
       
  2171 			CApaAppData* newApp=NULL;
       
  2172 			TApaAppEntry appEntry;
       
  2173 			appData->iSuccessor->Get(appEntry);
       
  2174 			TRAPD(err,newApp=CApaAppData::NewL(appEntry, iFs));
       
  2175 			if (err==KErrNone)
       
  2176 				{
       
  2177 				// remove the old one and add the new one in its place
       
  2178 				if (prev)
       
  2179 					prev->iNext=newApp;
       
  2180 				else
       
  2181 					iAppData=newApp;
       
  2182 				newApp->iNext = appData->iNext;
       
  2183 				delete appData;
       
  2184 				// increment the iterator
       
  2185 				prev = newApp;
       
  2186 				}
       
  2187 			}
       
  2188 		else
       
  2189 			prev=appData;
       
  2190 		appData=next;
       
  2191 		}
       
  2192 	}
       
  2193 
       
  2194 EXPORT_C TInt CApaAppList::Count() const
       
  2195 /** Gets the count of applications present in the app list.
       
  2196 
       
  2197 @return The number of applications in the list. */
       
  2198 
       
  2199 	{
       
  2200 	TInt count=0;
       
  2201 	CApaAppData* appData=iAppData;
       
  2202 	while (appData)
       
  2203 		{
       
  2204 		count++;
       
  2205 		appData=appData->iNext;
       
  2206 		}
       
  2207 	return count;
       
  2208 	}
       
  2209 
       
  2210 EXPORT_C CApaAppData* CApaAppList::FirstApp() const
       
  2211 /** Gets a pointer to the first application in the list 
       
  2212 that can use the default screen mode.
       
  2213 
       
  2214 @return A pointer to the first application. */
       
  2215 	{
       
  2216 	return FirstApp(0);
       
  2217 	}
       
  2218 
       
  2219 EXPORT_C CApaAppData* CApaAppList::FirstApp(TInt aScreenMode) const
       
  2220 /** Gets a pointer to the first application in the list 
       
  2221 that can use the specified screen mode.
       
  2222 
       
  2223 @param aScreenMode The index of the screen mode. Specifying 
       
  2224 KIgnoreScreenMode returns the first application in the list, 
       
  2225 regardless of screen mode.
       
  2226 @return A pointer to the first application that can use the 
       
  2227 specified screen mode. */
       
  2228 	{
       
  2229 
       
  2230 	CApaAppData* appData=iValidFirstAppData;
       
  2231 
       
  2232 	if(aScreenMode!=KIgnoreScreenMode)
       
  2233 		{
       
  2234 		while (appData && !appData->CanUseScreenMode(aScreenMode))
       
  2235 			appData = appData->iNext;
       
  2236 		}
       
  2237 
       
  2238 	return appData;
       
  2239 	}
       
  2240 
       
  2241 EXPORT_C CApaAppData* CApaAppList::NextApp(const CApaAppData* aApp) const
       
  2242 /** Gets a pointer to the next application after aApp in the list 
       
  2243 that can use the default screen mode.
       
  2244 
       
  2245 @param aApp A pointer to an application in the list.
       
  2246 @return A pointer to the next application after aApp in the list 
       
  2247 that can use the default screen mode.
       
  2248 @panic APGRFX 12 aApp is NULL. */
       
  2249 	{
       
  2250 	return NextApp(aApp,0);
       
  2251 	}
       
  2252 
       
  2253 EXPORT_C CApaAppData* CApaAppList::NextApp(const CApaAppData* aApp, TInt aScreenMode) const
       
  2254 /** Gets a pointer to the next application after aApp in the list 
       
  2255 that can use the specified screen mode.
       
  2256 
       
  2257 @param aApp A pointer to an application in the list. 
       
  2258 @param aScreenMode The index of the screen mode. Specifying 
       
  2259 KIgnoreScreenMode returns the next application in the list, 
       
  2260 regardless of screen mode.
       
  2261 @return A pointer to the next application after aApp in the list 
       
  2262 that can use the specified screen mode.
       
  2263 @panic APGRFX 12 aApp is NULL. */
       
  2264 
       
  2265 	{
       
  2266 	__ASSERT_ALWAYS(aApp,Panic(EPanicNoAppDataSupplied));
       
  2267 	//
       
  2268 	CApaAppData* iApp=aApp->iNext; //lint !e613 Suppress possible use of null pointer - asserted above
       
  2269 
       
  2270 	if(aScreenMode!=KIgnoreScreenMode)
       
  2271 		while (iApp && !iApp->CanUseScreenMode(aScreenMode))
       
  2272 			iApp = iApp->iNext;
       
  2273 
       
  2274 	return iApp;
       
  2275 	}
       
  2276 
       
  2277 EXPORT_C CApaAppData* CApaAppList::AppDataByUid(TUid aAppUid) const
       
  2278 /** Gets a pointer to the application in the list whose third 
       
  2279 UID matches the specified UID.
       
  2280 
       
  2281 @param aAppUid An application's third UID. 
       
  2282 @return A pointer to the application, if successful. Null, 
       
  2283 if no match is found or if KNullUid was specified. */
       
  2284 	{
       
  2285 	if (aAppUid==KNullUid)
       
  2286 		return NULL; // never match null UID as it represents an un-UIDed file
       
  2287 	CApaAppData* appData=iAppData;
       
  2288 	while (appData)
       
  2289 		{
       
  2290 		if (appData->AppEntry().iUidType[2]==aAppUid)
       
  2291 			return appData;
       
  2292 		appData=appData->iNext;
       
  2293 		}
       
  2294 	return NULL;
       
  2295 	}
       
  2296 
       
  2297 EXPORT_C CApaAppData* CApaAppList::AppDataByFileName(const TDesC& aFullFileName) const
       
  2298 /** Gets a pointer to the application in the list whose application
       
  2299 file name matches the one specified
       
  2300 
       
  2301 @param aFullFileName a file name. 
       
  2302 @return A pointer to the application, if successful. Null, 
       
  2303 if no match is found or if KNullDesC was specified.
       
  2304 @internalTechnology
       
  2305 */
       
  2306 	{
       
  2307 	if (aFullFileName.Length()==0)
       
  2308 		{
       
  2309 		return NULL; // never match null UID as it represents an un-UIDed file
       
  2310 		}
       
  2311 	CApaAppData* appData=iAppData;
       
  2312 	while (appData)
       
  2313 		{
       
  2314 		if (appData->AppEntry().iFullName.CompareF(aFullFileName)==0)
       
  2315 			{
       
  2316 			return appData;
       
  2317 			}
       
  2318 		appData=appData->iNext;
       
  2319 		}
       
  2320 	return NULL;
       
  2321 	}
       
  2322 	
       
  2323 /**
       
  2324 Adds a registration file to the iForcedRegistrations array.
       
  2325 
       
  2326 @param aRegistrationFile The function takes ownership of the HBufC.
       
  2327 @internalComponent
       
  2328 */
       
  2329 EXPORT_C void CApaAppList::AddForcedRegistrationL(HBufC* aRegistrationFile)
       
  2330 	{
       
  2331 	TInt err = iForcedRegistrations.InsertInOrder(aRegistrationFile, TLinearOrder<HBufC>(CompareStrings));
       
  2332 	if (err == KErrAlreadyExists) // We silently ignore attempts to insert duplicates
       
  2333 		{
       
  2334 		delete aRegistrationFile;
       
  2335 		}
       
  2336 	else
       
  2337 		{
       
  2338 		User::LeaveIfError(err);
       
  2339 		}
       
  2340 	} //lint !e818 Suppress pointer parameter 'aRegistrationFile' could be declared as pointing to const
       
  2341 	
       
  2342 EXPORT_C void CApaAppList::ResetForcedRegistrations()
       
  2343 	{
       
  2344 	iForcedRegistrations.ResetAndDestroy();
       
  2345 	}
       
  2346 
       
  2347 EXPORT_C TUid CApaAppList::PreferredDataHandlerL(const TDataType& aDataType) const
       
  2348 /** Finds the preferred application to handle the specified data type.
       
  2349 
       
  2350 @param aDataType The data type of interest.
       
  2351 @return The third UID of the application in the list which has the 
       
  2352 highest priority for handling the specified data type. A null UID is 
       
  2353 returned if no application in the list can handle the specified data type. */
       
  2354 	{
       
  2355 	TInt dummy;
       
  2356 	return PreferredDataHandlerL(aDataType, NULL, dummy);
       
  2357 	}
       
  2358 	
       
  2359 EXPORT_C TUid CApaAppList::PreferredDataHandlerL(const TDataType& aDataType, const TUid* aServiceUid, TInt& aPriority) const
       
  2360 /** Finds the preferred application to handle the specified data type.
       
  2361 
       
  2362 @param aDataType The data type of interest.
       
  2363 @param aServiceUid The optional service UID.
       
  2364 @param aPriority The priority associated with the returned app.
       
  2365 @return The third UID of the application in the list which has the 
       
  2366 highest priority for handling a combination of the specified data type
       
  2367 and service. A null UID is returned if no application in the list can
       
  2368 handle the combination of specified data type and service.
       
  2369 @internalComponent
       
  2370 */
       
  2371 	{
       
  2372 	// If there is a service uid we first try to use the service specific list
       
  2373 	// of datatypes
       
  2374 	if (aServiceUid)
       
  2375 		{
       
  2376 		CApaAppData* appData=iAppData;
       
  2377 		aPriority=KDataTypePriorityNotSupported;
       
  2378 		TUid uid={0};
       
  2379 		while (appData)
       
  2380 			{
       
  2381 			TInt priority = appData->ImplementsServiceWithDataType(*aServiceUid, aDataType);
       
  2382 			if (priority > aPriority)
       
  2383 				{
       
  2384 				aPriority=priority;
       
  2385 				uid=appData->AppEntry().iUidType[2];
       
  2386 				}
       
  2387 			appData=appData->iNext;
       
  2388 			}
       
  2389 		if (aPriority != KDataTypePriorityNotSupported)
       
  2390 			{
       
  2391 			return uid;
       
  2392 			}
       
  2393 		}
       
  2394 	
       
  2395 	CApaAppData* appData=iAppData;
       
  2396 	aPriority=KDataTypePriorityNotSupported;
       
  2397 	TUid uid={0};
       
  2398 	while (appData)
       
  2399 		{
       
  2400 		TInt priority=appData->DataType(aDataType);
       
  2401 		if ((priority > aPriority) &&
       
  2402 			(!aServiceUid || (aServiceUid && appData->ImplementsService(*aServiceUid))))
       
  2403 			{
       
  2404 			aPriority=priority;
       
  2405 			uid=appData->AppEntry().iUidType[2];
       
  2406 			}
       
  2407 		appData=appData->iNext;
       
  2408 		}
       
  2409 	return uid;
       
  2410 	}
       
  2411   
       
  2412 void CApaAppList::DeleteAppData()
       
  2413 	{
       
  2414 	iValidFirstAppData = NULL;
       
  2415 	iFlags &= ~EFirstScanComplete;
       
  2416 	iFlags &= ~EAppListHasChanged;
       
  2417 	iFlags &= ~ELangChangePending;
       
  2418 	
       
  2419 	CApaAppData* next = NULL;
       
  2420 	for (CApaAppData* appData=iAppData; appData; appData = next)
       
  2421 		{
       
  2422 		next = appData->iNext;
       
  2423 		delete appData;
       
  2424 		}
       
  2425 	iAppData = NULL;
       
  2426 	}
       
  2427 
       
  2428 void CApaAppList::ScanComplete()
       
  2429 	{
       
  2430 	if (!(iFlags & EFirstScanComplete) && iObserver)
       
  2431 		iObserver->InitialListPopulationComplete();
       
  2432 	iValidFirstAppData = iAppData;
       
  2433 	iFlags|=EFirstScanComplete;
       
  2434 	iNNAInstallation = EFalse;
       
  2435 	}
       
  2436 
       
  2437 /**
       
  2438  *
       
  2439  * Tests whether the first scan for list of Apps has completed.
       
  2440  *
       
  2441  * @return   "TBool"
       
  2442  *            True, if the first scan for list of Apps has completed; false, otherwise.
       
  2443  * @internalComponent
       
  2444  */
       
  2445 EXPORT_C TBool CApaAppList::IsFirstScanComplete() const
       
  2446 	{
       
  2447 	return iFlags&EFirstScanComplete;
       
  2448 	}
       
  2449 
       
  2450 EXPORT_C TBool CApaAppList::AppScanInProgress() const
       
  2451 /** @internalComponent */
       
  2452 	{
       
  2453 	return (iAppIdler!=NULL) && iAppIdler->IsActive();
       
  2454 	}
       
  2455 
       
  2456 /**
       
  2457 @internalComponent
       
  2458 */
       
  2459 EXPORT_C CBufFlat* CApaAppList::ServiceArrayBufferL(TUid aAppUid) const
       
  2460 	{
       
  2461 	CApaAppData* app = FirstApp(KIgnoreScreenMode);
       
  2462 	while (app && app->AppEntry().iUidType[2] != aAppUid)
       
  2463 		{
       
  2464 		app = NextApp(app, KIgnoreScreenMode);
       
  2465 		}
       
  2466 
       
  2467 	if (app)
       
  2468 		{
       
  2469 		if (!app->RegistrationFileUsed())
       
  2470 			{
       
  2471 			User::Leave(KErrNotSupported);
       
  2472 			}
       
  2473 		if (app->iServiceArray)
       
  2474 			{
       
  2475 			CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
       
  2476 			CleanupStack::PushL(buf);
       
  2477 			RBufWriteStream writeStream(*buf);
       
  2478 			writeStream << *(app->iServiceArray);
       
  2479 			writeStream.CommitL();
       
  2480 			writeStream.Release();
       
  2481 			CleanupStack::Pop(buf);
       
  2482 			return buf;
       
  2483 			}
       
  2484 		}
       
  2485 	User::Leave(KErrNotFound);
       
  2486 	return NULL; // to keep compiler happy
       
  2487 	}
       
  2488 
       
  2489 /**
       
  2490 @internalComponent
       
  2491 */
       
  2492 EXPORT_C CBufFlat* CApaAppList::ServiceUidBufferL(TUid aAppUid) const
       
  2493 	{
       
  2494 	CApaAppData* app = FirstApp(KIgnoreScreenMode);
       
  2495 	while (app && app->AppEntry().iUidType[2] != aAppUid)
       
  2496 		{
       
  2497 		app = NextApp(app, KIgnoreScreenMode);
       
  2498 		}
       
  2499 
       
  2500 	if (app)
       
  2501 		{
       
  2502 		if (!app->RegistrationFileUsed())
       
  2503 			{
       
  2504 			User::Leave(KErrNotSupported);
       
  2505 			}
       
  2506 		if (app->iServiceArray)
       
  2507 			{
       
  2508 			CArrayFixFlat<TApaAppServiceInfo>& serviceArray = *(app->iServiceArray);
       
  2509 			CArrayFixFlat<TUid>* uidArray = new(ELeave) CArrayFixFlat<TUid>(4);
       
  2510 			CleanupStack::PushL(uidArray);
       
  2511 			for (TInt i = serviceArray.Count()-1; i >= 0; i--)
       
  2512 				{
       
  2513 				uidArray->AppendL(serviceArray[i].Uid());
       
  2514 				}
       
  2515 			CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
       
  2516 			CleanupStack::PushL(buf);
       
  2517 			RBufWriteStream writeStream(*buf);
       
  2518 			writeStream << *uidArray;
       
  2519 			writeStream.CommitL();
       
  2520 			writeStream.Release();
       
  2521 			CleanupStack::Pop(buf);
       
  2522 			CleanupStack::PopAndDestroy(uidArray);
       
  2523 			return buf;
       
  2524 			}
       
  2525 		}
       
  2526 	User::Leave(KErrNotFound);
       
  2527 	return NULL; // to keep compiler happy
       
  2528 	}
       
  2529 
       
  2530 /**
       
  2531 @internalComponent
       
  2532 */
       
  2533 EXPORT_C CBufFlat* CApaAppList::ServiceOpaqueDataBufferL(TUid aAppUid, TUid aServiceUid) const
       
  2534 	{
       
  2535 	CApaAppData* app = FirstApp(KIgnoreScreenMode);
       
  2536 	while (app && app->AppEntry().iUidType[2] != aAppUid)
       
  2537 		{
       
  2538 		app = NextApp(app, KIgnoreScreenMode);
       
  2539 		}
       
  2540 
       
  2541 	if (app)
       
  2542 		{
       
  2543 		if (!app->RegistrationFileUsed())
       
  2544 			{
       
  2545 			User::Leave(KErrNotSupported);
       
  2546 			}
       
  2547 		if (app->iServiceArray)
       
  2548 			{
       
  2549 			CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
       
  2550 			CArrayFixFlat<TApaAppServiceInfo>& serviceArray = *(app->iServiceArray);
       
  2551 			for (TInt i = serviceArray.Count()-1; i >= 0; i--)
       
  2552 				{
       
  2553 				const TApaAppServiceInfo& infoRef = serviceArray[i];
       
  2554 				if (infoRef.Uid() == aServiceUid)
       
  2555 					{
       
  2556 					if (!implArray)
       
  2557 						{
       
  2558 						implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
       
  2559 						CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
       
  2560 						}
       
  2561 					CArrayFixFlat<TDataTypeWithPriority>* dummy =
       
  2562 						new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
       
  2563 					CleanupStack::PushL(dummy);					
       
  2564 					TApaAppServiceInfo info(aServiceUid, dummy, infoRef.OpaqueData().AllocLC());
       
  2565 					implArray->AppendL(info);
       
  2566 					CleanupStack::Pop(CONST_CAST(TDesC8*,&info.OpaqueData()));
       
  2567 					CleanupStack::Pop(dummy);
       
  2568 					}
       
  2569 				}
       
  2570 			if (implArray)
       
  2571 				{
       
  2572 				CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
       
  2573 				CleanupStack::PushL(buf);
       
  2574 				RBufWriteStream writeStream(*buf);
       
  2575 				writeStream << *implArray;
       
  2576 				writeStream.CommitL();
       
  2577 				writeStream.Release();
       
  2578 				CleanupStack::Pop(buf);
       
  2579 				CleanupStack::PopAndDestroy(implArray);
       
  2580 				return buf;
       
  2581 				}
       
  2582 			}
       
  2583 		}
       
  2584 	User::Leave(KErrNotFound);
       
  2585 	return NULL; // to keep compiler happy
       
  2586 	}
       
  2587 
       
  2588 /**
       
  2589 @internalComponent
       
  2590 */
       
  2591 EXPORT_C CBufFlat* CApaAppList::ServiceImplArrayBufferL(TUid aServiceUid) const
       
  2592 	{
       
  2593 	CApaAppData* app = FirstApp(KIgnoreScreenMode);
       
  2594 	// build an array containing all implementations of the service identified by aServiceUid
       
  2595 	CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
       
  2596 	while (app)
       
  2597 		{
       
  2598 		if (app->iServiceArray)
       
  2599 			{
       
  2600 			for (TInt i = app->iServiceArray->Count()-1; i >= 0; i--)
       
  2601 				{
       
  2602 				const TApaAppServiceInfo& infoRef = (*app->iServiceArray)[i];
       
  2603 				if (infoRef.Uid() == aServiceUid)
       
  2604 					{
       
  2605 					if (!implArray)
       
  2606 						{
       
  2607 						implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
       
  2608 						CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
       
  2609 						}
       
  2610 					CArrayFixFlat<TDataTypeWithPriority>* datatypes = DataTypeArrayDeepCopyLC(infoRef.DataTypes());
       
  2611 					HBufC8* data = infoRef.OpaqueData().AllocLC();
       
  2612 					TApaAppServiceInfo info(app->AppEntry().iUidType[2], datatypes, data);
       
  2613 					implArray->AppendL(info);
       
  2614 					CleanupStack::Pop(data);
       
  2615 					CleanupStack::Pop(datatypes);
       
  2616 					}
       
  2617 				}
       
  2618 			}
       
  2619 		app = NextApp(app, KIgnoreScreenMode);
       
  2620 		}
       
  2621 
       
  2622 	if (implArray)
       
  2623 		{
       
  2624 		CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
       
  2625 		CleanupStack::PushL(buf);
       
  2626 		RBufWriteStream writeStream(*buf);
       
  2627 		writeStream << *(implArray);
       
  2628 		writeStream.CommitL();
       
  2629 		writeStream.Release();
       
  2630 		CleanupStack::Pop(buf);
       
  2631 		CleanupStack::PopAndDestroy(implArray);
       
  2632 		return buf;
       
  2633 		}
       
  2634 	User::Leave(KErrNotFound);
       
  2635 	return NULL; // to keep compiler happy
       
  2636 	}
       
  2637 
       
  2638 EXPORT_C CBufFlat* CApaAppList::ServiceImplArrayBufferL(TUid aServiceUid, const TDataType& aDataType) const
       
  2639 	{
       
  2640 	CApaAppData* app = FirstApp(KIgnoreScreenMode);
       
  2641 	// build an array containing all implementations of the service identified by aServiceUid
       
  2642 	CArrayFixFlat<TApaAppServiceInfo>* implArray = NULL;
       
  2643 	while (app)
       
  2644 		{
       
  2645 		if (app->iServiceArray)
       
  2646 			{
       
  2647 			for (TInt i = app->iServiceArray->Count()-1; i >= 0; i--)
       
  2648 				{
       
  2649 				const TApaAppServiceInfo& infoRef = (*app->iServiceArray)[i];
       
  2650 				if (infoRef.Uid() == aServiceUid)
       
  2651 					{
       
  2652 				 	if (KDataTypePriorityNotSupported != app->DataType(aDataType, infoRef.DataTypes()))
       
  2653 						{
       
  2654 						if (!implArray)
       
  2655 							{
       
  2656 							implArray = new(ELeave) CArrayFixFlat<TApaAppServiceInfo>(4);
       
  2657 							CleanupStack::PushL(TCleanupItem(CleanupServiceArray, implArray));
       
  2658 							}
       
  2659 						CArrayFixFlat<TDataTypeWithPriority>* datatypes = DataTypeArrayDeepCopyLC(infoRef.DataTypes());
       
  2660 						HBufC8* data = infoRef.OpaqueData().AllocLC();
       
  2661 						TApaAppServiceInfo info(app->AppEntry().iUidType[2], datatypes, data);
       
  2662 						implArray->AppendL(info);
       
  2663 						CleanupStack::Pop(data);
       
  2664 						CleanupStack::Pop(datatypes);
       
  2665 						}
       
  2666 					}
       
  2667 				}
       
  2668 			}
       
  2669 		app = NextApp(app, KIgnoreScreenMode);
       
  2670 		}
       
  2671 
       
  2672 	if (implArray)
       
  2673 		{
       
  2674 		CBufFlat* const buf = CBufFlat::NewL(KBufferExpansionGranularity);
       
  2675 		CleanupStack::PushL(buf);
       
  2676 		RBufWriteStream writeStream(*buf);
       
  2677 		writeStream << *(implArray);
       
  2678 		writeStream.CommitL();
       
  2679 		writeStream.Release();
       
  2680 		CleanupStack::Pop(buf);
       
  2681 		CleanupStack::PopAndDestroy(implArray);
       
  2682 		return buf;
       
  2683 		}
       
  2684 	User::Leave(KErrNotFound);
       
  2685 	return NULL; // to keep compiler happy
       
  2686 	}
       
  2687 	
       
  2688 CArrayFixFlat<TDataTypeWithPriority>* CApaAppList::DataTypeArrayDeepCopyLC(const CArrayFixFlat<TDataTypeWithPriority>& aOriginal) const
       
  2689 	{
       
  2690 	CArrayFixFlat<TDataTypeWithPriority>* result = new(ELeave) CArrayFixFlat<TDataTypeWithPriority>(1);
       
  2691 	CleanupStack::PushL(result);
       
  2692 	TInt ii = 0;
       
  2693 	TInt end = aOriginal.Count();
       
  2694 	while (ii < end)
       
  2695 		{
       
  2696 		result->AppendL(aOriginal[ii]);
       
  2697 		ii++;
       
  2698 		}
       
  2699 	return result;
       
  2700 	}
       
  2701 	
       
  2702 EXPORT_C TInt CApaAppList::CompareStrings(const HBufC& aFirst, const HBufC& aSecond)
       
  2703 	{
       
  2704 	return aFirst.CompareF(aSecond);
       
  2705 	}
       
  2706 
       
  2707 EXPORT_C CApaAppList* CApaAppList::Self()
       
  2708 	{ // static
       
  2709 	return STATIC_CAST(CApaAppList*,Dll::Tls());
       
  2710 	}
       
  2711 	
       
  2712 /*EXPORT_C*/ RFs& CApaAppList::ShareProtectedFileServer()
       
  2713 	{
       
  2714 	return iFsShareProtected; //lint !e1536 Exposing low access member - need to consider a redesign or design clarification here(iFsShareProtected should be owned be the one that needs it) but postpone for now as that may require large changes
       
  2715 	}
       
  2716 	
       
  2717 CApaAppIconArray* CApaAppList::LoadDefaultIconsL() const
       
  2718 	{
       
  2719 	CApaIconLoader* iconLoader = CApaIconLoader::NewLC(iFs);
       
  2720 	CApaAppIconArray* icons = CApaAppIconArray::NewRealDefaultIconsLC(KNumberOfIconsInDefaultMbm,*iDefaultAppIconMbmFileName, *iconLoader);
       
  2721 	const TBool badMbmEntryInfo = !icons->LoadIconsL();
       
  2722 	if(badMbmEntryInfo)
       
  2723 		{
       
  2724 		CleanupStack::PopAndDestroy(2,iconLoader);
       
  2725 		return CApaAppIconArray::NewL();
       
  2726 		}
       
  2727 	else
       
  2728 		{
       
  2729 		CleanupStack::Pop(icons);
       
  2730 		CleanupStack::PopAndDestroy(iconLoader);
       
  2731 		}
       
  2732 	return icons;
       
  2733 	}
       
  2734 
       
  2735 void CApaAppList::AcquireDefaultIconArrayL() const
       
  2736 	{
       
  2737 	ASSERT(iDefaultIconUsageCount >= 0);
       
  2738 	if (iDefaultIconUsageCount == 0)
       
  2739 		{
       
  2740 		iDefaultIconArray = LoadDefaultIconsL();
       
  2741 		}
       
  2742 	++iDefaultIconUsageCount;
       
  2743 	}
       
  2744 
       
  2745 // Should NEVER be called by an object that does not call AcquireDefaultIconArrayL and
       
  2746 // ReleaseDefaultIconArray at the beginning and end of its lifetime respectively
       
  2747 const CApaAppIconArray& CApaAppList::DefaultIconArray() const
       
  2748 	{
       
  2749 	__ASSERT_ALWAYS(iDefaultIconArray, Panic(EPanicNullPointer));
       
  2750 	return *iDefaultIconArray;
       
  2751 	}
       
  2752 
       
  2753 void CApaAppList::ReleaseDefaultIconArray() const
       
  2754 	{
       
  2755 	ASSERT(iDefaultIconUsageCount > 0);
       
  2756 	if(0 == --iDefaultIconUsageCount)
       
  2757 		{
       
  2758 		delete iDefaultIconArray;
       
  2759 		iDefaultIconArray = NULL;		
       
  2760 		}
       
  2761 	}
       
  2762 	
       
  2763 // DEF077478 - Required to update the default icons that the app list holds.
       
  2764 void CApaAppList::UpdateDefaultIconsL()
       
  2765 	{
       
  2766 	CApaAppIconArray* iconArray = LoadDefaultIconsL();
       
  2767 	if (iconArray)
       
  2768 		{
       
  2769 		delete iDefaultIconArray;
       
  2770 		iDefaultIconArray = iconArray;
       
  2771 		}
       
  2772 	}
       
  2773 
       
  2774 void CApaAppList::DeleteAppListStorer()
       
  2775 	{
       
  2776 	delete iAppListStorer;
       
  2777 	iAppListStorer = NULL;
       
  2778 	}
       
  2779 
       
  2780 void CApaAppList::DeleteAppIconLoader()
       
  2781 	{
       
  2782 	delete iAppIconLoader;
       
  2783 	iAppIconLoader = NULL;
       
  2784 	}
       
  2785 
       
  2786 void CApaAppList::InitiateStoringOfAppList()
       
  2787 	{
       
  2788 	ScanComplete();	
       
  2789 	NotifyObserver();
       
  2790 	iFlags &= ~ENotifyUpdateOnFirstScanComplete;
       
  2791 	// now that the scan is finished, iDefaultAppIconMbmFileName is deleted
       
  2792 	delete iDefaultAppIconMbmFileName;
       
  2793 	iDefaultAppIconMbmFileName=NULL;
       
  2794 	// if applist has not changed and AppsList_Backup.bin file exists then it is replaced back to AppsList.bin
       
  2795 	if (!(iFlags & EAppListHasChanged) && BaflUtils::FileExists(iFs, iAppsListCacheBackUpFileName))
       
  2796 		{
       
  2797 		TInt replaceError = iFs.Replace(iAppsListCacheBackUpFileName, iAppsListCacheFileName);
       
  2798 		if (replaceError == KErrNone)
       
  2799 			{
       
  2800 			return;
       
  2801 			}
       
  2802 		}
       
  2803     iFlags &= ~EAppListHasChanged;
       
  2804 	iFs.Delete(iAppsListCacheBackUpFileName);
       
  2805 	TInt err = iFs.MkDir(iAppsListCachePath);
       
  2806 	if (err == KErrNone || err == KErrAlreadyExists)
       
  2807 		{
       
  2808 		TRAP(err, StoreL());
       
  2809 		if (err)
       
  2810 			{
       
  2811 			DeleteAppListStorer();
       
  2812 			}
       
  2813 		}
       
  2814 	}
       
  2815 //
       
  2816 // Class CApaAppListStorer
       
  2817 //
       
  2818 
       
  2819 CApaAppList::CApaAppListStorer::CApaAppListStorer(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList) : CActive(EPriorityIdle), iCurrentAppData(aFirstAppData), iFs(aFs), iAppList(aAppList)
       
  2820 	{
       
  2821 	}
       
  2822 
       
  2823 CApaAppList::CApaAppListStorer::~CApaAppListStorer()
       
  2824 	{
       
  2825 	Cancel();
       
  2826 	iWriteStream.Close();
       
  2827 	iFs.Delete(iTempFilename);
       
  2828 	iTimer.Close();
       
  2829 	iCurrentAppData = NULL;
       
  2830 	}
       
  2831 
       
  2832 CApaAppList::CApaAppListStorer* CApaAppList::CApaAppListStorer::NewL(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList)
       
  2833 	{
       
  2834 	CApaAppListStorer* self = new(ELeave) CApaAppListStorer(aFirstAppData, aFs, aAppList);
       
  2835 	CleanupStack::PushL(self);
       
  2836 	self->ConstructL();
       
  2837 	CleanupStack::Pop(self);
       
  2838 	return self;
       
  2839 	}
       
  2840 
       
  2841 void CApaAppList::CApaAppListStorer::ConstructL()
       
  2842 	{
       
  2843 	User::LeaveIfError(iTimer.CreateLocal());
       
  2844 	CActiveScheduler::Add(this);
       
  2845 	}
       
  2846 
       
  2847 void CApaAppList::CApaAppListStorer::StartL(const TTimeIntervalMicroSeconds32& aDelay)
       
  2848 	{
       
  2849 	User::LeaveIfError(iWriteStream.Temp(iFs, iAppList.iAppsListCachePath, iTempFilename, EFileWrite));
       
  2850 	iWriteStream.WriteInt32L(User::Language());
       
  2851 
       
  2852 #if defined (SYMBIAN_BAFL_SYSUTIL)
       
  2853 	//Write a cache of the ROM version to a separate stream
       
  2854 	//Build the filename for the cache file
       
  2855 	TInt maxSizeofFileName = iAppList.iAppsListCachePath.Length() + KROMVersionStringCacheFileName().Length();
       
  2856 	RBuf romVersionCacheFileName;
       
  2857 	romVersionCacheFileName.CreateL(maxSizeofFileName);
       
  2858 	romVersionCacheFileName.CleanupClosePushL();
       
  2859 	romVersionCacheFileName.Append(iAppList.iAppsListCachePath);
       
  2860 	romVersionCacheFileName.Append(KROMVersionStringCacheFileName());
       
  2861 	
       
  2862 	RFileWriteStream romVerStream;
       
  2863 	User::LeaveIfError(romVerStream.Replace(iFs,romVersionCacheFileName,EFileWrite));
       
  2864 	CleanupClosePushL(romVerStream);
       
  2865 	
       
  2866 	// Write the file version that apparc can handle.
       
  2867 	romVerStream.WriteInt8L(KROMVersionCacheFileMajorVersion);
       
  2868 	romVerStream.WriteInt8L(KROMVersionCacheFileMinorVersion);
       
  2869 	romVerStream.WriteInt16L(KROMVersionCacheFileBuildVersion);
       
  2870 		
       
  2871 	TBuf<KInfoBufLength> version;
       
  2872 	SysUtil::GetSWVersion(version);
       
  2873 	
       
  2874 	// Write the software version even if SysUtil returns err since all conditions are taken care during restore.
       
  2875 	romVerStream.WriteUint32L(version.Length());
       
  2876 	romVerStream.WriteL(version, version.Length());
       
  2877 	CleanupStack::PopAndDestroy(2); //romVerStream, romVersionCacheFileName
       
  2878 #endif //(SYMBIAN_BAFL_SYSUTIL)
       
  2879 	
       
  2880 	iTimer.After(iStatus, aDelay);
       
  2881 	SetActive();
       
  2882 	}
       
  2883 
       
  2884 void CApaAppList::CApaAppListStorer::RunL()
       
  2885 	{ 
       
  2886 	// iStatus could be KErrNone or negative when timer completes, irrespective of its status we need to re-queue the request.
       
  2887 	if (iCurrentAppData)
       
  2888 		{
       
  2889 		StoreEntryL(iWriteStream, *iCurrentAppData);
       
  2890 		iCurrentAppData = iCurrentAppData->Next();
       
  2891 		SetActive();
       
  2892 		TRequestStatus* status = &iStatus;
       
  2893 		User::RequestComplete(status, KErrNone);
       
  2894 		}
       
  2895 	else
       
  2896 		{
       
  2897 		iWriteStream.CommitL();
       
  2898 		iWriteStream.Close();
       
  2899 
       
  2900 		TInt err = iFs.Replace(iTempFilename, iAppList.iAppsListCacheFileName);
       
  2901 		if (err != KErrNone)
       
  2902 			{
       
  2903 			iFs.Delete(iTempFilename);
       
  2904 			}
       
  2905 		iAppList.DeleteAppListStorer();
       
  2906 		}
       
  2907 	}
       
  2908 
       
  2909 void CApaAppList::CApaAppListStorer::StoreEntryL(RWriteStream& aWriteStream, const CApaAppData& aApp)
       
  2910 	{
       
  2911 	aWriteStream << aApp;
       
  2912 	}
       
  2913 
       
  2914 void CApaAppList::CApaAppListStorer::DoCancel()
       
  2915 	{
       
  2916 	iTimer.Cancel();
       
  2917 	}
       
  2918 
       
  2919 TInt CApaAppList::CApaAppListStorer::RunError(TInt /*aError*/)
       
  2920 	{
       
  2921 	iAppList.DeleteAppListStorer();
       
  2922 	return KErrNone;
       
  2923 	}
       
  2924 
       
  2925 //
       
  2926 // Class CApaIdleIconLoader
       
  2927 //
       
  2928 
       
  2929 CApaAppList::CApaIdleIconLoader::CApaIdleIconLoader(CApaAppData* aFirstAppData, RFs& aFs, CApaAppList& aAppList) : CActive(EPriorityLow), iCurrentAppData(aFirstAppData), iFs(aFs), iAppList(aAppList)
       
  2930 	{ // Priority is less than KAppListServerPriority, to maintain server responsiveness.
       
  2931 	CActiveScheduler::Add(this);
       
  2932 	}
       
  2933 
       
  2934 CApaAppList::CApaIdleIconLoader::~CApaIdleIconLoader()
       
  2935 	{
       
  2936 	Cancel();
       
  2937 	iCurrentAppData = NULL;
       
  2938 	}
       
  2939 
       
  2940 void CApaAppList::CApaIdleIconLoader::Start()
       
  2941 	{
       
  2942 	SetActive();
       
  2943 	TRequestStatus* status = &iStatus;
       
  2944 	User::RequestComplete(status, KErrNone);
       
  2945 	}
       
  2946 
       
  2947 void CApaAppList::CApaIdleIconLoader::RunL()
       
  2948 /** if the icons are not already loaded on demand then it would be loaded here. */
       
  2949 	{
       
  2950 	while (iCurrentAppData && !iCurrentAppData->MbmIconsRequireLoading())
       
  2951 		{
       
  2952 		iCurrentAppData = iCurrentAppData->Next();
       
  2953 		}
       
  2954 
       
  2955 	if(iCurrentAppData)
       
  2956 		{
       
  2957 		Start();
       
  2958 		CApaAppData* const appData = iCurrentAppData;
       
  2959 		iCurrentAppData = iCurrentAppData->Next();
       
  2960 		appData->LoadIconsL();
       
  2961 		}
       
  2962 	else
       
  2963 		{
       
  2964 		iAppList.InitiateStoringOfAppList();
       
  2965 		iAppList.DeleteAppIconLoader();
       
  2966 		}
       
  2967 	}
       
  2968 
       
  2969 void CApaAppList::CApaIdleIconLoader::DoCancel()
       
  2970 	{
       
  2971 	}
       
  2972 
       
  2973 TInt CApaAppList::CApaIdleIconLoader::RunError(TInt /*aError*/)
       
  2974 	{
       
  2975 	return KErrNone;
       
  2976 	}
       
  2977 
       
  2978 // ApaUtils
       
  2979 
       
  2980 EXPORT_C TBool ApaUtils::HandleAsRegistrationFile(const TUidType& aUidType)
       
  2981 	{ // static
       
  2982 	return (aUidType[1].iUid==KUidAppRegistrationFile.iUid ||
       
  2983 		   aUidType[0].iUid==KUidPrefixedNonNativeRegistrationResourceFile);
       
  2984 	}
       
  2985 	
       
  2986 
       
  2987 //
       
  2988 // Class CApaLangChangeMonitor
       
  2989 //
       
  2990 
       
  2991 CApaAppList::CApaLangChangeMonitor::~CApaLangChangeMonitor()
       
  2992 	{	
       
  2993 	Cancel();
       
  2994 	iLangNotifier.Close();
       
  2995 	}
       
  2996 
       
  2997 CApaAppList::CApaLangChangeMonitor* CApaAppList::CApaLangChangeMonitor::NewL(CApaAppList& aAppList)
       
  2998 	{ // static	
       
  2999 	CApaLangChangeMonitor* self=new(ELeave) CApaLangChangeMonitor(aAppList);
       
  3000 	self->ConstructL();
       
  3001 	return self;
       
  3002 	}
       
  3003 
       
  3004 CApaAppList::CApaLangChangeMonitor::CApaLangChangeMonitor(CApaAppList& aAppList)
       
  3005 	: CActive(EPriorityNormal),
       
  3006 	iAppList(aAppList)
       
  3007 	{	
       
  3008 	iPrevLanguage = User::Language();
       
  3009 	CActiveScheduler::Add(this);
       
  3010 	}
       
  3011 
       
  3012 void CApaAppList::CApaLangChangeMonitor::ConstructL()
       
  3013 	{
       
  3014 	User::LeaveIfError(iLangNotifier.Create());
       
  3015 	Start();
       
  3016 	}
       
  3017  
       
  3018 void CApaAppList::CApaLangChangeMonitor::Start()
       
  3019 	{
       
  3020 	iLangNotifier.Logon(iStatus);
       
  3021 	SetActive();
       
  3022 	}
       
  3023 
       
  3024 void CApaAppList::CApaLangChangeMonitor::DoCancel()
       
  3025 	{
       
  3026 	iLangNotifier.LogonCancel();
       
  3027 	}
       
  3028 
       
  3029 void CApaAppList::CApaLangChangeMonitor::RunL()
       
  3030 	{
       
  3031 	// Logon to get further events before handling current request.
       
  3032 	TRequestStatus status = iStatus;
       
  3033 	Start();
       
  3034 	
       
  3035 	// if it is a language change event, start a rescan on app-list.
       
  3036 	if (status.Int() == EChangesLocale && iPrevLanguage != User::Language())
       
  3037 		{		
       
  3038 		iPrevLanguage = User::Language();
       
  3039 		iAppList.iFlags |= CApaAppList::ELangChangePending;
       
  3040 		iAppList.StartIdleUpdateL(iAppList.iObserver);
       
  3041 		}
       
  3042 	}
       
  3043 
       
  3044 TInt CApaAppList::CApaLangChangeMonitor::RunError(TInt /*aError*/)
       
  3045 	{
       
  3046 	// Reset ELangChangePending flag if RunL leaves.
       
  3047 	iAppList.iFlags &= ~CApaAppList::ELangChangePending;
       
  3048 	// Reset iPrevLanguage to ELangNone if RunL leaves.
       
  3049 	iPrevLanguage = ELangNone;
       
  3050 	return KErrNone;
       
  3051 	}
       
  3052 
       
  3053 void CApaAppList::GetAppsListCachePathL()
       
  3054 	{
       
  3055 	_LIT(KAppsListCacheFileName, ":\\private\\10003a3f\\AppsListCache\\AppsList.bin");
       
  3056 	_LIT(KAppsListCacheBackUpFileName, ":\\private\\10003a3f\\AppsListCache\\AppsList_Backup.bin");
       
  3057 	_LIT(KAppsListCachePath, ":\\private\\10003a3f\\AppsListCache\\");
       
  3058 	TChar sysDrive = RFs::GetSystemDriveChar();
       
  3059 	TInt maxSizeofFileName = KAppsListCacheFileName().Length() + 1;
       
  3060 	iAppsListCacheFileName.CreateL(maxSizeofFileName);
       
  3061 	iAppsListCacheFileName.Append(sysDrive);
       
  3062 	iAppsListCacheFileName.Append(KAppsListCacheFileName());
       
  3063 	maxSizeofFileName = KAppsListCacheBackUpFileName().Length() + 1;
       
  3064 	iAppsListCacheBackUpFileName.CreateL(maxSizeofFileName);
       
  3065 	iAppsListCacheBackUpFileName.Append(sysDrive);
       
  3066 	iAppsListCacheBackUpFileName.Append(KAppsListCacheBackUpFileName());
       
  3067 	maxSizeofFileName = KAppsListCachePath().Length() + 1;
       
  3068 	iAppsListCachePath.CreateL(maxSizeofFileName);
       
  3069 	iAppsListCachePath.Append(sysDrive);
       
  3070 	iAppsListCachePath.Append(KAppsListCachePath());
       
  3071 	}
       
  3072 
       
  3073 
       
  3074 // The function transfers ownership of the pointer owned by a CApaAppList to the caller
       
  3075 // to avoid copying the array.
       
  3076 
       
  3077 EXPORT_C CArrayFixFlat<TUid>* CApaAppList::UninstalledAppArray()
       
  3078     {
       
  3079     CArrayFixFlat<TUid>* uninstalledApps=iUninstalledApps;
       
  3080     iUninstalledApps=NULL;
       
  3081     return uninstalledApps;
       
  3082     }