appfw/apparchitecture/apserv/APSSERV.CPP
changeset 0 2e3d3ce01487
child 29 6a787171e1de
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     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 "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // apsserv.cpp
       
    15 //
       
    16 
       
    17 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    18 #if !defined(__APA_INTERNAL_H__)
       
    19 #include "apainternal.h"
       
    20 #endif
       
    21 #include "apaidpartner.h"
       
    22 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
       
    23 #include <e32svr.h>
       
    24 #include <u32hal.h>
       
    25 #include "apsserv.h"
       
    26 #include "APFREC.H"
       
    27 #include "APSSES.H"
       
    28 #include "APSSTD.H"
       
    29 #include "../aplist/aplappregfinder.h"
       
    30 #include "../aplist/aplapplistitem.h"
       
    31 #include "APSSCAN.H"
       
    32 #include "APSSTD.H"
       
    33 #include "APASVST.H"
       
    34 #include <datastor.h>
       
    35 #include "APSRECCACHE.h"
       
    36 #include "apsnnapps.h"
       
    37 #include "../apfile/apinstallationmonitor.h"
       
    38 #include "../apgrfx/apprivate.h"
       
    39 #include "apgnotif.h"
       
    40 
       
    41 _LIT(KAppArcServerSemaphore,"AppArcServerSemaphore");
       
    42 _LIT(KAppArcServerThread,"AppArcServerThread");
       
    43 _LIT(KAppRegistrationFileImportLocation, "?:\\private\\10003a3f\\import\\apps\\");
       
    44 _LIT(KAppResourceAppsLocation, "?:\\resource\\apps\\");
       
    45 _LIT(KNonNativeApplicationTypeRegistry, ":\\private\\10003a3f\\NonNativeTypes.dat");
       
    46 
       
    47 /*
       
    48  * patchable const data values defined in ApsConstData.cpp
       
    49  */
       
    50 
       
    51 IMPORT_C extern const TInt KApaLoadDataRecognizersOnDemand;
       
    52 IMPORT_C extern const TInt KApaUnloadRecognizersTimeout;
       
    53 IMPORT_C extern const TInt KApaDrivesToMonitor;
       
    54 IMPORT_C extern const TInt KApaLoadMbmIconsOnDemand;
       
    55 
       
    56 const TUint8 KPolicyElementWriteDeviceData = 0;
       
    57 
       
    58 //To monitor all drives.
       
    59 const TInt KApaMonitorAllDrives = 0x3FFFFFF;
       
    60 
       
    61 const TUint KRangeCount = 3; 
       
    62 
       
    63 const TInt KAppListServRanges[KRangeCount] = 
       
    64 	{	
       
    65 	EFirstUnrestrictedOpcodeInAppListServ,
       
    66 	EFirstOpcodeNeedingWriteDeviceDataInAppListServ, 
       
    67 	EAppListFirstUnusedOpcode,
       
    68 	};
       
    69 
       
    70 const TUint8 KElementsIndex[KRangeCount] =
       
    71 	{
       
    72 	CPolicyServer::EAlwaysPass,			//Always passing no capability required [0-99]
       
    73 	KPolicyElementWriteDeviceData,		//Requires WriteDeviceData				 [100-(EAppListFirstUnusedOpcode-1)]
       
    74 	CPolicyServer::ENotSupported, 		//Not Supported		[EAppListFirstUnusedOpcode-End]
       
    75 	};
       
    76 
       
    77 const CPolicyServer::TPolicyElement KPolicyElements[] = 
       
    78 	{ 
       
    79 	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient} 
       
    80 	};
       
    81 
       
    82 const CPolicyServer::TPolicy KApaServPolicy =
       
    83 	{
       
    84 	CPolicyServer::EAlwaysPass, 
       
    85 	KRangeCount,
       
    86 	KAppListServRanges,
       
    87 	KElementsIndex, 	
       
    88 	KPolicyElements 	
       
    89 	};
       
    90  	
       
    91 
       
    92 
       
    93 //
       
    94 // CApaAppArcServer
       
    95 //
       
    96 
       
    97 const TInt KAppListServerPriority=CActive::EPriorityStandard;
       
    98 /**
       
    99 NameApaServStartSemaphore
       
   100 
       
   101 @internalTechnology
       
   102 @released
       
   103 */
       
   104 EXPORT_C TPtrC NameApaServStartSemaphore()
       
   105 	{
       
   106 	TPtrC nameApaServStartSemaphore(KAppArcServerSemaphore);
       
   107 	return nameApaServStartSemaphore;
       
   108 	}
       
   109 
       
   110 /**
       
   111 NameApaServServerThread
       
   112 
       
   113 @internalTechnology
       
   114 @released
       
   115 */
       
   116 EXPORT_C TPtrC NameApaServServerThread()
       
   117 	{
       
   118 	TPtrC nameApaServServerThread(KAppArcServerThread);
       
   119 	return nameApaServServerThread;
       
   120 	}
       
   121 
       
   122 EXPORT_C CApaAppArcServer* CApaAppArcServer::Self()
       
   123 	{ // static
       
   124 	return static_cast<CApaAppArcServer*>(Dll::Tls());
       
   125 	}
       
   126 
       
   127 EXPORT_C CApaAppArcServer* CApaAppArcServer::NewL()
       
   128 // Create a new CApaAppArcServer which owns it's own resources
       
   129 	{
       
   130 	CApaAppArcServer* self=new(ELeave) CApaAppArcServer(KAppListServerPriority);
       
   131 	CleanupStack::PushL(self);
       
   132 	self->ConstructL();
       
   133 	CleanupStack::Pop();
       
   134 	return self;
       
   135 	}
       
   136 
       
   137 CApaAppArcServer::CApaAppArcServer(TInt aPriority)
       
   138 	: CPolicyServer(aPriority,KApaServPolicy),
       
   139 	iAppList(0),
       
   140 	iTypeStoreModified(0),
       
   141 	iLoadRecognizersOnDemand(KApaLoadDataRecognizersOnDemand),
       
   142 	iLoadMbmIconsOnDemand(KApaLoadMbmIconsOnDemand),
       
   143 	iForceRegistrationStatus(EForceRegistrationNone)
       
   144 	{
       
   145 	
       
   146 #ifdef __WINS__
       
   147 	// KApaLoadDataRecognizersOnDemand and KApaloadIconsOnDemand are Rom patchable constants,
       
   148 	// so need an emulator equivalent
       
   149 	// if WINS then read value from epoc.ini
       
   150 	// requires licencees to set property in epoc.ini
       
   151 
       
   152 	TInt halValue = 0;
       
   153 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, (TAny*)"patchdata_apserv_dll_KApaLoadDataRecognizersOnDemand", &halValue) == KErrNone)
       
   154 		iLoadRecognizersOnDemand = halValue;
       
   155 
       
   156 	if (UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty, (TAny*)"patchdata_apserv_dll_KApaLoadMbmIconsOnDemand", &halValue) == KErrNone)
       
   157 		iLoadMbmIconsOnDemand = halValue;
       
   158 #endif
       
   159 	}
       
   160 
       
   161 void CApaAppArcServer::ConstructL()
       
   162 	{
       
   163 	StartL(KAppListServerName);
       
   164 	User::LeaveIfError(Dll::SetTls(this));
       
   165 	User::LeaveIfError(iFs.Connect());
       
   166 		
       
   167 	// Get the idle timeout delay from the commandline if specified. The default is 50000ms
       
   168 	const TInt cmdLineLen = User::CommandLineLength();
       
   169 	TInt idlePeriodicDelay=50000; //default value
       
   170 	if(cmdLineLen)
       
   171 		{
       
   172 		_LIT(KIdleTimeout,"IDLE_TIMEOUT_PERIODIC_DELAY_");
       
   173 		
       
   174 		// Extract the command line into a buffer
       
   175 		HBufC* cmdLine = HBufC::NewLC(cmdLineLen);
       
   176 		TPtr cmdLinePtr = cmdLine->Des();
       
   177 		User::CommandLine(cmdLinePtr);
       
   178 		cmdLinePtr.UpperCase();
       
   179 				
       
   180 		// Check if there is an idle timeout value given
       
   181 		TInt idleTimeOutArgPos = cmdLinePtr.Find(KIdleTimeout);
       
   182 		if(KErrNotFound != idleTimeOutArgPos)
       
   183 			{
       
   184 			// Extract the value out of the command line argument
       
   185 			const TInt idleTimeOutValuePos = idleTimeOutArgPos + KIdleTimeout().Length();
       
   186 			TInt i = idleTimeOutValuePos;
       
   187 			while (i < cmdLineLen)
       
   188 				{
       
   189 				TChar c(cmdLinePtr[i]);
       
   190 				if (!c.IsDigit())
       
   191 					{
       
   192 					break;
       
   193 					}
       
   194 				i++;
       
   195 				}
       
   196 			TLex idleTimeOutParser(cmdLinePtr.Mid(idleTimeOutValuePos, (i-idleTimeOutValuePos)));
       
   197 		  	User::LeaveIfError(idleTimeOutParser.Val(idlePeriodicDelay));	  					  	
       
   198 			}
       
   199 							
       
   200 		// Check if the recognition cache should be used or not. By default the cache is used
       
   201 		iRecognitionCache = 0;
       
   202 		_LIT(KWithoutRecognitionCache,"WITHOUT_RECOGNITION_CACHE");
       
   203 		if(KErrNotFound == cmdLinePtr.Find(KWithoutRecognitionCache))
       
   204 			{
       
   205 			iRecognitionCache = new (ELeave) CApsRecognitionCache(iFs);
       
   206 			}
       
   207 			
       
   208 		_LIT(KTextShellMode,"TEXT_SHELL_MODE");
       
   209 		if (KErrNotFound == cmdLinePtr.Find(KTextShellMode))
       
   210 			{
       
   211 			// We are NOT running in text shell mode so connect to wserv session
       
   212 			User::LeaveIfError(iWsSession.Connect());
       
   213 			iRuleBasedPlugIns = CApaScanningRuleBasedPlugIns::NewL();
       
   214 			}
       
   215 
       
   216 		CleanupStack::PopAndDestroy(cmdLine);		
       
   217 		}
       
   218 	else
       
   219 		{
       
   220 		// no arguments so cache is used
       
   221 		iRecognitionCache = new (ELeave) CApsRecognitionCache(iFs);
       
   222 		// and rule based plugins are enabled
       
   223 		User::LeaveIfError(iWsSession.Connect());
       
   224 		iRuleBasedPlugIns = CApaScanningRuleBasedPlugIns::NewL();
       
   225 		}
       
   226 	
       
   227 	iAppList=CApaAppList::NewL(iFs, 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 	iMimeTypeRecognizer=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 	//
       
   245 	iRecEcomMonitor=CApaEComMonitor::NewL(TCallBack(&PlugInNotifyCallBack,this));
       
   246 	iRecEcomMonitor->Start();
       
   247 
       
   248 	// Create the EMIME type store manager (part of the app-framework_emime component)
       
   249 	iMimeTypeToAppMappingsManager=CTypeStoreManager::NewL(iFs);
       
   250 	TRAPD(err,iMimeTypeToAppMappingsManager->RestoreL());
       
   251 	if(!err)
       
   252 		User::LeaveIfError(iFs.Modified(iMimeTypeToAppMappingsManager->IniFileName(),iTypeStoreModified));
       
   253 
       
   254 	// Create the EMIME type store monitor
       
   255 	iTypeStoreMonitor = CApaFsMonitor::NewL(iFs,iMimeTypeToAppMappingsManager->IniFileName(),TCallBack(&TypeStoreNotifyCallback,this));
       
   256 	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
       
   257 	TypeStoreNotifyCallback(this);
       
   258 
       
   259 	//
       
   260 	iBaBackupSessionWrapper=CBaBackupSessionWrapper::NewL();
       
   261 	iBaBackupSessionWrapper->RegisterBackupOperationObserverL(*((MBackupOperationObserver*)this));
       
   262 
       
   263 	//
       
   264 	TChar sysDrive = RFs::GetSystemDriveChar();
       
   265 	TInt maxSizeofFileName = KNonNativeApplicationTypeRegistry().Length() + 1;
       
   266 	iNonNativeApplicationTypeRegistry.CreateL(maxSizeofFileName);
       
   267 	iNonNativeApplicationTypeRegistry.Append(sysDrive);
       
   268 	iNonNativeApplicationTypeRegistry.Append(KNonNativeApplicationTypeRegistry());
       
   269 
       
   270 	TRAP_IGNORE(InternalizeNonNativeApplicationTypeArrayL());	// We don't want a corrupt file to prevent from starting
       
   271 	if(iLoadRecognizersOnDemand)
       
   272 		iRecognizerUnloadTimer=CPeriodic::NewL(EPriorityNormal);
       
   273 
       
   274 	//
       
   275 	iAppInstallationMonitor = CApaAppInstallationMonitor::NewL(this);
       
   276 	iAppInstallationMonitor->Start();
       
   277 	}
       
   278 	
       
   279 void CApaAppArcServer::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 CApaAppArcServer::~CApaAppArcServer()
       
   342 	{
       
   343 	if(iBaBackupSessionWrapper)
       
   344 		iBaBackupSessionWrapper->DeRegisterBackupOperationObserver(*this);
       
   345 	delete iAppInstallationMonitor;
       
   346 	delete iAppList; // deletes scanners
       
   347 	delete iMimeTypeRecognizer;
       
   348 	delete iMimeTypeToAppMappingsManager;
       
   349 	delete iAppFsMonitor;	
       
   350 	delete iTypeStoreMonitor;
       
   351 	delete iBaBackupSessionWrapper;
       
   352 	delete iRecognitionCache;
       
   353 	delete iRecEcomMonitor;
       
   354 
       
   355 	iFs.Close();
       
   356 	iWsSession.Close();	
       
   357 	delete 	iRuleBasedPlugIns;
       
   358 	for (TInt i = iNonNativeApplicationTypeArray.Count()-1; i >= 0; --i)
       
   359 		delete iNonNativeApplicationTypeArray[i].iNativeExecutable;
       
   360 
       
   361 	iNonNativeApplicationTypeArray.Close();
       
   362 
       
   363 	delete iRecognizerUnloadTimer;
       
   364 	iNonNativeApplicationTypeRegistry.Close();
       
   365 	}
       
   366 
       
   367 EXPORT_C void CApaAppArcServer::HandleInstallationStartEvent()
       
   368 	{
       
   369 	if ( iAppFsMonitor )
       
   370 		{
       
   371 		iAppFsMonitor->SetBlocked(ETrue);	
       
   372 		}
       
   373 	AppList().StopScan();
       
   374 	}
       
   375 
       
   376 EXPORT_C void CApaAppArcServer::HandleInstallationEndEventL()
       
   377 	{
       
   378 	if ( iAppFsMonitor )
       
   379 		{
       
   380 		iAppFsMonitor->SetBlocked(EFalse);	
       
   381 		}
       
   382 	AppList().RestartScanL();
       
   383 	}
       
   384 
       
   385 CSession2* CApaAppArcServer::NewSessionL(const TVersion& aVersion,const RMessage2&/* aMessage*/) const
       
   386 // Create a new server session.
       
   387 	{
       
   388 	// check we're the right version
       
   389 	TVersion v(KAppListServMajorVersionNumber, KAppListServMinorVersionNumber, KAppListServBuildVersionNumber);
       
   390 	if (!User::QueryVersionSupported(v,aVersion))
       
   391 		User::Leave(KErrNotSupported);
       
   392 	// make new session
       
   393 	return CApaAppArcServSession::NewL(const_cast<CApaAppArcServer&>(*this), const_cast<RFs&>(iFs));
       
   394 	}
       
   395 
       
   396 //
       
   397 // scanning code here
       
   398 //
       
   399 
       
   400 EXPORT_C TCallBack CApaAppArcServer::RescanCallBack()
       
   401 	{
       
   402 	return TCallBack(&AppFsNotifyWithForcedRegistrationsResetCallBack,this);
       
   403 	}
       
   404 
       
   405 TInt CApaAppArcServer::AppFsNotifyWithForcedRegistrationsResetCallBack(TAny* aPtr)
       
   406 	{
       
   407 	ASSERT(aPtr);
       
   408 	reinterpret_cast<CApaAppArcServer*>(aPtr)->AppList().ResetForcedRegistrations();
       
   409 	return AppFsNotifyCallBack(aPtr);
       
   410 	}
       
   411 
       
   412 TInt CApaAppArcServer::AppFsNotifyCallBack(TAny* aObject)
       
   413 	{
       
   414 	ASSERT(aObject);
       
   415 	reinterpret_cast<CApaAppArcServer*>(aObject)->UpdateApps();
       
   416 	return KErrNone;
       
   417 	}
       
   418 
       
   419 TInt CApaAppArcServer::PlugInNotifyCallBack(TAny* aObject)
       
   420 	{
       
   421 	//update the pre-Platform-security style  recognizers and rule-based plug-ins
       
   422 	ASSERT(aObject);
       
   423 	reinterpret_cast<CApaAppArcServer*>(aObject)->UpdatePlugIns();
       
   424 	return KErrNone;
       
   425 	}
       
   426 
       
   427 TInt CApaAppArcServer::TypeStoreNotifyCallback(TAny* aObject)
       
   428 	{
       
   429 	ASSERT(aObject);
       
   430 	reinterpret_cast<CApaAppArcServer*>(aObject)->UpdateTypeStore();
       
   431 	return KErrNone;
       
   432 	}
       
   433 
       
   434 void CApaAppArcServer::UpdateApps()
       
   435 // update the list
       
   436 	{
       
   437 	// File system change, rescan
       
   438 	TRAP_IGNORE(iAppList->StartIdleUpdateL (this));
       
   439 	}
       
   440 
       
   441 /*
       
   442 Updates application list with force registered applications.
       
   443 */
       
   444  
       
   445 void CApaAppArcServer::UpdateAppsByForceRegistration()
       
   446     {
       
   447     iForceRegistrationStatus|=EForceRegistrationRequested;
       
   448     UpdateApps();
       
   449     }
       
   450 
       
   451 void CApaAppArcServer::NotifyUpdate(TInt aReason)
       
   452 // tell all sessions to update their clients
       
   453 	{
       
   454 	// Updates the applist with the icon caption details from the Central Repository.
       
   455 	TRAP_IGNORE(iAppList->UpdateAppListByIconCaptionOverridesL());
       
   456 	// The short caption value sets through the API has got the highest precedence over the
       
   457 	// values found in either central repository or resource file.
       
   458 	TRAP_IGNORE(iAppList->UpdateAppListByShortCaptionL());
       
   459 
       
   460     //Delete any data mappings in service registry related to uninstalled applications.
       
   461     CArrayFixFlat<TUid>* uninstalledApps=iAppList->UninstalledAppArray();
       
   462     TBool modificationStatus=EFalse;
       
   463     TBool modified;
       
   464     
       
   465     if(uninstalledApps)
       
   466         {
       
   467         TInt count=uninstalledApps->Count();
       
   468         for(int index=0;index<count;index++)
       
   469             {
       
   470             modified=iMimeTypeToAppMappingsManager->DeleteApplicationDataMappings((*uninstalledApps)[index]);
       
   471         
       
   472             //Set modificationStatus if any data mapping is removed from the service registry
       
   473             if(modified)
       
   474                 modificationStatus=ETrue;
       
   475             }
       
   476         
       
   477         delete uninstalledApps;
       
   478         
       
   479         //If service registry is modified, store it to a file
       
   480         if(modificationStatus)
       
   481             TRAP_IGNORE(iMimeTypeToAppMappingsManager->StoreL());
       
   482         }
       
   483     
       
   484 	// iterate through sessions
       
   485 	iSessionIter.SetToFirst();
       
   486 	CApaAppArcServSession* ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   487 	while (ses!=NULL)
       
   488 		{
       
   489 		if(iForceRegistrationStatus & EForceRegistrationRequested)
       
   490             {
       
   491              //Notify clients about completion of force registration. 
       
   492             ses->NotifyScanComplete();
       
   493             }
       
   494 		else
       
   495             {
       
   496             ses->NotifyClients(aReason);
       
   497             }
       
   498 		ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   499 		}
       
   500 	
       
   501      if(iForceRegistrationStatus & EForceRegistrationRequested)
       
   502          {
       
   503          //If this function is called because of force registration, clear force registration request status and
       
   504         //set force registration applist change status
       
   505         iForceRegistrationStatus &= (~EForceRegistrationRequested);
       
   506          iForceRegistrationStatus |= EForceRegistrationAppListChanged;
       
   507          }
       
   508      else
       
   509          {
       
   510          //If this function is called not because of force registration, clear force registration applist change status. 
       
   511         iForceRegistrationStatus &= (~EForceRegistrationAppListChanged);        
       
   512          }
       
   513 	}
       
   514 
       
   515 void CApaAppArcServer::UpdatePlugIns()
       
   516 // update the pre-Platform-security style, ecom style recognizers and rule-based plug-ins
       
   517 	{
       
   518 	//we want the recognizers to be loaded either if:
       
   519 	// 1) they are not loaded on demand
       
   520 	// 2) they are loaded on demand and actively used
       
   521 	// 3) they are loaded on demand but waiting for the timer to be unloaded
       
   522 	if(!iLoadRecognizersOnDemand || iRecognizerUsageCount > 0 || (iRecognizerUnloadTimer && iRecognizerUnloadTimer->IsActive()))
       
   523 		{
       
   524 		TRAP_IGNORE(iMimeTypeRecognizer->LoadRecognizersL());
       
   525 		}
       
   526 	if (iRecognitionCache)
       
   527 		{	// RecognitionCache is flushed if there are any changes in plugins, i.e.,if:
       
   528 			// 1. New ECom Plugin is installed.
       
   529 			// 2. Existing ECom Plugin is uninstalled.
       
   530 		iRecognitionCache->Flush();
       
   531 		}
       
   532 
       
   533 	TRAP_IGNORE(iRuleBasedPlugIns->ScanForRuleBasedPlugInsL());
       
   534 	}
       
   535 
       
   536 void CApaAppArcServer::UpdateTypeStore()
       
   537 // Update the internal type store if things have changed
       
   538 	{
       
   539 	TRAP_IGNORE(DoUpdateTypeStoreL());
       
   540 	}
       
   541 
       
   542 void CApaAppArcServer::DoUpdateTypeStoreL()
       
   543 	{
       
   544 	TTime modified;
       
   545 	TInt err=iFs.Modified(iMimeTypeToAppMappingsManager->IniFileName(),modified);
       
   546 	// check the time stamp to see if we are interested in an update
       
   547 	if (modified>iTypeStoreModified && err==KErrNone)
       
   548 		{
       
   549 		CTypeStoreManager* manager=CTypeStoreManager::NewL(iFs);
       
   550 		CleanupStack::PushL(manager);
       
   551 		manager->RestoreL();
       
   552 		iTypeStoreModified=modified;
       
   553 		delete iMimeTypeToAppMappingsManager;
       
   554 		iMimeTypeToAppMappingsManager=manager;
       
   555 		CleanupStack::Pop(manager); 
       
   556 		}
       
   557 		
       
   558 	for (iSessionIter.SetToFirst(); ; iSessionIter++) //lint !e1757 prefix operator not defined for TDblQueIter
       
   559 		{
       
   560      	CSession2* const session=iSessionIter;
       
   561      	if (!session)
       
   562   			break;
       
   563 
       
   564      	static_cast<CApaAppArcServSession*>(session)->NotifyClientOfDataMappingChange();
       
   565 		}
       
   566 	}
       
   567 
       
   568 void CApaAppArcServer::HandleBackupOperationEventL(const TBackupOperationAttributes& aBackupOperationAttributes)
       
   569 //
       
   570 // Handle a signal from the backup server to indicate that a backup has started or finished.
       
   571 //
       
   572 	{
       
   573 	switch(aBackupOperationAttributes.iOperation)
       
   574 		{
       
   575 	case MBackupOperationObserver::ENone:
       
   576 	case MBackupOperationObserver::EAbort:
       
   577 		break;
       
   578 	case MBackupOperationObserver::EStart:
       
   579 		if ( iAppFsMonitor )
       
   580 			{
       
   581 			iAppFsMonitor->SetBlocked(ETrue);	
       
   582 			}
       
   583 		break;
       
   584 	case MBackupOperationObserver::EEnd:
       
   585 		if ( iAppFsMonitor )
       
   586 			{
       
   587 			iAppFsMonitor->SetBlocked(EFalse);	
       
   588 			}
       
   589 		break;
       
   590 	default:
       
   591 		Panic(EEventFromBackupObserverError);
       
   592 		break;
       
   593 		}
       
   594 	}
       
   595 
       
   596 void CApaAppArcServer::InitialListPopulationComplete()
       
   597 	{
       
   598 	if ( iAppFsMonitor )
       
   599 		{
       
   600 		iAppFsMonitor->SetBlocked(EFalse);	
       
   601 		}
       
   602 	
       
   603 	// notify clients (whoever is interested) that initial population of list is completed
       
   604 	iSessionIter.SetToFirst();
       
   605 	CApaAppArcServSession* ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   606 	// iterate through sessions
       
   607 	while (ses!=NULL)
       
   608 		{
       
   609 		ses->NotifyClientForCompletionOfListPopulation();	
       
   610 		ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   611 		}
       
   612 	}
       
   613 
       
   614 void CApaAppArcServer::RegisterNonNativeApplicationTypeL(TUid aApplicationType, const TDesC& aNativeExecutable)
       
   615 	{
       
   616 	for (TInt i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   617 		{
       
   618 		if (iNonNativeApplicationTypeArray[i].iTypeUid.iUid==aApplicationType.iUid)
       
   619 			User::Leave(KErrAlreadyExists);
       
   620 		}
       
   621 		
       
   622 	SNonNativeApplicationType nonNativeApplicationType;
       
   623 	nonNativeApplicationType.iTypeUid.iUid=aApplicationType.iUid;
       
   624 	nonNativeApplicationType.iNativeExecutable=aNativeExecutable.AllocLC();
       
   625 	iNonNativeApplicationTypeArray.AppendL(nonNativeApplicationType);
       
   626 	CleanupStack::Pop(nonNativeApplicationType.iNativeExecutable);
       
   627 	CleanupStack::PushL(TCleanupItem(DeleteLastNonNativeApplicationType, this));
       
   628 	ExternalizeNonNativeApplicationTypeArrayL();
       
   629 	CleanupStack::Pop(this); // the TCleanupItem
       
   630 	}
       
   631 
       
   632 void CApaAppArcServer::DeregisterNonNativeApplicationTypeL(TUid aApplicationType)
       
   633 	{
       
   634 	TInt i;
       
   635 	for (i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   636 		{
       
   637 		if (iNonNativeApplicationTypeArray[i].iTypeUid.iUid==aApplicationType.iUid)
       
   638 			break;
       
   639 		}
       
   640 		
       
   641 	if (i>=0)
       
   642 		{
       
   643 		ExternalizeNonNativeApplicationTypeArrayL(i);
       
   644 		delete iNonNativeApplicationTypeArray[i].iNativeExecutable;
       
   645 		iNonNativeApplicationTypeArray[i].iNativeExecutable = NULL;
       
   646 		iNonNativeApplicationTypeArray.Remove(i);
       
   647 		}
       
   648 	}
       
   649 
       
   650 void CApaAppArcServer::InternalizeNonNativeApplicationTypeArrayL()
       
   651 	{
       
   652 	RFile file;
       
   653 	CleanupClosePushL(file);
       
   654 	const TInt error=file.Open(iFs, iNonNativeApplicationTypeRegistry, EFileShareReadersOnly|EFileStream|EFileRead);
       
   655 	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)
       
   656 		{
       
   657 		RFileReadStream sourceStream;
       
   658 		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)
       
   659 		CleanupClosePushL(sourceStream);
       
   660 		TCardinality arrayCount;
       
   661 		arrayCount.InternalizeL(sourceStream);
       
   662 		for (TInt i=0; i<TInt(arrayCount); ++i)
       
   663 			{
       
   664 			SNonNativeApplicationType nonNativeApplicationType;
       
   665 			nonNativeApplicationType.iTypeUid.iUid=sourceStream.ReadUint32L();
       
   666 			nonNativeApplicationType.iNativeExecutable=HBufC::NewLC(sourceStream, KMaxFileName);
       
   667 			iNonNativeApplicationTypeArray.AppendL(nonNativeApplicationType);
       
   668 			CleanupStack::Pop(nonNativeApplicationType.iNativeExecutable);
       
   669 			}
       
   670 		CleanupStack::PopAndDestroy(&sourceStream);
       
   671 		}
       
   672 		
       
   673 	CleanupStack::PopAndDestroy(&file);
       
   674 	}
       
   675 
       
   676 void CApaAppArcServer::ExternalizeNonNativeApplicationTypeArrayL(TInt aIndexToIgnore/*=-1*/) const
       
   677 	{
       
   678 	RFs& fs=const_cast<RFs&>(iFs);
       
   679 	fs.MkDirAll(iNonNativeApplicationTypeRegistry); // ignore any error
       
   680 	RFile file;
       
   681 	CleanupClosePushL(file);
       
   682 	User::LeaveIfError(file.Replace(fs, iNonNativeApplicationTypeRegistry, EFileShareExclusive|EFileStream|EFileWrite));
       
   683 	RFileWriteStream targetStream;
       
   684 	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)
       
   685 	CleanupClosePushL(targetStream);
       
   686 	const TInt arrayCount(iNonNativeApplicationTypeArray.Count());
       
   687 	TInt arrayCountToExternalize=arrayCount;
       
   688 	if (aIndexToIgnore>=0)
       
   689 		--arrayCountToExternalize;
       
   690 
       
   691 	TCardinality(arrayCountToExternalize).ExternalizeL(targetStream);
       
   692 	for (TInt i=0; i<arrayCount; ++i)
       
   693 		{
       
   694 		if (i!=aIndexToIgnore)
       
   695 			{
       
   696 			const SNonNativeApplicationType& nonNativeApplicationType=iNonNativeApplicationTypeArray[i];
       
   697 			targetStream.WriteUint32L(nonNativeApplicationType.iTypeUid.iUid);
       
   698 			targetStream << *nonNativeApplicationType.iNativeExecutable;
       
   699 			}
       
   700 		}
       
   701 		
       
   702 	targetStream.CommitL();
       
   703 	CleanupStack::PopAndDestroy(2, &file);
       
   704 	}
       
   705 
       
   706 TPtrC CApaAppArcServer::NativeExecutableL(TUid aNonNativeApplicationType) const
       
   707 	{
       
   708 	for (TInt i=iNonNativeApplicationTypeArray.Count()-1; i>=0; --i)
       
   709 		{
       
   710 		const SNonNativeApplicationType& nonNativeApplicationType=iNonNativeApplicationTypeArray[i];
       
   711 		if (nonNativeApplicationType.iTypeUid.iUid==aNonNativeApplicationType.iUid)
       
   712 			return *nonNativeApplicationType.iNativeExecutable;
       
   713 		}
       
   714 		
       
   715 	User::Leave(KErrNotSupported); // not KErrNotFound
       
   716 	return KNullDesC();
       
   717 	}
       
   718 
       
   719 void CApaAppArcServer::DeleteLastNonNativeApplicationType(TAny* aThis)
       
   720 	{ // static
       
   721 	CApaAppArcServer& self=*static_cast<CApaAppArcServer*>(aThis);
       
   722 	const TInt arrayIndex=self.iNonNativeApplicationTypeArray.Count()-1;
       
   723 	delete self.iNonNativeApplicationTypeArray[arrayIndex].iNativeExecutable;
       
   724 	self.iNonNativeApplicationTypeArray[arrayIndex].iNativeExecutable = NULL;
       
   725 	self.iNonNativeApplicationTypeArray.Remove(arrayIndex);
       
   726 	}
       
   727 
       
   728 void CApaAppArcServer::NotifyScanComplete()
       
   729 	{
       
   730 	// Updates the applist with the icon caption details from the Central Repository.
       
   731 	TRAP_IGNORE(iAppList->UpdateAppListByIconCaptionOverridesL());
       
   732 	// The short caption value sets through the API has got the highest precedence over the
       
   733 	// values found in either central repository or resource file.		
       
   734 	TRAP_IGNORE(iAppList->UpdateAppListByShortCaptionL());
       
   735 
       
   736 	// iterate through sessions
       
   737 	iSessionIter.SetToFirst();
       
   738 	CApaAppArcServSession* ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   739 	while (ses)
       
   740 		{
       
   741 		if((iForceRegistrationStatus & EForceRegistrationRequested) ||
       
   742 	            !(iForceRegistrationStatus & EForceRegistrationAppListChanged))
       
   743 		    {
       
   744 		    //Notify clients about completion of force registration or scan completion		
       
   745 		    ses->NotifyScanComplete();
       
   746 		    }
       
   747 		else
       
   748 		    {
       
   749 		    //If force registration changes applicaiton list,
       
   750 		    // then notify applist change to clients.
       
   751 		    ses->NotifyClients(MApaAppListServObserver::EAppListChanged);
       
   752 		    }		
       
   753 		ses=static_cast<CApaAppArcServSession*>(&(*iSessionIter++));
       
   754 		}
       
   755 	if(!(iForceRegistrationStatus & EForceRegistrationRequested))
       
   756 	    {
       
   757 	    //If this function is called not because of force registration, 
       
   758 	    //clear force registration applist change status. 
       
   759             iForceRegistrationStatus &= (~EForceRegistrationAppListChanged);	        
       
   760 	    }
       
   761 	//Clear force registration request status
       
   762         iForceRegistrationStatus &= (~EForceRegistrationRequested);
       
   763 	}
       
   764 
       
   765 /*
       
   766  * Data Recognizer calls
       
   767  */
       
   768  
       
   769 TBool CApaAppArcServer::CachedRecognitionResult(const TParseBase& aParser, TDataRecognitionResult& aResult) const
       
   770 	{
       
   771 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   772 		return iRecognitionCache->Get(aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   773 
       
   774 	return EFalse;
       
   775 	}
       
   776 
       
   777 /**
       
   778 N.B. The @c CRecognitionResult object is reference counted so it must be closed!
       
   779 */
       
   780 CRecognitionResult* CApaAppArcServer::CachedRecognitionResult(const RFile& aFile, const TParseBase& aParser) const
       
   781 	{
       
   782 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   783 		return iRecognitionCache->Get(aFile, aParser.DriveAndPath(), aParser.NameAndExt());
       
   784 
       
   785 	return NULL;
       
   786 	}
       
   787 
       
   788 void CApaAppArcServer::CacheRecognitionResultL(const TParseBase& aParser, const TDataRecognitionResult& aResult)
       
   789 	{
       
   790 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   791 		iRecognitionCache->AddL(aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   792 	}
       
   793 
       
   794 void CApaAppArcServer::CacheRecognitionResultL(const RFile& aFile, const TParseBase& aParser, const TDataRecognitionResult& aResult)
       
   795 	{
       
   796 	if(iRecognitionCache && aParser.PathPresent() && aParser.NamePresent())
       
   797 		{
       
   798 		iRecognitionCache->AddL(aFile, aParser.DriveAndPath(), aParser.NameAndExt(), aResult);
       
   799 		}
       
   800 	}
       
   801 
       
   802 TDataRecognitionResult CApaAppArcServer::RecognizeDataL(const TDesC& aName, const TDesC8& aBuffer)
       
   803 	{
       
   804 	TParsePtrC parser(iFs.IsValidName(aName) ? aName : KNullDesC);
       
   805 	TDataRecognitionResult result;
       
   806 	
       
   807 	// check cache	
       
   808 	if(!CachedRecognitionResult(parser, result))
       
   809 		{
       
   810 		// recognize
       
   811 		if(iLoadRecognizersOnDemand)
       
   812 			LoadRecognizersLC();
       
   813 
       
   814 		result = iMimeTypeRecognizer->RecognizeL(aName, aBuffer);
       
   815 		if(iLoadRecognizersOnDemand)
       
   816 			CleanupStack::PopAndDestroy();
       
   817 
       
   818 		// add to cache
       
   819 		CacheRecognitionResultL(parser, result);
       
   820 		}
       
   821 	
       
   822 	return result;	
       
   823 	}
       
   824 
       
   825 TDataRecognitionResult CApaAppArcServer::RecognizeDataL(RFile& aFile, TInt aPreferredBufSize)
       
   826 	{
       
   827 	CRecognitionResult* result = RecognizeDataAsCRecognitionResultL(aFile, aPreferredBufSize);
       
   828 	TDataRecognitionResult ret;
       
   829 	result->Get(ret);
       
   830 	result->Close();
       
   831 	return ret;
       
   832 	}
       
   833 
       
   834 /**
       
   835 Same as @c RecognizeDataL(RFile&, TInt) but returns a @c CRecognitionResult 
       
   836 instead of a @c TDataRecognitionResult.
       
   837 
       
   838 N.B. The @c CRecognitionResult object is reference counted so it must be closed!
       
   839 */
       
   840 CRecognitionResult* CApaAppArcServer::RecognizeDataAsCRecognitionResultL(RFile& aFile, TInt aPreferredBufSize)
       
   841 	{
       
   842 	CRecognitionResult* result = NULL;
       
   843 	
       
   844 	TFileName fileName;
       
   845 	User::LeaveIfError(aFile.FullName(fileName));
       
   846 	TParsePtrC parser(fileName); //fileName is valid since it comes from RFile
       
   847 
       
   848 	//check cache
       
   849 	result = CachedRecognitionResult(aFile,parser);
       
   850 	if(!result)
       
   851 		{
       
   852 		// recognize
       
   853 		if(iLoadRecognizersOnDemand)
       
   854 			LoadRecognizersLC();
       
   855 
       
   856 		const TDataRecognitionResult recResult = iMimeTypeRecognizer->RecognizeL(aFile, aPreferredBufSize);
       
   857 		if(iLoadRecognizersOnDemand)
       
   858 			CleanupStack::PopAndDestroy();
       
   859 	
       
   860 		//add to cache
       
   861 		CacheRecognitionResultL(aFile, parser, recResult);
       
   862 
       
   863 		result = CRecognitionResult::NewL(parser.NameAndExt(), recResult);
       
   864 		}
       
   865 	
       
   866 	return result;
       
   867 	}
       
   868 
       
   869 TBool CApaAppArcServer::RecognizeDataL(const TDesC& aName, const TDesC8& aBuffer, const TDataType& aDataType)
       
   870 	{
       
   871 	if(iLoadRecognizersOnDemand)
       
   872 		LoadRecognizersLC();
       
   873 
       
   874 	const TBool ret = iMimeTypeRecognizer->RecognizeL(aName,aBuffer,aDataType);
       
   875 	if(iLoadRecognizersOnDemand)
       
   876 		CleanupStack::PopAndDestroy();
       
   877 
       
   878 	return ret;
       
   879 	}
       
   880 
       
   881 TBool CApaAppArcServer::RecognizeDataL(RFile& aFile, TInt aPreferredBufSize, const TDataType& aDataType)
       
   882 	{
       
   883 	if(iLoadRecognizersOnDemand)
       
   884 		LoadRecognizersLC();
       
   885 
       
   886 	const TBool ret = iMimeTypeRecognizer->RecognizeL(aFile,aPreferredBufSize,aDataType);
       
   887 	if(iLoadRecognizersOnDemand)
       
   888 		CleanupStack::PopAndDestroy();
       
   889 
       
   890 	return ret;
       
   891 	}
       
   892 
       
   893 TInt CApaAppArcServer::DataRecognizerPreferredBufSizeL()
       
   894 	{
       
   895 	if(iLoadRecognizersOnDemand)
       
   896 		LoadRecognizersLC();
       
   897 
       
   898 	const TInt ret = iMimeTypeRecognizer->PreferredBufSize();
       
   899 	if(iLoadRecognizersOnDemand)
       
   900 		CleanupStack::PopAndDestroy();
       
   901 
       
   902 	return ret;
       
   903 	}
       
   904 
       
   905 void CApaAppArcServer::DataTypeL(CDataTypeArray& aArray)
       
   906 	{
       
   907 	if(iLoadRecognizersOnDemand)
       
   908 		LoadRecognizersLC();
       
   909 
       
   910 	iMimeTypeRecognizer->DataTypeL(aArray);
       
   911 	if(iLoadRecognizersOnDemand)
       
   912 		CleanupStack::PopAndDestroy();
       
   913 	}
       
   914 
       
   915 /*
       
   916  * Recognizer loading/unloading code
       
   917  */
       
   918 
       
   919 void CApaAppArcServer::LoadRecognizersLC()
       
   920 	{
       
   921 	ASSERT(iLoadRecognizersOnDemand);
       
   922 
       
   923 	LoadRecognizersL();
       
   924 	TCleanupItem cleanup(CApaAppArcServer::RecognizerCleanup, this);
       
   925 	CleanupStack::PushL(cleanup);
       
   926 	}
       
   927 
       
   928 void CApaAppArcServer::RecognizerCleanup(TAny* aSelf)
       
   929 	{
       
   930 	if (aSelf)
       
   931 		{
       
   932 		static_cast<CApaAppArcServer*>(aSelf)->UnloadRecognizers();
       
   933 		}
       
   934 	}
       
   935 
       
   936 void CApaAppArcServer::LoadRecognizersL()
       
   937 	{
       
   938 	ASSERT(iLoadRecognizersOnDemand);
       
   939 
       
   940 	if(iRecognizerUnloadTimer->IsActive())
       
   941 		{
       
   942 		__ASSERT_DEBUG(iRecognizerUsageCount==0,Panic(EReferenceCountingError1));
       
   943 		iRecognizerUnloadTimer->Cancel();
       
   944 		}
       
   945 	else if(iRecognizerUsageCount==0)
       
   946 		{
       
   947 		iMimeTypeRecognizer->LoadRecognizersL();
       
   948 		}
       
   949 
       
   950 	++iRecognizerUsageCount;
       
   951 	}
       
   952 
       
   953 TInt CApaAppArcServer::UnloadRecognizers()
       
   954 	{
       
   955 	ASSERT(iLoadRecognizersOnDemand);
       
   956 
       
   957 	--iRecognizerUsageCount;
       
   958 	__ASSERT_DEBUG(iRecognizerUsageCount>=0,Panic(EReferenceCountingError2));
       
   959 	if (iRecognizerUsageCount==0)
       
   960 		{
       
   961 		iRecognizerUnloadTimer->Start(KApaUnloadRecognizersTimeout,0,TCallBack(CApaAppArcServer::DoUnloadRecognizersCallback,this));
       
   962 		}
       
   963 	return KErrNone;
       
   964 	}
       
   965 	
       
   966 TInt CApaAppArcServer::DoUnloadRecognizersCallback(TAny* aSelf)
       
   967 	{
       
   968 	TInt ret=KErrNone;
       
   969 	if (aSelf)
       
   970 		{
       
   971 		ret = static_cast<CApaAppArcServer*>(aSelf)->DoUnloadRecognizers();
       
   972 		}
       
   973 	return ret;
       
   974 	}
       
   975 
       
   976 TInt CApaAppArcServer::DoUnloadRecognizers()
       
   977 	{
       
   978 	ASSERT(iLoadRecognizersOnDemand);
       
   979 
       
   980 	// need to cancel the periodic timer since we only want a oneshot timer
       
   981 	iRecognizerUnloadTimer->Cancel();
       
   982 	iMimeTypeRecognizer->UnloadRecognizers();
       
   983 	return KErrNone;
       
   984 	}
       
   985 	
       
   986 void CApaAppArcServer::GetAppForMimeType(const TDataType& aDataType, TUid& aUid) const
       
   987 	{
       
   988 	iMimeTypeToAppMappingsManager->GetAppByDataType(aDataType, aUid);
       
   989 	}
       
   990 	
       
   991 void CApaAppArcServer::GetAppForMimeType(const TDataType& aDataType, TUid aServiceUid, TUid& aUid) const
       
   992 	{
       
   993 	iMimeTypeToAppMappingsManager->GetAppByDataType(aDataType, aServiceUid, aUid);
       
   994 	}
       
   995 	
       
   996 TBool CApaAppArcServer::InsertAndStoreIfHigherL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid)
       
   997 	{
       
   998 	return iMimeTypeToAppMappingsManager->InsertAndStoreIfHigherL(aDataType, aPriority, aUid);
       
   999 	}
       
  1000 	
       
  1001 void CApaAppArcServer::InsertAndStoreDataMappingL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid, TUid aServiceUid)
       
  1002 	{
       
  1003 	iMimeTypeToAppMappingsManager->InsertAndStoreDataMappingL(aDataType, aPriority, aUid, aServiceUid);
       
  1004 	}
       
  1005 	
       
  1006 void CApaAppArcServer::DeleteAndStoreDataMappingL(const TDataType& aDataType, TUid aServiceUid)
       
  1007 	{
       
  1008 	iMimeTypeToAppMappingsManager->DeleteAndStoreDataMappingL(aDataType, aServiceUid);
       
  1009 	}
       
  1010 
       
  1011 TBool CApaAppArcServer::LoadMbmIconsOnDemand() const
       
  1012 	{
       
  1013 	return iLoadMbmIconsOnDemand;
       
  1014 	}
       
  1015 
       
  1016 #ifdef _DEBUG
       
  1017 
       
  1018 /**
       
  1019 Flushes the recognition cache.
       
  1020 
       
  1021 Useful for debugging.
       
  1022 */
       
  1023 void CApaAppArcServer::FlushRecognitionCache()
       
  1024 	{
       
  1025 	if(iRecognitionCache)
       
  1026 		iRecognitionCache->Flush();
       
  1027 	}
       
  1028 
       
  1029 /**
       
  1030 Sets whether or not recognizers should be loaded when they are needed.
       
  1031 
       
  1032 Useful for debugging.
       
  1033 */	
       
  1034 void CApaAppArcServer::SetLoadRecognizersOnDemandL(TBool aLoadRecognizersOnDemand)
       
  1035 	{
       
  1036 	if(iLoadRecognizersOnDemand == aLoadRecognizersOnDemand)
       
  1037 		return;
       
  1038 	
       
  1039 	CPeriodic* newUnloadTimer;
       
  1040 	if(aLoadRecognizersOnDemand)
       
  1041 		{
       
  1042 		ASSERT(!iRecognizerUnloadTimer);
       
  1043 		newUnloadTimer = CPeriodic::NewL(EPriorityNormal);
       
  1044 		}
       
  1045 	else
       
  1046 		{
       
  1047 		ASSERT(iRecognizerUnloadTimer);
       
  1048 		newUnloadTimer = NULL;
       
  1049 		}
       
  1050 	CleanupStack::PushL(newUnloadTimer);
       
  1051 	
       
  1052 	CApaScanningDataRecognizer* newMimeTypeRecognizer = CApaScanningDataRecognizer::NewL(iFs,!aLoadRecognizersOnDemand);
       
  1053 	delete iMimeTypeRecognizer;
       
  1054 	iMimeTypeRecognizer = newMimeTypeRecognizer;
       
  1055 	
       
  1056 	delete iRecognizerUnloadTimer;
       
  1057 	iRecognizerUnloadTimer = newUnloadTimer;
       
  1058 	CleanupStack::Pop(newUnloadTimer);
       
  1059 	
       
  1060 	iRecognizerUsageCount = 0;
       
  1061 	iLoadRecognizersOnDemand = aLoadRecognizersOnDemand;	
       
  1062 	}
       
  1063 
       
  1064 /**
       
  1065 If recognizers are set to be loaded on demand this method can be used to perform
       
  1066 the unloading synchronously, instead of waiting for the unloading timer to go off.
       
  1067 
       
  1068 Useful for debugging.
       
  1069 */
       
  1070 void CApaAppArcServer::PerformOutstandingRecognizerUnloading()
       
  1071 	{
       
  1072 	if(iLoadRecognizersOnDemand && iRecognizerUnloadTimer->IsActive())
       
  1073 		{
       
  1074 		__ASSERT_DEBUG(iRecognizerUsageCount==0,Panic(EReferenceCountingError3));
       
  1075 		DoUnloadRecognizers();
       
  1076 		}
       
  1077 	}
       
  1078 
       
  1079 #endif //_DEBUG
       
  1080