os/mm/mmlibs/mmfw/src/Client/Utility/mmfclientutility.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/mmlibs/mmfw/src/Client/Utility/mmfclientutility.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2531 @@
     1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Audio, MIDI and Video client utility functions.
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <e32std.h>
    1.22 +#include <f32file.h>
    1.23 +#include <bautils.h>
    1.24 +#include <mmf/server/mmfdrmpluginserverproxy.h>
    1.25 +#include <caf/content.h>
    1.26 +#include <caf/data.h>
    1.27 +using namespace ContentAccess;
    1.28 +
    1.29 +#include "mmfclientutility.h"
    1.30 +#include <mmf/common/mmfpaniccodes.h>
    1.31 +
    1.32 +const TInt KMaxMimeLength = 256;
    1.33 +const TInt KMaxHeaderSize = 256;
    1.34 +const TInt KExpandSize = 100;
    1.35 +
    1.36 +#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
    1.37 +	const TInt KDefaultScreenNo = 0;
    1.38 +#endif
    1.39 +
    1.40 +void CUPanic(TInt aCUPanicCode)
    1.41 +	{
    1.42 +	_LIT(KMMFMediaClientUtilityPaanicCategory, "MMFClientUtility");
    1.43 +	User::Panic(KMMFMediaClientUtilityPaanicCategory, aCUPanicCode);
    1.44 +	}
    1.45 +
    1.46 +/**
    1.47 + * @internalComponent
    1.48 + */
    1.49 +EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid)
    1.50 +	{
    1.51 +	TUid ECOMUid = KNullUid;
    1.52 +	if (aMdaFormatUid == KUidMdaClipFormatWav)	
    1.53 +		ECOMUid = TUid::Uid(KMmfUidFormatWAVWrite);
    1.54 +	else if (aMdaFormatUid == KUidMdaClipFormatAu)	
    1.55 +		ECOMUid = TUid::Uid(KMmfUidFormatAUWrite);
    1.56 +	else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)	
    1.57 +		ECOMUid = TUid::Uid(KMmfUidFormatRAWWrite);
    1.58 +	else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)	
    1.59 +		ECOMUid = TUid::Uid(KAdvancedUidFormatAMRWrite);
    1.60 +
    1.61 +	return ECOMUid;
    1.62 +	}
    1.63 +
    1.64 +/**
    1.65 + * @internalComponent
    1.66 + */
    1.67 +EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid)
    1.68 +	{
    1.69 +	TUid ECOMUid = KNullUid;
    1.70 +	if (aMdaFormatUid == KUidMdaClipFormatWav)	
    1.71 +		ECOMUid = TUid::Uid(KMmfUidFormatWAVRead);
    1.72 +	else if (aMdaFormatUid == KUidMdaClipFormatAu)	
    1.73 +		ECOMUid = TUid::Uid(KMmfUidFormatAURead);
    1.74 +	else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)	
    1.75 +		ECOMUid = TUid::Uid(KMmfUidFormatRAWRead);
    1.76 +	else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)	
    1.77 +		ECOMUid = TUid::Uid(KAdvancedUidFormatAMRRead);
    1.78 +
    1.79 +	return ECOMUid;
    1.80 +	}
    1.81 +
    1.82 +/**
    1.83 + * @internalComponent
    1.84 + */
    1.85 +EXPORT_C TInt CMMFClientUtility::GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength)
    1.86 +	{
    1.87 +	RFs fsSession;
    1.88 +	RFile file;
    1.89 +	TInt error = KErrNone;
    1.90 +
    1.91 +	if ((error = fsSession.Connect()) == KErrNone)
    1.92 +		{
    1.93 +		if ((error = file.Open(fsSession, aFileName, EFileShareReadersOrWriters)) == KErrNone)
    1.94 +			{
    1.95 +			TInt size = 0;
    1.96 +
    1.97 +			if ((error = file.Size(size)) == KErrNone)
    1.98 +				{
    1.99 +				if (size > 0)
   1.100 +					{
   1.101 +					if (size > aMaxLength) 
   1.102 +						size = aMaxLength;
   1.103 +
   1.104 +					error = file.Read(aHeaderData, size);
   1.105 +					}
   1.106 +				}
   1.107 +			file.Close();
   1.108 +			}
   1.109 +		fsSession.Close();
   1.110 +		}
   1.111 +
   1.112 +	return error;
   1.113 +	}
   1.114 +
   1.115 +/**
   1.116 + * @internalComponent
   1.117 + */
   1.118 +EXPORT_C TFourCC CMMFClientUtility::ConvertMdaCodecToFourCC(TMdaPackage& aCodec)
   1.119 +	{
   1.120 +	TFourCC dataType = KMMFFourCCCodeNULL;	
   1.121 +	switch (aCodec.Uid().iUid)
   1.122 +		{
   1.123 +		case KUidMdaWavPcmCodecDefine: 
   1.124 +			{
   1.125 +			TMdaPcmWavCodec* pcmWavCodec = (TMdaPcmWavCodec*)&aCodec;
   1.126 +			if (pcmWavCodec->iBits == TMdaPcmWavCodec::E8BitPcm)
   1.127 +				dataType = KMMFFourCCCodePCMU8; //8 bit PCM
   1.128 +			else 
   1.129 +				dataType = KMMFFourCCCodePCM16; //16 bit PCM
   1.130 +			break;
   1.131 +			}
   1.132 +		case KUidMdaAu8PcmCodecDefine:
   1.133 +			dataType = KMMFFourCCCodePCM8;
   1.134 +			break;
   1.135 +		case KUidMdaAuCodecDefine:
   1.136 +		case KUidMdaAu16PcmCodecDefine:
   1.137 +			dataType = KMMFFourCCCodePCM16B;
   1.138 +			break;
   1.139 +
   1.140 +		case KUidMdaAuMulawCodecDefine:
   1.141 +		case KUidMdaWavMulawCodecDefine:
   1.142 +		case KUidMdaRawAudioMulawCodecDefine:  //uLAW
   1.143 +			dataType = KMMFFourCCCodeMuLAW;
   1.144 +			break;
   1.145 +		case KUidMdaAuAlawCodecDefine:
   1.146 +		case KUidMdaWavAlawCodecDefine:
   1.147 +		case KUidMdaRawAudioAlawCodecDefine:	 //ALAW
   1.148 +			dataType = KMMFFourCCCodeALAW;
   1.149 +			break;
   1.150 +		case KUidMdaRawAudioS8PcmCodecDefine:	 //  P8
   1.151 +			dataType = KMMFFourCCCodePCM8;
   1.152 +			break;
   1.153 +		case KUidMdaRawAudioU8PcmCodecDefine:	  // PU8
   1.154 +			dataType = KMMFFourCCCodePCMU8;
   1.155 +			break;
   1.156 +		case KUidMdaRawAudioSL16PcmCodecDefine: // P16
   1.157 +			dataType = KMMFFourCCCodePCM16;
   1.158 +			break;
   1.159 +		case KUidMdaRawAudioSB16PcmCodecDefine: //P16B
   1.160 +			dataType = KMMFFourCCCodePCM16B;
   1.161 +			break;
   1.162 +		case KUidMdaRawAudioUL16PcmCodecDefine: //PU16
   1.163 +			dataType = KMMFFourCCCodePCMU16;
   1.164 +			break;
   1.165 +		case KUidMdaRawAudioUB16PcmCodecDefine: //PU6B
   1.166 +			dataType = KMMFFourCCCodePCMU16B; 
   1.167 +			break;
   1.168 +		case KUidMdaGsmWavCodecDefine: //GSM6 
   1.169 +			dataType = KMMFFourCCCodeGSM610;
   1.170 +			break;
   1.171 +		case KUidMdaWavImaAdpcmCodecDefine:
   1.172 +			dataType = KMMFFourCCCodeIMAD;
   1.173 +			break;
   1.174 +		case KUidMdaRawAmrCodecDefine:
   1.175 +			dataType = KMMFFourCCCodeAMR;
   1.176 +			break;
   1.177 +		default:	// Not a Uid we recognise
   1.178 +			dataType = KMMFFourCCCodeNULL;
   1.179 +			break;
   1.180 +		}
   1.181 +	return dataType;
   1.182 +	}
   1.183 +
   1.184 +
   1.185 +CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewL(TMMSource& aSource, TBool aSecureDRMMode)
   1.186 +	{
   1.187 +	CMMFUtilityFileInfo* self = CMMFUtilityFileInfo::NewLC(aSource, aSecureDRMMode);
   1.188 +	CleanupStack::Pop(self);
   1.189 +	return self;
   1.190 +	}
   1.191 +
   1.192 +
   1.193 +CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewLC(TMMSource& aSource, TBool aSecureDRMMode)
   1.194 +	{
   1.195 +	CMMFUtilityFileInfo* self = new (ELeave) CMMFUtilityFileInfo;
   1.196 +	CleanupStack::PushL(self);
   1.197 +	self->ConstructL(aSource, aSecureDRMMode);
   1.198 +	return self;
   1.199 +	}
   1.200 +
   1.201 +
   1.202 +void CMMFUtilityFileInfo::ConstructL(const TMMSource& aSource, TBool aSecureDRMMode)
   1.203 +	{
   1.204 +	if (!aSecureDRMMode)
   1.205 +		{
   1.206 +		if (aSource.SourceType()==KUidMMFileSource)
   1.207 +			{
   1.208 +			const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
   1.209 +			iData = CData::NewL(TVirtualPathPtr(fileSource.Name(), fileSource.UniqueId()),
   1.210 +								EContentShareReadWrite);
   1.211 +			}
   1.212 +
   1.213 +		if (aSource.SourceType()==KUidMMFileHandleSource)
   1.214 +			{
   1.215 +			const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
   1.216 +			iData = CData::NewL(fileHandleSource.Handle(), fileHandleSource.UniqueId());
   1.217 +			}
   1.218 +		
   1.219 +		TInt err = iData->SetProperty(EAgentPropertyAgentUI, aSource.IsUIEnabled());		
   1.220 +		if (err != KErrNone && err != KErrCANotSupported)
   1.221 +			{
   1.222 +			// KErrCANotSupported isn't a problem for us so eat the error code.
   1.223 +			User::Leave(err);
   1.224 +			}
   1.225 +
   1.226 +		err = iData->EvaluateIntent(aSource.Intent());
   1.227 +		User::LeaveIfError(err);
   1.228 +		}
   1.229 +	else
   1.230 +		{
   1.231 +		// Use RMMFDRMPluginServerProxy as medium
   1.232 +		iDrmPluginServer = new (ELeave) RMMFDRMPluginServerProxy;
   1.233 +		User::LeaveIfError(iDrmPluginServer->Open());
   1.234 +		
   1.235 +		CBufFlat* dataBuffer = CBufFlat::NewL(KExpandSize);
   1.236 +		CleanupStack::PushL(dataBuffer);
   1.237 +		RBufWriteStream stream;
   1.238 +		stream.Open(*dataBuffer);
   1.239 +		CleanupClosePushL(stream);
   1.240 +		
   1.241 +		stream.WriteInt32L(aSource.UniqueId().Length());
   1.242 +		stream.WriteL(aSource.UniqueId());
   1.243 +		stream.WriteInt32L(aSource.IsUIEnabled());
   1.244 +		TPckgBuf<ContentAccess::TIntent> intentPckg(aSource.Intent());
   1.245 +		stream.WriteL(intentPckg);
   1.246 +		stream.CommitL();
   1.247 +	
   1.248 +		CleanupStack::PopAndDestroy(&stream);
   1.249 +		if (aSource.SourceType()==KUidMMFileSource)
   1.250 +			{
   1.251 +			const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
   1.252 +			iDrmPluginServer->OpenDataContentL(fileSource.Name(), dataBuffer->Ptr(0));
   1.253 +			}
   1.254 +		if (aSource.SourceType()==KUidMMFileHandleSource)
   1.255 +			{
   1.256 +			const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
   1.257 +			iDrmPluginServer->OpenDataContentL(fileHandleSource.Handle(), dataBuffer->Ptr(0));
   1.258 +			}
   1.259 +		CleanupStack::PopAndDestroy(dataBuffer);
   1.260 +		}
   1.261 +	}
   1.262 +
   1.263 +TInt CMMFUtilityFileInfo::EvaluateIntent(TIntent aIntent)
   1.264 +	{
   1.265 +	if (iData)
   1.266 +		{
   1.267 +		return iData->EvaluateIntent(aIntent);
   1.268 +		}
   1.269 +	else
   1.270 +		{
   1.271 +		ASSERT(iDrmPluginServer);
   1.272 +		return iDrmPluginServer->EvaluateDataContentIntent(aIntent);
   1.273 +		}
   1.274 +	}
   1.275 +/**
   1.276 + * @internalComponent
   1.277 + */
   1.278 +TBool CMMFUtilityFileInfo::GetFileMimeTypeL(TDes8& aMimeType)
   1.279 +	{
   1.280 +	if (iData)
   1.281 +		{
   1.282 +		return iData->GetMimeTypeL(aMimeType);
   1.283 +		}
   1.284 +	else
   1.285 +		{
   1.286 +		ASSERT(iDrmPluginServer);
   1.287 +		return iDrmPluginServer->GetDataContentMimeTypeL(aMimeType);
   1.288 +		}
   1.289 +	}
   1.290 +
   1.291 +/**
   1.292 + * @internalComponent
   1.293 + */
   1.294 +void CMMFUtilityFileInfo::GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength)
   1.295 +	{
   1.296 +	if (iData)
   1.297 +		{
   1.298 +		TInt size = 0;
   1.299 +		iData->DataSizeL(size);
   1.300 +		if (size > 0)
   1.301 +			{
   1.302 +			if (size > aMaxLength) 
   1.303 +				size = aMaxLength;
   1.304 +			TInt pos = 0;
   1.305 +			User::LeaveIfError(iData->Seek(ESeekStart, pos));
   1.306 +			User::LeaveIfError(iData->Read(aHeaderData, size));
   1.307 +			}
   1.308 +		}
   1.309 +	else
   1.310 +		{
   1.311 +		ASSERT(iDrmPluginServer);
   1.312 +		iDrmPluginServer->GetDataContentFileHeaderL(aHeaderData, aMaxLength);
   1.313 +		}
   1.314 +	}
   1.315 +
   1.316 +/**
   1.317 + * @internalComponent
   1.318 + */
   1.319 +EXPORT_C HBufC8* CMMFClientUtility::GetFileExtensionL(const TDesC& aFileName)
   1.320 +	{
   1.321 +	TParse fileName;
   1.322 +	fileName.Set(aFileName,NULL,NULL);
   1.323 +	HBufC8* fileSuffix = NULL;
   1.324 +	if(fileName.ExtPresent())
   1.325 +		{
   1.326 +		TPtrC fileSuffixPtr(fileName.Ext());
   1.327 +		fileSuffix = HBufC8::NewL(fileSuffixPtr.Length());
   1.328 +		fileSuffix->Des().Copy(fileSuffixPtr);
   1.329 +		}
   1.330 +	else
   1.331 +		{
   1.332 +		fileSuffix = KNullDesC8().AllocL();
   1.333 +		}
   1.334 +	return fileSuffix;
   1.335 +	}
   1.336 +
   1.337 +
   1.338 +/**
   1.339 + * @internalComponent
   1.340 + */
   1.341 +CMMFUtilityFileInfo::~CMMFUtilityFileInfo()
   1.342 +	{
   1.343 +	if (iData)
   1.344 +		{
   1.345 +		delete iData;
   1.346 +		}
   1.347 +	if (iDrmPluginServer)
   1.348 +		{
   1.349 +		iDrmPluginServer->Close();
   1.350 +		delete iDrmPluginServer;
   1.351 +		}
   1.352 +	}
   1.353 +
   1.354 +/*
   1.355 + * @internalComponent
   1.356 + *
   1.357 + * Returns an integer rating indicating how well the supplied format matches
   1.358 + * the header data and file extension supplied.
   1.359 + * 3 brownie points awarded for data & suffix match.
   1.360 + * 2 brownie points awarded for data match alone.
   1.361 + * 1 brownie point awarded for suffix match alone.
   1.362 + */
   1.363 +TInt CMMFClientUtility::GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension)
   1.364 +	{
   1.365 +	TInt browniePoints = 0;
   1.366 +
   1.367 +	if (aHeaderData.Length() > 0) // Non empty file
   1.368 +		{
   1.369 +		if (aFileExtension.Length() > 0) // With a file extension
   1.370 +			{
   1.371 +			if (format->SupportsHeaderDataL(aHeaderData) && 
   1.372 +				format->SupportsFileExtension(aFileExtension))
   1.373 +				{
   1.374 +				browniePoints = 3;
   1.375 +				}
   1.376 +			else if (format->SupportsHeaderDataL(aHeaderData))
   1.377 +				{
   1.378 +				browniePoints = 2;
   1.379 +				}
   1.380 +			else
   1.381 +				{
   1.382 +				// See if this format has any 'empty' match data or no match data, indicating 
   1.383 +				// that this format will match extension alone even if data present.
   1.384 +				// (A format may have more than one match data string.)
   1.385 +				const CDesC8Array& supportedHeaderData = format->SupportedHeaderData();
   1.386 +
   1.387 +				if (supportedHeaderData.Count() == 0)
   1.388 +					{
   1.389 +					// No header data indicated.
   1.390 +					if (format->SupportsFileExtension(aFileExtension))
   1.391 +						{
   1.392 +							browniePoints = 1;
   1.393 +						}
   1.394 +					}
   1.395 +				else
   1.396 +					{
   1.397 +					for (register TInt i = 0; i < supportedHeaderData.Count(); i++)
   1.398 +						{
   1.399 +						if ((supportedHeaderData[i].Length() == 0) && 
   1.400 +							format->SupportsFileExtension(aFileExtension))
   1.401 +							{
   1.402 +							browniePoints = 1;
   1.403 +							}
   1.404 +						}
   1.405 +					}
   1.406 +				}
   1.407 +			}
   1.408 +		else
   1.409 +			{
   1.410 +			// No file suffix, so must match header data alone.
   1.411 +			if (format->SupportsHeaderDataL(aHeaderData))
   1.412 +				{
   1.413 +				browniePoints = 2;
   1.414 +				}
   1.415 +			}
   1.416 +		}
   1.417 +	else // Empty File
   1.418 +		{
   1.419 +		// We have no choice but to match extension, if there is one.
   1.420 +		if ((aFileExtension.Length() > 0) && format->SupportsFileExtension(aFileExtension))
   1.421 +			{
   1.422 +			browniePoints = 1;
   1.423 +			}
   1.424 +		}
   1.425 +
   1.426 +	return browniePoints;
   1.427 +}
   1.428 +
   1.429 +/**
   1.430 + * @internalComponent
   1.431 + *
   1.432 + * This function parses all the play & record formats in the given list of controllers,
   1.433 + * looking for controllers & formats that best match the requirements. 
   1.434 + * Play controllers will be returned before record controllers, and
   1.435 + * in cases of equal priority between formats, ECom order will be maintained.
   1.436 + *
   1.437 + * @param	"aControllers"	
   1.438 + *			A reference to a user supplied list of controllers retrieved from ECom.
   1.439 + *			This list may be have been filtered for audio/video/play/record.
   1.440 + * @param	"aHeaderDataPlayback"
   1.441 + *			A descriptor reference containing the file's header data.
   1.442 + *          for matching against a controller's play formats. May be KNullDesC8
   1.443 + * @param	"aFileExtensionPlayback"
   1.444 + *			A descriptor reference containing the filename's extension.
   1.445 + *          for matching against a controller's play formats. May be KNullDesC8
   1.446 + * @param	"aHeaderDataRecord"
   1.447 + *			A descriptor reference containing the file's header data.
   1.448 + *          for matching against a controller's record formats. May be KNullDesC8
   1.449 + * @param	"aFileExtensionRecord"
   1.450 + *			A descriptor reference containing the filename's extension.
   1.451 + *          for matching against a controller's record formats. May be KNullDesC8
   1.452 + * @param	"aPrioritisedControllers"
   1.453 + *			A reference to a user supplied list through which the list of
   1.454 + *			prioritised controllers will be returned.
   1.455 + * @since	7.0s
   1.456 + */
   1.457 +void CMMFClientUtility::PrioritiseControllersL(
   1.458 +	const RMMFControllerImplInfoArray& aControllers, 
   1.459 +	const TDesC8& aHeaderDataPlayback, 
   1.460 +	const TDesC8& aFileExtensionPlayback, 
   1.461 +	const TDesC8& aHeaderDataRecord, 
   1.462 +	const TDesC8& aFileExtensionRecord, 
   1.463 +	RMMFControllerImplInfoArray& prioritisedControllers)
   1.464 +	{
   1.465 +	RMMFControllerImplInfoArray fullMatchControllers; // data AND suffix
   1.466 +	CleanupClosePushL(fullMatchControllers);
   1.467 +	RMMFControllerImplInfoArray partMatchControllers; // data OR suffix
   1.468 +	CleanupClosePushL(partMatchControllers);
   1.469 +
   1.470 +	TBool checkingPlaybackFormats = EFalse;
   1.471 +	TBool checkingRecordFormats = EFalse;
   1.472 +
   1.473 +	if (aHeaderDataPlayback != KNullDesC8 || aFileExtensionPlayback != KNullDesC8)
   1.474 +		checkingPlaybackFormats = ETrue;
   1.475 +	if (aHeaderDataRecord != KNullDesC8 || aFileExtensionRecord != KNullDesC8)
   1.476 +		checkingRecordFormats = ETrue;
   1.477 +
   1.478 +	// Examine each format for each controller. We only want to know at this stage
   1.479 +	// if the controller has suitable formats, so as soon as we know it has, we can
   1.480 +	// add it to out list, ranked by how well it matched.
   1.481 +	for (register TInt i = 0; i < aControllers.Count(); i++)
   1.482 +		{
   1.483 +		const CMMFControllerImplementationInformation* controller = aControllers[i];
   1.484 +		TInt savedBrowniePointsPlayback = 0;
   1.485 +		TInt savedBrowniePointsRecord = 0;
   1.486 +
   1.487 +		if (checkingPlaybackFormats)
   1.488 +			{
   1.489 +			for (register TInt p = 0; p < controller->PlayFormats().Count(); p++)
   1.490 +				{
   1.491 +				const CMMFFormatImplementationInformation* format = controller->PlayFormats()[p];
   1.492 +
   1.493 +				TInt browniePoints = GetBestMatchL(format, aHeaderDataPlayback, aFileExtensionPlayback);
   1.494 +
   1.495 +				if (browniePoints >= savedBrowniePointsPlayback)
   1.496 +					savedBrowniePointsPlayback = browniePoints;
   1.497 +				}
   1.498 +			}
   1.499 +
   1.500 +		if (checkingRecordFormats)
   1.501 +			{
   1.502 +			for (register TInt r = 0; r < controller->RecordFormats().Count(); r++)
   1.503 +				{
   1.504 +				const CMMFFormatImplementationInformation* format = controller->RecordFormats()[r];
   1.505 +
   1.506 +				TInt browniePoints = GetBestMatchL(format, aHeaderDataRecord, aFileExtensionRecord);
   1.507 +
   1.508 +				if (browniePoints >= savedBrowniePointsRecord)
   1.509 +					savedBrowniePointsRecord = browniePoints;
   1.510 +				}
   1.511 +			}
   1.512 +
   1.513 +		TInt savedBrowniePoints = 0;
   1.514 +		// if we're checking both playback & record formats
   1.515 +		// make sure we've found both
   1.516 +		if (checkingPlaybackFormats && checkingRecordFormats)
   1.517 +			{
   1.518 +			savedBrowniePoints = Min(savedBrowniePointsPlayback, savedBrowniePointsRecord);
   1.519 +			}
   1.520 +		else if (checkingPlaybackFormats)
   1.521 +			{
   1.522 +			savedBrowniePoints = savedBrowniePointsPlayback;
   1.523 +			}
   1.524 +		else if (checkingRecordFormats)
   1.525 +			{
   1.526 +			savedBrowniePoints = savedBrowniePointsRecord;
   1.527 +			}
   1.528 +
   1.529 +		// Checked all formats for this controller, now count our brownie points.
   1.530 +		switch (savedBrowniePoints)
   1.531 +			{
   1.532 +			case 3:
   1.533 +				User::LeaveIfError(fullMatchControllers.Append(controller));
   1.534 +				break;
   1.535 +			case 2:
   1.536 +				User::LeaveIfError(partMatchControllers.Insert(controller, 0));
   1.537 +				break;
   1.538 +			case 1:
   1.539 +				User::LeaveIfError(partMatchControllers.Append(controller));
   1.540 +				break;
   1.541 +			default:
   1.542 +				break;
   1.543 +			}
   1.544 +		}
   1.545 +
   1.546 +	// The better the controller matches, the earlier it will be in the final list.
   1.547 +	for (register TInt x = 0; x < fullMatchControllers.Count(); x++)
   1.548 +		{
   1.549 +		if (prioritisedControllers.Find(fullMatchControllers[x]) == KErrNotFound)
   1.550 +			{
   1.551 +			User::LeaveIfError(prioritisedControllers.Append(fullMatchControllers[x]));
   1.552 +			}
   1.553 +		}
   1.554 +
   1.555 +	for (register TInt y = 0; y < partMatchControllers.Count(); y++)
   1.556 +		{
   1.557 +		if (prioritisedControllers.Find(partMatchControllers[y]) == KErrNotFound)
   1.558 +			{
   1.559 +			User::LeaveIfError(prioritisedControllers.Append(partMatchControllers[y]));
   1.560 +			}
   1.561 +		}
   1.562 +
   1.563 +	CleanupStack::PopAndDestroy(2, &fullMatchControllers); // fullMatchControllers, partMatchControllers
   1.564 +	}
   1.565 +
   1.566 +/**
   1.567 + * @internalComponent
   1.568 + */
   1.569 +EXPORT_C CMMFMdaObjectStateChangeObserverCallback* CMMFMdaObjectStateChangeObserverCallback::NewL(MMdaObjectStateChangeObserver& aCallback)
   1.570 +	{
   1.571 +	return new(ELeave) CMMFMdaObjectStateChangeObserverCallback(aCallback);
   1.572 +	}
   1.573 +
   1.574 +/**
   1.575 + * @internalComponent
   1.576 + */
   1.577 +CMMFMdaObjectStateChangeObserverCallback::~CMMFMdaObjectStateChangeObserverCallback()
   1.578 +	{
   1.579 +	Cancel();
   1.580 +	}
   1.581 +
   1.582 +/**
   1.583 + * @internalComponent
   1.584 + */
   1.585 +EXPORT_C void CMMFMdaObjectStateChangeObserverCallback::CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
   1.586 +	{
   1.587 +	iObject = aObject;
   1.588 +	iPreviousState = aPreviousState;
   1.589 +	iCurrentState = aCurrentState;
   1.590 +	iErrorCode = aErrorCode;
   1.591 +	if (!IsActive())
   1.592 +		{
   1.593 +		TRequestStatus* s = &iStatus;
   1.594 +		SetActive();
   1.595 +		User::RequestComplete(s, KErrNone);
   1.596 +		}
   1.597 +	}
   1.598 +
   1.599 +CMMFMdaObjectStateChangeObserverCallback::CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback) :
   1.600 +	CActive(CActive::EPriorityHigh),
   1.601 +	iCallback(aCallback)
   1.602 +	{
   1.603 +	CActiveScheduler::Add(this);
   1.604 +	}
   1.605 +
   1.606 +void CMMFMdaObjectStateChangeObserverCallback::RunL()
   1.607 +	{
   1.608 +	iCallback.MoscoStateChangeEvent(iObject, iPreviousState, iCurrentState, iErrorCode);
   1.609 +	}
   1.610 +
   1.611 +void CMMFMdaObjectStateChangeObserverCallback::DoCancel()
   1.612 +	{
   1.613 +	//nothing to cancel
   1.614 +	}
   1.615 +
   1.616 +
   1.617 +//****************************************
   1.618 +// CMMFFindAndOpenController
   1.619 +//****************************************
   1.620 +
   1.621 +/**
   1.622 + * Factory function to create a CMMFFindAndOpenController class
   1.623 + *
   1.624 + * @internalComponent
   1.625 + */
   1.626 +EXPORT_C CMMFFindAndOpenController* CMMFFindAndOpenController::NewL(MMMFFindAndOpenControllerObserver& aObserver)
   1.627 +	{
   1.628 +	CMMFFindAndOpenController* self = new(ELeave) CMMFFindAndOpenController(aObserver);
   1.629 +	CleanupStack::PushL(self);
   1.630 +	self->ConstructL();
   1.631 +	CleanupStack::Pop(self);
   1.632 +	return self;
   1.633 +	}
   1.634 +
   1.635 +CMMFFindAndOpenController::~CMMFFindAndOpenController()
   1.636 +	{
   1.637 +	Cancel();
   1.638 +
   1.639 +	// delete temporary variables
   1.640 +	Close();
   1.641 +
   1.642 +	// this should cancel the AO
   1.643 +	delete iAddDataSourceSinkAsync;
   1.644 +
   1.645 +	delete iPrimaryConfig;
   1.646 +	delete iSecondaryConfig;
   1.647 +	}
   1.648 +
   1.649 +/**
   1.650 + * Function to free up memory after a successful open has completed
   1.651 + * Useful to allow a alloc testing to work.
   1.652 + * Must not be called if ReOpen() is to be called
   1.653 + *
   1.654 + * @internalComponent
   1.655 + */
   1.656 +EXPORT_C void CMMFFindAndOpenController::Close()
   1.657 +	{
   1.658 +
   1.659 +	Cancel();
   1.660 +	
   1.661 +	if(iAddDataSourceSinkAsync)
   1.662 +		{
   1.663 +		iAddDataSourceSinkAsync->Cancel();
   1.664 +		}
   1.665 +		
   1.666 +	if (iPrimaryConfig)
   1.667 +		iPrimaryConfig->Close();
   1.668 +	if (iSecondaryConfig)
   1.669 +		iSecondaryConfig->Close();
   1.670 +
   1.671 +	iPrioritisedControllers.Close();
   1.672 +	iControllers.ResetAndDestroy();
   1.673 +	iControllers.Close();
   1.674 +	
   1.675 +	iFileName.SetLength(0);
   1.676 +	iFileNameSecondary.SetLength(0);
   1.677 +
   1.678 +	delete iUrl;
   1.679 +	iUrl = NULL;
   1.680 +	
   1.681 +	delete iMimeType;
   1.682 +	iMimeType = NULL;
   1.683 +	
   1.684 +	delete iUniqueId;
   1.685 +	iUniqueId = NULL;
   1.686 +
   1.687 +	if (iOwnFileHandle)
   1.688 +		{
   1.689 +		iFileHandle.Close();
   1.690 +		iOwnFileHandle = EFalse;	
   1.691 +		}
   1.692 +	}
   1.693 +/**
   1.694 + * Function to free up memory of which is not required in ReOpen()
   1.695 + * after a successful open has completed
   1.696 + * Useful to allow a alloc testing to work.
   1.697 + *
   1.698 + * @internalComponent
   1.699 + */
   1.700 +
   1.701 +EXPORT_C void CMMFFindAndOpenController::CloseConfig()
   1.702 +	{
   1.703 +	Cancel();
   1.704 +	if(iAddDataSourceSinkAsync)
   1.705 +		{
   1.706 +		iAddDataSourceSinkAsync->Cancel();
   1.707 +		}
   1.708 +	
   1.709 +	if (iSecondaryConfig)
   1.710 +		{
   1.711 +		iSecondaryConfig->Close();
   1.712 +		}
   1.713 +	
   1.714 +	iPrioritisedControllers.Close();
   1.715 +	iControllers.ResetAndDestroy();
   1.716 +	iControllers.Close();
   1.717 +	
   1.718 +	iFileName.SetLength(0);
   1.719 +	iFileNameSecondary.SetLength(0);
   1.720 +
   1.721 +	delete iUrl;
   1.722 +	iUrl = NULL;
   1.723 +	
   1.724 +	delete iMimeType;
   1.725 +	iMimeType = NULL;
   1.726 +	
   1.727 +	delete iUniqueId;
   1.728 +	iUniqueId = NULL;
   1.729 +
   1.730 +	if (iOwnFileHandle)
   1.731 +		{
   1.732 +		iFileHandle.Close();
   1.733 +		iOwnFileHandle = EFalse;		
   1.734 +		}
   1.735 +	}
   1.736 +
   1.737 +CMMFFindAndOpenController::CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver) :
   1.738 +	CActive(EPriorityStandard), 
   1.739 +	iObserver(aObserver),
   1.740 +	iDescriptor(NULL, 0)
   1.741 +	{
   1.742 +	CActiveScheduler::Add(this);
   1.743 +	}
   1.744 +
   1.745 +void CMMFFindAndOpenController::ConstructL()
   1.746 +	{
   1.747 +	iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
   1.748 +	iPrimaryConfig = new (ELeave)  CConfig();
   1.749 +	iSecondaryConfig =  new (ELeave) CConfig;
   1.750 +	iCurrentConfig =  iPrimaryConfig;
   1.751 +	
   1.752 +	RProcess thisProcess;
   1.753 +	iHasDrmCapability = thisProcess.HasCapability(ECapabilityDRM, KSuppressPlatSecDiagnostic);
   1.754 +	thisProcess.Close();
   1.755 +	}
   1.756 +
   1.757 +void CMMFFindAndOpenController::RunL()
   1.758 +	{
   1.759 +	Process();
   1.760 +	}
   1.761 +
   1.762 +void CMMFFindAndOpenController::DoCancel()
   1.763 +	{
   1.764 +	iAddDataSourceSinkAsync->Cancel();
   1.765 +	}
   1.766 +
   1.767 +/**
   1.768 + * Defines the media ID & priority to be used when opening a controller
   1.769 + * Normally called once only after class has been constructed
   1.770 + *
   1.771 + * @param	aMediaId
   1.772 + *			the media ID to use when searching for a controller
   1.773 + *			e.g. KUidMediaTypeAudio 
   1.774 + * @param	aPrioritySettings
   1.775 + *			the priority settings to use when opening a controller
   1.776 + * @param	aMediaIdMatchType
   1.777 + *			Defines the type of media id match to be performed on the plugins 
   1.778 + *			returned from the ECOM registry.
   1.779 + * @leave	can leave with KErrNoMemory
   1.780 +
   1.781 + * @internalComponent
   1.782 + */
   1.783 +EXPORT_C void CMMFFindAndOpenController::Configure(
   1.784 +	TUid aMediaId, 
   1.785 +	TMMFPrioritySettings aPrioritySettings,
   1.786 +	CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType)
   1.787 +	{
   1.788 +	iPrioritySettings = aPrioritySettings;
   1.789 +
   1.790 +	iMediaIdMatchType = aMediaIdMatchType;
   1.791 +
   1.792 +	iMediaId = aMediaId;
   1.793 +	}
   1.794 +
   1.795 +void CMMFFindAndOpenController::ConfigureController(
   1.796 +	CConfig& config,
   1.797 +	RMMFController& aController, 
   1.798 +	CMMFControllerEventMonitor& aEventMonitor,
   1.799 +	TControllerMode aControllerMode)
   1.800 +	{
   1.801 +	config.iController = &aController;
   1.802 +	config.iEventMonitor = &aEventMonitor;
   1.803 +	config.iControllerMode = aControllerMode;
   1.804 +	}
   1.805 +
   1.806 +/**
   1.807 + * Configures the primary controller
   1.808 + *
   1.809 + * @param	aController
   1.810 + *			a reference to the client controller object to use
   1.811 + * @param	aEventMonitor
   1.812 + *			a reference to an event monitor object for receiving 
   1.813 + *			events from the controller
   1.814 + * @param	aControllerMode
   1.815 + *			indicates whether this controller is to be used for recording
   1.816 + *          or playback
   1.817 + *
   1.818 + * @internalComponent
   1.819 + */
   1.820 +EXPORT_C void CMMFFindAndOpenController::ConfigureController(
   1.821 +	RMMFController& aController, 
   1.822 +	CMMFControllerEventMonitor& aEventMonitor,
   1.823 +	TControllerMode aControllerMode)
   1.824 +	{
   1.825 +	ConfigureController(
   1.826 +		*iPrimaryConfig,
   1.827 +		aController, 
   1.828 +		aEventMonitor,
   1.829 +		aControllerMode);
   1.830 +	}
   1.831 +
   1.832 +/**
   1.833 + * Configures the secondary controller
   1.834 + *
   1.835 + * This is only needed for the audio recorder utility which opens
   1.836 + * one controller for playback and another for recording
   1.837 + *
   1.838 + * @param	aController
   1.839 + *			a reference to the client controller object to use
   1.840 + * @param	aEventMonitor
   1.841 + *			a reference to an event monitor object for receiving 
   1.842 + *			events from the controller
   1.843 + * @param	aControllerMode
   1.844 + *			indicates whether this controller is to be used for recording
   1.845 + *          or playback or converting
   1.846 + *
   1.847 + * @internalComponent
   1.848 + */
   1.849 +EXPORT_C void CMMFFindAndOpenController::ConfigureSecondaryController(
   1.850 +	RMMFController& aController, 
   1.851 +	CMMFControllerEventMonitor& aEventMonitor,
   1.852 +	TControllerMode aControllerMode)
   1.853 +	{
   1.854 +	ConfigureController(
   1.855 +		*iSecondaryConfig,
   1.856 +		aController, 
   1.857 +		aEventMonitor,
   1.858 +		aControllerMode);
   1.859 +	}
   1.860 +
   1.861 +/**
   1.862 + * Makes any controllers that are opened subsequently share a single heap.
   1.863 + * 
   1.864 + * The default behaviour is that each controller is created with its own heap.
   1.865 + * Each heap uses a chunk, so using this function avoids situations where the number
   1.866 + * of chunks per process is limited.
   1.867 + * The default behaviour is generally to be preferred, and should give lower overall
   1.868 + * memory usage. However, if many controllers are to be created for a particular thread,
   1.869 + * then this function should be used to prevent running out of heaps or chunks.
   1.870 + *
   1.871 + * @internalComponent
   1.872 + */
   1.873 +EXPORT_C void CMMFFindAndOpenController::UseSharedHeap()
   1.874 +	{
   1.875 +	iUseSharedHeap = ETrue;
   1.876 +	}
   1.877 +
   1.878 +void CMMFFindAndOpenController::Init()
   1.879 +	{
   1.880 +	// This should be called prior to opening, so reset the error
   1.881 +	iError = KErrNone;
   1.882 +	iSourceSinkConfigured = EFalse;
   1.883 +	iControllerCount = 0;
   1.884 +	}
   1.885 +
   1.886 +void CMMFFindAndOpenController::ConfigureSourceSink(
   1.887 +	CConfig& config,
   1.888 +	TSourceSink aSource, 
   1.889 +	TSourceSink aSink)
   1.890 +	{
   1.891 +	TInt err;
   1.892 +	TRAP(err, config.iSource = CreateSourceSinkL(aSource));
   1.893 +	if (err != KErrNone)
   1.894 +		{
   1.895 +		iError = err;
   1.896 +		return;
   1.897 +		}
   1.898 +		
   1.899 +	TRAP(err, config.iSink = CreateSourceSinkL(aSink));
   1.900 +	if (err != KErrNone)
   1.901 +		{
   1.902 +		iError = err;
   1.903 +		return;
   1.904 +		}
   1.905 +	}
   1.906 +	
   1.907 +
   1.908 +void CMMFFindAndOpenController::ConfigureSourceSink(
   1.909 +	CConfig& config,
   1.910 +	const TMMSource& aSource, 
   1.911 +	TSourceSink aSink)
   1.912 +	{
   1.913 +	TInt err;
   1.914 +	TRAP(err, config.iSource = CreateSourceSinkL(aSource));
   1.915 +	if (err != KErrNone)
   1.916 +		{
   1.917 +		iError = err;
   1.918 +		return;
   1.919 +		}
   1.920 +		
   1.921 +	TRAP(err, config.iSink = CreateSourceSinkL(aSink));
   1.922 +	if (err != KErrNone)
   1.923 +		{
   1.924 +		iError = err;
   1.925 +		return;
   1.926 +		}
   1.927 +	}
   1.928 +
   1.929 +
   1.930 +	
   1.931 +/**
   1.932 + * Configure the primary controller's source and sink
   1.933 + * The descriptors passed to this function are copied so they do not need to be persistent.
   1.934 + * To simplify the API, any errors that occur are reported back asynchronously following
   1.935 + * a subsequent call to OpenByXXX()
   1.936 + *
   1.937 + * @param	aSourceUid
   1.938 + *			the UID of the data source
   1.939 + * @param	aSourceData
   1.940 + *			a reference to a descriptor used to configure the source
   1.941 + * @param	aSinkUid
   1.942 + *			the UID of the data sink
   1.943 + * @param	aSinkData
   1.944 + *			a reference to a descriptor used to configure the sink
   1.945 + *
   1.946 + * @internalComponent
   1.947 + */
   1.948 +EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
   1.949 +	TSourceSink aSource,
   1.950 +	TSourceSink aSink)
   1.951 +	{
   1.952 +
   1.953 +	CConfig* config = NULL;
   1.954 +	
   1.955 +	Init();
   1.956 +	config = iPrimaryConfig;
   1.957 +
   1.958 +
   1.959 +	// must have already called ConfigureController()
   1.960 +	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
   1.961 +
   1.962 +	ConfigureSourceSink(
   1.963 +		*config,
   1.964 +		aSource, 
   1.965 +		aSink);
   1.966 +	iCurrentConfig = config;
   1.967 +
   1.968 +	iSourceSinkConfigured = ETrue;
   1.969 +	}
   1.970 +	
   1.971 +	
   1.972 +/**
   1.973 + * Configure the primary controller's source and sink
   1.974 + * The descriptors passed to this function are copied so they do not need to be persistent.
   1.975 + * To simplify the API, any errors that occur are reported back asynchronously following
   1.976 + * a subsequent call to OpenByXXX()
   1.977 + *
   1.978 + * @param	aSourceUid
   1.979 + *			the UID of the data source
   1.980 + * @param	aSourceData
   1.981 + *			a reference to a descriptor used to configure the source
   1.982 + * @param	aSinkUid
   1.983 + *			the UID of the data sink
   1.984 + * @param	aSinkData
   1.985 + *			a reference to a descriptor used to configure the sink
   1.986 + *
   1.987 + * @internalComponent
   1.988 + */
   1.989 +EXPORT_C void CMMFFindAndOpenController::ConfigureSecondarySourceSink(
   1.990 +	TSourceSink aSource,
   1.991 +	TSourceSink aSink)
   1.992 +	{
   1.993 +	if (iError != KErrNone)
   1.994 +		{
   1.995 +		// if there was an error configuring the primary source/sink, do not try the secondary one
   1.996 +		// Don't return the error, since the stored error will be returned by the OpenBy... method
   1.997 +		return;
   1.998 +		}
   1.999 +
  1.1000 +	CConfig* config = NULL;
  1.1001 +	
  1.1002 +	config = iSecondaryConfig;
  1.1003 +
  1.1004 +	// must have already configured the primary controller
  1.1005 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1006 +	config = iSecondaryConfig;
  1.1007 +			
  1.1008 +	// must have already called ConfigureController()
  1.1009 +	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
  1.1010 +
  1.1011 +	ConfigureSourceSink(
  1.1012 +		*config,
  1.1013 +		aSource, 
  1.1014 +		aSink);
  1.1015 +	iCurrentConfig = config;
  1.1016 +
  1.1017 +	iSourceSinkConfigured = ETrue;
  1.1018 +	}
  1.1019 +	
  1.1020 +
  1.1021 +	
  1.1022 +EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
  1.1023 +	const TMMSource& aSource,
  1.1024 +	TSourceSink aSink)
  1.1025 +	{
  1.1026 +	Init();
  1.1027 +	CConfig* config = iPrimaryConfig;
  1.1028 +			
  1.1029 +	// must have already called ConfigureController()
  1.1030 +	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
  1.1031 +
  1.1032 +	ConfigureSourceSink(
  1.1033 +		*config,
  1.1034 +		aSource, 
  1.1035 +		aSink);
  1.1036 +	iCurrentConfig = config;
  1.1037 +
  1.1038 +	iSourceSinkConfigured = ETrue;
  1.1039 +	}
  1.1040 +
  1.1041 +	
  1.1042 +	
  1.1043 +/**
  1.1044 + * Opens a controller using the supplied controller UID
  1.1045 + * and adds the source & sink
  1.1046 + * Completion is indicated asynchonously by a call to MfaocComplete()
  1.1047 + * 
  1.1048 + * @param	aControllerUid
  1.1049 + *			the UID of the primary controller
  1.1050 + * @param	aControllerUid
  1.1051 + *			the UID of the secondary controller
  1.1052 + *
  1.1053 + * @internalComponent
  1.1054 + */
  1.1055 +EXPORT_C void CMMFFindAndOpenController::OpenByControllerUid(
  1.1056 +		TUid aControllerUid,
  1.1057 +		TUid aSecondaryControllerUid)
  1.1058 +	{
  1.1059 +	// must have already called ConfigureSourceSink()
  1.1060 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1061 +
  1.1062 +	// Have there been any errors so far ?
  1.1063 +	if (iError != KErrNone)
  1.1064 +		{
  1.1065 +	    SchedSendError();
  1.1066 +		return;
  1.1067 +		}
  1.1068 +
  1.1069 +	if (iCurrentConfig == iPrimaryConfig)
  1.1070 +		{
  1.1071 +		// only do this for the playback controller
  1.1072 +		TRAP(iError, iCurrentConfig->iSource->EvaluateIntentL())
  1.1073 +		
  1.1074 +		if (iError != KErrNone && 
  1.1075 +			!(iCurrentConfig->iControllerMode == EPlayback && iError == KErrPermissionDenied && !iHasDrmCapability))
  1.1076 +			{
  1.1077 +			// KErrPermissionDenied error and no DRM capability are not problems in Playback mode
  1.1078 +			// proper action will be performed when controller is loaded
  1.1079 +	    	SchedSendError();
  1.1080 +			return;
  1.1081 +			}
  1.1082 +		}
  1.1083 +
  1.1084 +	iPrimaryConfig->iControllerUid = aControllerUid;
  1.1085 +	if (iCurrentConfig == iSecondaryConfig)
  1.1086 +		{
  1.1087 +		if (aSecondaryControllerUid == KNullUid)
  1.1088 +			iSecondaryConfig->iControllerUid = aControllerUid;
  1.1089 +		else
  1.1090 +			iSecondaryConfig->iControllerUid = aSecondaryControllerUid;
  1.1091 +		}
  1.1092 +		
  1.1093 +	iMode = EOpenByControllerUid;
  1.1094 +	iControllerImplInfo = NULL;
  1.1095 +	iState = EOpenController;
  1.1096 +	KickState();
  1.1097 +	}
  1.1098 +
  1.1099 +/**
  1.1100 + * Opens a controller using the supplied file name
  1.1101 + * and adds the source & sink
  1.1102 + * A copy is made of the filename or file handle so that it need not be persistent
  1.1103 + * Completion is indicated asynchonously by a call to MfaocComplete()
  1.1104 + * 
  1.1105 + * @param	aSource
  1.1106 + *			a reference to a TFileSource object to be used when searching
  1.1107 + *          for a controller
  1.1108 + * @param	aFileNameSecondary
  1.1109 + *			a reference to the seconday filename to be used when searching
  1.1110 + *          for a controller. This need only be supplied when converting 
  1.1111 + *			between two files.
  1.1112 + *
  1.1113 + * @internalComponent
  1.1114 + */
  1.1115 +EXPORT_C void CMMFFindAndOpenController::OpenByFileSource(const TMMSource& aSource, const TDesC& aFileNameSecondary)
  1.1116 +	{
  1.1117 +	// must have already called ConfigureSourceSink()
  1.1118 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1119 +
  1.1120 +	TInt err;
  1.1121 +	// Have there been any errors so far ?
  1.1122 +	if (iError != KErrNone)
  1.1123 +		{
  1.1124 +		SchedSendError();
  1.1125 +		return;
  1.1126 +		}
  1.1127 +		
  1.1128 +	if (iOwnFileHandle)
  1.1129 +		{
  1.1130 +		// in case of error
  1.1131 +		iFileHandle.Close();
  1.1132 +		iOwnFileHandle = EFalse;
  1.1133 +		}
  1.1134 +		
  1.1135 +	iEnableUi = aSource.IsUIEnabled();
  1.1136 +	if (aSource.SourceType()==KUidMMFileSource)
  1.1137 +		{
  1.1138 +		const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
  1.1139 +		iFileName = fileSource.Name();
  1.1140 +		iUseFileHandle = EFalse;
  1.1141 +		}
  1.1142 +
  1.1143 +	if (aSource.SourceType()==KUidMMFileHandleSource)
  1.1144 +		{
  1.1145 +		const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
  1.1146 +		ASSERT(iFileHandle.SubSessionHandle()==0); // closed just above
  1.1147 +		err = iFileHandle.Duplicate(fileHandleSource.Handle());
  1.1148 +		if (err != KErrNone)
  1.1149 +			{
  1.1150 +			SchedSendError(err);
  1.1151 +			return;
  1.1152 +			}
  1.1153 +		iFileHandle.Name(iFileName); //ignore error return since we'll just do without the filename if not available
  1.1154 +		iUseFileHandle = ETrue;
  1.1155 +		iOwnFileHandle = ETrue; // because we dup'd it
  1.1156 +		}
  1.1157 +		
  1.1158 +	TRAP(err, iUniqueId = aSource.UniqueId().AllocL());
  1.1159 +	iIntent = aSource.Intent();
  1.1160 +	if (err != KErrNone)
  1.1161 +		{
  1.1162 +		SchedSendError(err);
  1.1163 +		return;
  1.1164 +		}
  1.1165 +
  1.1166 +		
  1.1167 +	// take a copy of the secondary file name
  1.1168 +	iFileNameSecondary = aFileNameSecondary;
  1.1169 +
  1.1170 +	iMode = EOpenByFileName;
  1.1171 +	iState = EBuildControllerList;
  1.1172 +	KickState();
  1.1173 +	}
  1.1174 +	
  1.1175 +/**
  1.1176 + * Opens a controller using the supplied format UID
  1.1177 + * and adds the source & sink
  1.1178 + * Completion is indicated asynchonously by a call to MfaocComplete()
  1.1179 + * 
  1.1180 + * @param	aFormatUid
  1.1181 + *			the UID of a format that must be supported by the controller
  1.1182 + * @param	aFormatUidSecondary
  1.1183 + *			the UID of a secondary format that must be supported by the controller
  1.1184 + *			This need only be supplied when converting between two differnet formats.
  1.1185 + *
  1.1186 + * @internalComponent
  1.1187 + */
  1.1188 +EXPORT_C void CMMFFindAndOpenController::OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary)
  1.1189 +	{
  1.1190 +	// must have already called ConfigureSourceSink()
  1.1191 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1192 +
  1.1193 +	// Have there been any errors so far ?
  1.1194 +	if (iError != KErrNone)
  1.1195 +		{
  1.1196 +		SchedSendError();
  1.1197 +		return;
  1.1198 +		}
  1.1199 +
  1.1200 +	iFormatUid = aFormatUid;
  1.1201 +	iFormatUidSecondary = aFormatUidSecondary;
  1.1202 +
  1.1203 +	iMode = EOpenByFormatUid;
  1.1204 +	iState = EBuildControllerList;
  1.1205 +	KickState();
  1.1206 +	}
  1.1207 +
  1.1208 +/**
  1.1209 + * Opens a controller using the supplied descriptor 
  1.1210 + * and adds the source & sink
  1.1211 + * Completion is indicated asynchonously by a call to MfaocComplete()
  1.1212 + * 
  1.1213 + * @param	aDescriptor
  1.1214 + *			a reference to the descriptor to be used when searching
  1.1215 + *          for a controller
  1.1216 + *
  1.1217 + * @internalComponent
  1.1218 + */
  1.1219 +EXPORT_C void  CMMFFindAndOpenController::OpenByDescriptor(const TDesC8& aDescriptor)
  1.1220 +	{
  1.1221 +	// must have already called ConfigureSourceSink()
  1.1222 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1223 +
  1.1224 +	// Have there been any errors so far ?
  1.1225 +	if (iError != KErrNone)
  1.1226 +		{
  1.1227 +		SchedSendError();
  1.1228 +		return;
  1.1229 +		}
  1.1230 +
  1.1231 +	// take a copy of the descriptor
  1.1232 +	TUint8* desBufferPtr = const_cast<TUint8*> (aDescriptor.Ptr());
  1.1233 +	iDescriptor.Set( desBufferPtr,aDescriptor.Length(),aDescriptor.Length());
  1.1234 +	
  1.1235 +	iMode = EOpenByDescriptor;
  1.1236 +	iState = EBuildControllerList;
  1.1237 +	KickState();
  1.1238 +	}
  1.1239 +
  1.1240 +/**
  1.1241 + * Opens a controller using the supplied URL
  1.1242 + * and adds the source & sink
  1.1243 + * Completion is indicated asynchonously by a call to MfaocComplete()
  1.1244 + * 
  1.1245 + * @param	aUrl
  1.1246 + *			a reference to the URL to be used when searching for a controller
  1.1247 + * @param	aIapId
  1.1248 + *          the IAP ID to be used when searching for a controller
  1.1249 + * @param	aMimeType
  1.1250 + *          the MIME type of the data to be used when searching for a controller
  1.1251 + *
  1.1252 + * @internalComponent
  1.1253 + */
  1.1254 +EXPORT_C void CMMFFindAndOpenController::OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType)
  1.1255 +	{
  1.1256 +	// must have already called ConfigureSourceSink()
  1.1257 +	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
  1.1258 +
  1.1259 +	// Have there been any errors so far ?
  1.1260 +	if (iError != KErrNone)
  1.1261 +		{
  1.1262 +		SchedSendError();
  1.1263 +		return;
  1.1264 +		}
  1.1265 +
  1.1266 +	// take a copy of the Url
  1.1267 +	delete iUrl;
  1.1268 +	iUrl = NULL;
  1.1269 +	iUrl = aUrl.Alloc();
  1.1270 +	if (iUrl == NULL)
  1.1271 +		{
  1.1272 +		SchedSendError(KErrNoMemory);
  1.1273 +		return;
  1.1274 +		}
  1.1275 +
  1.1276 +	// take a copy of the IapId
  1.1277 +	iIapId = aIapId;
  1.1278 +	
  1.1279 +	// take a copy of the mime type
  1.1280 +	delete iMimeType;
  1.1281 +	iMimeType = NULL;
  1.1282 +	iMimeType = aMimeType.Alloc();
  1.1283 +	if (iMimeType == NULL)
  1.1284 +		{
  1.1285 +		SchedSendError(KErrNoMemory);
  1.1286 +		return;
  1.1287 +		}
  1.1288 +
  1.1289 +	iMode = EOpenByUrl;
  1.1290 +	iState = EBuildControllerList;
  1.1291 +	KickState();
  1.1292 +	}
  1.1293 +
  1.1294 +/**
  1.1295 + * Static function to return a TMMFFileConfig object
  1.1296 + * suitable for passing to ConfigureSourceSink()
  1.1297 + * 
  1.1298 + * @param	aFileName
  1.1299 + *          the filename to use
  1.1300 + *
  1.1301 + * @internalComponent
  1.1302 + */
  1.1303 +EXPORT_C TMMFFileConfig CMMFFindAndOpenController::GetConfigFile(const TDesC& aFileName)
  1.1304 +	{
  1.1305 +	TMMFFileConfig sourceSinkData;
  1.1306 +	sourceSinkData().iPath = aFileName;
  1.1307 +	return sourceSinkData;
  1.1308 +	}
  1.1309 +
  1.1310 +/**
  1.1311 + * Static function to return a TMMFDescriptorConfig object
  1.1312 + * suitable for passing to ConfigureSourceSink()
  1.1313 + * 
  1.1314 + * @param	aFileName
  1.1315 + *          the filename to use
  1.1316 + *
  1.1317 + * @internalComponent
  1.1318 + */
  1.1319 +EXPORT_C TMMFDescriptorConfig CMMFFindAndOpenController::GetConfigDescriptor(const TDesC8& aDescriptor)
  1.1320 +	{
  1.1321 +	TMMFDescriptorConfig sourceSinkData;
  1.1322 +	sourceSinkData().iDes = (TAny*)&aDescriptor;
  1.1323 +	sourceSinkData().iDesThreadId = RThread().Id();
  1.1324 +	return sourceSinkData;
  1.1325 +	}
  1.1326 +
  1.1327 +/**
  1.1328 + * Static function to create a CBufFlat object
  1.1329 + * suitable for passing to ConfigureSourceSink()
  1.1330 + * 
  1.1331 + * @param	aUrlCfgBuffer
  1.1332 + *          the reference to a caller-supplied pointer used to create
  1.1333 + *			a CBufFlat object. The caller is responsible for deletion.
  1.1334 + * @param	aUrl
  1.1335 + *			a reference to the URL to be used
  1.1336 + * @param	aIapId
  1.1337 + *          the IAP ID to be used
  1.1338 + * @return	can return KErrNone or KErrNoMemory
  1.1339 + *
  1.1340 + * @internalComponent
  1.1341 + */
  1.1342 +
  1.1343 +EXPORT_C void CMMFFindAndOpenController::GetConfigUrlL(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId)
  1.1344 +	{
  1.1345 +	delete aUrlCfgBuffer;
  1.1346 +	aUrlCfgBuffer = NULL;
  1.1347 +	
  1.1348 +	CMMFUrlParams* urlCfg = CMMFUrlParams::NewL(aUrl,aIapId);
  1.1349 +	CleanupStack::PushL(urlCfg);
  1.1350 +	aUrlCfgBuffer = urlCfg->ExternalizeToCBufFlatLC();
  1.1351 +	CleanupStack::Pop(aUrlCfgBuffer);
  1.1352 +	CleanupStack::PopAndDestroy(urlCfg);
  1.1353 +	}
  1.1354 +/**
  1.1355 + * ReOpens the previously opened primary controller
  1.1356 + *
  1.1357 + * @internalComponent
  1.1358 + */
  1.1359 +EXPORT_C void CMMFFindAndOpenController::ReOpen()
  1.1360 +	{
  1.1361 +	// should already have a valid controller uid so just open it
  1.1362 +	iControllerImplInfo = NULL;
  1.1363 +	iState = EOpenController;
  1.1364 +	KickState();
  1.1365 +	}
  1.1366 +
  1.1367 +void CMMFFindAndOpenController::OpenPrimaryController(void)
  1.1368 +	{
  1.1369 +	iCurrentConfig = iPrimaryConfig;
  1.1370 +	switch(iMode)
  1.1371 +		{
  1.1372 +		case EOpenByFileName:
  1.1373 +		case EOpenByFormatUid:
  1.1374 +		case EOpenByDescriptor:
  1.1375 +		case EOpenByUrl:
  1.1376 +			iState = EBuildControllerList;
  1.1377 +			break;
  1.1378 +		case EOpenByControllerUid:
  1.1379 +			iControllerImplInfo = NULL;
  1.1380 +			iState = EOpenController;
  1.1381 +			break;
  1.1382 +		}
  1.1383 +	KickState();
  1.1384 +	}
  1.1385 +
  1.1386 +void CMMFFindAndOpenController::KickState()
  1.1387 +	{
  1.1388 +	TRequestStatus* status = &iStatus;
  1.1389 +	User::RequestComplete(status, KErrNone);
  1.1390 +	SetActive();
  1.1391 +	}
  1.1392 +
  1.1393 +void CMMFFindAndOpenController::CloseController()
  1.1394 +	{
  1.1395 +	if (iCurrentConfig->iEventMonitor)
  1.1396 +		iCurrentConfig->iEventMonitor->Cancel();
  1.1397 +	iCurrentConfig->iController->Close(); 
  1.1398 +	}
  1.1399 +
  1.1400 +void CMMFFindAndOpenController::Process()
  1.1401 +	{
  1.1402 +	switch(iState)
  1.1403 +		{
  1.1404 +		case EBuildControllerList:
  1.1405 +			switch(iMode)
  1.1406 +				{
  1.1407 +				case EOpenByFileName:
  1.1408 +					TRAP(iError, BuildControllerListFileNameL());
  1.1409 +					break;
  1.1410 +				case EOpenByDescriptor:
  1.1411 +					TRAP(iError, BuildControllerListDescriptorL());
  1.1412 +					break;
  1.1413 +				case EOpenByUrl:
  1.1414 +					TRAP(iError, BuildControllerListUrlL());
  1.1415 +					break;
  1.1416 +				case EOpenByFormatUid:
  1.1417 +					TRAP(iError, BuildControllerListFormatL());
  1.1418 +					break;
  1.1419 +				default:
  1.1420 +					CUPanic(EMMFMediaClientUtilityBadState);
  1.1421 +				}
  1.1422 +			
  1.1423 +			if (iError != KErrNone)
  1.1424 +				{
  1.1425 +				iState = EIdle;
  1.1426 +				SendError();
  1.1427 +				break;
  1.1428 +				}
  1.1429 +
  1.1430 +			// try the first controller
  1.1431 +			iControllerIndex = -1;
  1.1432 +			TryNextController();
  1.1433 +			break;
  1.1434 +
  1.1435 +		case EOpenController:
  1.1436 +			{
  1.1437 +			// Make sure any existing controller is closed.
  1.1438 +			CloseController();
  1.1439 +			
  1.1440 +			TBool isSecureDrmProcess = EFalse;// need to keep it false as UseSecureDRMProcess may return error
  1.1441 +			// Loading controller in new threading model is enabled only in playback mode
  1.1442 +			TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
  1.1443 +			TBool localPlaybackMode = iCurrentConfig->iControllerMode == EPlayback && 
  1.1444 +										(sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource);
  1.1445 +            if(localPlaybackMode)
  1.1446 +                {
  1.1447 +                TRAPD(err,UseSecureDRMProcessL(isSecureDrmProcess));
  1.1448 +                if(err == KErrPermissionDenied)
  1.1449 +                	{
  1.1450 +                	isSecureDrmProcess = ETrue;
  1.1451 +                	}
  1.1452 +                else if(err != KErrNone)
  1.1453 +                    {
  1.1454 +                    iError = err;
  1.1455 +                    SendError(err);
  1.1456 +                    return;
  1.1457 +                    }
  1.1458 +                }
  1.1459 +			// Open the controller 
  1.1460 +			if (iControllerImplInfo)
  1.1461 +				{
  1.1462 +				if(isSecureDrmProcess && localPlaybackMode)
  1.1463 +					{
  1.1464 +					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
  1.1465 +					iUsingSecureDrmProcess = ETrue;
  1.1466 +					}
  1.1467 +				else
  1.1468 +					{
  1.1469 +					iError = iCurrentConfig->iController->Open(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
  1.1470 +					iUsingSecureDrmProcess = EFalse;;
  1.1471 +					}
  1.1472 +				}
  1.1473 +			else
  1.1474 +				{
  1.1475 +				if(isSecureDrmProcess && localPlaybackMode)
  1.1476 +					{
  1.1477 +					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
  1.1478 +					iUsingSecureDrmProcess = ETrue;
  1.1479 +	
  1.1480 +					}
  1.1481 +				else
  1.1482 +					{
  1.1483 +					iError = iCurrentConfig->iController->Open(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
  1.1484 +					iUsingSecureDrmProcess = EFalse;
  1.1485 +					}
  1.1486 +				}
  1.1487 +			//in case of error, including KErrNomemory try next controller
  1.1488 +			if (iError)
  1.1489 +				{
  1.1490 +				TryNextController();
  1.1491 +				}
  1.1492 +			else
  1.1493 +				{	
  1.1494 +			#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
  1.1495 +			#ifndef SYMBIAN_BUILD_GCE
  1.1496 +				if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
  1.1497 +					{
  1.1498 +					iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
  1.1499 +					if(iError)
  1.1500 +						{
  1.1501 +						if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
  1.1502 +							{
  1.1503 +							iError = KErrNone;
  1.1504 +							}
  1.1505 +						else
  1.1506 +							{
  1.1507 +							iState = EIdle;
  1.1508 +							SendError();
  1.1509 +							break;
  1.1510 +							}	
  1.1511 +						}
  1.1512 +					}
  1.1513 +			#endif // SYMBIAN_BUILD_GCE
  1.1514 +			#endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
  1.1515 +				iCurrentConfig->iEventMonitor->Start();
  1.1516 +
  1.1517 +				if (iCurrentConfig == iSecondaryConfig)
  1.1518 +					{
  1.1519 +					iState = EAddSource;
  1.1520 +					KickState();
  1.1521 +					}
  1.1522 +				else
  1.1523 +					{
  1.1524 +					iState = EAddSink;
  1.1525 +					KickState();
  1.1526 +					}
  1.1527 +				}
  1.1528 +			}
  1.1529 +			break;
  1.1530 +
  1.1531 +		case EAddSource:
  1.1532 +			{
  1.1533 +			iState = EWaitingForSource;
  1.1534 +			const CMMSourceSink* source = iCurrentConfig->iSource;
  1.1535 +			// CMMSourceSink has the ability to transform the data it stored into a data stream
  1.1536 +			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
  1.1537 +			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
  1.1538 +			// source/sink. The info about the file can be a file path or a file handle.
  1.1539 +			// When it holds a file handle and turns info into data stream, the file handle is
  1.1540 +			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
  1.1541 +			// the streamed info is always extracted within the same process. If the pointer is 
  1.1542 +			// dereferenced in other process, a panic will raise in the system. Therefore, a file
  1.1543 +			// handle, rather than pointer, is used when necessary.
  1.1544 +			if (iUsingSecureDrmProcess && source->CarryingFileHandle())
  1.1545 +				{
  1.1546 +				iAddDataSourceSinkAsync->AddFileHandleDataSource(*iCurrentConfig->iController,
  1.1547 +																 static_cast<const CMMFileSourceSink*>(source)->FileHandle(),
  1.1548 +																 source->SourceSinkData());
  1.1549 +				}
  1.1550 +			else
  1.1551 +				{
  1.1552 +				iAddDataSourceSinkAsync->AddDataSource(*iCurrentConfig->iController, 
  1.1553 +													   source->SourceSinkUid(), 
  1.1554 +													   source->SourceSinkData());
  1.1555 +				}
  1.1556 +			}
  1.1557 +			break;
  1.1558 +
  1.1559 +		case EAddSink:
  1.1560 +			{
  1.1561 +			iState = EWaitingForSink;
  1.1562 +			const CMMSourceSink* sink = iCurrentConfig->iSink;
  1.1563 +			// CMMSourceSink has the ability to transform the data it stored into a data stream
  1.1564 +			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
  1.1565 +			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
  1.1566 +			// source/sink. The info about the file can be a file path or a file handle.
  1.1567 +			// When it holds a file handle and turns info into data stream, the file handle is
  1.1568 +			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
  1.1569 +			// the streamed info is always extracted within the same process. If the pointer is 
  1.1570 +			// dereferenced in other process, a panic will raise in the system. Therefore, a file
  1.1571 +			// handle, rather than pointer, is used when necessary.
  1.1572 +			const TDesC8& sinkData = sink->SourceSinkData();
  1.1573 +			if (iUsingSecureDrmProcess && sink->CarryingFileHandle())
  1.1574 +				{
  1.1575 +				iAddDataSourceSinkAsync->AddFileHandleDataSink(*iCurrentConfig->iController,
  1.1576 +															   static_cast<const CMMFileSourceSink*>(sink)->FileHandle(),
  1.1577 +															   sinkData);
  1.1578 +				}
  1.1579 +			else
  1.1580 +				{
  1.1581 +				iAddDataSourceSinkAsync->AddDataSink(*iCurrentConfig->iController, 
  1.1582 +													 sink->SourceSinkUid(), 
  1.1583 +													 sinkData);
  1.1584 +				}
  1.1585 +			}
  1.1586 +			break;
  1.1587 +		
  1.1588 +		case EWaitingForSource:
  1.1589 +			break;
  1.1590 +
  1.1591 +		case EWaitingForSink:
  1.1592 +			break;
  1.1593 +
  1.1594 +		case ESendError:
  1.1595 +			SendError();
  1.1596 +			iState = EIdle;
  1.1597 +			break;
  1.1598 +
  1.1599 +		case EIdle:
  1.1600 +		default:
  1.1601 +			break;
  1.1602 +		}
  1.1603 +	}
  1.1604 +
  1.1605 +void CMMFFindAndOpenController::TryNextController()
  1.1606 +	{
  1.1607 +	// If an error occurred close the controller.
  1.1608 +	if (iError != KErrNone)
  1.1609 +		{
  1.1610 +		CloseController();
  1.1611 +		}
  1.1612 +	
  1.1613 +	iStopTryLoadController = EFalse;
  1.1614 +	
  1.1615 +	if (iMode == EOpenByControllerUid || ++iControllerIndex >= iControllerCount)
  1.1616 +		{
  1.1617 +		//Raise a flag to stop trying to load the controllers
  1.1618 +		iStopTryLoadController = ETrue;
  1.1619 +		
  1.1620 +		// KErrNotSupported is the default error, but will only be used if no other error 
  1.1621 +		// has been discovered (the first error found is used by default)
  1.1622 +		// However, KErrBadHandle seems to mean that we tried to use the DRM server without
  1.1623 +		// RFs::ShareProtected() having been called, so force usage of KErrNotSupported so
  1.1624 +		// client does not see changed 
  1.1625 +		TBool forceErrorUse = EFalse;
  1.1626 +		if (iError==KErrBadHandle)
  1.1627 +			{
  1.1628 +			forceErrorUse = ETrue;
  1.1629 +			}
  1.1630 +		SendError(KErrNotSupported, forceErrorUse);		
  1.1631 +			
  1.1632 +		return;
  1.1633 +		}
  1.1634 +
  1.1635 +	if (iMode == EOpenByFileName || iMode == EOpenByFormatUid)
  1.1636 +		{
  1.1637 +		iControllerImplInfo = iPrioritisedControllers[iControllerIndex];
  1.1638 +		}
  1.1639 +	else	//if (iMode == EOpenByDescriptor || iMode == EOpenByUrl)
  1.1640 +		{
  1.1641 +		iControllerImplInfo = iControllers[iControllerIndex];
  1.1642 +		}
  1.1643 +
  1.1644 +	iCurrentConfig->iControllerUid = iControllerImplInfo->Uid();
  1.1645 +	iState = EOpenController;
  1.1646 +	KickState();
  1.1647 +	}
  1.1648 +
  1.1649 +void CMMFFindAndOpenController::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
  1.1650 +	{
  1.1651 +	iError = aError;
  1.1652 +
  1.1653 +	// take the first available exit if we're out of memory
  1.1654 +	// or we've been cancelled
  1.1655 +	if (iError == KErrNoMemory || iError == KErrCancel)
  1.1656 +		{
  1.1657 +		SendError();
  1.1658 +		return;
  1.1659 +		}
  1.1660 +
  1.1661 +	// failed to add source or sink - try the next controller
  1.1662 +	if (aError != KErrNone)
  1.1663 +		{
  1.1664 +		TryNextController();
  1.1665 +		return;
  1.1666 +		}
  1.1667 +
  1.1668 +	if (iState == EWaitingForSource)
  1.1669 +		{
  1.1670 +		#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
  1.1671 +		#ifdef SYMBIAN_BUILD_GCE
  1.1672 +		// If surfaces are required try to use them.  If this fails then fall back to using
  1.1673 +		// direct screen access.
  1.1674 +		if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
  1.1675 +			{
  1.1676 +			// UseSurfaces call has to be done after adding data sink and adding data source.
  1.1677 +			iSurfaceSupported = iVideoPlaySurfaceSupportCustomCommands->UseSurfaces();
  1.1678 +			
  1.1679 +			if (iSurfaceSupported == KErrNotSupported)
  1.1680 +				{
  1.1681 +				if (iUseVPU2)
  1.1682 +					{
  1.1683 +					if (ControllerIndex() < ControllerCount() - 1)
  1.1684 +						{
  1.1685 +						// Until end of the list of controllers,
  1.1686 +						// try the next one for surface support
  1.1687 +						TryNextController(); // this will also kick-state
  1.1688 +						return;
  1.1689 +						}
  1.1690 +					else
  1.1691 +						{
  1.1692 +						iError = iSurfaceSupported;
  1.1693 +						}
  1.1694 +					}
  1.1695 +				else 
  1.1696 +					{
  1.1697 +					// No surface enabled controller found 
  1.1698 +					// not required to do only surface, 
  1.1699 +					// use the last one that matched.
  1.1700 +					iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
  1.1701 +					if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
  1.1702 +						{
  1.1703 +						iError = KErrNone;
  1.1704 +						}
  1.1705 +					}
  1.1706 +				}
  1.1707 +			else
  1.1708 +				{
  1.1709 +				iError = iSurfaceSupported;
  1.1710 +				}
  1.1711 +			}
  1.1712 +		#endif // SYMBIAN_BUILD_GCE
  1.1713 +		#endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
  1.1714 +			
  1.1715 +		iSourceHandle = aHandle;
  1.1716 +		if (iCurrentConfig == iSecondaryConfig)
  1.1717 +			{
  1.1718 +			iState = EAddSink;
  1.1719 +			}
  1.1720 +		else	// completed ok !
  1.1721 +			{
  1.1722 +			iState = EIdle;
  1.1723 +			SendError(KErrNone, ETrue);
  1.1724 +			return;
  1.1725 +			}
  1.1726 +		}
  1.1727 +	else if (iState == EWaitingForSink)
  1.1728 +		{
  1.1729 +		iSinkHandle = aHandle;
  1.1730 +		if (iCurrentConfig == iSecondaryConfig)	// completed ok !
  1.1731 +			{
  1.1732 +			iState = EIdle;
  1.1733 +			iError = KErrNone;
  1.1734 +			SendError();
  1.1735 +			return;
  1.1736 +			}
  1.1737 +		else
  1.1738 +			{
  1.1739 +			iState = EAddSource;
  1.1740 +			}
  1.1741 +		}
  1.1742 +
  1.1743 +	KickState();
  1.1744 +	}
  1.1745 +
  1.1746 +void CMMFFindAndOpenController::SendError(TInt aError, TBool aOverrideError)
  1.1747 +	{
  1.1748 +	if (iError == KErrNone || aOverrideError)
  1.1749 +		{
  1.1750 +		iError = aError;		
  1.1751 +		}
  1.1752 +
  1.1753 +	iObserver.MfaocComplete(iError, iCurrentConfig->iController, iCurrentConfig->iControllerUid, &iSourceHandle, &iSinkHandle);
  1.1754 +
  1.1755 +	// if we've just attempted to open the Secondary controller, 
  1.1756 +	// try to open the Primary controller
  1.1757 +	if (iCurrentConfig == iSecondaryConfig)
  1.1758 +		{
  1.1759 +		if (iError == KErrNone)
  1.1760 +			OpenPrimaryController();
  1.1761 +		}
  1.1762 +
  1.1763 +	// if we failed to open, may as well free up some memory
  1.1764 +	// if open succeeded we need to preserve state in case of a re-open
  1.1765 +	if (iError != KErrNone)
  1.1766 +		{
  1.1767 +		if(iControllerIndex >= iControllerCount-1)
  1.1768 +			{
  1.1769 +			Close();
  1.1770 +			}
  1.1771 +		else //if there are other controllers selected in the controller list, try them
  1.1772 +			{
  1.1773 +			Cancel();
  1.1774 +			if(iAddDataSourceSinkAsync)
  1.1775 +				{
  1.1776 +				iAddDataSourceSinkAsync->Cancel();
  1.1777 +				}
  1.1778 +
  1.1779 + 			TryNextController();
  1.1780 +			}
  1.1781 +		}
  1.1782 +	}
  1.1783 +
  1.1784 +void CMMFFindAndOpenController::SchedSendError(TInt aError)
  1.1785 +	{
  1.1786 +	if (aError != KErrNone)
  1.1787 +		iError = aError;
  1.1788 +	iState = ESendError;
  1.1789 +	KickState();
  1.1790 +	}
  1.1791 +
  1.1792 +void CMMFFindAndOpenController::BuildControllerListFileNameL()
  1.1793 +	{
  1.1794 +	// Retrieve a list of possible controllers from ECOM
  1.1795 +	// If we don't have a match, leave with unsupported
  1.1796 +
  1.1797 +	iControllers.ResetAndDestroy();
  1.1798 +	iPrioritisedControllers.Reset();
  1.1799 +
  1.1800 +	TControllerMode mode = iCurrentConfig->iControllerMode;
  1.1801 +
  1.1802 +	// if we're playing, try to get the MIME type from the Content Access
  1.1803 +	// Framework (CAF) & use that to select a controller - if that fails, 
  1.1804 +	// try to select a controller based on the header data/file extension
  1.1805 +	
  1.1806 +	CMMFUtilityFileInfo* fileInfo = NULL;
  1.1807 +
  1.1808 +	TInt error;
  1.1809 +	
  1.1810 +	//If the current CMMSourceSink is a CMMFileSourceSink
  1.1811 +	// Using the previous version we'd get KErrCANoPermission when calling EvaluateIntent in the
  1.1812 +	// CMMFUtilityFileInfo ConstructL as the intent == EUnknown, so now pass the intent as a parameter
  1.1813 +	// to TMMFileHandleSource and....
  1.1814 +	TBool isSecureDrmProcess = EFalse;
  1.1815 +	//need to do this only in local playback mode
  1.1816 +	//UseSecureDRMProcess() function in called only in case of local play / record
  1.1817 +	// so we'll just chk for playback mode
  1.1818 +	if(mode == EPlayback)
  1.1819 +	    {
  1.1820 +	    TRAP(error, UseSecureDRMProcessL(isSecureDrmProcess));
  1.1821 +	    if(error == KErrPermissionDenied)
  1.1822 +	    	{
  1.1823 +	    	isSecureDrmProcess = ETrue;
  1.1824 +	    	}
  1.1825 +	    else
  1.1826 +	    	{
  1.1827 +	    	User::LeaveIfError(error);
  1.1828 +	    	}
  1.1829 +	    }
  1.1830 +    TRAP(error, fileInfo = CreateFileInfoL(isSecureDrmProcess));
  1.1831 +    
  1.1832 +	if (fileInfo != NULL)
  1.1833 +		{
  1.1834 +		CleanupDeletePushL(fileInfo);
  1.1835 +		}
  1.1836 +	
  1.1837 +	if (error != KErrNone)
  1.1838 +		{
  1.1839 +		// if playback mode, leave for any error
  1.1840 +		// if record mode, allow KErrNotFound
  1.1841 +		if (mode == EPlayback || (mode != EPlayback && error != KErrNotFound))
  1.1842 +			{
  1.1843 +			User::Leave(error);
  1.1844 +			}
  1.1845 +		}
  1.1846 +
  1.1847 +	CMMFControllerPluginSelectionParameters* cSelect = NULL;
  1.1848 +	if (isSecureDrmProcess)
  1.1849 +		{
  1.1850 +		cSelect = CMMFControllerSecureDrmPluginSelectionParameters::NewLC();
  1.1851 +		}
  1.1852 +	else
  1.1853 +		{
  1.1854 +		cSelect = CMMFControllerPluginSelectionParameters::NewLC();
  1.1855 +		}
  1.1856 +	RArray<TUid> mediaIds;
  1.1857 +	CleanupClosePushL(mediaIds);
  1.1858 +	User::LeaveIfError(mediaIds.Append(iMediaId));
  1.1859 +
  1.1860 +	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
  1.1861 +
  1.1862 +	if (mode == EPlayback)
  1.1863 +		{
  1.1864 +		ASSERT(fileInfo!=NULL);
  1.1865 +		TBuf8<KMaxMimeLength> mimeType;
  1.1866 +		TBool mimeTypeKnown = fileInfo->GetFileMimeTypeL(mimeType);
  1.1867 +		if (mimeTypeKnown)
  1.1868 +			{
  1.1869 +			CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
  1.1870 +			fSelect->SetMatchToMimeTypeL(mimeType);
  1.1871 +			cSelect->SetRequiredPlayFormatSupportL(*fSelect);
  1.1872 +			cSelect->ListImplementationsL(iControllers);
  1.1873 +			CleanupStack::PopAndDestroy(fSelect);
  1.1874 +			}
  1.1875 +
  1.1876 +
  1.1877 +		// copy to the iPrioritisedControllers array - this is a NOOP if the 
  1.1878 +		// MIME type is not known since iControllers will be empty
  1.1879 +		ASSERT(mimeTypeKnown || iControllers.Count() == 0);
  1.1880 +		for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
  1.1881 +			User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
  1.1882 +
  1.1883 +		iControllerCount = iPrioritisedControllers.Count();
  1.1884 +		if (iControllerCount > 0)
  1.1885 +			{
  1.1886 +			// Clean up
  1.1887 +			// cSelect, mediaIds, 
  1.1888 +			CleanupStack::PopAndDestroy(2, cSelect);
  1.1889 +			if (fileInfo != NULL)
  1.1890 +				{
  1.1891 +				CleanupStack::PopAndDestroy(fileInfo);
  1.1892 +				}
  1.1893 +			return;
  1.1894 +			}
  1.1895 +		}
  1.1896 +
  1.1897 +	// Retrieve header data first. If file doesn't exist, its ok.
  1.1898 +	HBufC8* headerData = HBufC8::NewLC(KMaxHeaderSize);
  1.1899 +	TPtr8 headerDataPtr = headerData->Des();
  1.1900 +	if (fileInfo)
  1.1901 +		{
  1.1902 +		fileInfo->GetFileHeaderDataL(headerDataPtr, KMaxHeaderSize);
  1.1903 +		}
  1.1904 +
  1.1905 +	// Get the filename's suffix
  1.1906 +	HBufC8* fileSuffix = CMMFClientUtility::GetFileExtensionL(iFileName);
  1.1907 +
  1.1908 +	CleanupStack::PushL(fileSuffix);
  1.1909 +	TPtr8 fileSuffixPtr = fileSuffix->Des();
  1.1910 +
  1.1911 +	// Get the secondary filename's header data (for convert)
  1.1912 +	HBufC8* headerDataSecondary = HBufC8::NewLC(KMaxHeaderSize);
  1.1913 +	TPtr8 headerDataPtrSecondary = headerDataSecondary->Des();
  1.1914 +	if (iFileNameSecondary.Length() > 0 && fileInfo)
  1.1915 +		{
  1.1916 +		fileInfo->GetFileHeaderDataL(headerDataPtrSecondary, KMaxHeaderSize);
  1.1917 +		}
  1.1918 +
  1.1919 +	// Get the secondary filename's suffix
  1.1920 +	HBufC8* fileSuffixSecondary = CMMFClientUtility::GetFileExtensionL(iFileNameSecondary);
  1.1921 +	CleanupStack::PushL(fileSuffixSecondary);
  1.1922 +	TPtr8 fileSuffixPtrSecondary = fileSuffixSecondary->Des();
  1.1923 +
  1.1924 +
  1.1925 +	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
  1.1926 +
  1.1927 +	if (mode == EPlayback || mode == EConvert)
  1.1928 +		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
  1.1929 +	if (mode == ERecord || mode == EConvert)
  1.1930 +		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
  1.1931 +	
  1.1932 +	cSelect->ListImplementationsL(iControllers);
  1.1933 +	
  1.1934 +	if (iControllers.Count()==0)
  1.1935 +		User::Leave(KErrNotSupported);
  1.1936 +
  1.1937 +	if (mode == ERecord)
  1.1938 +		{
  1.1939 +		CMMFClientUtility::PrioritiseControllersL(
  1.1940 +			iControllers, 
  1.1941 +			headerDataPtrSecondary, 
  1.1942 +			fileSuffixPtrSecondary, 
  1.1943 +			headerDataPtr, 
  1.1944 +			fileSuffixPtr, 
  1.1945 +			iPrioritisedControllers);
  1.1946 +		}
  1.1947 +	else
  1.1948 +		{
  1.1949 +		CMMFClientUtility::PrioritiseControllersL(
  1.1950 +			iControllers, 
  1.1951 +			headerDataPtr, 
  1.1952 +			fileSuffixPtr, 
  1.1953 +			headerDataPtrSecondary, 
  1.1954 +			fileSuffixPtrSecondary, 
  1.1955 +			iPrioritisedControllers);
  1.1956 +		}
  1.1957 +	
  1.1958 +	iControllerCount = iPrioritisedControllers.Count();
  1.1959 +	if (iControllerCount == 0)
  1.1960 +		User::Leave(KErrNotSupported);
  1.1961 +	
  1.1962 +	// Clean up
  1.1963 +	// cSelect, mediaIds, 
  1.1964 +	// headerData, fileSuffix, headerDataSecondary, fileSuffixSecondary, 
  1.1965 +	// fSelect
  1.1966 +	CleanupStack::PopAndDestroy(7, cSelect);
  1.1967 +	if (fileInfo != NULL)
  1.1968 +		{
  1.1969 +		CleanupStack::PopAndDestroy(fileInfo);
  1.1970 +		}
  1.1971 +	}
  1.1972 +
  1.1973 +void CMMFFindAndOpenController::BuildControllerListDescriptorL()
  1.1974 +	{
  1.1975 +	// Retrieve a list of possible controllers from ECOM
  1.1976 +	// If we don't have a match, leave with unsupported
  1.1977 +
  1.1978 +	iControllers.ResetAndDestroy();
  1.1979 +
  1.1980 +	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
  1.1981 +	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
  1.1982 +
  1.1983 +	
  1.1984 +	RArray<TUid> mediaIds;
  1.1985 +	CleanupClosePushL(mediaIds);
  1.1986 +	User::LeaveIfError(mediaIds.Append(iMediaId));
  1.1987 +
  1.1988 +	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
  1.1989 +	
  1.1990 +	TPtrC8 header = iDescriptor.Left(KMaxHeaderSize);
  1.1991 +	fSelect->SetMatchToHeaderDataL(header);
  1.1992 +	
  1.1993 +	
  1.1994 +	TControllerMode mode = iCurrentConfig->iControllerMode;
  1.1995 +	if (mode == EPlayback || mode == EConvert)
  1.1996 +		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
  1.1997 +	if (mode == ERecord || mode == EConvert)
  1.1998 +		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
  1.1999 +
  1.2000 +	cSelect->ListImplementationsL(iControllers);
  1.2001 +
  1.2002 +	iControllerCount = iControllers.Count();
  1.2003 +	if (iControllerCount == 0)
  1.2004 +		User::Leave(KErrNotSupported);
  1.2005 +
  1.2006 +	// Clean up
  1.2007 +	// cSelect, fSelect, mediaIds
  1.2008 +	CleanupStack::PopAndDestroy(3, cSelect);
  1.2009 +	}
  1.2010 +
  1.2011 +void CMMFFindAndOpenController::BuildControllerListUrlL()
  1.2012 +	{
  1.2013 +	// Retrieve a list of possible controllers from ECOM
  1.2014 +	// If we don't have a match, leave with unsupported
  1.2015 +
  1.2016 +	iControllers.ResetAndDestroy();
  1.2017 +
  1.2018 +	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
  1.2019 +	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
  1.2020 +
  1.2021 +	RArray<TUid> mediaIds;
  1.2022 +	CleanupClosePushL(mediaIds);
  1.2023 +	User::LeaveIfError(mediaIds.Append(iMediaId));
  1.2024 +
  1.2025 +	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
  1.2026 +	
  1.2027 +
  1.2028 + 	if (*iMimeType != KNullDesC8)
  1.2029 +		{
  1.2030 +		fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
  1.2031 +		}
  1.2032 +	else
  1.2033 +		{
  1.2034 +		fSelect->SetMatchToUriSupportL(*iUrl);
  1.2035 +		}
  1.2036 +	
  1.2037 +	TControllerMode mode = iCurrentConfig->iControllerMode;
  1.2038 +	if (mode == EPlayback || mode == EConvert)
  1.2039 +		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
  1.2040 +	if (mode == ERecord || mode == EConvert)
  1.2041 +		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
  1.2042 +
  1.2043 +	cSelect->ListImplementationsL(iControllers);
  1.2044 +
  1.2045 +	iControllerCount = iControllers.Count();
  1.2046 +	if (iControllerCount == 0)
  1.2047 +		User::Leave(KErrNotSupported);
  1.2048 +
  1.2049 +	// Clean up
  1.2050 +	// cSelect, fSelect, mediaIds
  1.2051 +	CleanupStack::PopAndDestroy(3, cSelect);
  1.2052 +	}
  1.2053 +
  1.2054 +void CMMFFindAndOpenController::BuildControllerListFormatL()
  1.2055 +	{
  1.2056 +	// Retrieve a list of possible controllers from ECOM
  1.2057 +	// If we don't have a match, leave with unsupported
  1.2058 +
  1.2059 +	iControllers.ResetAndDestroy();
  1.2060 +	iPrioritisedControllers.Reset();
  1.2061 +
  1.2062 +	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
  1.2063 +
  1.2064 +	// Select the media IDs to allow
  1.2065 +	RArray<TUid> mediaIds;
  1.2066 +	CleanupClosePushL(mediaIds);
  1.2067 +	User::LeaveIfError(mediaIds.Append(iMediaId));
  1.2068 +
  1.2069 +	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
  1.2070 +
  1.2071 +	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
  1.2072 +
  1.2073 +	TControllerMode mode = iCurrentConfig->iControllerMode;
  1.2074 +	if (mode == EPlayback || mode == EConvert)
  1.2075 +		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
  1.2076 +	if (mode == ERecord || mode == EConvert)
  1.2077 +		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
  1.2078 +
  1.2079 +	//Obtain a list of the controllers
  1.2080 +	cSelect->ListImplementationsL(iControllers);
  1.2081 +
  1.2082 +	CleanupStack::PopAndDestroy(3, cSelect); // cSelect, mediaIds, fSelect
  1.2083 +
  1.2084 +	iControllerCount = iControllers.Count();
  1.2085 +	if (iControllerCount == 0)
  1.2086 +		User::Leave(KErrNotSupported);
  1.2087 +
  1.2088 +	TUid formatUidPrimary;
  1.2089 +	TUid formatUidSecondary;
  1.2090 +	if (mode == ERecord)
  1.2091 +		{
  1.2092 +		formatUidSecondary = iFormatUid;
  1.2093 +		formatUidPrimary = iFormatUidSecondary;
  1.2094 +		}
  1.2095 +	else
  1.2096 +		{
  1.2097 +		formatUidPrimary = iFormatUid;
  1.2098 +		formatUidSecondary = iFormatUidSecondary;
  1.2099 +		}
  1.2100 +	
  1.2101 +	for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
  1.2102 +		{
  1.2103 +		const RMMFFormatImplInfoArray& recFormatInfo = iControllers[controllerIndex]->RecordFormats();
  1.2104 +		const RMMFFormatImplInfoArray& playFormatInfo = iControllers[controllerIndex]->PlayFormats();
  1.2105 +
  1.2106 +		TBool playFormatMatched = EFalse;
  1.2107 +		TBool recordFormatMatched = EFalse;
  1.2108 +
  1.2109 +		if (formatUidPrimary == KNullUid)
  1.2110 +			{
  1.2111 +			playFormatMatched = ETrue;
  1.2112 +			}
  1.2113 +		else
  1.2114 +			{
  1.2115 +			for(TInt playFormatIndex =0; playFormatIndex < playFormatInfo.Count(); playFormatIndex++)
  1.2116 +				{
  1.2117 +				if(playFormatInfo[playFormatIndex]->Uid() == formatUidPrimary)
  1.2118 +					{
  1.2119 +					playFormatMatched = ETrue;
  1.2120 +					break;
  1.2121 +					}
  1.2122 +				}
  1.2123 +			}
  1.2124 +
  1.2125 +		if (formatUidSecondary == KNullUid)
  1.2126 +			{
  1.2127 +			recordFormatMatched = ETrue;
  1.2128 +			}
  1.2129 +		else
  1.2130 +			{
  1.2131 +			for (TInt recFormatIndex =0; recFormatIndex < recFormatInfo.Count(); recFormatIndex++)
  1.2132 +				{
  1.2133 +				if (recFormatInfo[recFormatIndex]->Uid() == formatUidSecondary)
  1.2134 +					{
  1.2135 +					recordFormatMatched = ETrue;
  1.2136 +					break;
  1.2137 +					}
  1.2138 +				}
  1.2139 +			}
  1.2140 +
  1.2141 +		if (playFormatMatched && recordFormatMatched)
  1.2142 +			User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
  1.2143 +		}
  1.2144 +
  1.2145 +	iControllerCount = iPrioritisedControllers.Count();
  1.2146 +	if (iControllerCount == 0)
  1.2147 +		User::Leave(KErrNotSupported);
  1.2148 +	}
  1.2149 +	
  1.2150 +CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TSourceSink& aParams) 
  1.2151 +	{
  1.2152 +	if (aParams.iUseFileHandle)
  1.2153 +		{
  1.2154 +		return CMMFileSourceSink::NewL(aParams.iUid, aParams.iFileHandle);
  1.2155 +		}
  1.2156 +	return CMMSourceSink::NewL(aParams.iUid, aParams.iConfigData);
  1.2157 +	}
  1.2158 +
  1.2159 +
  1.2160 +CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TMMSource& aSource) 
  1.2161 +	{	
  1.2162 +	if (!(aSource.SourceType()==KUidMMFileSource || 
  1.2163 +		aSource.SourceType()==KUidMMFileHandleSource))
  1.2164 +		User::Leave(KErrNotSupported);
  1.2165 +
  1.2166 +	return CMMFileSourceSink::NewL(KUidMmfFileSource, aSource);
  1.2167 +	}
  1.2168 +
  1.2169 +CMMFUtilityFileInfo* CMMFFindAndOpenController::CreateFileInfoL(TBool aSecureDRMMode)
  1.2170 +	{
  1.2171 +	CMMFUtilityFileInfo* fileInfo = NULL;
  1.2172 +	if (iUseFileHandle) 
  1.2173 +		{
  1.2174 +		if (iUniqueId != NULL)
  1.2175 +			{
  1.2176 +			TMMFileHandleSource fileHandleSource(iFileHandle, (*iUniqueId), iIntent,iEnableUi);
  1.2177 +			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
  1.2178 +			}
  1.2179 +		else
  1.2180 +			{
  1.2181 +			TMMFileHandleSource fileHandleSource(iFileHandle);
  1.2182 +			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
  1.2183 +			}
  1.2184 +		}
  1.2185 +	else
  1.2186 +		{
  1.2187 +		if (iUniqueId != NULL)
  1.2188 +			{
  1.2189 +			TMMFileSource fileSource(iFileName, (*iUniqueId), iIntent,iEnableUi);	
  1.2190 +			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
  1.2191 +			}
  1.2192 +		else
  1.2193 +			{
  1.2194 +			TMMFileSource fileSource(iFileName);	
  1.2195 +			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
  1.2196 +			}
  1.2197 +		}
  1.2198 +	return fileInfo;
  1.2199 +	}
  1.2200 +	
  1.2201 +EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const TDesC8& aConfigData)	
  1.2202 +	: iConfigData(aConfigData)
  1.2203 +	{
  1.2204 +	iUid = aUid;
  1.2205 +
  1.2206 +	iUseFileHandle = EFalse;
  1.2207 +	}
  1.2208 +	
  1.2209 +EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const RFile& aFile)	
  1.2210 +	: iConfigData(KNullDesC8)
  1.2211 +	{
  1.2212 +	iUid = aUid;
  1.2213 +
  1.2214 +	iFileHandle = aFile;
  1.2215 +	iUseFileHandle = ETrue;
  1.2216 +	}
  1.2217 +	
  1.2218 +EXPORT_C void CMMFFindAndOpenController::SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands)
  1.2219 +	{	
  1.2220 +	iScreenNumber = aScreenNumber;
  1.2221 +	iVideoSetInitScreenCustomCommands = aVideoSetInitScreenCustomCommands;
  1.2222 +	}
  1.2223 +		
  1.2224 +CMMFFindAndOpenController::CConfig::CConfig()
  1.2225 +	{
  1.2226 +	}
  1.2227 +	
  1.2228 +void CMMFFindAndOpenController::CConfig::Close()
  1.2229 +	{
  1.2230 +	delete iSource;
  1.2231 +	iSource = NULL;
  1.2232 +	delete iSink;
  1.2233 +	iSink = NULL;
  1.2234 +	}
  1.2235 +CMMFFindAndOpenController::CConfig::~CConfig()
  1.2236 +	{
  1.2237 +	Close();
  1.2238 +	}
  1.2239 +
  1.2240 +void CMMFFindAndOpenController::UseSecureDRMProcessL(TBool& aIsSecureDrmProcess)
  1.2241 +    {
  1.2242 +    if(iHasDrmCapability)//if client has DRM capability, we never use Secure DRM Process
  1.2243 +        {
  1.2244 +        aIsSecureDrmProcess = EFalse;
  1.2245 +        return;
  1.2246 +        }       
  1.2247 +    TBool isDataProtected = EFalse;
  1.2248 +    ContentAccess::CContent* content = NULL;
  1.2249 +    TControllerMode mode = iCurrentConfig->iControllerMode;
  1.2250 +
  1.2251 +    //setting aUseSecureDrmProcess to false(default value)
  1.2252 +    aIsSecureDrmProcess = EFalse;
  1.2253 +
  1.2254 +    //need to proceed only in case of local playback mode
  1.2255 +    TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
  1.2256 +    TBool localPlaybackMode = ( mode == EPlayback && 
  1.2257 +                                (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource) );
  1.2258 +    if(!localPlaybackMode)
  1.2259 +        {
  1.2260 +        return;
  1.2261 +        }
  1.2262 +
  1.2263 +    if (iUseFileHandle && iOwnFileHandle) 
  1.2264 +        {
  1.2265 +        content = ContentAccess::CContent::NewLC(iFileHandle);
  1.2266 +        }
  1.2267 +    else if(iFileName.Length())  //need to check if file name exist
  1.2268 +        {
  1.2269 +        content = ContentAccess::CContent::NewLC(iFileName);
  1.2270 +        }
  1.2271 +    else
  1.2272 +        {//in case of descriptor source content object will not be created
  1.2273 +        return;
  1.2274 +        }
  1.2275 +    TInt value = 0;
  1.2276 +    TInt error = KErrNone;
  1.2277 +    if(iUniqueId != NULL)
  1.2278 +    	{
  1.2279 +    	error = content->GetAttribute(EIsProtected, value, *iUniqueId );
  1.2280 +    	}
  1.2281 +    else
  1.2282 +    	{
  1.2283 +    	error = content->GetAttribute(EIsProtected, value);
  1.2284 +    	}
  1.2285 +    if( (error == KErrNone && value) || error == KErrPermissionDenied )
  1.2286 +        {//2nd condition can be true if GetAttribute checks for DRM cap and return error if not found
  1.2287 +        isDataProtected = ETrue;
  1.2288 +        }
  1.2289 +    else if( error != KErrNone && error != KErrPermissionDenied)
  1.2290 +        {//leaving as GetAttribute of CAF caused an error.
  1.2291 +        User::Leave(error);
  1.2292 +        }
  1.2293 +
  1.2294 +    CleanupStack::PopAndDestroy(content);
  1.2295 +    if(isDataProtected && !iHasDrmCapability && mode == EPlayback)
  1.2296 +        {//only when the Data is protected and client does not have the DRM capability, we need secure DRM process
  1.2297 +        aIsSecureDrmProcess = ETrue;
  1.2298 +        }
  1.2299 +    }
  1.2300 +
  1.2301 +EXPORT_C CMMSourceSink* CMMSourceSink::NewLC(TUid aUid, const TDesC8& aDescriptor)
  1.2302 +	{
  1.2303 +	CMMSourceSink* self = new (ELeave) CMMSourceSink(aUid);	
  1.2304 +	CleanupStack::PushL(self);
  1.2305 +	self->ConstructL(aDescriptor);
  1.2306 +	return self;
  1.2307 +	}
  1.2308 +
  1.2309 +EXPORT_C CMMSourceSink* CMMSourceSink::NewL(TUid aUid, const TDesC8& aDescriptor)
  1.2310 +	{
  1.2311 +	CMMSourceSink* sourcesink = CMMSourceSink::NewLC(aUid, aDescriptor);
  1.2312 +	CleanupStack::Pop(sourcesink);
  1.2313 +	return sourcesink;
  1.2314 +	}
  1.2315 +
  1.2316 +CMMSourceSink::CMMSourceSink(TUid aUid)
  1.2317 +	: iUid(aUid)
  1.2318 +	{
  1.2319 +	}
  1.2320 +	
  1.2321 +CMMSourceSink::~CMMSourceSink()
  1.2322 +	{
  1.2323 +	delete iBuf;
  1.2324 +	}
  1.2325 +	
  1.2326 +void CMMSourceSink::ConstructL(const TDesC8& aDescriptor)
  1.2327 +	{
  1.2328 +	iBuf = aDescriptor.AllocL();
  1.2329 +	}
  1.2330 +	
  1.2331 +TUid CMMSourceSink::SourceSinkUid() const
  1.2332 +	{
  1.2333 +	return iUid;
  1.2334 +	}
  1.2335 +	
  1.2336 +const TDesC8& CMMSourceSink::SourceSinkData() const
  1.2337 +	{
  1.2338 +	return *iBuf;
  1.2339 +	}
  1.2340 +	
  1.2341 +TBool CMMSourceSink::CarryingFileHandle() const
  1.2342 +	{
  1.2343 +	return EFalse;
  1.2344 +	}
  1.2345 +
  1.2346 +EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const RFile& aFile)
  1.2347 +	{
  1.2348 +	CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);	
  1.2349 +	CleanupStack::PushL(self);
  1.2350 +	self->ConstructL(aFile);
  1.2351 +	return self;
  1.2352 +	}
  1.2353 +
  1.2354 +EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const RFile& aFile)
  1.2355 +	{
  1.2356 +	CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aFile);
  1.2357 +	CleanupStack::Pop(sourcesink);
  1.2358 +	return sourcesink;
  1.2359 +	}
  1.2360 +	
  1.2361 +CMMFileSourceSink::CMMFileSourceSink(TUid aUid)
  1.2362 +	: CMMSourceSink(aUid)
  1.2363 +	{
  1.2364 +	}
  1.2365 +
  1.2366 +void CMMFileSourceSink::ConstructL(const RFile& aFile)
  1.2367 +	{
  1.2368 +	User::LeaveIfError(iHandle.Duplicate(aFile));
  1.2369 +	iUsingFileHandle = ETrue;
  1.2370 +	iFileName = HBufC::NewMaxL(KMaxFileName);
  1.2371 +	TPtr fileNamePtr = iFileName->Des();
  1.2372 +	iHandle.Name(fileNamePtr);
  1.2373 +	DoCreateFileHandleSourceConfigDataL();
  1.2374 +	}
  1.2375 +
  1.2376 +void CMMFileSourceSink::DoCreateFileHandleSourceConfigDataL()
  1.2377 +	{
  1.2378 +	CBufFlat* buf = CBufFlat::NewL(KExpandSize);
  1.2379 +	CleanupStack::PushL(buf);
  1.2380 +	RBufWriteStream stream;
  1.2381 +	stream.Open(*buf);
  1.2382 +	CleanupClosePushL(stream);
  1.2383 +	
  1.2384 +	TPckgBuf<RFile*> fileptr(&iHandle);
  1.2385 +	stream.WriteInt32L(KMMFileHandleSourceUid.iUid);
  1.2386 +	stream.WriteL(fileptr);
  1.2387 +	
  1.2388 +	TInt length = 0;
  1.2389 +	if (iUniqueId != NULL)
  1.2390 +		length = iUniqueId->Length();
  1.2391 +	stream.WriteInt32L(length);
  1.2392 +	if (length>0)
  1.2393 +		stream.WriteL(*iUniqueId);
  1.2394 +	
  1.2395 +	stream.WriteInt32L(iEnableUI);
  1.2396 +	
  1.2397 +	stream.CommitL();
  1.2398 +	CleanupStack::PopAndDestroy(&stream);		
  1.2399 +	iSourceSinkData = buf->Ptr(0).AllocL();
  1.2400 +	
  1.2401 +	CleanupStack::PopAndDestroy(buf); 
  1.2402 +	}
  1.2403 +	
  1.2404 +const TDesC8& CMMFileSourceSink::SourceSinkData() const
  1.2405 +	{
  1.2406 +	ASSERT(iSourceSinkData);
  1.2407 +	return *iSourceSinkData;
  1.2408 +	}
  1.2409 +
  1.2410 +CMMFileSourceSink::~CMMFileSourceSink()
  1.2411 +	{
  1.2412 +	iHandle.Close(); // delete whatever
  1.2413 +	delete iFileName;
  1.2414 +	delete iSourceSinkData;
  1.2415 +	delete iUniqueId;
  1.2416 +	}
  1.2417 +
  1.2418 +EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const TMMSource& aSource)
  1.2419 +	{
  1.2420 +	CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);	
  1.2421 +	CleanupStack::PushL(self);
  1.2422 +	self->ConstructL(aSource);
  1.2423 +	return self;
  1.2424 +	}
  1.2425 +
  1.2426 +EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const TMMSource& aSource)
  1.2427 +	{
  1.2428 +	CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aSource);
  1.2429 +	CleanupStack::Pop(sourcesink);
  1.2430 +	return sourcesink;
  1.2431 +	}
  1.2432 +	
  1.2433 +void CMMFileSourceSink::ConstructL(const TMMSource& aSource)
  1.2434 +	{
  1.2435 +	iUniqueId = aSource.UniqueId().AllocL();
  1.2436 +	iIntent = aSource.Intent();
  1.2437 +	iEnableUI = aSource.IsUIEnabled();
  1.2438 +	
  1.2439 +	if (aSource.SourceType() == KUidMMFileSource)
  1.2440 +		{
  1.2441 +		const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
  1.2442 +		iFileName = fileSource.Name().AllocL();
  1.2443 +		
  1.2444 +		DoCreateFileSourceConfigDataL();
  1.2445 +		}
  1.2446 +	else if (aSource.SourceType() == KUidMMFileHandleSource)
  1.2447 +		{
  1.2448 +		const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
  1.2449 +		iHandle.Close(); // in case already open
  1.2450 +		User::LeaveIfError(iHandle.Duplicate(fileHandleSource.Handle()));
  1.2451 +		iUsingFileHandle = ETrue;
  1.2452 +		iFileName = HBufC::NewMaxL(KMaxFileName);
  1.2453 +		TPtr fileNamePtr = iFileName->Des();
  1.2454 +		iHandle.Name(fileNamePtr);
  1.2455 +		
  1.2456 +		DoCreateFileHandleSourceConfigDataL();
  1.2457 +		}
  1.2458 +	else
  1.2459 +		{
  1.2460 +		User::Leave(KErrNotSupported);
  1.2461 +		}
  1.2462 +	}
  1.2463 +	
  1.2464 +void CMMSourceSink::EvaluateIntentL()
  1.2465 +	{
  1.2466 +	}
  1.2467 +	
  1.2468 +void CMMFileSourceSink::EvaluateIntentL()
  1.2469 +	{
  1.2470 +	if (iUsingFileHandle)
  1.2471 +		{
  1.2472 +   		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
  1.2473 +   		Content->OpenContentLC(iIntent, *iUniqueId);
  1.2474 +   		CleanupStack::PopAndDestroy(2, Content);	
  1.2475 +		}
  1.2476 +	else	
  1.2477 +		{
  1.2478 +		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
  1.2479 +   		Content->OpenContentLC(iIntent, *iUniqueId);
  1.2480 +   		CleanupStack::PopAndDestroy(2, Content);
  1.2481 +		}
  1.2482 +	}
  1.2483 +
  1.2484 +
  1.2485 +	
  1.2486 +EXPORT_C void CMMFileSourceSink::EvaluateIntentL(ContentAccess::TIntent aIntent)
  1.2487 +	{
  1.2488 +	if (iUsingFileHandle)
  1.2489 +		{
  1.2490 +   		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
  1.2491 +   		Content->OpenContentLC(aIntent, *iUniqueId);
  1.2492 +   		CleanupStack::PopAndDestroy(2, Content);	
  1.2493 +		}
  1.2494 +	else	
  1.2495 +		{
  1.2496 +		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
  1.2497 +   		Content->OpenContentLC(aIntent, *iUniqueId);
  1.2498 +   		CleanupStack::PopAndDestroy(2, Content);
  1.2499 +		}
  1.2500 +	}
  1.2501 +
  1.2502 +void CMMFileSourceSink::DoCreateFileSourceConfigDataL()
  1.2503 +	{
  1.2504 +	CBufFlat* buf = CBufFlat::NewL(KExpandSize);
  1.2505 +	CleanupStack::PushL(buf);
  1.2506 +	RBufWriteStream stream;
  1.2507 +	stream.Open(*buf);
  1.2508 +	CleanupClosePushL(stream);
  1.2509 +	
  1.2510 +	stream.WriteInt32L(KMMFileSourceUid.iUid);
  1.2511 +	stream.WriteInt32L(iFileName->Length());
  1.2512 +	stream.WriteL(*iFileName);
  1.2513 +	TInt length = 0;
  1.2514 +	if (iUniqueId != NULL)
  1.2515 +		length = iUniqueId->Length();
  1.2516 +	stream.WriteInt32L(length);
  1.2517 +	if (length>0)
  1.2518 +		stream.WriteL(*iUniqueId);
  1.2519 +	
  1.2520 +	stream.WriteInt32L(iEnableUI);
  1.2521 +	
  1.2522 +	stream.CommitL();
  1.2523 +	CleanupStack::PopAndDestroy(&stream);
  1.2524 +	iSourceSinkData = buf->Ptr(0).AllocL();
  1.2525 +		
  1.2526 +	CleanupStack::PopAndDestroy(buf); 
  1.2527 +	}	
  1.2528 +	
  1.2529 +TBool CMMFileSourceSink::CarryingFileHandle() const
  1.2530 +	{
  1.2531 +	return iUsingFileHandle;
  1.2532 +	}
  1.2533 +
  1.2534 +