breakdeps/mmfclientutility.cpp
changeset 129 4a58d534bdaa
parent 128 8338c5c25b5b
child 130 40dccd6dd558
equal deleted inserted replaced
128:8338c5c25b5b 129:4a58d534bdaa
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Audio, MIDI and Video client utility functions.
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32std.h>
       
    19 #include <f32file.h>
       
    20 #include <bautils.h>
       
    21 #include <mmf/server/mmfdrmpluginserverproxy.h>
       
    22 #include <caf/content.h>
       
    23 #include <caf/data.h>
       
    24 using namespace ContentAccess;
       
    25 
       
    26 #include "mmfclientutility.h"
       
    27 #include <mmf/common/mmfpaniccodes.h>
       
    28 
       
    29 const TInt KMaxMimeLength = 256;
       
    30 const TInt KMaxHeaderSize = 256;
       
    31 const TInt KExpandSize = 100;
       
    32 
       
    33 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
    34 	const TInt KDefaultScreenNo = 0;
       
    35 #endif
       
    36 
       
    37 void CUPanic(TInt aCUPanicCode)
       
    38 	{
       
    39 	_LIT(KMMFMediaClientUtilityPaanicCategory, "MMFClientUtility");
       
    40 	User::Panic(KMMFMediaClientUtilityPaanicCategory, aCUPanicCode);
       
    41 	}
       
    42 
       
    43 /**
       
    44  * @internalComponent
       
    45  */
       
    46 EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid)
       
    47 	{
       
    48 	TUid ECOMUid = KNullUid;
       
    49 	if (aMdaFormatUid == KUidMdaClipFormatWav)	
       
    50 		ECOMUid = TUid::Uid(KMmfUidFormatWAVWrite);
       
    51 	else if (aMdaFormatUid == KUidMdaClipFormatAu)	
       
    52 		ECOMUid = TUid::Uid(KMmfUidFormatAUWrite);
       
    53 	else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)	
       
    54 		ECOMUid = TUid::Uid(KMmfUidFormatRAWWrite);
       
    55 	else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)	
       
    56 		ECOMUid = TUid::Uid(KAdvancedUidFormatAMRWrite);
       
    57 
       
    58 	return ECOMUid;
       
    59 	}
       
    60 
       
    61 /**
       
    62  * @internalComponent
       
    63  */
       
    64 EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid)
       
    65 	{
       
    66 	TUid ECOMUid = KNullUid;
       
    67 	if (aMdaFormatUid == KUidMdaClipFormatWav)	
       
    68 		ECOMUid = TUid::Uid(KMmfUidFormatWAVRead);
       
    69 	else if (aMdaFormatUid == KUidMdaClipFormatAu)	
       
    70 		ECOMUid = TUid::Uid(KMmfUidFormatAURead);
       
    71 	else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)	
       
    72 		ECOMUid = TUid::Uid(KMmfUidFormatRAWRead);
       
    73 	else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)	
       
    74 		ECOMUid = TUid::Uid(KAdvancedUidFormatAMRRead);
       
    75 
       
    76 	return ECOMUid;
       
    77 	}
       
    78 
       
    79 /**
       
    80  * @internalComponent
       
    81  */
       
    82 EXPORT_C TInt CMMFClientUtility::GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength)
       
    83 	{
       
    84 	RFs fsSession;
       
    85 	RFile file;
       
    86 	TInt error = KErrNone;
       
    87 
       
    88 	if ((error = fsSession.Connect()) == KErrNone)
       
    89 		{
       
    90 		if ((error = file.Open(fsSession, aFileName, EFileShareReadersOrWriters)) == KErrNone)
       
    91 			{
       
    92 			TInt size = 0;
       
    93 
       
    94 			if ((error = file.Size(size)) == KErrNone)
       
    95 				{
       
    96 				if (size > 0)
       
    97 					{
       
    98 					if (size > aMaxLength) 
       
    99 						size = aMaxLength;
       
   100 
       
   101 					error = file.Read(aHeaderData, size);
       
   102 					}
       
   103 				}
       
   104 			file.Close();
       
   105 			}
       
   106 		fsSession.Close();
       
   107 		}
       
   108 
       
   109 	return error;
       
   110 	}
       
   111 
       
   112 /**
       
   113  * @internalComponent
       
   114  */
       
   115 EXPORT_C TFourCC CMMFClientUtility::ConvertMdaCodecToFourCC(TMdaPackage& aCodec)
       
   116 	{
       
   117 	TFourCC dataType = KMMFFourCCCodeNULL;	
       
   118 	switch (aCodec.Uid().iUid)
       
   119 		{
       
   120 		case KUidMdaWavPcmCodecDefine: 
       
   121 			{
       
   122 			TMdaPcmWavCodec* pcmWavCodec = (TMdaPcmWavCodec*)&aCodec;
       
   123 			if (pcmWavCodec->iBits == TMdaPcmWavCodec::E8BitPcm)
       
   124 				dataType = KMMFFourCCCodePCMU8; //8 bit PCM
       
   125 			else 
       
   126 				dataType = KMMFFourCCCodePCM16; //16 bit PCM
       
   127 			break;
       
   128 			}
       
   129 		case KUidMdaAu8PcmCodecDefine:
       
   130 			dataType = KMMFFourCCCodePCM8;
       
   131 			break;
       
   132 		case KUidMdaAuCodecDefine:
       
   133 		case KUidMdaAu16PcmCodecDefine:
       
   134 			dataType = KMMFFourCCCodePCM16B;
       
   135 			break;
       
   136 
       
   137 		case KUidMdaAuMulawCodecDefine:
       
   138 		case KUidMdaWavMulawCodecDefine:
       
   139 		case KUidMdaRawAudioMulawCodecDefine:  //uLAW
       
   140 			dataType = KMMFFourCCCodeMuLAW;
       
   141 			break;
       
   142 		case KUidMdaAuAlawCodecDefine:
       
   143 		case KUidMdaWavAlawCodecDefine:
       
   144 		case KUidMdaRawAudioAlawCodecDefine:	 //ALAW
       
   145 			dataType = KMMFFourCCCodeALAW;
       
   146 			break;
       
   147 		case KUidMdaRawAudioS8PcmCodecDefine:	 //  P8
       
   148 			dataType = KMMFFourCCCodePCM8;
       
   149 			break;
       
   150 		case KUidMdaRawAudioU8PcmCodecDefine:	  // PU8
       
   151 			dataType = KMMFFourCCCodePCMU8;
       
   152 			break;
       
   153 		case KUidMdaRawAudioSL16PcmCodecDefine: // P16
       
   154 			dataType = KMMFFourCCCodePCM16;
       
   155 			break;
       
   156 		case KUidMdaRawAudioSB16PcmCodecDefine: //P16B
       
   157 			dataType = KMMFFourCCCodePCM16B;
       
   158 			break;
       
   159 		case KUidMdaRawAudioUL16PcmCodecDefine: //PU16
       
   160 			dataType = KMMFFourCCCodePCMU16;
       
   161 			break;
       
   162 		case KUidMdaRawAudioUB16PcmCodecDefine: //PU6B
       
   163 			dataType = KMMFFourCCCodePCMU16B; 
       
   164 			break;
       
   165 		case KUidMdaGsmWavCodecDefine: //GSM6 
       
   166 			dataType = KMMFFourCCCodeGSM610;
       
   167 			break;
       
   168 		case KUidMdaWavImaAdpcmCodecDefine:
       
   169 			dataType = KMMFFourCCCodeIMAD;
       
   170 			break;
       
   171 		case KUidMdaRawAmrCodecDefine:
       
   172 			dataType = KMMFFourCCCodeAMR;
       
   173 			break;
       
   174 		default:	// Not a Uid we recognise
       
   175 			dataType = KMMFFourCCCodeNULL;
       
   176 			break;
       
   177 		}
       
   178 	return dataType;
       
   179 	}
       
   180 
       
   181 
       
   182 CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewL(TMMSource& aSource, TBool aSecureDRMMode)
       
   183 	{
       
   184 	CMMFUtilityFileInfo* self = CMMFUtilityFileInfo::NewLC(aSource, aSecureDRMMode);
       
   185 	CleanupStack::Pop(self);
       
   186 	return self;
       
   187 	}
       
   188 
       
   189 
       
   190 CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewLC(TMMSource& aSource, TBool aSecureDRMMode)
       
   191 	{
       
   192 	CMMFUtilityFileInfo* self = new (ELeave) CMMFUtilityFileInfo;
       
   193 	CleanupStack::PushL(self);
       
   194 	self->ConstructL(aSource, aSecureDRMMode);
       
   195 	return self;
       
   196 	}
       
   197 
       
   198 
       
   199 void CMMFUtilityFileInfo::ConstructL(const TMMSource& aSource, TBool aSecureDRMMode)
       
   200 	{
       
   201 	if (!aSecureDRMMode)
       
   202 		{
       
   203 		if (aSource.SourceType()==KUidMMFileSource)
       
   204 			{
       
   205 			const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
       
   206 			iData = CData::NewL(TVirtualPathPtr(fileSource.Name(), fileSource.UniqueId()),
       
   207 								EContentShareReadWrite);
       
   208 			}
       
   209 
       
   210 		if (aSource.SourceType()==KUidMMFileHandleSource)
       
   211 			{
       
   212 			const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
       
   213 			iData = CData::NewL(fileHandleSource.Handle(), fileHandleSource.UniqueId());
       
   214 			}
       
   215 		
       
   216 		TInt err = iData->SetProperty(EAgentPropertyAgentUI, aSource.IsUIEnabled());		
       
   217 		if (err != KErrNone && err != KErrCANotSupported)
       
   218 			{
       
   219 			// KErrCANotSupported isn't a problem for us so eat the error code.
       
   220 			User::Leave(err);
       
   221 			}
       
   222 
       
   223 		err = iData->EvaluateIntent(aSource.Intent());
       
   224 		User::LeaveIfError(err);
       
   225 		}
       
   226 	else
       
   227 		{
       
   228 		// Use RMMFDRMPluginServerProxy as medium
       
   229 		iDrmPluginServer = new (ELeave) RMMFDRMPluginServerProxy;
       
   230 		User::LeaveIfError(iDrmPluginServer->Open());
       
   231 		
       
   232 		CBufFlat* dataBuffer = CBufFlat::NewL(KExpandSize);
       
   233 		CleanupStack::PushL(dataBuffer);
       
   234 		RBufWriteStream stream;
       
   235 		stream.Open(*dataBuffer);
       
   236 		CleanupClosePushL(stream);
       
   237 		
       
   238 		stream.WriteInt32L(aSource.UniqueId().Length());
       
   239 		stream.WriteL(aSource.UniqueId());
       
   240 		stream.WriteInt32L(aSource.IsUIEnabled());
       
   241 		TPckgBuf<ContentAccess::TIntent> intentPckg(aSource.Intent());
       
   242 		stream.WriteL(intentPckg);
       
   243 		stream.CommitL();
       
   244 	
       
   245 		CleanupStack::PopAndDestroy(&stream);
       
   246 		if (aSource.SourceType()==KUidMMFileSource)
       
   247 			{
       
   248 			const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
       
   249 			iDrmPluginServer->OpenDataContentL(fileSource.Name(), dataBuffer->Ptr(0));
       
   250 			}
       
   251 		if (aSource.SourceType()==KUidMMFileHandleSource)
       
   252 			{
       
   253 			const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
       
   254 			iDrmPluginServer->OpenDataContentL(fileHandleSource.Handle(), dataBuffer->Ptr(0));
       
   255 			}
       
   256 		CleanupStack::PopAndDestroy(dataBuffer);
       
   257 		}
       
   258 	}
       
   259 
       
   260 TInt CMMFUtilityFileInfo::EvaluateIntent(TIntent aIntent)
       
   261 	{
       
   262 	if (iData)
       
   263 		{
       
   264 		return iData->EvaluateIntent(aIntent);
       
   265 		}
       
   266 	else
       
   267 		{
       
   268 		ASSERT(iDrmPluginServer);
       
   269 		return iDrmPluginServer->EvaluateDataContentIntent(aIntent);
       
   270 		}
       
   271 	}
       
   272 /**
       
   273  * @internalComponent
       
   274  */
       
   275 TBool CMMFUtilityFileInfo::GetFileMimeTypeL(TDes8& aMimeType)
       
   276 	{
       
   277 	if (iData)
       
   278 		{
       
   279 		return iData->GetMimeTypeL(aMimeType);
       
   280 		}
       
   281 	else
       
   282 		{
       
   283 		ASSERT(iDrmPluginServer);
       
   284 		return iDrmPluginServer->GetDataContentMimeTypeL(aMimeType);
       
   285 		}
       
   286 	}
       
   287 
       
   288 /**
       
   289  * @internalComponent
       
   290  */
       
   291 void CMMFUtilityFileInfo::GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength)
       
   292 	{
       
   293 	if (iData)
       
   294 		{
       
   295 		TInt size = 0;
       
   296 		iData->DataSizeL(size);
       
   297 		if (size > 0)
       
   298 			{
       
   299 			if (size > aMaxLength) 
       
   300 				size = aMaxLength;
       
   301 			TInt pos = 0;
       
   302 			User::LeaveIfError(iData->Seek(ESeekStart, pos));
       
   303 			User::LeaveIfError(iData->Read(aHeaderData, size));
       
   304 			}
       
   305 		}
       
   306 	else
       
   307 		{
       
   308 		ASSERT(iDrmPluginServer);
       
   309 		iDrmPluginServer->GetDataContentFileHeaderL(aHeaderData, aMaxLength);
       
   310 		}
       
   311 	}
       
   312 
       
   313 /**
       
   314  * @internalComponent
       
   315  */
       
   316 EXPORT_C HBufC8* CMMFClientUtility::GetFileExtensionL(const TDesC& aFileName)
       
   317 	{
       
   318 	TParse fileName;
       
   319 	fileName.Set(aFileName,NULL,NULL);
       
   320 	HBufC8* fileSuffix = NULL;
       
   321 	if(fileName.ExtPresent())
       
   322 		{
       
   323 		TPtrC fileSuffixPtr(fileName.Ext());
       
   324 		fileSuffix = HBufC8::NewL(fileSuffixPtr.Length());
       
   325 		fileSuffix->Des().Copy(fileSuffixPtr);
       
   326 		}
       
   327 	else
       
   328 		{
       
   329 		fileSuffix = KNullDesC8().AllocL();
       
   330 		}
       
   331 	return fileSuffix;
       
   332 	}
       
   333 
       
   334 
       
   335 /**
       
   336  * @internalComponent
       
   337  */
       
   338 CMMFUtilityFileInfo::~CMMFUtilityFileInfo()
       
   339 	{
       
   340 	if (iData)
       
   341 		{
       
   342 		delete iData;
       
   343 		}
       
   344 	if (iDrmPluginServer)
       
   345 		{
       
   346 		iDrmPluginServer->Close();
       
   347 		delete iDrmPluginServer;
       
   348 		}
       
   349 	}
       
   350 
       
   351 /*
       
   352  * @internalComponent
       
   353  *
       
   354  * Returns an integer rating indicating how well the supplied format matches
       
   355  * the header data and file extension supplied.
       
   356  * 3 brownie points awarded for data & suffix match.
       
   357  * 2 brownie points awarded for data match alone.
       
   358  * 1 brownie point awarded for suffix match alone.
       
   359  */
       
   360 TInt CMMFClientUtility::GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension)
       
   361 	{
       
   362 	TInt browniePoints = 0;
       
   363 
       
   364 	if (aHeaderData.Length() > 0) // Non empty file
       
   365 		{
       
   366 		if (aFileExtension.Length() > 0) // With a file extension
       
   367 			{
       
   368 			if (format->SupportsHeaderDataL(aHeaderData) && 
       
   369 				format->SupportsFileExtension(aFileExtension))
       
   370 				{
       
   371 				browniePoints = 3;
       
   372 				}
       
   373 			else if (format->SupportsHeaderDataL(aHeaderData))
       
   374 				{
       
   375 				browniePoints = 2;
       
   376 				}
       
   377 			else
       
   378 				{
       
   379 				// See if this format has any 'empty' match data or no match data, indicating 
       
   380 				// that this format will match extension alone even if data present.
       
   381 				// (A format may have more than one match data string.)
       
   382 				const CDesC8Array& supportedHeaderData = format->SupportedHeaderData();
       
   383 
       
   384 				if (supportedHeaderData.Count() == 0)
       
   385 					{
       
   386 					// No header data indicated.
       
   387 					if (format->SupportsFileExtension(aFileExtension))
       
   388 						{
       
   389 							browniePoints = 1;
       
   390 						}
       
   391 					}
       
   392 				else
       
   393 					{
       
   394 					for (register TInt i = 0; i < supportedHeaderData.Count(); i++)
       
   395 						{
       
   396 						if ((supportedHeaderData[i].Length() == 0) && 
       
   397 							format->SupportsFileExtension(aFileExtension))
       
   398 							{
       
   399 							browniePoints = 1;
       
   400 							}
       
   401 						}
       
   402 					}
       
   403 				}
       
   404 			}
       
   405 		else
       
   406 			{
       
   407 			// No file suffix, so must match header data alone.
       
   408 			if (format->SupportsHeaderDataL(aHeaderData))
       
   409 				{
       
   410 				browniePoints = 2;
       
   411 				}
       
   412 			}
       
   413 		}
       
   414 	else // Empty File
       
   415 		{
       
   416 		// We have no choice but to match extension, if there is one.
       
   417 		if ((aFileExtension.Length() > 0) && format->SupportsFileExtension(aFileExtension))
       
   418 			{
       
   419 			browniePoints = 1;
       
   420 			}
       
   421 		}
       
   422 
       
   423 	return browniePoints;
       
   424 }
       
   425 
       
   426 /**
       
   427  * @internalComponent
       
   428  *
       
   429  * This function parses all the play & record formats in the given list of controllers,
       
   430  * looking for controllers & formats that best match the requirements. 
       
   431  * Play controllers will be returned before record controllers, and
       
   432  * in cases of equal priority between formats, ECom order will be maintained.
       
   433  *
       
   434  * @param	"aControllers"	
       
   435  *			A reference to a user supplied list of controllers retrieved from ECom.
       
   436  *			This list may be have been filtered for audio/video/play/record.
       
   437  * @param	"aHeaderDataPlayback"
       
   438  *			A descriptor reference containing the file's header data.
       
   439  *          for matching against a controller's play formats. May be KNullDesC8
       
   440  * @param	"aFileExtensionPlayback"
       
   441  *			A descriptor reference containing the filename's extension.
       
   442  *          for matching against a controller's play formats. May be KNullDesC8
       
   443  * @param	"aHeaderDataRecord"
       
   444  *			A descriptor reference containing the file's header data.
       
   445  *          for matching against a controller's record formats. May be KNullDesC8
       
   446  * @param	"aFileExtensionRecord"
       
   447  *			A descriptor reference containing the filename's extension.
       
   448  *          for matching against a controller's record formats. May be KNullDesC8
       
   449  * @param	"aPrioritisedControllers"
       
   450  *			A reference to a user supplied list through which the list of
       
   451  *			prioritised controllers will be returned.
       
   452  * @since	7.0s
       
   453  */
       
   454 void CMMFClientUtility::PrioritiseControllersL(
       
   455 	const RMMFControllerImplInfoArray& aControllers, 
       
   456 	const TDesC8& aHeaderDataPlayback, 
       
   457 	const TDesC8& aFileExtensionPlayback, 
       
   458 	const TDesC8& aHeaderDataRecord, 
       
   459 	const TDesC8& aFileExtensionRecord, 
       
   460 	RMMFControllerImplInfoArray& prioritisedControllers)
       
   461 	{
       
   462 	RMMFControllerImplInfoArray fullMatchControllers; // data AND suffix
       
   463 	CleanupClosePushL(fullMatchControllers);
       
   464 	RMMFControllerImplInfoArray partMatchControllers; // data OR suffix
       
   465 	CleanupClosePushL(partMatchControllers);
       
   466 
       
   467 	TBool checkingPlaybackFormats = EFalse;
       
   468 	TBool checkingRecordFormats = EFalse;
       
   469 
       
   470 	if (aHeaderDataPlayback != KNullDesC8 || aFileExtensionPlayback != KNullDesC8)
       
   471 		checkingPlaybackFormats = ETrue;
       
   472 	if (aHeaderDataRecord != KNullDesC8 || aFileExtensionRecord != KNullDesC8)
       
   473 		checkingRecordFormats = ETrue;
       
   474 
       
   475 	// Examine each format for each controller. We only want to know at this stage
       
   476 	// if the controller has suitable formats, so as soon as we know it has, we can
       
   477 	// add it to out list, ranked by how well it matched.
       
   478 	for (register TInt i = 0; i < aControllers.Count(); i++)
       
   479 		{
       
   480 		const CMMFControllerImplementationInformation* controller = aControllers[i];
       
   481 		TInt savedBrowniePointsPlayback = 0;
       
   482 		TInt savedBrowniePointsRecord = 0;
       
   483 
       
   484 		if (checkingPlaybackFormats)
       
   485 			{
       
   486 			for (register TInt p = 0; p < controller->PlayFormats().Count(); p++)
       
   487 				{
       
   488 				const CMMFFormatImplementationInformation* format = controller->PlayFormats()[p];
       
   489 
       
   490 				TInt browniePoints = GetBestMatchL(format, aHeaderDataPlayback, aFileExtensionPlayback);
       
   491 
       
   492 				if (browniePoints >= savedBrowniePointsPlayback)
       
   493 					savedBrowniePointsPlayback = browniePoints;
       
   494 				}
       
   495 			}
       
   496 
       
   497 		if (checkingRecordFormats)
       
   498 			{
       
   499 			for (register TInt r = 0; r < controller->RecordFormats().Count(); r++)
       
   500 				{
       
   501 				const CMMFFormatImplementationInformation* format = controller->RecordFormats()[r];
       
   502 
       
   503 				TInt browniePoints = GetBestMatchL(format, aHeaderDataRecord, aFileExtensionRecord);
       
   504 
       
   505 				if (browniePoints >= savedBrowniePointsRecord)
       
   506 					savedBrowniePointsRecord = browniePoints;
       
   507 				}
       
   508 			}
       
   509 
       
   510 		TInt savedBrowniePoints = 0;
       
   511 		// if we're checking both playback & record formats
       
   512 		// make sure we've found both
       
   513 		if (checkingPlaybackFormats && checkingRecordFormats)
       
   514 			{
       
   515 			savedBrowniePoints = Min(savedBrowniePointsPlayback, savedBrowniePointsRecord);
       
   516 			}
       
   517 		else if (checkingPlaybackFormats)
       
   518 			{
       
   519 			savedBrowniePoints = savedBrowniePointsPlayback;
       
   520 			}
       
   521 		else if (checkingRecordFormats)
       
   522 			{
       
   523 			savedBrowniePoints = savedBrowniePointsRecord;
       
   524 			}
       
   525 
       
   526 		// Checked all formats for this controller, now count our brownie points.
       
   527 		switch (savedBrowniePoints)
       
   528 			{
       
   529 			case 3:
       
   530 				User::LeaveIfError(fullMatchControllers.Append(controller));
       
   531 				break;
       
   532 			case 2:
       
   533 				User::LeaveIfError(partMatchControllers.Insert(controller, 0));
       
   534 				break;
       
   535 			case 1:
       
   536 				User::LeaveIfError(partMatchControllers.Append(controller));
       
   537 				break;
       
   538 			default:
       
   539 				break;
       
   540 			}
       
   541 		}
       
   542 
       
   543 	// The better the controller matches, the earlier it will be in the final list.
       
   544 	for (register TInt x = 0; x < fullMatchControllers.Count(); x++)
       
   545 		{
       
   546 		if (prioritisedControllers.Find(fullMatchControllers[x]) == KErrNotFound)
       
   547 			{
       
   548 			User::LeaveIfError(prioritisedControllers.Append(fullMatchControllers[x]));
       
   549 			}
       
   550 		}
       
   551 
       
   552 	for (register TInt y = 0; y < partMatchControllers.Count(); y++)
       
   553 		{
       
   554 		if (prioritisedControllers.Find(partMatchControllers[y]) == KErrNotFound)
       
   555 			{
       
   556 			User::LeaveIfError(prioritisedControllers.Append(partMatchControllers[y]));
       
   557 			}
       
   558 		}
       
   559 
       
   560 	CleanupStack::PopAndDestroy(2, &fullMatchControllers); // fullMatchControllers, partMatchControllers
       
   561 	}
       
   562 
       
   563 /**
       
   564  * @internalComponent
       
   565  */
       
   566 EXPORT_C CMMFMdaObjectStateChangeObserverCallback* CMMFMdaObjectStateChangeObserverCallback::NewL(MMdaObjectStateChangeObserver& aCallback)
       
   567 	{
       
   568 	return new(ELeave) CMMFMdaObjectStateChangeObserverCallback(aCallback);
       
   569 	}
       
   570 
       
   571 /**
       
   572  * @internalComponent
       
   573  */
       
   574 CMMFMdaObjectStateChangeObserverCallback::~CMMFMdaObjectStateChangeObserverCallback()
       
   575 	{
       
   576 	Cancel();
       
   577 	}
       
   578 
       
   579 /**
       
   580  * @internalComponent
       
   581  */
       
   582 EXPORT_C void CMMFMdaObjectStateChangeObserverCallback::CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
       
   583 	{
       
   584 	iObject = aObject;
       
   585 	iPreviousState = aPreviousState;
       
   586 	iCurrentState = aCurrentState;
       
   587 	iErrorCode = aErrorCode;
       
   588 	if (!IsActive())
       
   589 		{
       
   590 		TRequestStatus* s = &iStatus;
       
   591 		SetActive();
       
   592 		User::RequestComplete(s, KErrNone);
       
   593 		}
       
   594 	}
       
   595 
       
   596 CMMFMdaObjectStateChangeObserverCallback::CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback) :
       
   597 	CActive(CActive::EPriorityHigh),
       
   598 	iCallback(aCallback)
       
   599 	{
       
   600 	CActiveScheduler::Add(this);
       
   601 	}
       
   602 
       
   603 void CMMFMdaObjectStateChangeObserverCallback::RunL()
       
   604 	{
       
   605 	iCallback.MoscoStateChangeEvent(iObject, iPreviousState, iCurrentState, iErrorCode);
       
   606 	}
       
   607 
       
   608 void CMMFMdaObjectStateChangeObserverCallback::DoCancel()
       
   609 	{
       
   610 	//nothing to cancel
       
   611 	}
       
   612 
       
   613 
       
   614 //****************************************
       
   615 // CMMFFindAndOpenController
       
   616 //****************************************
       
   617 
       
   618 /**
       
   619  * Factory function to create a CMMFFindAndOpenController class
       
   620  *
       
   621  * @internalComponent
       
   622  */
       
   623 EXPORT_C CMMFFindAndOpenController* CMMFFindAndOpenController::NewL(MMMFFindAndOpenControllerObserver& aObserver)
       
   624 	{
       
   625 	CMMFFindAndOpenController* self = new(ELeave) CMMFFindAndOpenController(aObserver);
       
   626 	CleanupStack::PushL(self);
       
   627 	self->ConstructL();
       
   628 	CleanupStack::Pop(self);
       
   629 	return self;
       
   630 	}
       
   631 
       
   632 CMMFFindAndOpenController::~CMMFFindAndOpenController()
       
   633 	{
       
   634 	Cancel();
       
   635 
       
   636 	// delete temporary variables
       
   637 	Close();
       
   638 
       
   639 	// this should cancel the AO
       
   640 	delete iAddDataSourceSinkAsync;
       
   641 
       
   642 	delete iPrimaryConfig;
       
   643 	delete iSecondaryConfig;
       
   644 	}
       
   645 
       
   646 /**
       
   647  * Function to free up memory after a successful open has completed
       
   648  * Useful to allow a alloc testing to work.
       
   649  * Must not be called if ReOpen() is to be called
       
   650  *
       
   651  * @internalComponent
       
   652  */
       
   653 EXPORT_C void CMMFFindAndOpenController::Close()
       
   654 	{
       
   655 
       
   656 	Cancel();
       
   657 	
       
   658 	if(iAddDataSourceSinkAsync)
       
   659 		{
       
   660 		iAddDataSourceSinkAsync->Cancel();
       
   661 		}
       
   662 		
       
   663 	if (iPrimaryConfig)
       
   664 		iPrimaryConfig->Close();
       
   665 	if (iSecondaryConfig)
       
   666 		iSecondaryConfig->Close();
       
   667 
       
   668 	iPrioritisedControllers.Close();
       
   669 	iControllers.ResetAndDestroy();
       
   670 	iControllers.Close();
       
   671 	
       
   672 	iFileName.SetLength(0);
       
   673 	iFileNameSecondary.SetLength(0);
       
   674 
       
   675 	delete iUrl;
       
   676 	iUrl = NULL;
       
   677 	
       
   678 	delete iMimeType;
       
   679 	iMimeType = NULL;
       
   680 	
       
   681 	delete iUniqueId;
       
   682 	iUniqueId = NULL;
       
   683 
       
   684 	if (iOwnFileHandle)
       
   685 		{
       
   686 		iFileHandle.Close();
       
   687 		iOwnFileHandle = EFalse;	
       
   688 		}
       
   689 	}
       
   690 /**
       
   691  * Function to free up memory of which is not required in ReOpen()
       
   692  * after a successful open has completed
       
   693  * Useful to allow a alloc testing to work.
       
   694  *
       
   695  * @internalComponent
       
   696  */
       
   697 
       
   698 EXPORT_C void CMMFFindAndOpenController::CloseConfig()
       
   699 	{
       
   700 	Cancel();
       
   701 	if(iAddDataSourceSinkAsync)
       
   702 		{
       
   703 		iAddDataSourceSinkAsync->Cancel();
       
   704 		}
       
   705 	
       
   706 	if (iSecondaryConfig)
       
   707 		{
       
   708 		iSecondaryConfig->Close();
       
   709 		}
       
   710 	
       
   711 	iPrioritisedControllers.Close();
       
   712 	iControllers.ResetAndDestroy();
       
   713 	iControllers.Close();
       
   714 	
       
   715 	iFileName.SetLength(0);
       
   716 	iFileNameSecondary.SetLength(0);
       
   717 
       
   718 	delete iUrl;
       
   719 	iUrl = NULL;
       
   720 	
       
   721 	delete iMimeType;
       
   722 	iMimeType = NULL;
       
   723 	
       
   724 	delete iUniqueId;
       
   725 	iUniqueId = NULL;
       
   726 
       
   727 	if (iOwnFileHandle)
       
   728 		{
       
   729 		iFileHandle.Close();
       
   730 		iOwnFileHandle = EFalse;		
       
   731 		}
       
   732 	}
       
   733 
       
   734 CMMFFindAndOpenController::CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver) :
       
   735 	CActive(EPriorityStandard), 
       
   736 	iObserver(aObserver),
       
   737 	iDescriptor(NULL, 0)
       
   738 	{
       
   739 	CActiveScheduler::Add(this);
       
   740 	}
       
   741 
       
   742 void CMMFFindAndOpenController::ConstructL()
       
   743 	{
       
   744 	iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
       
   745 	iPrimaryConfig = new (ELeave)  CConfig();
       
   746 	iSecondaryConfig =  new (ELeave) CConfig;
       
   747 	iCurrentConfig =  iPrimaryConfig;
       
   748 	
       
   749 	RProcess thisProcess;
       
   750 	iHasDrmCapability = thisProcess.HasCapability(ECapabilityDRM, KSuppressPlatSecDiagnostic);
       
   751 	thisProcess.Close();
       
   752 	}
       
   753 
       
   754 void CMMFFindAndOpenController::RunL()
       
   755 	{
       
   756 	Process();
       
   757 	}
       
   758 
       
   759 void CMMFFindAndOpenController::DoCancel()
       
   760 	{
       
   761 	iAddDataSourceSinkAsync->Cancel();
       
   762 	}
       
   763 
       
   764 /**
       
   765  * Defines the media ID & priority to be used when opening a controller
       
   766  * Normally called once only after class has been constructed
       
   767  *
       
   768  * @param	aMediaId
       
   769  *			the media ID to use when searching for a controller
       
   770  *			e.g. KUidMediaTypeAudio 
       
   771  * @param	aPrioritySettings
       
   772  *			the priority settings to use when opening a controller
       
   773  * @param	aMediaIdMatchType
       
   774  *			Defines the type of media id match to be performed on the plugins 
       
   775  *			returned from the ECOM registry.
       
   776  * @leave	can leave with KErrNoMemory
       
   777 
       
   778  * @internalComponent
       
   779  */
       
   780 EXPORT_C void CMMFFindAndOpenController::Configure(
       
   781 	TUid aMediaId, 
       
   782 	TMMFPrioritySettings aPrioritySettings,
       
   783 	CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType)
       
   784 	{
       
   785 	iPrioritySettings = aPrioritySettings;
       
   786 
       
   787 	iMediaIdMatchType = aMediaIdMatchType;
       
   788 
       
   789 	iMediaId = aMediaId;
       
   790 	}
       
   791 
       
   792 void CMMFFindAndOpenController::ConfigureController(
       
   793 	CConfig& config,
       
   794 	RMMFController& aController, 
       
   795 	CMMFControllerEventMonitor& aEventMonitor,
       
   796 	TControllerMode aControllerMode)
       
   797 	{
       
   798 	config.iController = &aController;
       
   799 	config.iEventMonitor = &aEventMonitor;
       
   800 	config.iControllerMode = aControllerMode;
       
   801 	}
       
   802 
       
   803 /**
       
   804  * Configures the primary controller
       
   805  *
       
   806  * @param	aController
       
   807  *			a reference to the client controller object to use
       
   808  * @param	aEventMonitor
       
   809  *			a reference to an event monitor object for receiving 
       
   810  *			events from the controller
       
   811  * @param	aControllerMode
       
   812  *			indicates whether this controller is to be used for recording
       
   813  *          or playback
       
   814  *
       
   815  * @internalComponent
       
   816  */
       
   817 EXPORT_C void CMMFFindAndOpenController::ConfigureController(
       
   818 	RMMFController& aController, 
       
   819 	CMMFControllerEventMonitor& aEventMonitor,
       
   820 	TControllerMode aControllerMode)
       
   821 	{
       
   822 	ConfigureController(
       
   823 		*iPrimaryConfig,
       
   824 		aController, 
       
   825 		aEventMonitor,
       
   826 		aControllerMode);
       
   827 	}
       
   828 
       
   829 /**
       
   830  * Configures the secondary controller
       
   831  *
       
   832  * This is only needed for the audio recorder utility which opens
       
   833  * one controller for playback and another for recording
       
   834  *
       
   835  * @param	aController
       
   836  *			a reference to the client controller object to use
       
   837  * @param	aEventMonitor
       
   838  *			a reference to an event monitor object for receiving 
       
   839  *			events from the controller
       
   840  * @param	aControllerMode
       
   841  *			indicates whether this controller is to be used for recording
       
   842  *          or playback or converting
       
   843  *
       
   844  * @internalComponent
       
   845  */
       
   846 EXPORT_C void CMMFFindAndOpenController::ConfigureSecondaryController(
       
   847 	RMMFController& aController, 
       
   848 	CMMFControllerEventMonitor& aEventMonitor,
       
   849 	TControllerMode aControllerMode)
       
   850 	{
       
   851 	ConfigureController(
       
   852 		*iSecondaryConfig,
       
   853 		aController, 
       
   854 		aEventMonitor,
       
   855 		aControllerMode);
       
   856 	}
       
   857 
       
   858 /**
       
   859  * Makes any controllers that are opened subsequently share a single heap.
       
   860  * 
       
   861  * The default behaviour is that each controller is created with its own heap.
       
   862  * Each heap uses a chunk, so using this function avoids situations where the number
       
   863  * of chunks per process is limited.
       
   864  * The default behaviour is generally to be preferred, and should give lower overall
       
   865  * memory usage. However, if many controllers are to be created for a particular thread,
       
   866  * then this function should be used to prevent running out of heaps or chunks.
       
   867  *
       
   868  * @internalComponent
       
   869  */
       
   870 EXPORT_C void CMMFFindAndOpenController::UseSharedHeap()
       
   871 	{
       
   872 	iUseSharedHeap = ETrue;
       
   873 	}
       
   874 
       
   875 void CMMFFindAndOpenController::Init()
       
   876 	{
       
   877 	// This should be called prior to opening, so reset the error
       
   878 	iError = KErrNone;
       
   879 	iSourceSinkConfigured = EFalse;
       
   880 	iControllerCount = 0;
       
   881 	}
       
   882 
       
   883 void CMMFFindAndOpenController::ConfigureSourceSink(
       
   884 	CConfig& config,
       
   885 	TSourceSink aSource, 
       
   886 	TSourceSink aSink)
       
   887 	{
       
   888 	TInt err;
       
   889 	TRAP(err, config.iSource = CreateSourceSinkL(aSource));
       
   890 	if (err != KErrNone)
       
   891 		{
       
   892 		iError = err;
       
   893 		return;
       
   894 		}
       
   895 		
       
   896 	TRAP(err, config.iSink = CreateSourceSinkL(aSink));
       
   897 	if (err != KErrNone)
       
   898 		{
       
   899 		iError = err;
       
   900 		return;
       
   901 		}
       
   902 	}
       
   903 	
       
   904 
       
   905 void CMMFFindAndOpenController::ConfigureSourceSink(
       
   906 	CConfig& config,
       
   907 	const TMMSource& aSource, 
       
   908 	TSourceSink aSink)
       
   909 	{
       
   910 	TInt err;
       
   911 	TRAP(err, config.iSource = CreateSourceSinkL(aSource));
       
   912 	if (err != KErrNone)
       
   913 		{
       
   914 		iError = err;
       
   915 		return;
       
   916 		}
       
   917 		
       
   918 	TRAP(err, config.iSink = CreateSourceSinkL(aSink));
       
   919 	if (err != KErrNone)
       
   920 		{
       
   921 		iError = err;
       
   922 		return;
       
   923 		}
       
   924 	}
       
   925 
       
   926 
       
   927 	
       
   928 /**
       
   929  * Configure the primary controller's source and sink
       
   930  * The descriptors passed to this function are copied so they do not need to be persistent.
       
   931  * To simplify the API, any errors that occur are reported back asynchronously following
       
   932  * a subsequent call to OpenByXXX()
       
   933  *
       
   934  * @param	aSourceUid
       
   935  *			the UID of the data source
       
   936  * @param	aSourceData
       
   937  *			a reference to a descriptor used to configure the source
       
   938  * @param	aSinkUid
       
   939  *			the UID of the data sink
       
   940  * @param	aSinkData
       
   941  *			a reference to a descriptor used to configure the sink
       
   942  *
       
   943  * @internalComponent
       
   944  */
       
   945 EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
       
   946 	TSourceSink aSource,
       
   947 	TSourceSink aSink)
       
   948 	{
       
   949 
       
   950 	CConfig* config = NULL;
       
   951 	
       
   952 	Init();
       
   953 	config = iPrimaryConfig;
       
   954 
       
   955 
       
   956 	// must have already called ConfigureController()
       
   957 	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
       
   958 
       
   959 	ConfigureSourceSink(
       
   960 		*config,
       
   961 		aSource, 
       
   962 		aSink);
       
   963 	iCurrentConfig = config;
       
   964 
       
   965 	iSourceSinkConfigured = ETrue;
       
   966 	}
       
   967 	
       
   968 	
       
   969 /**
       
   970  * Configure the primary controller's source and sink
       
   971  * The descriptors passed to this function are copied so they do not need to be persistent.
       
   972  * To simplify the API, any errors that occur are reported back asynchronously following
       
   973  * a subsequent call to OpenByXXX()
       
   974  *
       
   975  * @param	aSourceUid
       
   976  *			the UID of the data source
       
   977  * @param	aSourceData
       
   978  *			a reference to a descriptor used to configure the source
       
   979  * @param	aSinkUid
       
   980  *			the UID of the data sink
       
   981  * @param	aSinkData
       
   982  *			a reference to a descriptor used to configure the sink
       
   983  *
       
   984  * @internalComponent
       
   985  */
       
   986 EXPORT_C void CMMFFindAndOpenController::ConfigureSecondarySourceSink(
       
   987 	TSourceSink aSource,
       
   988 	TSourceSink aSink)
       
   989 	{
       
   990 	if (iError != KErrNone)
       
   991 		{
       
   992 		// if there was an error configuring the primary source/sink, do not try the secondary one
       
   993 		// Don't return the error, since the stored error will be returned by the OpenBy... method
       
   994 		return;
       
   995 		}
       
   996 
       
   997 	CConfig* config = NULL;
       
   998 	
       
   999 	config = iSecondaryConfig;
       
  1000 
       
  1001 	// must have already configured the primary controller
       
  1002 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1003 	config = iSecondaryConfig;
       
  1004 			
       
  1005 	// must have already called ConfigureController()
       
  1006 	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
       
  1007 
       
  1008 	ConfigureSourceSink(
       
  1009 		*config,
       
  1010 		aSource, 
       
  1011 		aSink);
       
  1012 	iCurrentConfig = config;
       
  1013 
       
  1014 	iSourceSinkConfigured = ETrue;
       
  1015 	}
       
  1016 	
       
  1017 
       
  1018 	
       
  1019 EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
       
  1020 	const TMMSource& aSource,
       
  1021 	TSourceSink aSink)
       
  1022 	{
       
  1023 	Init();
       
  1024 	CConfig* config = iPrimaryConfig;
       
  1025 			
       
  1026 	// must have already called ConfigureController()
       
  1027 	__ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
       
  1028 
       
  1029 	ConfigureSourceSink(
       
  1030 		*config,
       
  1031 		aSource, 
       
  1032 		aSink);
       
  1033 	iCurrentConfig = config;
       
  1034 
       
  1035 	iSourceSinkConfigured = ETrue;
       
  1036 	}
       
  1037 
       
  1038 	
       
  1039 	
       
  1040 /**
       
  1041  * Opens a controller using the supplied controller UID
       
  1042  * and adds the source & sink
       
  1043  * Completion is indicated asynchonously by a call to MfaocComplete()
       
  1044  * 
       
  1045  * @param	aControllerUid
       
  1046  *			the UID of the primary controller
       
  1047  * @param	aControllerUid
       
  1048  *			the UID of the secondary controller
       
  1049  *
       
  1050  * @internalComponent
       
  1051  */
       
  1052 EXPORT_C void CMMFFindAndOpenController::OpenByControllerUid(
       
  1053 		TUid aControllerUid,
       
  1054 		TUid aSecondaryControllerUid)
       
  1055 	{
       
  1056 	// must have already called ConfigureSourceSink()
       
  1057 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1058 
       
  1059 	// Have there been any errors so far ?
       
  1060 	if (iError != KErrNone)
       
  1061 		{
       
  1062 	    SchedSendError();
       
  1063 		return;
       
  1064 		}
       
  1065 
       
  1066 	if (iCurrentConfig == iPrimaryConfig)
       
  1067 		{
       
  1068 		// only do this for the playback controller
       
  1069 		TRAP(iError, iCurrentConfig->iSource->EvaluateIntentL())
       
  1070 		
       
  1071 		if (iError != KErrNone && 
       
  1072 			!(iCurrentConfig->iControllerMode == EPlayback && iError == KErrPermissionDenied && !iHasDrmCapability))
       
  1073 			{
       
  1074 			// KErrPermissionDenied error and no DRM capability are not problems in Playback mode
       
  1075 			// proper action will be performed when controller is loaded
       
  1076 	    	SchedSendError();
       
  1077 			return;
       
  1078 			}
       
  1079 		}
       
  1080 
       
  1081 	iPrimaryConfig->iControllerUid = aControllerUid;
       
  1082 	if (iCurrentConfig == iSecondaryConfig)
       
  1083 		{
       
  1084 		if (aSecondaryControllerUid == KNullUid)
       
  1085 			iSecondaryConfig->iControllerUid = aControllerUid;
       
  1086 		else
       
  1087 			iSecondaryConfig->iControllerUid = aSecondaryControllerUid;
       
  1088 		}
       
  1089 		
       
  1090 	iMode = EOpenByControllerUid;
       
  1091 	iControllerImplInfo = NULL;
       
  1092 	iState = EOpenController;
       
  1093 	KickState();
       
  1094 	}
       
  1095 
       
  1096 /**
       
  1097  * Opens a controller using the supplied file name
       
  1098  * and adds the source & sink
       
  1099  * A copy is made of the filename or file handle so that it need not be persistent
       
  1100  * Completion is indicated asynchonously by a call to MfaocComplete()
       
  1101  * 
       
  1102  * @param	aSource
       
  1103  *			a reference to a TFileSource object to be used when searching
       
  1104  *          for a controller
       
  1105  * @param	aFileNameSecondary
       
  1106  *			a reference to the seconday filename to be used when searching
       
  1107  *          for a controller. This need only be supplied when converting 
       
  1108  *			between two files.
       
  1109  *
       
  1110  * @internalComponent
       
  1111  */
       
  1112 EXPORT_C void CMMFFindAndOpenController::OpenByFileSource(const TMMSource& aSource, const TDesC& aFileNameSecondary)
       
  1113 	{
       
  1114 	// must have already called ConfigureSourceSink()
       
  1115 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1116 
       
  1117 	TInt err;
       
  1118 	// Have there been any errors so far ?
       
  1119 	if (iError != KErrNone)
       
  1120 		{
       
  1121 		SchedSendError();
       
  1122 		return;
       
  1123 		}
       
  1124 		
       
  1125 	if (iOwnFileHandle)
       
  1126 		{
       
  1127 		// in case of error
       
  1128 		iFileHandle.Close();
       
  1129 		iOwnFileHandle = EFalse;
       
  1130 		}
       
  1131 		
       
  1132 	iEnableUi = aSource.IsUIEnabled();
       
  1133 	if (aSource.SourceType()==KUidMMFileSource)
       
  1134 		{
       
  1135 		const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
       
  1136 		iFileName = fileSource.Name();
       
  1137 		iUseFileHandle = EFalse;
       
  1138 		}
       
  1139 
       
  1140 	if (aSource.SourceType()==KUidMMFileHandleSource)
       
  1141 		{
       
  1142 		const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
       
  1143 		ASSERT(iFileHandle.SubSessionHandle()==0); // closed just above
       
  1144 		err = iFileHandle.Duplicate(fileHandleSource.Handle());
       
  1145 		if (err != KErrNone)
       
  1146 			{
       
  1147 			SchedSendError(err);
       
  1148 			return;
       
  1149 			}
       
  1150 		iFileHandle.Name(iFileName); //ignore error return since we'll just do without the filename if not available
       
  1151 		iUseFileHandle = ETrue;
       
  1152 		iOwnFileHandle = ETrue; // because we dup'd it
       
  1153 		}
       
  1154 		
       
  1155 	TRAP(err, iUniqueId = aSource.UniqueId().AllocL());
       
  1156 	iIntent = aSource.Intent();
       
  1157 	if (err != KErrNone)
       
  1158 		{
       
  1159 		SchedSendError(err);
       
  1160 		return;
       
  1161 		}
       
  1162 
       
  1163 		
       
  1164 	// take a copy of the secondary file name
       
  1165 	iFileNameSecondary = aFileNameSecondary;
       
  1166 
       
  1167 	iMode = EOpenByFileName;
       
  1168 	iState = EBuildControllerList;
       
  1169 	KickState();
       
  1170 	}
       
  1171 	
       
  1172 /**
       
  1173  * Opens a controller using the supplied format UID
       
  1174  * and adds the source & sink
       
  1175  * Completion is indicated asynchonously by a call to MfaocComplete()
       
  1176  * 
       
  1177  * @param	aFormatUid
       
  1178  *			the UID of a format that must be supported by the controller
       
  1179  * @param	aFormatUidSecondary
       
  1180  *			the UID of a secondary format that must be supported by the controller
       
  1181  *			This need only be supplied when converting between two differnet formats.
       
  1182  *
       
  1183  * @internalComponent
       
  1184  */
       
  1185 EXPORT_C void CMMFFindAndOpenController::OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary)
       
  1186 	{
       
  1187 	// must have already called ConfigureSourceSink()
       
  1188 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1189 
       
  1190 	// Have there been any errors so far ?
       
  1191 	if (iError != KErrNone)
       
  1192 		{
       
  1193 		SchedSendError();
       
  1194 		return;
       
  1195 		}
       
  1196 
       
  1197 	iFormatUid = aFormatUid;
       
  1198 	iFormatUidSecondary = aFormatUidSecondary;
       
  1199 
       
  1200 	iMode = EOpenByFormatUid;
       
  1201 	iState = EBuildControllerList;
       
  1202 	KickState();
       
  1203 	}
       
  1204 
       
  1205 /**
       
  1206  * Opens a controller using the supplied descriptor 
       
  1207  * and adds the source & sink
       
  1208  * Completion is indicated asynchonously by a call to MfaocComplete()
       
  1209  * 
       
  1210  * @param	aDescriptor
       
  1211  *			a reference to the descriptor to be used when searching
       
  1212  *          for a controller
       
  1213  *
       
  1214  * @internalComponent
       
  1215  */
       
  1216 EXPORT_C void  CMMFFindAndOpenController::OpenByDescriptor(const TDesC8& aDescriptor)
       
  1217 	{
       
  1218 	// must have already called ConfigureSourceSink()
       
  1219 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1220 
       
  1221 	// Have there been any errors so far ?
       
  1222 	if (iError != KErrNone)
       
  1223 		{
       
  1224 		SchedSendError();
       
  1225 		return;
       
  1226 		}
       
  1227 
       
  1228 	// take a copy of the descriptor
       
  1229 	TUint8* desBufferPtr = const_cast<TUint8*> (aDescriptor.Ptr());
       
  1230 	iDescriptor.Set( desBufferPtr,aDescriptor.Length(),aDescriptor.Length());
       
  1231 	
       
  1232 	iMode = EOpenByDescriptor;
       
  1233 	iState = EBuildControllerList;
       
  1234 	KickState();
       
  1235 	}
       
  1236 
       
  1237 /**
       
  1238  * Opens a controller using the supplied URL
       
  1239  * and adds the source & sink
       
  1240  * Completion is indicated asynchonously by a call to MfaocComplete()
       
  1241  * 
       
  1242  * @param	aUrl
       
  1243  *			a reference to the URL to be used when searching for a controller
       
  1244  * @param	aIapId
       
  1245  *          the IAP ID to be used when searching for a controller
       
  1246  * @param	aMimeType
       
  1247  *          the MIME type of the data to be used when searching for a controller
       
  1248  *
       
  1249  * @internalComponent
       
  1250  */
       
  1251 EXPORT_C void CMMFFindAndOpenController::OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType)
       
  1252 	{
       
  1253 	// must have already called ConfigureSourceSink()
       
  1254 	__ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
       
  1255 
       
  1256 	// Have there been any errors so far ?
       
  1257 	if (iError != KErrNone)
       
  1258 		{
       
  1259 		SchedSendError();
       
  1260 		return;
       
  1261 		}
       
  1262 
       
  1263 	// take a copy of the Url
       
  1264 	delete iUrl;
       
  1265 	iUrl = NULL;
       
  1266 	iUrl = aUrl.Alloc();
       
  1267 	if (iUrl == NULL)
       
  1268 		{
       
  1269 		SchedSendError(KErrNoMemory);
       
  1270 		return;
       
  1271 		}
       
  1272 
       
  1273 	// take a copy of the IapId
       
  1274 	iIapId = aIapId;
       
  1275 	
       
  1276 	// take a copy of the mime type
       
  1277 	delete iMimeType;
       
  1278 	iMimeType = NULL;
       
  1279 	iMimeType = aMimeType.Alloc();
       
  1280 	if (iMimeType == NULL)
       
  1281 		{
       
  1282 		SchedSendError(KErrNoMemory);
       
  1283 		return;
       
  1284 		}
       
  1285 
       
  1286 	iMode = EOpenByUrl;
       
  1287 	iState = EBuildControllerList;
       
  1288 	KickState();
       
  1289 	}
       
  1290 
       
  1291 /**
       
  1292  * Static function to return a TMMFFileConfig object
       
  1293  * suitable for passing to ConfigureSourceSink()
       
  1294  * 
       
  1295  * @param	aFileName
       
  1296  *          the filename to use
       
  1297  *
       
  1298  * @internalComponent
       
  1299  */
       
  1300 EXPORT_C TMMFFileConfig CMMFFindAndOpenController::GetConfigFile(const TDesC& aFileName)
       
  1301 	{
       
  1302 	TMMFFileConfig sourceSinkData;
       
  1303 	sourceSinkData().iPath = aFileName;
       
  1304 	return sourceSinkData;
       
  1305 	}
       
  1306 
       
  1307 /**
       
  1308  * Static function to return a TMMFDescriptorConfig object
       
  1309  * suitable for passing to ConfigureSourceSink()
       
  1310  * 
       
  1311  * @param	aFileName
       
  1312  *          the filename to use
       
  1313  *
       
  1314  * @internalComponent
       
  1315  */
       
  1316 EXPORT_C TMMFDescriptorConfig CMMFFindAndOpenController::GetConfigDescriptor(const TDesC8& aDescriptor)
       
  1317 	{
       
  1318 	TMMFDescriptorConfig sourceSinkData;
       
  1319 	sourceSinkData().iDes = (TAny*)&aDescriptor;
       
  1320 	sourceSinkData().iDesThreadId = RThread().Id();
       
  1321 	return sourceSinkData;
       
  1322 	}
       
  1323 
       
  1324 /**
       
  1325  * Static function to create a CBufFlat object
       
  1326  * suitable for passing to ConfigureSourceSink()
       
  1327  * 
       
  1328  * @param	aUrlCfgBuffer
       
  1329  *          the reference to a caller-supplied pointer used to create
       
  1330  *			a CBufFlat object. The caller is responsible for deletion.
       
  1331  * @param	aUrl
       
  1332  *			a reference to the URL to be used
       
  1333  * @param	aIapId
       
  1334  *          the IAP ID to be used
       
  1335  * @return	can return KErrNone or KErrNoMemory
       
  1336  *
       
  1337  * @internalComponent
       
  1338  */
       
  1339 
       
  1340 EXPORT_C void CMMFFindAndOpenController::GetConfigUrlL(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId)
       
  1341 	{
       
  1342 	delete aUrlCfgBuffer;
       
  1343 	aUrlCfgBuffer = NULL;
       
  1344 	
       
  1345 	CMMFUrlParams* urlCfg = CMMFUrlParams::NewL(aUrl,aIapId);
       
  1346 	CleanupStack::PushL(urlCfg);
       
  1347 	aUrlCfgBuffer = urlCfg->ExternalizeToCBufFlatLC();
       
  1348 	CleanupStack::Pop(aUrlCfgBuffer);
       
  1349 	CleanupStack::PopAndDestroy(urlCfg);
       
  1350 	}
       
  1351 /**
       
  1352  * ReOpens the previously opened primary controller
       
  1353  *
       
  1354  * @internalComponent
       
  1355  */
       
  1356 EXPORT_C void CMMFFindAndOpenController::ReOpen()
       
  1357 	{
       
  1358 	// should already have a valid controller uid so just open it
       
  1359 	iControllerImplInfo = NULL;
       
  1360 	iState = EOpenController;
       
  1361 	KickState();
       
  1362 	}
       
  1363 
       
  1364 void CMMFFindAndOpenController::OpenPrimaryController(void)
       
  1365 	{
       
  1366 	iCurrentConfig = iPrimaryConfig;
       
  1367 	switch(iMode)
       
  1368 		{
       
  1369 		case EOpenByFileName:
       
  1370 		case EOpenByFormatUid:
       
  1371 		case EOpenByDescriptor:
       
  1372 		case EOpenByUrl:
       
  1373 			iState = EBuildControllerList;
       
  1374 			break;
       
  1375 		case EOpenByControllerUid:
       
  1376 			iControllerImplInfo = NULL;
       
  1377 			iState = EOpenController;
       
  1378 			break;
       
  1379 		}
       
  1380 	KickState();
       
  1381 	}
       
  1382 
       
  1383 void CMMFFindAndOpenController::KickState()
       
  1384 	{
       
  1385 	TRequestStatus* status = &iStatus;
       
  1386 	User::RequestComplete(status, KErrNone);
       
  1387 	SetActive();
       
  1388 	}
       
  1389 
       
  1390 void CMMFFindAndOpenController::CloseController()
       
  1391 	{
       
  1392 	if (iCurrentConfig->iEventMonitor)
       
  1393 		iCurrentConfig->iEventMonitor->Cancel();
       
  1394 	iCurrentConfig->iController->Close(); 
       
  1395 	}
       
  1396 
       
  1397 void CMMFFindAndOpenController::Process()
       
  1398 	{
       
  1399 	switch(iState)
       
  1400 		{
       
  1401 		case EBuildControllerList:
       
  1402 			switch(iMode)
       
  1403 				{
       
  1404 				case EOpenByFileName:
       
  1405 					TRAP(iError, BuildControllerListFileNameL());
       
  1406 					break;
       
  1407 				case EOpenByDescriptor:
       
  1408 					TRAP(iError, BuildControllerListDescriptorL());
       
  1409 					break;
       
  1410 				case EOpenByUrl:
       
  1411 					TRAP(iError, BuildControllerListUrlL());
       
  1412 					break;
       
  1413 				case EOpenByFormatUid:
       
  1414 					TRAP(iError, BuildControllerListFormatL());
       
  1415 					break;
       
  1416 				default:
       
  1417 					CUPanic(EMMFMediaClientUtilityBadState);
       
  1418 				}
       
  1419 			
       
  1420 			if (iError != KErrNone)
       
  1421 				{
       
  1422 				iState = EIdle;
       
  1423 				SendError();
       
  1424 				break;
       
  1425 				}
       
  1426 
       
  1427 			// try the first controller
       
  1428 			iControllerIndex = -1;
       
  1429 			TryNextController();
       
  1430 			break;
       
  1431 
       
  1432 		case EOpenController:
       
  1433 			{
       
  1434 			// Make sure any existing controller is closed.
       
  1435 			CloseController();
       
  1436 			
       
  1437 			TBool isSecureDrmProcess = EFalse;// need to keep it false as UseSecureDRMProcess may return error
       
  1438 			// Loading controller in new threading model is enabled only in playback mode
       
  1439 			TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
       
  1440 			TBool localPlaybackMode = iCurrentConfig->iControllerMode == EPlayback && 
       
  1441 										(sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource);
       
  1442             if(localPlaybackMode)
       
  1443                 {
       
  1444                 TRAPD(err,UseSecureDRMProcessL(isSecureDrmProcess));
       
  1445                 if(err == KErrPermissionDenied)
       
  1446                 	{
       
  1447                 	isSecureDrmProcess = ETrue;
       
  1448                 	}
       
  1449                 else if(err != KErrNone)
       
  1450                     {
       
  1451                     iError = err;
       
  1452                     SendError(err);
       
  1453                     return;
       
  1454                     }
       
  1455                 }
       
  1456 			// Open the controller 
       
  1457 			if (iControllerImplInfo)
       
  1458 				{
       
  1459 				if(isSecureDrmProcess && localPlaybackMode)
       
  1460 					{
       
  1461 					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
       
  1462 					iUsingSecureDrmProcess = ETrue;
       
  1463 					}
       
  1464 				else
       
  1465 					{
       
  1466 					iError = iCurrentConfig->iController->Open(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
       
  1467 					iUsingSecureDrmProcess = EFalse;;
       
  1468 					}
       
  1469 				}
       
  1470 			else
       
  1471 				{
       
  1472 				if(isSecureDrmProcess && localPlaybackMode)
       
  1473 					{
       
  1474 					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
       
  1475 					iUsingSecureDrmProcess = ETrue;
       
  1476 	
       
  1477 					}
       
  1478 				else
       
  1479 					{
       
  1480 					iError = iCurrentConfig->iController->Open(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
       
  1481 					iUsingSecureDrmProcess = EFalse;
       
  1482 					}
       
  1483 				}
       
  1484 			//in case of error, including KErrNomemory try next controller
       
  1485 			if (iError)
       
  1486 				{
       
  1487 				TryNextController();
       
  1488 				}
       
  1489 			else
       
  1490 				{	
       
  1491 			#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
  1492 			#ifndef SYMBIAN_BUILD_GCE
       
  1493 				if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
       
  1494 					{
       
  1495 					iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
       
  1496 					if(iError)
       
  1497 						{
       
  1498 						if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
       
  1499 							{
       
  1500 							iError = KErrNone;
       
  1501 							}
       
  1502 						else
       
  1503 							{
       
  1504 							iState = EIdle;
       
  1505 							SendError();
       
  1506 							break;
       
  1507 							}	
       
  1508 						}
       
  1509 					}
       
  1510 			#endif // SYMBIAN_BUILD_GCE
       
  1511 			#endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
  1512 				iCurrentConfig->iEventMonitor->Start();
       
  1513 
       
  1514 				if (iCurrentConfig == iSecondaryConfig)
       
  1515 					{
       
  1516 					iState = EAddSource;
       
  1517 					KickState();
       
  1518 					}
       
  1519 				else
       
  1520 					{
       
  1521 					iState = EAddSink;
       
  1522 					KickState();
       
  1523 					}
       
  1524 				}
       
  1525 			}
       
  1526 			break;
       
  1527 
       
  1528 		case EAddSource:
       
  1529 			{
       
  1530 			iState = EWaitingForSource;
       
  1531 			const CMMSourceSink* source = iCurrentConfig->iSource;
       
  1532 			// CMMSourceSink has the ability to transform the data it stored into a data stream
       
  1533 			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
       
  1534 			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
       
  1535 			// source/sink. The info about the file can be a file path or a file handle.
       
  1536 			// When it holds a file handle and turns info into data stream, the file handle is
       
  1537 			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
       
  1538 			// the streamed info is always extracted within the same process. If the pointer is 
       
  1539 			// dereferenced in other process, a panic will raise in the system. Therefore, a file
       
  1540 			// handle, rather than pointer, is used when necessary.
       
  1541 			if (iUsingSecureDrmProcess && source->CarryingFileHandle())
       
  1542 				{
       
  1543 				iAddDataSourceSinkAsync->AddFileHandleDataSource(*iCurrentConfig->iController,
       
  1544 																 static_cast<const CMMFileSourceSink*>(source)->FileHandle(),
       
  1545 																 source->SourceSinkData());
       
  1546 				}
       
  1547 			else
       
  1548 				{
       
  1549 				iAddDataSourceSinkAsync->AddDataSource(*iCurrentConfig->iController, 
       
  1550 													   source->SourceSinkUid(), 
       
  1551 													   source->SourceSinkData());
       
  1552 				}
       
  1553 			}
       
  1554 			break;
       
  1555 
       
  1556 		case EAddSink:
       
  1557 			{
       
  1558 			iState = EWaitingForSink;
       
  1559 			const CMMSourceSink* sink = iCurrentConfig->iSink;
       
  1560 			// CMMSourceSink has the ability to transform the data it stored into a data stream
       
  1561 			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
       
  1562 			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
       
  1563 			// source/sink. The info about the file can be a file path or a file handle.
       
  1564 			// When it holds a file handle and turns info into data stream, the file handle is
       
  1565 			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
       
  1566 			// the streamed info is always extracted within the same process. If the pointer is 
       
  1567 			// dereferenced in other process, a panic will raise in the system. Therefore, a file
       
  1568 			// handle, rather than pointer, is used when necessary.
       
  1569 			const TDesC8& sinkData = sink->SourceSinkData();
       
  1570 			if (iUsingSecureDrmProcess && sink->CarryingFileHandle())
       
  1571 				{
       
  1572 				iAddDataSourceSinkAsync->AddFileHandleDataSink(*iCurrentConfig->iController,
       
  1573 															   static_cast<const CMMFileSourceSink*>(sink)->FileHandle(),
       
  1574 															   sinkData);
       
  1575 				}
       
  1576 			else
       
  1577 				{
       
  1578 				iAddDataSourceSinkAsync->AddDataSink(*iCurrentConfig->iController, 
       
  1579 													 sink->SourceSinkUid(), 
       
  1580 													 sinkData);
       
  1581 				}
       
  1582 			}
       
  1583 			break;
       
  1584 		
       
  1585 		case EWaitingForSource:
       
  1586 			break;
       
  1587 
       
  1588 		case EWaitingForSink:
       
  1589 			break;
       
  1590 
       
  1591 		case ESendError:
       
  1592 			SendError();
       
  1593 			iState = EIdle;
       
  1594 			break;
       
  1595 
       
  1596 		case EIdle:
       
  1597 		default:
       
  1598 			break;
       
  1599 		}
       
  1600 	}
       
  1601 
       
  1602 void CMMFFindAndOpenController::TryNextController()
       
  1603 	{
       
  1604 	// If an error occurred close the controller.
       
  1605 	if (iError != KErrNone)
       
  1606 		{
       
  1607 		CloseController();
       
  1608 		}
       
  1609 	
       
  1610 	iStopTryLoadController = EFalse;
       
  1611 	
       
  1612 	if (iMode == EOpenByControllerUid || ++iControllerIndex >= iControllerCount)
       
  1613 		{
       
  1614 		//Raise a flag to stop trying to load the controllers
       
  1615 		iStopTryLoadController = ETrue;
       
  1616 		
       
  1617 		// KErrNotSupported is the default error, but will only be used if no other error 
       
  1618 		// has been discovered (the first error found is used by default)
       
  1619 		// However, KErrBadHandle seems to mean that we tried to use the DRM server without
       
  1620 		// RFs::ShareProtected() having been called, so force usage of KErrNotSupported so
       
  1621 		// client does not see changed 
       
  1622 		TBool forceErrorUse = EFalse;
       
  1623 		if (iError==KErrBadHandle)
       
  1624 			{
       
  1625 			forceErrorUse = ETrue;
       
  1626 			}
       
  1627 		SendError(KErrNotSupported, forceErrorUse);		
       
  1628 			
       
  1629 		return;
       
  1630 		}
       
  1631 
       
  1632 	if (iMode == EOpenByFileName || iMode == EOpenByFormatUid)
       
  1633 		{
       
  1634 		iControllerImplInfo = iPrioritisedControllers[iControllerIndex];
       
  1635 		}
       
  1636 	else	//if (iMode == EOpenByDescriptor || iMode == EOpenByUrl)
       
  1637 		{
       
  1638 		iControllerImplInfo = iControllers[iControllerIndex];
       
  1639 		}
       
  1640 
       
  1641 	iCurrentConfig->iControllerUid = iControllerImplInfo->Uid();
       
  1642 	iState = EOpenController;
       
  1643 	KickState();
       
  1644 	}
       
  1645 
       
  1646 void CMMFFindAndOpenController::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
       
  1647 	{
       
  1648 	iError = aError;
       
  1649 
       
  1650 	// take the first available exit if we're out of memory
       
  1651 	// or we've been cancelled
       
  1652 	if (iError == KErrNoMemory || iError == KErrCancel)
       
  1653 		{
       
  1654 		SendError();
       
  1655 		return;
       
  1656 		}
       
  1657 
       
  1658 	// failed to add source or sink - try the next controller
       
  1659 	if (aError != KErrNone)
       
  1660 		{
       
  1661 		TryNextController();
       
  1662 		return;
       
  1663 		}
       
  1664 
       
  1665 	if (iState == EWaitingForSource)
       
  1666 		{
       
  1667 		#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
  1668 		#ifdef SYMBIAN_BUILD_GCE
       
  1669 		// If surfaces are required try to use them.  If this fails then fall back to using
       
  1670 		// direct screen access.
       
  1671 		if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
       
  1672 			{
       
  1673 			// UseSurfaces call has to be done after adding data sink and adding data source.
       
  1674 			iSurfaceSupported = iVideoPlaySurfaceSupportCustomCommands->UseSurfaces();
       
  1675 			
       
  1676 			if (iSurfaceSupported == KErrNotSupported)
       
  1677 				{
       
  1678 				if (iUseVPU2)
       
  1679 					{
       
  1680 					if (ControllerIndex() < ControllerCount() - 1)
       
  1681 						{
       
  1682 						// Until end of the list of controllers,
       
  1683 						// try the next one for surface support
       
  1684 						TryNextController(); // this will also kick-state
       
  1685 						return;
       
  1686 						}
       
  1687 					else
       
  1688 						{
       
  1689 						iError = iSurfaceSupported;
       
  1690 						}
       
  1691 					}
       
  1692 				else 
       
  1693 					{
       
  1694 					// No surface enabled controller found 
       
  1695 					// not required to do only surface, 
       
  1696 					// use the last one that matched.
       
  1697 					iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
       
  1698 					if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
       
  1699 						{
       
  1700 						iError = KErrNone;
       
  1701 						}
       
  1702 					}
       
  1703 				}
       
  1704 			else
       
  1705 				{
       
  1706 				iError = iSurfaceSupported;
       
  1707 				}
       
  1708 			}
       
  1709 		#endif // SYMBIAN_BUILD_GCE
       
  1710 		#endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
  1711 			
       
  1712 		iSourceHandle = aHandle;
       
  1713 		if (iCurrentConfig == iSecondaryConfig)
       
  1714 			{
       
  1715 			iState = EAddSink;
       
  1716 			}
       
  1717 		else	// completed ok !
       
  1718 			{
       
  1719 			iState = EIdle;
       
  1720 			SendError(KErrNone, ETrue);
       
  1721 			return;
       
  1722 			}
       
  1723 		}
       
  1724 	else if (iState == EWaitingForSink)
       
  1725 		{
       
  1726 		iSinkHandle = aHandle;
       
  1727 		if (iCurrentConfig == iSecondaryConfig)	// completed ok !
       
  1728 			{
       
  1729 			iState = EIdle;
       
  1730 			iError = KErrNone;
       
  1731 			SendError();
       
  1732 			return;
       
  1733 			}
       
  1734 		else
       
  1735 			{
       
  1736 			iState = EAddSource;
       
  1737 			}
       
  1738 		}
       
  1739 
       
  1740 	KickState();
       
  1741 	}
       
  1742 
       
  1743 void CMMFFindAndOpenController::SendError(TInt aError, TBool aOverrideError)
       
  1744 	{
       
  1745 	if (iError == KErrNone || aOverrideError)
       
  1746 		{
       
  1747 		iError = aError;		
       
  1748 		}
       
  1749 
       
  1750 	iObserver.MfaocComplete(iError, iCurrentConfig->iController, iCurrentConfig->iControllerUid, &iSourceHandle, &iSinkHandle);
       
  1751 
       
  1752 	// if we've just attempted to open the Secondary controller, 
       
  1753 	// try to open the Primary controller
       
  1754 	if (iCurrentConfig == iSecondaryConfig)
       
  1755 		{
       
  1756 		if (iError == KErrNone)
       
  1757 			OpenPrimaryController();
       
  1758 		}
       
  1759 
       
  1760 	// if we failed to open, may as well free up some memory
       
  1761 	// if open succeeded we need to preserve state in case of a re-open
       
  1762 	if (iError != KErrNone)
       
  1763 		{
       
  1764 		if(iControllerIndex >= iControllerCount-1)
       
  1765 			{
       
  1766 			Close();
       
  1767 			}
       
  1768 		else //if there are other controllers selected in the controller list, try them
       
  1769 			{
       
  1770 			Cancel();
       
  1771 			if(iAddDataSourceSinkAsync)
       
  1772 				{
       
  1773 				iAddDataSourceSinkAsync->Cancel();
       
  1774 				}
       
  1775 
       
  1776  			TryNextController();
       
  1777 			}
       
  1778 		}
       
  1779 	}
       
  1780 
       
  1781 void CMMFFindAndOpenController::SchedSendError(TInt aError)
       
  1782 	{
       
  1783 	if (aError != KErrNone)
       
  1784 		iError = aError;
       
  1785 	iState = ESendError;
       
  1786 	KickState();
       
  1787 	}
       
  1788 
       
  1789 void CMMFFindAndOpenController::BuildControllerListFileNameL()
       
  1790 	{
       
  1791 	// Retrieve a list of possible controllers from ECOM
       
  1792 	// If we don't have a match, leave with unsupported
       
  1793 
       
  1794 	iControllers.ResetAndDestroy();
       
  1795 	iPrioritisedControllers.Reset();
       
  1796 
       
  1797 	TControllerMode mode = iCurrentConfig->iControllerMode;
       
  1798 
       
  1799 	// if we're playing, try to get the MIME type from the Content Access
       
  1800 	// Framework (CAF) & use that to select a controller - if that fails, 
       
  1801 	// try to select a controller based on the header data/file extension
       
  1802 	
       
  1803 	CMMFUtilityFileInfo* fileInfo = NULL;
       
  1804 
       
  1805 	TInt error;
       
  1806 	
       
  1807 	//If the current CMMSourceSink is a CMMFileSourceSink
       
  1808 	// Using the previous version we'd get KErrCANoPermission when calling EvaluateIntent in the
       
  1809 	// CMMFUtilityFileInfo ConstructL as the intent == EUnknown, so now pass the intent as a parameter
       
  1810 	// to TMMFileHandleSource and....
       
  1811 	TBool isSecureDrmProcess = EFalse;
       
  1812 	//need to do this only in local playback mode
       
  1813 	//UseSecureDRMProcess() function in called only in case of local play / record
       
  1814 	// so we'll just chk for playback mode
       
  1815 	if(mode == EPlayback)
       
  1816 	    {
       
  1817 	    TRAP(error, UseSecureDRMProcessL(isSecureDrmProcess));
       
  1818 	    if(error == KErrPermissionDenied)
       
  1819 	    	{
       
  1820 	    	isSecureDrmProcess = ETrue;
       
  1821 	    	}
       
  1822 	    else
       
  1823 	    	{
       
  1824 	    	User::LeaveIfError(error);
       
  1825 	    	}
       
  1826 	    }
       
  1827     TRAP(error, fileInfo = CreateFileInfoL(isSecureDrmProcess));
       
  1828     
       
  1829 	if (fileInfo != NULL)
       
  1830 		{
       
  1831 		CleanupDeletePushL(fileInfo);
       
  1832 		}
       
  1833 	
       
  1834 	if (error != KErrNone)
       
  1835 		{
       
  1836 		// if playback mode, leave for any error
       
  1837 		// if record mode, allow KErrNotFound
       
  1838 		if (mode == EPlayback || (mode != EPlayback && error != KErrNotFound))
       
  1839 			{
       
  1840 			User::Leave(error);
       
  1841 			}
       
  1842 		}
       
  1843 
       
  1844 	CMMFControllerPluginSelectionParameters* cSelect = NULL;
       
  1845 	if (isSecureDrmProcess)
       
  1846 		{
       
  1847 		cSelect = CMMFControllerSecureDrmPluginSelectionParameters::NewLC();
       
  1848 		}
       
  1849 	else
       
  1850 		{
       
  1851 		cSelect = CMMFControllerPluginSelectionParameters::NewLC();
       
  1852 		}
       
  1853 	RArray<TUid> mediaIds;
       
  1854 	CleanupClosePushL(mediaIds);
       
  1855 	User::LeaveIfError(mediaIds.Append(iMediaId));
       
  1856 
       
  1857 	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
       
  1858 
       
  1859 	if (mode == EPlayback)
       
  1860 		{
       
  1861 		ASSERT(fileInfo!=NULL);
       
  1862 		TBuf8<KMaxMimeLength> mimeType;
       
  1863 		TBool mimeTypeKnown = fileInfo->GetFileMimeTypeL(mimeType);
       
  1864 		if (mimeTypeKnown)
       
  1865 			{
       
  1866 			CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
       
  1867 			fSelect->SetMatchToMimeTypeL(mimeType);
       
  1868 			cSelect->SetRequiredPlayFormatSupportL(*fSelect);
       
  1869 			cSelect->ListImplementationsL(iControllers);
       
  1870 			CleanupStack::PopAndDestroy(fSelect);
       
  1871 			}
       
  1872 
       
  1873 
       
  1874 		// copy to the iPrioritisedControllers array - this is a NOOP if the 
       
  1875 		// MIME type is not known since iControllers will be empty
       
  1876 		ASSERT(mimeTypeKnown || iControllers.Count() == 0);
       
  1877 		for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
       
  1878 			User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
       
  1879 
       
  1880 		iControllerCount = iPrioritisedControllers.Count();
       
  1881 		if (iControllerCount > 0)
       
  1882 			{
       
  1883 			// Clean up
       
  1884 			// cSelect, mediaIds, 
       
  1885 			CleanupStack::PopAndDestroy(2, cSelect);
       
  1886 			if (fileInfo != NULL)
       
  1887 				{
       
  1888 				CleanupStack::PopAndDestroy(fileInfo);
       
  1889 				}
       
  1890 			return;
       
  1891 			}
       
  1892 		}
       
  1893 
       
  1894 	// Retrieve header data first. If file doesn't exist, its ok.
       
  1895 	HBufC8* headerData = HBufC8::NewLC(KMaxHeaderSize);
       
  1896 	TPtr8 headerDataPtr = headerData->Des();
       
  1897 	if (fileInfo)
       
  1898 		{
       
  1899 		fileInfo->GetFileHeaderDataL(headerDataPtr, KMaxHeaderSize);
       
  1900 		}
       
  1901 
       
  1902 	// Get the filename's suffix
       
  1903 	HBufC8* fileSuffix = CMMFClientUtility::GetFileExtensionL(iFileName);
       
  1904 
       
  1905 	CleanupStack::PushL(fileSuffix);
       
  1906 	TPtr8 fileSuffixPtr = fileSuffix->Des();
       
  1907 
       
  1908 	// Get the secondary filename's header data (for convert)
       
  1909 	HBufC8* headerDataSecondary = HBufC8::NewLC(KMaxHeaderSize);
       
  1910 	TPtr8 headerDataPtrSecondary = headerDataSecondary->Des();
       
  1911 	if (iFileNameSecondary.Length() > 0 && fileInfo)
       
  1912 		{
       
  1913 		fileInfo->GetFileHeaderDataL(headerDataPtrSecondary, KMaxHeaderSize);
       
  1914 		}
       
  1915 
       
  1916 	// Get the secondary filename's suffix
       
  1917 	HBufC8* fileSuffixSecondary = CMMFClientUtility::GetFileExtensionL(iFileNameSecondary);
       
  1918 	CleanupStack::PushL(fileSuffixSecondary);
       
  1919 	TPtr8 fileSuffixPtrSecondary = fileSuffixSecondary->Des();
       
  1920 
       
  1921 
       
  1922 	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
       
  1923 
       
  1924 	if (mode == EPlayback || mode == EConvert)
       
  1925 		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
       
  1926 	if (mode == ERecord || mode == EConvert)
       
  1927 		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
       
  1928 	
       
  1929 	cSelect->ListImplementationsL(iControllers);
       
  1930 	
       
  1931 	if (iControllers.Count()==0)
       
  1932 		User::Leave(KErrNotSupported);
       
  1933 
       
  1934 	if (mode == ERecord)
       
  1935 		{
       
  1936 		CMMFClientUtility::PrioritiseControllersL(
       
  1937 			iControllers, 
       
  1938 			headerDataPtrSecondary, 
       
  1939 			fileSuffixPtrSecondary, 
       
  1940 			headerDataPtr, 
       
  1941 			fileSuffixPtr, 
       
  1942 			iPrioritisedControllers);
       
  1943 		}
       
  1944 	else
       
  1945 		{
       
  1946 		CMMFClientUtility::PrioritiseControllersL(
       
  1947 			iControllers, 
       
  1948 			headerDataPtr, 
       
  1949 			fileSuffixPtr, 
       
  1950 			headerDataPtrSecondary, 
       
  1951 			fileSuffixPtrSecondary, 
       
  1952 			iPrioritisedControllers);
       
  1953 		}
       
  1954 	
       
  1955 	iControllerCount = iPrioritisedControllers.Count();
       
  1956 	if (iControllerCount == 0)
       
  1957 		User::Leave(KErrNotSupported);
       
  1958 	
       
  1959 	// Clean up
       
  1960 	// cSelect, mediaIds, 
       
  1961 	// headerData, fileSuffix, headerDataSecondary, fileSuffixSecondary, 
       
  1962 	// fSelect
       
  1963 	CleanupStack::PopAndDestroy(7, cSelect);
       
  1964 	if (fileInfo != NULL)
       
  1965 		{
       
  1966 		CleanupStack::PopAndDestroy(fileInfo);
       
  1967 		}
       
  1968 	}
       
  1969 
       
  1970 void CMMFFindAndOpenController::BuildControllerListDescriptorL()
       
  1971 	{
       
  1972 	// Retrieve a list of possible controllers from ECOM
       
  1973 	// If we don't have a match, leave with unsupported
       
  1974 
       
  1975 	iControllers.ResetAndDestroy();
       
  1976 
       
  1977 	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
       
  1978 	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
       
  1979 
       
  1980 	
       
  1981 	RArray<TUid> mediaIds;
       
  1982 	CleanupClosePushL(mediaIds);
       
  1983 	User::LeaveIfError(mediaIds.Append(iMediaId));
       
  1984 
       
  1985 	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
       
  1986 	
       
  1987 	TPtrC8 header = iDescriptor.Left(KMaxHeaderSize);
       
  1988 	fSelect->SetMatchToHeaderDataL(header);
       
  1989 	
       
  1990 	
       
  1991 	TControllerMode mode = iCurrentConfig->iControllerMode;
       
  1992 	if (mode == EPlayback || mode == EConvert)
       
  1993 		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
       
  1994 	if (mode == ERecord || mode == EConvert)
       
  1995 		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
       
  1996 
       
  1997 	cSelect->ListImplementationsL(iControllers);
       
  1998 
       
  1999 	iControllerCount = iControllers.Count();
       
  2000 	if (iControllerCount == 0)
       
  2001 		User::Leave(KErrNotSupported);
       
  2002 
       
  2003 	// Clean up
       
  2004 	// cSelect, fSelect, mediaIds
       
  2005 	CleanupStack::PopAndDestroy(3, cSelect);
       
  2006 	}
       
  2007 
       
  2008 void CMMFFindAndOpenController::BuildControllerListUrlL()
       
  2009 	{
       
  2010 	// Retrieve a list of possible controllers from ECOM
       
  2011 	// If we don't have a match, leave with unsupported
       
  2012 
       
  2013 	iControllers.ResetAndDestroy();
       
  2014 
       
  2015 	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
       
  2016 	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
       
  2017 
       
  2018 	RArray<TUid> mediaIds;
       
  2019 	CleanupClosePushL(mediaIds);
       
  2020 	User::LeaveIfError(mediaIds.Append(iMediaId));
       
  2021 
       
  2022 	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
       
  2023 	
       
  2024 
       
  2025  	if (*iMimeType != KNullDesC8)
       
  2026 		{
       
  2027 		fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
       
  2028 		}
       
  2029 	else
       
  2030 		{
       
  2031 		fSelect->SetMatchToUriSupportL(*iUrl);
       
  2032 		}
       
  2033 	
       
  2034 	TControllerMode mode = iCurrentConfig->iControllerMode;
       
  2035 	if (mode == EPlayback || mode == EConvert)
       
  2036 		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
       
  2037 	if (mode == ERecord || mode == EConvert)
       
  2038 		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
       
  2039 
       
  2040 	cSelect->ListImplementationsL(iControllers);
       
  2041 
       
  2042 	iControllerCount = iControllers.Count();
       
  2043 	if (iControllerCount == 0)
       
  2044 		User::Leave(KErrNotSupported);
       
  2045 
       
  2046 	// Clean up
       
  2047 	// cSelect, fSelect, mediaIds
       
  2048 	CleanupStack::PopAndDestroy(3, cSelect);
       
  2049 	}
       
  2050 
       
  2051 void CMMFFindAndOpenController::BuildControllerListFormatL()
       
  2052 	{
       
  2053 	// Retrieve a list of possible controllers from ECOM
       
  2054 	// If we don't have a match, leave with unsupported
       
  2055 
       
  2056 	iControllers.ResetAndDestroy();
       
  2057 	iPrioritisedControllers.Reset();
       
  2058 
       
  2059 	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
       
  2060 
       
  2061 	// Select the media IDs to allow
       
  2062 	RArray<TUid> mediaIds;
       
  2063 	CleanupClosePushL(mediaIds);
       
  2064 	User::LeaveIfError(mediaIds.Append(iMediaId));
       
  2065 
       
  2066 	cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
       
  2067 
       
  2068 	CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
       
  2069 
       
  2070 	TControllerMode mode = iCurrentConfig->iControllerMode;
       
  2071 	if (mode == EPlayback || mode == EConvert)
       
  2072 		cSelect->SetRequiredPlayFormatSupportL(*fSelect);
       
  2073 	if (mode == ERecord || mode == EConvert)
       
  2074 		cSelect->SetRequiredRecordFormatSupportL(*fSelect);
       
  2075 
       
  2076 	//Obtain a list of the controllers
       
  2077 	cSelect->ListImplementationsL(iControllers);
       
  2078 
       
  2079 	CleanupStack::PopAndDestroy(3, cSelect); // cSelect, mediaIds, fSelect
       
  2080 
       
  2081 	iControllerCount = iControllers.Count();
       
  2082 	if (iControllerCount == 0)
       
  2083 		User::Leave(KErrNotSupported);
       
  2084 
       
  2085 	TUid formatUidPrimary;
       
  2086 	TUid formatUidSecondary;
       
  2087 	if (mode == ERecord)
       
  2088 		{
       
  2089 		formatUidSecondary = iFormatUid;
       
  2090 		formatUidPrimary = iFormatUidSecondary;
       
  2091 		}
       
  2092 	else
       
  2093 		{
       
  2094 		formatUidPrimary = iFormatUid;
       
  2095 		formatUidSecondary = iFormatUidSecondary;
       
  2096 		}
       
  2097 	
       
  2098 	for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
       
  2099 		{
       
  2100 		const RMMFFormatImplInfoArray& recFormatInfo = iControllers[controllerIndex]->RecordFormats();
       
  2101 		const RMMFFormatImplInfoArray& playFormatInfo = iControllers[controllerIndex]->PlayFormats();
       
  2102 
       
  2103 		TBool playFormatMatched = EFalse;
       
  2104 		TBool recordFormatMatched = EFalse;
       
  2105 
       
  2106 		if (formatUidPrimary == KNullUid)
       
  2107 			{
       
  2108 			playFormatMatched = ETrue;
       
  2109 			}
       
  2110 		else
       
  2111 			{
       
  2112 			for(TInt playFormatIndex =0; playFormatIndex < playFormatInfo.Count(); playFormatIndex++)
       
  2113 				{
       
  2114 				if(playFormatInfo[playFormatIndex]->Uid() == formatUidPrimary)
       
  2115 					{
       
  2116 					playFormatMatched = ETrue;
       
  2117 					break;
       
  2118 					}
       
  2119 				}
       
  2120 			}
       
  2121 
       
  2122 		if (formatUidSecondary == KNullUid)
       
  2123 			{
       
  2124 			recordFormatMatched = ETrue;
       
  2125 			}
       
  2126 		else
       
  2127 			{
       
  2128 			for (TInt recFormatIndex =0; recFormatIndex < recFormatInfo.Count(); recFormatIndex++)
       
  2129 				{
       
  2130 				if (recFormatInfo[recFormatIndex]->Uid() == formatUidSecondary)
       
  2131 					{
       
  2132 					recordFormatMatched = ETrue;
       
  2133 					break;
       
  2134 					}
       
  2135 				}
       
  2136 			}
       
  2137 
       
  2138 		if (playFormatMatched && recordFormatMatched)
       
  2139 			User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
       
  2140 		}
       
  2141 
       
  2142 	iControllerCount = iPrioritisedControllers.Count();
       
  2143 	if (iControllerCount == 0)
       
  2144 		User::Leave(KErrNotSupported);
       
  2145 	}
       
  2146 	
       
  2147 CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TSourceSink& aParams) 
       
  2148 	{
       
  2149 	if (aParams.iUseFileHandle)
       
  2150 		{
       
  2151 		return CMMFileSourceSink::NewL(aParams.iUid, aParams.iFileHandle);
       
  2152 		}
       
  2153 	return CMMSourceSink::NewL(aParams.iUid, aParams.iConfigData);
       
  2154 	}
       
  2155 
       
  2156 
       
  2157 CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TMMSource& aSource) 
       
  2158 	{	
       
  2159 	if (!(aSource.SourceType()==KUidMMFileSource || 
       
  2160 		aSource.SourceType()==KUidMMFileHandleSource))
       
  2161 		User::Leave(KErrNotSupported);
       
  2162 
       
  2163 	return CMMFileSourceSink::NewL(KUidMmfFileSource, aSource);
       
  2164 	}
       
  2165 
       
  2166 CMMFUtilityFileInfo* CMMFFindAndOpenController::CreateFileInfoL(TBool aSecureDRMMode)
       
  2167 	{
       
  2168 	CMMFUtilityFileInfo* fileInfo = NULL;
       
  2169 	if (iUseFileHandle) 
       
  2170 		{
       
  2171 		if (iUniqueId != NULL)
       
  2172 			{
       
  2173 			TMMFileHandleSource fileHandleSource(iFileHandle, (*iUniqueId), iIntent,iEnableUi);
       
  2174 			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
       
  2175 			}
       
  2176 		else
       
  2177 			{
       
  2178 			TMMFileHandleSource fileHandleSource(iFileHandle);
       
  2179 			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
       
  2180 			}
       
  2181 		}
       
  2182 	else
       
  2183 		{
       
  2184 		if (iUniqueId != NULL)
       
  2185 			{
       
  2186 			TMMFileSource fileSource(iFileName, (*iUniqueId), iIntent,iEnableUi);	
       
  2187 			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
       
  2188 			}
       
  2189 		else
       
  2190 			{
       
  2191 			TMMFileSource fileSource(iFileName);	
       
  2192 			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
       
  2193 			}
       
  2194 		}
       
  2195 	return fileInfo;
       
  2196 	}
       
  2197 	
       
  2198 EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const TDesC8& aConfigData)	
       
  2199 	: iConfigData(aConfigData)
       
  2200 	{
       
  2201 	iUid = aUid;
       
  2202 
       
  2203 	iUseFileHandle = EFalse;
       
  2204 	}
       
  2205 	
       
  2206 EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const RFile& aFile)	
       
  2207 	: iConfigData(KNullDesC8)
       
  2208 	{
       
  2209 	iUid = aUid;
       
  2210 
       
  2211 	iFileHandle = aFile;
       
  2212 	iUseFileHandle = ETrue;
       
  2213 	}
       
  2214 	
       
  2215 EXPORT_C void CMMFFindAndOpenController::SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands)
       
  2216 	{	
       
  2217 	iScreenNumber = aScreenNumber;
       
  2218 	iVideoSetInitScreenCustomCommands = aVideoSetInitScreenCustomCommands;
       
  2219 	}
       
  2220 		
       
  2221 CMMFFindAndOpenController::CConfig::CConfig()
       
  2222 	{
       
  2223 	}
       
  2224 	
       
  2225 void CMMFFindAndOpenController::CConfig::Close()
       
  2226 	{
       
  2227 	delete iSource;
       
  2228 	iSource = NULL;
       
  2229 	delete iSink;
       
  2230 	iSink = NULL;
       
  2231 	}
       
  2232 CMMFFindAndOpenController::CConfig::~CConfig()
       
  2233 	{
       
  2234 	Close();
       
  2235 	}
       
  2236 
       
  2237 void CMMFFindAndOpenController::UseSecureDRMProcessL(TBool& aIsSecureDrmProcess)
       
  2238     {
       
  2239     if(iHasDrmCapability)//if client has DRM capability, we never use Secure DRM Process
       
  2240         {
       
  2241         aIsSecureDrmProcess = EFalse;
       
  2242         return;
       
  2243         }       
       
  2244     TBool isDataProtected = EFalse;
       
  2245     ContentAccess::CContent* content = NULL;
       
  2246     TControllerMode mode = iCurrentConfig->iControllerMode;
       
  2247 
       
  2248     //setting aUseSecureDrmProcess to false(default value)
       
  2249     aIsSecureDrmProcess = EFalse;
       
  2250 
       
  2251     //need to proceed only in case of local playback mode
       
  2252     TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
       
  2253     TBool localPlaybackMode = ( mode == EPlayback && 
       
  2254                                 (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource) );
       
  2255     if(!localPlaybackMode)
       
  2256         {
       
  2257         return;
       
  2258         }
       
  2259 
       
  2260     if (iUseFileHandle && iOwnFileHandle) 
       
  2261         {
       
  2262         content = ContentAccess::CContent::NewLC(iFileHandle);
       
  2263         }
       
  2264     else if(iFileName.Length())  //need to check if file name exist
       
  2265         {
       
  2266         content = ContentAccess::CContent::NewLC(iFileName);
       
  2267         }
       
  2268     else
       
  2269         {//in case of descriptor source content object will not be created
       
  2270         return;
       
  2271         }
       
  2272     TInt value = 0;
       
  2273     TInt error = KErrNone;
       
  2274     if(iUniqueId != NULL)
       
  2275     	{
       
  2276     	error = content->GetAttribute(EIsProtected, value, *iUniqueId );
       
  2277     	}
       
  2278     else
       
  2279     	{
       
  2280     	error = content->GetAttribute(EIsProtected, value);
       
  2281     	}
       
  2282     if( (error == KErrNone && value) || error == KErrPermissionDenied )
       
  2283         {//2nd condition can be true if GetAttribute checks for DRM cap and return error if not found
       
  2284         isDataProtected = ETrue;
       
  2285         }
       
  2286     else if( error != KErrNone && error != KErrPermissionDenied)
       
  2287         {//leaving as GetAttribute of CAF caused an error.
       
  2288         User::Leave(error);
       
  2289         }
       
  2290 
       
  2291     CleanupStack::PopAndDestroy(content);
       
  2292     if(isDataProtected && !iHasDrmCapability && mode == EPlayback)
       
  2293         {//only when the Data is protected and client does not have the DRM capability, we need secure DRM process
       
  2294         aIsSecureDrmProcess = ETrue;
       
  2295         }
       
  2296     }
       
  2297 
       
  2298 EXPORT_C CMMSourceSink* CMMSourceSink::NewLC(TUid aUid, const TDesC8& aDescriptor)
       
  2299 	{
       
  2300 	CMMSourceSink* self = new (ELeave) CMMSourceSink(aUid);	
       
  2301 	CleanupStack::PushL(self);
       
  2302 	self->ConstructL(aDescriptor);
       
  2303 	return self;
       
  2304 	}
       
  2305 
       
  2306 EXPORT_C CMMSourceSink* CMMSourceSink::NewL(TUid aUid, const TDesC8& aDescriptor)
       
  2307 	{
       
  2308 	CMMSourceSink* sourcesink = CMMSourceSink::NewLC(aUid, aDescriptor);
       
  2309 	CleanupStack::Pop(sourcesink);
       
  2310 	return sourcesink;
       
  2311 	}
       
  2312 
       
  2313 CMMSourceSink::CMMSourceSink(TUid aUid)
       
  2314 	: iUid(aUid)
       
  2315 	{
       
  2316 	}
       
  2317 	
       
  2318 CMMSourceSink::~CMMSourceSink()
       
  2319 	{
       
  2320 	delete iBuf;
       
  2321 	}
       
  2322 	
       
  2323 void CMMSourceSink::ConstructL(const TDesC8& aDescriptor)
       
  2324 	{
       
  2325 	iBuf = aDescriptor.AllocL();
       
  2326 	}
       
  2327 	
       
  2328 TUid CMMSourceSink::SourceSinkUid() const
       
  2329 	{
       
  2330 	return iUid;
       
  2331 	}
       
  2332 	
       
  2333 const TDesC8& CMMSourceSink::SourceSinkData() const
       
  2334 	{
       
  2335 	return *iBuf;
       
  2336 	}
       
  2337 	
       
  2338 TBool CMMSourceSink::CarryingFileHandle() const
       
  2339 	{
       
  2340 	return EFalse;
       
  2341 	}
       
  2342 
       
  2343 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const RFile& aFile)
       
  2344 	{
       
  2345 	CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);	
       
  2346 	CleanupStack::PushL(self);
       
  2347 	self->ConstructL(aFile);
       
  2348 	return self;
       
  2349 	}
       
  2350 
       
  2351 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const RFile& aFile)
       
  2352 	{
       
  2353 	CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aFile);
       
  2354 	CleanupStack::Pop(sourcesink);
       
  2355 	return sourcesink;
       
  2356 	}
       
  2357 	
       
  2358 CMMFileSourceSink::CMMFileSourceSink(TUid aUid)
       
  2359 	: CMMSourceSink(aUid)
       
  2360 	{
       
  2361 	}
       
  2362 
       
  2363 void CMMFileSourceSink::ConstructL(const RFile& aFile)
       
  2364 	{
       
  2365 	User::LeaveIfError(iHandle.Duplicate(aFile));
       
  2366 	iUsingFileHandle = ETrue;
       
  2367 	iFileName = HBufC::NewMaxL(KMaxFileName);
       
  2368 	TPtr fileNamePtr = iFileName->Des();
       
  2369 	iHandle.Name(fileNamePtr);
       
  2370 	DoCreateFileHandleSourceConfigDataL();
       
  2371 	}
       
  2372 
       
  2373 void CMMFileSourceSink::DoCreateFileHandleSourceConfigDataL()
       
  2374 	{
       
  2375 	CBufFlat* buf = CBufFlat::NewL(KExpandSize);
       
  2376 	CleanupStack::PushL(buf);
       
  2377 	RBufWriteStream stream;
       
  2378 	stream.Open(*buf);
       
  2379 	CleanupClosePushL(stream);
       
  2380 	
       
  2381 	TPckgBuf<RFile*> fileptr(&iHandle);
       
  2382 	stream.WriteInt32L(KMMFileHandleSourceUid.iUid);
       
  2383 	stream.WriteL(fileptr);
       
  2384 	
       
  2385 	TInt length = 0;
       
  2386 	if (iUniqueId != NULL)
       
  2387 		length = iUniqueId->Length();
       
  2388 	stream.WriteInt32L(length);
       
  2389 	if (length>0)
       
  2390 		stream.WriteL(*iUniqueId);
       
  2391 	
       
  2392 	stream.WriteInt32L(iEnableUI);
       
  2393 	
       
  2394 	stream.CommitL();
       
  2395 	CleanupStack::PopAndDestroy(&stream);		
       
  2396 	iSourceSinkData = buf->Ptr(0).AllocL();
       
  2397 	
       
  2398 	CleanupStack::PopAndDestroy(buf); 
       
  2399 	}
       
  2400 	
       
  2401 const TDesC8& CMMFileSourceSink::SourceSinkData() const
       
  2402 	{
       
  2403 	ASSERT(iSourceSinkData);
       
  2404 	return *iSourceSinkData;
       
  2405 	}
       
  2406 
       
  2407 CMMFileSourceSink::~CMMFileSourceSink()
       
  2408 	{
       
  2409 	iHandle.Close(); // delete whatever
       
  2410 	delete iFileName;
       
  2411 	delete iSourceSinkData;
       
  2412 	delete iUniqueId;
       
  2413 	}
       
  2414 
       
  2415 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const TMMSource& aSource)
       
  2416 	{
       
  2417 	CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);	
       
  2418 	CleanupStack::PushL(self);
       
  2419 	self->ConstructL(aSource);
       
  2420 	return self;
       
  2421 	}
       
  2422 
       
  2423 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const TMMSource& aSource)
       
  2424 	{
       
  2425 	CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aSource);
       
  2426 	CleanupStack::Pop(sourcesink);
       
  2427 	return sourcesink;
       
  2428 	}
       
  2429 	
       
  2430 void CMMFileSourceSink::ConstructL(const TMMSource& aSource)
       
  2431 	{
       
  2432 	iUniqueId = aSource.UniqueId().AllocL();
       
  2433 	iIntent = aSource.Intent();
       
  2434 	iEnableUI = aSource.IsUIEnabled();
       
  2435 	
       
  2436 	if (aSource.SourceType() == KUidMMFileSource)
       
  2437 		{
       
  2438 		const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
       
  2439 		iFileName = fileSource.Name().AllocL();
       
  2440 		
       
  2441 		DoCreateFileSourceConfigDataL();
       
  2442 		}
       
  2443 	else if (aSource.SourceType() == KUidMMFileHandleSource)
       
  2444 		{
       
  2445 		const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
       
  2446 		iHandle.Close(); // in case already open
       
  2447 		User::LeaveIfError(iHandle.Duplicate(fileHandleSource.Handle()));
       
  2448 		iUsingFileHandle = ETrue;
       
  2449 		iFileName = HBufC::NewMaxL(KMaxFileName);
       
  2450 		TPtr fileNamePtr = iFileName->Des();
       
  2451 		iHandle.Name(fileNamePtr);
       
  2452 		
       
  2453 		DoCreateFileHandleSourceConfigDataL();
       
  2454 		}
       
  2455 	else
       
  2456 		{
       
  2457 		User::Leave(KErrNotSupported);
       
  2458 		}
       
  2459 	}
       
  2460 	
       
  2461 void CMMSourceSink::EvaluateIntentL()
       
  2462 	{
       
  2463 	}
       
  2464 	
       
  2465 void CMMFileSourceSink::EvaluateIntentL()
       
  2466 	{
       
  2467 	if (iUsingFileHandle)
       
  2468 		{
       
  2469    		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
       
  2470    		Content->OpenContentLC(iIntent, *iUniqueId);
       
  2471    		CleanupStack::PopAndDestroy(2, Content);	
       
  2472 		}
       
  2473 	else	
       
  2474 		{
       
  2475 		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
       
  2476    		Content->OpenContentLC(iIntent, *iUniqueId);
       
  2477    		CleanupStack::PopAndDestroy(2, Content);
       
  2478 		}
       
  2479 	}
       
  2480 
       
  2481 
       
  2482 	
       
  2483 EXPORT_C void CMMFileSourceSink::EvaluateIntentL(ContentAccess::TIntent aIntent)
       
  2484 	{
       
  2485 	if (iUsingFileHandle)
       
  2486 		{
       
  2487    		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
       
  2488    		Content->OpenContentLC(aIntent, *iUniqueId);
       
  2489    		CleanupStack::PopAndDestroy(2, Content);	
       
  2490 		}
       
  2491 	else	
       
  2492 		{
       
  2493 		ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
       
  2494    		Content->OpenContentLC(aIntent, *iUniqueId);
       
  2495    		CleanupStack::PopAndDestroy(2, Content);
       
  2496 		}
       
  2497 	}
       
  2498 
       
  2499 void CMMFileSourceSink::DoCreateFileSourceConfigDataL()
       
  2500 	{
       
  2501 	CBufFlat* buf = CBufFlat::NewL(KExpandSize);
       
  2502 	CleanupStack::PushL(buf);
       
  2503 	RBufWriteStream stream;
       
  2504 	stream.Open(*buf);
       
  2505 	CleanupClosePushL(stream);
       
  2506 	
       
  2507 	stream.WriteInt32L(KMMFileSourceUid.iUid);
       
  2508 	stream.WriteInt32L(iFileName->Length());
       
  2509 	stream.WriteL(*iFileName);
       
  2510 	TInt length = 0;
       
  2511 	if (iUniqueId != NULL)
       
  2512 		length = iUniqueId->Length();
       
  2513 	stream.WriteInt32L(length);
       
  2514 	if (length>0)
       
  2515 		stream.WriteL(*iUniqueId);
       
  2516 	
       
  2517 	stream.WriteInt32L(iEnableUI);
       
  2518 	
       
  2519 	stream.CommitL();
       
  2520 	CleanupStack::PopAndDestroy(&stream);
       
  2521 	iSourceSinkData = buf->Ptr(0).AllocL();
       
  2522 		
       
  2523 	CleanupStack::PopAndDestroy(buf); 
       
  2524 	}	
       
  2525 	
       
  2526 TBool CMMFileSourceSink::CarryingFileHandle() const
       
  2527 	{
       
  2528 	return iUsingFileHandle;
       
  2529 	}
       
  2530 
       
  2531