sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "DATASTOR.H" sl@0: #include "APMPAN.H" sl@0: sl@0: const TUid KOpenServiceUid = { 0x10208DCA }; sl@0: sl@0: const TInt KAppMappingGranularity=1; sl@0: // sl@0: // class TMappingDataTypeToApp sl@0: // sl@0: sl@0: EXPORT_C TMappingDataTypeToApp::TMappingDataTypeToApp() sl@0: :iDataType(TDataType(_L8(""))), iServiceUid(KOpenServiceUid) sl@0: { sl@0: iAppUid.iUid=0; sl@0: } sl@0: sl@0: EXPORT_C TMappingDataTypeToApp::TMappingDataTypeToApp(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aAppUid) sl@0: :iDataType(aDataType), sl@0: iPriority(aPriority), sl@0: iAppUid(aAppUid), sl@0: iServiceUid(KOpenServiceUid) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TMappingDataTypeToApp::TMappingDataTypeToApp(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aAppUid, TUid aServiceUid) sl@0: :iDataType(aDataType), sl@0: iPriority(aPriority), sl@0: iAppUid(aAppUid), sl@0: iServiceUid(aServiceUid) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C void TMappingDataTypeToApp::InternalizeL(RReadStream& aStream) sl@0: { sl@0: aStream >> iDataType; sl@0: iPriority=aStream.ReadInt32L(); sl@0: iAppUid.iUid=aStream.ReadInt32L(); sl@0: iServiceUid.iUid=aStream.ReadInt32L(); sl@0: } sl@0: sl@0: EXPORT_C void TMappingDataTypeToApp::ExternalizeL(RWriteStream& aStream) const sl@0: { sl@0: aStream << iDataType; sl@0: aStream.WriteInt32L(iPriority); sl@0: aStream.WriteInt32L(iAppUid.iUid); sl@0: aStream.WriteInt32L(iServiceUid.iUid); sl@0: } sl@0: sl@0: sl@0: // sl@0: // class CTypeStoreManager sl@0: // sl@0: sl@0: EXPORT_C void CTypeStoreManager::InternalizeL(RReadStream& aStream) sl@0: /** Internalises the array of data type mappings from a read stream. sl@0: sl@0: @param aStream Stream from which the data type mappings are internalised. */ sl@0: { sl@0: aStream >> iAppMappings; sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::ExternalizeL(RWriteStream& aStream) const sl@0: /** Externalises the data type mappings to a write stream. sl@0: sl@0: @param aStream Stream to which the data type mappings should be externalised. */ sl@0: { sl@0: aStream << iAppMappings; sl@0: } sl@0: sl@0: EXPORT_C CTypeStoreManager* CTypeStoreManager::NewL(RFs& aFs) sl@0: /** Constructs a CTypeStoreManager object. sl@0: sl@0: @param aFs A session with the file server. sl@0: @return The newly created CTypeStoreManager object. */ sl@0: { sl@0: CTypeStoreManager* self = new(ELeave) CTypeStoreManager(aFs); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return (self); sl@0: } sl@0: sl@0: void CTypeStoreManager::ConstructL() sl@0: { sl@0: TChar sysDrive = RFs::GetSystemDriveChar(); sl@0: TInt maxSizeOfFileName = KIniFileName().Length() + 1; sl@0: iIniFileName.CreateL(maxSizeOfFileName); sl@0: iIniFileName.Append(sysDrive); sl@0: iIniFileName.Append(KIniFileName()); sl@0: } sl@0: CTypeStoreManager::CTypeStoreManager(RFs& aFs) sl@0: : iAppMappings(KAppMappingGranularity), sl@0: iFs(aFs) sl@0: { sl@0: __ASSERT_ALWAYS(RProcess().SecureId()==0x10003a3f, Panic(EPanicNotBeingUsedFromWithinApparcServerProcess)); sl@0: } sl@0: sl@0: EXPORT_C CTypeStoreManager::~CTypeStoreManager() sl@0: /** Destructor. */ sl@0: { sl@0: iIniFileName.Close(); sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::StoreL() sl@0: /** Stores the data type mappings to the data store ini file sl@0: (c:\\System\\Data\\Dtstor.ini), creating a new ini file if it does sl@0: not already exist. */ sl@0: { sl@0: CDictionaryStore* iniFile=OpenIniFileLC(); sl@0: iniFile->RemoveL(KUidDatastorSettings); sl@0: RDictionaryWriteStream outStream; sl@0: outStream.AssignLC(*iniFile,KUidDatastorSettings); sl@0: outStream << *this; sl@0: outStream.CommitL(); sl@0: CleanupStack::PopAndDestroy(); sl@0: iniFile->CommitL(); sl@0: CleanupStack::PopAndDestroy(); // inifile sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::RestoreL() sl@0: /** Restores the data type mappings from the data store ini file. */ sl@0: { sl@0: CDictionaryStore* iniFile=OpenIniFileLC(); sl@0: RDictionaryReadStream inStream; sl@0: inStream.OpenLC(*iniFile,KUidDatastorSettings); sl@0: inStream >> *this; sl@0: CleanupStack::PopAndDestroy(2); // inStream * iniFile sl@0: } sl@0: sl@0: /** Changes an existing data type mapping, or adds a new one. sl@0: sl@0: If the data type does not exist in the store, the new mapping is appended. sl@0: If the data type does exist, its mapping is replaced. sl@0: sl@0: The service is considered to be the KOpenServiceUid service. sl@0: sl@0: @param aDataType A new or existing data type. sl@0: @param aPriority The priority with which the application handles the data type. sl@0: @param aUid The UID of the application to associate with the data type. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::InsertDataMappingL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid) sl@0: { sl@0: InsertDataMappingL(aDataType, aPriority, aUid, KOpenServiceUid); sl@0: } sl@0: sl@0: /** Changes an existing data type mapping, or adds a new one. sl@0: sl@0: If the data type does not exist in the store, the new mapping is appended. sl@0: If the data type does exist, its mapping is replaced. sl@0: sl@0: @param aDataType A new or existing data type. sl@0: @param aPriority The priority with which the application handles the data type. sl@0: @param aUid The UID of the application to associate with the data type. sl@0: @param aServiceUid The UID of the service. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::InsertDataMappingL(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aUid, TUid aServiceUid) sl@0: { sl@0: TInt i = FindDataMapping(aDataType, aServiceUid); sl@0: if ( i == KErrNotFound ) sl@0: iAppMappings.AppendL( TMappingDataTypeToApp( aDataType, aPriority, aUid, aServiceUid ) ); sl@0: else sl@0: { sl@0: TMappingDataTypeToApp& mapping = iAppMappings[i]; sl@0: mapping.iDataType=aDataType; sl@0: mapping.iPriority=aPriority; sl@0: mapping.iAppUid=aUid; sl@0: mapping.iServiceUid=aServiceUid; sl@0: } sl@0: } sl@0: sl@0: /** Changes an existing data type mapping, or adds a new one. sl@0: If the data type does not exist in the store, or if it does and its existing priority sl@0: is less than aPriority, the new mapping is added to the store, or replaces the existing one. sl@0: Otherwise, no change is made. sl@0: sl@0: The service is considered to be the KOpenServiceUid service. sl@0: sl@0: @param aDataType A new or existing data type. sl@0: @param aPriority The priority with which the application handles the data type. sl@0: @param aUid The UID of the application to associate with the data type. sl@0: @return ETrue if the new mapping was added or an existing mapping replaced, EFalse if no sl@0: change was made. sl@0: */ sl@0: EXPORT_C TBool CTypeStoreManager::InsertIfHigherL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid) sl@0: { sl@0: return InsertIfHigherL(aDataType, aPriority, aUid, KOpenServiceUid); sl@0: } sl@0: sl@0: /** Changes an existing data type mapping, or adds a new one. sl@0: If the data type does not exist in the store, or if it does and its existing priority sl@0: is less than aPriority, the new mapping is added to the store, or replaces the existing one. sl@0: Otherwise, no change is made. sl@0: sl@0: @param aDataType A new or existing data type. sl@0: @param aPriority The priority with which the application handles the data type. sl@0: @param aUid The UID of the application to associate with the data type. sl@0: @param aServiceUid The UID of the service. sl@0: @return ETrue if the new mapping was added or an existing mapping replaced, EFalse if no sl@0: change was made. sl@0: */ sl@0: EXPORT_C TBool CTypeStoreManager::InsertIfHigherL(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aUid, TUid aServiceUid) sl@0: { sl@0: TInt i = FindDataMapping( aDataType, aServiceUid ); sl@0: if ( i == KErrNotFound || iAppMappings[i].iPriority < aPriority ) sl@0: { sl@0: InsertDataMappingL( aDataType, aPriority, aUid, aServiceUid ); sl@0: return ETrue; sl@0: } sl@0: else sl@0: return EFalse; sl@0: } sl@0: sl@0: /** Removes an existing data type mapping from the store. sl@0: sl@0: The service is considered to be the KOpenServiceUid service. sl@0: sl@0: @param aDataType Data type whose mapping should be removed. sl@0: @panic USER 0 The specified data type cannot be found. Debug builds only. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::DeleteDataMapping(const TDataType& aDataType) sl@0: { sl@0: DeleteDataMapping(aDataType, KOpenServiceUid); sl@0: } sl@0: sl@0: /** Removes an existing data type mapping from the store. sl@0: sl@0: @param aDataType Data type whose mapping should be removed. sl@0: @param aServiceUid The UID of the service. sl@0: @panic USER 0 The specified data type cannot be found. Debug builds only. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::DeleteDataMapping(const TDataType& aDataType, sl@0: TUid aServiceUid) sl@0: { sl@0: TInt i=FindDataMapping(aDataType, aServiceUid); sl@0: __ASSERT_DEBUG(i!=KErrNotFound,User::Invariant()); sl@0: iAppMappings.Delete(i); sl@0: } sl@0: sl@0: /** Gets the UID of the application mapped to the specified data type. sl@0: sl@0: The service is considered to be the KOpenServiceUid service. sl@0: sl@0: @param aDataType The data type. sl@0: @param aUid On return, the UID of the application associated with the sl@0: data type, or KNullUid if the data type is not found. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::GetAppByDataType(const TDataType& aDataType, TUid& aUid) const sl@0: { sl@0: GetAppByDataType(aDataType, KOpenServiceUid, aUid); sl@0: } sl@0: sl@0: /** Gets the UID of the application mapped to the specified data type. sl@0: sl@0: The service is considered to be the KOpenServiceUid service. sl@0: sl@0: @param aDataType The data type. sl@0: @param aServiceUid The UID of the service. sl@0: @param aUid On return, the UID of the application associated with the sl@0: data type, or KNullUid if the data type is not found. sl@0: */ sl@0: EXPORT_C void CTypeStoreManager::GetAppByDataType(const TDataType& aDataType, sl@0: TUid aServiceUid, TUid& aUid) const sl@0: { sl@0: TInt i=FindDataMapping(aDataType, aServiceUid); sl@0: aUid=(i==KErrNotFound? KNullUid : iAppMappings[i].iAppUid); sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::GetDataTypesByAppL(TUid aUid, CArrayFix<TDataType>* aTypeArray) const sl@0: /** Populates an array with all the data types supported by the specified application. sl@0: sl@0: If the specified UID is zero, the array is populated with all the data types found in sl@0: the store. sl@0: sl@0: @param aUid An application UID. sl@0: @param aTypeArray An empty array. On return, contains all data types supported by the sl@0: application. sl@0: @panic APMIME 5 The array is NULL. sl@0: @panic APMIME 6 The array passed to the function is not empty. Debug builds only. */ sl@0: { sl@0: __ASSERT_ALWAYS(aTypeArray,Panic(EInvalidArgument)); sl@0: __ASSERT_DEBUG(!aTypeArray->Count(),Panic(EArrayNotEmpty)); sl@0: TInt count=iAppMappings.Count(); sl@0: for (TInt i=0; i<count; i++) sl@0: { sl@0: if ((iAppMappings[i].iAppUid==aUid || aUid.iUid==0) && sl@0: (iAppMappings[i].iServiceUid == KOpenServiceUid)) sl@0: { sl@0: aTypeArray->AppendL(iAppMappings[i].iDataType); sl@0: } sl@0: } sl@0: } sl@0: sl@0: EXPORT_C const CArrayFixFlat<TMappingDataTypeToApp>& CTypeStoreManager::MappingArray() const sl@0: /** Returns the array of data type mappings. sl@0: sl@0: @return The array of data type mappings. */ sl@0: { sl@0: return iAppMappings; sl@0: } sl@0: sl@0: TInt CTypeStoreManager::FindDataMapping(const TDataType& aDataType, sl@0: const TUid& aServiceUid) const sl@0: { sl@0: TInt count=iAppMappings.Count(); sl@0: for (TInt i=0; i<count; i++) sl@0: { sl@0: // Match the pattern at the start of the mime type sl@0: if ((iAppMappings[i].iDataType.Des8().Match(aDataType.Des8())==0) && sl@0: (iAppMappings[i].iServiceUid == aServiceUid)) sl@0: { sl@0: return i; sl@0: } sl@0: } sl@0: return KErrNotFound; sl@0: } sl@0: sl@0: CDictionaryStore* CTypeStoreManager::OpenIniFileLC() const sl@0: // Open dtstor's ini file - will create a new one if it doesn't exist or is corrupted sl@0: { sl@0: const TPtrC iniFileName(IniFileName()); sl@0: TInt err=iFs.MkDirAll(iniFileName); sl@0: if(err!=KErrAlreadyExists) sl@0: { sl@0: User::LeaveIfError(err); sl@0: } sl@0: CDictionaryStore* iniFile=NULL; sl@0: TRAP(err,iniFile=CDictionaryFileStore::OpenL(iFs,iniFileName,KUidDatastor)); sl@0: if (err==KErrNone) sl@0: { sl@0: CleanupStack::PushL(iniFile); sl@0: } sl@0: else if (err==KErrEof || err==KErrCorrupt) sl@0: { sl@0: User::LeaveIfError(iFs.Delete(iniFileName)); sl@0: iniFile=CDictionaryFileStore::OpenLC(iFs,iniFileName,KUidDatastor); sl@0: err=KErrNone; sl@0: } sl@0: User::LeaveIfError(err); sl@0: return iniFile; sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::InsertAndStoreDataMappingL(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aUid) sl@0: { sl@0: InsertAndStoreDataMappingL(aDataType, aPriority, aUid, KOpenServiceUid); sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::InsertAndStoreDataMappingL(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aUid, TUid aServiceUid) sl@0: { sl@0: InsertDataMappingL(aDataType, aPriority, aUid, aServiceUid); sl@0: TRAPD(ret,StoreL()); sl@0: if(ret!=KErrNone) sl@0: { sl@0: DeleteDataMapping(aDataType, aServiceUid); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C TBool CTypeStoreManager::InsertAndStoreIfHigherL(const TDataType& aDataType, TDataTypePriority aPriority, TUid aUid) sl@0: { sl@0: return InsertAndStoreIfHigherL(aDataType, aPriority, aUid, KOpenServiceUid); sl@0: } sl@0: sl@0: EXPORT_C TBool CTypeStoreManager::InsertAndStoreIfHigherL(const TDataType& aDataType, sl@0: TDataTypePriority aPriority, TUid aUid, TUid aServiceUid) sl@0: { sl@0: TInt i = FindDataMapping( aDataType, aServiceUid ); sl@0: if ( i == KErrNotFound || iAppMappings[i].iPriority < aPriority ) sl@0: { sl@0: InsertAndStoreDataMappingL( aDataType, aPriority, aUid, aServiceUid ); sl@0: return ETrue; sl@0: } sl@0: else sl@0: return EFalse; sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::DeleteAndStoreDataMappingL(const TDataType& aDataType) sl@0: { sl@0: DeleteAndStoreDataMappingL(aDataType, KOpenServiceUid); sl@0: } sl@0: sl@0: EXPORT_C void CTypeStoreManager::DeleteAndStoreDataMappingL(const TDataType& aDataType, sl@0: TUid aServiceUid) sl@0: { sl@0: TInt i=FindDataMapping(aDataType, aServiceUid); sl@0: __ASSERT_DEBUG(i!=KErrNotFound,User::Invariant()); sl@0: TMappingDataTypeToApp mapping (iAppMappings[i].iDataType,iAppMappings[i].iPriority,iAppMappings[i].iAppUid,iAppMappings[i].iServiceUid); sl@0: iAppMappings.Delete(i); sl@0: TRAPD(ret,StoreL()); sl@0: if(ret!=KErrNone) sl@0: { sl@0: iAppMappings.InsertL(i,mapping); sl@0: } sl@0: } sl@0: sl@0: //Removes data mappings related to aAppUid sl@0: //Returns modification status of service registry sl@0: EXPORT_C TBool CTypeStoreManager::DeleteApplicationDataMappings(const TUid aAppUid) sl@0: { sl@0: TInt count=iAppMappings.Count(); sl@0: TInt index=0; sl@0: TBool modified=EFalse; sl@0: sl@0: //goes through service registry to find data mappings related to aAppUid sl@0: while(index<count) sl@0: { sl@0: if (iAppMappings[index].iAppUid==aAppUid) sl@0: { sl@0: iAppMappings.Delete(index); sl@0: //As data mapping is removed from service registry, reduce the count sl@0: count--; sl@0: modified=ETrue; sl@0: } sl@0: else sl@0: index++; sl@0: } sl@0: return(modified); sl@0: }