--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmutilitylib/src/MmPluginUtils.cpp Thu Oct 07 22:34:12 2010 +0100
@@ -0,0 +1,307 @@
+
+// MmPluginUtils.cpp
+
+// Copyright (c) 2005-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 <mm/mmpluginutils.h>
+#include <mm/mmcleanup.h>
+
+//
+// MmPluginUtils
+//
+
+/**
+Find a plugin with the requested interfaceUid and whose match string matches
+the default data field. Where there are more than one plugin, choose that
+with highest version no.
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TInt32 aKeyOffset,
+ const TDesC8& aDefaultData,
+ TUid aResolverUid)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray, aDefaultData, aResolverUid);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationKeyOffsetL(pluginArray,aKeyOffset);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+/**
+Find a plugin with the requested interfaceUid and whose match string matches
+the default data field. Where there are more than one plugin, choose that
+with highest version no.
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TInt32 aKeyOffset,
+ const TDesC8& aDefaultData)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray, aDefaultData);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationKeyOffsetL(pluginArray,aKeyOffset);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+/**
+Find a plugin with the requested interfaceUid and whose match string matches
+the default data field. Where there are more than one plugin, choose that
+with highest version no.
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TInt32 aKeyOffset)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationKeyOffsetL(pluginArray,aKeyOffset);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+
+/**
+Get the higher version of plugin passing keyoffset
+*/
+TAny* MmPluginUtils::GetHigherVersionImplementationKeyOffsetL(RImplInfoPtrArray& pluginArray, TInt32 aKeyOffset)
+ {
+ TAny* self = NULL;
+
+ if (pluginArray.Count() == 0)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ else if (pluginArray.Count() == 1)
+ {
+ self = REComSession::CreateImplementationL(pluginArray[0]->ImplementationUid(), aKeyOffset);
+ }
+ else
+ {
+ // create each in turn, starting with the highest version, which is the start element
+ for (TInt index = 0; index < pluginArray.Count(); index++)
+ {
+ TInt err=KErrNone;
+ self = NULL;
+ TRAP(err, self = REComSession::CreateImplementationL(pluginArray[index]->ImplementationUid(), aKeyOffset))
+ if (err == KErrNone)
+ {
+ break;
+ }
+ if (err != KErrNotSupported)
+ {
+ User::Leave(err);
+ }
+ }
+ if (!self)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+ return self;
+ }
+
+/*
+Similar but return destructor key via reference
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TUid& aDestructorKey,
+ const TDesC8& aDefaultData,
+ TUid aResolverUid)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray, aDefaultData, aResolverUid);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationaDestructorKeyL(pluginArray, aDestructorKey);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+/*
+Similar but return destructor key via reference
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TUid& aDestructorKey,
+ const TDesC8& aDefaultData)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray, aDefaultData);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationaDestructorKeyL(pluginArray, aDestructorKey);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+/*
+Similar but return destructor key via reference
+*/
+EXPORT_C TAny* MmPluginUtils::CreateImplementationL(TUid aInterfaceUid,
+ TUid& aDestructorKey)
+ {
+ RImplInfoPtrArray pluginArray;
+ CleanupResetAndDestroyPushL(pluginArray);
+
+ FindImplementationsL(aInterfaceUid, pluginArray);
+
+ // Get higher version implementation
+ TAny* higherversionplugin = GetHigherVersionImplementationaDestructorKeyL(pluginArray, aDestructorKey);
+
+ CleanupStack::PopAndDestroy(&pluginArray);
+ return higherversionplugin;
+ }
+
+/**
+Get the higher version of plugin passing destructorkey
+*/
+TAny* MmPluginUtils::GetHigherVersionImplementationaDestructorKeyL(RImplInfoPtrArray& pluginArray, TUid& aDestructorKey)
+ {
+ TAny* self = NULL;
+ if (pluginArray.Count() == 0)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ else if (pluginArray.Count() == 1)
+ {
+ self = REComSession::CreateImplementationL(pluginArray[0]->ImplementationUid(), aDestructorKey);
+ }
+ else
+ {
+ // create each in turn, starting with the highest version, which is the start element
+ for (TInt index = 0; index < pluginArray.Count(); index++)
+ {
+ TInt err = KErrNone;
+ self = NULL;
+ TRAP(err, self = REComSession::CreateImplementationL(pluginArray[index]->ImplementationUid(), aDestructorKey))
+ if (err == KErrNone)
+ {
+ break;
+ }
+ if (err != KErrNotSupported)
+ {
+ User::Leave(err);
+ }
+ }
+ if (!self)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+ return self;
+ }
+
+/*
+The function is an implementation of the templated TLinearOrder so it can order implementation information
+in an increasing version number.
+*/
+TInt VersionLinearOrderFunction(const CImplementationInformation& pluginA,
+ const CImplementationInformation& pluginB)
+ {
+ if (pluginA.Version() == pluginB.Version())
+ {
+ return 0;
+ }
+
+ return (pluginA.Version() < pluginB.Version())? 1: -1;
+ }
+
+EXPORT_C void MmPluginUtils::FindImplementationsL(TUid aInterfaceUid,
+ RImplInfoPtrArray& aPluginArray)
+ {
+ REComSession::ListImplementationsL(aInterfaceUid, aPluginArray);
+
+ CheckAndSortL(aPluginArray);
+ }
+
+EXPORT_C void MmPluginUtils::FindImplementationsL(TUid aInterfaceUid,
+ RImplInfoPtrArray& aPluginArray,
+ const TDesC8& aDefaultData,
+ TUid aResolverUid)
+ {
+ TEComResolverParams resolverParams;
+ resolverParams.SetDataType(aDefaultData);
+
+ FindImplementationsL(aInterfaceUid, aPluginArray, resolverParams, aResolverUid);
+ }
+
+EXPORT_C void MmPluginUtils::FindImplementationsL(TUid aInterfaceUid,
+ RImplInfoPtrArray& aPluginArray,
+ const TDesC8& aDefaultData)
+ {
+ TEComResolverParams resolverParams;
+ resolverParams.SetDataType(aDefaultData);
+
+ FindImplementationsL(aInterfaceUid, aPluginArray, resolverParams);
+ }
+
+void MmPluginUtils::FindImplementationsL(TUid aInterfaceUid,
+ RImplInfoPtrArray& aPluginArray,
+ TEComResolverParams& aResolverParams)
+ {
+ REComSession::ListImplementationsL(aInterfaceUid, aResolverParams, aPluginArray);
+
+ CheckAndSortL(aPluginArray);
+ }
+
+void MmPluginUtils::FindImplementationsL(TUid aInterfaceUid,
+ RImplInfoPtrArray& aPluginArray,
+ TEComResolverParams& aResolverParams,
+ TUid aResolverUid)
+ {
+ REComSession::ListImplementationsL(aInterfaceUid, aResolverParams, aResolverUid, aPluginArray);
+
+ CheckAndSortL(aPluginArray);
+ }
+
+void MmPluginUtils::CheckAndSortL(RImplInfoPtrArray& aPluginArray)
+ {
+ // there must be at least one implementation
+ if (aPluginArray.Count() > 0)
+ {
+ if (aPluginArray.Count() > 1)
+ {
+ aPluginArray.Sort(VersionLinearOrderFunction);
+ }
+
+ // if the highest version is zero there is no need to linger -- it should not be supported
+ // and we will leave
+ if (aPluginArray[0]->Version() == 0)
+ {
+ // plugins were found to be malformed, with 0 version numbers
+ User::Leave(KErrNotSupported);
+ }
+ }
+ }