os/mm/mmlibs/mmfw/tsrc/mmfunittest/videorenderer/src/testgceharness.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "testgceharness.h"
    17 
    18 static TAny* globalGCEHarness = NULL;
    19 
    20 CTestGCEHarness* CTestGCEHarness::NewL(TInt aNumBuffers)
    21 	{
    22 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
    23 	if(!self)
    24 		{
    25 		self = new (ELeave) CTestGCEHarness;
    26 		CleanupStack::PushL(self);
    27 		self->ConstructL(aNumBuffers);
    28 		globalGCEHarness = self;
    29 		CleanupStack::Pop(self);
    30 		}
    31 	return self;
    32 	}
    33 
    34 void CTestGCEHarness::Remove()
    35 	{
    36 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
    37 	if(self)
    38 		{
    39 		delete self;
    40 		globalGCEHarness = NULL;
    41 		}
    42 	}
    43 
    44 /* Use with care. Will leak memory if use inappropriately. Only use if objected pointed to has been
    45  * deleted ro otherwise removed. Required for panic testing where pointer is left hanging when thread
    46  * terminates.
    47  */
    48 void CTestGCEHarness::ResetGlobalPointer()
    49 	{
    50 	globalGCEHarness = NULL;
    51 	}
    52 
    53 void CTestGCEHarness::SetBufferEventProcessingDelay(TRendererEvent aEventType, TTimeIntervalMicroSeconds32 aDelay)
    54 	{
    55 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
    56 	if(!self)
    57 		{
    58 		return;
    59 		}
    60 	
    61 	TInt count = self->iUpdateArray.Count();
    62 	if(count == 0)
    63 		{
    64 		return;
    65 		}
    66 	
    67 	// Get current value of buffers.
    68 	// Processing delays are for all buffers. This function will need to change
    69 	// if delays are to be set on a per buffer basis.
    70 	TTimeIntervalMicroSeconds32 displayDelay = self->iUpdateArray[0].iDisplayedProcessingDelay;
    71 	TTimeIntervalMicroSeconds32 availableDelay = self->iUpdateArray[0].iAvailableProcessingDelay;
    72 
    73 	// set new values for delay
    74 	if(aEventType == EEventDisplayed || aEventType == EEventAll)
    75 		{
    76 		displayDelay = aDelay;
    77 		}
    78 	
    79 	if(aEventType == EEventAvailable || aEventType == EEventAll)
    80 		{
    81 		availableDelay = aDelay;
    82 		}
    83 
    84 	for(TInt i=0; i < count; i++)
    85 		{
    86 		self->iUpdateArray[i].iDisplayedProcessingDelay = displayDelay;
    87 		self->iUpdateArray[i].iAvailableProcessingDelay = availableDelay;
    88 		}
    89 	}
    90 
    91 /*
    92  * Use with care. It results in a reset of the harness on the next
    93  * call to RetrieveL(). This is necessary when the Video Renderer is in timed mode. i.e.
    94  * The thread that creates an AO must also delete it. 
    95  */
    96 void CTestGCEHarness::ResetBuffersL(TInt aNumBuffers)
    97 	{
    98 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
    99 	if(!self)
   100 		{
   101 		User::Leave(KErrNotReady);
   102 		}
   103 	
   104 	self->iResetBuffers = aNumBuffers;
   105 	}
   106 
   107 CTestGCEHarness* CTestGCEHarness::RetrieveL()
   108 	{
   109 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
   110 	if(!self)
   111 		{
   112 		User::Leave(KErrNotReady);
   113 		}
   114 	
   115 	// This code is necessary for the replace tests as the timer active objects must be
   116 	// created and deleted in the same thread, which is not always the test thread. When the
   117 	// Video Renderer is in timed mode the thread the harness is executed in is not
   118 	// the same as the test thread.
   119 	if(self->iResetBuffers)
   120 		{
   121 		TInt buffers = self->iResetBuffers;
   122 		self->Close(); // resets self->iResetBuffers
   123 		self->ConstructL(buffers);
   124 		self->Connect();
   125 		}
   126 	return self;
   127 	}
   128 
   129 TInt CTestGCEHarness::Connect()
   130 	{
   131 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
   132 	if(!self)
   133 		{
   134 		return KErrNotReady;
   135 		}
   136 	
   137 	TInt count = self->iUpdateArray.Count();
   138 	for(TInt i=0; i < count; i++)
   139 		{
   140 		if(self->iUpdateArray[i].iAvailableTimer == NULL)
   141 			{
   142 			self->iUpdateArray[i].iAvailableTimer = CTestTimer::NewL(*self, i, EEventAvailable);
   143 			}
   144 		if(self->iUpdateArray[i].iDisplayedTimer == NULL)
   145 			{
   146 			self->iUpdateArray[i].iDisplayedTimer = CTestTimer::NewL(*self, i, EEventDisplayed);
   147 			}
   148 		}
   149 	return KErrNone;
   150 	}
   151 
   152 void CTestGCEHarness::Close()
   153 	{
   154 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
   155 	if(!self)
   156 		{
   157 		return;
   158 		}
   159 	
   160 	TInt count = self->iUpdateArray.Count();
   161 	for(TInt i=0; i < count; i++)
   162 		{
   163 		if(self->iUpdateArray[i].iAvailableTimer != NULL)
   164 			{
   165 			self->iUpdateArray[i].iAvailableTimer->Cancel();
   166 			delete self->iUpdateArray[i].iAvailableTimer;
   167 			self->iUpdateArray[i].iAvailableTimer = NULL;
   168 			}
   169 		if(self->iUpdateArray[i].iDisplayedTimer != NULL)
   170 			{
   171 			self->iUpdateArray[i].iDisplayedTimer->Cancel();
   172 			delete self->iUpdateArray[i].iDisplayedTimer;
   173 			self->iUpdateArray[i].iDisplayedTimer = NULL;
   174 			}
   175 		}
   176 	self->iUpdateArray.Reset();
   177 	self->iLastPosted = -1;
   178 	self->iResetBuffers = 0;
   179 	}
   180 
   181 void CTestGCEHarness::CancelAllNotifications()
   182 	{
   183 	CTestGCEHarness* self = static_cast <CTestGCEHarness*>(globalGCEHarness);
   184 	if(!self)
   185 		{
   186 		return;
   187 		}
   188 	
   189 	if(self->iStatusDisplayed)
   190 		{
   191 		User::RequestComplete(self->iStatusDisplayed, KErrCancel);
   192 		self->iStatusDisplayed = NULL;
   193 		}
   194 	
   195 	TInt count = self->iUpdateArray.Count();
   196 	for(TInt i=0; i < count; i++)
   197 		{
   198 		if(self->iUpdateArray[i].iAvailableTimer != NULL)
   199 			{
   200 			self->iUpdateArray[i].iAvailableTimer->Cancel();
   201 			}
   202 		if(self->iUpdateArray[i].iDisplayedTimer != NULL)
   203 			{
   204 			self->iUpdateArray[i].iDisplayedTimer->Cancel();
   205 			}
   206 		if(self->iUpdateArray[i].iStatusAvailable)
   207 			{
   208 			User::RequestComplete(self->iUpdateArray[i].iStatusAvailable, KErrCancel);
   209 			self->iUpdateArray[i].iStatusAvailable = NULL;
   210 			}
   211 		}
   212 	}
   213 
   214 CTestGCEHarness::CTestGCEHarness()
   215 : iLastPosted(-1)
   216 	{
   217 	}
   218 
   219 CTestGCEHarness::~CTestGCEHarness()
   220 	{
   221 	iUpdateArray.Close();
   222 	}
   223 
   224 void CTestGCEHarness::ConstructL(TInt aNumBuffers)
   225 	{
   226 	TBufferUpdateData data;
   227 	for(TInt i=0; i < aNumBuffers; i++)
   228 		{
   229 		iUpdateArray.AppendL(data);
   230 		iUpdateArray[i].iAvailableProcessingDelay = KDefaultAvailableProcessingDelay;
   231 		iUpdateArray[i].iDisplayedProcessingDelay = KDefaultDisplayedProcessingDelay;
   232 		iUpdateArray[i].iDisplayedCompleteReason = KErrNone;
   233 		iUpdateArray[i].iAvailableCompleteReason = KErrNone;
   234 		iUpdateArray[i].iDisplayedInProgress = EFalse;
   235 		iUpdateArray[i].iAvailableInProgress = EFalse;
   236 		iUpdateArray[i].iAvailableTimer = NULL;
   237 		iUpdateArray[i].iDisplayedTimer = NULL;
   238 		iUpdateArray[i].iStatusAvailable = NULL;
   239 		}
   240 	}
   241 
   242 TInt CTestGCEHarness::SubmitUpdate(TInt aBuffer)
   243 	{
   244 	if(aBuffer < 0 || aBuffer > iUpdateArray.Count()-1)
   245 		{
   246 		return KErrArgument;
   247 		}
   248 	
   249 	if(iUpdateArray[aBuffer].iDisplayedInProgress || iUpdateArray[aBuffer].iAvailableInProgress)
   250 		{
   251 		return KErrInUse;
   252 		}
   253 
   254 	iUpdateArray[aBuffer].iDisplayedTimer->After(iUpdateArray[aBuffer].iDisplayedProcessingDelay);
   255 	iUpdateArray[aBuffer].iDisplayedInProgress = ETrue;
   256 	
   257 	iUpdateArray[aBuffer].iStatusAvailable = iStatusAvailable;
   258 	iStatusAvailable = NULL;
   259 	
   260 	if(iUpdateArray.Count() == 1)
   261 		{
   262 		// set off available timer - this buffer
   263 		iUpdateArray[aBuffer].iAvailableTimer->After(iUpdateArray[aBuffer].iAvailableProcessingDelay);
   264 		iUpdateArray[aBuffer].iAvailableInProgress = ETrue;
   265 		}
   266 	else if(iLastPosted > -1)
   267 		{
   268 		// set off available timer for iLastPosted
   269 		iUpdateArray[iLastPosted].iAvailableTimer->After(iUpdateArray[iLastPosted].iAvailableProcessingDelay);
   270 		iUpdateArray[iLastPosted].iAvailableInProgress = ETrue;
   271 		// set last posted to this buffer so that it is kicked off on next submit
   272 		iLastPosted = aBuffer;
   273 		}
   274 	else
   275 		{
   276 		iLastPosted = aBuffer;
   277 		}
   278 
   279 	return KErrNone;
   280 	}
   281 
   282 void CTestGCEHarness::NotifyWhenAvailable(TRequestStatus& aStatus)
   283 	{
   284 	iStatusAvailable = &aStatus;
   285 	*iStatusAvailable = KRequestPending;
   286 	}
   287 
   288 void CTestGCEHarness::NotifyWhenDisplayed(TRequestStatus& aStatus, TTimeStamp& aTimeStamp)
   289 	{
   290 	iStatusDisplayed = &aStatus;
   291 	iTimeStamp = &aTimeStamp;
   292 	*iStatusDisplayed = KRequestPending;
   293 	}
   294 
   295 void CTestGCEHarness::OnTimer(TInt aBufferId, TRendererEvent aEvent)
   296 	{
   297 	if(aEvent == EEventDisplayed)
   298 		{
   299 		iUpdateArray[aBufferId].iDisplayedInProgress = EFalse;
   300 		if(iStatusDisplayed)
   301 			{
   302 			*iTimeStamp = User::FastCounter();
   303 			User::RequestComplete(iStatusDisplayed, iUpdateArray[aBufferId].iDisplayedCompleteReason);
   304 			iTimeStamp = NULL;
   305 			iStatusDisplayed = NULL;
   306 			}
   307 		}
   308 	else if(aEvent == EEventAvailable)
   309 		{
   310 		iUpdateArray[aBufferId].iAvailableInProgress = EFalse;
   311 		if(iUpdateArray[aBufferId].iStatusAvailable)
   312 			{
   313 			User::RequestComplete(iUpdateArray[aBufferId].iStatusAvailable, iUpdateArray[aBufferId].iAvailableCompleteReason);
   314 			iUpdateArray[aBufferId].iStatusAvailable = NULL;
   315 			}
   316 		}
   317 	}
   318 
   319 CTestGCEHarness::CTestTimer*
   320 CTestGCEHarness::CTestTimer::NewL(CTestGCEHarness& aContainer, TInt aBufferId, TRendererEvent aEvent)
   321 	{
   322 	CTestTimer* self = new(ELeave)CTestTimer(aContainer, aBufferId, aEvent);
   323  	CleanupStack::PushL(self);
   324  	self->ConstructL();
   325  	CleanupStack::Pop();
   326  	return self;
   327  	}
   328 
   329