mmlibs/mmutilitylib/src/MmPluginUtils.cpp
changeset 0 b8ed18f6c07b
--- /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);
+			}
+		}
+	}