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