First public contribution.
1 // Copyright (c) 2008-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 @internalComponent - Internal Symbian test code
22 #include "tmultiptreventhandlingperf.h"
25 _LIT(KPerformanceTimingChunk, "PerformanceTimingChunk");
27 // Number of iterations for eventset
28 const TInt KNumOfIterations = 100;
30 // Maximum descriptor length for results
31 const TInt KMaxDescLength = 528;
33 // Static variables used for synchronisation between threads
34 GLDEF_D TInt NumOfEventsAdded = 0;
36 GLDEF_D RCondVar ConVar;
38 void MultiPtrPerfPanic(TInt aPanic)
40 User::Panic(_L("MultiPterEventHanldingPerformancePanic"), aPanic);
43 // This function opens the chunk and adds the failure description followed by '*'
44 TInt CMultiPtrPerfTestControl::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
46 TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
51 TUint8* desPtr = iChunk.Base() + iChunkOffset;
52 TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
55 if (aExpPtrNum != aActPtrNum)
57 _LIT(KFailedPointerNum, "Failed Expected Pointer Num = %d Actual Pointer Num = %d*");
58 buf.AppendFormat(KFailedPointerNum, aExpPtrNum, aActPtrNum);
61 else if (aErrorCode != KErrNone)
63 _LIT(KFailedErrorCode, "Failed Errorcode = %d*");
64 buf.AppendFormat(KFailedErrorCode, aErrorCode);
69 _LIT(KFailedWrongCoord, "Failed Coordinates Expected = [%d, %d, %d] Actual = [%d, %d, %d]*");
70 buf.AppendFormat(KFailedWrongCoord, aExp3DPoint.iX, aExp3DPoint.iY, aExp3DPoint.iZ, aActual3DPoint.iX, aActual3DPoint.iY, aActual3DPoint.iZ);
78 // This function opens the chunk and adds a pointer event not supported message followed by '#'
79 TInt CMultiPtrPerfTestControl::PointerEventsNotSupported()
81 iPointerEventNotSupported = ETrue;
82 TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
87 TUint8* desPtr = iChunk.Base() + iChunkOffset;
88 TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
90 _LIT(KPointerEventsNotSupported, "Test Skipped As Pointer Events Are Not Supported By This Configuration#");
91 buf.AppendFormat(KPointerEventsNotSupported);
97 // This function calulates the average latency, opens the chunk and appends
98 // the same in descriptor form. Then close the child thread and calls function
99 // for creating new thread for events.
100 // If all the events have been tested then stops the tests
101 // by calling active CActiveScheduler::Stop.
102 TInt CMultiPtrPerfTestControl::CalculateLatencyAndStartThread()
105 switch (iPtrAppUi->TestCaseNum())
111 iAverageLatency = iLatency/(4*KNumOfIterations);
117 iAverageLatency = iLatency/(8*KNumOfIterations);
123 iAverageLatency = iLatency/(16*KNumOfIterations);
129 iAverageLatency = iLatency/(32*KNumOfIterations);
132 MultiPtrPerfPanic(EMultiPtrPerfPanicWrongTest);
135 ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
140 TUint8* desPtr = iChunk.Base() + iChunkOffset;
141 TPtr8 ptrDes(desPtr, iLatLenInLetters, KMaxDescLength);
144 buf.Num(iAverageLatency);
148 // reset the iLatency for next set of test
151 // For writing the next latency in chunk memory
152 iLatLenInLetters = ptrDes.Length();
156 // Before calling the thread Function close the current thread and then call the function
157 // here when we kill the child thread it releases both mutex and condvar that it holds
158 iPtrAppUi->ChildThread().Kill(KErrNone);
159 iPtrAppUi->ChildThread().Close();
161 if (iPtrAppUi->TestCaseNum() == 16)
163 // It it is the last test case then stop the active scheduler
164 CActiveScheduler::Stop();
169 return iPtrAppUi->CreateEventSimulatingThreads();
173 // This function is called by Cone whenever a event is outstanding
174 // Here we check if the sent event is same as the expected event in array.
175 // Then resumes the thread for next set of events. When all the events are completed
176 // calls CalculateLatencyAndStartThread
177 void CMultiPtrPerfTestControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
179 ASSERT(!iPointerEventNotSupported);
180 // The event that is received is (0,0,0) then it is the first event that the test code is sending
181 const TAdvancedPointerEvent* advancedPointerEvent = aPointerEvent.AdvancedPointerEvent();
183 if (iPtrAppUi->TestCaseNum() == 0)
185 if (advancedPointerEvent->PointerNumber() == 0 && advancedPointerEvent->Position3D() == TPoint3D())
187 iPtrAppUi->CreateEventSimulatingThreads();
192 return; // ignore other events before starting the tests
196 // Get the current time.
197 // Subtract from the test start time.
199 currentTime.UniversalTime();
200 TInt64 curTime64 = currentTime.Int64();
201 TInt timeSinceTestStart = curTime64 - iPtrAppUi->TestStartTime();
203 // Get the event, get the time stored in Z corodinate
204 // Then subtract the calculated time from Z coordinate
205 iLatency += timeSinceTestStart - advancedPointerEvent->ProximityAndPressure();
207 // Get the current event from buffer and compare it with got event
208 TAdvancedPointerEvent expectedPtrEvent;
209 if(0 == iEventBuffer.Remove(&expectedPtrEvent))
211 iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNotFound);
215 // Here Z corodinate is not checked.
216 if (expectedPtrEvent.iPosition != advancedPointerEvent->iPosition)
218 iPtrAppUi->Failed(expectedPtrEvent.Position3D(), advancedPointerEvent->Position3D(), KErrNone);
222 if (expectedPtrEvent.PointerNumber() != advancedPointerEvent->PointerNumber())
224 iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNone, expectedPtrEvent.PointerNumber(), advancedPointerEvent->PointerNumber());
228 iPtrAppUi->DecrementEventCount();
231 // Event count is zero when all the events have been tested
232 if (iPtrAppUi->EventCount() == 0)
234 TInt ret = CalculateLatencyAndStartThread();
237 iPtrAppUi->Failed(TPoint3D(), TPoint3D(), ret);
241 else if (NumOfEventsAdded == 0)
247 void CMultiPtrPerfTestControl::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
249 iEventBuffer.Add(&aExpEvent);
252 CMultiPtrPerfTestControl::~CMultiPtrPerfTestControl()
257 void CMultiPtrPerfTestControl::ConstructL()
259 iPointerEventNotSupported = EFalse;
260 ConstructL(TPoint(), ControlEnv()->ScreenDevice()->SizeInPixels());
263 void CMultiPtrPerfTestControl::ConstructL(TPoint aOrigin, TSize aSize)
265 iEventBuffer.SetLengthL(EEventBufferSize);
267 iPtrAppUi = static_cast<CMultiPtrPerfTestAppUi*>(ControlEnv()->AppUi());
270 Window().EnableAdvancedPointers();
272 SetExtent(aOrigin, aSize);
275 // Get the cmdline argument of this process in descriptor
276 // convert the descriptor to number and store it in iChunkOffset
278 User::CommandLine(buf);
280 User::LeaveIfError(lex.Val(iChunkOffset));
283 // This function gets the current time and subtracts it from the time when the whole test was started.
284 // Simulates the event and suspends the thread if aWaitAfterEachEvent is ETrue
285 // If aWaitAfterEachEvent is EFalse then it suspends the thread after each set of event i,e after 4, 8, 16 and 32 events
286 void SimulatePointerEvents(TInt aCount, CMultiPtrPerfTestAppUi* appUi, TBool aMultiPtrEvent = EFalse, TBool aWaitAfterEachEvent = ETrue)
291 TInt64 testStartTime = appUi->TestStartTime();
294 // HAL as already been tested at the start of these tests. So no need to test once again
295 HAL::Get(HALData::EPointerNumberOfPointers, ptrMax);
297 appUi->SetNumberOfEvents((KNumOfIterations*aCount)-1);
299 // For testing time taken for each event and for each set of events we make use of RMutex and RConvar.
300 // RMutex is used not to preempt this thread until events has been added
301 // RConVar is used to hold this thread until the events have been tested
302 for (TInt loop = 0; loop < KNumOfIterations; loop++)
305 ptrPos.iX = ptrPos.iY = 0;
307 for (TInt count = 0; count < aCount/2; count++, ptrNum++)
309 if (ptrNum >= ptrMax)
317 event.InitAdvancedPointerEvent(TPointerEvent::EButton1Down, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
318 appUi->AddExpectedEvent(*event.Pointer());
319 currentTime.UniversalTime();
320 TInt64 curTime64 = currentTime.Int64();
321 TInt timeSinceTestStart = curTime64 - testStartTime;
322 rawEvent.Set(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
323 UserSvr::AddEvent(rawEvent);
325 if (aWaitAfterEachEvent)
327 while(NumOfEventsAdded)
331 event.InitAdvancedPointerEvent(TPointerEvent::EButton1Up, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
332 appUi->AddExpectedEvent(*event.Pointer());
333 currentTime.UniversalTime();
334 curTime64 = currentTime.Int64();
335 timeSinceTestStart = curTime64 - testStartTime;
336 rawEvent.Set(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
337 UserSvr::AddEvent(rawEvent);
339 if (aWaitAfterEachEvent)
341 while(NumOfEventsAdded)
345 if (!aWaitAfterEachEvent)
347 while(NumOfEventsAdded)
354 TInt EventSimulatingThreadStartFunc(TAny* aAny)
356 CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(aAny);
358 switch(appUi->TestCaseNum()++)
361 SimulatePointerEvents(4, appUi);
364 SimulatePointerEvents(8, appUi);
367 SimulatePointerEvents(16, appUi);
370 SimulatePointerEvents(32, appUi);
373 SimulatePointerEvents(4, appUi, ETrue);
376 SimulatePointerEvents(8, appUi, ETrue);
379 SimulatePointerEvents(16, appUi, ETrue);
382 SimulatePointerEvents(32, appUi, ETrue);
385 SimulatePointerEvents(4, appUi, EFalse, EFalse);
388 SimulatePointerEvents(8, appUi, EFalse, EFalse);
391 SimulatePointerEvents(16, appUi, EFalse, EFalse);
394 SimulatePointerEvents(32, appUi, EFalse, EFalse);
397 SimulatePointerEvents(4, appUi, ETrue, EFalse);
400 SimulatePointerEvents(8, appUi, ETrue, EFalse);
403 SimulatePointerEvents(16, appUi, ETrue, EFalse);
406 SimulatePointerEvents(32, appUi, ETrue, EFalse);
414 TInt CMultiPtrPerfTestAppUi::CreateEventSimulatingThreads()
416 // Depending upon the iTestCase number create thread and simulate events in that thread function
418 _LIT(KSimulateEventsThread, "Events simulating thread");
419 ret = iThread.Create(KSimulateEventsThread, EventSimulatingThreadStartFunc, KDefaultStackSize, 0x4000, 0x4000, this, EOwnerThread);
427 void CMultiPtrPerfTestAppUi::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
429 iControl->AddExpectedEvent(aExpEvent);
432 void CMultiPtrPerfTestAppUi::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
434 // Write error description in the memory of shared chunk
435 // so that the main performance test just stops by saying that it failed
436 // and then stop the active scheduler.
437 iControl->Failed(aExp3DPoint, aActual3DPoint, aErrorCode, aExpPtrNum, aActPtrNum);
438 CActiveScheduler::Stop();
441 void CMultiPtrPerfTestAppUi::PointerEventsNotSupported()
443 // Write a pointer events not supported message in the memory of shared chunk
444 // so that the main performance test just skips the pointer test
445 iControl->PointerEventsNotSupported();
448 CMultiPtrPerfTestAppUi::CMultiPtrPerfTestAppUi()
452 CMultiPtrPerfTestAppUi::~CMultiPtrPerfTestAppUi()
454 RemoveFromStack(iControl);
458 void CMultiPtrPerfTestAppUi::ConstructL()
460 CCoeAppUi::ConstructL();
463 testStartTime.UniversalTime();
464 iTestStartTime = testStartTime.Int64();
466 iControl = new (ELeave) CMultiPtrPerfTestControl();
467 iControl->ConstructL();
468 AddToStackL(iControl);
471 void ConstructControlEnvironmentL(CCoeEnv* aCoe)
474 CMultiPtrPerfTestAppUi* appUi=new(ELeave) CMultiPtrPerfTestAppUi();
475 CleanupStack::PushL(appUi); // If it leaves after this then there is no way of deleting the appui
476 aCoe->SetAppUi(appUi); // So pushed it on to cleanup stack
477 aCoe->WsSession().SetAutoFlush(ETrue);
479 User::LeaveIfError(Mutex.CreateLocal(EOwnerProcess));
480 User::LeaveIfError(ConVar.CreateLocal(EOwnerProcess));
481 CleanupStack::Pop(appUi);
484 GLDEF_C TInt E32Main()
487 CCoeEnv* coe = new CCoeEnv;
492 TRAPD(err, ConstructControlEnvironmentL(coe));
497 else // If KErrNone then no need to delte coe as it is taken care by ConEnv
499 // Check whether the configuration supports pointer events.
500 // If it dosn't support pointer events then the pointer cursor area will be empty,
501 // in this case skip the test and inform the test framework that the test has been skipped
502 TRect pointerCursorArea = coe->WsSession().PointerCursorArea();
503 if(pointerCursorArea.IsEmpty())
505 RDebug::Printf("PointerCursorArea is Empty");
506 CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(coe->AppUi());
507 appUi->PointerEventsNotSupported();
511 // First event which starts the test from HandlePointerEventL
513 rawEvent.Set(TRawEvent::EButton1Down, 0, 0, 0, 0);
514 UserSvr::AddEvent(rawEvent);