--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/xmltestharness/xmlclient/src/baseprofilehandler.cpp Wed Aug 25 12:40:50 2010 +0300
@@ -0,0 +1,359 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+
+
+#include "baseprofilehandler.h"
+
+_LIT(KErrDialogInvalidPortIndex, "Base Profile support command called on port not configured for base profile comms, component: %S, port: %d");
+_LIT(KErrDialogBufferNumber, "Test script specified %d buffers, less than the port's minimum of %d, component: %S, port: %d");
+_LIT(KErrDialogFillBufferInvalidBufIndex, "Test script specified invalid buffer index on a FillThisBuffer call, component: %S, port: %d, buffer index passed: %d");
+_LIT(KErrDialogEmptyBufferInvalidBufIndex, "Test script specified invalid buffer index on a EmptyThisBuffer call, component: %S, port: %d, buffer index passed: %d");
+
+
+CBaseProfileHandler::CBaseProfileHandler(ROmxScriptTest& aTestOwner, RASBreakEventHandler& aParentEventHandler)
+: iErrorCallbacks(aTestOwner), iEventHandlerCallbacks(aParentEventHandler)
+ {
+ iOmxCallbacks.EmptyBufferDone = EmptyBufferDone;
+ iOmxCallbacks.EventHandler = EventHandler;
+ iOmxCallbacks.FillBufferDone = FillBufferDone;
+ iMutex.CreateLocal();
+ }
+
+CBaseProfileHandler::~CBaseProfileHandler()
+ {
+ iMutex.Close();
+ delete iXmlName;
+ iBufferHeaders.ResetAndDestroy();
+ iPortsUsingBaseProfile.Close();
+ }
+
+void CBaseProfileHandler::AddPortSupportL(TInt aPortIndex)
+ {
+ TPortInfo portInfo;
+ portInfo.iPortIndex = aPortIndex;
+ portInfo.iAutoMode = EFalse;
+ portInfo.iWeAreBufferSupplier = ETrue;
+ iPortsUsingBaseProfile.AppendL(portInfo);
+ }
+
+void CBaseProfileHandler::SetBufferSupplier(TInt aPortIndex, TBool aComponentBufferSupplier)
+ {
+ TInt portIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+ if (portIndex == KErrNotFound)
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex);
+ iErrorCallbacks.FailTest(errorString);
+ return;
+ }
+ iPortsUsingBaseProfile[portIndex].iWeAreBufferSupplier = !aComponentBufferSupplier;
+ }
+
+void CBaseProfileHandler::SetAutoMode(TInt aPortIndex, TBool aAutoMode)
+ {
+ TInt portIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+ if (portIndex == KErrNotFound)
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex);
+ iErrorCallbacks.FailTest(errorString);
+ return;
+ }
+ iPortsUsingBaseProfile[portIndex].iAutoMode = aAutoMode;
+ }
+
+TInt CBaseProfileHandler::LocateBufferForPort(TInt aPortIndex, TInt aBufferIndexInPort)
+ {
+ //Implementation based on the fact that:
+ //-All the buffers for a port are allocated and appended to iBufferHeaders
+ //in a single contiguous block.
+ //-So once the first relevant buffer is found this index marks the zero index
+ //for the set of indexed buffers relevant to that port.
+
+ TInt result = -1;
+ TInt bufferCount = iBufferHeaders.Count();
+ for (TInt bufferIndex = 0; bufferIndex < bufferCount; bufferIndex++)
+ {
+ if (iBufferHeaders[bufferIndex]->iPortIndex != aPortIndex)
+ {
+ continue;
+ }
+
+ //Safety check that the script hasn't made a manual Fill/Empty call on
+ //an invalid buffer index
+ if (iBufferHeaders[bufferIndex]->iPortIndex == iBufferHeaders[(bufferIndex + aBufferIndexInPort)]->iPortIndex)
+ {
+ result = bufferIndex + aBufferIndexInPort;
+ }
+ break;
+ }
+ return result;
+ }
+
+void CBaseProfileHandler::FillThisBuffer(TInt aPortIndex, TInt aBufferIndexInPort)
+ {
+ TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort);
+ if (bufHeaderIndex >= 0)
+ {
+ iBufferHeaders[bufHeaderIndex]->iBufferAvailable = EFalse;
+ iOmxComponent->FillThisBuffer(iOmxComponent, iBufferHeaders[bufHeaderIndex]->iBufferHeader);
+ }
+ else
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogFillBufferInvalidBufIndex, iXmlName, aPortIndex, aBufferIndexInPort);
+ iErrorCallbacks.FailTest(errorString);
+ }
+ }
+
+void CBaseProfileHandler::EmptyThisBuffer(TInt aPortIndex, TInt aBufferIndexInPort)
+ {
+ TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort);
+ if (bufHeaderIndex >= 0)
+ {
+ iBufferHeaders[bufHeaderIndex]->iBufferAvailable = EFalse;
+ iOmxComponent->EmptyThisBuffer(iOmxComponent, iBufferHeaders[bufHeaderIndex]->iBufferHeader);
+ }
+ else
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogEmptyBufferInvalidBufIndex, iXmlName, aPortIndex, aBufferIndexInPort);
+ iErrorCallbacks.FailTest(errorString);
+ }
+ }
+
+void CBaseProfileHandler::WaitForBufferCompletion(TInt aPortIndex, TInt aBufferIndexInPort)
+ {
+ TInt bufHeaderIndex = LocateBufferForPort(aPortIndex, aBufferIndexInPort);
+ iMutex.Wait();
+ if (iBufferHeaders[bufHeaderIndex]->iBufferAvailable)
+ {
+ //Buffer has already completed either while waiting on another buffer or as a result of test command processing delay, no need to wait
+ iMutex.Signal();
+ }
+ else
+ {
+ iWaitingOnBuffer = iBufferHeaders[bufHeaderIndex]->iBufferHeader;
+ iMutex.Signal();
+ iErrorCallbacks.BeginWait();
+ }
+
+ }
+
+OMX_ERRORTYPE CBaseProfileHandler::EventHandler(OMX_HANDLETYPE /*hComponent*/, OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData)
+ {
+ reinterpret_cast<CBaseProfileHandler*>(pAppData)->HandleEventReceived(eEvent, nData1, nData2, pEventData);
+ return OMX_ErrorNone;
+ }
+
+OMX_ERRORTYPE CBaseProfileHandler::FillBufferDone(OMX_IN OMX_HANDLETYPE /*hComponent*/, OMX_IN OMX_PTR pAppData, OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+ {
+ reinterpret_cast<CBaseProfileHandler*>(pAppData)->HandleFillBufferDone(pBuffer);
+ return OMX_ErrorNone;
+ }
+
+OMX_ERRORTYPE CBaseProfileHandler::EmptyBufferDone(OMX_IN OMX_HANDLETYPE /*hComponent*/, OMX_IN OMX_PTR pAppData, OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+ {
+ reinterpret_cast<CBaseProfileHandler*>(pAppData)->HandleEmptyBufferDone(pBuffer);
+ return OMX_ErrorNone;
+ }
+
+void CBaseProfileHandler::HandleEventReceived(OMX_EVENTTYPE aeEvent, OMX_U32 anData1, OMX_U32 anData2, OMX_PTR apEventData)
+ {
+ DoEventReceived(aeEvent, anData1, anData2, apEventData);
+ iEventHandlerCallbacks.EventHandler(iOmxComponent, &iEventHandlerCallbacks, aeEvent, anData1, anData2, apEventData);
+ }
+
+void CBaseProfileHandler::HandleFillBufferDone(OMX_IN OMX_BUFFERHEADERTYPE* aFilledBuffer)
+ {
+ iMutex.Wait();
+ DoFillBufferDone(aFilledBuffer);
+ TInt bufferIndex = iBufferHeaders.Find(*aFilledBuffer, CBaseProfileHandler::BufferHeaderMatchComparison);
+ iBufferHeaders[bufferIndex]->iBufferAvailable = ETrue;
+ TInt portIndex = iPortsUsingBaseProfile.Find((*iBufferHeaders[bufferIndex]).iPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+
+ if (iPortsUsingBaseProfile[portIndex].iAutoMode)
+ {
+ iBufferHeaders[bufferIndex]->iBufferAvailable = EFalse;
+ iOmxComponent->FillThisBuffer(iOmxComponent, aFilledBuffer);
+ }
+
+ if (iWaitingOnBuffer == iBufferHeaders[bufferIndex]->iBufferHeader)
+ {
+ iWaitingOnBuffer = NULL;
+ iErrorCallbacks.EndWait();
+ }
+
+ iMutex.Signal();
+ }
+
+void CBaseProfileHandler::HandleEmptyBufferDone(OMX_IN OMX_BUFFERHEADERTYPE* aEmptiedBuffer)
+ {
+ iMutex.Wait();
+ DoEmptyBufferDone(aEmptiedBuffer);
+ TInt bufferIndex = iBufferHeaders.Find(*aEmptiedBuffer, CBaseProfileHandler::BufferHeaderMatchComparison);
+ iBufferHeaders[bufferIndex]->iBufferAvailable = ETrue;
+ TInt portIndex = iPortsUsingBaseProfile.Find((*iBufferHeaders[bufferIndex]).iPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+
+ if (iPortsUsingBaseProfile[portIndex].iAutoMode)
+ {
+ iBufferHeaders[bufferIndex]->iBufferAvailable = EFalse;
+ iOmxComponent->EmptyThisBuffer(iOmxComponent, aEmptiedBuffer);
+ }
+
+ if (iWaitingOnBuffer == iBufferHeaders[bufferIndex]->iBufferHeader)
+ {
+ iWaitingOnBuffer = NULL;
+ iErrorCallbacks.EndWait();
+ }
+
+ iMutex.Signal();
+ }
+
+OMX_COMPONENTTYPE* CBaseProfileHandler::LoadComponentL(const TDesC8& aTestSpecificName, const TDesC8& aOmxName)
+ {
+
+ iXmlName = HBufC::NewL(aTestSpecificName.Length());
+ iXmlName->Des().Copy(aTestSpecificName);
+ // allow room for the '\0' used in call to OMX_GetHandle
+ HBufC8* omxNameToLoad = HBufC8::NewL(aOmxName.Length() + 1);
+ *omxNameToLoad = aOmxName;
+
+ OMX_ERRORTYPE error = OMX_GetHandle((TAny**) &iOmxComponent, (OMX_STRING) omxNameToLoad->Des().PtrZ(), this, &iOmxCallbacks);
+ delete omxNameToLoad;
+ if (error != OMX_ErrorNone)
+ {
+ iErrorCallbacks.FailWithOmxError(_L("OMX_GetHandle()"), error);
+ }
+
+ return iOmxComponent;
+ }
+
+void CBaseProfileHandler::FreeAllocatedBuffersL()
+ {
+ for (TInt i = 0; i < iBufferHeaders.Count(); ++i)
+ {
+ delete iBufferHeaders[i];
+ }
+ iBufferHeaders.Reset();
+ }
+
+void CBaseProfileHandler::SetupBuffersL(TInt aPortIndex, TInt aNumberBuffers)
+ {
+ TInt portInfoIndex = iPortsUsingBaseProfile.Find(aPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+ if (portInfoIndex == KErrNotFound)
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogInvalidPortIndex, iXmlName, aPortIndex);
+ iErrorCallbacks.FailTest(errorString);
+ return;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE portDef;
+ portDef.nSize = sizeof(portDef);
+ portDef.nVersion = KOmxVersion;
+ portDef.nPortIndex = aPortIndex;
+ OMX_ERRORTYPE error = iOmxComponent->GetParameter(iOmxComponent, OMX_IndexParamPortDefinition, &portDef);
+ if(error != OMX_ErrorNone)
+ {
+ iErrorCallbacks.FailWithOmxError(_L("GetParameter"), error);
+ return;
+ }
+
+ if (aNumberBuffers < portDef.nBufferCountMin)
+ {
+ TBuf<140> errorString;
+ errorString.Format(KErrDialogBufferNumber, aNumberBuffers, portDef.nBufferCountMin, iXmlName, aPortIndex);
+ iErrorCallbacks.FailTest(errorString);
+ return;
+ }
+
+ TInt bufSize = portDef.nBufferSize;
+
+ for (TInt bufIndex=0; bufIndex < aNumberBuffers; bufIndex++)
+ {
+ CBufferHeaderInfo* headerInfo = new (ELeave) CBufferHeaderInfo(*this);
+ iBufferHeaders.AppendL(headerInfo);
+ headerInfo->iPortIndex = aPortIndex;
+
+ if (iPortsUsingBaseProfile[portInfoIndex].iWeAreBufferSupplier)
+ {
+ OMX_U8* buffer = new (ELeave) OMX_U8[bufSize];
+ iOmxComponent->UseBuffer(iOmxComponent, &(headerInfo->iBufferHeader), aPortIndex, NULL, bufSize, buffer);
+ }
+ else
+ {
+ iOmxComponent->AllocateBuffer(iOmxComponent, &(headerInfo->iBufferHeader), aPortIndex, NULL, bufSize);
+ }
+ }
+ }
+
+void CBaseProfileHandler::DoEventReceived(OMX_EVENTTYPE /*aeEvent*/, OMX_U32 /*anData1*/, OMX_U32 /*anData2*/, OMX_PTR /*apEventData*/)
+ {
+ //Uninterested
+ }
+
+void CBaseProfileHandler::DoFillBufferDone(OMX_BUFFERHEADERTYPE* /*aFilledBuffer*/)
+ {
+ //Uninterested
+ }
+
+void CBaseProfileHandler::DoEmptyBufferDone(OMX_BUFFERHEADERTYPE* /*aEmptiedBuffer*/)
+ {
+ //Uninterested
+ }
+
+CBaseProfileHandler::CBufferHeaderInfo::CBufferHeaderInfo(CBaseProfileHandler& aParent)
+: iBufferAvailable(ETrue), iParent(aParent)
+ {
+ }
+
+CBaseProfileHandler::CBufferHeaderInfo::~CBufferHeaderInfo()
+ {
+ OMX_U8* buffer = iBufferHeader->pBuffer;
+ OMX_ERRORTYPE error = iParent.iOmxComponent->FreeBuffer(iParent.iOmxComponent, iPortIndex, iBufferHeader);
+ if (error != OMX_ErrorNone)
+ {
+ iParent.iErrorCallbacks.FailWithOmxError(_L("OMX_FreeBuffer()"), error);
+ return;
+ }
+
+ TInt portInfoIndex = iParent.iPortsUsingBaseProfile.Find(iPortIndex, CBaseProfileHandler::PortIndexMatchComparison);
+ if (iParent.iPortsUsingBaseProfile[portInfoIndex].iWeAreBufferSupplier)
+ {
+ delete[] buffer;
+ }
+ }
+
+TBool CBaseProfileHandler::PortIndexMatchComparison(const TInt* aPortIndex, const TPortInfo& aPortInfo)
+ {
+ if (*aPortIndex == aPortInfo.iPortIndex)
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+TBool CBaseProfileHandler::BufferHeaderMatchComparison(const OMX_BUFFERHEADERTYPE* aBufferHeader, const CBufferHeaderInfo& aBufferHeaderInfo)
+ {
+ if (aBufferHeader == aBufferHeaderInfo.iBufferHeader)
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+