sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // INCLUDE FILES sl@0: // sl@0: sl@0: sl@0: sl@0: #include "sounddevicebody.h" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: /* sl@0: * Default Constructor. sl@0: */ sl@0: CMMFDevSound::CBody::CBody() sl@0: { sl@0: } sl@0: sl@0: /* sl@0: * Destructor. sl@0: * sl@0: * Deletes all objects and releases all resource owned by this sl@0: * instance. sl@0: */ sl@0: CMMFDevSound::CBody::~CBody() sl@0: { sl@0: // Clear the array of custom interfaces sl@0: TInt numIfs = iCustomInterfaceArray.Count(); sl@0: for (TInt i = 0; i < numIfs; i++) sl@0: { sl@0: if(iCustomInterfaceArray[i].iInterface) sl@0: { sl@0: iCustomInterfaceArray[i].iInterface->Release(); sl@0: } sl@0: } sl@0: iCustomInterfaceArray.Reset(); sl@0: iCustomInterfaceArray.Close(); sl@0: sl@0: // Delete the MUX utility sl@0: delete iMuxUtility; sl@0: sl@0: if (iDevSoundProxy) sl@0: { sl@0: iDevSoundProxy->Close(); sl@0: delete iDevSoundProxy; sl@0: } sl@0: sl@0: // Delete the CI extension sl@0: if (iCIExtension) sl@0: { sl@0: iCIExtension->Release(); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Constructs, and returns a pointer to, a new CMMFDevSound::CBody object. sl@0: * sl@0: * Leaves on failure. sl@0: */ sl@0: CMMFDevSound::CBody* CMMFDevSound::CBody::NewL() sl@0: { sl@0: CBody* self = new (ELeave) CBody; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: /* sl@0: * Second phase constructor. sl@0: */ sl@0: void CMMFDevSound::CBody::ConstructL() sl@0: { sl@0: // all these data properties should be NULL, but add ASSERTs to verify. sl@0: ASSERT(!iDevSoundProxy); sl@0: iDevSoundProxy = new (ELeave) RMMFDevSoundProxy(); sl@0: TInt err = iDevSoundProxy->Open(); sl@0: User::LeaveIfError(err); sl@0: sl@0: User::LeaveIfError(iDevSoundProxy->PostOpen()); sl@0: sl@0: // create Custom Interface MUX utility sl@0: iMuxUtility = CMMFDevSoundCIMuxUtility::NewL(this); sl@0: sl@0: // Create Custom Interface extension sl@0: RImplInfoPtrArray pluginArray; sl@0: CleanupResetAndDestroyPushL(pluginArray); sl@0: TUid interfaceUid = {KUidDevSoundCIClientExtension}; sl@0: REComSession::ListImplementationsL(interfaceUid, pluginArray); sl@0: TUid destructorKey; sl@0: if (pluginArray.Count() > 0) sl@0: { sl@0: // One or more exists - use the 1st one found sl@0: iCIExtension = static_cast sl@0: (REComSession::CreateImplementationL(pluginArray[0]->ImplementationUid(), destructorKey)); sl@0: } sl@0: CleanupStack::PopAndDestroy(&pluginArray); sl@0: if (iCIExtension) sl@0: { sl@0: // Extension exists. Complete the setup sl@0: iCIExtension->PassDestructorKey(destructorKey); sl@0: User::LeaveIfError(iCIExtension->Setup(*iDevSoundProxy)); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * CMMFDevSound::InitializeL sl@0: * sl@0: * Initializes CMMFDevSound object. On completion of Initialization will sl@0: * call InitializeComplete() on aDevSoundObserver. sl@0: * sl@0: * Leaves on failure. sl@0: * sl@0: * @param MDevSoundObserver& sl@0: * A reference to the DevSound Observer instance. sl@0: * sl@0: * @param TMMFState sl@0: * A mode for which this object will be used. sl@0: */ sl@0: void CMMFDevSound::CBody::InitializeL(MDevSoundObserver& aDevSoundObserver, sl@0: TMMFState aMode) sl@0: sl@0: { sl@0: sl@0: ASSERT(iDevSoundProxy); sl@0: iDevSoundProxy->InitializeL(aDevSoundObserver, aMode, *this); sl@0: } sl@0: sl@0: /* sl@0: * CMMFDevSound::InitializeL sl@0: * sl@0: * Initializes CMMFDevSound object with hardware device with hardware sl@0: * device's FourCC code. On completion of Initialization will call sl@0: * InitializeComplete() on aDevSoundObserver. sl@0: * sl@0: * Leaves on failure. sl@0: * sl@0: * @param MDevSoundObserver& sl@0: * A reference to the DevSound Observer instance. sl@0: * sl@0: * @param TFourCC sl@0: * CMMFHwDevice implementation FourCC. sl@0: * sl@0: * @param TMMFState sl@0: * A mode for which this object will be used. sl@0: * sl@0: */ sl@0: void CMMFDevSound::CBody::InitializeL(MDevSoundObserver& aDevSoundObserver, sl@0: TFourCC aDesiredFourCC, sl@0: TMMFState aMode) sl@0: { sl@0: ASSERT(iDevSoundProxy); sl@0: iDevSoundProxy->InitializeL(aDevSoundObserver, aDesiredFourCC, aMode, *this); sl@0: } sl@0: sl@0: /** sl@0: * CMMFDevSound::CBody::CustomInterface sl@0: * sl@0: * Returns custom interface proxy object created by Proxy Custom Interface sl@0: * Utility. sl@0: * sl@0: * @param TUid sl@0: * UID of the custom interface object to be started. sl@0: * sl@0: * @return TAny* sl@0: * Pointer to the Interface Returned by the DevSoundProxy member. sl@0: */ sl@0: TAny* CMMFDevSound::CBody::CustomInterface(TUid aInterfaceId) sl@0: { sl@0: // check if this UID refers to CancelInitialize() sl@0: if (aInterfaceId == KMmfUidDevSoundCancelInitializeCustomInterface) sl@0: { sl@0: MMMFDevSoundCancelInitialize* result = this; sl@0: return result; sl@0: } sl@0: sl@0: // check if this UID refers to EmptyBuffers() sl@0: if (aInterfaceId == KMmfUidDevSoundEmptyBuffersCustomInterface) sl@0: { sl@0: MMMFDevSoundEmptyBuffers* result = this; sl@0: return result; sl@0: } sl@0: sl@0: if (aInterfaceId == KMmfUidDevSoundAudioResourceCustomInterface) sl@0: { sl@0: MAutoPauseResumeSupport* result = this; sl@0: return result; sl@0: } sl@0: sl@0: if (aInterfaceId == KMmfUidDevSoundTimePlayedCustomInterface) sl@0: { sl@0: MMMFDevSoundTimePlayed* result = this; sl@0: return result; sl@0: } sl@0: sl@0: if (aInterfaceId == KMmfUidDevSoundQueryIgnoresUnderflowCustomInterface) sl@0: { sl@0: MMMFDevSoundQueryIgnoresUnderflow* result = this; sl@0: return result; sl@0: } sl@0: sl@0: if (aInterfaceId == KMmfUidDevSoundAudioClientThreadInfoCustomInterface) sl@0: { sl@0: MAudioClientThreadInfo* result = this; sl@0: return result; sl@0: } sl@0: sl@0: if (aInterfaceId == KMmfUidDevSoundTruePauseCustomInterface) sl@0: { sl@0: MMMFDevSoundTruePause* result = this; sl@0: return result; sl@0: } sl@0: sl@0: // first check if we already have resolved a custom interface of this type sl@0: TInt index = FindCustomInterface(aInterfaceId); sl@0: sl@0: MMMFDevSoundCustomInterfaceMuxPlugin* ptr = NULL; sl@0: sl@0: // if we found the interface, take a copy of this instead sl@0: if (index != KNullHandle) sl@0: { sl@0: // check our index is valid sl@0: ptr = iCustomInterfaceArray[index-1].iInterface; sl@0: if (ptr) sl@0: { sl@0: return ptr->CustomInterface(aInterfaceId); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // else try and instantiate a plugin tunnelling sl@0: // pair to support this Custom Interface sl@0: TRAPD(err, ptr = iMuxUtility->CreateCustomInterfaceMuxL(aInterfaceId)); sl@0: sl@0: if (ptr && (err == KErrNone)) sl@0: { sl@0: TMMFDevSoundCustomInterfaceData data; sl@0: data.iInterface = ptr; sl@0: data.iId = aInterfaceId; sl@0: sl@0: // attempt to open remote demux sl@0: // this will store a handle in the mux plugin if successful sl@0: // and also return it here - invalid handle = -1 sl@0: data.iHandle = ptr->OpenInterface(aInterfaceId); sl@0: sl@0: // if the handle is greater than zero then we know we have sl@0: // successfully opened the interface sl@0: if (data.iHandle > KNullHandle) sl@0: { sl@0: // append this to the current interface list sl@0: TInt err = KErrNone; sl@0: err = iCustomInterfaceArray.Append(data); sl@0: if (err == KErrNone) sl@0: { sl@0: // return the custom interface on the ptr sl@0: return ptr->CustomInterface(aInterfaceId); sl@0: } sl@0: } sl@0: sl@0: // no memory or other problem so shut down interface sl@0: ptr->Release(); sl@0: ptr = NULL; sl@0: } sl@0: } sl@0: sl@0: if (iCIExtension) sl@0: { sl@0: // CI Extension exists, see if it supports the interface sl@0: TAny* interface; sl@0: TInt err = iCIExtension->CustomInterfaceExtension(aInterfaceId, interface); sl@0: if (err == KErrNone) sl@0: { sl@0: return interface; sl@0: } sl@0: } sl@0: // No Mux/DeMux support & no support from CI Extension, if here sl@0: // So, its not supported sl@0: return NULL; sl@0: } sl@0: sl@0: TInt CMMFDevSound::CBody::FindCustomInterface(TUid aInterfaceId) sl@0: { sl@0: TInt index = KNullHandle; sl@0: TInt count = iCustomInterfaceArray.Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: if (iCustomInterfaceArray[i].iId == aInterfaceId) sl@0: { sl@0: index = i+1; // use index+1 as the handle, so 0 is undefined/not-found sl@0: break; sl@0: } sl@0: } sl@0: sl@0: return index; sl@0: } sl@0: sl@0: void CMMFDevSound::CBody::CloseCustomInterface(TInt aIndex) sl@0: { sl@0: TInt count = iCustomInterfaceArray.Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: if(iCustomInterfaceArray[i].iHandle == aIndex) sl@0: { sl@0: iCustomInterfaceArray[i].iInterface->Release(); sl@0: iCustomInterfaceArray.Remove(i); sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: TInt CMMFDevSound::CBody::GetTimePlayed(TTimeIntervalMicroSeconds& aTime) sl@0: { sl@0: return iDevSoundProxy->GetTimePlayed(aTime); sl@0: } sl@0: sl@0: TBool CMMFDevSound::CBody::QueryIgnoresUnderflow() sl@0: { sl@0: return ETrue; sl@0: } sl@0: sl@0: TInt CMMFDevSound::CBody::SetClientThreadInfo(TThreadId aTid) sl@0: { sl@0: return iDevSoundProxy->SetClientThreadInfo(aTid); sl@0: } sl@0: // End of File