sl@0: // Copyright (c) 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: // sl@0: sl@0: #include "testgceharness.h" sl@0: sl@0: static TAny* globalGCEHarness = NULL; sl@0: sl@0: CTestGCEHarness* CTestGCEHarness::NewL(TInt aNumBuffers) sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: self = new (ELeave) CTestGCEHarness; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aNumBuffers); sl@0: globalGCEHarness = self; sl@0: CleanupStack::Pop(self); sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: void CTestGCEHarness::Remove() sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(self) sl@0: { sl@0: delete self; sl@0: globalGCEHarness = NULL; sl@0: } sl@0: } sl@0: sl@0: /* Use with care. Will leak memory if use inappropriately. Only use if objected pointed to has been sl@0: * deleted ro otherwise removed. Required for panic testing where pointer is left hanging when thread sl@0: * terminates. sl@0: */ sl@0: void CTestGCEHarness::ResetGlobalPointer() sl@0: { sl@0: globalGCEHarness = NULL; sl@0: } sl@0: sl@0: void CTestGCEHarness::SetBufferEventProcessingDelay(TRendererEvent aEventType, TTimeIntervalMicroSeconds32 aDelay) sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: TInt count = self->iUpdateArray.Count(); sl@0: if(count == 0) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: // Get current value of buffers. sl@0: // Processing delays are for all buffers. This function will need to change sl@0: // if delays are to be set on a per buffer basis. sl@0: TTimeIntervalMicroSeconds32 displayDelay = self->iUpdateArray[0].iDisplayedProcessingDelay; sl@0: TTimeIntervalMicroSeconds32 availableDelay = self->iUpdateArray[0].iAvailableProcessingDelay; sl@0: sl@0: // set new values for delay sl@0: if(aEventType == EEventDisplayed || aEventType == EEventAll) sl@0: { sl@0: displayDelay = aDelay; sl@0: } sl@0: sl@0: if(aEventType == EEventAvailable || aEventType == EEventAll) sl@0: { sl@0: availableDelay = aDelay; sl@0: } sl@0: sl@0: for(TInt i=0; i < count; i++) sl@0: { sl@0: self->iUpdateArray[i].iDisplayedProcessingDelay = displayDelay; sl@0: self->iUpdateArray[i].iAvailableProcessingDelay = availableDelay; sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Use with care. It results in a reset of the harness on the next sl@0: * call to RetrieveL(). This is necessary when the Video Renderer is in timed mode. i.e. sl@0: * The thread that creates an AO must also delete it. sl@0: */ sl@0: void CTestGCEHarness::ResetBuffersL(TInt aNumBuffers) sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: self->iResetBuffers = aNumBuffers; sl@0: } sl@0: sl@0: CTestGCEHarness* CTestGCEHarness::RetrieveL() sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: // This code is necessary for the replace tests as the timer active objects must be sl@0: // created and deleted in the same thread, which is not always the test thread. When the sl@0: // Video Renderer is in timed mode the thread the harness is executed in is not sl@0: // the same as the test thread. sl@0: if(self->iResetBuffers) sl@0: { sl@0: TInt buffers = self->iResetBuffers; sl@0: self->Close(); // resets self->iResetBuffers sl@0: self->ConstructL(buffers); sl@0: self->Connect(); sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: TInt CTestGCEHarness::Connect() sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: sl@0: TInt count = self->iUpdateArray.Count(); sl@0: for(TInt i=0; i < count; i++) sl@0: { sl@0: if(self->iUpdateArray[i].iAvailableTimer == NULL) sl@0: { sl@0: self->iUpdateArray[i].iAvailableTimer = CTestTimer::NewL(*self, i, EEventAvailable); sl@0: } sl@0: if(self->iUpdateArray[i].iDisplayedTimer == NULL) sl@0: { sl@0: self->iUpdateArray[i].iDisplayedTimer = CTestTimer::NewL(*self, i, EEventDisplayed); sl@0: } sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CTestGCEHarness::Close() sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: TInt count = self->iUpdateArray.Count(); sl@0: for(TInt i=0; i < count; i++) sl@0: { sl@0: if(self->iUpdateArray[i].iAvailableTimer != NULL) sl@0: { sl@0: self->iUpdateArray[i].iAvailableTimer->Cancel(); sl@0: delete self->iUpdateArray[i].iAvailableTimer; sl@0: self->iUpdateArray[i].iAvailableTimer = NULL; sl@0: } sl@0: if(self->iUpdateArray[i].iDisplayedTimer != NULL) sl@0: { sl@0: self->iUpdateArray[i].iDisplayedTimer->Cancel(); sl@0: delete self->iUpdateArray[i].iDisplayedTimer; sl@0: self->iUpdateArray[i].iDisplayedTimer = NULL; sl@0: } sl@0: } sl@0: self->iUpdateArray.Reset(); sl@0: self->iLastPosted = -1; sl@0: self->iResetBuffers = 0; sl@0: } sl@0: sl@0: void CTestGCEHarness::CancelAllNotifications() sl@0: { sl@0: CTestGCEHarness* self = static_cast (globalGCEHarness); sl@0: if(!self) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: if(self->iStatusDisplayed) sl@0: { sl@0: User::RequestComplete(self->iStatusDisplayed, KErrCancel); sl@0: self->iStatusDisplayed = NULL; sl@0: } sl@0: sl@0: TInt count = self->iUpdateArray.Count(); sl@0: for(TInt i=0; i < count; i++) sl@0: { sl@0: if(self->iUpdateArray[i].iAvailableTimer != NULL) sl@0: { sl@0: self->iUpdateArray[i].iAvailableTimer->Cancel(); sl@0: } sl@0: if(self->iUpdateArray[i].iDisplayedTimer != NULL) sl@0: { sl@0: self->iUpdateArray[i].iDisplayedTimer->Cancel(); sl@0: } sl@0: if(self->iUpdateArray[i].iStatusAvailable) sl@0: { sl@0: User::RequestComplete(self->iUpdateArray[i].iStatusAvailable, KErrCancel); sl@0: self->iUpdateArray[i].iStatusAvailable = NULL; sl@0: } sl@0: } sl@0: } sl@0: sl@0: CTestGCEHarness::CTestGCEHarness() sl@0: : iLastPosted(-1) sl@0: { sl@0: } sl@0: sl@0: CTestGCEHarness::~CTestGCEHarness() sl@0: { sl@0: iUpdateArray.Close(); sl@0: } sl@0: sl@0: void CTestGCEHarness::ConstructL(TInt aNumBuffers) sl@0: { sl@0: TBufferUpdateData data; sl@0: for(TInt i=0; i < aNumBuffers; i++) sl@0: { sl@0: iUpdateArray.AppendL(data); sl@0: iUpdateArray[i].iAvailableProcessingDelay = KDefaultAvailableProcessingDelay; sl@0: iUpdateArray[i].iDisplayedProcessingDelay = KDefaultDisplayedProcessingDelay; sl@0: iUpdateArray[i].iDisplayedCompleteReason = KErrNone; sl@0: iUpdateArray[i].iAvailableCompleteReason = KErrNone; sl@0: iUpdateArray[i].iDisplayedInProgress = EFalse; sl@0: iUpdateArray[i].iAvailableInProgress = EFalse; sl@0: iUpdateArray[i].iAvailableTimer = NULL; sl@0: iUpdateArray[i].iDisplayedTimer = NULL; sl@0: iUpdateArray[i].iStatusAvailable = NULL; sl@0: } sl@0: } sl@0: sl@0: TInt CTestGCEHarness::SubmitUpdate(TInt aBuffer) sl@0: { sl@0: if(aBuffer < 0 || aBuffer > iUpdateArray.Count()-1) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: sl@0: if(iUpdateArray[aBuffer].iDisplayedInProgress || iUpdateArray[aBuffer].iAvailableInProgress) sl@0: { sl@0: return KErrInUse; sl@0: } sl@0: sl@0: iUpdateArray[aBuffer].iDisplayedTimer->After(iUpdateArray[aBuffer].iDisplayedProcessingDelay); sl@0: iUpdateArray[aBuffer].iDisplayedInProgress = ETrue; sl@0: sl@0: iUpdateArray[aBuffer].iStatusAvailable = iStatusAvailable; sl@0: iStatusAvailable = NULL; sl@0: sl@0: if(iUpdateArray.Count() == 1) sl@0: { sl@0: // set off available timer - this buffer sl@0: iUpdateArray[aBuffer].iAvailableTimer->After(iUpdateArray[aBuffer].iAvailableProcessingDelay); sl@0: iUpdateArray[aBuffer].iAvailableInProgress = ETrue; sl@0: } sl@0: else if(iLastPosted > -1) sl@0: { sl@0: // set off available timer for iLastPosted sl@0: iUpdateArray[iLastPosted].iAvailableTimer->After(iUpdateArray[iLastPosted].iAvailableProcessingDelay); sl@0: iUpdateArray[iLastPosted].iAvailableInProgress = ETrue; sl@0: // set last posted to this buffer so that it is kicked off on next submit sl@0: iLastPosted = aBuffer; sl@0: } sl@0: else sl@0: { sl@0: iLastPosted = aBuffer; sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CTestGCEHarness::NotifyWhenAvailable(TRequestStatus& aStatus) sl@0: { sl@0: iStatusAvailable = &aStatus; sl@0: *iStatusAvailable = KRequestPending; sl@0: } sl@0: sl@0: void CTestGCEHarness::NotifyWhenDisplayed(TRequestStatus& aStatus, TTimeStamp& aTimeStamp) sl@0: { sl@0: iStatusDisplayed = &aStatus; sl@0: iTimeStamp = &aTimeStamp; sl@0: *iStatusDisplayed = KRequestPending; sl@0: } sl@0: sl@0: void CTestGCEHarness::OnTimer(TInt aBufferId, TRendererEvent aEvent) sl@0: { sl@0: if(aEvent == EEventDisplayed) sl@0: { sl@0: iUpdateArray[aBufferId].iDisplayedInProgress = EFalse; sl@0: if(iStatusDisplayed) sl@0: { sl@0: *iTimeStamp = User::FastCounter(); sl@0: User::RequestComplete(iStatusDisplayed, iUpdateArray[aBufferId].iDisplayedCompleteReason); sl@0: iTimeStamp = NULL; sl@0: iStatusDisplayed = NULL; sl@0: } sl@0: } sl@0: else if(aEvent == EEventAvailable) sl@0: { sl@0: iUpdateArray[aBufferId].iAvailableInProgress = EFalse; sl@0: if(iUpdateArray[aBufferId].iStatusAvailable) sl@0: { sl@0: User::RequestComplete(iUpdateArray[aBufferId].iStatusAvailable, iUpdateArray[aBufferId].iAvailableCompleteReason); sl@0: iUpdateArray[aBufferId].iStatusAvailable = NULL; sl@0: } sl@0: } sl@0: } sl@0: sl@0: CTestGCEHarness::CTestTimer* sl@0: CTestGCEHarness::CTestTimer::NewL(CTestGCEHarness& aContainer, TInt aBufferId, TRendererEvent aEvent) sl@0: { sl@0: CTestTimer* self = new(ELeave)CTestTimer(aContainer, aBufferId, aEvent); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: