localisation/apparchitecture/apserv/APSSERV.CPP
branchSymbian2
changeset 1 8758140453c0
child 6 c108117318cb
equal deleted inserted replaced
0:e8c1ea2c6496 1:8758140453c0
       
     1 // Copyright (c) 2005-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 
       
    17 #include <e32svr.h>
       
    18 #include <u32hal.h>
       
    19 #include <bautils.h>
       
    20 #include "APSSERV.H"
       
    21 #include "APFREC.H"
       
    22 #include "APSSES.H"
       
    23 #include "APSSTD.H"
       
    24 #include "../apfile/aprfndr.h"
       
    25 #include "APGAPLST.H"
       
    26 #include "APSSCAN.H"
       
    27 #include "APSSTD.H"
       
    28 #include "APASVST.H"
       
    29 #include "datastor.h"
       
    30 #include "APSRECCACHE.h"
       
    31 #include "apsnnapps.h"
       
    32 #include "../apfile/apuninstallmonitor.h"
       
    33 #include "../apgrfx/apprivate.h"
       
    34 #include "apsiconcaptionoverride.h"
       
    35 
       
    36 _LIT(KAppArcServerSemaphore,"AppArcServerSemaphore");
       
    37 _LIT(KAppArcServerThread,"AppArcServerThread");
       
    38 _LIT(KAppRegistrationFileImportLocation, "?:\\private\\10003a3f\\import\\apps\\");
       
    39 _LIT(KAppResourceAppsLocation, "?:\\resource\\apps\\");
       
    40 _LIT(KNonNativeApplicationTypeRegistry, ":\\private\\10003a3f\\NonNativeTypes.dat");
       
    41 
       
    42 /*
       
    43  * patchable const data values defined in ApsConstData.cpp
       
    44  */
       
    45 
       
    46 IMPORT_C extern const TInt KApaLoadDataRecognizersOnDemand;
       
    47 IMPORT_C extern const TInt KApaUnloadRecognizersTimeout;
       
    48 IMPORT_C extern const TInt KApaDrivesToMonitor;
       
    49 IMPORT_C extern const TInt KApaLoadMbmIconsOnDemand;
       
    50 
       
    51 const TUint8 KPolicyElementWriteDeviceData = 0;
       
    52 
       
    53 //To monitor all drives.
       
    54 const TInt KApaMonitorAllDrives = 0x3FFFFFF;
       
    55 
       
    56 const TUint KRangeCount = 3; 
       
    57 
       
    58 const TInt KAppListServRanges[KRangeCount] = 
       
    59 	{	
       
    60 	EFirstUnrestrictedOpcodeInAppListServ,
       
    61 	EFirstOpcodeNeedingWriteDeviceDataInAppListServ, 
       
    62 	EAppListFirstUnusedOpcode,
       
    63 	};
       
    64 
       
    65 const TUint8 KElementsIndex[KRangeCount] =
       
    66 	{
       
    67 	CPolicyServer::EAlwaysPass,			//Always passing no capability required [0-99]
       
    68 	KPolicyElementWriteDeviceData,		//Requires WriteDeviceData				 [100-(EAppListFirstUnusedOpcode-1)]
       
    69 	CPolicyServer::ENotSupported, 		//Not Supported		[EAppListFirstUnusedOpcode-End]
       
    70 	};
       
    71 
       
    72 const CPolicyServer::TPolicyElement KPolicyElements[] = 
       
    73 	{ 
       
    74 	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient} 
       
    75 	};
       
    76 
       
    77 const CPolicyServer::TPolicy KApaServPolicy =
       
    78 	{
       
    79 	CPolicyServer::EAlwaysPass, 
       
    80 	KRangeCount,
       
    81 	KAppListServRanges,
       
    82 	KElementsIndex, 	
       
    83 	KPolicyElements 	
       
    84 	};
       
    85  	
       
    86 
       
    87 
       
    88 //////////////////////////////
       
    89 // CApaAppListServer
       
    90 //////////////////////////////
       
    91 
       
    92 const TInt KAppListServerPriority=CActive::EPriorityStandard;
       
    93 /**
       
    94 NameApaServStartSemaphore
       
    95 
       
    96 @internalTechnology
       
    97 */
       
    98 EXPORT_C TPtrC NameApaServStartSemaphore()
       
    99 	{
       
   100 	TPtrC nameApaServStartSemaphore(KAppArcServerSemaphore);
       
   101 	return nameApaServStartSemaphore;
       
   102 	}
       
   103 
       
   104 /**
       
   105 NameApaServServerThread
       
   106 
       
   107 @internalTechnology 
       
   108 */
       
   109 EXPORT_C TPtrC NameApaServServerThread()
       
   110 	{
       
   111 	TPtrC nameApaServServerThread(KAppArcServerThread);
       
   112 	return nameApaServServerThread;
       
   113 	}
       
   114 
       
   115 EXPORT_C CApaAppListServer* CApaAppListServer::Self()
       
   116 	{ // static
       
   117 	return static_cast<CApaAppListServer*>(Dll::Tls());
       
   118 	}
       
   119 
       
   120 EXPORT_C CApaAppListServer* CApaAppListServer::NewL(MApaAppStarter* aAppStarter)
       
   121 // Create a new CApaAppListServer which owns it's own resources
       
   122 	{
       
   123 	CApaAppListServer* self=new(ELeave) CApaAppListServer(KAppListServerPriority);
       
   124 	CleanupStack::PushL(self);
       
   125 	self->ConstructL(aAppStarter);
       
   126 	CleanupStack::Pop();
       
   127 	return self;
       
   128 	}
       
   129 
       
   130 CApaAppListServer::CApaAppListServer(TInt aPriority)
       
   131 	: CPolicyServer(aPriority,KApaServPolicy),
       
   132 	iAppList(0),
       
   133 	iTypeStoreModified(0),
       
   134 	iLoadRecognizersOnDemand(KApaLoadDataRecognizersOnDemand),
       
   135 	iLoadMbmIconsOnDemand(KApaLoadMbmIconsOnDemand)
       
   136 	{
       
   137 	
       
   138 	#ifdef __WINS__
       
   139 	// KApaLoadDataRecognizersOnDemand and KApaloadIconsOnDemand are Rom patchable constants,
       
   140 	// so need an emulator equivalent
       
   141 	// if WINS then read value from epoc.ini
       
   142 	// requires licencees to set property in epoc.ini
       
   143 
       
   144 	TInt halValue = 0;
       
   145 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, (TAny*)"patchdata_apserv_dll_KApaLoadDataRecognizersOnDemand", &halValue) == KErrNone)
       
   146 		{
       
   147 		iLoadRecognizersOnDemand = halValue;
       
   148 		}
       
   149 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, (TAny*)"patchdata_apserv_dll_KApaLoadMbmIconsOnDemand", &halValue) == KErrNone)
       
   150 		{
       
   151 		iLoadMbmIconsOnDemand = halValue;
       
   152 		}
       
   153 	#endif
       
   154 
       
   155 	__DECLARE_NAME(_S("CApaAppListServer"));
       
   156 	}
       
   157 
       
   158 void CApaAppListServer::ConstructL(MApaAppStarter* aAppStarter)
       
   159 	{
       
   160 	StartL(KAppListServerName);
       
   161 	User::LeaveIfError(Dll::SetTls(this));
       
   162 	User::LeaveIfError(iFs.Connect());
       
   163 	
       
   164 	iScanningFileRecognizer=CApaScanningFileRecognizer::NewL(iFs,aAppStarter);
       
   165 		
       
   166 	// Get the idle timeout delay from the commandline if specified. The default is 50000ms
       
   167 	const TInt cmdLineLen = User::CommandLineLength();
       
   168 	TInt idlePeriodicDelay=50000; //default value
       
   169 	if(cmdLineLen)
       
   170 		{
       
   171 		_LIT(KIdleTimeout,"IDLE_TIMEOUT_PERIODIC_DELAY_");
       
   172 		
       
   173 		// Extract the command line into a buffer
       
   174 		HBufC* cmdLine = HBufC::NewLC(cmdLineLen);
       
   175 		TPtr cmdLinePtr = cmdLine->Des();
       
   176 		User::CommandLine(cmdLinePtr);
       
   177 		cmdLinePtr.UpperCase();
       
   178 				
       
   179 		// Check if there is an idle timeout value given
       
   180 		TInt idleTimeOutArgPos = cmdLinePtr.Find(KIdleTimeout);
       
   181 		if(KErrNotFound != idleTimeOutArgPos)
       
   182 			{
       
   183 			// Extract the value out of the command line argument
       
   184 			const TInt idleTimeOutValuePos = idleTimeOutArgPos + KIdleTimeout().Length();
       
   185 			TInt i = idleTimeOutValuePos;
       
   186 			while (i < cmdLineLen)
       
   187 				{
       
   188 				TChar c(cmdLinePtr[i]);
       
   189 				if (!c.IsDigit())
       
   190 					{
       
   191 					break;
       
   192 					}
       
   193 				i++;
       
   194 				}
       
   195 			TLex idleTimeOutParser(cmdLinePtr.Mid(idleTimeOutValuePos, (i-idleTimeOutValuePos)));
       
   196 		  	User::LeaveIfError(idleTimeOutParser.Val(idlePeriodicDelay));	  					  	
       
   197 			}
       
   198 							
       
   199 		// Check if the recognition cache should be used or not. By default the cache is used
       
   200 		iRecognitionCache = 0;
       
   201 		_LIT(KWithoutRecognitionCache,"WITHOUT_RECOGNITION_CACHE");
       
   202 		if(KErrNotFound == cmdLinePtr.Find(KWithoutRecognitionCache))
       
   203 			{
       
   204 			iRecognitionCache = new (ELeave) CApsRecognitionCache(iFs);
       
   205 			}
       
   206 			
       
   207 		_LIT(KTextShellMode,"TEXT_SHELL_MODE");
       
   208 		if (KErrNotFound == cmdLinePtr.Find(KTextShellMode))
       
   209 			{
       
   210 			// We are NOT running in text shell mode so connect to wserv session
       
   211 			User::LeaveIfError(iWsSession.Connect());
       
   212 			iRuleBasedPlugIns = CApaScanningRuleBasedPlugIns::NewL();
       
   213 			}
       
   214 
       
   215 		CleanupStack::PopAndDestroy(cmdLine);		
       
   216 		}
       
   217 	else
       
   218 		{
       
   219 		// no arguments so cache is used
       
   220 		iRecognitionCache = new (ELeave) CApsRecognitionCache(iFs);
       
   221 		// and rule based plugins are enabled
       
   222 		User::LeaveIfError(iWsSession.Connect());
       
   223 		iRuleBasedPlugIns = CApaScanningRuleBasedPlugIns::NewL();
       
   224 		}
       
   225 	
       
   226 	CApaAppRegFinder* appRegFinder=CApaAppRegFinder::NewL(iFs); //non-standard transfer of ownership, no need for CleanupStack
       
   227 	iAppList=CApaAppList::NewL(iFs, appRegFinder, iLoadMbmIconsOnDemand, idlePeriodicDelay); // takes ownership of scanner
       
   228 
       
   229 	// If the phone rebooted halfway through processing updates, there will be a log file left
       
   230 	// look for one and recover if neccessary
       
   231 	CApsNonNativeApplicationsManager::RecoverFromUpdateLogL(iFs);
       
   232 
       
   233 	iDataRecognizer=CApaScanningDataRecognizer::NewL(iFs, !iLoadRecognizersOnDemand);
       
   234 
       
   235 	ConstructPathsToMonitorL();	
       
   236 
       
   237 	if ( iAppFsMonitor )
       
   238 		{
       
   239 		iAppFsMonitor->Start(ENotifyFile);
       
   240 		iAppFsMonitor->SetBlocked(ETrue);			
       
   241 		}
       
   242 	TRAP_IGNORE(iAppList->InitListL(this));
       
   243 	
       
   244 #ifdef USING_ECOM_RECOGS
       
   245 	iRecEcomMonitor=CApaEComMonitor::NewL(TCallBack(&PlugInNotifyCallBack,this));
       
   246 	iRecEcomMonitor->Start();
       
   247 #endif
       
   248 	iTypeStoreManager=CTypeStoreManager::NewL(iFs);
       
   249 	TRAPD(err,iTypeStoreManager->RestoreL());
       
   250 	if(err==KErrNone)
       
   251 		{
       
   252 		User::LeaveIfError(iFs.Modified(iTypeStoreManager->IniFileName(),iTypeStoreModified));
       
   253 		}
       
   254 	iTypeStoreMonitor=CApaFsMonitor::NewL(iFs,iTypeStoreManager->IniFileName(),TCallBack(&TypeStoreNotifyCallback,this));
       
   255 	iTypeStoreMonitor->Start(ENotifyWrite); // this presumably needs to be ENotifyWrite rather than ENotifyFile (the latter being used or the other CApaFsMonitor objects) because CTypeStoreManager internally uses CDictionaryFileStore::OpenL, which presumably itself uses RFile::Open, which isn't covered by ENotifyFile according to its documentation
       
   256 	TypeStoreNotifyCallback(this);
       
   257 	iBaBackupSessionWrapper=CBaBackupSessionWrapper::NewL();
       
   258 	iBaBackupSessionWrapper->RegisterBackupOperationObserverL(*((MBackupOperationObserver*)this));
       
   259 
       
   260 	TChar sysDrive = RFs::GetSystemDriveChar();
       
   261 	TInt maxSizeofFileName = KNonNativeApplicationTypeRegistry().Length() + 1;
       
   262 	iNonNativeApplicationTypeRegistry.CreateL(maxSizeofFileName);
       
   263 	iNonNativeApplicationTypeRegistry.Append(sysDrive);
       
   264 	iNonNativeApplicationTypeRegistry.Append(KNonNativeApplicationTypeRegistry());
       
   265 
       
   266 	TRAP_IGNORE(InternalizeNonNativeApplicationTypeArrayL());	// We don't want a corrupt file to prevent from starting
       
   267 	if(iLoadRecognizersOnDemand)
       
   268 		{
       
   269 		iRecognizerUnloadTimer=CPeriodic::NewL(EPriorityNormal);
       
   270 		}
       
   271 	iAppUnInstallMonitor = CApaAppUnInstallMonitor::NewL(this);
       
   272 	iAppUnInstallMonitor->Start();
       
   273 
       
   274 	iIconCaptionOverrides = new(ELeave) CApaIconCaptionOverrides();
       
   275 	iIconCaptionObserver = CApaIconCaptionCenrepObserver::NewL(*iIconCaptionOverrides);
       
   276 	iIconCaptionObserver->LoadOverridesL();
       
   277 	}
       
   278 	
       
   279 void CApaAppListServer::ConstructPathsToMonitorL()
       
   280 	{
       
   281 	TInt drivesToMonitor = KApaDrivesToMonitor;
       
   282 	#ifdef __WINS__
       
   283 	// KApaDrivesToMonitor is a Rom patchable constant, so need an emulator equivalent
       
   284 	// if WINS then read value from epoc.ini requires licencees to set property in epoc.ini
       
   285 	// Usage: In epoc.ini patchdata_apserv_dll_KApaDrivesToMonitor 4
       
   286 	
       
   287 	TInt valueOfKApaDrivesToMonitor = 0;
       
   288 	if (UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"patchdata_apserv_dll_KApaDrivesToMonitor",&valueOfKApaDrivesToMonitor) == KErrNone)
       
   289 		{
       
   290 		drivesToMonitor = valueOfKApaDrivesToMonitor;
       
   291 		}
       
   292 	#endif
       
   293 	
       
   294 	if ( drivesToMonitor != KApaMonitorAllDrives )
       
   295 		{
       
   296 		// 1. Create and add CApaFsNotifier for all locations belonging to a drive if the drive is set to monitor.
       
   297 		// 2. Do this for all the drives which are required to monitor.
       
   298 		TInt maskBit = 1;
       
   299 		TChar driveLetter;
       
   300 		//Only bits from 0(EDriveA)- 25(EDriveZ) are valid other bits are ignored from 32-bit KApaDrivesToMonitor.
       
   301 		for ( TInt i = EDriveA; i <= EDriveZ; i++ )
       
   302 			{
       
   303 			if ( drivesToMonitor & maskBit )
       
   304 				{
       
   305 				RFs::DriveToChar(i,driveLetter);
       
   306 				RBuf pathToBeMonitored;
       
   307 				TBuf<1> drive;
       
   308 				drive.Append(driveLetter);
       
   309 				
       
   310 				//Creating or Adding <driveLetter>:\private\10003a3f\import\apps\ path to monitor.
       
   311 				pathToBeMonitored.CreateL(KAppRegistrationFileImportLocation());				
       
   312 				CleanupClosePushL(pathToBeMonitored);
       
   313 				pathToBeMonitored.Replace(0,1,drive);				
       
   314 				if ( iAppFsMonitor == NULL )
       
   315 					{
       
   316 					iAppFsMonitor=CApaFsMonitor::NewL(iFs, pathToBeMonitored, TCallBack(&AppFsNotifyCallBack, this));
       
   317 					}
       
   318 				else
       
   319 					{
       
   320 					iAppFsMonitor->AddLocationL(pathToBeMonitored);		
       
   321 					}
       
   322 				CleanupStack::PopAndDestroy(&pathToBeMonitored);
       
   323 			
       
   324 				//Adding <driveLetter>:\resource\apps\ path to monitor.
       
   325 				pathToBeMonitored.CreateL(KAppResourceAppsLocation());
       
   326 				CleanupClosePushL(pathToBeMonitored);
       
   327 				pathToBeMonitored.Replace(0,1,drive);			
       
   328 				iAppFsMonitor->AddLocationL(pathToBeMonitored);
       
   329 				CleanupStack::PopAndDestroy(&pathToBeMonitored);
       
   330 				}
       
   331 			maskBit = maskBit << 1;
       
   332 			}	
       
   333 		}
       
   334 	else
       
   335 		{
       
   336 		iAppFsMonitor=CApaFsMonitor::NewL(iFs, KAppRegistrationFileImportLocation, TCallBack(&AppFsNotifyCallBack, this));
       
   337 		iAppFsMonitor->AddLocationL(KAppResourceAppsLocation);
       
   338 		}	
       
   339 	}
       
   340 	
       
   341 EXPORT_C CApaAppListServer::~CApaAppListServer()
       
   342 	{
       
   343 	delete iIconCaptionObserver;
       
   344 	delete iIconCaptionOverrides;
       
   345 	if(iBaBackupSessionWrapper)
       
   346 		iBaBackupSessionWrapper->DeRegisterBackupOperationObserver(*this);
       
   347 	delete iAppUnInstallMonitor;
       
   348 	delete iScanningFileRecognizer;
       
   349 	delete iAppList; // deletes scanners
       
   350 	delete iDataRecognizer;
       
   351 	delete iTypeStoreManager;
       
   352 	delete iAppFsMonitor;	
       
   353 	delete iTypeStoreMonitor;
       
   354 	delete iBaBackupSessionWrapper;
       
   355 	delete iRecognitionCache;
       
   356 #ifdef USING_ECOM_RECOGS
       
   357 	delete iRecEcomMonitor;
       
   358 #else
       
   359 	iRecEcomMonitor = NULL;
       
   360 #endif
       
   361 	iFs.Close();
       
   362 	iAppCmdLine=NULL;
       
   363 	iWsSession.Close();	
       
   364 	delete 	iRuleBasedPlugIns;
       
   365 	for (TInt i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   366 		{
       
   367 		delete iNonNativeApplicationTypeArray[i].iNativeExecutable;
       
   368 		}
       
   369 	iNonNativeApplicationTypeArray.Close();
       
   370 	iCustomAppList.ResetAndDestroy();
       
   371 	iCustomAppList.Close();
       
   372 	delete iRecognizerUnloadTimer;
       
   373 	iNonNativeApplicationTypeRegistry.Close();
       
   374 	}
       
   375 
       
   376 EXPORT_C void CApaAppListServer::HandleStartUninstallEvent()
       
   377 	{
       
   378 	if ( iAppFsMonitor )
       
   379 		{
       
   380 		iAppFsMonitor->SetBlocked(ETrue);	
       
   381 		}
       
   382 	AppList().StopScan();
       
   383 	}
       
   384 EXPORT_C void CApaAppListServer::HandleEndUninstallEventL()
       
   385 	{
       
   386 	if ( iAppFsMonitor )
       
   387 		{
       
   388 		iAppFsMonitor->SetBlocked(EFalse);	
       
   389 		}
       
   390 	AppList().RestartScanL();
       
   391 	}
       
   392 
       
   393 CSession2* CApaAppListServer::NewSessionL(const TVersion& aVersion,const RMessage2&/* aMessage*/) const
       
   394 
       
   395 // Create a new server session.
       
   396 	{
       
   397 	// check we're the right version
       
   398 	TVersion v(KAppListServMajorVersionNumber,KAppListServMinorVersionNumber,KAppListServBuildVersionNumber);
       
   399 	if (!User::QueryVersionSupported(v,aVersion))
       
   400 		User::Leave(KErrNotSupported);
       
   401 	// make new session
       
   402 	return CApaAppListServSession::NewL(const_cast<CApaAppListServer&>(*this), const_cast<RFs&>(iFs));
       
   403 	}
       
   404 
       
   405 //
       
   406 // scanning code here
       
   407 //
       
   408 
       
   409 EXPORT_C TCallBack CApaAppListServer::RescanCallBack()
       
   410 	{
       
   411 	return TCallBack(&AppFsNotifyWithForcedRegistrationsResetCallBack,this);
       
   412 	}
       
   413 
       
   414 TInt CApaAppListServer::AppFsNotifyWithForcedRegistrationsResetCallBack(TAny* aPtr)
       
   415 	{
       
   416 	ASSERT(aPtr);
       
   417 	reinterpret_cast<CApaAppListServer*>(aPtr)->AppList().ResetForcedRegistrations();
       
   418 	return AppFsNotifyCallBack(aPtr);
       
   419 	}
       
   420 
       
   421 TInt CApaAppListServer::AppFsNotifyCallBack(TAny* aObject)
       
   422 	{
       
   423 	ASSERT(aObject);
       
   424 	reinterpret_cast<CApaAppListServer*>(aObject)->UpdateApps();
       
   425 	return KErrNone;
       
   426 	}
       
   427 
       
   428 TInt CApaAppListServer::PlugInNotifyCallBack(TAny* aObject)
       
   429 	{
       
   430 	//update the pre-Platform-security style  recognizers and rule-based plug-ins
       
   431 	ASSERT(aObject);
       
   432 	reinterpret_cast<CApaAppListServer*>(aObject)->UpdatePlugIns();
       
   433 	return KErrNone;
       
   434 	}
       
   435 
       
   436 TInt CApaAppListServer::TypeStoreNotifyCallback(TAny* aObject)
       
   437 	{
       
   438 	ASSERT(aObject);
       
   439 	reinterpret_cast<CApaAppListServer*>(aObject)->UpdateTypeStore();
       
   440 	return KErrNone;
       
   441 	}
       
   442 
       
   443 void CApaAppListServer::UpdateApps()
       
   444 // update the list
       
   445 	{
       
   446 	// File system change, rescan
       
   447 	TRAP_IGNORE(iAppList->StartIdleUpdateL (this));
       
   448 	}
       
   449 
       
   450 void CApaAppListServer::NotifyUpdate(TInt aReason)
       
   451 // tell all sessions to update their clients
       
   452 	{
       
   453 	// Updates the applist with the icon caption details from the Central Repository.
       
   454 	TRAP_IGNORE(UpdateAppListByIconCaptionOverridesL());
       
   455 	// The short caption value sets through the API has got the highest precedence over the
       
   456 	// values found in either central repository or resource file.
       
   457 	TRAP_IGNORE(UpdateAppListByShortCaptionL());
       
   458 		
       
   459     //Delete any data mappings in service registry related to uninstalled applications.
       
   460     CArrayFixFlat<TUid>* uninstalledApps=iAppList->UninstalledAppArray();
       
   461     TBool modificationStatus=EFalse;
       
   462     TBool modified;
       
   463     
       
   464     if(uninstalledApps)
       
   465         {
       
   466         TInt count=uninstalledApps->Count();
       
   467         for(int index=0;index<count;index++)
       
   468             {
       
   469             modified=iTypeStoreManager->DeleteApplicationDataMappings((*uninstalledApps)[index]);
       
   470         
       
   471             //Set modificationStatus if any data mapping is removed from the service registry
       
   472             if(modified)
       
   473                 modificationStatus=ETrue;
       
   474             }
       
   475         
       
   476         delete uninstalledApps;
       
   477         
       
   478         //If service registry is modified, store it to a file
       
   479         if(modificationStatus)
       
   480             TRAP_IGNORE(iTypeStoreManager->StoreL());
       
   481         }
       
   482     
       
   483 	// iterate through sessions
       
   484 	iSessionIter.SetToFirst();
       
   485 	CApaAppListServSession* ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   486 	while (ses!=NULL)
       
   487 		{
       
   488 		ses->NotifyClients(aReason);	
       
   489 		ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   490 		}
       
   491 	}
       
   492 
       
   493 void CApaAppListServer::UpdatePlugIns()
       
   494 // update the pre-Platform-security style, ecom style recognizers and rule-based plug-ins
       
   495 	{
       
   496 	TRAP_IGNORE(iScanningFileRecognizer->ScanForRecognizersL());
       
   497 	//we want the recognizers to be loaded either if:
       
   498 	// 1) they are not loaded on demand
       
   499 	// 2) they are loaded on demand and actively used
       
   500 	// 3) they are loaded on demand but waiting for the timer to be unloaded
       
   501 	if(!iLoadRecognizersOnDemand || iRecognizerUsageCount > 0 || (iRecognizerUnloadTimer && iRecognizerUnloadTimer->IsActive()))
       
   502 		{
       
   503 		TRAP_IGNORE(iDataRecognizer->LoadRecognizersL());
       
   504 		}
       
   505 	if (iRecognitionCache)
       
   506 		{	// RecognitionCache is flushed if there are any changes in plugins, i.e.,if:
       
   507 			// 1. New ECom Plugin is installed.
       
   508 			// 2. Existing ECom Plugin is uninstalled.
       
   509 		iRecognitionCache->Flush();
       
   510 		}
       
   511 
       
   512 	TRAP_IGNORE(iRuleBasedPlugIns->ScanForRuleBasedPlugInsL());
       
   513 	}
       
   514 
       
   515 void CApaAppListServer::UpdateTypeStore()
       
   516 // Update the internal type store if things have changed
       
   517 	{
       
   518 	TRAP_IGNORE(DoUpdateTypeStoreL());
       
   519 	}
       
   520 
       
   521 void CApaAppListServer::DoUpdateTypeStoreL()
       
   522 	{
       
   523 	TTime modified;
       
   524 	TInt err=iFs.Modified(iTypeStoreManager->IniFileName(),modified);
       
   525 	// check the time stamp to see if we are interested in an update
       
   526 	if (modified>iTypeStoreModified && err==KErrNone)
       
   527 		{
       
   528 		CTypeStoreManager* manager=CTypeStoreManager::NewL(iFs);
       
   529 		CleanupStack::PushL(manager);
       
   530 		manager->RestoreL();
       
   531 		iTypeStoreModified=modified;
       
   532 		delete iTypeStoreManager;
       
   533 		iTypeStoreManager=manager;
       
   534 		CleanupStack::Pop(manager); 
       
   535 		}
       
   536 	for (iSessionIter.SetToFirst(); ; iSessionIter++) //lint !e1757 prefix operator not defined for TDblQueIter
       
   537 		{
       
   538      	CSession2* const session=iSessionIter;
       
   539      	if (session==NULL)
       
   540 			{
       
   541   			break;
       
   542 			}
       
   543      	static_cast<CApaAppListServSession*>(session)->NotifyClientOfDataMappingChange();
       
   544 		}
       
   545 	}
       
   546 
       
   547 void CApaAppListServer::HandleBackupOperationEventL(const TBackupOperationAttributes& aBackupOperationAttributes)
       
   548 //
       
   549 // Handle a signal from the backup server to indicate that a backup has started or finished.
       
   550 //
       
   551 	{
       
   552 	switch(aBackupOperationAttributes.iOperation)
       
   553 		{
       
   554 	case MBackupOperationObserver::ENone:
       
   555 	case MBackupOperationObserver::EAbort:
       
   556 		break;
       
   557 	case MBackupOperationObserver::EStart:
       
   558 		if ( iAppFsMonitor )
       
   559 			{
       
   560 			iAppFsMonitor->SetBlocked(ETrue);	
       
   561 			}
       
   562 		break;
       
   563 	case MBackupOperationObserver::EEnd:
       
   564 		if ( iAppFsMonitor )
       
   565 			{
       
   566 			iAppFsMonitor->SetBlocked(EFalse);	
       
   567 			}
       
   568 		break;
       
   569 	default:
       
   570 		Panic(EEventFromBackupObserverError);
       
   571 		break;
       
   572 		}
       
   573 	}
       
   574 
       
   575 void CApaAppListServer::InitialListPopulationComplete()
       
   576 	{
       
   577 	if ( iAppFsMonitor )
       
   578 		{
       
   579 		iAppFsMonitor->SetBlocked(EFalse);	
       
   580 		}
       
   581 	
       
   582 	// notify clients (whoever is interested) that initial population of list is completed
       
   583 	iSessionIter.SetToFirst();
       
   584 	CApaAppListServSession* ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   585 	// iterate through sessions
       
   586 	while (ses!=NULL)
       
   587 		{
       
   588 		ses->NotifyClientForCompletionOfListPopulation();	
       
   589 		ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   590 		}
       
   591 	}
       
   592 
       
   593 void CApaAppListServer::RegisterNonNativeApplicationTypeL(TUid aApplicationType, const TDesC& aNativeExecutable)
       
   594 	{
       
   595 	for (TInt i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   596 		{
       
   597 		if (iNonNativeApplicationTypeArray[i].iTypeUid.iUid==aApplicationType.iUid)
       
   598 			{
       
   599 			User::Leave(KErrAlreadyExists);
       
   600 			}
       
   601 		}
       
   602 	SNonNativeApplicationType nonNativeApplicationType;
       
   603 	nonNativeApplicationType.iTypeUid.iUid=aApplicationType.iUid;
       
   604 	nonNativeApplicationType.iNativeExecutable=aNativeExecutable.AllocLC();
       
   605 	iNonNativeApplicationTypeArray.AppendL(nonNativeApplicationType);
       
   606 	CleanupStack::Pop(nonNativeApplicationType.iNativeExecutable);
       
   607 	CleanupStack::PushL(TCleanupItem(DeleteLastNonNativeApplicationType, this));
       
   608 	ExternalizeNonNativeApplicationTypeArrayL();
       
   609 	CleanupStack::Pop(this); // the TCleanupItem
       
   610 	}
       
   611 
       
   612 void CApaAppListServer::DeregisterNonNativeApplicationTypeL(TUid aApplicationType)
       
   613 	{
       
   614 	TInt i;
       
   615 	for (i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   616 		{
       
   617 		if (iNonNativeApplicationTypeArray[i].iTypeUid.iUid==aApplicationType.iUid)
       
   618 			{
       
   619 			break;
       
   620 			}
       
   621 		}
       
   622 	if (i>=0)
       
   623 		{
       
   624 		ExternalizeNonNativeApplicationTypeArrayL(i);
       
   625 		delete iNonNativeApplicationTypeArray[i].iNativeExecutable;
       
   626 		iNonNativeApplicationTypeArray[i].iNativeExecutable = NULL;
       
   627 		iNonNativeApplicationTypeArray.Remove(i);
       
   628 		}
       
   629 	}
       
   630 
       
   631 void CApaAppListServer::InternalizeNonNativeApplicationTypeArrayL()
       
   632 	{
       
   633 	RFile file;
       
   634 	CleanupClosePushL(file);
       
   635 	const TInt error=file.Open(iFs, iNonNativeApplicationTypeRegistry, EFileShareReadersOnly|EFileStream|EFileRead);
       
   636 	if (error==KErrNone) // don't leave if the file can't be opened (because it doesn't exist, or because the directory we're looking for it in doesn't exist)
       
   637 		{
       
   638 		RFileReadStream sourceStream;
       
   639 		sourceStream.Attach(file); // file gets closed by this call, but that's okay, we don't need it any more (sourceStream has its own copy of this RFile object that it owns)
       
   640 		CleanupClosePushL(sourceStream);
       
   641 		TCardinality arrayCount;
       
   642 		arrayCount.InternalizeL(sourceStream);
       
   643 		for (TInt i=0; i<TInt(arrayCount); ++i)
       
   644 			{
       
   645 			SNonNativeApplicationType nonNativeApplicationType;
       
   646 			nonNativeApplicationType.iTypeUid.iUid=sourceStream.ReadUint32L();
       
   647 			nonNativeApplicationType.iNativeExecutable=HBufC::NewLC(sourceStream, KMaxFileName);
       
   648 			iNonNativeApplicationTypeArray.AppendL(nonNativeApplicationType);
       
   649 			CleanupStack::Pop(nonNativeApplicationType.iNativeExecutable);
       
   650 			}
       
   651 		CleanupStack::PopAndDestroy(&sourceStream);
       
   652 		}
       
   653 	CleanupStack::PopAndDestroy(&file);
       
   654 	}
       
   655 
       
   656 void CApaAppListServer::ExternalizeNonNativeApplicationTypeArrayL(TInt aIndexToIgnore/*=-1*/) const
       
   657 	{
       
   658 	RFs& fs=const_cast<RFs&>(iFs);
       
   659 	fs.MkDirAll(iNonNativeApplicationTypeRegistry); // ignore any error
       
   660 	RFile file;
       
   661 	CleanupClosePushL(file);
       
   662 	User::LeaveIfError(file.Replace(fs, iNonNativeApplicationTypeRegistry, EFileShareExclusive|EFileStream|EFileWrite));
       
   663 	RFileWriteStream targetStream;
       
   664 	targetStream.Attach(file); // file gets closed by this call, but that's okay, we don't need it any more (targetStream has its own copy of this RFile object that it owns)
       
   665 	CleanupClosePushL(targetStream);
       
   666 	const TInt arrayCount(iNonNativeApplicationTypeArray.Count());
       
   667 	TInt arrayCountToExternalize=arrayCount;
       
   668 	if (aIndexToIgnore>=0)
       
   669 		{
       
   670 		--arrayCountToExternalize;
       
   671 		}
       
   672 	TCardinality(arrayCountToExternalize).ExternalizeL(targetStream);
       
   673 	for (TInt i=0; i<arrayCount; ++i)
       
   674 		{
       
   675 		if (i!=aIndexToIgnore)
       
   676 			{
       
   677 			const SNonNativeApplicationType& nonNativeApplicationType=iNonNativeApplicationTypeArray[i];
       
   678 			targetStream.WriteUint32L(nonNativeApplicationType.iTypeUid.iUid);
       
   679 			targetStream << *nonNativeApplicationType.iNativeExecutable;
       
   680 			}
       
   681 		}
       
   682 	targetStream.CommitL();
       
   683 	CleanupStack::PopAndDestroy(2, &file);
       
   684 	}
       
   685 
       
   686 TPtrC CApaAppListServer::NativeExecutableL(TUid aNonNativeApplicationType) const
       
   687 	{
       
   688 	for (TInt i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   689 		{
       
   690 		const SNonNativeApplicationType& nonNativeApplicationType=iNonNativeApplicationTypeArray[i];
       
   691 		if (nonNativeApplicationType.iTypeUid.iUid==aNonNativeApplicationType.iUid)
       
   692 			{
       
   693 			return *nonNativeApplicationType.iNativeExecutable;
       
   694 			}
       
   695 		}
       
   696 	User::Leave(KErrNotSupported); // not KErrNotFound
       
   697 	return KNullDesC();
       
   698 	}
       
   699 
       
   700 void CApaAppListServer::DeleteLastNonNativeApplicationType(TAny* aThis)
       
   701 	{ // static
       
   702 	CApaAppListServer& self=*static_cast<CApaAppListServer*>(aThis);
       
   703 	const TInt arrayIndex=self.iNonNativeApplicationTypeArray.Count()-1;
       
   704 	delete self.iNonNativeApplicationTypeArray[arrayIndex].iNativeExecutable;
       
   705 	self.iNonNativeApplicationTypeArray[arrayIndex].iNativeExecutable = NULL;
       
   706 	self.iNonNativeApplicationTypeArray.Remove(arrayIndex);
       
   707 	}
       
   708 
       
   709 void CApaAppListServer::NotifyScanComplete()
       
   710 	{
       
   711 	// Updates the applist with the icon caption details from the Central Repository.
       
   712 	TRAP_IGNORE(UpdateAppListByIconCaptionOverridesL());
       
   713 	// The short caption value sets through the API has got the highest precedence over the
       
   714 	// values found in either central repository or resource file.		
       
   715 	TRAP_IGNORE(UpdateAppListByShortCaptionL());
       
   716 
       
   717 	// iterate through sessions
       
   718 	iSessionIter.SetToFirst();
       
   719 	CApaAppListServSession* ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   720 	while (ses!=NULL)
       
   721 		{
       
   722 		ses->NotifyScanComplete();	
       
   723 		ses=static_cast<CApaAppListServSession*>(&(*iSessionIter++));
       
   724 		}
       
   725 	}
       
   726 
       
   727 void CApaAppListServer::AddCustomAppInfoInListL(CCustomAppInfoData* aCustomAppInfo)
       
   728 	{
       
   729 	TBool replaced=EFalse;
       
   730 	for (TInt i=iCustomAppList.Count()-1; i>=0; --i)
       
   731 		{
       
   732 		if ((aCustomAppInfo->Uid()==iCustomAppList[i]->Uid()) && (aCustomAppInfo->Language()==iCustomAppList[i]->Language()))
       
   733 			{
       
   734 			CCustomAppInfoData* oldAppInfo = iCustomAppList[i];
       
   735 			iCustomAppList[i]=aCustomAppInfo;
       
   736 			delete oldAppInfo;
       
   737 			replaced=ETrue;
       
   738 			break;
       
   739 			}
       
   740 		}
       
   741 	//Add ELangNone items at the end and others at the beginning
       
   742 	if(!replaced)
       
   743 		{
       
   744 		if(aCustomAppInfo->Language()==ELangNone)
       
   745 			{
       
   746 			iCustomAppList.AppendL(aCustomAppInfo);
       
   747 			}
       
   748 		else
       
   749 			{
       
   750 			iCustomAppList.InsertL(aCustomAppInfo,0);
       
   751 			}
       
   752 		}
       
   753 	
       
   754 	} //lint !e818 Suppress pointer parameter could be declared as pointing to const - this method takes ownership
       
   755 
       
   756 
       
   757 void CApaAppListServer::UpdateAppListByShortCaptionL()
       
   758 	{
       
   759 	CApaAppData* app=NULL;
       
   760 	//Items with ELangNone are always found at the end and other languages at the beginning
       
   761 	//While iterating from end to beginning, we overwrite short caption set by ELangNone if there is any provided for the application language
       
   762 	for (TInt i=iCustomAppList.Count()-1; i>=0; --i)
       
   763 		{
       
   764 		const CCustomAppInfoData* const customAppInfo=iCustomAppList[i];
       
   765 		app=iAppList->AppDataByUid(customAppInfo->Uid());
       
   766 		if ( app && ((app->ApplicationLanguage()==customAppInfo->Language()) || (customAppInfo->Language()==ELangNone)))
       
   767 			{
       
   768 			app->SetShortCaptionL(*customAppInfo->ShortCaption());
       
   769 			}
       
   770 		}
       
   771 	}
       
   772 
       
   773 void CApaAppListServer::UpdateAppListByIconCaptionOverridesL()
       
   774 	{
       
   775 	// get the language downgrade path, so that most appropriate language can be used
       
   776 	RArray<TLanguage> languageDowngradePath;
       
   777 	CleanupClosePushL(languageDowngradePath);
       
   778 	BaflUtils::GetDowngradePathL(iFs, User::Language(), languageDowngradePath);
       
   779 	for (CApaAppData* app = iAppList->FirstApp(); app; app = iAppList->NextApp(app))
       
   780 		{
       
   781 		CApaIconCaptionOverridesForApp* appOverride = iIconCaptionOverrides->OverrideForApp(app->AppEntry().iUidType[2]);
       
   782 		if (appOverride)
       
   783 			{
       
   784 			TApaIconCaptionOverrideReader overrideReader = appOverride->Reader(languageDowngradePath);
       
   785 			const TDesC* shortCaption = overrideReader.ShortCaption();
       
   786 			if (shortCaption)
       
   787 				app->SetShortCaptionL(*shortCaption);
       
   788 			const TDesC* caption = overrideReader.Caption();
       
   789 			if (caption)
       
   790 				app->SetCaptionL(*caption);
       
   791 			const TDesC* iconFileName = overrideReader.IconFileName();
       
   792 			if (overrideReader.NumIconsSet() && iconFileName)
       
   793 				app->SetIconsL(*iconFileName, overrideReader.NumIcons());
       
   794 			}
       
   795 		}
       
   796 	CleanupStack::PopAndDestroy(&languageDowngradePath);
       
   797 	}
       
   798 
       
   799 CCustomAppInfoData* CCustomAppInfoData::NewL(TUid aAppUid, TLanguage aLanguage, const TDesC& aShortCaption)
       
   800 	{
       
   801 	CCustomAppInfoData* self=new(ELeave) CCustomAppInfoData(aAppUid, aLanguage);
       
   802     CleanupStack::PushL(self);
       
   803 	self->ConstructL(aShortCaption);
       
   804 	CleanupStack::Pop(self);
       
   805 	return self;
       
   806 	}
       
   807 
       
   808 CCustomAppInfoData::~CCustomAppInfoData()
       
   809 	{
       
   810 	delete iShortCaption;
       
   811 	}
       
   812 
       
   813 CCustomAppInfoData::CCustomAppInfoData(TUid aAppUid, TLanguage aLanguage)
       
   814 	:iUid(aAppUid),
       
   815 	iLanguage(aLanguage)
       
   816 	{
       
   817 	}
       
   818 
       
   819 void CCustomAppInfoData::ConstructL(const TDesC& aShortCaption)
       
   820 	{
       
   821 	iShortCaption=aShortCaption.AllocL();
       
   822 	}
       
   823 
       
   824 /*
       
   825  * Data Recognizer calls
       
   826  */
       
   827  
       
   828 TBool CApaAppListServer::CachedRecognitionResult(const TParseBase& aParser, TDataRecognitionResult& aResult) const
       
   829 	{
       
   830 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   831 		{
       
   832 		return iRecognitionCache->Get(aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   833 		}
       
   834 	return EFalse;
       
   835 	}
       
   836 
       
   837 /**
       
   838 N.B. The @c CRecognitionResult object is reference counted so it must be closed!
       
   839 */
       
   840 CRecognitionResult* CApaAppListServer::CachedRecognitionResult(const RFile& aFile, const TParseBase& aParser) const
       
   841 	{
       
   842 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   843 		{
       
   844 		return iRecognitionCache->Get(aFile, aParser.DriveAndPath(), aParser.NameAndExt());
       
   845 		}
       
   846 	return NULL;
       
   847 	}
       
   848 
       
   849 void CApaAppListServer::CacheRecognitionResultL(const TParseBase& aParser, const TDataRecognitionResult& aResult)
       
   850 	{
       
   851 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   852 		{
       
   853 		iRecognitionCache->AddL(aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   854 		}
       
   855 	}
       
   856 
       
   857 void CApaAppListServer::CacheRecognitionResultL(const RFile& aFile, const TParseBase& aParser, const TDataRecognitionResult& aResult)
       
   858 	{
       
   859 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   860 		{
       
   861 		iRecognitionCache->AddL(aFile, aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   862 		}
       
   863 	}
       
   864 
       
   865 TDataRecognitionResult CApaAppListServer::RecognizeDataL(const TDesC& aName, const TDesC8& aBuffer)
       
   866 	{
       
   867 	TParsePtrC parser(iFs.IsValidName(aName) ? aName : KNullDesC);
       
   868 	TDataRecognitionResult result;
       
   869 	
       
   870 	// check cache	
       
   871 	if(!CachedRecognitionResult(parser, result))
       
   872 		{
       
   873 		// recognize
       
   874 		if(iLoadRecognizersOnDemand)
       
   875 			{
       
   876 			LoadRecognizersLC();
       
   877 			}
       
   878 		result = iDataRecognizer->RecognizeL(aName, aBuffer);
       
   879 		if(iLoadRecognizersOnDemand)
       
   880 			{
       
   881 			CleanupStack::PopAndDestroy();
       
   882 			}
       
   883 
       
   884 		// add to cache
       
   885 		CacheRecognitionResultL(parser, result);
       
   886 		}
       
   887 	
       
   888 	return result;	
       
   889 	}
       
   890 
       
   891 TDataRecognitionResult CApaAppListServer::RecognizeDataL(RFile& aFile, TInt aPreferredBufSize)
       
   892 	{
       
   893 	CRecognitionResult* result = RecognizeDataAsCRecognitionResultL(aFile, aPreferredBufSize);
       
   894 	TDataRecognitionResult ret;
       
   895 	result->Get(ret);
       
   896 	result->Close();
       
   897 	return ret;
       
   898 	}
       
   899 
       
   900 /**
       
   901 Same as @c RecognizeDataL(RFile&, TInt) but returns a @c CRecognitionResult 
       
   902 instead of a @c TDataRecognitionResult.
       
   903 
       
   904 N.B. The @c CRecognitionResult object is reference counted so it must be closed!
       
   905 */
       
   906 CRecognitionResult* CApaAppListServer::RecognizeDataAsCRecognitionResultL(RFile& aFile, TInt aPreferredBufSize)
       
   907 	{
       
   908 	CRecognitionResult* result = NULL;
       
   909 	
       
   910 	TFileName fileName;
       
   911 	User::LeaveIfError(aFile.FullName(fileName));
       
   912 	TParsePtrC parser(fileName); //fileName is valid since it comes from RFile
       
   913 
       
   914 	//check cache
       
   915 	result = CachedRecognitionResult(aFile,parser);
       
   916 	if(!result)
       
   917 		{
       
   918 		// recognize
       
   919 		if(iLoadRecognizersOnDemand)
       
   920 			{
       
   921 			LoadRecognizersLC();
       
   922 			}
       
   923 		const TDataRecognitionResult recResult = iDataRecognizer->RecognizeL(aFile, aPreferredBufSize);
       
   924 		if(iLoadRecognizersOnDemand)
       
   925 			{
       
   926 			CleanupStack::PopAndDestroy();
       
   927 			}
       
   928 		
       
   929 		//add to cache
       
   930 		CacheRecognitionResultL(aFile, parser, recResult);
       
   931 
       
   932 		result = CRecognitionResult::NewL(parser.NameAndExt(), recResult);
       
   933 		}
       
   934 	
       
   935 	return result;
       
   936 	}
       
   937 
       
   938 TBool CApaAppListServer::RecognizeDataL(const TDesC& aName, const TDesC8& aBuffer, const TDataType& aDataType)
       
   939 	{
       
   940 	if(iLoadRecognizersOnDemand)
       
   941 		{
       
   942 		LoadRecognizersLC();
       
   943 		}
       
   944 	const TBool ret = iDataRecognizer->RecognizeL(aName,aBuffer,aDataType);
       
   945 	if(iLoadRecognizersOnDemand)
       
   946 		{
       
   947 		CleanupStack::PopAndDestroy();
       
   948 		}
       
   949 	return ret;
       
   950 	}
       
   951 
       
   952 TBool CApaAppListServer::RecognizeDataL(RFile& aFile, TInt aPreferredBufSize, const TDataType& aDataType)
       
   953 	{
       
   954 	if(iLoadRecognizersOnDemand)
       
   955 		{
       
   956 		LoadRecognizersLC();
       
   957 		}
       
   958 	const TBool ret = iDataRecognizer->RecognizeL(aFile,aPreferredBufSize,aDataType);
       
   959 	if(iLoadRecognizersOnDemand)
       
   960 		{
       
   961 		CleanupStack::PopAndDestroy();
       
   962 		}
       
   963 	return ret;
       
   964 	}
       
   965 
       
   966 TInt CApaAppListServer::DataRecognizerPreferredBufSizeL()
       
   967 	{
       
   968 	if(iLoadRecognizersOnDemand)
       
   969 		{
       
   970 		LoadRecognizersLC();
       
   971 		}
       
   972 	const TInt ret = iDataRecognizer->PreferredBufSize();
       
   973 	if(iLoadRecognizersOnDemand)
       
   974 		{
       
   975 		CleanupStack::PopAndDestroy();
       
   976 		}
       
   977 	return ret;
       
   978 	}
       
   979 
       
   980 void CApaAppListServer::DataTypeL(CDataTypeArray& aArray)
       
   981 	{
       
   982 	if(iLoadRecognizersOnDemand)
       
   983 		{
       
   984 		LoadRecognizersLC();
       
   985 		}
       
   986 	iDataRecognizer->DataTypeL(aArray);
       
   987 	if(iLoadRecognizersOnDemand)
       
   988 		{
       
   989 		CleanupStack::PopAndDestroy();
       
   990 		}
       
   991 	}
       
   992 
       
   993 /*
       
   994  * Recognizer loading/unloading code
       
   995  */
       
   996 
       
   997 void CApaAppListServer::LoadRecognizersLC()
       
   998 	{
       
   999 	ASSERT(iLoadRecognizersOnDemand);
       
  1000 
       
  1001 	LoadRecognizersL();
       
  1002 	TCleanupItem cleanup(CApaAppListServer::RecognizerCleanup, this);
       
  1003 	CleanupStack::PushL(cleanup);
       
  1004 	}
       
  1005 
       
  1006 void CApaAppListServer::RecognizerCleanup(TAny* aSelf)
       
  1007 	{
       
  1008 	if (aSelf)
       
  1009 		{
       
  1010 		static_cast<CApaAppListServer*>(aSelf)->UnloadRecognizers();
       
  1011 		}
       
  1012 	}
       
  1013 
       
  1014 void CApaAppListServer::LoadRecognizersL()
       
  1015 	{
       
  1016 	ASSERT(iLoadRecognizersOnDemand);
       
  1017 
       
  1018 	if(iRecognizerUnloadTimer->IsActive())
       
  1019 		{
       
  1020 		__ASSERT_DEBUG(iRecognizerUsageCount==0,Panic(EReferenceCountingError1));
       
  1021 		iRecognizerUnloadTimer->Cancel();
       
  1022 		}
       
  1023 	else if(iRecognizerUsageCount==0)
       
  1024 		{
       
  1025 		iDataRecognizer->LoadRecognizersL();
       
  1026 		}
       
  1027 
       
  1028 	++iRecognizerUsageCount;
       
  1029 	}
       
  1030 
       
  1031 TInt CApaAppListServer::UnloadRecognizers()
       
  1032 	{
       
  1033 	ASSERT(iLoadRecognizersOnDemand);
       
  1034 
       
  1035 	--iRecognizerUsageCount;
       
  1036 	__ASSERT_DEBUG(iRecognizerUsageCount>=0,Panic(EReferenceCountingError2));
       
  1037 	if (iRecognizerUsageCount==0)
       
  1038 		{
       
  1039 		iRecognizerUnloadTimer->Start(KApaUnloadRecognizersTimeout,0,TCallBack(CApaAppListServer::DoUnloadRecognizersCallback,this));
       
  1040 		}
       
  1041 	return KErrNone;
       
  1042 	}
       
  1043 	
       
  1044 TInt CApaAppListServer::DoUnloadRecognizersCallback(TAny* aSelf)
       
  1045 	{
       
  1046 	TInt ret=KErrNone;
       
  1047 	if (aSelf)
       
  1048 		{
       
  1049 		ret = static_cast<CApaAppListServer*>(aSelf)->DoUnloadRecognizers();
       
  1050 		}
       
  1051 	return ret;
       
  1052 	}
       
  1053 
       
  1054 TInt CApaAppListServer::DoUnloadRecognizers()
       
  1055 	{
       
  1056 	ASSERT(iLoadRecognizersOnDemand);
       
  1057 
       
  1058 	// need to cancel the periodic timer since we only want a oneshot timer
       
  1059 	iRecognizerUnloadTimer->Cancel();
       
  1060 	iDataRecognizer->UnloadRecognizers();
       
  1061 	return KErrNone;
       
  1062 	}
       
  1063 	
       
  1064 void CApaAppListServer::GetAppByDataType(const TDataType& aDataType, TUid& aUid) const
       
  1065 	{
       
  1066 	iTypeStoreManager->GetAppByDataType(aDataType, aUid);
       
  1067 	}
       
  1068 	
       
  1069 void CApaAppListServer::GetAppByDataType(const TDataType& aDataType, TUid aServiceUid, TUid& aUid) const
       
  1070 	{
       
  1071 	iTypeStoreManager->GetAppByDataType(aDataType, aServiceUid, aUid);
       
  1072 	}
       
  1073 	
       
  1074 TBool CApaAppListServer::InsertAndStoreIfHigherL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid)
       
  1075 	{
       
  1076 	return iTypeStoreManager->InsertAndStoreIfHigherL(aDataType, aPriority, aUid);
       
  1077 	}
       
  1078 	
       
  1079 void CApaAppListServer::InsertAndStoreDataMappingL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid, TUid aServiceUid)
       
  1080 	{
       
  1081 	iTypeStoreManager->InsertAndStoreDataMappingL(aDataType, aPriority, aUid, aServiceUid);
       
  1082 	}
       
  1083 	
       
  1084 void CApaAppListServer::DeleteAndStoreDataMappingL(const TDataType& aDataType, TUid aServiceUid)
       
  1085 	{
       
  1086 	iTypeStoreManager->DeleteAndStoreDataMappingL(aDataType, aServiceUid);
       
  1087 	}
       
  1088 	
       
  1089 CApaFileRecognizer* CApaAppListServer::FileRecognizer()
       
  1090 	{ 
       
  1091 	return static_cast<CApaFileRecognizer*>(iScanningFileRecognizer); 
       
  1092 	}
       
  1093 
       
  1094 TBool CApaAppListServer::LoadMbmIconsOnDemand() const
       
  1095 	{
       
  1096 	return iLoadMbmIconsOnDemand;
       
  1097 	}
       
  1098 
       
  1099 #ifdef _DEBUG
       
  1100 
       
  1101 /**
       
  1102 Flushes the recognition cache.
       
  1103 
       
  1104 Useful for debugging.
       
  1105 */
       
  1106 void CApaAppListServer::FlushRecognitionCache()
       
  1107 	{
       
  1108 	if(iRecognitionCache)
       
  1109 		iRecognitionCache->Flush();
       
  1110 	}
       
  1111 
       
  1112 /**
       
  1113 Sets whether or not recognizers should be loaded when they are needed.
       
  1114 
       
  1115 Useful for debugging.
       
  1116 */	
       
  1117 void CApaAppListServer::SetLoadRecognizersOnDemandL(TBool aLoadRecognizersOnDemand)
       
  1118 	{
       
  1119 	if(iLoadRecognizersOnDemand == aLoadRecognizersOnDemand)
       
  1120 		return;
       
  1121 	
       
  1122 	CPeriodic* newUnloadTimer;
       
  1123 	if(aLoadRecognizersOnDemand)
       
  1124 		{
       
  1125 		ASSERT(!iRecognizerUnloadTimer);
       
  1126 		newUnloadTimer = CPeriodic::NewL(EPriorityNormal);
       
  1127 		}
       
  1128 	else
       
  1129 		{
       
  1130 		ASSERT(iRecognizerUnloadTimer);
       
  1131 		newUnloadTimer = NULL;
       
  1132 		}
       
  1133 	CleanupStack::PushL(newUnloadTimer);
       
  1134 	
       
  1135 	CApaScanningDataRecognizer* newDataRecognizer = CApaScanningDataRecognizer::NewL(iFs,!aLoadRecognizersOnDemand);
       
  1136 	delete iDataRecognizer;
       
  1137 	iDataRecognizer = newDataRecognizer;
       
  1138 	
       
  1139 	delete iRecognizerUnloadTimer;
       
  1140 	iRecognizerUnloadTimer = newUnloadTimer;
       
  1141 	CleanupStack::Pop(newUnloadTimer);
       
  1142 	
       
  1143 	iRecognizerUsageCount = 0;
       
  1144 	iLoadRecognizersOnDemand = aLoadRecognizersOnDemand;	
       
  1145 	}
       
  1146 
       
  1147 /**
       
  1148 If recognizers are set to be loaded on demand this method can be used to perform
       
  1149 the unloading synchronously, instead of waiting for the unloading timer to go off.
       
  1150 
       
  1151 Useful for debugging.
       
  1152 */
       
  1153 void CApaAppListServer::PerformOutstandingRecognizerUnloading()
       
  1154 	{
       
  1155 	if(iLoadRecognizersOnDemand && iRecognizerUnloadTimer->IsActive())
       
  1156 		{
       
  1157 		__ASSERT_DEBUG(iRecognizerUsageCount==0,Panic(EReferenceCountingError3));
       
  1158 		DoUnloadRecognizers();
       
  1159 		}
       
  1160 	}
       
  1161 
       
  1162 #endif //_DEBUG