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