diff -r 675a964f4eb5 -r 35751d3474b7 contentmgmt/contentaccessfwfordrm/source/caf/resolver.cpp --- a/contentmgmt/contentaccessfwfordrm/source/caf/resolver.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/contentmgmt/contentaccessfwfordrm/source/caf/resolver.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,598 +1,598 @@ -/* -* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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 "resolver.h" -#include "agentfactory.h" -#include "agentinterface.h" -#include "agentinfo.h" -#include "agent.h" -#include "cafpanic.h" -#include "caferr.h" -#include "patchdata.h" - - -using namespace ContentAccess; - -// Constants for the F32 agent -_LIT(KF32Agent,"F32 CA Agent"); - - -_LIT(KParentDir, "..\\"); -_LIT(KPrivateDir, "\\private\\"); -const TInt KPrivateDirLength = 9; // "\\private\\" -const TInt KPrivateDirAndDriveLength = 11; // "x:\\private\\" -const TInt KPrivateDirOffset = 2; // "x:\\" - - -EXPORT_C CAgentResolver* CAgentResolver::NewLC(const TBool aDynamicAgentUpdate) - { - CAgentResolver* self = new (ELeave) CAgentResolver(aDynamicAgentUpdate); - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } - -EXPORT_C CAgentResolver* CAgentResolver::NewL(const TBool aDynamicAgentUpdate) - { - CAgentResolver* self = CAgentResolver::NewLC(aDynamicAgentUpdate); - CleanupStack::Pop(self); - return self; - } - -CAgentResolver::CAgentResolver(const TBool aDynamicAgentUpdate) : CActive(EPriorityStandard), iDynamicAgentUpdate(aDynamicAgentUpdate) - { - } - -CAgentResolver::~CAgentResolver() - { - // remove ourselves from the ActiveScheduler - if(IsAdded()) - { - Deque(); - } - - // Unload all the agents - DestroyListOfAgents(); - - // Close our ECOM session - if(iEcomSession) - { - if(iDynamicAgentUpdate) - { - iEcomSession->CancelNotifyOnChange(iStatus); - } - iEcomSession->Close(); - REComSession::FinalClose(); - } - - iSupplierMimeTypes.Close(); - iConsumerMimeTypes.Close(); - iAgentInfos.Close(); - } - -void CAgentResolver::ConstructL() - { - if(iDynamicAgentUpdate) - { - // Add ourselves to the current active scheduler so we can get dynamic - // updates when agents are removed or new agents are added - CActiveScheduler::Add(this); - } - - iEcomSession = &REComSession::OpenL(); - - // find all the agents - BuildListOfAgentsL(); - - if(iDynamicAgentUpdate) - { - // register for ECOM update notifications in case a new agent appears - SetActive(); - iEcomSession->NotifyOnChange(iStatus); - } - } - -void CAgentResolver::BuildListOfAgentsL() - { - TInt err = KErrNone; - - // Get all plugins which implement the agent interface - RImplInfoPtrArray implArray; - CleanupStack::PushL(TCleanupItem(CleanImplArray, &implArray)); - REComSession::ListImplementationsL(KCAAgentInterfaceUid, implArray); - - for (TInt i = 0; i < implArray.Count(); ++i) - { -#ifdef __EPOC32__ - // On hardware - to load agents from sources other than ROM the patch - // data KCafLoadPostProductionAgents must be set to True (non-zero). - // Default SymbianOS behavior is to only load agents from ROM - if ((KCafLoadPostProductionAgents == 0) && - !implArray[i]->RomBased()) - { - // If the agent is not in ROM, don't load it because it might - // be a security risk. - continue; - } -#endif - - // Construct all the agent infos from these implementations - TRAP(err, AddAgentL(*implArray[i])); - - // If we ran out of memory proagate the leave to the caller - // otherwise don't let a dodgy agent affect the construction of the other - // agents - if(err == KErrNoMemory) - { - User::Leave(KErrNoMemory); - } - } - CleanupStack::PopAndDestroy(&implArray); - - - if (!iDefaultAgent) - { - // If we didn't find a default agent, we have a big problem so panic - User::Panic(KCafPanicString, ECafPanicNoF32Agent); - } - } - -void CAgentResolver::AddAgentL(const CImplementationInformation& aImplInfo) - { - // Create a CAgentInfo instance - CAgentInfo* agentInfo = CAgentInfo::NewLC(aImplInfo); - - - if(IsF32Agent(*agentInfo)) - { - // It's the F32 Agent - if(iDefaultAgent) - { - // If we already have a default agent something is seriously wrong - User::Panic(KCafPanicString, ECafPanicDuplicateF32Agent); - } - - // Note that the default agent is NOT stored in the agents list, it is a special case - iDefaultAgent = agentInfo; - CleanupStack::Pop(agentInfo); - } - else - { - // All other agents go in the agent list - User::LeaveIfError(iAgentInfos.Append(agentInfo)); - CleanupStack::Pop(agentInfo); - - TInt mimeIndex=0; - - // Update our list of all supplier mime types supported by CAF - for(mimeIndex=0;mimeIndex < agentInfo->SupplierMimeTypes().Count(); mimeIndex++) - { - User::LeaveIfError(iSupplierMimeTypes.Append(*agentInfo->SupplierMimeTypes()[mimeIndex])); - } - - // Update our list of all consumer mime types supported by CAF - for(mimeIndex=0;mimeIndex < agentInfo->ConsumerMimeTypes().Count(); mimeIndex++) - { - User::LeaveIfError(iConsumerMimeTypes.Append(*agentInfo->ConsumerMimeTypes()[mimeIndex])); - } - } - } - -void CAgentResolver::DestroyListOfAgents() - { - iSupplierMimeTypes.Reset(); - iConsumerMimeTypes.Reset(); - - // cant forget to delete the default agent - delete iDefaultAgent; - iDefaultAgent = NULL; - - // Free memory assocated with the iAgentInfos array - iAgentInfos.ResetAndDestroy(); - } - -void CAgentResolver::DoCancel() - { - // Abort any update notification - iEcomSession->CancelNotifyOnChange(iStatus); - } - -void CAgentResolver::RunL() - { - // Called by the ECOM framework if a new agent appears - - // remove the existing list of agents and build a new one - DestroyListOfAgents(); - BuildListOfAgentsL(); - - // request notification of any further changes - iEcomSession->NotifyOnChange(iStatus); - SetActive(); - } - -TBool CAgentResolver::IsF32Agent(CAgentInfo& aAgentInfo) - { - // Check if the agent has no consumer or supplier mime types - // and that it has the correct name and Uid - if (aAgentInfo.Agent().ImplementationUid() == KF32AgentImplUid - && aAgentInfo.Agent().Name().Compare(KF32Agent()) == 0 - && aAgentInfo.ConsumerMimeTypes().Count() == 0 - && aAgentInfo.SupplierMimeTypes().Count() == 0) - { - return ETrue; - } - else - { - return EFalse; - } - } - -CAgentInfo& CAgentResolver::ResolveSupplierMimeL(const TDesC8& aMimeType) const - { - // Go through all the agents and return the one which supports the - // required supplier mime type - CAgentInfo* retVal=NULL; - - for (TInt i = 0; i < iAgentInfos.Count(); ++i) - { - if (iAgentInfos[i]->IsSupportedSupplier(aMimeType)) - { - retVal = iAgentInfos[i]; - break; - } - } - - if (!retVal) - { - User::Leave(KErrCANoAgent); - } - return *retVal; - } - -CAgentInfo& CAgentResolver::ResolveConsumerMime(const TDesC8& aMimeType) const - { - // By default, set the return value to be the default agent. If we find - // anything better, then we change it - CAgentInfo* retVal = iDefaultAgent; - - for (TInt i = 0; i < iAgentInfos.Count(); ++i) - { - if (iAgentInfos[i]->IsSupportedConsumer(aMimeType)) - { - retVal = iAgentInfos[i]; - break; - } - } - - ASSERT(retVal); - return *retVal; - } - -CAgentInfo& CAgentResolver::ResolveFileL(const TDesC& aURI, TDes& aActualUri, TContentShareMode aShareMode) const - { - // Go through all the agents and return the one which supports the file at the given URI - TBool thePrivateDir = EFalse; - TUid agentUid = ResolveDirectory(aURI, aActualUri, thePrivateDir); - - if(agentUid != iDefaultAgent->Agent().ImplementationUid()) - { - // this file must be living in a private server directory - // return the agent who owns the directory - return AgentInfoL(agentUid); - } - else - { - TInt agentsCount(iAgentInfos.Count()); - CAgentManager* agentManager = NULL; - for (TInt i = 0; i < agentsCount; ++i) - { - TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); - if(result != KErrNone) - { - if(KErrNoMemory == result) - { - User::Leave(result); - } - else - { - continue; - } - } - if (agentManager->IsRecognizedL(aURI, aShareMode)) - { - return *iAgentInfos[i]; - } - } - } - return *iDefaultAgent; - } - -CAgentInfo& CAgentResolver::ResolveFileL(RFile& aFile) const - { - // Go through all the agents and return the one which supports the file - - TInt agentsCount(iAgentInfos.Count()); - CAgentManager* agentManager = NULL; - for (TInt i = 0; i < agentsCount; ++i) - { - TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); - if(result != KErrNone) - { - if(KErrNoMemory == result) - { - User::Leave(result); - } - else - { - continue; - } - } - if (agentManager->IsRecognizedL(aFile)) - { - return *iAgentInfos[i]; - } - } - return *iDefaultAgent; - } - -TUid CAgentResolver::ResolveDirectory(const TDesC& aPath, TDes& aActualPath, TBool& aThePrivateDir) const - { - TInt i = 0; - TInt pathLength = 0; - TBuf pathLowerCase; - - // Assume it's a publicly accessable path - aThePrivateDir = EFalse; - - // Find the length of the path and private directory - pathLength = aPath.Length(); - - // Check that the path is long enough to be within a private directory - // and does not include "..\\".The "..\\" sequence could be a security risk - if(aPath.Find(KParentDir()) == KErrNotFound && pathLength >= KPrivateDirAndDriveLength) - { - // Create a lower case copy of the left hand side of the path - TPtrC lowerCasePtr = aPath.Mid(KPrivateDirOffset, KPrivateDirLength); - pathLowerCase.Copy(lowerCasePtr); - pathLowerCase.LowerCase(); - - // Compare the first directory in the path to \\private\\ - if(KPrivateDir() == pathLowerCase) - { - // It is a private directory of some sort - if(pathLength > KPrivateDirAndDriveLength) - { - // It must be a server private directory data cage - TPtrC serverDirectoryPath = aPath.Right(pathLength - KPrivateDirAndDriveLength); - for(i = 0; i < AgentInfoCount(); i++) - { - // See if the part after \\private\\ matches the agent name - TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName(); - TPtrC agentName = AgentInfo(i).Agent().Name(); - if(privateDirectoryName.Length() && agentName.Length() && agentName == serverDirectoryPath.Left(agentName.Length())) - { - // It must be this agent's private directory - // Convert \\private\\agentName\\... to \\private\\SID\\... - aActualPath.Copy(aPath.Left(KPrivateDirAndDriveLength)); - aActualPath.Append(privateDirectoryName); - aActualPath.Append(aPath.Right(pathLength - KPrivateDirAndDriveLength - agentName.Length())); - return AgentInfo(i).Agent().ImplementationUid(); - } - } - } - else - { - // It's just the c:\\private\\ directory - // Use the default agent, any calls will just fail - aThePrivateDir = ETrue; - } - } - } - - // Not an agent private directory so just return the default agent - aActualPath.Copy(aPath); - return iDefaultAgent->Agent().ImplementationUid(); - } - -HBufC* CAgentResolver::ConvertAgentFileNameL(const TDesC& aFileName) const - { - TInt i = 0; - TInt fileNameLength = 0; - TBuf pathLowerCase; - - fileNameLength = aFileName.Length(); - - // If the path is shorter than the x:\\private\\ it must be a F32 file - if(fileNameLength > KPrivateDirAndDriveLength) - { - // Create a lower case copy of the left hand side of the path - TPtrC lowerCasePtr = aFileName.Mid(KPrivateDirOffset, KPrivateDirLength); - pathLowerCase.Copy(lowerCasePtr); - pathLowerCase.LowerCase(); - - // Compare the first directory in the path to \\private\\ - if(KPrivateDir() == pathLowerCase) - { - // It is a private directory of some sort - if(fileNameLength > KPrivateDirAndDriveLength) - { - // It must be a server private directory data cage - TPtrC serverDirectoryPath = aFileName.Right(fileNameLength - KPrivateDirAndDriveLength); - for(i = 0; i < AgentInfoCount(); i++) - { - // See if the part after \\private\\ matches the agent name - TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName(); - TPtrC agentName = AgentInfo(i).Agent().Name(); - if(privateDirectoryName.Length() && agentName.Length() && privateDirectoryName == serverDirectoryPath.Left(privateDirectoryName.Length())) - { - // It is this agent's private directory - // Convert \\private\\SID\\... \\private\\agentName\\... - HBufC* buffer = HBufC::NewL(fileNameLength - privateDirectoryName.Length() + agentName.Length()); - TPtr ptr = buffer->Des(); - ptr.Copy(aFileName.Left(KPrivateDirAndDriveLength)); - ptr.Append(agentName); - ptr.Append(aFileName.Right(fileNameLength - KPrivateDirAndDriveLength - privateDirectoryName.Length())); - return buffer; - } - } - } - } - } - return aFileName.AllocL(); - } - -EXPORT_C TBool CAgentResolver::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer, TDes8& aFileMimeType, TDes8& aContentMimeType) - { - - // Given the filename and buffer from apparc, ask the agents in turn if they recognize the file - // Note this will not call the DefaultAgent (F32) because it won't be able to recognize anything - - TInt agentsCount(iAgentInfos.Count()); - CAgentManager* agentManager = NULL; - for (TInt i = 0; i < agentsCount; ++i) - { - TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); - if(result != KErrNone) - { - if(KErrNoMemory == result) - { - User::Leave(result); - } - else - { - continue; - } - } - if (agentManager->RecognizeFileL(aName, aBuffer, aFileMimeType, aContentMimeType)) - { - // force to lower case to ensure that chosen lower case scheme for mime types is maintained - aFileMimeType.LowerCase(); - aContentMimeType.LowerCase(); - return ETrue; - } - } - return EFalse; - } - - -void CAgentResolver::CleanImplArray(TAny* aArray) - { - static_cast(aArray)->ResetAndDestroy(); - } - -EXPORT_C TInt CAgentResolver::PreferredBufferSize() - { - TInt size=0; - - if(iDefaultAgent != NULL) - { - size = iDefaultAgent->PreferredBufferSize(); - } - - // Find out the maximum buffer requested by any agent - for (TInt i = 0; i < iAgentInfos.Count(); ++i) - { - if(iAgentInfos[i]->PreferredBufferSize() > size) - { - size = iAgentInfos[i]->PreferredBufferSize(); - } - } - return size; - } - - -EXPORT_C const RArray& CAgentResolver::ConsumerMimeTypes() const - { - return iConsumerMimeTypes; - } - - -EXPORT_C const RArray& CAgentResolver::SupplierMimeTypes() const - { - return iSupplierMimeTypes; - } - - -CAgentInfo& CAgentResolver::AgentInfoL(const TDesC& aAgentName) const - { - TBool found = EFalse; - TInt i = 0; - for(i = 0; i < iAgentInfos.Count(); i++) - { - if(iAgentInfos[i]->Agent().Name() == aAgentName) - { - found = ETrue; - break; - } - } - - if(!found) - { - // Can't find the agent so leave - User::Leave(KErrNotFound); - } - - return *iAgentInfos[i]; - } - -CAgentInfo& CAgentResolver::AgentInfoL(const TUid& aUid) const - { - TInt i = 0; - TBool found = EFalse; - - // See if it's the F32 agent - if(aUid == DefaultAgentUid()) - { - return *iDefaultAgent; - } - - for(i = 0; i < iAgentInfos.Count(); i++) - { - if(iAgentInfos[i]->Agent().ImplementationUid() == aUid) - { - found = ETrue; - break; - } - } - - if(!found) - { - // couldn't find the agent so leave - User::Leave(KErrNotFound); - } - - return *iAgentInfos[i]; - } - -CAgentInfo& CAgentResolver::AgentInfo(TInt aIndex) const - { - return *iAgentInfos[aIndex]; - } - -TInt CAgentResolver::AgentInfoCount() const - { - return iAgentInfos.Count(); - } - -TUid CAgentResolver::DefaultAgentUid() const - { - return iDefaultAgent->Agent().ImplementationUid(); - } +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 "resolver.h" +#include +#include +#include "agentinfo.h" +#include +#include +#include +#include + + +using namespace ContentAccess; + +// Constants for the F32 agent +_LIT(KF32Agent,"F32 CA Agent"); + + +_LIT(KParentDir, "..\\"); +_LIT(KPrivateDir, "\\private\\"); +const TInt KPrivateDirLength = 9; // "\\private\\" +const TInt KPrivateDirAndDriveLength = 11; // "x:\\private\\" +const TInt KPrivateDirOffset = 2; // "x:\\" + + +EXPORT_C CAgentResolver* CAgentResolver::NewLC(const TBool aDynamicAgentUpdate) + { + CAgentResolver* self = new (ELeave) CAgentResolver(aDynamicAgentUpdate); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C CAgentResolver* CAgentResolver::NewL(const TBool aDynamicAgentUpdate) + { + CAgentResolver* self = CAgentResolver::NewLC(aDynamicAgentUpdate); + CleanupStack::Pop(self); + return self; + } + +CAgentResolver::CAgentResolver(const TBool aDynamicAgentUpdate) : CActive(EPriorityStandard), iDynamicAgentUpdate(aDynamicAgentUpdate) + { + } + +CAgentResolver::~CAgentResolver() + { + // remove ourselves from the ActiveScheduler + if(IsAdded()) + { + Deque(); + } + + // Unload all the agents + DestroyListOfAgents(); + + // Close our ECOM session + if(iEcomSession) + { + if(iDynamicAgentUpdate) + { + iEcomSession->CancelNotifyOnChange(iStatus); + } + iEcomSession->Close(); + REComSession::FinalClose(); + } + + iSupplierMimeTypes.Close(); + iConsumerMimeTypes.Close(); + iAgentInfos.Close(); + } + +void CAgentResolver::ConstructL() + { + if(iDynamicAgentUpdate) + { + // Add ourselves to the current active scheduler so we can get dynamic + // updates when agents are removed or new agents are added + CActiveScheduler::Add(this); + } + + iEcomSession = &REComSession::OpenL(); + + // find all the agents + BuildListOfAgentsL(); + + if(iDynamicAgentUpdate) + { + // register for ECOM update notifications in case a new agent appears + SetActive(); + iEcomSession->NotifyOnChange(iStatus); + } + } + +void CAgentResolver::BuildListOfAgentsL() + { + TInt err = KErrNone; + + // Get all plugins which implement the agent interface + RImplInfoPtrArray implArray; + CleanupStack::PushL(TCleanupItem(CleanImplArray, &implArray)); + REComSession::ListImplementationsL(KCAAgentInterfaceUid, implArray); + + for (TInt i = 0; i < implArray.Count(); ++i) + { +#ifdef __EPOC32__ + // On hardware - to load agents from sources other than ROM the patch + // data KCafLoadPostProductionAgents must be set to True (non-zero). + // Default SymbianOS behavior is to only load agents from ROM + if ((KCafLoadPostProductionAgents == 0) && + !implArray[i]->RomBased()) + { + // If the agent is not in ROM, don't load it because it might + // be a security risk. + continue; + } +#endif + + // Construct all the agent infos from these implementations + TRAP(err, AddAgentL(*implArray[i])); + + // If we ran out of memory proagate the leave to the caller + // otherwise don't let a dodgy agent affect the construction of the other + // agents + if(err == KErrNoMemory) + { + User::Leave(KErrNoMemory); + } + } + CleanupStack::PopAndDestroy(&implArray); + + + if (!iDefaultAgent) + { + // If we didn't find a default agent, we have a big problem so panic + User::Panic(KCafPanicString, ECafPanicNoF32Agent); + } + } + +void CAgentResolver::AddAgentL(const CImplementationInformation& aImplInfo) + { + // Create a CAgentInfo instance + CAgentInfo* agentInfo = CAgentInfo::NewLC(aImplInfo); + + + if(IsF32Agent(*agentInfo)) + { + // It's the F32 Agent + if(iDefaultAgent) + { + // If we already have a default agent something is seriously wrong + User::Panic(KCafPanicString, ECafPanicDuplicateF32Agent); + } + + // Note that the default agent is NOT stored in the agents list, it is a special case + iDefaultAgent = agentInfo; + CleanupStack::Pop(agentInfo); + } + else + { + // All other agents go in the agent list + User::LeaveIfError(iAgentInfos.Append(agentInfo)); + CleanupStack::Pop(agentInfo); + + TInt mimeIndex=0; + + // Update our list of all supplier mime types supported by CAF + for(mimeIndex=0;mimeIndex < agentInfo->SupplierMimeTypes().Count(); mimeIndex++) + { + User::LeaveIfError(iSupplierMimeTypes.Append(*agentInfo->SupplierMimeTypes()[mimeIndex])); + } + + // Update our list of all consumer mime types supported by CAF + for(mimeIndex=0;mimeIndex < agentInfo->ConsumerMimeTypes().Count(); mimeIndex++) + { + User::LeaveIfError(iConsumerMimeTypes.Append(*agentInfo->ConsumerMimeTypes()[mimeIndex])); + } + } + } + +void CAgentResolver::DestroyListOfAgents() + { + iSupplierMimeTypes.Reset(); + iConsumerMimeTypes.Reset(); + + // cant forget to delete the default agent + delete iDefaultAgent; + iDefaultAgent = NULL; + + // Free memory assocated with the iAgentInfos array + iAgentInfos.ResetAndDestroy(); + } + +void CAgentResolver::DoCancel() + { + // Abort any update notification + iEcomSession->CancelNotifyOnChange(iStatus); + } + +void CAgentResolver::RunL() + { + // Called by the ECOM framework if a new agent appears + + // remove the existing list of agents and build a new one + DestroyListOfAgents(); + BuildListOfAgentsL(); + + // request notification of any further changes + iEcomSession->NotifyOnChange(iStatus); + SetActive(); + } + +TBool CAgentResolver::IsF32Agent(CAgentInfo& aAgentInfo) + { + // Check if the agent has no consumer or supplier mime types + // and that it has the correct name and Uid + if (aAgentInfo.Agent().ImplementationUid() == KF32AgentImplUid + && aAgentInfo.Agent().Name().Compare(KF32Agent()) == 0 + && aAgentInfo.ConsumerMimeTypes().Count() == 0 + && aAgentInfo.SupplierMimeTypes().Count() == 0) + { + return ETrue; + } + else + { + return EFalse; + } + } + +CAgentInfo& CAgentResolver::ResolveSupplierMimeL(const TDesC8& aMimeType) const + { + // Go through all the agents and return the one which supports the + // required supplier mime type + CAgentInfo* retVal=NULL; + + for (TInt i = 0; i < iAgentInfos.Count(); ++i) + { + if (iAgentInfos[i]->IsSupportedSupplier(aMimeType)) + { + retVal = iAgentInfos[i]; + break; + } + } + + if (!retVal) + { + User::Leave(KErrCANoAgent); + } + return *retVal; + } + +CAgentInfo& CAgentResolver::ResolveConsumerMime(const TDesC8& aMimeType) const + { + // By default, set the return value to be the default agent. If we find + // anything better, then we change it + CAgentInfo* retVal = iDefaultAgent; + + for (TInt i = 0; i < iAgentInfos.Count(); ++i) + { + if (iAgentInfos[i]->IsSupportedConsumer(aMimeType)) + { + retVal = iAgentInfos[i]; + break; + } + } + + ASSERT(retVal); + return *retVal; + } + +CAgentInfo& CAgentResolver::ResolveFileL(const TDesC& aURI, TDes& aActualUri, TContentShareMode aShareMode) const + { + // Go through all the agents and return the one which supports the file at the given URI + TBool thePrivateDir = EFalse; + TUid agentUid = ResolveDirectory(aURI, aActualUri, thePrivateDir); + + if(agentUid != iDefaultAgent->Agent().ImplementationUid()) + { + // this file must be living in a private server directory + // return the agent who owns the directory + return AgentInfoL(agentUid); + } + else + { + TInt agentsCount(iAgentInfos.Count()); + CAgentManager* agentManager = NULL; + for (TInt i = 0; i < agentsCount; ++i) + { + TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); + if(result != KErrNone) + { + if(KErrNoMemory == result) + { + User::Leave(result); + } + else + { + continue; + } + } + if (agentManager->IsRecognizedL(aURI, aShareMode)) + { + return *iAgentInfos[i]; + } + } + } + return *iDefaultAgent; + } + +CAgentInfo& CAgentResolver::ResolveFileL(RFile& aFile) const + { + // Go through all the agents and return the one which supports the file + + TInt agentsCount(iAgentInfos.Count()); + CAgentManager* agentManager = NULL; + for (TInt i = 0; i < agentsCount; ++i) + { + TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); + if(result != KErrNone) + { + if(KErrNoMemory == result) + { + User::Leave(result); + } + else + { + continue; + } + } + if (agentManager->IsRecognizedL(aFile)) + { + return *iAgentInfos[i]; + } + } + return *iDefaultAgent; + } + +TUid CAgentResolver::ResolveDirectory(const TDesC& aPath, TDes& aActualPath, TBool& aThePrivateDir) const + { + TInt i = 0; + TInt pathLength = 0; + TBuf pathLowerCase; + + // Assume it's a publicly accessable path + aThePrivateDir = EFalse; + + // Find the length of the path and private directory + pathLength = aPath.Length(); + + // Check that the path is long enough to be within a private directory + // and does not include "..\\".The "..\\" sequence could be a security risk + if(aPath.Find(KParentDir()) == KErrNotFound && pathLength >= KPrivateDirAndDriveLength) + { + // Create a lower case copy of the left hand side of the path + TPtrC lowerCasePtr = aPath.Mid(KPrivateDirOffset, KPrivateDirLength); + pathLowerCase.Copy(lowerCasePtr); + pathLowerCase.LowerCase(); + + // Compare the first directory in the path to \\private\\ + if(KPrivateDir() == pathLowerCase) + { + // It is a private directory of some sort + if(pathLength > KPrivateDirAndDriveLength) + { + // It must be a server private directory data cage + TPtrC serverDirectoryPath = aPath.Right(pathLength - KPrivateDirAndDriveLength); + for(i = 0; i < AgentInfoCount(); i++) + { + // See if the part after \\private\\ matches the agent name + TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName(); + TPtrC agentName = AgentInfo(i).Agent().Name(); + if(privateDirectoryName.Length() && agentName.Length() && agentName == serverDirectoryPath.Left(agentName.Length())) + { + // It must be this agent's private directory + // Convert \\private\\agentName\\... to \\private\\SID\\... + aActualPath.Copy(aPath.Left(KPrivateDirAndDriveLength)); + aActualPath.Append(privateDirectoryName); + aActualPath.Append(aPath.Right(pathLength - KPrivateDirAndDriveLength - agentName.Length())); + return AgentInfo(i).Agent().ImplementationUid(); + } + } + } + else + { + // It's just the c:\\private\\ directory + // Use the default agent, any calls will just fail + aThePrivateDir = ETrue; + } + } + } + + // Not an agent private directory so just return the default agent + aActualPath.Copy(aPath); + return iDefaultAgent->Agent().ImplementationUid(); + } + +HBufC* CAgentResolver::ConvertAgentFileNameL(const TDesC& aFileName) const + { + TInt i = 0; + TInt fileNameLength = 0; + TBuf pathLowerCase; + + fileNameLength = aFileName.Length(); + + // If the path is shorter than the x:\\private\\ it must be a F32 file + if(fileNameLength > KPrivateDirAndDriveLength) + { + // Create a lower case copy of the left hand side of the path + TPtrC lowerCasePtr = aFileName.Mid(KPrivateDirOffset, KPrivateDirLength); + pathLowerCase.Copy(lowerCasePtr); + pathLowerCase.LowerCase(); + + // Compare the first directory in the path to \\private\\ + if(KPrivateDir() == pathLowerCase) + { + // It is a private directory of some sort + if(fileNameLength > KPrivateDirAndDriveLength) + { + // It must be a server private directory data cage + TPtrC serverDirectoryPath = aFileName.Right(fileNameLength - KPrivateDirAndDriveLength); + for(i = 0; i < AgentInfoCount(); i++) + { + // See if the part after \\private\\ matches the agent name + TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName(); + TPtrC agentName = AgentInfo(i).Agent().Name(); + if(privateDirectoryName.Length() && agentName.Length() && privateDirectoryName == serverDirectoryPath.Left(privateDirectoryName.Length())) + { + // It is this agent's private directory + // Convert \\private\\SID\\... \\private\\agentName\\... + HBufC* buffer = HBufC::NewL(fileNameLength - privateDirectoryName.Length() + agentName.Length()); + TPtr ptr = buffer->Des(); + ptr.Copy(aFileName.Left(KPrivateDirAndDriveLength)); + ptr.Append(agentName); + ptr.Append(aFileName.Right(fileNameLength - KPrivateDirAndDriveLength - privateDirectoryName.Length())); + return buffer; + } + } + } + } + } + return aFileName.AllocL(); + } + +EXPORT_C TBool CAgentResolver::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer, TDes8& aFileMimeType, TDes8& aContentMimeType) + { + + // Given the filename and buffer from apparc, ask the agents in turn if they recognize the file + // Note this will not call the DefaultAgent (F32) because it won't be able to recognize anything + + TInt agentsCount(iAgentInfos.Count()); + CAgentManager* agentManager = NULL; + for (TInt i = 0; i < agentsCount; ++i) + { + TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL()); + if(result != KErrNone) + { + if(KErrNoMemory == result) + { + User::Leave(result); + } + else + { + continue; + } + } + if (agentManager->RecognizeFileL(aName, aBuffer, aFileMimeType, aContentMimeType)) + { + // force to lower case to ensure that chosen lower case scheme for mime types is maintained + aFileMimeType.LowerCase(); + aContentMimeType.LowerCase(); + return ETrue; + } + } + return EFalse; + } + + +void CAgentResolver::CleanImplArray(TAny* aArray) + { + static_cast(aArray)->ResetAndDestroy(); + } + +EXPORT_C TInt CAgentResolver::PreferredBufferSize() + { + TInt size=0; + + if(iDefaultAgent != NULL) + { + size = iDefaultAgent->PreferredBufferSize(); + } + + // Find out the maximum buffer requested by any agent + for (TInt i = 0; i < iAgentInfos.Count(); ++i) + { + if(iAgentInfos[i]->PreferredBufferSize() > size) + { + size = iAgentInfos[i]->PreferredBufferSize(); + } + } + return size; + } + + +EXPORT_C const RArray& CAgentResolver::ConsumerMimeTypes() const + { + return iConsumerMimeTypes; + } + + +EXPORT_C const RArray& CAgentResolver::SupplierMimeTypes() const + { + return iSupplierMimeTypes; + } + + +CAgentInfo& CAgentResolver::AgentInfoL(const TDesC& aAgentName) const + { + TBool found = EFalse; + TInt i = 0; + for(i = 0; i < iAgentInfos.Count(); i++) + { + if(iAgentInfos[i]->Agent().Name() == aAgentName) + { + found = ETrue; + break; + } + } + + if(!found) + { + // Can't find the agent so leave + User::Leave(KErrNotFound); + } + + return *iAgentInfos[i]; + } + +CAgentInfo& CAgentResolver::AgentInfoL(const TUid& aUid) const + { + TInt i = 0; + TBool found = EFalse; + + // See if it's the F32 agent + if(aUid == DefaultAgentUid()) + { + return *iDefaultAgent; + } + + for(i = 0; i < iAgentInfos.Count(); i++) + { + if(iAgentInfos[i]->Agent().ImplementationUid() == aUid) + { + found = ETrue; + break; + } + } + + if(!found) + { + // couldn't find the agent so leave + User::Leave(KErrNotFound); + } + + return *iAgentInfos[i]; + } + +CAgentInfo& CAgentResolver::AgentInfo(TInt aIndex) const + { + return *iAgentInfos[aIndex]; + } + +TInt CAgentResolver::AgentInfoCount() const + { + return iAgentInfos.Count(); + } + +TUid CAgentResolver::DefaultAgentUid() const + { + return iDefaultAgent->Agent().ImplementationUid(); + }