Fixed "extra qualification" syntax errors.
// 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
@test
@internalComponent - Internal Symbian test code
*/
#include "tmultiptreventhandlingperf.h"
#include <hal.h>
_LIT(KPerformanceTimingChunk, "PerformanceTimingChunk");
// Number of iterations for eventset
const TInt KNumOfIterations = 100;
// Maximum descriptor length for results
const TInt KMaxDescLength = 528;
// Static variables used for synchronisation between threads
GLDEF_D TInt NumOfEventsAdded = 0;
GLDEF_D RMutex Mutex;
GLDEF_D RCondVar ConVar;
void MultiPtrPerfPanic(TInt aPanic)
{
User::Panic(_L("MultiPterEventHanldingPerformancePanic"), aPanic);
}
// This function opens the chunk and adds the failure description followed by '*'
TInt CMultiPtrPerfTestControl::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
{
TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
if (ret != KErrNone)
{
return ret;
}
TUint8* desPtr = iChunk.Base() + iChunkOffset;
TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
TBuf<80> buf;
if (aExpPtrNum != aActPtrNum)
{
_LIT(KFailedPointerNum, "Failed Expected Pointer Num = %d Actual Pointer Num = %d*");
buf.AppendFormat(KFailedPointerNum, aExpPtrNum, aActPtrNum);
ptrDes.Append(buf);
}
else if (aErrorCode != KErrNone)
{
_LIT(KFailedErrorCode, "Failed Errorcode = %d*");
buf.AppendFormat(KFailedErrorCode, aErrorCode);
ptrDes.Append(buf);
}
else
{
_LIT(KFailedWrongCoord, "Failed Coordinates Expected = [%d, %d, %d] Actual = [%d, %d, %d]*");
buf.AppendFormat(KFailedWrongCoord, aExp3DPoint.iX, aExp3DPoint.iY, aExp3DPoint.iZ, aActual3DPoint.iX, aActual3DPoint.iY, aActual3DPoint.iZ);
ptrDes.Append(buf);
}
iChunk.Close();
return ret;
}
// This function opens the chunk and adds a pointer event not supported message followed by '#'
TInt CMultiPtrPerfTestControl::PointerEventsNotSupported()
{
iPointerEventNotSupported = ETrue;
TInt ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
if (ret != KErrNone)
{
return ret;
}
TUint8* desPtr = iChunk.Base() + iChunkOffset;
TPtr8 ptrDes(desPtr, 0, KMaxDescLength);
TBuf<80> buf;
_LIT(KPointerEventsNotSupported, "Test Skipped As Pointer Events Are Not Supported By This Configuration#");
buf.AppendFormat(KPointerEventsNotSupported);
ptrDes.Append(buf);
iChunk.Close();
return ret;
}
// This function calulates the average latency, opens the chunk and appends
// the same in descriptor form. Then close the child thread and calls function
// for creating new thread for events.
// If all the events have been tested then stops the tests
// by calling active CActiveScheduler::Stop.
TInt CMultiPtrPerfTestControl::CalculateLatencyAndStartThread()
{
TInt ret = KErrNone;
switch (iPtrAppUi->TestCaseNum())
{
case 1:
case 5:
case 9:
case 13:
iAverageLatency = iLatency/(4*KNumOfIterations);
break;
case 2:
case 6:
case 10:
case 14:
iAverageLatency = iLatency/(8*KNumOfIterations);
break;
case 3:
case 7:
case 11:
case 15:
iAverageLatency = iLatency/(16*KNumOfIterations);
break;
case 4:
case 8:
case 12:
case 16:
iAverageLatency = iLatency/(32*KNumOfIterations);
break;
default:
MultiPtrPerfPanic(EMultiPtrPerfPanicWrongTest);
}
ret = iChunk.OpenGlobal(KPerformanceTimingChunk, ETrue);
if (ret != KErrNone)
{
return ret;
}
TUint8* desPtr = iChunk.Base() + iChunkOffset;
TPtr8 ptrDes(desPtr, iLatLenInLetters, KMaxDescLength);
TBuf<66> buf;
buf.Num(iAverageLatency);
buf.Append(',');
ptrDes.Append(buf);
// reset the iLatency for next set of test
iLatency = 0;
// For writing the next latency in chunk memory
iLatLenInLetters = ptrDes.Length();
iChunk.Close();
// Before calling the thread Function close the current thread and then call the function
// here when we kill the child thread it releases both mutex and condvar that it holds
iPtrAppUi->ChildThread().Kill(KErrNone);
iPtrAppUi->ChildThread().Close();
if (iPtrAppUi->TestCaseNum() == 16)
{
// It it is the last test case then stop the active scheduler
CActiveScheduler::Stop();
return ret;
}
else
{
return iPtrAppUi->CreateEventSimulatingThreads();
}
}
// This function is called by Cone whenever a event is outstanding
// Here we check if the sent event is same as the expected event in array.
// Then resumes the thread for next set of events. When all the events are completed
// calls CalculateLatencyAndStartThread
void CMultiPtrPerfTestControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
ASSERT(!iPointerEventNotSupported);
// The event that is received is (0,0,0) then it is the first event that the test code is sending
const TAdvancedPointerEvent* advancedPointerEvent = aPointerEvent.AdvancedPointerEvent();
if (iPtrAppUi->TestCaseNum() == 0)
{
if (advancedPointerEvent->PointerNumber() == 0 && advancedPointerEvent->Position3D() == TPoint3D())
{
iPtrAppUi->CreateEventSimulatingThreads();
return;
}
else
{
return; // ignore other events before starting the tests
}
}
// Get the current time.
// Subtract from the test start time.
TTime currentTime;
currentTime.UniversalTime();
TInt64 curTime64 = currentTime.Int64();
TInt timeSinceTestStart = curTime64 - iPtrAppUi->TestStartTime();
// Get the event, get the time stored in Z corodinate
// Then subtract the calculated time from Z coordinate
iLatency += timeSinceTestStart - advancedPointerEvent->ProximityAndPressure();
// Get the current event from buffer and compare it with got event
TAdvancedPointerEvent expectedPtrEvent;
if(0 == iEventBuffer.Remove(&expectedPtrEvent))
{
iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNotFound);
return;
}
// Here Z corodinate is not checked.
if (expectedPtrEvent.iPosition != advancedPointerEvent->iPosition)
{
iPtrAppUi->Failed(expectedPtrEvent.Position3D(), advancedPointerEvent->Position3D(), KErrNone);
return;
}
if (expectedPtrEvent.PointerNumber() != advancedPointerEvent->PointerNumber())
{
iPtrAppUi->Failed(TPoint3D(), TPoint3D(), KErrNone, expectedPtrEvent.PointerNumber(), advancedPointerEvent->PointerNumber());
return;
}
iPtrAppUi->DecrementEventCount();
NumOfEventsAdded--;
// Event count is zero when all the events have been tested
if (iPtrAppUi->EventCount() == 0)
{
TInt ret = CalculateLatencyAndStartThread();
if (ret != KErrNone)
{
iPtrAppUi->Failed(TPoint3D(), TPoint3D(), ret);
return;
}
}
else if (NumOfEventsAdded == 0)
{
ConVar.Signal();
}
}
void CMultiPtrPerfTestControl::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
{
iEventBuffer.Add(&aExpEvent);
}
CMultiPtrPerfTestControl::~CMultiPtrPerfTestControl()
{
iChunk.Close();
}
void CMultiPtrPerfTestControl::ConstructL()
{
iPointerEventNotSupported = EFalse;
ConstructL(TPoint(), ControlEnv()->ScreenDevice()->SizeInPixels());
}
void CMultiPtrPerfTestControl::ConstructL(TPoint aOrigin, TSize aSize)
{
iEventBuffer.SetLengthL(EEventBufferSize);
iPtrAppUi = static_cast<CMultiPtrPerfTestAppUi*>(ControlEnv()->AppUi());
CreateWindowL();
Window().EnableAdvancedPointers();
EnableDragEvents();
SetExtent(aOrigin, aSize);
ActivateL();
// Get the cmdline argument of this process in descriptor
// convert the descriptor to number and store it in iChunkOffset
TBuf<128> buf;
User::CommandLine(buf);
TLex lex(buf);
User::LeaveIfError(lex.Val(iChunkOffset));
}
// This function gets the current time and subtracts it from the time when the whole test was started.
// Simulates the event and suspends the thread if aWaitAfterEachEvent is ETrue
// If aWaitAfterEachEvent is EFalse then it suspends the thread after each set of event i,e after 4, 8, 16 and 32 events
void SimulatePointerEvents(TInt aCount, CMultiPtrPerfTestAppUi* appUi, TBool aMultiPtrEvent = EFalse, TBool aWaitAfterEachEvent = ETrue)
{
TRawEvent rawEvent;
TPoint ptrPos;
TTime currentTime;
TInt64 testStartTime = appUi->TestStartTime();
TInt ptrNum = 0;
TInt ptrMax = 0;
// HAL as already been tested at the start of these tests. So no need to test once again
HAL::Get(HALData::EPointerNumberOfPointers, ptrMax);
appUi->SetNumberOfEvents((KNumOfIterations*aCount)-1);
// For testing time taken for each event and for each set of events we make use of RMutex and RConvar.
// RMutex is used not to preempt this thread until events has been added
// RConVar is used to hold this thread until the events have been tested
for (TInt loop = 0; loop < KNumOfIterations; loop++)
{
ptrNum = 0;
ptrPos.iX = ptrPos.iY = 0;
Mutex.Wait();
for (TInt count = 0; count < aCount/2; count++, ptrNum++)
{
if (ptrNum >= ptrMax)
{
ptrNum = 0;
}
ptrPos.iX += 2;
ptrPos.iY += 1;
TWsEvent event;
event.InitAdvancedPointerEvent(TPointerEvent::EButton1Down, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
appUi->AddExpectedEvent(*event.Pointer());
currentTime.UniversalTime();
TInt64 curTime64 = currentTime.Int64();
TInt timeSinceTestStart = curTime64 - testStartTime;
rawEvent.Set(TRawEvent::EButton1Down, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
UserSvr::AddEvent(rawEvent);
NumOfEventsAdded++;
if (aWaitAfterEachEvent)
{
while(NumOfEventsAdded)
ConVar.Wait(Mutex);
}
event.InitAdvancedPointerEvent(TPointerEvent::EButton1Up, 0, TPoint3D(ptrPos.iX, ptrPos.iY, 0), (aMultiPtrEvent ? ptrNum : 0));
appUi->AddExpectedEvent(*event.Pointer());
currentTime.UniversalTime();
curTime64 = currentTime.Int64();
timeSinceTestStart = curTime64 - testStartTime;
rawEvent.Set(TRawEvent::EButton1Up, ptrPos.iX, ptrPos.iY, timeSinceTestStart, (aMultiPtrEvent ? ptrNum : 0));
UserSvr::AddEvent(rawEvent);
NumOfEventsAdded++;
if (aWaitAfterEachEvent)
{
while(NumOfEventsAdded)
ConVar.Wait(Mutex);
}
}
if (!aWaitAfterEachEvent)
{
while(NumOfEventsAdded)
ConVar.Wait(Mutex);
}
Mutex.Signal();
}
}
TInt EventSimulatingThreadStartFunc(TAny* aAny)
{
CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(aAny);
switch(appUi->TestCaseNum()++)
{
case 0:
SimulatePointerEvents(4, appUi);
break;
case 1:
SimulatePointerEvents(8, appUi);
break;
case 2:
SimulatePointerEvents(16, appUi);
break;
case 3:
SimulatePointerEvents(32, appUi);
break;
case 4:
SimulatePointerEvents(4, appUi, ETrue);
break;
case 5:
SimulatePointerEvents(8, appUi, ETrue);
break;
case 6:
SimulatePointerEvents(16, appUi, ETrue);
break;
case 7:
SimulatePointerEvents(32, appUi, ETrue);
break;
case 8:
SimulatePointerEvents(4, appUi, EFalse, EFalse);
break;
case 9:
SimulatePointerEvents(8, appUi, EFalse, EFalse);
break;
case 10:
SimulatePointerEvents(16, appUi, EFalse, EFalse);
break;
case 11:
SimulatePointerEvents(32, appUi, EFalse, EFalse);
break;
case 12:
SimulatePointerEvents(4, appUi, ETrue, EFalse);
break;
case 13:
SimulatePointerEvents(8, appUi, ETrue, EFalse);
break;
case 14:
SimulatePointerEvents(16, appUi, ETrue, EFalse);
break;
case 15:
SimulatePointerEvents(32, appUi, ETrue, EFalse);
break;
default:
break;
}
return KErrNone;
}
TInt CMultiPtrPerfTestAppUi::CreateEventSimulatingThreads()
{
// Depending upon the iTestCase number create thread and simulate events in that thread function
TInt ret = KErrNone;
_LIT(KSimulateEventsThread, "Events simulating thread");
ret = iThread.Create(KSimulateEventsThread, EventSimulatingThreadStartFunc, KDefaultStackSize, 0x4000, 0x4000, this, EOwnerThread);
if (ret == KErrNone)
{
iThread.Resume();
}
return ret;
}
void CMultiPtrPerfTestAppUi::AddExpectedEvent(TAdvancedPointerEvent& aExpEvent)
{
iControl->AddExpectedEvent(aExpEvent);
}
void CMultiPtrPerfTestAppUi::Failed(TPoint3D aExp3DPoint, TPoint3D aActual3DPoint, TInt aErrorCode, TInt aExpPtrNum, TInt aActPtrNum)
{
// Write error description in the memory of shared chunk
// so that the main performance test just stops by saying that it failed
// and then stop the active scheduler.
iControl->Failed(aExp3DPoint, aActual3DPoint, aErrorCode, aExpPtrNum, aActPtrNum);
CActiveScheduler::Stop();
}
void CMultiPtrPerfTestAppUi::PointerEventsNotSupported()
{
// Write a pointer events not supported message in the memory of shared chunk
// so that the main performance test just skips the pointer test
iControl->PointerEventsNotSupported();
}
CMultiPtrPerfTestAppUi::CMultiPtrPerfTestAppUi()
{
}
CMultiPtrPerfTestAppUi::~CMultiPtrPerfTestAppUi()
{
RemoveFromStack(iControl);
delete iControl;
}
void CMultiPtrPerfTestAppUi::ConstructL()
{
CCoeAppUi::ConstructL();
TTime testStartTime;
testStartTime.UniversalTime();
iTestStartTime = testStartTime.Int64();
iControl = new (ELeave) CMultiPtrPerfTestControl();
iControl->ConstructL();
AddToStackL(iControl);
}
void ConstructControlEnvironmentL(CCoeEnv* aCoe)
{
aCoe->ConstructL();
CMultiPtrPerfTestAppUi* appUi=new(ELeave) CMultiPtrPerfTestAppUi();
CleanupStack::PushL(appUi); // If it leaves after this then there is no way of deleting the appui
aCoe->SetAppUi(appUi); // So pushed it on to cleanup stack
aCoe->WsSession().SetAutoFlush(ETrue);
appUi->ConstructL();
User::LeaveIfError(Mutex.CreateLocal(EOwnerProcess));
User::LeaveIfError(ConVar.CreateLocal(EOwnerProcess));
CleanupStack::Pop(appUi);
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CCoeEnv* coe = new CCoeEnv;
if (!coe)
{
return KErrNoMemory;
}
TRAPD(err, ConstructControlEnvironmentL(coe));
if (err != KErrNone)
{
delete coe;
}
else // If KErrNone then no need to delte coe as it is taken care by ConEnv
{
// Check whether the configuration supports pointer events.
// If it dosn't support pointer events then the pointer cursor area will be empty,
// in this case skip the test and inform the test framework that the test has been skipped
TRect pointerCursorArea = coe->WsSession().PointerCursorArea();
if(pointerCursorArea.IsEmpty())
{
RDebug::Printf("PointerCursorArea is Empty");
CMultiPtrPerfTestAppUi* appUi = static_cast<CMultiPtrPerfTestAppUi*>(coe->AppUi());
appUi->PointerEventsNotSupported();
}
else
{
// First event which starts the test from HandlePointerEventL
TRawEvent rawEvent;
rawEvent.Set(TRawEvent::EButton1Down, 0, 0, 0, 0);
UserSvr::AddEvent(rawEvent);
coe->ExecuteD();
}
Mutex.Close();
ConVar.Close();
}
__UHEAP_MARKEND;
return err;
}