diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/src/cmtpdataprovidercontroller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/src/cmtpdataprovidercontroller.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,1150 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include +#include +#include + +#include "cmtpdataprovider.h" +#include "cmtpdataproviderconfig.h" +#include "cmtpdataprovidercontroller.h" +#include "cmtpobjectmgr.h" +#include "mtpframeworkconst.h" +#include "cmtpframeworkconfig.h" +#include "cmtpstoragemgr.h" + + +// Class constants. +_LIT(KMTPDpResourceDirectory, "z:\\resource\\mtp\\"); +_LIT(KMTPDpDummyResourcefile, "z:\\resource\\mtp\\dummydp.rsc"); + +// Class constants. +__FLOG_STMT(_LIT8(KComponent,"DataProviderController");) + +static const TUint KOpaqueDataLength(64); + +/** +CMTPDataProviderController panics +*/ +_LIT(KMTPPanicCategory, "CMTPDataProviderController"); +enum TMTPPanicReasons + { + EMTPPanicStorageEnumeration = 0, + EMTPPanicFrameworkEnumeration = 1, + EMTPPanicDataProviderStorageEnumeration = 2, + EMTPPanicDataProviderEnumeration = 3 + }; + +LOCAL_C void Panic(TInt aReason) + { + User::Panic(KMTPPanicCategory, aReason); + } + +/** +CMTPDataProviderController factory method. +@return A pointer to a new CMTPDataProviderController instance. Ownership IS +transfered. +@leave One of the system wide error codes if a processing failure occurs. +*/ +CMTPDataProviderController* CMTPDataProviderController::NewL() + { + CMTPDataProviderController* self = new (ELeave) CMTPDataProviderController(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Destructor. +*/ +CMTPDataProviderController::~CMTPDataProviderController() + { + __FLOG(_L8("~CMTPDataProviderController - Entry")); + Cancel(); + UnloadDataProviders(); + iDataProviderIds.Close(); + iEnumeratingDps.Close(); + iEnumeratingStorages.Close(); + iSingletons.Close(); + CloseRegistrySessionAndEntryL(); + delete iOpenSessionWaiter; + __FLOG(_L8("~CMTPDataProviderController - Exit")); + __FLOG_CLOSE; + } + +/** +Loads the set of available data providers and initiates the data provider +enumeration sequence. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C void CMTPDataProviderController::LoadDataProvidersL() + { + __FLOG(_L8("LoadDataProvidersL - Entry")); + // Retrieve the ECOM data provider implementations list + RImplInfoPtrArray implementations; + TCleanupItem cleanup(ImplementationsCleanup, reinterpret_cast(&implementations)); + CleanupStack::PushL(cleanup); + REComSession::ListImplementationsL(KMTPDataProviderPluginInterfaceUid, implementations); + implementations.Sort(TLinearOrder(ImplementationsLinearOrderUid)); + + // Retrieve the data provider registration resource file list. + CDir* registrations; + User::LeaveIfError(iSingletons.Fs().GetDir(KMTPDpResourceDirectory, KEntryAttNormal, ESortByName, registrations)); + CleanupStack::PushL(registrations); + + // Load the registered data providers. + const TUint KCount(registrations->Count()); + TInt index = 0; + for (TInt i = 0; i < KCount; ++i) + { + TUint uid = 0; + if(Uid((*registrations)[i].iName, uid) != KErrNone) + { + __FLOG_1(_L8("LoadDataProvidersL - Fail to get UID = %s"),&((*registrations)[i].iName) ); + continue; + } + index = implementations.FindInOrder(TUid::Uid(uid), ImplementationsLinearOrderUid); + if (KErrNotFound == index) + { + continue; + } + if( uid != KMTPImplementationUidDeviceDp && uid != KMTPImplementationUidProxyDp && uid != KMTPImplementationUidFileDp ) + { + //get the dpid for the uid from dpidstore table + TBool tFlag; + iNextDpId = iSingletons.ObjectMgr().DPIDL(uid, tFlag); + if(tFlag == EFalse) + { + iSingletons.ObjectMgr().InsertDPIDObjectL(iNextDpId,uid); + } + } + else + { + switch (uid) + { + case KMTPImplementationUidDeviceDp : + iNextDpId = KMTPDeviceDPID; + break; + + case KMTPImplementationUidFileDp : + iNextDpId = KMTPFileDPID; + break; + + case KMTPImplementationUidProxyDp : + iNextDpId = KMTPProxyDPID; + break; + } + } + LoadROMDataProvidersL((*registrations)[i].iName, implementations); + delete implementations[index]; + implementations.Remove(index); + } + + //Load installed DPs on non-ROM drives. + for (index = 0; index < implementations.Count(); ++index) + { + TRAPD(err, LoadInstalledDataProvidersL(implementations[index])); + if (KErrNone != err) + { + __FLOG_VA((_L8("Load installed data provider[0x%x] failed."),implementations[index]->ImplementationUid().iUid)); + } + } + + CleanupStack::PopAndDestroy(registrations); + CleanupStack::PopAndDestroy(&implementations); + + // Verify that the framework data providers are loaded. + User::LeaveIfError(DpId(KMTPImplementationUidDeviceDp)); + User::LeaveIfError(DpId(KMTPImplementationUidProxyDp)); + User::LeaveIfError(DpId(KMTPImplementationUidFileDp)); + + // Sort the data provider set on enumeration phase order. + iDataProviders.Sort(TLinearOrder(CMTPDataProvider::LinearOrderEnumerationPhase)); + // Add the DP IDs into DP ID array, except for device DP, File DP and proxy DP + for (TUint index=0; index < iDataProviders.Count(); index++) + { + if ((iDataProviders[index]->DataProviderId() != iDpIdDeviceDp) + && (iDataProviders[index]->DataProviderId() != iDpIdFileDp) + && (iDataProviders[index]->DataProviderId() != iDpIdProxyDp)) + { + iDataProviderIds.Append(iDataProviders[index]->DataProviderId()); + } + } + + // Ensure that the data provider set is ordered on DataProvider Id. + iDataProviders.Sort(TLinearOrder(CMTPDataProvider::LinearOrderDPId)); + + // Start enumerating. + iEnumeratingStorages.AppendL(KMTPStorageAll); + iEnumerationState = EEnumerationStarting; + Schedule(); + __FLOG(_L8("LoadDataProvidersL - Exit")); + } + +/** +Unloads all active data providers. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C void CMTPDataProviderController::UnloadDataProviders() + { + __FLOG(_L8("UnloadDataProviders - Entry")); + TRAP_IGNORE(iSingletons.ObjectMgr().ObjectStore().CleanL()); + iDataProviders.ResetAndDestroy(); + iDataProviderIds.Reset(); + __FLOG(_L8("UnloadDataProviders - Exit")); + } + +/** +Issues the specified notification to all loaded data providers. +@param aNotification The notification type identifier. +@param aParams The notification type specific parameter block +@leave One of the system wide error code if a processing failure occurs +in the data provider. +*/ +EXPORT_C void CMTPDataProviderController::NotifyDataProvidersL(TMTPNotification aNotification, const TAny* aParams) + { + NotifyDataProvidersL(KMTPDataProviderAll, aNotification, aParams); + } + +EXPORT_C void CMTPDataProviderController::NotifyDataProvidersL(TUint aDPId, TMTPNotification aNotification, const TAny* aParams) + { + __FLOG(_L8("NotifyDataProvidersL - Entry")); + // Schedule any long running operations. + switch (aNotification) + { + case EMTPStorageAdded: + { + // Queue a storage enumeration operation. + __ASSERT_DEBUG(aParams, User::Invariant()); + const TMTPNotificationParamsStorageChange* params(static_cast(aParams)); + iEnumeratingStorages.AppendL(params->iStorageId); + + // Only schedule the operation start if there is not one currently underway. + if (iEnumerationState == EEnumerated) + { + iNextDpId = iDpIdDeviceDp; + iEnumerationState = EEnumeratingFrameworkObjects; + Schedule(); + } + } + break; + case EMTPStorageRemoved: + { + // Dequeue an unhandled storage enumeration operations if existed. + // If not existed, just ignore the remove event, since the logical storageId already removed from StorageMgr + // by the caller, i.e. CMTPStorageWatcher. + __ASSERT_DEBUG(aParams, User::Invariant()); + const TMTPNotificationParamsStorageChange* params(static_cast(aParams)); + //Start checking from the second event, since iEnumeratingStorages[0] is the event being handled by DPs. + TUint32 storageId = params->iStorageId; + for(TInt i=1; iDataProviderId() != iDpIdDeviceDp) && + (dp->DataProviderId() != iDpIdProxyDp)) + { + dp->Plugin().ProcessNotificationL(aNotification, aParams); + } + } + } + else + { + for (TUint i(0); i < KLoadedDps; ++i) + { + CMTPDataProvider *dp = iDataProviders[i]; + if ( dp->DataProviderId() == aDPId ) + { + dp->Plugin().ProcessNotificationL(aNotification, aParams); + break; + } + } + } + __FLOG(_L8("NotifyDataProvidersL - Exit")); + } + +/** +Provides the number of active data providers. +@return the number of active data providers. +*/ +EXPORT_C TUint CMTPDataProviderController::Count() + { + return iDataProviders.Count(); + } + +/** +Provides a reference to the data provider with the specified identifier. +@param aId The data provider identifier. +@return The data provider reference. +*/ +EXPORT_C CMTPDataProvider& CMTPDataProviderController::DataProviderL(TUint aId) + { + return DataProviderByIndexL(iDataProviders.FindInOrder(aId, CMTPDataProvider::LinearOrderDPId)); + } + +/** +Provides a reference to the data provider with the specified index. +@param aIndex The data provider index. +@return The data provider reference. +*/ +EXPORT_C CMTPDataProvider& CMTPDataProviderController::DataProviderByIndexL(TUint aIndex) + { + __ASSERT_DEBUG((aIndex < iDataProviders.Count()), User::Invariant()); + return *(iDataProviders[aIndex]); + } + +/** + * Determine whether a data provider with the specified data provider id has been loaded + * @param aId the id of the data provider to be checked + * @return true if the data provider has been loaded, otherwise false + */ +EXPORT_C TBool CMTPDataProviderController::IsDataProviderLoaded(TUint aId) const + { + TInt index = iDataProviders.FindInOrder(aId, CMTPDataProvider::LinearOrderDPId); + if (index >= 0 && index < iDataProviders.Count()) + { + return ETrue; + } + else + { + return EFalse; + } + } + +/** +Provides the identifier of the device data provider. +@return TInt The device data provider identifier. +*/ +EXPORT_C TInt CMTPDataProviderController::DeviceDpId() + { + return iDpIdDeviceDp; + } + +/** +Provides the identifier of the data provider with the specified implementation +UID. +@param aUid The implementation UID. +@return TInt The proxy data provider identifier. +*/ +EXPORT_C TInt CMTPDataProviderController::DpId(TUint aUid) + { + return iDataProviders.FindInOrder(TUid::Uid(aUid), CMTPDataProvider::LinearOrderUid); + } + +/** +Provides the identifier of the proxy data provider. +@return TInt The proxy data provider identifier. +*/ +EXPORT_C TInt CMTPDataProviderController::ProxyDpId() + { + return iDpIdProxyDp; + } + +EXPORT_C TInt CMTPDataProviderController::FileDpId() + { + return iDpIdFileDp; + } + +/** +Wait for the enumeration complete. +*/ +EXPORT_C void CMTPDataProviderController::WaitForEnumerationComplete() +{ + if(EnumerateState() != CMTPDataProviderController::EEnumerated) + { + iOpenSessionWaiter->Start(); + } +} +TBool CMTPDataProviderController::FreeEnumerationWaiter() + { + if(iOpenSessionWaiter->IsStarted()) + { + iOpenSessionWaiter->AsyncStop(); + return ETrue; + } + return EFalse; + } +/** +Data provider enumeration state change notification callback. +@param aDp The notifying data provider. +*/ +void CMTPDataProviderController::EnumerationStateChangedL(const CMTPDataProvider& aDp) + { + __FLOG(_L8("EnumerationStateChangedL - Entry")); + switch (iEnumerationState) + { + case EEnumeratingFrameworkStorages: + switch (aDp.ImplementationUid().iUid) + { + case KMTPImplementationUidDeviceDp: + iNextDpId = iDpIdProxyDp; + break; + + + case KMTPImplementationUidProxyDp: + iNextDpId = iDpIdFileDp; + break; + + case KMTPImplementationUidFileDp: + iEnumerationState = EEnumeratingDataProviderStorages; + iDpIdArrayIndex = 0; + break; + } + Schedule(); + break; + + case EEnumeratingDataProviderStorages: + // Data provider storage enumerations execute sequentially. + if (++iDpIdArrayIndex >= iDataProviderIds.Count()) + { + iNextDpId = iDpIdDeviceDp; + iEnumerationState = EEnumeratingFrameworkObjects; + } + Schedule(); + break; + + case EEnumeratingFrameworkObjects: + switch (aDp.ImplementationUid().iUid) + { + case KMTPImplementationUidDeviceDp: + iSingletons.ObjectMgr().RemoveNonPersistentObjectsL(aDp.DataProviderId()); + iNextDpId = iDpIdProxyDp; + Schedule(); + break; + + case KMTPImplementationUidProxyDp: + //iNextDpId = iDpIdFileDp; + if ( iDataProviderIds.Count()>0 ) + { + iEnumerationState = EEnumeratingDataProviderObjects; + iEnumerationPhase = DataProviderL(iDataProviderIds[0]).DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase); + iDpIdArrayIndex = 0; + } + else + { + iNextDpId = iDpIdFileDp; + } + Schedule(); + break; + + case KMTPImplementationUidFileDp: + iSingletons.ObjectMgr().RemoveNonPersistentObjectsL(aDp.DataProviderId()); + // No other data providers + iNextDpId = 0; + iEnumeratingStorages.Remove(0); + if (iEnumeratingStorages.Count() == 0) + { + // No queued enumerations. + iSingletons.ObjectMgr().ObjectStore().CleanDBSnapshotL(); + iEnumerationState = EEnumerated; + Cancel(); + if(iOpenSessionWaiter->IsStarted()) + { + iOpenSessionWaiter->AsyncStop(); + } + } + else + { + // Queued enumerations. + iNextDpId = iDpIdDeviceDp; + Schedule(); + } + } + break; + + case EEnumeratingDataProviderObjects: + // Enumerate non-framework data providers concurrently. + iEnumeratingDps.Remove(iEnumeratingDps.FindInOrderL(aDp.DataProviderId())); + // Remove any non-persistent objects that are still marked. + iSingletons.ObjectMgr().RemoveNonPersistentObjectsL(aDp.DataProviderId()); + + if ((iEnumeratingDps.Count() == 0) && iDpIdArrayIndex >= iDataProviderIds.Count()) + { + // Enumeration complete. + iNextDpId = 0; + iNextDpId = iDpIdFileDp; + iEnumerationState = EEnumeratingFrameworkObjects; + } + else + { + if ((iEnumeratingDps.Count() == 0) && (iEnumerationPhase != DataProviderL(iDataProviderIds[iDpIdArrayIndex]).DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase))) + { + // Enter next enumeration phase + iEnumerationPhase = DataProviderL(iDataProviderIds[iDpIdArrayIndex]).DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase); + } + } + Schedule(); + break; + + case EUnenumerated: + case EEnumerationStarting: + case EEnumerated: + default: + __DEBUG_ONLY(User::Invariant()); + break; + } + __FLOG(_L8("EnumerationStateChangedL - Exit")); + } + +void CMTPDataProviderController::DoCancel() + { + __FLOG(_L8("DoCancel - Entry")); + __FLOG(_L8("DoCancel - Exit")); + } + +void CMTPDataProviderController::RunL() + { + __FLOG(_L8("RunL - Entry")); + __FLOG_VA((_L8("iEnumerationState: 0x%x iNextDpId: %d"), iEnumerationState, iNextDpId)); + switch (iEnumerationState) + { + case EEnumerationStarting: + iEnumerationState = EEnumeratingFrameworkStorages; + iNextDpId = iDpIdDeviceDp; + // Fall through to issue the StartStorageEnumerationL signal. + + case EEnumeratingFrameworkStorages: + // Enumerate storages sequentially. + DataProviderL(iNextDpId).EnumerateStoragesL(); + break; + + case EEnumeratingDataProviderStorages: + // Enumerate storages sequentially. + + // In case there was no DPs other than devdp and proxydp. + if (iDpIdArrayIndex < iDataProviderIds.Count()) + { + DataProviderL(iDataProviderIds[iDpIdArrayIndex]).EnumerateStoragesL(); + } + else + { + iNextDpId = iDpIdDeviceDp; + iEnumerationState = EEnumeratingFrameworkObjects; + + + + Schedule(); + } + break; + + case EEnumeratingFrameworkObjects: + { + TUint32 storageId = iEnumeratingStorages[0]; + if( ( KMTPStorageAll != storageId ) && (!iSingletons.StorageMgr().ValidStorageId(storageId))) + { + iNextDpId = 0; + //Specified storage not existed, not necessary to start enumeration on this stroage. + //Do this check will save enumeration time, i.e. avoid unnecessary enumeration, since memory card removed before enumeration starts. + iEnumeratingStorages.Remove(0); + if (iEnumeratingStorages.Count() == 0) + { + iEnumerationState = EEnumerated; + } + else + { + //deal next storage + iNextDpId = iDpIdDeviceDp; + Schedule(); + } + } + else + { + // Enumerate framework data providers sequentially. + if(iNextDpId == iDpIdDeviceDp) + { + if(KMTPStorageAll == storageId) + { + iSingletons.ObjectMgr().ObjectStore().EstablishDBSnapshotL(storageId); + } + else + { + const CMTPStorageMetaData& storage(iSingletons.StorageMgr().StorageL(storageId)); + if(storage.Uint(CMTPStorageMetaData::EStorageSystemType) == CMTPStorageMetaData::ESystemTypeDefaultFileSystem) + { + const RArray& logicalIds(storage.UintArray(CMTPStorageMetaData::EStorageLogicalIds)); + const TUint KCountLogicalIds(logicalIds.Count()); + for (TUint i(0); (i < KCountLogicalIds); i++) + { + __FLOG_VA((_L8("Establish snapshot for storage: 0x%x"), storageId)); + iSingletons.ObjectMgr().ObjectStore().EstablishDBSnapshotL(storageId); + } + } + } + } + EnumerateDataProviderObjectsL(iNextDpId); + } + } + break; + + case EEnumeratingDataProviderObjects: + { + TUint currentDp = 0; + + // Enumerate non-framework data providers concurrently. + const TUint KLoadedDps(iDataProviderIds.Count()); + while ((iEnumeratingDps.Count() < KMTPMaxEnumeratingDataProviders) && (iDpIdArrayIndex < KLoadedDps) + && (iEnumerationPhase == DataProviderL(iDataProviderIds[iDpIdArrayIndex]).DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase))) + { + currentDp = iDataProviderIds[iDpIdArrayIndex++]; + iEnumeratingDps.InsertInOrderL(currentDp); + EnumerateDataProviderObjectsL(currentDp); + } + } + break; + + case EUnenumerated: + case EEnumerated: + default: + __DEBUG_ONLY(User::Invariant()); + break; + } + __FLOG(_L8("RunL - Exit")); + } + +#ifdef __FLOG_ACTIVE +TInt CMTPDataProviderController::RunError(TInt aError) +#else +TInt CMTPDataProviderController::RunError(TInt /*aError*/) +#endif + { + __FLOG(_L8("RunError - Entry")); + __FLOG_VA((_L8("Error = %d"), aError)); + + // If a RunL error happens, there's no point in trying to continue. + switch (iEnumerationState) + { + case EEnumerationStarting: + case EEnumeratingFrameworkStorages: + Panic(EMTPPanicStorageEnumeration); + break; + + case EEnumeratingFrameworkObjects: + Panic(EMTPPanicFrameworkEnumeration); + break; + + case EEnumeratingDataProviderStorages: + Panic(EMTPPanicDataProviderStorageEnumeration); + break; + + case EEnumeratingDataProviderObjects: + Panic(EMTPPanicDataProviderEnumeration); + break; + + case EUnenumerated: + case EEnumerated: + default: + User::Invariant(); + break; + } + + // This code is never reached + __FLOG(_L8("RunError - Exit")); + return KErrNone; + } + +/** +Constructor. +*/ +CMTPDataProviderController::CMTPDataProviderController() : + CActive(EPriorityNormal) + { + CActiveScheduler::Add(this); + } + +/** +Second-phase constructor. +@leave One of the system wide error codes if a processing failure occurs. +*/ +void CMTPDataProviderController::ConstructL() + { + __FLOG_OPEN(KMTPSubsystem, KComponent); + __FLOG(_L8("ConstructL - Entry")); + iSingletons.OpenL(); + TInt tMTPMode; + TInt err = RProperty::Get(KUidSystemCategory, KUidMTPModeKeyValue, tMTPMode); + if(err != KErrNone) + { + tMTPMode = KMTPModeMTP; + } + else + { + if(tMTPMode != KMTPModeMTP && tMTPMode != KMTPModePTP && tMTPMode != KMTPModePictBridge) + tMTPMode = KMTPModeMTP; + } + iMode = (TMTPOperationalMode)tMTPMode; + CreateRegistrySessionAndEntryL(); + + iFlagDb = 0; + + iOpenSessionWaiter = new(ELeave) CActiveSchedulerWait(); + __FLOG(_L8("ConstructL - Exit")); + } + +/** +Creates a data provider configurability parameter data instance on the cleanup +stack. +@param aResourceFilename The data provider configuration data resource filename. +@return A pointer to the data provider configurability parameter data instance, +which is also placed on the cleanup stack. Ownership is transferred. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +CMTPDataProviderConfig* CMTPDataProviderController::CreateConfigLC(const TDesC& aResourceFilename) + { + __FLOG(_L8("CreateConfigLC - Entry")); + // Open the configuration data resource file + RResourceFile file; + CleanupClosePushL(file); + file.OpenL(iSingletons.Fs(), aResourceFilename); + + // Create the resource reader. + const TInt KDefaultResourceId(1); + HBufC8* buffer(file.AllocReadLC(KDefaultResourceId)); + TResourceReader reader; + reader.SetBuffer(buffer); + + // Load the data provider configurability parameter data. + CMTPDataProviderConfig* config(CMTPDataProviderConfig::NewL(reader, aResourceFilename)); + CleanupStack::PopAndDestroy(buffer); + CleanupStack::PopAndDestroy(&file); + CleanupStack::PushL(config); + __FLOG(_L8("CreateConfigLC - Exit")); + return config; + } + +/** +Check the necessity of objects enumeration as given the data provider +@param dp CMTPDataProvider reference +*/ +TBool CMTPDataProviderController::IsObjectsEnumerationNeededL(CMTPDataProvider& dp) +{ + __FLOG(_L8("CheckEnumerateDPObjectsL - Entry")); + + CMTPStorageMgr& storages = iSingletons.StorageMgr(); + TUint32 aStorageId = iEnumeratingStorages[0]; + + TBool doEnumeration = true; + + if (aStorageId != KMTPStorageAll && storages.PhysicalStorageId(aStorageId)) + { + TBool isFSBased(false); + RArray storageTypes = dp.SupportedCodes( EStorageSystemTypes ); + // check whether the storage type of the dp is file system based. + for (TInt i = 0; i < storageTypes.Count() && !isFSBased; i++) + { + isFSBased= (storageTypes[i] == CMTPStorageMetaData::ESystemTypeDefaultFileSystem); + } + // As given physical storage id, only fs based dp need to do the enumeration. + if (!isFSBased) + { + doEnumeration = false; + } + } + __FLOG(_L8("CheckEnumerateDPObjectsL - Exit")); + return doEnumeration; +} + +/** +Requests that the given data provider enumerate its objects. +@param aId data provider ID +*/ +void CMTPDataProviderController::EnumerateDataProviderObjectsL(TUint aId) + { + __FLOG(_L8("EnumerateDataProviderObjectsL - Entry")); + CMTPDataProvider& dp(DataProviderL(aId)); + + if (IsObjectsEnumerationNeededL(dp)) + { + TBool abnormaldown = ETrue; + iSingletons.FrameworkConfig().GetValueL(CMTPFrameworkConfig::EAbnormalDown , abnormaldown); + if ( (!abnormaldown) && (dp.DataProviderConfig().BoolValue(MMTPDataProviderConfig::EObjectEnumerationPersistent))) + { + // Initialize persistent objects store. + iSingletons.ObjectMgr().RestorePersistentObjectsL(aId); + } + else + { + // Mark all non-persistent objects. + iSingletons.ObjectMgr().MarkNonPersistentObjectsL(aId,iEnumeratingStorages[0]); + } + + // Initiate the data provider enumeration sequence. + dp.EnumerateObjectsL(iEnumeratingStorages[0]); + } + else + { + //The DP does not need enumeration this time, so just change the state to go on. + EnumerationStateChangedL(dp); + } + + __FLOG(_L8("EnumerateDataProviderObjectsL - Exit")); + } + +/** +Loads the dataprovider on ROM drives depending upon the mode and activates the specified ECOM data provider. +@param aResourceFilename The data provider registration and configuration data +resource filename. +@param aImplementations The ECOM data provider implementations list (ordered by +implementation UID). +@return ETrue if data provider is successfully loaded, EFalse otherwise. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +TBool CMTPDataProviderController::LoadROMDataProvidersL(const TDesC& aResourceFilename, const RImplInfoPtrArray& aImplementations) + { + __FLOG(_L8("LoadROMDataProvidersL - Entry")); + // Retrieve the implementation UID + TUint uid(0); + User::LeaveIfError(Uid(aResourceFilename, uid)); + TBool success(EFalse); + + // Check for a corresponding plug-in implementation. + TInt index = aImplementations.FindInOrder(TUid::Uid(uid), ImplementationsLinearOrderUid); + if (index >= 0) + { + // Construct the configuration data resource file full path name. + RBuf filename; + CleanupClosePushL(filename); + filename.CreateL(KMTPDpResourceDirectory.BufferSize + aResourceFilename.Length()); + filename.Append(KMTPDpResourceDirectory); + filename.Append(aResourceFilename); + if(iStubFound) + { + RPointerArray files; + CleanupClosePushL(files); + iSisEntry.FilesL(files); + for (TInt i = 0; i< files.Count(); ++i) + { + TPtrC resourceFileName = files[i]->Des(); + TPtrC fileName = resourceFileName.Mid(resourceFileName.LocateReverse('\\') + 1); + if(fileName.MatchF(aResourceFilename) != KErrNotFound) + { + TDriveName drive = aImplementations[index]->Drive().Name(); + //replace "z:" with "c:" or "d:" or ... + filename.Replace(0,2,drive); + break; + } + } + CleanupStack::Pop(&files); + files.ResetAndDestroy(); + } + success = LoadDataProviderL(filename); + CleanupStack::PopAndDestroy(&filename); + } + __FLOG(_L8("LoadROMDataProvidersL - Exit")); + return success; + } + +/** +Load all data providers installed on non-ROM drives depending upon the mode and activates +the specified ECOM data provider. +@param aImplementations The installed ECOM data provider implementations list (ordered by +implementation UID). +@leave One of the system wide error codes, if a processing failure occurs. +*/ +void CMTPDataProviderController::LoadInstalledDataProvidersL(const CImplementationInformation* aImplementations) + { + __FLOG(_L8("LoadInstalledDataProvidersL - Entry")); + TUint uid = aImplementations->ImplementationUid().iUid; + TBool tFlag(EFalse); + iNextDpId = iSingletons.ObjectMgr().DPIDL(uid, tFlag); + if(!tFlag) + { + iSingletons.ObjectMgr().InsertDPIDObjectL(iNextDpId, uid); + } + + HBufC8 *OpaqData = HBufC8::NewLC(KOpaqueDataLength); + *OpaqData = aImplementations->OpaqueData(); + TBuf16 pkgIDstr; + pkgIDstr.Copy(*OpaqData); + CleanupStack::PopAndDestroy(OpaqData); + pkgIDstr.Trim(); + _LIT(prefix, "0x"); + TInt searchindex = pkgIDstr.FindC(prefix); + if(KErrNotFound != searchindex) + { + //Skip "0x". + pkgIDstr = pkgIDstr.Mid(searchindex + 2); + } + if (0 == pkgIDstr.Length()) + { + User::Leave(KErrArgument); + } + + TUint aUid(0); + User::LeaveIfError(Uid(pkgIDstr, aUid)); + + iSingletons.ObjectMgr().InsertPkgIDObjectL(iNextDpId, aUid); + TDriveName drive = aImplementations->Drive().Name(); + RBuf resourcefilename; + CleanupClosePushL(resourcefilename); + resourcefilename.CreateL(KMaxFileName); + resourcefilename.Copy(KMTPDpResourceDirectory); + //Replace "z:"(at 0 position) with "c:" or "d:" or ... + resourcefilename.Replace(0,2,drive); + + RBuf rscfile; + CleanupClosePushL(rscfile); + rscfile.CreateL(KMaxFileName); + rscfile.NumUC(uid,EHex); + _LIT(postfix, ".rsc"); + rscfile.Append(postfix); + resourcefilename.Append(rscfile); + CleanupStack::PopAndDestroy(&rscfile); + + LoadDataProviderL(resourcefilename); + + CleanupStack::PopAndDestroy(&resourcefilename); + __FLOG(_L8("LoadInstalledDataProvidersL - Exit")); + } + +/** +Load data providers +@param aImplementations The installed ECOM data provider implementations list (ordered by +implementation UID). +@return ETrue if data provider is successfully loaded, EFalse otherwise. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +TBool CMTPDataProviderController::LoadDataProviderL(const TDesC& aResourceFilename) + { + __FLOG(_L8("LoadDataProviderL - Entry")); + // Load the configurability parameter data. + CMTPDataProviderConfig* config(CreateConfigLC(aResourceFilename)); + + + TBool success(EFalse); + TBool supported(ETrue); + TUint aUid(0); + if ( Uid(aResourceFilename,aUid) != KErrNone ) + { + return success; + } + TUint uid(aUid); + if ((uid != KMTPImplementationUidDeviceDp) && (uid != KMTPImplementationUidProxyDp) && (uid != KMTPImplementationUidFileDp)) + { + supported = EFalse; + RArray supportedModeArray; + config->GetArrayValue(MMTPDataProviderConfig::ESupportedModes, supportedModeArray); + TInt i=0; + while (i < supportedModeArray.Count()) + { + if(iMode == supportedModeArray[i]) + { + supported = ETrue; + break; + } + i++; + } + supportedModeArray.Close(); + if(!supported) + { + //Update the Database table last IsDploaded filed with Efalse; + /* create dummy DP which is just new of Dervied DataPRoviderClass + update the DataBase so that DPIP which this was get then set handle Store DB */ + iSingletons.ObjectMgr().MarkDPLoadedL(iNextDpId,EFalse); + RBuf dummyfilename; + CleanupClosePushL(dummyfilename); + dummyfilename.CreateL(KMTPDpDummyResourcefile.BufferSize); + dummyfilename.Append(KMTPDpDummyResourcefile); + CMTPDataProviderConfig* aDummyConfig(CreateConfigLC(dummyfilename)); + CMTPDataProvider* dummyDp(NULL); + dummyDp = CMTPDataProvider::NewLC(iNextDpId, TUid::Uid(uid), aDummyConfig); + iDataProviders.InsertInOrderL(dummyDp, TLinearOrder(CMTPDataProvider::LinearOrderUid)); + CleanupStack::Pop(dummyDp); + CleanupStack::Pop(aDummyConfig); + CleanupStack::PopAndDestroy(&dummyfilename); + } + } + CMTPDataProvider* dp(NULL); + if(supported) + { + // Load the data provider. + switch (config->UintValue(MMTPDataProviderConfig::EDataProviderType)) + { + case EEcom: + { + // Configurability parameter data ownership is passed to the data provider. + iSingletons.ObjectMgr().MarkDPLoadedL(iNextDpId, ETrue); + dp = CMTPDataProvider::NewLC(iNextDpId, TUid::Uid(uid), config); + } + break; + + default: + __DEBUG_ONLY(User::Invariant()); + break; + } + } + if (dp) + { + // Register the data provider. + switch (uid) + { + case KMTPImplementationUidDeviceDp: + iDpIdDeviceDp = iNextDpId; + break; + + case KMTPImplementationUidFileDp: + iDpIdFileDp = iNextDpId; + break; + + case KMTPImplementationUidProxyDp: + iDpIdProxyDp = iNextDpId; + break; + + default: + break; + } + iDataProviders.InsertInOrderL(dp, TLinearOrder(CMTPDataProvider::LinearOrderUid)); + CleanupStack::Pop(dp); + CleanupStack::Pop(config); + success = ETrue; + } + else + { + // No data provider was created. + CleanupStack::PopAndDestroy(config); + } + __FLOG(_L8("LoadDataProviderL - Exit")); + return success; + } + +/** +Provides the implemetation UID associated with the specified data provider +configuration data resource filename. +@param aResourceFilename The data provider configuration data resource +filename. +@param aUid On completion, the implemetation UID. +*/ +TInt CMTPDataProviderController::Uid(const TDesC& aResourceFilename, TUint& aUid) + { + __FLOG(_L8("Uid - Entry")); + // Extract the implemetation UID from the filename. + TParsePtrC parser(aResourceFilename); + TLex lex(parser.Name()); + TInt err = lex.Val(aUid, EHex); + __FLOG(_L8("Uid - Exit")); + return err; + } + +/** +Schedules an enumeration iteration. +*/ +void CMTPDataProviderController::Schedule() + { + __FLOG(_L8("Schedule - Entry")); + if (!IsActive()) + { + TRequestStatus* status(&iStatus); + *status = KRequestPending; + SetActive(); + User::RequestComplete(status, KErrNone); + } + __FLOG(_L8("Schedule - Exit")); + } +/** +Get the mtpkey mode. +*/ +TMTPOperationalMode CMTPDataProviderController::Mode() + { + return iMode; + } + +void CMTPDataProviderController::ImplementationsCleanup(TAny* aData) + { + reinterpret_cast(aData)->ResetAndDestroy(); + } + +/** +Implements a linear order relation for @see CImplementationInformation +objects based on relative @see CImplementationInformation::ImplementationUid. +@param aUid The implementation UID object to match. +@param aObject The object instance to match. +@return Zero, if the two objects are equal; A negative value, if the first +object is less than the second, or; A positive value, if the first object is +greater than the second. +*/ +TInt CMTPDataProviderController::ImplementationsLinearOrderUid(const TUid* aUid, const CImplementationInformation& aObject) + { + return (aUid->iUid - aObject.ImplementationUid().iUid); + } + +/** +Implements a @see TLinearOrder for @see CImplementationInformation objects +based on relative @see CImplementationInformation::ImplementationUid. +@param aL The first object instance. +@param aR The second object instance. +@return Zero, if the two objects are equal; A negative value, if the first +object is less than the second, or; A positive value, if the first object is +greater than the second. +*/ +TInt CMTPDataProviderController::ImplementationsLinearOrderUid(const CImplementationInformation& aL, const CImplementationInformation& aR) + { + return (aL.ImplementationUid().iUid - aR.ImplementationUid().iUid); + } + +/** +Provides the enumeration state +@return iEnumerationState +*/ +EXPORT_C TUint CMTPDataProviderController::EnumerateState() + { + return iEnumerationState; + } + +void CMTPDataProviderController::CreateRegistrySessionAndEntryL() + { + User::LeaveIfError(iSisSession.Connect()); + CleanupClosePushL(iSisSession); + TInt err = KErrNone; + TUint stubuid; + iSingletons.FrameworkConfig().GetValueL(CMTPFrameworkConfig::EPackageStubUID , stubuid); + TRAP_IGNORE(err=iSisEntry.Open(iSisSession, TUid::Uid(stubuid) )); + if(err == KErrNone) + { + iStubFound = ETrue; + } + CleanupStack::Pop(); + } + +void CMTPDataProviderController::CloseRegistrySessionAndEntryL() + { + if (&iSisEntry != NULL) + { + iSisEntry.Close(); + } + iSisSession.Close(); + } +