imagingandcamerafws/imagingfws/ImageDisplay/src/Resolver/ImageDisplayResolver.cpp
author Tapani Kanerva <tapani.kanerva@nice.fi>
Tue, 16 Nov 2010 14:11:25 +0200
branchRCL_3
changeset 67 b35006be8823
parent 0 40261b775718
permissions -rw-r--r--
Bug 3673 - Seeking via grabbing the Music Player progress bar does not work.

// Copyright (c) 2004-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:
//

/** @file
	@internalComponent */
#include <ecom/ecom.h>
#include <ecom/ecomerrorcodes.h>
#include <ecom/implementationinformation.h>

#include "ImageDisplayResolver.h"
#include "ImageDisplayResolvrUtils.h"

_LIT(KIclResolverPanicCategory, "ImageDisplayResolver");

// To save some space, we don't support IdentifyImplementationL()

GLDEF_C void Panic(TInt aReason)
	{
	User::Panic(KIclResolverPanicCategory, aReason);
	}

/** 
 * Constructs and initialises a new instance of CImageDisplayResolver.
 *
 * @param     "MPublicRegistry& aRegistry"
 *            A reference to the registry on which it will operate
 * @return    "CImageDisplayResolver*"
 *            A pointer to the newly constructed resolver
 */
CImageDisplayResolver* CImageDisplayResolver::NewL(MPublicRegistry& aRegistry)
	{
	return new(ELeave) CImageDisplayResolver(aRegistry);
	}

/** 
 *
 * Default destructor
 *
 */
CImageDisplayResolver::~CImageDisplayResolver()
	{
	}

/** 
 *
 * Default constructor
 *
 * @param     "MPublicRegistry& aRegistry"
 *            A reference to the registry on which it will operate
 */
CImageDisplayResolver::CImageDisplayResolver(MPublicRegistry& aRegistry)
	: CResolver(aRegistry)
	{
	}

/** 
 *
 * Request that the resolver identify the most appropriate interface
 * implementation.
 *
 * @param     "TUid aInterfaceUid"
 *            The Uid of the interface you want to match against
 * @param     "const TEComResolverParams& aAdditionalParameters"
 *            A passed in reference to the parameters on which to match
 * @return    "TUid"
 *            The implementation Uid of the single best match found
 */
TUid CImageDisplayResolver::IdentifyImplementationL(TUid /*aInterfaceUid*/, const TEComResolverParams& /*aAdditionalParameters*/) const
	{
	// To save some space, we don't support IdentifyImplementationL()
	return KNullUid;
	}

