mmfenh/enhancedmediaclient/Client/src/Components/StreamControl/ClientUtility.cpp
changeset 0 71ca22bcf22a
child 12 5a06f39ad45b
child 45 095bea5f582e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmfenh/enhancedmediaclient/Client/src/Components/StreamControl/ClientUtility.cpp	Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,2598 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Definition of the ClientUtility class.
+*  Version     : %version: bh1mmcf#12 %
+*
+*/
+
+//
+// Copyright (c) Symbian Software Ltd 2002-2006.  All rights reserved.
+//
+// Audio, MIDI and Video client utility functions.
+#include "ClientUtility.h"
+#include <e32std.h>
+#include <bautils.h>
+#include <mmf/common/mmfpaniccodes.h>
+#include <StreamControlCustomCommands.h>
+#include <mmf/server/mmfdrmpluginserverproxy.h>
+#include "../../../Plugins/FileSource/inc/FileDataSourceUid.hrh"
+#include "../../../Plugins/ProgDLSource/inc/ProgDLSourceUid.hrh"
+using namespace ContentAccess;
+using namespace multimedia;
+
+const TInt KMaxMimeLength = 256;
+const TInt KMaxHeaderSize = 256;
+const TInt KExpandSize = 100;
+
+void CUPanic(TInt aCUPanicCode)
+    {
+    _LIT(KMMFMediaClientUtilityPaanicCategory, "EnhancedAudioClient");
+    User::Panic(KMMFMediaClientUtilityPaanicCategory, aCUPanicCode);
+    }
+
+    /**
+    * @internalComponent
+*/
+TUid CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid)
+    {
+    TUid ECOMUid = KNullUid;
+    if (aMdaFormatUid == KUidMdaClipFormatWav)
+        ECOMUid = TUid::Uid(KMmfUidFormatWAVWrite);
+    else if (aMdaFormatUid == KUidMdaClipFormatAu)
+        ECOMUid = TUid::Uid(KMmfUidFormatAUWrite);
+    else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
+        ECOMUid = TUid::Uid(KMmfUidFormatRAWWrite);
+    else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
+        ECOMUid = TUid::Uid(KAdvancedUidFormatAMRWrite);
+    
+    return ECOMUid;
+    }
+
+    /**
+    * @internalComponent
+*/
+TUid CMMFClientUtility::ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid)
+    {
+    TUid ECOMUid = KNullUid;
+    if (aMdaFormatUid == KUidMdaClipFormatWav)
+        ECOMUid = TUid::Uid(KMmfUidFormatWAVRead);
+    else if (aMdaFormatUid == KUidMdaClipFormatAu)
+        ECOMUid = TUid::Uid(KMmfUidFormatAURead);
+    else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
+        ECOMUid = TUid::Uid(KMmfUidFormatRAWRead);
+    else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
+        ECOMUid = TUid::Uid(KAdvancedUidFormatAMRRead);
+    
+    return ECOMUid;
+    }
+
+    /**
+    * @internalComponent
+*/
+TInt CMMFClientUtility::GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength)
+    {
+    RFs fsSession;
+    RFile file;
+    TInt error = KErrNone;
+    
+    if ((error = fsSession.Connect()) == KErrNone)
+        {
+        if ((error = file.Open(fsSession, aFileName, EFileShareReadersOnly)) == KErrNone)
+            {
+            TInt size = 0;
+            
+            if ((error = file.Size(size)) == KErrNone)
+                {
+                if (size > 0)
+                    {
+                    if (size > aMaxLength)
+                        size = aMaxLength;
+                    
+                    error = file.Read(aHeaderData, size);
+                    }
+                }
+            file.Close();
+            }
+        fsSession.Close();
+        }
+    
+    return error;
+    }
+
+    /**
+    * @internalComponent
+*/
+TFourCC CMMFClientUtility::ConvertMdaCodecToFourCC(TMdaPackage& aCodec)
+    {
+    TFourCC dataType = KMMFFourCCCodeNULL;
+    switch (aCodec.Uid().iUid)
+        {
+        case KUidMdaWavPcmCodecDefine:
+            {
+            TMdaPcmWavCodec* pcmWavCodec = (TMdaPcmWavCodec*)&aCodec;
+            if (pcmWavCodec->iBits == TMdaPcmWavCodec::E8BitPcm)
+                dataType = KMMFFourCCCodePCMU8; //8 bit PCM
+            else
+                dataType = KMMFFourCCCodePCM16; //16 bit PCM
+            break;
+            }
+        case KUidMdaAu8PcmCodecDefine:
+            dataType = KMMFFourCCCodePCM8;
+            break;
+        case KUidMdaAuCodecDefine:
+        case KUidMdaAu16PcmCodecDefine:
+            dataType = KMMFFourCCCodePCM16B;
+            break;
+            
+        case KUidMdaAuMulawCodecDefine:
+        case KUidMdaWavMulawCodecDefine:
+        case KUidMdaRawAudioMulawCodecDefine:  //uLAW
+            dataType = KMMFFourCCCodeMuLAW;
+            break;
+        case KUidMdaAuAlawCodecDefine:
+        case KUidMdaWavAlawCodecDefine:
+        case KUidMdaRawAudioAlawCodecDefine:     //ALAW
+            dataType = KMMFFourCCCodeALAW;
+            break;
+        case KUidMdaRawAudioS8PcmCodecDefine:    //  P8
+            dataType = KMMFFourCCCodePCM8;
+            break;
+        case KUidMdaRawAudioU8PcmCodecDefine:     // PU8
+            dataType = KMMFFourCCCodePCMU8;
+            break;
+        case KUidMdaRawAudioSL16PcmCodecDefine: // P16
+            dataType = KMMFFourCCCodePCM16;
+            break;
+        case KUidMdaRawAudioSB16PcmCodecDefine: //P16B
+            dataType = KMMFFourCCCodePCM16B;
+            break;
+        case KUidMdaRawAudioUL16PcmCodecDefine: //PU16
+            dataType = KMMFFourCCCodePCMU16;
+            break;
+        case KUidMdaRawAudioUB16PcmCodecDefine: //PU6B
+            dataType = KMMFFourCCCodePCMU16B;
+            break;
+        case KUidMdaGsmWavCodecDefine: //GSM6
+            dataType = KMMFFourCCCodeGSM610;
+            break;
+        case KUidMdaWavImaAdpcmCodecDefine:
+            dataType = KMMFFourCCCodeIMAD;
+            break;
+        case KUidMdaRawAmrCodecDefine:
+            dataType = KMMFFourCCCodeAMR;
+            break;
+        default:    // Not a Uid we recognise
+            dataType = KMMFFourCCCodeNULL;
+            break;
+        }
+    return dataType;
+    }
+
+
+CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewL(TMMSource& aSource, TBool aSecureDRMMode)
+    {
+   	CMMFUtilityFileInfo* self = CMMFUtilityFileInfo::NewLC(aSource, aSecureDRMMode);
+	CleanupStack::Pop(self);
+    return self;
+    }
+
+
+CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewLC(TMMSource& aSource, TBool aSecureDRMMode)
+    {
+    CMMFUtilityFileInfo* self = new (ELeave) CMMFUtilityFileInfo;
+    CleanupStack::PushL(self);
+	self->ConstructL(aSource, aSecureDRMMode);
+    return self;
+    }
+
+
+void CMMFUtilityFileInfo::ConstructL(const TMMSource& aSource, TBool aSecureDRMMode)
+    {
+	if (!aSecureDRMMode)
+    {
+    if (aSource.SourceType()==KUidMMFileSource)
+        {
+        const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+        iData = CData::NewL(TVirtualPathPtr(fileSource.Name(), fileSource.UniqueId()),
+            EContentShareReadWrite);
+        }
+    
+    if (aSource.SourceType()==KUidMMFileHandleSource)
+        {
+        const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+        iData = CData::NewL(fileHandleSource.Handle(), fileHandleSource.UniqueId());
+        }
+    
+    TInt err = iData->SetProperty(EAgentPropertyAgentUI, aSource.IsUIEnabled());
+    
+    if (err != KErrNone && err != KErrCANotSupported)
+        {
+        // KErrCANotSupported isn't a problem for us so eat the error code.
+        User::Leave(err);
+        }
+    
+    err = iData->EvaluateIntent(aSource.Intent());
+    User::LeaveIfError(err);
+    }
+	else
+		{
+		// Use RMMFDRMPluginServerProxy as medium
+		iDrmPluginServer = new (ELeave) RMMFDRMPluginServerProxy;
+		User::LeaveIfError(iDrmPluginServer->Open()); 
+		
+		CBufFlat* dataBuffer = CBufFlat::NewL(KExpandSize);
+		CleanupStack::PushL(dataBuffer);
+		RBufWriteStream stream;
+		stream.Open(*dataBuffer);
+		CleanupClosePushL(stream);
+		
+		stream.WriteInt32L(aSource.UniqueId().Length());
+		stream.WriteL(aSource.UniqueId());
+		stream.WriteInt32L(aSource.IsUIEnabled());
+		TPckgBuf<ContentAccess::TIntent> intentPckg(aSource.Intent());
+		stream.WriteL(intentPckg);
+		stream.CommitL();
+	
+		CleanupStack::PopAndDestroy(&stream);
+		if (aSource.SourceType()==KUidMMFileSource)
+			{
+			const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+			iDrmPluginServer->OpenDataContentL(fileSource.Name(), dataBuffer->Ptr(0)); 
+			}
+		if (aSource.SourceType()==KUidMMFileHandleSource)
+			{
+			const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+			iDrmPluginServer->OpenDataContentL(fileHandleSource.Handle(), dataBuffer->Ptr(0)); 
+			}
+		CleanupStack::PopAndDestroy(dataBuffer);
+		}
+	}
+
+TInt CMMFUtilityFileInfo::EvaluateIntent(TIntent aIntent)
+    {
+	if (iData)
+		{
+        return iData->EvaluateIntent(aIntent);
+        }
+	else
+		{
+		ASSERT(iDrmPluginServer); 
+		return iDrmPluginServer->EvaluateDataContentIntent(aIntent); 
+		}
+	}
+    /**
+    * @internalComponent
+*/
+TBool CMMFUtilityFileInfo::GetFileMimeTypeL(TDes8& aMimeType)
+    {
+	if (iData)
+		{
+		return iData->GetMimeTypeL(aMimeType);
+		}
+	else
+		{
+		ASSERT(iDrmPluginServer);
+		return iDrmPluginServer->GetDataContentMimeTypeL(aMimeType); 
+		}
+	}
+
+    /**
+    * @internalComponent
+*/
+void CMMFUtilityFileInfo::GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength)
+	{
+	if (iData)
+		{
+		TInt size = 0;
+		iData->DataSizeL(size);
+		if (size > 0)
+			{
+			if (size > aMaxLength) 
+				size = aMaxLength;
+			TInt pos = 0;
+			User::LeaveIfError(iData->Seek(ESeekStart, pos));
+			User::LeaveIfError(iData->Read(aHeaderData, size));
+			}
+		}
+	else
+		{
+		ASSERT(iDrmPluginServer); 
+		iDrmPluginServer->GetDataContentFileHeaderL(aHeaderData, aMaxLength); 
+		}
+	}
+
+    /**
+    * @internalComponent
+*/
+HBufC8* CMMFClientUtility::GetFileExtensionL(const TDesC& aFileName)
+    {
+    TParse fileName;
+    fileName.Set(aFileName,NULL,NULL);
+    HBufC8* fileSuffix = NULL;
+    if(fileName.ExtPresent())
+        {
+        TPtrC fileSuffixPtr(fileName.Ext());
+        fileSuffix = HBufC8::NewL(fileSuffixPtr.Length());
+        fileSuffix->Des().Copy(fileSuffixPtr);
+        }
+    else
+        {
+        fileSuffix = KNullDesC8().AllocL();
+        }
+    return fileSuffix;
+    }
+
+
+    /**
+    * @internalComponent
+*/
+CMMFUtilityFileInfo::~CMMFUtilityFileInfo()
+    {
+	if (iData)
+		{
+		delete iData;
+		}
+	if (iDrmPluginServer)
+		{
+		iDrmPluginServer->Close(); 
+		delete iDrmPluginServer; 
+		}
+	}
+
+    /*
+    * @internalComponent
+    *
+    * Returns an integer rating indicating how well the supplied format matches
+    * the header data and file extension supplied.
+    * 3 brownie points awarded for data & suffix match.
+    * 2 brownie points awarded for data match alone.
+    * 1 brownie point awarded for suffix match alone.
+*/
+TInt CMMFClientUtility::GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension)
+    {
+    TInt browniePoints = 0;
+    
+    if (aHeaderData.Length() > 0) // Non empty file
+        {
+        if (aFileExtension.Length() > 0) // With a file extension
+            {
+            if (format->SupportsHeaderDataL(aHeaderData) &&
+                format->SupportsFileExtension(aFileExtension))
+                {
+                browniePoints = 3;
+                }
+            else if (format->SupportsHeaderDataL(aHeaderData))
+                {
+                browniePoints = 2;
+                }
+            else
+                {
+                // See if this format has any 'empty' match data or no match data, indicating
+                // that this format will match extension alone even if data present.
+                // (A format may have more than one match data string.)
+                const CDesC8Array& supportedHeaderData = format->SupportedHeaderData();
+                
+                if (supportedHeaderData.Count() == 0)
+                    {
+                    // No header data indicated.
+                    if (format->SupportsFileExtension(aFileExtension))
+                        {
+                        browniePoints = 1;
+                        }
+                    }
+                else
+                    {
+                    for (register TInt i = 0; i < supportedHeaderData.Count(); i++)
+                        {
+                        if (/*(supportedHeaderData[i].Length() == 0) &&*/  //Shubham
+                            format->SupportsFileExtension(aFileExtension))
+                            {
+                            browniePoints = 1;
+                            }
+                        }
+                    }
+                }
+            }
+        else
+            {
+            // No file suffix, so must match header data alone.
+            if (format->SupportsHeaderDataL(aHeaderData))
+                {
+                browniePoints = 2;
+                }
+            }
+        }
+    else // Empty File
+        {
+        // We have no choice but to match extension, if there is one.
+        if ((aFileExtension.Length() > 0) && format->SupportsFileExtension(aFileExtension))
+            {
+            browniePoints = 1;
+            }
+        }
+    
+    return browniePoints;
+    }
+
+    /**
+    * @internalComponent
+    *
+    * This function parses all the play & record formats in the given list of controllers,
+    * looking for controllers & formats that best match the requirements.
+    * Play controllers will be returned before record controllers, and
+    * in cases of equal priority between formats, ECom order will be maintained.
+    *
+    * @param   "aControllers"
+    *          A reference to a user supplied list of controllers retrieved from ECom.
+    *          This list may be have been filtered for audio/video/play/record.
+    * @param   "aHeaderDataPlayback"
+    *          A descriptor reference containing the file's header data.
+    *          for matching against a controller's play formats. May be KNullDesC8
+    * @param   "aFileExtensionPlayback"
+    *          A descriptor reference containing the filename's extension.
+    *          for matching against a controller's play formats. May be KNullDesC8
+    * @param   "aHeaderDataRecord"
+    *          A descriptor reference containing the file's header data.
+    *          for matching against a controller's record formats. May be KNullDesC8
+    * @param   "aFileExtensionRecord"
+    *          A descriptor reference containing the filename's extension.
+    *          for matching against a controller's record formats. May be KNullDesC8
+    * @param   "aPrioritisedControllers"
+    *          A reference to a user supplied list through which the list of
+    *          prioritised controllers will be returned.
+    * @since   7.0s
+    * @lib "MediaClientUtility.lib"
+*/
+void CMMFClientUtility::PrioritiseControllersL(
+                                               const RMMFControllerImplInfoArray& aControllers,
+                                               const TDesC8& aHeaderDataPlayback,
+                                               const TDesC8& aFileExtensionPlayback,
+                                               const TDesC8& aHeaderDataRecord,
+                                               const TDesC8& aFileExtensionRecord,
+                                               RMMFControllerImplInfoArray& prioritisedControllers)
+    {
+    RMMFControllerImplInfoArray fullMatchControllers; // data AND suffix
+    CleanupClosePushL(fullMatchControllers);
+    RMMFControllerImplInfoArray partMatchControllers; // data OR suffix
+    CleanupClosePushL(partMatchControllers);
+    
+    TBool checkingPlaybackFormats = EFalse;
+    TBool checkingRecordFormats = EFalse;
+    
+    if (aHeaderDataPlayback != KNullDesC8 || aFileExtensionPlayback != KNullDesC8)
+        checkingPlaybackFormats = ETrue;
+    if (aHeaderDataRecord != KNullDesC8 || aFileExtensionRecord != KNullDesC8)
+        checkingRecordFormats = ETrue;
+    
+    // Examine each format for each controller. We only want to know at this stage
+    // if the controller has suitable formats, so as soon as we know it has, we can
+    // add it to out list, ranked by how well it matched.
+    for (register TInt i = 0; i < aControllers.Count(); i++)
+        {
+        const CMMFControllerImplementationInformation* controller = aControllers[i];
+        TInt savedBrowniePointsPlayback = 0;
+        TInt savedBrowniePointsRecord = 0;
+        
+        if (checkingPlaybackFormats)
+            {
+            for (register TInt p = 0; p < controller->PlayFormats().Count(); p++)
+                {
+                const CMMFFormatImplementationInformation* format = controller->PlayFormats()[p];
+                
+                TInt browniePoints = GetBestMatchL(format, aHeaderDataPlayback, aFileExtensionPlayback);
+                
+                if (browniePoints >= savedBrowniePointsPlayback)
+                    savedBrowniePointsPlayback = browniePoints;
+                }
+            }
+        
+        if (checkingRecordFormats)
+            {
+            for (register TInt r = 0; r < controller->RecordFormats().Count(); r++)
+                {
+                const CMMFFormatImplementationInformation* format = controller->RecordFormats()[r];
+                
+                TInt browniePoints = GetBestMatchL(format, aHeaderDataRecord, aFileExtensionRecord);
+                
+                if (browniePoints >= savedBrowniePointsRecord)
+                    savedBrowniePointsRecord = browniePoints;
+                }
+            }
+        
+        TInt savedBrowniePoints = 0;
+        // if we're checking both playback & record formats
+        // make sure we've found both
+        if (checkingPlaybackFormats && checkingRecordFormats)
+            {
+            savedBrowniePoints = Min(savedBrowniePointsPlayback, savedBrowniePointsRecord);
+            }
+        else if (checkingPlaybackFormats)
+            {
+            savedBrowniePoints = savedBrowniePointsPlayback;
+            }
+        else if (checkingRecordFormats)
+            {
+            savedBrowniePoints = savedBrowniePointsRecord;
+            }
+        
+        // Checked all formats for this controller, now count our brownie points.
+        switch (savedBrowniePoints)
+            {
+            case 3:
+                User::LeaveIfError(fullMatchControllers.Append(controller));
+                break;
+            case 2:
+                User::LeaveIfError(partMatchControllers.Insert(controller, 0));
+                break;
+            case 1:
+                User::LeaveIfError(partMatchControllers.Append(controller));
+                break;
+            default:
+                break;
+            }
+        }
+    
+    // The better the controller matches, the earlier it will be in the final list.
+    for (register TInt x = 0; x < fullMatchControllers.Count(); x++)
+        {
+        if (prioritisedControllers.Find(fullMatchControllers[x]) == KErrNotFound)
+            {
+            User::LeaveIfError(prioritisedControllers.Append(fullMatchControllers[x]));
+            }
+        }
+    
+    for (register TInt y = 0; y < partMatchControllers.Count(); y++)
+        {
+        if (prioritisedControllers.Find(partMatchControllers[y]) == KErrNotFound)
+            {
+            User::LeaveIfError(prioritisedControllers.Append(partMatchControllers[y]));
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(2, &fullMatchControllers); // fullMatchControllers, partMatchControllers
+    }
+    
+/**
+* @internalComponent
+*/
+CMMFMdaObjectStateChangeObserverCallback* CMMFMdaObjectStateChangeObserverCallback::NewL(MMdaObjectStateChangeObserver& aCallback)
+    {
+    return new(ELeave) CMMFMdaObjectStateChangeObserverCallback(aCallback);
+    }
+    
+    /**
+    * @internalComponent
+*/
+CMMFMdaObjectStateChangeObserverCallback::~CMMFMdaObjectStateChangeObserverCallback()
+    {
+    Cancel();
+    }
+    
+    /**
+    * @internalComponent
+*/
+void CMMFMdaObjectStateChangeObserverCallback::CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
+    {
+    iObject = aObject;
+    iPreviousState = aPreviousState;
+    iCurrentState = aCurrentState;
+    iErrorCode = aErrorCode;
+    if (!IsActive())
+        {
+        TRequestStatus* s = &iStatus;
+        SetActive();
+        User::RequestComplete(s, KErrNone);
+        }
+    }
+    
+CMMFMdaObjectStateChangeObserverCallback::CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback) :
+    CActive(CActive::EPriorityHigh),
+        iCallback(aCallback)
+        {
+        CActiveScheduler::Add(this);
+        }
+    
+void CMMFMdaObjectStateChangeObserverCallback::RunL()
+    {
+    iCallback.MoscoStateChangeEvent(iObject, iPreviousState, iCurrentState, iErrorCode);
+    }
+
+void CMMFMdaObjectStateChangeObserverCallback::DoCancel()
+    {
+    //nothing to cancel
+    }
+        
+        
+        //****************************************
+        // CMMFFindAndOpenController
+        //****************************************
+        
+        /**
+        * Factory function to create a CMMFFindAndOpenController class
+        *
+        * @internalComponent
+        */
+CMMFFindAndOpenController* CMMFFindAndOpenController::NewL(MMMFFindAndOpenControllerObserver& aObserver)
+    {
+    CMMFFindAndOpenController* self = new(ELeave) CMMFFindAndOpenController(aObserver);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CMMFFindAndOpenController::~CMMFFindAndOpenController()
+    {
+    Cancel();
+    
+    // delete temporary variables
+    Close();
+    
+    // this should cancel the AO
+    delete iAddDataSourceSinkAsync;
+    
+    delete iPrimaryConfig;
+    delete iSecondaryConfig;
+    }
+        
+            /**
+            * Function to free up memory after a successful open has completed
+            * Useful to allow a alloc testing to work.
+            * Must not be called if ReOpen() is to be called
+            *
+            * @internalComponent
+        */
+void CMMFFindAndOpenController::Close()
+    {
+    
+    Cancel();
+    
+    if(iAddDataSourceSinkAsync)
+        {
+        iAddDataSourceSinkAsync->Cancel();
+        }
+    
+    if (iPrimaryConfig)
+        iPrimaryConfig->Close();
+    if (iSecondaryConfig)
+        iSecondaryConfig->Close();
+    
+    iPrioritisedControllers.Close();
+    iControllers.ResetAndDestroy();
+    iControllers.Close();
+    
+    iFileName.SetLength(0);
+    iFileNameSecondary.SetLength(0);
+    
+    delete iUrl;
+    iUrl = NULL;
+    
+    delete iMimeType;
+    iMimeType = NULL;
+	delete iUniqueId;
+	iUniqueId = NULL;
+    
+	if (iOwnFileHandle)
+		{
+		iFileHandle.Close();
+		iOwnFileHandle = EFalse;	
+		}
+	}
+/**
+ * Function to free up memory of which is not required in ReOpen()
+ * after a successful open has completed
+ * Useful to allow a alloc testing to work.
+ *
+ * @internalComponent
+ */
+
+void CMMFFindAndOpenController::CloseConfig()
+	{
+	Cancel();
+	if(iAddDataSourceSinkAsync)
+		{
+		iAddDataSourceSinkAsync->Cancel();
+		}
+	
+	if (iSecondaryConfig)
+		{
+		iSecondaryConfig->Close();
+		}
+	
+	iPrioritisedControllers.Close();
+	iControllers.ResetAndDestroy();
+	iControllers.Close();
+	
+	iFileName.SetLength(0);
+	iFileNameSecondary.SetLength(0);
+
+	delete iUrl;
+	iUrl = NULL;
+	
+	delete iMimeType;
+	iMimeType = NULL;
+	
+	delete iUniqueId;
+	iUniqueId = NULL;
+
+	if (iOwnFileHandle)
+		{
+		iFileHandle.Close();
+		iOwnFileHandle = EFalse;		
+		}
+	}
+
+CMMFFindAndOpenController::CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver) :
+    CActive(EPriorityStandard),
+        iObserver(aObserver),
+        iDescriptor(NULL, 0)
+        {
+        CActiveScheduler::Add(this);
+        }
+            
+void CMMFFindAndOpenController::ConstructL()
+    {
+    iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
+    iPrimaryConfig = new (ELeave)  CConfig();
+    iSecondaryConfig =  new (ELeave) CConfig;
+    iCurrentConfig =  iPrimaryConfig;
+	RProcess thisProcess;
+	iHasDrmCapability = thisProcess.HasCapability(ECapabilityDRM, KSuppressPlatSecDiagnostic);
+	thisProcess.Close();
+    }
+
+void CMMFFindAndOpenController::RunL()
+    {
+    Process();
+    }
+
+void CMMFFindAndOpenController::DoCancel()
+    {
+    iAddDataSourceSinkAsync->Cancel();
+    }
+            
+                /**
+                * Defines the media ID & priority to be used when opening a controller
+                * Normally called once only after class has been constructed
+                *
+                * @param   aMediaId
+                *          the media ID to use when searching for a controller
+                *          e.g. KUidMediaTypeAudio
+                * @param   aPrioritySettings
+                *          the priority settings to use when opening a controller
+                * @param   aMediaIdMatchType
+                *          Defines the type of media id match to be performed on the plugins
+                *          returned from the ECOM registry.
+                * @leave   can leave with KErrNoMemory
+                
+                  * @internalComponent
+            */
+void CMMFFindAndOpenController::Configure(
+    TUid aMediaId,
+    TMMFPrioritySettings aPrioritySettings,
+    CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType)
+    {
+    iPrioritySettings = aPrioritySettings;
+    
+    iMediaIdMatchType = aMediaIdMatchType;
+    
+    iMediaId = aMediaId;
+    }
+
+void CMMFFindAndOpenController::ConfigureController(
+    CConfig& config,
+    RMMFController& aController,
+    CMMFControllerEventMonitor& aEventMonitor,
+    TControllerMode aControllerMode)
+    {
+    config.iController = &aController;
+    config.iEventMonitor = &aEventMonitor;
+    config.iControllerMode = aControllerMode;
+    }
+
+                /**
+                * Configures the primary controller
+                *
+                * @param   aController
+                *          a reference to the client controller object to use
+                * @param   aEventMonitor
+                *          a reference to an event monitor object for receiving
+                *          events from the controller
+                * @param   aControllerMode
+                *          indicates whether this controller is to be used for recording
+                *          or playback
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::ConfigureController(
+    RMMFController& aController,
+    CMMFControllerEventMonitor& aEventMonitor,
+    TControllerMode aControllerMode)
+    {
+    ConfigureController(
+        *iPrimaryConfig,
+        aController,
+        aEventMonitor,
+        aControllerMode);
+    }
+            
+                /**
+                * Configures the secondary controller
+                *
+                * This is only needed for the audio recorder utility which opens
+                * one controller for playback and another for recording
+                *
+                * @param   aController
+                *          a reference to the client controller object to use
+                * @param   aEventMonitor
+                *          a reference to an event monitor object for receiving
+                *          events from the controller
+                * @param   aControllerMode
+                *          indicates whether this controller is to be used for recording
+                *          or playback or converting
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::ConfigureSecondaryController(
+    RMMFController& aController,
+    CMMFControllerEventMonitor& aEventMonitor,
+    TControllerMode aControllerMode)
+    {
+    ConfigureController(
+        *iSecondaryConfig,
+        aController,
+        aEventMonitor,
+        aControllerMode);
+    }
+            
+                /**
+                * Makes any controllers that are opened subsequently share a single heap.
+                *
+                * The default behaviour is that each controller is created with its own heap.
+                * Each heap uses a chunk, so using this function avoids situations where the number
+                * of chunks per process is limited.
+                * The default behaviour is generally to be preferred, and should give lower overall
+                * memory usage. However, if many controllers are to be created for a particular thread,
+                * then this function should be used to prevent running out of heaps or chunks.
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::UseSharedHeap()
+    {
+    iUseSharedHeap = ETrue;
+    }
+
+void CMMFFindAndOpenController::Init()
+    {
+    // This should be called prior to opening, so reset the error
+    iError = KErrNone;
+    iSourceSinkConfigured = EFalse;
+    iControllerCount = 0;
+    }
+
+void CMMFFindAndOpenController::ConfigureSourceSink(
+    CConfig& config,
+    TSourceSink aSource,
+    TSourceSink aSink)
+    {
+    TInt err;
+    TRAP(err, config.iSource = CreateSourceSinkL(aSource));
+    if (err != KErrNone)
+        {
+        iError = err;
+        return;
+        }
+    
+    TRAP(err, config.iSink = CreateSourceSinkL(aSink));
+    if (err != KErrNone)
+        {
+        iError = err;
+        return;
+        }
+    }
+
+
+void CMMFFindAndOpenController::ConfigureSourceSink(
+    CConfig& config,
+    const TMMSource& aSource,
+    TSourceSink aSink)
+    {
+    TInt err;
+    TRAP(err, config.iSource = CreateSourceSinkL(aSource));
+    if (err != KErrNone)
+        {
+        iError = err;
+        return;
+        }
+    
+    TRAP(err, config.iSink = CreateSourceSinkL(aSink));
+    if (err != KErrNone)
+        {
+        iError = err;
+        return;
+        }
+    }
+            
+            
+            
+                /**
+                * Configure the primary controller's source and sink
+                * The descriptors passed to this function are copied so they do not need to be persistent.
+                * To simplify the API, any errors that occur are reported back asynchronously following
+                * a subsequent call to OpenByXXX()
+                *
+                * @param   aSourceUid
+                *          the UID of the data source
+                * @param   aSourceData
+                *          a reference to a descriptor used to configure the source
+                * @param   aSinkUid
+                *          the UID of the data sink
+                * @param   aSinkData
+                *          a reference to a descriptor used to configure the sink
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::ConfigureSourceSink(
+    TSourceSink aSource,
+    TSourceSink aSink)
+    {
+    
+    CConfig* config = NULL;
+    
+    Init();
+    config = iPrimaryConfig;
+    
+    
+    // must have already called ConfigureController()
+    __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    ConfigureSourceSink(
+        *config,
+        aSource,
+        aSink);
+    iCurrentConfig = config;
+    
+    iSourceSinkConfigured = ETrue;
+    }
+            
+            
+                /**
+                * Configure the primary controller's source and sink
+                * The descriptors passed to this function are copied so they do not need to be persistent.
+                * To simplify the API, any errors that occur are reported back asynchronously following
+                * a subsequent call to OpenByXXX()
+                *
+                * @param   aSourceUid
+                *          the UID of the data source
+                * @param   aSourceData
+                *          a reference to a descriptor used to configure the source
+                * @param   aSinkUid
+                *          the UID of the data sink
+                * @param   aSinkData
+                *          a reference to a descriptor used to configure the sink
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::ConfigureSecondarySourceSink(
+    TSourceSink aSource,
+    TSourceSink aSink)
+    {
+    if (iError != KErrNone)
+        {
+        // if there was an error configuring the primary source/sink, do not try the secondary one
+        // Don't return the error, since the stored error will be returned by the OpenBy... method
+        return;
+        }
+    
+    CConfig* config = NULL;
+    
+    config = iSecondaryConfig;
+    
+    // must have already configured the primary controller
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    config = iSecondaryConfig;
+    
+    // must have already called ConfigureController()
+    __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    ConfigureSourceSink(
+        *config,
+        aSource,
+        aSink);
+    iCurrentConfig = config;
+    
+    iSourceSinkConfigured = ETrue;
+    }
+
+
+            
+void CMMFFindAndOpenController::ConfigureSourceSink(
+    const TMMSource& aSource,
+    TSourceSink aSink)
+    {
+    Init();
+    CConfig* config = iPrimaryConfig;
+    
+    // must have already called ConfigureController()
+    __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    ConfigureSourceSink(
+        *config,
+        aSource,
+        aSink);
+    iCurrentConfig = config;
+    
+    iSourceSinkConfigured = ETrue;
+    }
+
+            
+            
+                /**
+                * Opens a controller using the supplied controller UID
+                * and adds the source & sink
+                * Completion is indicated asynchonously by a call to MfaocComplete()
+                *
+                * @param   aControllerUid
+                *          the UID of the primary controller
+                * @param   aControllerUid
+                *          the UID of the secondary controller
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::OpenByControllerUid(
+    TUid aControllerUid,
+    TUid aSecondaryControllerUid)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+
+	if (iCurrentConfig == iPrimaryConfig)
+		{
+		// only do this for the playback controller
+		TRAP(iError, iCurrentConfig->iSource->EvaluateIntentL())
+		
+		if (iError != KErrNone && 
+			!(iCurrentConfig->iControllerMode == EPlayback && iError == KErrPermissionDenied && !iHasDrmCapability))
+			{
+			// KErrPermissionDenied error and no DRM capability are not problems in Playback mode
+			// proper action will be performed when controller is loaded
+	    	SchedSendError();
+			return;
+			}
+		}
+    iPrimaryConfig->iControllerUid = aControllerUid;
+    if (iCurrentConfig == iSecondaryConfig)
+        {
+        if (aSecondaryControllerUid == KNullUid)
+            iSecondaryConfig->iControllerUid = aControllerUid;
+        else
+            iSecondaryConfig->iControllerUid = aSecondaryControllerUid;
+        }
+    
+    iMode = EOpenByControllerUid;
+    iControllerImplInfo = NULL;
+    iState = EOpenController;
+    KickState();
+    }
+            
+                /**
+                * Opens a controller using the supplied file name
+                * and adds the source & sink
+                * A copy is made of the filename or file handle so that it need not be persistent
+                * Completion is indicated asynchonously by a call to MfaocComplete()
+                *
+                * @param   aSource
+                *          a reference to a TFileSource object to be used when searching
+                *          for a controller
+                * @param   aFileNameSecondary
+                *          a reference to the seconday filename to be used when searching
+                *          for a controller. This need only be supplied when converting
+                *          between two files.
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::OpenByFileSource(const TMMSource& aSource, const TDesC& aFileNameSecondary)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    TInt err;
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+	if (iOwnFileHandle)
+		{
+		// in case of error
+		iFileHandle.Close();
+		iOwnFileHandle = EFalse;
+		}
+    iEnableUi = aSource.IsUIEnabled();
+    if (aSource.SourceType()==KUidMMFileSource)
+        {
+        const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+        iFileName = fileSource.Name();
+		iUseFileHandle = EFalse;
+        }
+    
+    if (aSource.SourceType()==KUidMMFileHandleSource)
+        {
+        const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+		ASSERT(iFileHandle.SubSessionHandle()==0); // closed just above
+        err = iFileHandle.Duplicate(fileHandleSource.Handle());
+        if (err != KErrNone)
+            {
+            SchedSendError(err);
+            return;
+            }
+        iFileHandle.Name(iFileName); //ignore error return since we'll just do without the filename if not available
+        iUseFileHandle = ETrue;
+		iOwnFileHandle = ETrue; // because we dup'd it
+        }
+    
+    TRAP(err, iUniqueId = aSource.UniqueId().AllocL());
+    iIntent = aSource.Intent();
+    if (err != KErrNone)
+        {
+        SchedSendError(err);
+        return;
+        }
+    
+    
+    // take a copy of the secondary file name
+    iFileNameSecondary = aFileNameSecondary;
+    
+    iMode = EOpenByFileName;
+    iState = EBuildControllerList;
+    KickState();
+    }
+
+                /**
+                * Opens a controller using the supplied format UID
+                * and adds the source & sink
+                * Completion is indicated asynchonously by a call to MfaocComplete()
+                *
+                * @param   aFormatUid
+                *          the UID of a format that must be supported by the controller
+                * @param   aFormatUidSecondary
+                *          the UID of a secondary format that must be supported by the controller
+                *          This need only be supplied when converting between two differnet formats.
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+    
+    iFormatUid = aFormatUid;
+    iFormatUidSecondary = aFormatUidSecondary;
+    
+    iMode = EOpenByFormatUid;
+    iState = EBuildControllerList;
+    KickState();
+    }
+            
+                /**
+                * Opens a controller using the supplied descriptor
+                * and adds the source & sink
+                * Completion is indicated asynchonously by a call to MfaocComplete()
+                *
+                * @param   aDescriptor
+                *          a reference to the descriptor to be used when searching
+                *          for a controller
+                *
+                * @internalComponent
+            */
+void  CMMFFindAndOpenController::OpenByDescriptor(const TDesC8& aDescriptor)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+    
+    // take a copy of the descriptor
+    TUint8* desBufferPtr = const_cast<TUint8*> (aDescriptor.Ptr());
+    iDescriptor.Set( desBufferPtr,aDescriptor.Length(),aDescriptor.Length());
+    
+    iMode = EOpenByDescriptor;
+    iState = EBuildControllerList;
+    KickState();
+    }
+            
+                /**
+                * Opens a controller using the supplied URL
+                * and adds the source & sink
+                * Completion is indicated asynchonously by a call to MfaocComplete()
+                *
+                * @param   aUrl
+                *          a reference to the URL to be used when searching for a controller
+                * @param   aIapId
+                *          the IAP ID to be used when searching for a controller
+                * @param   aMimeType
+                *          the MIME type of the data to be used when searching for a controller
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+    
+    // take a copy of the Url
+    delete iUrl;
+    iUrl = NULL;
+    iUrl = aUrl.Alloc();
+    if (iUrl == NULL)
+        {
+        SchedSendError(KErrNoMemory);
+        return;
+        }
+    
+    // take a copy of the IapId
+    iIapId = aIapId;
+    
+    // take a copy of the mime type
+    delete iMimeType;
+    iMimeType = NULL;
+    iMimeType = aMimeType.Alloc();
+    if (iMimeType == NULL)
+        {
+        SchedSendError(KErrNoMemory);
+        return;
+        }
+    
+    iMode = EOpenByUrl;
+    iState = EBuildControllerList;
+    KickState();
+    }
+            
+            
+void CMMFFindAndOpenController::OpenByMimeType(const TDesC8& aMimeType)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        SchedSendError();
+        return;
+        }
+    
+    // take a copy of the mime type
+    delete iMimeType;
+    iMimeType = NULL;
+    iMimeType = aMimeType.Alloc();
+    if (iMimeType == NULL)
+        {
+        SchedSendError(KErrNoMemory);
+        return;
+        }
+    
+    iMode = EOpenByMimeType;
+    iState = EBuildControllerList;
+    KickState();
+    }
+
+void CMMFFindAndOpenController::FindByMimeTypeL(const TDesC8& aMimeType)
+    {
+    // must have already called ConfigureSourceSink()
+    __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+    
+    // Have there been any errors so far ?
+    if (iError != KErrNone)
+        {
+        User::Leave(iError);
+        }
+    
+    // take a copy of the mime type
+    delete iMimeType;
+    iMimeType = NULL;
+    iMimeType = aMimeType.Alloc();
+    if (iMimeType == NULL)
+        {
+        User::Leave(KErrNoMemory);
+        }
+    
+    BuildControllerListMimeTypeL();
+    
+    }
+            
+                /**
+                * Static function to return a TMMFFileConfig object
+                * suitable for passing to ConfigureSourceSink()
+                *
+                * @param   aFileName
+                *          the filename to use
+                *
+                * @internalComponent
+            */
+TMMFFileConfig CMMFFindAndOpenController::GetConfigFile(const TDesC& aFileName)
+    {
+    TMMFFileConfig sourceSinkData;
+    sourceSinkData().iPath = aFileName;
+    return sourceSinkData;
+    }
+
+                /**
+                * Static function to return a TMMFDescriptorConfig object
+                * suitable for passing to ConfigureSourceSink()
+                *
+                * @param   aFileName
+                *          the filename to use
+                *
+                * @internalComponent
+            */
+TMMFDescriptorConfig CMMFFindAndOpenController::GetConfigDescriptor(const TDesC8& aDescriptor)
+    {
+    TMMFDescriptorConfig sourceSinkData;
+    sourceSinkData().iDes = (TAny*)&aDescriptor;
+    sourceSinkData().iDesThreadId = RThread().Id();
+    return sourceSinkData;
+    }
+            
+                /**
+                * Static function to create a CBufFlat object
+                * suitable for passing to ConfigureSourceSink()
+                *
+                * @param   aUrlCfgBuffer
+                *          the reference to a caller-supplied pointer used to create
+                *          a CBufFlat object. The caller is responsible for deletion.
+                * @param   aUrl
+                *          a reference to the URL to be used
+                * @param   aIapId
+                *          the IAP ID to be used
+                * @return  can return KErrNone or KErrNoMemory
+                *
+                * @internalComponent
+            */
+TInt CMMFFindAndOpenController::GetConfigUrl(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId)
+    {
+    TInt error;
+    delete aUrlCfgBuffer;
+    aUrlCfgBuffer = NULL;
+    
+    CMMFUrlParams* urlCfg = NULL;
+    TRAP(error, urlCfg = CMMFUrlParams::NewL(aUrl,aIapId));
+    if (error != KErrNone)
+        return error;
+    
+    TRAP(error,
+        aUrlCfgBuffer = urlCfg->ExternalizeToCBufFlatLC();
+    CleanupStack::Pop(aUrlCfgBuffer);
+    );
+    
+    delete urlCfg;
+    
+    return error;
+    }
+            
+                /**
+                * ReOpens the previously opened primary controller
+                *
+                * @internalComponent
+            */
+void CMMFFindAndOpenController::ReOpen()
+    {
+    // should already have a valid controller uid so just open it
+    iControllerImplInfo = NULL;
+    iState = EOpenController;
+    KickState();
+    }
+            
+void CMMFFindAndOpenController::OpenPrimaryController(void)
+    {
+    iCurrentConfig = iPrimaryConfig;
+    switch(iMode)
+        {
+        case EOpenByFileName:
+        case EOpenByFormatUid:
+        case EOpenByDescriptor:
+        case EOpenByUrl:
+            iState = EBuildControllerList;
+            break;
+        case EOpenByControllerUid:
+            iControllerImplInfo = NULL;
+            iState = EOpenController;
+            break;
+        }
+    KickState();
+    }
+
+void CMMFFindAndOpenController::KickState()
+    {
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status, KErrNone);
+    }
+
+void CMMFFindAndOpenController::CloseController()
+    {
+    if (iCurrentConfig->iEventMonitor)
+        iCurrentConfig->iEventMonitor->Cancel();
+    iCurrentConfig->iController->Close();
+    }
+
+void CMMFFindAndOpenController::Process()
+    {
+    switch(iState)
+        {
+        case EBuildControllerList:
+            switch(iMode)
+                {
+                case EOpenByFileName:
+                    TRAP(iError, BuildControllerListFileNameL());
+                    break;
+                case EOpenByDescriptor:
+                    TRAP(iError, BuildControllerListDescriptorL());
+                    break;
+                case EOpenByUrl:
+                    TRAP(iError, BuildControllerListUrlL());
+                    break;
+                case EOpenByFormatUid:
+                    TRAP(iError, BuildControllerListFormatL());
+                    break;
+                case EOpenByMimeType:
+                    TRAP(iError, BuildControllerListMimeTypeL());
+                    break;
+                default:
+                    CUPanic(EMMFMediaClientUtilityBadState);
+                }
+            
+            if (iError != KErrNone)
+                {
+                iState = EIdle;
+                SendError();
+                break;
+                }
+            
+            // try the first controller
+            iControllerIndex = -1;
+            TryNextController();
+            break;
+            
+        case EOpenController:
+            {
+            // Make sure any existing controller is closed.
+            CloseController();
+            TBool isSecureDrmProcess = EFalse;// need to keep it false as UseSecureDRMProcess may return error
+			// Loading controller in new threading model is enabled only in playback mode
+			TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
+           TRAPD(err,UseSecureDRMProcessL(isSecureDrmProcess));
+           //we'll never get err == KErrPermisionDenied, as it being handled inside UseSecureDRMProcessL
+           //but for other fatal errors we need to TRAP as Process is non-Leaving function. 
+           if(err != KErrNone)
+                {
+                iError = err;
+                SendError(err);
+                break;
+                }
+            // Open the controller
+            if (iControllerImplInfo)
+                {
+				if(isSecureDrmProcess)
+					{
+					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
+					iUsingSecureDrmProcess = ETrue;
+					}
+				else
+					{
+					iError = iCurrentConfig->iController->Open(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
+					iUsingSecureDrmProcess = EFalse;
+					}
+				}
+			else
+				{
+				if(isSecureDrmProcess)
+					{
+					iError = iCurrentConfig->iController->OpenInSecureDRMProcess(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
+					iUsingSecureDrmProcess = ETrue;
+	
+					}
+				else
+					{
+					iError = iCurrentConfig->iController->Open(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
+					iUsingSecureDrmProcess = EFalse;
+					}
+				}
+            
+            if (iError)
+                {
+                TryNextController();
+                }
+            else
+                {
+            	RStreamControlCustomCommands streamControlCustomCommands(*iCurrentConfig->iController);
+	            streamControlCustomCommands.EnableEvents(ETrue);
+                
+                iCurrentConfig->iEventMonitor->Start();
+                
+                if (iCurrentConfig == iSecondaryConfig)
+                    {
+                    iState = EAddSource;
+                    KickState();
+                    }
+                else
+                    {
+                    iState = EAddSink;
+                    KickState();
+                    }
+                }
+            }
+            break;
+                        
+        case EAddSource:
+            {
+            iState = EWaitingForSource;
+            const CMMSourceSink* source = iCurrentConfig->iSource;
+			// CMMSourceSink has the ability to transform the data it stored into a data stream
+			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
+			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
+			// source/sink. The info about the file can be a file path or a file handle.
+			// When it holds a file handle and turns info into data stream, the file handle is
+			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
+			// the streamed info is always extracted within the same process. If the pointer is 
+			// dereferenced in other process, a panic will raise in the system. Therefore, a file
+			// handle, rather than pointer, is used when necessary.
+			const TDesC8& sourceData = source->SourceSinkData();
+			if (iUsingSecureDrmProcess && source->CarryingFileHandle())
+				{
+				iAddDataSourceSinkAsync->AddFileHandleDataSource(*iCurrentConfig->iController,
+																 static_cast<const CMMFileSourceSink*>(source)->FileHandle(),
+																 source->SourceSinkData());
+				}
+			else
+				{
+				iAddDataSourceSinkAsync->AddDataSource(*iCurrentConfig->iController, 
+													   source->SourceSinkUid(), 
+													   source->SourceSinkData());
+				}
+			}
+            break;
+            
+        case EAddSink:
+            {
+            iState = EWaitingForSink;
+			const CMMSourceSink* sink = iCurrentConfig->iSink;
+			// CMMSourceSink has the ability to transform the data it stored into a data stream
+			// which can be passed to CMMFAddDataSourceSinkAsync for further processing.
+			// CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
+			// source/sink. The info about the file can be a file path or a file handle.
+			// When it holds a file handle and turns info into data stream, the file handle is
+			// stored as a pointer in the stream. However, at this point, it cannot guarantee that
+			// the streamed info is always extracted within the same process. If the pointer is 
+			// dereferenced in other process, a panic will raise in the system. Therefore, a file
+			// handle, rather than pointer, is used when necessary.
+			const TDesC8& sinkData = sink->SourceSinkData();
+			if (iUsingSecureDrmProcess && sink->CarryingFileHandle())
+				{
+				iAddDataSourceSinkAsync->AddFileHandleDataSink(*iCurrentConfig->iController,
+															   static_cast<const CMMFileSourceSink*>(sink)->FileHandle(),
+															   sinkData);
+				}
+			else
+				{
+				iAddDataSourceSinkAsync->AddDataSink(*iCurrentConfig->iController, 
+													 sink->SourceSinkUid(), 
+													 sinkData);
+				}
+			}
+            break;
+            
+        case EWaitingForSource:
+            break;
+            
+        case EWaitingForSink:
+            break;
+            
+        case ESendError:
+            SendError();
+            iState = EIdle;
+            break;
+            
+        case EIdle:
+        default:
+            break;
+        }
+    }
+    
+void CMMFFindAndOpenController::TryNextController()
+    {
+    
+    // If an error occurred close the controller.
+    if (iError != KErrNone)
+        CloseController();
+    
+	iStopTryLoadController = EFalse;
+	
+	if (iMode == EOpenByControllerUid || ++iControllerIndex >= iControllerCount)
+		{
+		//Raise a flag to stop trying to load the controllers
+		iStopTryLoadController = ETrue;
+		
+		// KErrNotSupported is the default error, but will only be used if no other error 
+		// has been discovered (the first error found is used by default)
+		// However, KErrBadHandle seems to mean that we tried to use the DRM server without
+		// RFs::ShareProtected() having been called, so force usage of KErrNotSupported so
+		// client does not see changed 
+		TBool forceErrorUse = EFalse;
+		if (iError==KErrBadHandle)
+			{
+			forceErrorUse = ETrue;
+			}
+		SendError(KErrNotSupported, forceErrorUse);		
+        return;
+        }
+    
+    if (iMode == EOpenByFileName || iMode == EOpenByFormatUid)
+        {
+        iControllerImplInfo = iPrioritisedControllers[iControllerIndex];
+        }
+    else    //if (iMode == EOpenByDescriptor || iMode == EOpenByUrl)
+        {
+        iControllerImplInfo = iControllers[iControllerIndex];
+        }
+    
+    iCurrentConfig->iControllerUid = iControllerImplInfo->Uid();
+    iState = EOpenController;
+    KickState();
+    }
+    
+void CMMFFindAndOpenController::OpenController()
+    {
+    
+    iControllerIndex = -1;
+    TryNextController();
+    
+    }
+
+void CMMFFindAndOpenController::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
+    {
+    iError = aError;
+    
+    // take the first available exit if we're out of memory
+    // or we've been cancelled
+    if (iError == KErrNoMemory || iError == KErrCancel)
+        {
+        SendError();
+        return;
+        }
+    
+    // failed to add source or sink - try the next controller
+    if (aError != KErrNone)
+        {
+        TryNextController();
+        return;
+        }
+    
+    if (iState == EWaitingForSource)
+        {
+        iSourceHandle = aHandle;
+        if (iCurrentConfig == iSecondaryConfig)
+            {
+            iState = EAddSink;
+            }
+        else    // completed ok !
+            {
+            iState = EIdle;
+			SendError(KErrNone, ETrue);
+            return;
+            }
+        }
+    else if (iState == EWaitingForSink)
+        {
+        iSinkHandle = aHandle;
+        if (iCurrentConfig == iSecondaryConfig) // completed ok !
+            {
+            iState = EIdle;
+            iError = KErrNone;
+            SendError();
+            return;
+            }
+        else
+            {
+            iState = EAddSource;
+            }
+        }
+    
+    KickState();
+    }
+    
+void CMMFFindAndOpenController::SendError(TInt aError, TBool aOverrideError)
+	{
+	if (iError == KErrNone || aOverrideError)
+		{
+		iError = aError;		
+		}
+    
+    iObserver.MfaocComplete(iError, iCurrentConfig->iController, iCurrentConfig->iControllerUid, &iSourceHandle, &iSinkHandle);
+    
+    // if we've just attempted to open the Secondary controller,
+    // try to open the Primary controller
+    if (iCurrentConfig == iSecondaryConfig)
+        {
+        if (iError == KErrNone)
+            OpenPrimaryController();
+        }
+    
+    // if we failed to open, may as well free up some memory
+    // if open succeeded we need to preserve state in case of a re-open
+    if (iError != KErrNone)
+		{
+		if(iControllerIndex >= iControllerCount-1)
+			{
+			Close();
+			}
+		else //if there are other controllers selected in the controller list, try them
+			{
+			Cancel();
+			if(iAddDataSourceSinkAsync)
+				{
+				iAddDataSourceSinkAsync->Cancel();
+				}
+
+ 			TryNextController();
+			}
+		}
+	}
+void CMMFFindAndOpenController::SchedSendError(TInt aError)
+    {
+    if (aError != KErrNone)
+        iError = aError;
+    iState = ESendError;
+    KickState();
+    }
+    
+void CMMFFindAndOpenController::BuildControllerListFileNameL()
+    {
+    // Retrieve a list of possible controllers from ECOM
+    // If we don't have a match, leave with unsupported
+    
+    iControllers.ResetAndDestroy();
+    iPrioritisedControllers.Reset();
+    
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+    
+    // if we're playing, try to get the MIME type from the Content Access
+    // Framework (CAF) & use that to select a controller - if that fails,
+    // try to select a controller based on the header data/file extension
+    
+    CMMFUtilityFileInfo* fileInfo = NULL;
+    
+    TInt error;
+    
+    //If the current CMMSourceSink is a CMMFileSourceSink
+    // Using the previous version we'd get KErrCANoPermission when calling EvaluateIntent in the
+    // CMMFUtilityFileInfo ConstructL as the intent == EUnknown, so now pass the intent as a parameter
+    // to TMMFileHandleSource and....
+    TBool isSecureDrmProcess = EFalse;
+    //need to do this only in local playback mode
+    //UseSecureDRMProcess() function in called only in case of local play / record
+    // so we'll just chk for playback mode
+    if(mode == EPlayback)
+        {
+        UseSecureDRMProcessL(isSecureDrmProcess);
+        }
+	TRAP(error, fileInfo = CreateFileInfoL(isSecureDrmProcess));
+	
+    if (fileInfo != NULL)
+        {
+        CleanupDeletePushL(fileInfo);
+        }
+    
+    if (error != KErrNone)
+        {
+        // if playback mode, leave for any error
+        // if record mode, allow KErrNotFound
+        if (mode == EPlayback || (mode != EPlayback && error != KErrNotFound))
+            {
+            User::Leave(error);
+            }
+        }
+	CMMFControllerPluginSelectionParameters* cSelect = NULL;
+	if (isSecureDrmProcess)
+		{
+		cSelect = CMMFControllerSecureDrmPluginSelectionParameters::NewLC();
+		}
+	else
+		{
+		cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+		}
+    RArray<TUid> mediaIds;
+    CleanupClosePushL(mediaIds);
+    User::LeaveIfError(mediaIds.Append(iMediaId));
+    
+    cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+    
+        
+    if (mode == EPlayback)
+        {
+        ASSERT(fileInfo!=NULL);
+        TBuf8<KMaxMimeLength> mimeType;
+        TBool mimeTypeKnown = fileInfo->GetFileMimeTypeL(mimeType);
+        if (mimeTypeKnown)
+            {
+            CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+            fSelect->SetMatchToMimeTypeL(mimeType);
+            cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+            cSelect->ListImplementationsL(iControllers);
+            CleanupStack::PopAndDestroy(fSelect);
+            }
+        
+        
+        // copy to the iPrioritisedControllers array - this is a NOOP if the
+        // MIME type is not known since iControllers will be empty
+        ASSERT(mimeTypeKnown || iControllers.Count() == 0);
+        for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
+            User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
+        
+        iControllerCount = iPrioritisedControllers.Count();
+        if (iControllerCount > 0)
+            {
+            // Clean up
+            // cSelect, mediaIds,
+            CleanupStack::PopAndDestroy(2, cSelect);
+            if (fileInfo != NULL)
+                {
+                CleanupStack::PopAndDestroy(fileInfo);
+                }
+            return;
+            }
+        }
+        
+        // Retrieve header data first. If file doesn't exist, its ok.
+        HBufC8* headerData = HBufC8::NewLC(KMaxHeaderSize);
+        TPtr8 headerDataPtr = headerData->Des();
+        if (fileInfo)
+            {
+            fileInfo->GetFileHeaderDataL(headerDataPtr, KMaxHeaderSize);
+            }
+        
+        // Get the filename's suffix
+        HBufC8* fileSuffix = CMMFClientUtility::GetFileExtensionL(iFileName);
+        
+        CleanupStack::PushL(fileSuffix);
+        TPtr8 fileSuffixPtr = fileSuffix->Des();
+        
+        // Get the secondary filename's header data (for convert)
+        HBufC8* headerDataSecondary = HBufC8::NewLC(KMaxHeaderSize);
+        TPtr8 headerDataPtrSecondary = headerDataSecondary->Des();
+        if (iFileNameSecondary.Length() > 0 && fileInfo)
+            {
+            fileInfo->GetFileHeaderDataL(headerDataPtrSecondary, KMaxHeaderSize);
+            }
+        
+        // Get the secondary filename's suffix
+        HBufC8* fileSuffixSecondary = CMMFClientUtility::GetFileExtensionL(iFileNameSecondary);
+        CleanupStack::PushL(fileSuffixSecondary);
+        TPtr8 fileSuffixPtrSecondary = fileSuffixSecondary->Des();
+        
+        
+        CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+        
+        if (mode == EPlayback || mode == EConvert)
+            cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+        if (mode == ERecord || mode == EConvert)
+            cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+        
+        cSelect->ListImplementationsL(iControllers);
+        
+        if (iControllers.Count()==0)
+            User::Leave(KErrNotSupported);
+        
+        if (mode == ERecord)
+            {
+            CMMFClientUtility::PrioritiseControllersL(
+                iControllers,
+                headerDataPtrSecondary,
+                fileSuffixPtrSecondary,
+                headerDataPtr,
+                fileSuffixPtr,
+                iPrioritisedControllers);
+            }
+        else
+            {
+            CMMFClientUtility::PrioritiseControllersL(
+                iControllers,
+                headerDataPtr,
+                fileSuffixPtr,
+                headerDataPtrSecondary,
+                fileSuffixPtrSecondary,
+                iPrioritisedControllers);
+            }
+        
+        iControllerCount = iPrioritisedControllers.Count();
+        if (iControllerCount == 0)
+            User::Leave(KErrNotSupported);
+        
+        // Clean up
+        // cSelect, mediaIds,
+        // headerData, fileSuffix, headerDataSecondary, fileSuffixSecondary,
+        // fSelect
+        CleanupStack::PopAndDestroy(7, cSelect);
+        if (fileInfo != NULL)
+            {
+            CleanupStack::PopAndDestroy(fileInfo);
+            }
+    }
+    
+void CMMFFindAndOpenController::BuildControllerListDescriptorL()
+    {
+    // Retrieve a list of possible controllers from ECOM
+    // If we don't have a match, leave with unsupported
+    
+    iControllers.ResetAndDestroy();
+    
+    CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+    CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+    
+    
+    RArray<TUid> mediaIds;
+    CleanupClosePushL(mediaIds);
+    User::LeaveIfError(mediaIds.Append(iMediaId));
+    
+    cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+    
+    TPtrC8 header = iDescriptor.Left(KMaxHeaderSize);
+    fSelect->SetMatchToHeaderDataL(header);
+    
+    
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+    if (mode == EPlayback || mode == EConvert)
+        cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+    if (mode == ERecord || mode == EConvert)
+        cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+    
+    cSelect->ListImplementationsL(iControllers);
+    
+    iControllerCount = iControllers.Count();
+    if (iControllerCount == 0)
+        User::Leave(KErrNotSupported);
+    
+    // Clean up
+    // cSelect, fSelect, mediaIds
+    CleanupStack::PopAndDestroy(3, cSelect);
+    }
+    
+void CMMFFindAndOpenController::BuildControllerListUrlL()
+    {
+    // Retrieve a list of possible controllers from ECOM
+    // If we don't have a match, leave with unsupported
+    
+    iControllers.ResetAndDestroy();
+    
+    CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+    CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+    
+    RArray<TUid> mediaIds;
+    CleanupClosePushL(mediaIds);
+    User::LeaveIfError(mediaIds.Append(iMediaId));
+    
+    cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+    
+    
+    if (*iMimeType != KNullDesC8)
+        {
+        fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
+        }
+    else
+		{
+		fSelect->SetMatchToUriSupportL(*iUrl);
+		}
+    
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+    if (mode == EPlayback || mode == EConvert)
+        cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+    if (mode == ERecord || mode == EConvert)
+        cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+    
+    cSelect->ListImplementationsL(iControllers);
+    
+    iControllerCount = iControllers.Count();
+    if (iControllerCount == 0)
+        User::Leave(KErrNotSupported);
+    
+    // Clean up
+    // cSelect, fSelect, mediaIds
+    CleanupStack::PopAndDestroy(3, cSelect);
+    }
+    
+void CMMFFindAndOpenController::BuildControllerListFormatL()
+    {
+    // Retrieve a list of possible controllers from ECOM
+    // If we don't have a match, leave with unsupported
+    
+    iControllers.ResetAndDestroy();
+    iPrioritisedControllers.Reset();
+    
+    CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+    
+    // Select the media IDs to allow
+    RArray<TUid> mediaIds;
+    CleanupClosePushL(mediaIds);
+    User::LeaveIfError(mediaIds.Append(iMediaId));
+    
+    cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+    
+    CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+    
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+    if (mode == EPlayback || mode == EConvert)
+        cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+    if (mode == ERecord || mode == EConvert)
+        cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+    
+    //Obtain a list of the controllers
+    cSelect->ListImplementationsL(iControllers);
+    
+    CleanupStack::PopAndDestroy(3, cSelect); // cSelect, mediaIds, fSelect
+    
+    iControllerCount = iControllers.Count();
+    if (iControllerCount == 0)
+        User::Leave(KErrNotSupported);
+    
+    TUid formatUidPrimary;
+    TUid formatUidSecondary;
+    if (mode == ERecord)
+        {
+        formatUidSecondary = iFormatUid;
+        formatUidPrimary = iFormatUidSecondary;
+        }
+    else
+        {
+        formatUidPrimary = iFormatUid;
+        formatUidSecondary = iFormatUidSecondary;
+        }
+    
+    for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
+        {
+        const RMMFFormatImplInfoArray& recFormatInfo = iControllers[controllerIndex]->RecordFormats();
+        const RMMFFormatImplInfoArray& playFormatInfo = iControllers[controllerIndex]->PlayFormats();
+        
+        TBool playFormatMatched = EFalse;
+        TBool recordFormatMatched = EFalse;
+        
+        if (formatUidPrimary == KNullUid)
+            {
+            playFormatMatched = ETrue;
+            }
+        else
+            {
+            for(TInt playFormatIndex =0; playFormatIndex < playFormatInfo.Count(); playFormatIndex++)
+                {
+                if(playFormatInfo[playFormatIndex]->Uid() == formatUidPrimary)
+                    {
+                    playFormatMatched = ETrue;
+                    break;
+                    }
+                }
+            }
+        
+        if (formatUidSecondary == KNullUid)
+            {
+            recordFormatMatched = ETrue;
+            }
+        else
+            {
+            for (TInt recFormatIndex =0; recFormatIndex < recFormatInfo.Count(); recFormatIndex++)
+                {
+                if (recFormatInfo[recFormatIndex]->Uid() == formatUidSecondary)
+                    {
+                    recordFormatMatched = ETrue;
+                    break;
+                    }
+                }
+            }
+        
+        if (playFormatMatched && recordFormatMatched)
+            User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
+        }
+    
+    iControllerCount = iPrioritisedControllers.Count();
+    if (iControllerCount == 0)
+        User::Leave(KErrNotSupported);
+    }
+    
+    
+void CMMFFindAndOpenController::BuildControllerListMimeTypeL()
+    {
+    // Retrieve a list of possible controllers from ECOM
+    // If we don't have a match, leave with unsupported
+    
+    iControllers.ResetAndDestroy();
+    
+    CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+    CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+    
+    RArray<TUid> mediaIds;
+    CleanupClosePushL(mediaIds);
+    User::LeaveIfError(mediaIds.Append(iMediaId));
+    
+    cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+    
+    
+    if (*iMimeType != KNullDesC8)
+        {
+        fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
+        }
+    else
+        User::Leave(KErrNotSupported);
+    
+    
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+    if (mode == EPlayback || mode == EConvert)
+        cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+    if (mode == ERecord || mode == EConvert)
+        cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+    
+    
+    cSelect->ListImplementationsL(iControllers);
+    
+    iControllerCount = iControllers.Count();
+    if (iControllerCount == 0)
+        User::Leave(KErrNotSupported);
+    
+    // Clean up
+    CleanupStack::PopAndDestroy(&mediaIds);
+    CleanupStack::PopAndDestroy(fSelect);
+    CleanupStack::PopAndDestroy(cSelect);
+    }
+    
+CMMFUtilityFileInfo* CMMFFindAndOpenController::CreateFileInfoL(TBool aSecureDRMMode)
+	{
+	CMMFUtilityFileInfo* fileInfo = NULL;
+	if (iUseFileHandle) 
+		{
+		if (iUniqueId != NULL)
+			{
+			TMMFileHandleSource fileHandleSource(iFileHandle, (*iUniqueId), iIntent,iEnableUi);
+			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
+			}
+		else
+			{
+			TMMFileHandleSource fileHandleSource(iFileHandle);
+			fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
+			}
+		}
+	else
+		{
+		if (iUniqueId != NULL)
+			{
+			TMMFileSource fileSource(iFileName, (*iUniqueId), iIntent,iEnableUi);	
+			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
+			}
+		else
+			{
+			TMMFileSource fileSource(iFileName);	
+			fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
+			}
+		}
+	return fileInfo;
+	}
+    
+    
+CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TSourceSink& aParams)
+    {
+    if (aParams.iUseFileHandle)
+        {
+        return CMMFileSourceSink::NewL(aParams.iUid, aParams.iFileHandle);
+        }
+    
+    if(!aParams.iConfigData.Length())
+        return CMMSourceSink::NewL(aParams.iUid, aParams.iConfigData);
+    else
+        {
+        iUrl = HBufC::NewL(256);
+        TPtr fileNamePtr = iUrl->Des();
+        
+        fileNamePtr.Copy(aParams.iConfigData);
+        
+        TMMFileSource source( *iUrl, ContentAccess::KDefaultContentObject, ContentAccess::EPlay );
+        return CMMFileSourceSink::NewL(aParams.iUid, source);
+        }
+    }
+    
+    
+CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TMMSource& aSource)
+    {
+    if (!(aSource.SourceType()==KUidMMFileSource ||
+        aSource.SourceType()==KUidMMFileHandleSource))
+        User::Leave(KErrNotSupported);
+    
+    return CMMFileSourceSink::NewL(/*KUidMmfFileSource*/TUid::Uid(0x10207B46), aSource);
+    }
+    
+    
+    
+CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const TDesC8& aConfigData)
+    : iConfigData(aConfigData)
+    {
+    iUid = aUid;
+    
+    iUseFileHandle = EFalse;
+    }
+
+CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const RFile& aFile)
+    : iConfigData(KNullDesC8)
+    {
+    iUid = aUid;
+    
+    iFileHandle = aFile;
+    iUseFileHandle = ETrue;
+    }
+    
+void CMMFFindAndOpenController::SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands)
+	{	
+	iScreenNumber = aScreenNumber;
+	iVideoSetInitScreenCustomCommands = aVideoSetInitScreenCustomCommands;
+	}
+		
+CMMFFindAndOpenController::CConfig::CConfig()
+    {
+    }
+
+void CMMFFindAndOpenController::CConfig::Close()
+    {
+    delete iSource;
+    iSource = NULL;
+    delete iSink;
+    iSink = NULL;
+    }
+
+CMMFFindAndOpenController::CConfig::~CConfig()
+    {
+    Close();
+    }
+
+void CMMFFindAndOpenController::UseSecureDRMProcessL(TBool& aIsSecureDrmProcess)
+    {       
+    TBool isDataProtected = EFalse;
+    ContentAccess::CContent* content = NULL;
+    TControllerMode mode = iCurrentConfig->iControllerMode;
+
+    //setting aUseSecureDrmProcess to false(default value)
+    aIsSecureDrmProcess = EFalse;
+
+    //need to proceed only in case of local playback mode
+    TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
+    TBool localPlaybackMode;
+	if( mode == EPlayback && ( sourceUid.iUid == KFileDataSourcePlugin || sourceUid.iUid == KMmfProgDLSourceUid ) )
+		{
+		localPlaybackMode = ETrue;
+		}
+	else
+		{
+		localPlaybackMode = EFalse;
+		}
+    if(!localPlaybackMode)
+        {
+        return;
+        }
+    TInt error = KErrNone;
+    
+    if (iUseFileHandle != EFalse && iOwnFileHandle != EFalse) 
+        {
+        TRAP(error, content = ContentAccess::CContent::NewL(iFileHandle));
+        if(error == KErrPermissionDenied)
+            {
+            aIsSecureDrmProcess = ETrue;
+            return;
+            }
+        else
+            {
+            User::LeaveIfError(error);
+            }
+        }
+    else if(iFileName.Length() != 0)  //need to check if file name exist
+        {
+        TRAP(error, content = ContentAccess::CContent::NewL(iFileName,EContentShareReadWrite));
+        if(error == KErrPermissionDenied)
+            {
+            aIsSecureDrmProcess = ETrue;
+            return;
+            }
+        else
+            {
+            User::LeaveIfError(error);
+            }
+        }
+    else
+        {//in case of descriptor source content object will not be created
+        return;
+        }
+    TInt value = 0;
+    if(iUniqueId != NULL)
+        {
+        error = content->GetAttribute(EIsProtected, value, *iUniqueId );
+        }
+    else
+        {
+        error = content->GetAttribute(EIsProtected, value);
+        }
+    if( (error == KErrNone && value) || error == KErrPermissionDenied )
+        {//2nd condition can be true if GetAttribute checks for DRM cap and return error if not found
+        isDataProtected = ETrue;
+        }
+    else if( error != KErrNone && error != KErrPermissionDenied)
+        {//leaving as GetAttribute of CAF caused an error.
+        User::Leave(error);
+        }
+    delete content;
+    if(isDataProtected && !iHasDrmCapability && mode == EPlayback )
+        {//only when the Data is protected and client does not have the DRM capability, we need secure DRM process
+        aIsSecureDrmProcess = ETrue;
+        }
+    }
+
+CMMSourceSink* CMMSourceSink::NewLC(TUid aUid, const TDesC8& aDescriptor)
+    {
+    CMMSourceSink* self = new (ELeave) CMMSourceSink(aUid);
+    CleanupStack::PushL(self);
+    self->ConstructL(aDescriptor);
+    return self;
+    }
+
+CMMSourceSink* CMMSourceSink::NewL(TUid aUid, const TDesC8& aDescriptor)
+    {
+    CMMSourceSink* sourcesink = CMMSourceSink::NewLC(aUid, aDescriptor);
+    CleanupStack::Pop(sourcesink);
+    return sourcesink;
+    }
+
+CMMSourceSink::CMMSourceSink(TUid aUid)
+    : iUid(aUid)
+    {
+    }
+
+CMMSourceSink::~CMMSourceSink()
+    {
+    delete iBuf;
+    }
+
+void CMMSourceSink::ConstructL(const TDesC8& aDescriptor)
+    {
+    iBuf = aDescriptor.AllocL();
+    }
+
+TUid CMMSourceSink::SourceSinkUid() const
+    {
+    return iUid;
+    }
+
+const TDesC8& CMMSourceSink::SourceSinkData() const
+    {
+    return *iBuf;
+    }
+TBool CMMSourceSink::CarryingFileHandle() const
+	{
+	return EFalse;
+	}
+
+CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const RFile& aFile)
+    {
+    CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
+    CleanupStack::PushL(self);
+    self->ConstructL(aFile);
+    return self;
+    }
+
+CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const RFile& aFile)
+    {
+    CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aFile);
+    CleanupStack::Pop(sourcesink);
+    return sourcesink;
+    }
+    
+CMMFileSourceSink::CMMFileSourceSink(TUid aUid)
+    : CMMSourceSink(aUid)
+    {
+    }
+
+void CMMFileSourceSink::ConstructL(const RFile& aFile)
+    {
+	User::LeaveIfError(iHandle.Duplicate(aFile));
+    iUsingFileHandle = ETrue;
+    iFileName = HBufC::NewMaxL(KMaxFileName);
+    TPtr fileNamePtr = iFileName->Des();
+    iHandle.Name(fileNamePtr);
+    DoCreateFileHandleSourceConfigDataL();
+    }
+
+void CMMFileSourceSink::DoCreateFileHandleSourceConfigDataL()
+    {
+    CBufFlat* buf = CBufFlat::NewL(KExpandSize);
+    CleanupStack::PushL(buf);
+    RBufWriteStream stream;
+    stream.Open(*buf);
+    CleanupClosePushL(stream);
+    
+    TPckgBuf<RFile*> fileptr(&iHandle);
+    stream.WriteInt32L(KMMFileHandleSourceUid.iUid);
+    stream.WriteL(fileptr);
+    
+    TInt length = 0;
+    if (iUniqueId != NULL)
+        length = iUniqueId->Length();
+    stream.WriteInt32L(length);
+    if (length>0)
+        stream.WriteL(*iUniqueId);
+    
+    stream.WriteInt32L(iEnableUI);
+    
+    stream.CommitL();
+    CleanupStack::PopAndDestroy(&stream);
+    iSourceSinkData = buf->Ptr(0).AllocL();
+    
+    CleanupStack::PopAndDestroy(buf);
+    }
+    
+const TDesC8& CMMFileSourceSink::SourceSinkData() const
+    {
+    ASSERT(iSourceSinkData);
+    return *iSourceSinkData;
+    }
+
+CMMFileSourceSink::~CMMFileSourceSink()
+    {
+    iHandle.Close();
+    delete iFileName;
+    delete iSourceSinkData;
+    delete iUniqueId;
+    }
+
+CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const TMMSource& aSource)
+    {
+    CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
+    CleanupStack::PushL(self);
+    self->ConstructL(aSource);
+    return self;
+    }
+
+CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const TMMSource& aSource)
+    {
+    CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aSource);
+    CleanupStack::Pop(sourcesink);
+    return sourcesink;
+    }
+
+void CMMFileSourceSink::ConstructL(const TMMSource& aSource)
+    {
+    iUniqueId = aSource.UniqueId().AllocL();
+    iIntent = aSource.Intent();
+    iEnableUI = aSource.IsUIEnabled();
+    
+    if (aSource.SourceType() == KUidMMFileSource)
+        {
+        const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+        iFileName = fileSource.Name().AllocL();
+        
+        DoCreateFileSourceConfigDataL();
+        }
+    else if (aSource.SourceType() == KUidMMFileHandleSource)
+        {
+        const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+		iHandle.Close(); // in case already open
+		User::LeaveIfError(iHandle.Duplicate(fileHandleSource.Handle()));
+        iUsingFileHandle = ETrue;
+        iFileName = HBufC::NewMaxL(KMaxFileName);
+        TPtr fileNamePtr = iFileName->Des();
+        iHandle.Name(fileNamePtr);
+        
+        DoCreateFileHandleSourceConfigDataL();
+        }
+    else
+        {
+        User::Leave(KErrNotSupported);
+        }
+    }
+
+void CMMSourceSink::EvaluateIntentL()
+    {
+    }
+
+void CMMFileSourceSink::EvaluateIntentL()
+    {
+    if (iUsingFileHandle)
+        {
+        ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
+        Content->OpenContentLC(iIntent, *iUniqueId);
+        CleanupStack::PopAndDestroy(2, Content);
+        }
+    else
+        {
+        ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
+        Content->OpenContentLC(iIntent, *iUniqueId);
+        CleanupStack::PopAndDestroy(2, Content);
+        }
+    }
+
+
+
+void CMMFileSourceSink::EvaluateIntentL(ContentAccess::TIntent aIntent)
+    {
+    if (iUsingFileHandle)
+        {
+        ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
+        Content->OpenContentLC(aIntent, *iUniqueId);
+        CleanupStack::PopAndDestroy(2, Content);
+        }
+    else
+        {
+        ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
+        Content->OpenContentLC(aIntent, *iUniqueId);
+        CleanupStack::PopAndDestroy(2, Content);
+        }
+    }
+    
+void CMMFileSourceSink::DoCreateFileSourceConfigDataL()
+    {
+    CBufFlat* buf = CBufFlat::NewL(KExpandSize);
+    CleanupStack::PushL(buf);
+    RBufWriteStream stream;
+    stream.Open(*buf);
+    CleanupClosePushL(stream);
+    
+    stream.WriteInt32L(KMMFileSourceUid.iUid);
+    stream.WriteInt32L(iFileName->Length());
+    stream.WriteL(*iFileName);
+    TInt length = 0;
+    if (iUniqueId != NULL)
+        length = iUniqueId->Length();
+    stream.WriteInt32L(length);
+    if (length>0)
+        stream.WriteL(*iUniqueId);
+    
+    stream.WriteInt32L(iEnableUI);
+    
+    stream.CommitL();
+    CleanupStack::PopAndDestroy(&stream);
+    iSourceSinkData = buf->Ptr(0).AllocL();
+    
+    CleanupStack::PopAndDestroy(buf);
+    }
+TBool CMMFileSourceSink::CarryingFileHandle() const
+	{
+	return iUsingFileHandle;
+	}
+
+    // End of file