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