/**
 *
 * List all the implementations which satisfy the specified interface, ignoring 
 * any implementations that have their Disabled flag set or are not of the 
 * current framework version.
 *
 * The list is sorted:
 * 1) For EMatchString in desending order of number of bytes matched and version number.
 * 2) For EMatchMIMEType in asending order of the MIME position that matched and
 *    desending version number.
 * 3) All others - desending version numbers.
 *
 * @param     "TUid aInterfaceUid"
 *            The Uid of the interface you want to match against
 * @param     "const TEComResolverParams& aAdditionalParameters"
 *            A passed in reference to the parameters on which to match
 * @return    "RImplInfoArray*"
 *            The list of matches found
 */
 RImplInfoArray* CImageDisplayResolver::ListAllL(TUid aInterfaceUid, const TEComResolverParams& aAdditionalParameters) const
	{

	// Retrieve the match data from the descriptor
	CCustomMatchData* customMatch = CCustomMatchData::NewLC(aAdditionalParameters.DataType());

	TResolverMatchType matchType = customMatch->MatchType();
	// get the flags that the plugin must support
	TPluginFlagsNeeded pluginFlagsNeeded = customMatch->PluginFlagsNeeded();

	TUid baseType = customMatch->BaseType();
	TUid subType = customMatch->SubType();
	TUid implementationUid = customMatch->ImplementationType();
	HBufC8* matchString = customMatch->MatchString().AllocLC();
	HBufC* fileSuffix = customMatch->FileSuffix().AllocLC();

	// Use the member var to create the array so that we get proper cleanup behaviour
	RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid);

	RArray<TSortImplInfo> sortList;
	CleanupClosePushL(sortList);

	TInt matchLevel = 0;

	// Loop through the implementations matching on appropriate info
	const TInt count = fullList.Count();
	TInt index;

	for(index = 0; index < count; index++)
		{
		const CImplementationInformation& impData = *(fullList[index]);
		COpaqueDataParse* parse = NULL;
		TRAPD(error, parse = COpaqueDataParse::NewL(impData.OpaqueData()));
		if (error!=KErrNone)
			{
			if (error==KErrNotSupported)
				{
				// means that the resource entry was not valid
				continue;
				}
			else
				User::Leave(error);
			}

		CleanupStack::PushL(parse);

		// we can assume the version is valid as it is checked in 
		// COpaqueDataParse::ConstructL() which leaves if not valid
		ASSERT(parse->Version() <= KIclPluginFrameworkVersionMax);
		
		// get the plugin's flags
		TBool flagsSupported = ETrue;
		if ((pluginFlagsNeeded & ESetSourceRectSupportNeeded) &&
			!parse->IsSetSourceRectSupported())
			{
			flagsSupported = EFalse;
			}

		if (!impData.Disabled() && flagsSupported)
			{
			TBool matchFound = EFalse;
			switch(matchType)
				{
				case EMatchMIMEType:
					{
					if(!parse->OnlyUidsAvail())
						{ //If codec has no MIME types ignore it
						parse->EnsureMIMETypesReadL();
						const TInt numMimeTypes = parse->MIMETypesCount();
						for (TInt index2 = 0; index2 < numMimeTypes; index2++)
							{
							const TDesC8& mimeType = parse->MIMEType(index2);
							if (COpaqueDataParse::CompareMIMETypes(*matchString, mimeType))
								{
								matchFound = ETrue;
								matchLevel = index2;
								break;
								}
							}
						}

					break;
					}

				case EMatchString:
					{ // Match the match strings
					if (CImageDisplayResolverUtils::Match(*matchString, impData.DataType(), matchLevel))
						matchFound = ETrue;
					break;
					}

				case EMatchUids:
					{ // match on UIDs
					if (implementationUid != KNullUid)
						{// We're matching on codec implementation uid
						if (implementationUid == impData.ImplementationUid())
							matchFound = ETrue;
						}
					else
						{ // We're matching on image type (and sub-type)
						if (parse->CompareUids(baseType, subType))
							matchFound = ETrue;
						}
					break;
					}

				case EMatchFileSuffix:
					{
					if(!parse->OnlyUidsAvail() && parse->IsOpenAgainstSuffix())
						{ //If codec has file extensions and allow matching on them
						parse->EnsureExtnsReadL();
						const TInt numExtns = parse->ExtnsCount();
						for (TInt index2 = 0; index2 < numExtns; index2++)
							{
							const TDesC8& extn = parse->Extn(index2);
							if (COpaqueDataParse::CompareFileSuffixL(*fileSuffix, extn))
								{
								matchFound = ETrue;
								matchLevel = index2;
								break;
								}
							}
						}

					break;
					}

				default:
					{//unknown match type
					Panic(KErrArgument);
					}
				}
			if (matchFound)
				{
				TSortImplInfo sortInfo(fullList[index],matchLevel);
				User::LeaveIfError(sortList.Append(sortInfo));
				}
			}
		CleanupStack::PopAndDestroy(parse);
		}

	TLinearOrder<TSortImplInfo>* sortFunction = NULL;
	if(matchType==EMatchMIMEType)
		sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortAsending);
	else
		sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortDesending);

	sortList.Sort(*sortFunction);
	delete sortFunction;

	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
	CleanupStack::PushL(retList);
	// coverity[double_push]
	CleanupClosePushL(*retList); // note the double PushL - will Close and delete on PopAndDestroy(2)

	TInt noEntries = sortList.Count();
	for(index = 0; index < noEntries; index++)
		User::LeaveIfError(retList->Append(sortList[index].iImplInfo));

	CleanupStack::Pop(2, retList); // retList x2

	CleanupStack::PopAndDestroy(4, customMatch); //sortList, fileSuffix, matchString, customMatch

	return retList;
	}

/**
 * Function to sort an array of TSortImplInfo in asending order of the match level and
 * then in desending order of version numbers.
 *
 * @param	"const TSortImplInfo& aImpInfo1"
 *			First element.
 * @param	"const TSortImplInfo& aImpInfo2"
 *			Second element.
 * @return	"TInt"
 *			Indication of element swapping order.
 */
TInt CImageDisplayResolver::SortAsending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2)
	{
	TInt result = aImpInfo1.iMatchLevel - aImpInfo2.iMatchLevel;

	if(result == 0)
		result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version();

	return result;
	}

/**
 * Function to sort an array of TSortImplInfo in desending order of the match level 
 * and version numbers.
 *
 * @param	"const TSortImplInfo& aImpInfo1"
 *			First element.
 * @param	"const TSortImplInfo& aImpInfo2"
 *			Second element.
 * @return	"TInt"
 *			Indication of element swapping order.
 */
TInt CImageDisplayResolver::SortDesending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2)
	{
	TInt result = aImpInfo2.iMatchLevel - aImpInfo1.iMatchLevel;

	if(result == 0)
		result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version();

	return result;
	}

/**
 * Construtor for the TSortImplInfo class
 *
 * @param	"CImplementationInformation *const aImplInfo"
 *			A implementation information element to be soreted.
 * @param	"TInt aMatchLevel"
 *			The matching level of the entry
 */
TSortImplInfo::TSortImplInfo(CImplementationInformation *const aImplInfo, TInt aMatchLevel):
	iImplInfo(aImplInfo),
	iMatchLevel(aMatchLevel)
	{
	}