tsrc/xmltestharness/xmlclient/src/asbreakeventhandler.cpp
changeset 0 0e4a32b9112d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/xmltestharness/xmlclient/src/asbreakeventhandler.cpp	Wed Aug 25 12:40:50 2010 +0300
@@ -0,0 +1,219 @@
+/*
+* Copyright (c) 2008-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:
+*
+*/
+
+
+/**
+@file
+@internalComponent
+*/
+
+#include <e32debug.h>
+#include "asbreakeventhandler.h"
+
+const TDesC* StateDes(OMX_STATETYPE);
+
+RASBreakEventHandler::RASBreakEventHandler(MASBreakCallback& aHandler):
+iHandler(aHandler),
+iCounter(0),
+iMode(EIdle)
+	{
+	iOmxCallbackType.EventHandler = EventHandler;
+	
+	// do nothing function is set for these callbacks, rather than using NULL
+	iOmxCallbackType.EmptyBufferDone = EmptyBufferDone;
+	iOmxCallbackType.FillBufferDone = FillBufferDone;
+	}
+
+TInt RASBreakEventHandler::Create()
+	{
+	return iMutex.CreateLocal();
+	}
+
+void RASBreakEventHandler::Close()
+	{
+	for(TInt aIndex = 0, aCount = iComponents.Count(); aIndex < aCount; aIndex++)
+		{
+		delete iComponents[aIndex].iName;
+		}
+	iComponents.Close();
+	iCounter = 0;
+	iMode = EIdle;
+	iMutex.Close();
+	}
+
+void RASBreakEventHandler::AddComponentL(OMX_COMPONENTTYPE* aComponent, const TDesC& aName)
+	{
+	ASSERT(iMode == EIdle);
+	TComponentInfo componentInfo;
+	componentInfo.iHandle = aComponent;
+	componentInfo.iName = HBufC::NewLC(aName.Length());
+	*(componentInfo.iName) = aName;
+	componentInfo.iComplete = EFalse;
+	User::LeaveIfError(iComponents.Append(componentInfo));
+	CleanupStack::Pop(componentInfo.iName);
+	}
+
+OMX_ERRORTYPE RASBreakEventHandler::FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                                   OMX_IN OMX_PTR pAppData,
+                                                   OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+	{
+	return reinterpret_cast<RASBreakEventHandler*>(pAppData)->DoBufferDone(reinterpret_cast<OMX_COMPONENTTYPE*>(hComponent), pBuffer, ETrue);
+	}
+
+OMX_ERRORTYPE RASBreakEventHandler::EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                                    OMX_IN OMX_PTR pAppData,
+                                                    OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+	{
+	return reinterpret_cast<RASBreakEventHandler*>(pAppData)->DoBufferDone(reinterpret_cast<OMX_COMPONENTTYPE*>(hComponent), pBuffer, EFalse);
+	}
+
+OMX_ERRORTYPE RASBreakEventHandler::DoBufferDone(OMX_COMPONENTTYPE* aComponent, OMX_BUFFERHEADERTYPE* aBufHdr, TBool aSource)
+	{
+	iHandler.BufferDone(aComponent, aBufHdr, aSource);
+	return OMX_ErrorNone;
+	}
+
+OMX_ERRORTYPE RASBreakEventHandler::EventHandler(OMX_HANDLETYPE hComponent,
+		OMX_PTR pAppData,
+		OMX_EVENTTYPE eEvent,
+		OMX_U32 nData1,
+		OMX_U32 nData2,
+		OMX_PTR pEventData)
+	{
+	return reinterpret_cast<RASBreakEventHandler*>(pAppData)->DoEventHandler(reinterpret_cast<OMX_COMPONENTTYPE*>(hComponent), eEvent, nData1, nData2, pEventData);
+	}
+
+OMX_ERRORTYPE RASBreakEventHandler::DoEventHandler(OMX_COMPONENTTYPE* aComponent, OMX_EVENTTYPE aEvent, TUint32 aData1, TUint32 aData2, TAny* aEventData)
+	{
+	iMutex.Wait();
+	if((iMode == EAwaitingTransition || iMode == EAwaitingSingleTransition) && aEvent == OMX_EventCmdComplete && aData1 == OMX_CommandStateSet)
+		{
+		StateSet(aComponent, (OMX_STATETYPE) aData2);
+		}
+	else if(iMode == EAwaitingEOS && aEvent == OMX_EventBufferFlag && aData2 & OMX_BUFFERFLAG_EOS)
+		{
+		EndOfStream(aComponent);
+		}
+	else
+		{
+		iHandler.EventReceived(aComponent, aEvent, aData1, aData2, aEventData);
+		}
+	iMutex.Signal();
+	return OMX_ErrorNone;
+	}
+
+void RASBreakEventHandler::StateSet(OMX_COMPONENTTYPE* aComponent, OMX_STATETYPE aState)
+	{
+	RDebug::Print(_L("State transition: component %S is in state %S\n"), ComponentName(aComponent), StateDes(aState));
+	if(iMode == EAwaitingTransition)
+		{
+		__ASSERT_ALWAYS(aState == iNewState, User::Panic(_L("RASBreakEventHandler"), 2));
+		if(--iCounter == 0)
+			{
+			iMode = EIdle;
+			iHandler.AllComponentsTransitioned(iNewState, iOldState);
+			}
+		}
+	else if (iMode == EAwaitingSingleTransition)
+		{
+		__ASSERT_ALWAYS(aState == iNewState, User::Panic(_L("RASBreakEventHandler"), 2));
+		iMode = EIdle;
+		iHandler.ComponentTransitioned(iNewState, iOldState);		
+		}
+	}
+
+void RASBreakEventHandler::EndOfStream(OMX_COMPONENTTYPE* aComponent)
+	{
+	RDebug::Print(_L("End of stream from component %S\n"), ComponentName(aComponent));
+	if(iMode == EAwaitingEOS)
+		{
+		TInt index = iComponents.Find(aComponent, TComponentInfo::CompareHandle);
+		// panic if component was not found
+		__ASSERT_ALWAYS(index >= 0, User::Invariant());
+	
+		// only respond to EOS changing state, to allow potential duplicates
+		if(!iComponents[index].iComplete)
+			{
+			iComponents[index].iComplete = ETrue;
+			iCounter--;
+			// if iEOSComponent is NULL, wait for all components, otherwise wait for individual component
+			if(iEOSComponent == NULL && iCounter == 0 || iEOSComponent == aComponent)
+				{
+				iMode = EIdle;
+				iHandler.AllComponentsEOS();
+				}
+			}
+		}
+	}
+
+void RASBreakEventHandler::AwaitTransition(OMX_STATETYPE aNewState, OMX_STATETYPE aOldState)
+	{
+	RDebug::Print(_L("Awaiting all components to transition from %S to %S\n"), StateDes(aOldState), StateDes(aNewState));
+	ASSERT(iMode == EIdle);
+	iMode = EAwaitingTransition;
+	iNewState = aNewState;
+	iOldState = aOldState;
+	iCounter = iComponents.Count();
+	}
+
+void RASBreakEventHandler::AwaitSingleTransition(OMX_COMPONENTTYPE* aComponent, OMX_STATETYPE aNewState, OMX_STATETYPE aOldState)
+	{
+	RDebug::Print(_L("Awaiting %S components to transition from %S to %S\n"), ComponentName(aComponent), StateDes(aOldState), StateDes(aNewState));	
+	ASSERT(iMode == EIdle);
+	iMode = EAwaitingSingleTransition;
+	iNewState = aNewState;
+	iOldState = aOldState;
+	}
+
+void RASBreakEventHandler::AwaitEOS()
+	{
+	RDebug::Print(_L("Awaiting End Of Stream flag from all components\n"));
+	ASSERT(iMode == EIdle);
+	iMode = EAwaitingEOS;
+	iEOSComponent = NULL;	// wait for all components, not an individual component
+	for(iCounter = 0; iCounter < iComponents.Count(); iCounter++)
+		{
+		iComponents[iCounter].iComplete = EFalse;
+		}
+	}
+
+void RASBreakEventHandler::AwaitEOS(OMX_COMPONENTTYPE* aComponent)
+	{
+	RDebug::Print(_L("Awaiting End Of Stream flag from component %S\n"), ComponentName(aComponent));
+	ASSERT(iMode == EIdle);
+	iMode = EAwaitingEOS;
+	iEOSComponent = aComponent;
+	for(iCounter = 0; iCounter < iComponents.Count(); iCounter++)
+		{
+		iComponents[iCounter].iComplete = EFalse;
+		}
+	}
+
+const TDesC* RASBreakEventHandler::ComponentName(OMX_COMPONENTTYPE* aComponent)
+	{
+	TInt index = iComponents.Find(aComponent, TComponentInfo::CompareHandle);
+	if(index == KErrNotFound)
+		{
+		return NULL;
+		}
+	return iComponents[index].iName;
+	}
+
+OMX_CALLBACKTYPE& RASBreakEventHandler::CallbackStruct()
+	{
+	return iOmxCallbackType;
+	}