Update contrib.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Audio, MIDI and Video client utility functions.
21 #include <mmf/server/mmfdrmpluginserverproxy.h>
22 #include <caf/content.h>
24 using namespace ContentAccess;
26 #include "mmfclientutility.h"
27 #include <mmf/common/mmfpaniccodes.h>
29 const TInt KMaxMimeLength = 256;
30 const TInt KMaxHeaderSize = 256;
31 const TInt KExpandSize = 100;
33 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
34 const TInt KDefaultScreenNo = 0;
37 void CUPanic(TInt aCUPanicCode)
39 _LIT(KMMFMediaClientUtilityPaanicCategory, "MMFClientUtility");
40 User::Panic(KMMFMediaClientUtilityPaanicCategory, aCUPanicCode);
46 EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid)
48 TUid ECOMUid = KNullUid;
49 if (aMdaFormatUid == KUidMdaClipFormatWav)
50 ECOMUid = TUid::Uid(KMmfUidFormatWAVWrite);
51 else if (aMdaFormatUid == KUidMdaClipFormatAu)
52 ECOMUid = TUid::Uid(KMmfUidFormatAUWrite);
53 else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
54 ECOMUid = TUid::Uid(KMmfUidFormatRAWWrite);
55 else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
56 ECOMUid = TUid::Uid(KAdvancedUidFormatAMRWrite);
64 EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid)
66 TUid ECOMUid = KNullUid;
67 if (aMdaFormatUid == KUidMdaClipFormatWav)
68 ECOMUid = TUid::Uid(KMmfUidFormatWAVRead);
69 else if (aMdaFormatUid == KUidMdaClipFormatAu)
70 ECOMUid = TUid::Uid(KMmfUidFormatAURead);
71 else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
72 ECOMUid = TUid::Uid(KMmfUidFormatRAWRead);
73 else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
74 ECOMUid = TUid::Uid(KAdvancedUidFormatAMRRead);
82 EXPORT_C TInt CMMFClientUtility::GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength)
86 TInt error = KErrNone;
88 if ((error = fsSession.Connect()) == KErrNone)
90 if ((error = file.Open(fsSession, aFileName, EFileShareReadersOrWriters)) == KErrNone)
94 if ((error = file.Size(size)) == KErrNone)
98 if (size > aMaxLength)
101 error = file.Read(aHeaderData, size);
115 EXPORT_C TFourCC CMMFClientUtility::ConvertMdaCodecToFourCC(TMdaPackage& aCodec)
117 TFourCC dataType = KMMFFourCCCodeNULL;
118 switch (aCodec.Uid().iUid)
120 case KUidMdaWavPcmCodecDefine:
122 TMdaPcmWavCodec* pcmWavCodec = (TMdaPcmWavCodec*)&aCodec;
123 if (pcmWavCodec->iBits == TMdaPcmWavCodec::E8BitPcm)
124 dataType = KMMFFourCCCodePCMU8; //8 bit PCM
126 dataType = KMMFFourCCCodePCM16; //16 bit PCM
129 case KUidMdaAu8PcmCodecDefine:
130 dataType = KMMFFourCCCodePCM8;
132 case KUidMdaAuCodecDefine:
133 case KUidMdaAu16PcmCodecDefine:
134 dataType = KMMFFourCCCodePCM16B;
137 case KUidMdaAuMulawCodecDefine:
138 case KUidMdaWavMulawCodecDefine:
139 case KUidMdaRawAudioMulawCodecDefine: //uLAW
140 dataType = KMMFFourCCCodeMuLAW;
142 case KUidMdaAuAlawCodecDefine:
143 case KUidMdaWavAlawCodecDefine:
144 case KUidMdaRawAudioAlawCodecDefine: //ALAW
145 dataType = KMMFFourCCCodeALAW;
147 case KUidMdaRawAudioS8PcmCodecDefine: // P8
148 dataType = KMMFFourCCCodePCM8;
150 case KUidMdaRawAudioU8PcmCodecDefine: // PU8
151 dataType = KMMFFourCCCodePCMU8;
153 case KUidMdaRawAudioSL16PcmCodecDefine: // P16
154 dataType = KMMFFourCCCodePCM16;
156 case KUidMdaRawAudioSB16PcmCodecDefine: //P16B
157 dataType = KMMFFourCCCodePCM16B;
159 case KUidMdaRawAudioUL16PcmCodecDefine: //PU16
160 dataType = KMMFFourCCCodePCMU16;
162 case KUidMdaRawAudioUB16PcmCodecDefine: //PU6B
163 dataType = KMMFFourCCCodePCMU16B;
165 case KUidMdaGsmWavCodecDefine: //GSM6
166 dataType = KMMFFourCCCodeGSM610;
168 case KUidMdaWavImaAdpcmCodecDefine:
169 dataType = KMMFFourCCCodeIMAD;
171 case KUidMdaRawAmrCodecDefine:
172 dataType = KMMFFourCCCodeAMR;
174 default: // Not a Uid we recognise
175 dataType = KMMFFourCCCodeNULL;
182 CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewL(TMMSource& aSource, TBool aSecureDRMMode)
184 CMMFUtilityFileInfo* self = CMMFUtilityFileInfo::NewLC(aSource, aSecureDRMMode);
185 CleanupStack::Pop(self);
190 CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewLC(TMMSource& aSource, TBool aSecureDRMMode)
192 CMMFUtilityFileInfo* self = new (ELeave) CMMFUtilityFileInfo;
193 CleanupStack::PushL(self);
194 self->ConstructL(aSource, aSecureDRMMode);
199 void CMMFUtilityFileInfo::ConstructL(const TMMSource& aSource, TBool aSecureDRMMode)
203 if (aSource.SourceType()==KUidMMFileSource)
205 const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
206 iData = CData::NewL(TVirtualPathPtr(fileSource.Name(), fileSource.UniqueId()),
207 EContentShareReadWrite);
210 if (aSource.SourceType()==KUidMMFileHandleSource)
212 const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
213 iData = CData::NewL(fileHandleSource.Handle(), fileHandleSource.UniqueId());
216 TInt err = iData->SetProperty(EAgentPropertyAgentUI, aSource.IsUIEnabled());
217 if (err != KErrNone && err != KErrCANotSupported)
219 // KErrCANotSupported isn't a problem for us so eat the error code.
223 err = iData->EvaluateIntent(aSource.Intent());
224 User::LeaveIfError(err);
228 // Use RMMFDRMPluginServerProxy as medium
229 iDrmPluginServer = new (ELeave) RMMFDRMPluginServerProxy;
230 User::LeaveIfError(iDrmPluginServer->Open());
232 CBufFlat* dataBuffer = CBufFlat::NewL(KExpandSize);
233 CleanupStack::PushL(dataBuffer);
234 RBufWriteStream stream;
235 stream.Open(*dataBuffer);
236 CleanupClosePushL(stream);
238 stream.WriteInt32L(aSource.UniqueId().Length());
239 stream.WriteL(aSource.UniqueId());
240 stream.WriteInt32L(aSource.IsUIEnabled());
241 TPckgBuf<ContentAccess::TIntent> intentPckg(aSource.Intent());
242 stream.WriteL(intentPckg);
245 CleanupStack::PopAndDestroy(&stream);
246 if (aSource.SourceType()==KUidMMFileSource)
248 const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
249 iDrmPluginServer->OpenDataContentL(fileSource.Name(), dataBuffer->Ptr(0));
251 if (aSource.SourceType()==KUidMMFileHandleSource)
253 const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
254 iDrmPluginServer->OpenDataContentL(fileHandleSource.Handle(), dataBuffer->Ptr(0));
256 CleanupStack::PopAndDestroy(dataBuffer);
260 TInt CMMFUtilityFileInfo::EvaluateIntent(TIntent aIntent)
264 return iData->EvaluateIntent(aIntent);
268 ASSERT(iDrmPluginServer);
269 return iDrmPluginServer->EvaluateDataContentIntent(aIntent);
275 TBool CMMFUtilityFileInfo::GetFileMimeTypeL(TDes8& aMimeType)
279 return iData->GetMimeTypeL(aMimeType);
283 ASSERT(iDrmPluginServer);
284 return iDrmPluginServer->GetDataContentMimeTypeL(aMimeType);
291 void CMMFUtilityFileInfo::GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength)
296 iData->DataSizeL(size);
299 if (size > aMaxLength)
302 User::LeaveIfError(iData->Seek(ESeekStart, pos));
303 User::LeaveIfError(iData->Read(aHeaderData, size));
308 ASSERT(iDrmPluginServer);
309 iDrmPluginServer->GetDataContentFileHeaderL(aHeaderData, aMaxLength);
316 EXPORT_C HBufC8* CMMFClientUtility::GetFileExtensionL(const TDesC& aFileName)
319 fileName.Set(aFileName,NULL,NULL);
320 HBufC8* fileSuffix = NULL;
321 if(fileName.ExtPresent())
323 TPtrC fileSuffixPtr(fileName.Ext());
324 fileSuffix = HBufC8::NewL(fileSuffixPtr.Length());
325 fileSuffix->Des().Copy(fileSuffixPtr);
329 fileSuffix = KNullDesC8().AllocL();
338 CMMFUtilityFileInfo::~CMMFUtilityFileInfo()
344 if (iDrmPluginServer)
346 iDrmPluginServer->Close();
347 delete iDrmPluginServer;
354 * Returns an integer rating indicating how well the supplied format matches
355 * the header data and file extension supplied.
356 * 3 brownie points awarded for data & suffix match.
357 * 2 brownie points awarded for data match alone.
358 * 1 brownie point awarded for suffix match alone.
360 TInt CMMFClientUtility::GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension)
362 TInt browniePoints = 0;
364 if (aHeaderData.Length() > 0) // Non empty file
366 if (aFileExtension.Length() > 0) // With a file extension
368 if (format->SupportsHeaderDataL(aHeaderData) &&
369 format->SupportsFileExtension(aFileExtension))
373 else if (format->SupportsHeaderDataL(aHeaderData))
379 // See if this format has any 'empty' match data or no match data, indicating
380 // that this format will match extension alone even if data present.
381 // (A format may have more than one match data string.)
382 const CDesC8Array& supportedHeaderData = format->SupportedHeaderData();
384 if (supportedHeaderData.Count() == 0)
386 // No header data indicated.
387 if (format->SupportsFileExtension(aFileExtension))
394 for (register TInt i = 0; i < supportedHeaderData.Count(); i++)
396 if ((supportedHeaderData[i].Length() == 0) &&
397 format->SupportsFileExtension(aFileExtension))
407 // No file suffix, so must match header data alone.
408 if (format->SupportsHeaderDataL(aHeaderData))
416 // We have no choice but to match extension, if there is one.
417 if ((aFileExtension.Length() > 0) && format->SupportsFileExtension(aFileExtension))
423 return browniePoints;
429 * This function parses all the play & record formats in the given list of controllers,
430 * looking for controllers & formats that best match the requirements.
431 * Play controllers will be returned before record controllers, and
432 * in cases of equal priority between formats, ECom order will be maintained.
434 * @param "aControllers"
435 * A reference to a user supplied list of controllers retrieved from ECom.
436 * This list may be have been filtered for audio/video/play/record.
437 * @param "aHeaderDataPlayback"
438 * A descriptor reference containing the file's header data.
439 * for matching against a controller's play formats. May be KNullDesC8
440 * @param "aFileExtensionPlayback"
441 * A descriptor reference containing the filename's extension.
442 * for matching against a controller's play formats. May be KNullDesC8
443 * @param "aHeaderDataRecord"
444 * A descriptor reference containing the file's header data.
445 * for matching against a controller's record formats. May be KNullDesC8
446 * @param "aFileExtensionRecord"
447 * A descriptor reference containing the filename's extension.
448 * for matching against a controller's record formats. May be KNullDesC8
449 * @param "aPrioritisedControllers"
450 * A reference to a user supplied list through which the list of
451 * prioritised controllers will be returned.
454 void CMMFClientUtility::PrioritiseControllersL(
455 const RMMFControllerImplInfoArray& aControllers,
456 const TDesC8& aHeaderDataPlayback,
457 const TDesC8& aFileExtensionPlayback,
458 const TDesC8& aHeaderDataRecord,
459 const TDesC8& aFileExtensionRecord,
460 RMMFControllerImplInfoArray& prioritisedControllers)
462 RMMFControllerImplInfoArray fullMatchControllers; // data AND suffix
463 CleanupClosePushL(fullMatchControllers);
464 RMMFControllerImplInfoArray partMatchControllers; // data OR suffix
465 CleanupClosePushL(partMatchControllers);
467 TBool checkingPlaybackFormats = EFalse;
468 TBool checkingRecordFormats = EFalse;
470 if (aHeaderDataPlayback != KNullDesC8 || aFileExtensionPlayback != KNullDesC8)
471 checkingPlaybackFormats = ETrue;
472 if (aHeaderDataRecord != KNullDesC8 || aFileExtensionRecord != KNullDesC8)
473 checkingRecordFormats = ETrue;
475 // Examine each format for each controller. We only want to know at this stage
476 // if the controller has suitable formats, so as soon as we know it has, we can
477 // add it to out list, ranked by how well it matched.
478 for (register TInt i = 0; i < aControllers.Count(); i++)
480 const CMMFControllerImplementationInformation* controller = aControllers[i];
481 TInt savedBrowniePointsPlayback = 0;
482 TInt savedBrowniePointsRecord = 0;
484 if (checkingPlaybackFormats)
486 for (register TInt p = 0; p < controller->PlayFormats().Count(); p++)
488 const CMMFFormatImplementationInformation* format = controller->PlayFormats()[p];
490 TInt browniePoints = GetBestMatchL(format, aHeaderDataPlayback, aFileExtensionPlayback);
492 if (browniePoints >= savedBrowniePointsPlayback)
493 savedBrowniePointsPlayback = browniePoints;
497 if (checkingRecordFormats)
499 for (register TInt r = 0; r < controller->RecordFormats().Count(); r++)
501 const CMMFFormatImplementationInformation* format = controller->RecordFormats()[r];
503 TInt browniePoints = GetBestMatchL(format, aHeaderDataRecord, aFileExtensionRecord);
505 if (browniePoints >= savedBrowniePointsRecord)
506 savedBrowniePointsRecord = browniePoints;
510 TInt savedBrowniePoints = 0;
511 // if we're checking both playback & record formats
512 // make sure we've found both
513 if (checkingPlaybackFormats && checkingRecordFormats)
515 savedBrowniePoints = Min(savedBrowniePointsPlayback, savedBrowniePointsRecord);
517 else if (checkingPlaybackFormats)
519 savedBrowniePoints = savedBrowniePointsPlayback;
521 else if (checkingRecordFormats)
523 savedBrowniePoints = savedBrowniePointsRecord;
526 // Checked all formats for this controller, now count our brownie points.
527 switch (savedBrowniePoints)
530 User::LeaveIfError(fullMatchControllers.Append(controller));
533 User::LeaveIfError(partMatchControllers.Insert(controller, 0));
536 User::LeaveIfError(partMatchControllers.Append(controller));
543 // The better the controller matches, the earlier it will be in the final list.
544 for (register TInt x = 0; x < fullMatchControllers.Count(); x++)
546 if (prioritisedControllers.Find(fullMatchControllers[x]) == KErrNotFound)
548 User::LeaveIfError(prioritisedControllers.Append(fullMatchControllers[x]));
552 for (register TInt y = 0; y < partMatchControllers.Count(); y++)
554 if (prioritisedControllers.Find(partMatchControllers[y]) == KErrNotFound)
556 User::LeaveIfError(prioritisedControllers.Append(partMatchControllers[y]));
560 CleanupStack::PopAndDestroy(2, &fullMatchControllers); // fullMatchControllers, partMatchControllers
566 EXPORT_C CMMFMdaObjectStateChangeObserverCallback* CMMFMdaObjectStateChangeObserverCallback::NewL(MMdaObjectStateChangeObserver& aCallback)
568 return new(ELeave) CMMFMdaObjectStateChangeObserverCallback(aCallback);
574 CMMFMdaObjectStateChangeObserverCallback::~CMMFMdaObjectStateChangeObserverCallback()
582 EXPORT_C void CMMFMdaObjectStateChangeObserverCallback::CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
585 iPreviousState = aPreviousState;
586 iCurrentState = aCurrentState;
587 iErrorCode = aErrorCode;
590 TRequestStatus* s = &iStatus;
592 User::RequestComplete(s, KErrNone);
596 CMMFMdaObjectStateChangeObserverCallback::CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback) :
597 CActive(CActive::EPriorityHigh),
600 CActiveScheduler::Add(this);
603 void CMMFMdaObjectStateChangeObserverCallback::RunL()
605 iCallback.MoscoStateChangeEvent(iObject, iPreviousState, iCurrentState, iErrorCode);
608 void CMMFMdaObjectStateChangeObserverCallback::DoCancel()
614 //****************************************
615 // CMMFFindAndOpenController
616 //****************************************
619 * Factory function to create a CMMFFindAndOpenController class
623 EXPORT_C CMMFFindAndOpenController* CMMFFindAndOpenController::NewL(MMMFFindAndOpenControllerObserver& aObserver)
625 CMMFFindAndOpenController* self = new(ELeave) CMMFFindAndOpenController(aObserver);
626 CleanupStack::PushL(self);
628 CleanupStack::Pop(self);
632 CMMFFindAndOpenController::~CMMFFindAndOpenController()
636 // delete temporary variables
639 // this should cancel the AO
640 delete iAddDataSourceSinkAsync;
642 delete iPrimaryConfig;
643 delete iSecondaryConfig;
647 * Function to free up memory after a successful open has completed
648 * Useful to allow a alloc testing to work.
649 * Must not be called if ReOpen() is to be called
653 EXPORT_C void CMMFFindAndOpenController::Close()
658 if(iAddDataSourceSinkAsync)
660 iAddDataSourceSinkAsync->Cancel();
664 iPrimaryConfig->Close();
665 if (iSecondaryConfig)
666 iSecondaryConfig->Close();
668 iPrioritisedControllers.Close();
669 iControllers.ResetAndDestroy();
670 iControllers.Close();
672 iFileName.SetLength(0);
673 iFileNameSecondary.SetLength(0);
687 iOwnFileHandle = EFalse;
691 * Function to free up memory of which is not required in ReOpen()
692 * after a successful open has completed
693 * Useful to allow a alloc testing to work.
698 EXPORT_C void CMMFFindAndOpenController::CloseConfig()
701 if(iAddDataSourceSinkAsync)
703 iAddDataSourceSinkAsync->Cancel();
706 if (iSecondaryConfig)
708 iSecondaryConfig->Close();
711 iPrioritisedControllers.Close();
712 iControllers.ResetAndDestroy();
713 iControllers.Close();
715 iFileName.SetLength(0);
716 iFileNameSecondary.SetLength(0);
730 iOwnFileHandle = EFalse;
734 CMMFFindAndOpenController::CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver) :
735 CActive(EPriorityStandard),
736 iObserver(aObserver),
739 CActiveScheduler::Add(this);
742 void CMMFFindAndOpenController::ConstructL()
744 iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
745 iPrimaryConfig = new (ELeave) CConfig();
746 iSecondaryConfig = new (ELeave) CConfig;
747 iCurrentConfig = iPrimaryConfig;
749 RProcess thisProcess;
750 iHasDrmCapability = thisProcess.HasCapability(ECapabilityDRM, KSuppressPlatSecDiagnostic);
754 void CMMFFindAndOpenController::RunL()
759 void CMMFFindAndOpenController::DoCancel()
761 iAddDataSourceSinkAsync->Cancel();
765 * Defines the media ID & priority to be used when opening a controller
766 * Normally called once only after class has been constructed
769 * the media ID to use when searching for a controller
770 * e.g. KUidMediaTypeAudio
771 * @param aPrioritySettings
772 * the priority settings to use when opening a controller
773 * @param aMediaIdMatchType
774 * Defines the type of media id match to be performed on the plugins
775 * returned from the ECOM registry.
776 * @leave can leave with KErrNoMemory
780 EXPORT_C void CMMFFindAndOpenController::Configure(
782 TMMFPrioritySettings aPrioritySettings,
783 CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType)
785 iPrioritySettings = aPrioritySettings;
787 iMediaIdMatchType = aMediaIdMatchType;
792 void CMMFFindAndOpenController::ConfigureController(
794 RMMFController& aController,
795 CMMFControllerEventMonitor& aEventMonitor,
796 TControllerMode aControllerMode)
798 config.iController = &aController;
799 config.iEventMonitor = &aEventMonitor;
800 config.iControllerMode = aControllerMode;
804 * Configures the primary controller
807 * a reference to the client controller object to use
808 * @param aEventMonitor
809 * a reference to an event monitor object for receiving
810 * events from the controller
811 * @param aControllerMode
812 * indicates whether this controller is to be used for recording
817 EXPORT_C void CMMFFindAndOpenController::ConfigureController(
818 RMMFController& aController,
819 CMMFControllerEventMonitor& aEventMonitor,
820 TControllerMode aControllerMode)
830 * Configures the secondary controller
832 * This is only needed for the audio recorder utility which opens
833 * one controller for playback and another for recording
836 * a reference to the client controller object to use
837 * @param aEventMonitor
838 * a reference to an event monitor object for receiving
839 * events from the controller
840 * @param aControllerMode
841 * indicates whether this controller is to be used for recording
842 * or playback or converting
846 EXPORT_C void CMMFFindAndOpenController::ConfigureSecondaryController(
847 RMMFController& aController,
848 CMMFControllerEventMonitor& aEventMonitor,
849 TControllerMode aControllerMode)
859 * Makes any controllers that are opened subsequently share a single heap.
861 * The default behaviour is that each controller is created with its own heap.
862 * Each heap uses a chunk, so using this function avoids situations where the number
863 * of chunks per process is limited.
864 * The default behaviour is generally to be preferred, and should give lower overall
865 * memory usage. However, if many controllers are to be created for a particular thread,
866 * then this function should be used to prevent running out of heaps or chunks.
870 EXPORT_C void CMMFFindAndOpenController::UseSharedHeap()
872 iUseSharedHeap = ETrue;
875 void CMMFFindAndOpenController::Init()
877 // This should be called prior to opening, so reset the error
879 iSourceSinkConfigured = EFalse;
880 iControllerCount = 0;
883 void CMMFFindAndOpenController::ConfigureSourceSink(
889 TRAP(err, config.iSource = CreateSourceSinkL(aSource));
896 TRAP(err, config.iSink = CreateSourceSinkL(aSink));
905 void CMMFFindAndOpenController::ConfigureSourceSink(
907 const TMMSource& aSource,
911 TRAP(err, config.iSource = CreateSourceSinkL(aSource));
918 TRAP(err, config.iSink = CreateSourceSinkL(aSink));
929 * Configure the primary controller's source and sink
930 * The descriptors passed to this function are copied so they do not need to be persistent.
931 * To simplify the API, any errors that occur are reported back asynchronously following
932 * a subsequent call to OpenByXXX()
935 * the UID of the data source
937 * a reference to a descriptor used to configure the source
939 * the UID of the data sink
941 * a reference to a descriptor used to configure the sink
945 EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
950 CConfig* config = NULL;
953 config = iPrimaryConfig;
956 // must have already called ConfigureController()
957 __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
963 iCurrentConfig = config;
965 iSourceSinkConfigured = ETrue;
970 * Configure the primary controller's source and sink
971 * The descriptors passed to this function are copied so they do not need to be persistent.
972 * To simplify the API, any errors that occur are reported back asynchronously following
973 * a subsequent call to OpenByXXX()
976 * the UID of the data source
978 * a reference to a descriptor used to configure the source
980 * the UID of the data sink
982 * a reference to a descriptor used to configure the sink
986 EXPORT_C void CMMFFindAndOpenController::ConfigureSecondarySourceSink(
990 if (iError != KErrNone)
992 // if there was an error configuring the primary source/sink, do not try the secondary one
993 // Don't return the error, since the stored error will be returned by the OpenBy... method
997 CConfig* config = NULL;
999 config = iSecondaryConfig;
1001 // must have already configured the primary controller
1002 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1003 config = iSecondaryConfig;
1005 // must have already called ConfigureController()
1006 __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
1008 ConfigureSourceSink(
1012 iCurrentConfig = config;
1014 iSourceSinkConfigured = ETrue;
1019 EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
1020 const TMMSource& aSource,
1024 CConfig* config = iPrimaryConfig;
1026 // must have already called ConfigureController()
1027 __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
1029 ConfigureSourceSink(
1033 iCurrentConfig = config;
1035 iSourceSinkConfigured = ETrue;
1041 * Opens a controller using the supplied controller UID
1042 * and adds the source & sink
1043 * Completion is indicated asynchonously by a call to MfaocComplete()
1045 * @param aControllerUid
1046 * the UID of the primary controller
1047 * @param aControllerUid
1048 * the UID of the secondary controller
1050 * @internalComponent
1052 EXPORT_C void CMMFFindAndOpenController::OpenByControllerUid(
1053 TUid aControllerUid,
1054 TUid aSecondaryControllerUid)
1056 // must have already called ConfigureSourceSink()
1057 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1059 // Have there been any errors so far ?
1060 if (iError != KErrNone)
1066 if (iCurrentConfig == iPrimaryConfig)
1068 // only do this for the playback controller
1069 TRAP(iError, iCurrentConfig->iSource->EvaluateIntentL())
1071 if (iError != KErrNone &&
1072 !(iCurrentConfig->iControllerMode == EPlayback && iError == KErrPermissionDenied && !iHasDrmCapability))
1074 // KErrPermissionDenied error and no DRM capability are not problems in Playback mode
1075 // proper action will be performed when controller is loaded
1081 iPrimaryConfig->iControllerUid = aControllerUid;
1082 if (iCurrentConfig == iSecondaryConfig)
1084 if (aSecondaryControllerUid == KNullUid)
1085 iSecondaryConfig->iControllerUid = aControllerUid;
1087 iSecondaryConfig->iControllerUid = aSecondaryControllerUid;
1090 iMode = EOpenByControllerUid;
1091 iControllerImplInfo = NULL;
1092 iState = EOpenController;
1097 * Opens a controller using the supplied file name
1098 * and adds the source & sink
1099 * A copy is made of the filename or file handle so that it need not be persistent
1100 * Completion is indicated asynchonously by a call to MfaocComplete()
1103 * a reference to a TFileSource object to be used when searching
1105 * @param aFileNameSecondary
1106 * a reference to the seconday filename to be used when searching
1107 * for a controller. This need only be supplied when converting
1108 * between two files.
1110 * @internalComponent
1112 EXPORT_C void CMMFFindAndOpenController::OpenByFileSource(const TMMSource& aSource, const TDesC& aFileNameSecondary)
1114 // must have already called ConfigureSourceSink()
1115 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1118 // Have there been any errors so far ?
1119 if (iError != KErrNone)
1128 iFileHandle.Close();
1129 iOwnFileHandle = EFalse;
1132 iEnableUi = aSource.IsUIEnabled();
1133 if (aSource.SourceType()==KUidMMFileSource)
1135 const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
1136 iFileName = fileSource.Name();
1137 iUseFileHandle = EFalse;
1140 if (aSource.SourceType()==KUidMMFileHandleSource)
1142 const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
1143 ASSERT(iFileHandle.SubSessionHandle()==0); // closed just above
1144 err = iFileHandle.Duplicate(fileHandleSource.Handle());
1145 if (err != KErrNone)
1147 SchedSendError(err);
1150 iFileHandle.Name(iFileName); //ignore error return since we'll just do without the filename if not available
1151 iUseFileHandle = ETrue;
1152 iOwnFileHandle = ETrue; // because we dup'd it
1155 TRAP(err, iUniqueId = aSource.UniqueId().AllocL());
1156 iIntent = aSource.Intent();
1157 if (err != KErrNone)
1159 SchedSendError(err);
1164 // take a copy of the secondary file name
1165 iFileNameSecondary = aFileNameSecondary;
1167 iMode = EOpenByFileName;
1168 iState = EBuildControllerList;
1173 * Opens a controller using the supplied format UID
1174 * and adds the source & sink
1175 * Completion is indicated asynchonously by a call to MfaocComplete()
1178 * the UID of a format that must be supported by the controller
1179 * @param aFormatUidSecondary
1180 * the UID of a secondary format that must be supported by the controller
1181 * This need only be supplied when converting between two differnet formats.
1183 * @internalComponent
1185 EXPORT_C void CMMFFindAndOpenController::OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary)
1187 // must have already called ConfigureSourceSink()
1188 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1190 // Have there been any errors so far ?
1191 if (iError != KErrNone)
1197 iFormatUid = aFormatUid;
1198 iFormatUidSecondary = aFormatUidSecondary;
1200 iMode = EOpenByFormatUid;
1201 iState = EBuildControllerList;
1206 * Opens a controller using the supplied descriptor
1207 * and adds the source & sink
1208 * Completion is indicated asynchonously by a call to MfaocComplete()
1210 * @param aDescriptor
1211 * a reference to the descriptor to be used when searching
1214 * @internalComponent
1216 EXPORT_C void CMMFFindAndOpenController::OpenByDescriptor(const TDesC8& aDescriptor)
1218 // must have already called ConfigureSourceSink()
1219 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1221 // Have there been any errors so far ?
1222 if (iError != KErrNone)
1228 // take a copy of the descriptor
1229 TUint8* desBufferPtr = const_cast<TUint8*> (aDescriptor.Ptr());
1230 iDescriptor.Set( desBufferPtr,aDescriptor.Length(),aDescriptor.Length());
1232 iMode = EOpenByDescriptor;
1233 iState = EBuildControllerList;
1238 * Opens a controller using the supplied URL
1239 * and adds the source & sink
1240 * Completion is indicated asynchonously by a call to MfaocComplete()
1243 * a reference to the URL to be used when searching for a controller
1245 * the IAP ID to be used when searching for a controller
1247 * the MIME type of the data to be used when searching for a controller
1249 * @internalComponent
1251 EXPORT_C void CMMFFindAndOpenController::OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType)
1253 // must have already called ConfigureSourceSink()
1254 __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
1256 // Have there been any errors so far ?
1257 if (iError != KErrNone)
1263 // take a copy of the Url
1266 iUrl = aUrl.Alloc();
1269 SchedSendError(KErrNoMemory);
1273 // take a copy of the IapId
1276 // take a copy of the mime type
1279 iMimeType = aMimeType.Alloc();
1280 if (iMimeType == NULL)
1282 SchedSendError(KErrNoMemory);
1287 iState = EBuildControllerList;
1292 * Static function to return a TMMFFileConfig object
1293 * suitable for passing to ConfigureSourceSink()
1296 * the filename to use
1298 * @internalComponent
1300 EXPORT_C TMMFFileConfig CMMFFindAndOpenController::GetConfigFile(const TDesC& aFileName)
1302 TMMFFileConfig sourceSinkData;
1303 sourceSinkData().iPath = aFileName;
1304 return sourceSinkData;
1308 * Static function to return a TMMFDescriptorConfig object
1309 * suitable for passing to ConfigureSourceSink()
1312 * the filename to use
1314 * @internalComponent
1316 EXPORT_C TMMFDescriptorConfig CMMFFindAndOpenController::GetConfigDescriptor(const TDesC8& aDescriptor)
1318 TMMFDescriptorConfig sourceSinkData;
1319 sourceSinkData().iDes = (TAny*)&aDescriptor;
1320 sourceSinkData().iDesThreadId = RThread().Id();
1321 return sourceSinkData;
1325 * Static function to create a CBufFlat object
1326 * suitable for passing to ConfigureSourceSink()
1328 * @param aUrlCfgBuffer
1329 * the reference to a caller-supplied pointer used to create
1330 * a CBufFlat object. The caller is responsible for deletion.
1332 * a reference to the URL to be used
1334 * the IAP ID to be used
1335 * @return can return KErrNone or KErrNoMemory
1337 * @internalComponent
1340 EXPORT_C void CMMFFindAndOpenController::GetConfigUrlL(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId)
1342 delete aUrlCfgBuffer;
1343 aUrlCfgBuffer = NULL;
1345 CMMFUrlParams* urlCfg = CMMFUrlParams::NewL(aUrl,aIapId);
1346 CleanupStack::PushL(urlCfg);
1347 aUrlCfgBuffer = urlCfg->ExternalizeToCBufFlatLC();
1348 CleanupStack::Pop(aUrlCfgBuffer);
1349 CleanupStack::PopAndDestroy(urlCfg);
1352 * ReOpens the previously opened primary controller
1354 * @internalComponent
1356 EXPORT_C void CMMFFindAndOpenController::ReOpen()
1358 // should already have a valid controller uid so just open it
1359 iControllerImplInfo = NULL;
1360 iState = EOpenController;
1364 void CMMFFindAndOpenController::OpenPrimaryController(void)
1366 iCurrentConfig = iPrimaryConfig;
1369 case EOpenByFileName:
1370 case EOpenByFormatUid:
1371 case EOpenByDescriptor:
1373 iState = EBuildControllerList;
1375 case EOpenByControllerUid:
1376 iControllerImplInfo = NULL;
1377 iState = EOpenController;
1383 void CMMFFindAndOpenController::KickState()
1385 TRequestStatus* status = &iStatus;
1386 User::RequestComplete(status, KErrNone);
1390 void CMMFFindAndOpenController::CloseController()
1392 if (iCurrentConfig->iEventMonitor)
1393 iCurrentConfig->iEventMonitor->Cancel();
1394 iCurrentConfig->iController->Close();
1397 void CMMFFindAndOpenController::Process()
1401 case EBuildControllerList:
1404 case EOpenByFileName:
1405 TRAP(iError, BuildControllerListFileNameL());
1407 case EOpenByDescriptor:
1408 TRAP(iError, BuildControllerListDescriptorL());
1411 TRAP(iError, BuildControllerListUrlL());
1413 case EOpenByFormatUid:
1414 TRAP(iError, BuildControllerListFormatL());
1417 CUPanic(EMMFMediaClientUtilityBadState);
1420 if (iError != KErrNone)
1427 // try the first controller
1428 iControllerIndex = -1;
1429 TryNextController();
1432 case EOpenController:
1434 // Make sure any existing controller is closed.
1437 TBool isSecureDrmProcess = EFalse;// need to keep it false as UseSecureDRMProcess may return error
1438 // Loading controller in new threading model is enabled only in playback mode
1439 TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
1440 TBool localPlaybackMode = iCurrentConfig->iControllerMode == EPlayback &&
1441 (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource);
1442 if(localPlaybackMode)
1444 TRAPD(err,UseSecureDRMProcessL(isSecureDrmProcess));
1445 if(err == KErrPermissionDenied)
1447 isSecureDrmProcess = ETrue;
1449 else if(err != KErrNone)
1456 // Open the controller
1457 if (iControllerImplInfo)
1459 if(isSecureDrmProcess && localPlaybackMode)
1461 iError = iCurrentConfig->iController->OpenInSecureDRMProcess(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
1462 iUsingSecureDrmProcess = ETrue;
1466 iError = iCurrentConfig->iController->Open(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
1467 iUsingSecureDrmProcess = EFalse;;
1472 if(isSecureDrmProcess && localPlaybackMode)
1474 iError = iCurrentConfig->iController->OpenInSecureDRMProcess(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
1475 iUsingSecureDrmProcess = ETrue;
1480 iError = iCurrentConfig->iController->Open(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
1481 iUsingSecureDrmProcess = EFalse;
1484 //in case of error, including KErrNomemory try next controller
1487 TryNextController();
1491 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
1492 #ifndef SYMBIAN_BUILD_GCE
1493 if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
1495 iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
1498 if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
1510 #endif // SYMBIAN_BUILD_GCE
1511 #endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
1512 iCurrentConfig->iEventMonitor->Start();
1514 if (iCurrentConfig == iSecondaryConfig)
1516 iState = EAddSource;
1530 iState = EWaitingForSource;
1531 const CMMSourceSink* source = iCurrentConfig->iSource;
1532 // CMMSourceSink has the ability to transform the data it stored into a data stream
1533 // which can be passed to CMMFAddDataSourceSinkAsync for further processing.
1534 // CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
1535 // source/sink. The info about the file can be a file path or a file handle.
1536 // When it holds a file handle and turns info into data stream, the file handle is
1537 // stored as a pointer in the stream. However, at this point, it cannot guarantee that
1538 // the streamed info is always extracted within the same process. If the pointer is
1539 // dereferenced in other process, a panic will raise in the system. Therefore, a file
1540 // handle, rather than pointer, is used when necessary.
1541 if (iUsingSecureDrmProcess && source->CarryingFileHandle())
1543 iAddDataSourceSinkAsync->AddFileHandleDataSource(*iCurrentConfig->iController,
1544 static_cast<const CMMFileSourceSink*>(source)->FileHandle(),
1545 source->SourceSinkData());
1549 iAddDataSourceSinkAsync->AddDataSource(*iCurrentConfig->iController,
1550 source->SourceSinkUid(),
1551 source->SourceSinkData());
1558 iState = EWaitingForSink;
1559 const CMMSourceSink* sink = iCurrentConfig->iSink;
1560 // CMMSourceSink has the ability to transform the data it stored into a data stream
1561 // which can be passed to CMMFAddDataSourceSinkAsync for further processing.
1562 // CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
1563 // source/sink. The info about the file can be a file path or a file handle.
1564 // When it holds a file handle and turns info into data stream, the file handle is
1565 // stored as a pointer in the stream. However, at this point, it cannot guarantee that
1566 // the streamed info is always extracted within the same process. If the pointer is
1567 // dereferenced in other process, a panic will raise in the system. Therefore, a file
1568 // handle, rather than pointer, is used when necessary.
1569 const TDesC8& sinkData = sink->SourceSinkData();
1570 if (iUsingSecureDrmProcess && sink->CarryingFileHandle())
1572 iAddDataSourceSinkAsync->AddFileHandleDataSink(*iCurrentConfig->iController,
1573 static_cast<const CMMFileSourceSink*>(sink)->FileHandle(),
1578 iAddDataSourceSinkAsync->AddDataSink(*iCurrentConfig->iController,
1579 sink->SourceSinkUid(),
1585 case EWaitingForSource:
1588 case EWaitingForSink:
1602 void CMMFFindAndOpenController::TryNextController()
1604 // If an error occurred close the controller.
1605 if (iError != KErrNone)
1610 iStopTryLoadController = EFalse;
1612 if (iMode == EOpenByControllerUid || ++iControllerIndex >= iControllerCount)
1614 //Raise a flag to stop trying to load the controllers
1615 iStopTryLoadController = ETrue;
1617 // KErrNotSupported is the default error, but will only be used if no other error
1618 // has been discovered (the first error found is used by default)
1619 // However, KErrBadHandle seems to mean that we tried to use the DRM server without
1620 // RFs::ShareProtected() having been called, so force usage of KErrNotSupported so
1621 // client does not see changed
1622 TBool forceErrorUse = EFalse;
1623 if (iError==KErrBadHandle)
1625 forceErrorUse = ETrue;
1627 SendError(KErrNotSupported, forceErrorUse);
1632 if (iMode == EOpenByFileName || iMode == EOpenByFormatUid)
1634 iControllerImplInfo = iPrioritisedControllers[iControllerIndex];
1636 else //if (iMode == EOpenByDescriptor || iMode == EOpenByUrl)
1638 iControllerImplInfo = iControllers[iControllerIndex];
1641 iCurrentConfig->iControllerUid = iControllerImplInfo->Uid();
1642 iState = EOpenController;
1646 void CMMFFindAndOpenController::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
1650 // take the first available exit if we're out of memory
1651 // or we've been cancelled
1652 if (iError == KErrNoMemory || iError == KErrCancel)
1658 // failed to add source or sink - try the next controller
1659 if (aError != KErrNone)
1661 TryNextController();
1665 if (iState == EWaitingForSource)
1667 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
1668 #ifdef SYMBIAN_BUILD_GCE
1669 // If surfaces are required try to use them. If this fails then fall back to using
1670 // direct screen access.
1671 if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
1673 // UseSurfaces call has to be done after adding data sink and adding data source.
1674 iSurfaceSupported = iVideoPlaySurfaceSupportCustomCommands->UseSurfaces();
1676 if (iSurfaceSupported == KErrNotSupported)
1680 if (ControllerIndex() < ControllerCount() - 1)
1682 // Until end of the list of controllers,
1683 // try the next one for surface support
1684 TryNextController(); // this will also kick-state
1689 iError = iSurfaceSupported;
1694 // No surface enabled controller found
1695 // not required to do only surface,
1696 // use the last one that matched.
1697 iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
1698 if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
1706 iError = iSurfaceSupported;
1709 #endif // SYMBIAN_BUILD_GCE
1710 #endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
1712 iSourceHandle = aHandle;
1713 if (iCurrentConfig == iSecondaryConfig)
1717 else // completed ok !
1720 SendError(KErrNone, ETrue);
1724 else if (iState == EWaitingForSink)
1726 iSinkHandle = aHandle;
1727 if (iCurrentConfig == iSecondaryConfig) // completed ok !
1736 iState = EAddSource;
1743 void CMMFFindAndOpenController::SendError(TInt aError, TBool aOverrideError)
1745 if (iError == KErrNone || aOverrideError)
1750 iObserver.MfaocComplete(iError, iCurrentConfig->iController, iCurrentConfig->iControllerUid, &iSourceHandle, &iSinkHandle);
1752 // if we've just attempted to open the Secondary controller,
1753 // try to open the Primary controller
1754 if (iCurrentConfig == iSecondaryConfig)
1756 if (iError == KErrNone)
1757 OpenPrimaryController();
1760 // if we failed to open, may as well free up some memory
1761 // if open succeeded we need to preserve state in case of a re-open
1762 if (iError != KErrNone)
1764 if(iControllerIndex >= iControllerCount-1)
1768 else //if there are other controllers selected in the controller list, try them
1771 if(iAddDataSourceSinkAsync)
1773 iAddDataSourceSinkAsync->Cancel();
1776 TryNextController();
1781 void CMMFFindAndOpenController::SchedSendError(TInt aError)
1783 if (aError != KErrNone)
1785 iState = ESendError;
1789 void CMMFFindAndOpenController::BuildControllerListFileNameL()
1791 // Retrieve a list of possible controllers from ECOM
1792 // If we don't have a match, leave with unsupported
1794 iControllers.ResetAndDestroy();
1795 iPrioritisedControllers.Reset();
1797 TControllerMode mode = iCurrentConfig->iControllerMode;
1799 // if we're playing, try to get the MIME type from the Content Access
1800 // Framework (CAF) & use that to select a controller - if that fails,
1801 // try to select a controller based on the header data/file extension
1803 CMMFUtilityFileInfo* fileInfo = NULL;
1807 //If the current CMMSourceSink is a CMMFileSourceSink
1808 // Using the previous version we'd get KErrCANoPermission when calling EvaluateIntent in the
1809 // CMMFUtilityFileInfo ConstructL as the intent == EUnknown, so now pass the intent as a parameter
1810 // to TMMFileHandleSource and....
1811 TBool isSecureDrmProcess = EFalse;
1812 //need to do this only in local playback mode
1813 //UseSecureDRMProcess() function in called only in case of local play / record
1814 // so we'll just chk for playback mode
1815 if(mode == EPlayback)
1817 TRAP(error, UseSecureDRMProcessL(isSecureDrmProcess));
1818 if(error == KErrPermissionDenied)
1820 isSecureDrmProcess = ETrue;
1824 User::LeaveIfError(error);
1827 TRAP(error, fileInfo = CreateFileInfoL(isSecureDrmProcess));
1829 if (fileInfo != NULL)
1831 CleanupDeletePushL(fileInfo);
1834 if (error != KErrNone)
1836 // if playback mode, leave for any error
1837 // if record mode, allow KErrNotFound
1838 if (mode == EPlayback || (mode != EPlayback && error != KErrNotFound))
1844 CMMFControllerPluginSelectionParameters* cSelect = NULL;
1845 if (isSecureDrmProcess)
1847 cSelect = CMMFControllerSecureDrmPluginSelectionParameters::NewLC();
1851 cSelect = CMMFControllerPluginSelectionParameters::NewLC();
1853 RArray<TUid> mediaIds;
1854 CleanupClosePushL(mediaIds);
1855 User::LeaveIfError(mediaIds.Append(iMediaId));
1857 cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
1859 if (mode == EPlayback)
1861 ASSERT(fileInfo!=NULL);
1862 TBuf8<KMaxMimeLength> mimeType;
1863 TBool mimeTypeKnown = fileInfo->GetFileMimeTypeL(mimeType);
1866 CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
1867 fSelect->SetMatchToMimeTypeL(mimeType);
1868 cSelect->SetRequiredPlayFormatSupportL(*fSelect);
1869 cSelect->ListImplementationsL(iControllers);
1870 CleanupStack::PopAndDestroy(fSelect);
1874 // copy to the iPrioritisedControllers array - this is a NOOP if the
1875 // MIME type is not known since iControllers will be empty
1876 ASSERT(mimeTypeKnown || iControllers.Count() == 0);
1877 for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
1878 User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
1880 iControllerCount = iPrioritisedControllers.Count();
1881 if (iControllerCount > 0)
1884 // cSelect, mediaIds,
1885 CleanupStack::PopAndDestroy(2, cSelect);
1886 if (fileInfo != NULL)
1888 CleanupStack::PopAndDestroy(fileInfo);
1894 // Retrieve header data first. If file doesn't exist, its ok.
1895 HBufC8* headerData = HBufC8::NewLC(KMaxHeaderSize);
1896 TPtr8 headerDataPtr = headerData->Des();
1899 fileInfo->GetFileHeaderDataL(headerDataPtr, KMaxHeaderSize);
1902 // Get the filename's suffix
1903 HBufC8* fileSuffix = CMMFClientUtility::GetFileExtensionL(iFileName);
1905 CleanupStack::PushL(fileSuffix);
1906 TPtr8 fileSuffixPtr = fileSuffix->Des();
1908 // Get the secondary filename's header data (for convert)
1909 HBufC8* headerDataSecondary = HBufC8::NewLC(KMaxHeaderSize);
1910 TPtr8 headerDataPtrSecondary = headerDataSecondary->Des();
1911 if (iFileNameSecondary.Length() > 0 && fileInfo)
1913 fileInfo->GetFileHeaderDataL(headerDataPtrSecondary, KMaxHeaderSize);
1916 // Get the secondary filename's suffix
1917 HBufC8* fileSuffixSecondary = CMMFClientUtility::GetFileExtensionL(iFileNameSecondary);
1918 CleanupStack::PushL(fileSuffixSecondary);
1919 TPtr8 fileSuffixPtrSecondary = fileSuffixSecondary->Des();
1922 CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
1924 if (mode == EPlayback || mode == EConvert)
1925 cSelect->SetRequiredPlayFormatSupportL(*fSelect);
1926 if (mode == ERecord || mode == EConvert)
1927 cSelect->SetRequiredRecordFormatSupportL(*fSelect);
1929 cSelect->ListImplementationsL(iControllers);
1931 if (iControllers.Count()==0)
1932 User::Leave(KErrNotSupported);
1934 if (mode == ERecord)
1936 CMMFClientUtility::PrioritiseControllersL(
1938 headerDataPtrSecondary,
1939 fileSuffixPtrSecondary,
1942 iPrioritisedControllers);
1946 CMMFClientUtility::PrioritiseControllersL(
1950 headerDataPtrSecondary,
1951 fileSuffixPtrSecondary,
1952 iPrioritisedControllers);
1955 iControllerCount = iPrioritisedControllers.Count();
1956 if (iControllerCount == 0)
1957 User::Leave(KErrNotSupported);
1960 // cSelect, mediaIds,
1961 // headerData, fileSuffix, headerDataSecondary, fileSuffixSecondary,
1963 CleanupStack::PopAndDestroy(7, cSelect);
1964 if (fileInfo != NULL)
1966 CleanupStack::PopAndDestroy(fileInfo);
1970 void CMMFFindAndOpenController::BuildControllerListDescriptorL()
1972 // Retrieve a list of possible controllers from ECOM
1973 // If we don't have a match, leave with unsupported
1975 iControllers.ResetAndDestroy();
1977 CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
1978 CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
1981 RArray<TUid> mediaIds;
1982 CleanupClosePushL(mediaIds);
1983 User::LeaveIfError(mediaIds.Append(iMediaId));
1985 cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
1987 TPtrC8 header = iDescriptor.Left(KMaxHeaderSize);
1988 fSelect->SetMatchToHeaderDataL(header);
1991 TControllerMode mode = iCurrentConfig->iControllerMode;
1992 if (mode == EPlayback || mode == EConvert)
1993 cSelect->SetRequiredPlayFormatSupportL(*fSelect);
1994 if (mode == ERecord || mode == EConvert)
1995 cSelect->SetRequiredRecordFormatSupportL(*fSelect);
1997 cSelect->ListImplementationsL(iControllers);
1999 iControllerCount = iControllers.Count();
2000 if (iControllerCount == 0)
2001 User::Leave(KErrNotSupported);
2004 // cSelect, fSelect, mediaIds
2005 CleanupStack::PopAndDestroy(3, cSelect);
2008 void CMMFFindAndOpenController::BuildControllerListUrlL()
2010 // Retrieve a list of possible controllers from ECOM
2011 // If we don't have a match, leave with unsupported
2013 iControllers.ResetAndDestroy();
2015 CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
2016 CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
2018 RArray<TUid> mediaIds;
2019 CleanupClosePushL(mediaIds);
2020 User::LeaveIfError(mediaIds.Append(iMediaId));
2022 cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
2025 if (*iMimeType != KNullDesC8)
2027 fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
2031 fSelect->SetMatchToUriSupportL(*iUrl);
2034 TControllerMode mode = iCurrentConfig->iControllerMode;
2035 if (mode == EPlayback || mode == EConvert)
2036 cSelect->SetRequiredPlayFormatSupportL(*fSelect);
2037 if (mode == ERecord || mode == EConvert)
2038 cSelect->SetRequiredRecordFormatSupportL(*fSelect);
2040 cSelect->ListImplementationsL(iControllers);
2042 iControllerCount = iControllers.Count();
2043 if (iControllerCount == 0)
2044 User::Leave(KErrNotSupported);
2047 // cSelect, fSelect, mediaIds
2048 CleanupStack::PopAndDestroy(3, cSelect);
2051 void CMMFFindAndOpenController::BuildControllerListFormatL()
2053 // Retrieve a list of possible controllers from ECOM
2054 // If we don't have a match, leave with unsupported
2056 iControllers.ResetAndDestroy();
2057 iPrioritisedControllers.Reset();
2059 CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
2061 // Select the media IDs to allow
2062 RArray<TUid> mediaIds;
2063 CleanupClosePushL(mediaIds);
2064 User::LeaveIfError(mediaIds.Append(iMediaId));
2066 cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
2068 CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
2070 TControllerMode mode = iCurrentConfig->iControllerMode;
2071 if (mode == EPlayback || mode == EConvert)
2072 cSelect->SetRequiredPlayFormatSupportL(*fSelect);
2073 if (mode == ERecord || mode == EConvert)
2074 cSelect->SetRequiredRecordFormatSupportL(*fSelect);
2076 //Obtain a list of the controllers
2077 cSelect->ListImplementationsL(iControllers);
2079 CleanupStack::PopAndDestroy(3, cSelect); // cSelect, mediaIds, fSelect
2081 iControllerCount = iControllers.Count();
2082 if (iControllerCount == 0)
2083 User::Leave(KErrNotSupported);
2085 TUid formatUidPrimary;
2086 TUid formatUidSecondary;
2087 if (mode == ERecord)
2089 formatUidSecondary = iFormatUid;
2090 formatUidPrimary = iFormatUidSecondary;
2094 formatUidPrimary = iFormatUid;
2095 formatUidSecondary = iFormatUidSecondary;
2098 for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
2100 const RMMFFormatImplInfoArray& recFormatInfo = iControllers[controllerIndex]->RecordFormats();
2101 const RMMFFormatImplInfoArray& playFormatInfo = iControllers[controllerIndex]->PlayFormats();
2103 TBool playFormatMatched = EFalse;
2104 TBool recordFormatMatched = EFalse;
2106 if (formatUidPrimary == KNullUid)
2108 playFormatMatched = ETrue;
2112 for(TInt playFormatIndex =0; playFormatIndex < playFormatInfo.Count(); playFormatIndex++)
2114 if(playFormatInfo[playFormatIndex]->Uid() == formatUidPrimary)
2116 playFormatMatched = ETrue;
2122 if (formatUidSecondary == KNullUid)
2124 recordFormatMatched = ETrue;
2128 for (TInt recFormatIndex =0; recFormatIndex < recFormatInfo.Count(); recFormatIndex++)
2130 if (recFormatInfo[recFormatIndex]->Uid() == formatUidSecondary)
2132 recordFormatMatched = ETrue;
2138 if (playFormatMatched && recordFormatMatched)
2139 User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
2142 iControllerCount = iPrioritisedControllers.Count();
2143 if (iControllerCount == 0)
2144 User::Leave(KErrNotSupported);
2147 CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TSourceSink& aParams)
2149 if (aParams.iUseFileHandle)
2151 return CMMFileSourceSink::NewL(aParams.iUid, aParams.iFileHandle);
2153 return CMMSourceSink::NewL(aParams.iUid, aParams.iConfigData);
2157 CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TMMSource& aSource)
2159 if (!(aSource.SourceType()==KUidMMFileSource ||
2160 aSource.SourceType()==KUidMMFileHandleSource))
2161 User::Leave(KErrNotSupported);
2163 return CMMFileSourceSink::NewL(KUidMmfFileSource, aSource);
2166 CMMFUtilityFileInfo* CMMFFindAndOpenController::CreateFileInfoL(TBool aSecureDRMMode)
2168 CMMFUtilityFileInfo* fileInfo = NULL;
2171 if (iUniqueId != NULL)
2173 TMMFileHandleSource fileHandleSource(iFileHandle, (*iUniqueId), iIntent,iEnableUi);
2174 fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
2178 TMMFileHandleSource fileHandleSource(iFileHandle);
2179 fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
2184 if (iUniqueId != NULL)
2186 TMMFileSource fileSource(iFileName, (*iUniqueId), iIntent,iEnableUi);
2187 fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
2191 TMMFileSource fileSource(iFileName);
2192 fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
2198 EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const TDesC8& aConfigData)
2199 : iConfigData(aConfigData)
2203 iUseFileHandle = EFalse;
2206 EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const RFile& aFile)
2207 : iConfigData(KNullDesC8)
2211 iFileHandle = aFile;
2212 iUseFileHandle = ETrue;
2215 EXPORT_C void CMMFFindAndOpenController::SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands)
2217 iScreenNumber = aScreenNumber;
2218 iVideoSetInitScreenCustomCommands = aVideoSetInitScreenCustomCommands;
2221 CMMFFindAndOpenController::CConfig::CConfig()
2225 void CMMFFindAndOpenController::CConfig::Close()
2232 CMMFFindAndOpenController::CConfig::~CConfig()
2237 void CMMFFindAndOpenController::UseSecureDRMProcessL(TBool& aIsSecureDrmProcess)
2239 if(iHasDrmCapability)//if client has DRM capability, we never use Secure DRM Process
2241 aIsSecureDrmProcess = EFalse;
2244 TBool isDataProtected = EFalse;
2245 ContentAccess::CContent* content = NULL;
2246 TControllerMode mode = iCurrentConfig->iControllerMode;
2248 //setting aUseSecureDrmProcess to false(default value)
2249 aIsSecureDrmProcess = EFalse;
2251 //need to proceed only in case of local playback mode
2252 TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
2253 TBool localPlaybackMode = ( mode == EPlayback &&
2254 (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource) );
2255 if(!localPlaybackMode)
2260 if (iUseFileHandle && iOwnFileHandle)
2262 content = ContentAccess::CContent::NewLC(iFileHandle);
2264 else if(iFileName.Length()) //need to check if file name exist
2266 content = ContentAccess::CContent::NewLC(iFileName);
2269 {//in case of descriptor source content object will not be created
2273 TInt error = KErrNone;
2274 if(iUniqueId != NULL)
2276 error = content->GetAttribute(EIsProtected, value, *iUniqueId );
2280 error = content->GetAttribute(EIsProtected, value);
2282 if( (error == KErrNone && value) || error == KErrPermissionDenied )
2283 {//2nd condition can be true if GetAttribute checks for DRM cap and return error if not found
2284 isDataProtected = ETrue;
2286 else if( error != KErrNone && error != KErrPermissionDenied)
2287 {//leaving as GetAttribute of CAF caused an error.
2291 CleanupStack::PopAndDestroy(content);
2292 if(isDataProtected && !iHasDrmCapability && mode == EPlayback)
2293 {//only when the Data is protected and client does not have the DRM capability, we need secure DRM process
2294 aIsSecureDrmProcess = ETrue;
2298 EXPORT_C CMMSourceSink* CMMSourceSink::NewLC(TUid aUid, const TDesC8& aDescriptor)
2300 CMMSourceSink* self = new (ELeave) CMMSourceSink(aUid);
2301 CleanupStack::PushL(self);
2302 self->ConstructL(aDescriptor);
2306 EXPORT_C CMMSourceSink* CMMSourceSink::NewL(TUid aUid, const TDesC8& aDescriptor)
2308 CMMSourceSink* sourcesink = CMMSourceSink::NewLC(aUid, aDescriptor);
2309 CleanupStack::Pop(sourcesink);
2313 CMMSourceSink::CMMSourceSink(TUid aUid)
2318 CMMSourceSink::~CMMSourceSink()
2323 void CMMSourceSink::ConstructL(const TDesC8& aDescriptor)
2325 iBuf = aDescriptor.AllocL();
2328 TUid CMMSourceSink::SourceSinkUid() const
2333 const TDesC8& CMMSourceSink::SourceSinkData() const
2338 TBool CMMSourceSink::CarryingFileHandle() const
2343 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const RFile& aFile)
2345 CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
2346 CleanupStack::PushL(self);
2347 self->ConstructL(aFile);
2351 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const RFile& aFile)
2353 CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aFile);
2354 CleanupStack::Pop(sourcesink);
2358 CMMFileSourceSink::CMMFileSourceSink(TUid aUid)
2359 : CMMSourceSink(aUid)
2363 void CMMFileSourceSink::ConstructL(const RFile& aFile)
2365 User::LeaveIfError(iHandle.Duplicate(aFile));
2366 iUsingFileHandle = ETrue;
2367 iFileName = HBufC::NewMaxL(KMaxFileName);
2368 TPtr fileNamePtr = iFileName->Des();
2369 iHandle.Name(fileNamePtr);
2370 DoCreateFileHandleSourceConfigDataL();
2373 void CMMFileSourceSink::DoCreateFileHandleSourceConfigDataL()
2375 CBufFlat* buf = CBufFlat::NewL(KExpandSize);
2376 CleanupStack::PushL(buf);
2377 RBufWriteStream stream;
2379 CleanupClosePushL(stream);
2381 TPckgBuf<RFile*> fileptr(&iHandle);
2382 stream.WriteInt32L(KMMFileHandleSourceUid.iUid);
2383 stream.WriteL(fileptr);
2386 if (iUniqueId != NULL)
2387 length = iUniqueId->Length();
2388 stream.WriteInt32L(length);
2390 stream.WriteL(*iUniqueId);
2392 stream.WriteInt32L(iEnableUI);
2395 CleanupStack::PopAndDestroy(&stream);
2396 iSourceSinkData = buf->Ptr(0).AllocL();
2398 CleanupStack::PopAndDestroy(buf);
2401 const TDesC8& CMMFileSourceSink::SourceSinkData() const
2403 ASSERT(iSourceSinkData);
2404 return *iSourceSinkData;
2407 CMMFileSourceSink::~CMMFileSourceSink()
2409 iHandle.Close(); // delete whatever
2411 delete iSourceSinkData;
2415 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const TMMSource& aSource)
2417 CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
2418 CleanupStack::PushL(self);
2419 self->ConstructL(aSource);
2423 EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const TMMSource& aSource)
2425 CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aSource);
2426 CleanupStack::Pop(sourcesink);
2430 void CMMFileSourceSink::ConstructL(const TMMSource& aSource)
2432 iUniqueId = aSource.UniqueId().AllocL();
2433 iIntent = aSource.Intent();
2434 iEnableUI = aSource.IsUIEnabled();
2436 if (aSource.SourceType() == KUidMMFileSource)
2438 const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
2439 iFileName = fileSource.Name().AllocL();
2441 DoCreateFileSourceConfigDataL();
2443 else if (aSource.SourceType() == KUidMMFileHandleSource)
2445 const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
2446 iHandle.Close(); // in case already open
2447 User::LeaveIfError(iHandle.Duplicate(fileHandleSource.Handle()));
2448 iUsingFileHandle = ETrue;
2449 iFileName = HBufC::NewMaxL(KMaxFileName);
2450 TPtr fileNamePtr = iFileName->Des();
2451 iHandle.Name(fileNamePtr);
2453 DoCreateFileHandleSourceConfigDataL();
2457 User::Leave(KErrNotSupported);
2461 void CMMSourceSink::EvaluateIntentL()
2465 void CMMFileSourceSink::EvaluateIntentL()
2467 if (iUsingFileHandle)
2469 ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
2470 Content->OpenContentLC(iIntent, *iUniqueId);
2471 CleanupStack::PopAndDestroy(2, Content);
2475 ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
2476 Content->OpenContentLC(iIntent, *iUniqueId);
2477 CleanupStack::PopAndDestroy(2, Content);
2483 EXPORT_C void CMMFileSourceSink::EvaluateIntentL(ContentAccess::TIntent aIntent)
2485 if (iUsingFileHandle)
2487 ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
2488 Content->OpenContentLC(aIntent, *iUniqueId);
2489 CleanupStack::PopAndDestroy(2, Content);
2493 ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
2494 Content->OpenContentLC(aIntent, *iUniqueId);
2495 CleanupStack::PopAndDestroy(2, Content);
2499 void CMMFileSourceSink::DoCreateFileSourceConfigDataL()
2501 CBufFlat* buf = CBufFlat::NewL(KExpandSize);
2502 CleanupStack::PushL(buf);
2503 RBufWriteStream stream;
2505 CleanupClosePushL(stream);
2507 stream.WriteInt32L(KMMFileSourceUid.iUid);
2508 stream.WriteInt32L(iFileName->Length());
2509 stream.WriteL(*iFileName);
2511 if (iUniqueId != NULL)
2512 length = iUniqueId->Length();
2513 stream.WriteInt32L(length);
2515 stream.WriteL(*iUniqueId);
2517 stream.WriteInt32L(iEnableUI);
2520 CleanupStack::PopAndDestroy(&stream);
2521 iSourceSinkData = buf->Ptr(0).AllocL();
2523 CleanupStack::PopAndDestroy(buf);
2526 TBool CMMFileSourceSink::CarryingFileHandle() const
2528 return iUsingFileHandle;