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