windowing/windowserver/tauto/TKRepeat.CPP
author Faisal Memon <faisal.memon@nokia.com>
Fri, 25 Jun 2010 17:49:58 +0100
branchEGL_MERGE
changeset 105 158b2308cc08
parent 0 5d03bc08d59c
permissions -rw-r--r--
Fix def files so that the implementation agnostic interface definition has no non-standards defined entry points, and change the eglrefimpl specific implementation to place its private entry points high up in the ordinal order space in the implementation region, not the standards based entrypoints region.

// Copyright (c) 1996-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:
// Converted from TMan test code May 2001
// Keyboard repeat test
// 
//

#include "TKRepeat.H"

#define LOGGING 1

//
// CRKWindow, class //
//

CRKWindow::CRKWindow(CTKRepeat *aTest) : CTWin(), iTest(aTest)
	{
	}

void CRKWindow::SetUpL(TPoint pos,TSize size,CTWinBase *parent, CWindowGc &aGc)
	{
	ConstructExtLD(*parent,pos,size);
	iWin.SetBackgroundColor(TRgb::Gray256(230));
	Activate();
	AssignGC(aGc);
	}

void CRKWindow::Draw()
	{
	iGc->Clear();
	switch(iState)
		{
		case EStateWaitingForKeyDown:
			iGc->DrawText(_L("Press and hold the space bar"), TPoint(10,20));
			break;
		case EStateWaitingForFirstRepeat:
		case EStateWaitingForNthRepeat:
			{
			TBuf<0x40> buf;
			buf.Format(TRefByValue<const TDesC>(_L("Keep space bar down (%d repeats so far)")),iRepCount);
			iGc->DrawText(buf, TPoint(10,20));
			}
			break;
		case EStateWaitingForKeyUp:
			iGc->DrawText(_L("Release space bar"), TPoint(10,20));
		default:
			break;
		}
	}

void CRKWindow::SetState(TRKStates aState)
	{
#if defined(LOGGING)
	TLogMessageText logMessageText;
	_LIT(KStateChange,"State Change  Old=%d  New=%d");
	logMessageText.Format(KStateChange,iState,aState);
	iTest->LOG_MESSAGE(logMessageText);
#endif
	iState=aState;
	DrawNow();
	TheClient->WaitForRedrawsToFinish();
	SendEvent();
	}

void CRKWindow::SendEvent()
	{
	switch (iState)
		{
	case EStateWaitingForKeyDown:
	case EStateWaitingForKeyUp:
	#if defined(LOGGING)
		_LIT(KKeyUp,"Send key up event  substate 0");
		_LIT(KKeyDown,"Send key down event  substate 4");
		iTest->LOG_MESSAGE(iState==EStateWaitingForKeyDown ? KKeyDown() : KKeyUp());
	#endif
		iTest->TestBase()->SimulateKey((iState==EStateWaitingForKeyDown ? TRawEvent::EKeyDown : TRawEvent::EKeyUp),EStdKeySpace);
		break;
	case EStateWaitingForKeyCode:
	case EStateWaitingForFirstRepeat:
	case EStateWaitingForNthRepeat:
	case EStateInactive:
	case EStateError:
	#if defined(LOGGING)
		_LIT(KLog,"SendEvent:  substate %d so no event to send");
		iTest->LOG_MESSAGE2(KLog,iState);
	#endif
		break;
		}
	}

TBool CRKWindow::CheckResults()
	{
//
// Checks repeat results, first convert everything to 10th's as that what is actually used 
// for the timer in the window server.
//
// Return ETrue if the inacuracy in the average time is greater than 1/10th either way
// Allow initial 2/10ths either
// Allow min 2/10ths below
// Allow max 2/10ths above
//
	if (iState!=EStateInactive)
		return(ETrue);
	TInt initial=iInitialGap.Int()/100000;
	TInt initialX=iInitialRepeatSet.Int()/100000;
	if (initialX==0)
		initialX=1;
	TInt average=(iTotalGap.Int()/100000)/(iRepCount-1);
	TInt repeatX=iRepeatSet.Int()/100000;
	if (repeatX==0)
		repeatX=1;
	TInt min=iMinGap.Int()/100000;
	TInt max=iMaxGap.Int()/100000;
	if (average>(repeatX+1) || average<(repeatX-1))
		return(ETrue);
	if (initial>(initialX+2) || initial<(initialX-2))
		return(ETrue);
#if defined(__MARM_ARM4__)
	if (min>(repeatX+1) || min<(repeatX-2) || max>(repeatX+3) || max<repeatX)
		{
		if (max<min || (max+min)<2*(repeatX-2) || (max+min)>2*(repeatX+2))
			return(ETrue);
		}
#else
	if (min>(repeatX+1) || min<(repeatX-2))
		return(ETrue);
	if (max>(repeatX+3) || max<repeatX)
		return(ETrue);
#endif
	return(EFalse);
	}

TDesC& CRKWindow::Report()
	{
	if (iState!=EStateInactive)
		{
		iReport.Format(_L("Error, test not completed"));
		}
	else
		{
		TInt initial=iInitialGap.Int()/10000;
		TInt initialX=iInitialRepeatSet.Int()/10000;
		TInt average=(iTotalGap.Int()/10000/(iRepCount-1));
		TInt repeatX=iRepeatSet.Int()/10000;
		TInt min=iMinGap.Int()/10000;
		TInt max=iMaxGap.Int()/10000;
		iReport.Format(TRefByValue<const TDesC>(_L("Initial=%d [%d], Av=%d [%d], Min=%d, Max=%d")),initial,initialX,average,repeatX,min,max);
		}
	return(iReport);
	}

void CRKWindow::KeyDownL(const TKeyEvent &aKey,const TTime &)
	{
#if defined(LOGGING)
	TLogMessageText logMessageText;
	_LIT(KKeyDown,"CRKWindow::KeyDownL  Code=%d '%c'  State=%d (0)");
	logMessageText.Format(KKeyDown,aKey.iScanCode,aKey.iScanCode,iState);
	iTest->LOG_MESSAGE(logMessageText);
#endif
	switch(iState)
		{
		case EStateWaitingForKeyDown:
			SetState(EStateWaitingForKeyCode);
			iDownCode=aKey.iScanCode;
			break;
		default:;
		}
	}

void CRKWindow::KeyUpL(const TKeyEvent &aKey,const TTime &)
	{
#if defined(LOGGING)
	TLogMessageText logMessageText;
	_LIT(KKeyUp,"CRKWindow::KeyUpL  Code=%d (%c)  State=%d  Down=%d");
	logMessageText.Format(KKeyUp,aKey.iScanCode,aKey.iScanCode,iState,iDownCode);
	iTest->LOG_MESSAGE(logMessageText);
#endif
	if (aKey.iScanCode==iDownCode)
		{
		switch(iState)
			{
			case EStateWaitingForKeyUp:
				SetState(EStateInactive);
				break;
			default:
				SetState(EStateError);
				break;
			}
		CActiveScheduler::Stop();
		}
	}

void CRKWindow::WinKeyL(const TKeyEvent &aKey,const TTime &aTime)
	{
	if (aKey.iCode==EKeyEscape)
		{
		CActiveScheduler::Stop();
		iTest->iAbort=ETrue;
		}
#if defined(LOGGING)
	TLogMessageText logMessageText;
	_LIT(KKey,"CRKWindow::WinKeyL  Code=%d (%c)  State=%d  RepeatCount=%d");
	logMessageText.Format(KKey,aKey.iScanCode,aKey.iScanCode,iState,iRepCount);
	iTest->LOG_MESSAGE(logMessageText);
#endif
	if (aKey.iCode==32)
		{
		switch(iState)
			{
			case EStateWaitingForKeyCode:
				SetState(EStateWaitingForFirstRepeat);
				iPrevTime=aTime;
				break;
			case EStateWaitingForFirstRepeat:
				iRepCount=1;
				iInitialGap = I64LOW(aTime.MicroSecondsFrom(iPrevTime).Int64());
				SetState(EStateWaitingForNthRepeat);
				break;
			case EStateWaitingForNthRepeat:
				if (iRepCount==5)
					SetState(EStateWaitingForKeyUp);
				else
					{
					TTimeIntervalMicroSeconds32 gap(I64LOW(aTime.MicroSecondsFrom(iPrevTime).Int64()));
				#if defined(LOGGING)
					TLogMessageText logMessageText;
					_LIT(KRepeatGap,"Repeat after %d");
					logMessageText.AppendFormat(KRepeatGap,gap.Int());
					iTest->LOG_MESSAGE(logMessageText);
					TheClient->Flush();
				#endif
					if (gap<iMinGap)
						iMinGap=gap;
					if (gap>iMaxGap)
						iMaxGap=gap;
					iTotalGap=iTotalGap.Int()+gap.Int();	// Horrible way to do a +=
					iRepCount++;
					SetState(EStateWaitingForNthRepeat);
					}
			case EStateWaitingForKeyUp: 	// Do nothing here
				break;
			default:
				//iTest->Test(EFalse);
				iTest->TestBase()->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
				CActiveScheduler::Stop();
			}
		iPrevTime=aTime;
		}
	}

void CRKWindow::SetKeyboardRepeatRate(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime)
	{
	iInitialRepeatSet=aInitialTime;
	iRepeatSet=aTime;
	iMinGap=TTimeIntervalMicroSeconds32(100000000);	// Any very big number will do
	iMaxGap=TTimeIntervalMicroSeconds32(0);
	iTotalGap=TTimeIntervalMicroSeconds32(0);
	SetState(EStateWaitingForKeyDown);
	Client()->iWs.Flush();
	}

//

CTKRepeat::CTKRepeat(CTestStep* aStep) : CTWsGraphicsBase(aStep)
	{
	}

CTKRepeat::~CTKRepeat()
	{
	CTWin::Delete(iWin);
	Client()->iWs.SetKeyboardRepeatRate(iOldInitialTime, iOldTime);
	}

void CTKRepeat::ConstructL()
	{
	TheClient->iWs.SetFocusScreen(iTest->iScreenNumber);
	iWin=new(ELeave) CRKWindow(this);
	TSize screenSize=Client()->iGroup->Size();
	iWin->SetUpL(TPoint(5,5),TSize(Min(Max(screenSize.iWidth/2,250),screenSize.iWidth-10),screenSize.iHeight-10),Client()->iGroup,*Client()->iGc);
	Client()->iGroup->WinTreeNode()->SetOrdinalPosition(0);
	Client()->iGroup->SetCurrentWindow(iWin);
	Client()->iWs.GetKeyboardRepeatRate(iOldInitialTime, iOldTime);
	iTest->SimulateKeyDownUp(EStdKeyLeftCtrl);
	iTest->SimulateKeyDownUp(EStdKeyRightCtrl);
	TInt mods=Client()->iWs.GetModifierState();
	TheClient->WaitForRedrawsToFinish();		//Let all pending events be processed before test begins
	_LIT(KLog,"Initial Modifiers state 0x%x (ideally should be zero)");
	LOG_MESSAGE2(KLog,mods);
	}

TInt CTKRepeat::CheckReportL()
	{
	if (iWin->CheckResults())
		{
		/*CTDialog *dialog=new(ELeave) CTDialog();
		dialog->SetTitle(_L("Keyboard repeat innacuracies"));
		dialog->SetLine1(iWin->Report());
		dialog->SetNumButtons(3);
		dialog->SetButtonText(0,_L("Okay"));
		dialog->SetButtonText(1,_L("Retest"));
		dialog->SetButtonText(2,_L("Fail"));
		dialog->ConstructLD(*Client()->iGroup,*Client()->iGc);
		switch(dialog->Display())
			{
			case 0:
				break;
			case 1:
				return(ETrue);	// Redo test
			case 2:
				Client()->iGroup->ClearCurrentWindow();
				Test(EFalse);
				break;
			}
		*/}
	return(EFalse);
	}

void CTKRepeat::TestKeyboardRepeatRateL(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime)
	{
	do
		{
	#if defined(LOGGING)
		const TInt KOneSec=1000000;
		const TInt KOneHundrethSec=KOneSec/100;
		TLogMessageText logMessageText;
		_LIT(KRepeatRate,"Repeat Rate Initial=%d.%02dsecs, Subsequent=%d.%02dsecs");
		logMessageText.Format(KRepeatRate,aInitialTime.Int()/KOneSec,(aInitialTime.Int()%KOneSec)/KOneHundrethSec
																	,aTime.Int()/KOneSec,(aTime.Int()%KOneSec)/KOneHundrethSec);
		LOG_MESSAGE(logMessageText);
	#endif
		TheClient->iWs.SetKeyboardRepeatRate(aInitialTime, aTime);
		iWin->SetKeyboardRepeatRate(aInitialTime, aTime);
		CActiveScheduler::Start();
		if (iAbort)
			{
			iTest->AbortL();
			}
		} while(CheckReportL());
	}
	
void CTKRepeat::RunTestCaseL(TInt /*aCurTestCase*/)
	{
	_LIT(KTestName1,"Keyboard Repeat 1");
	_LIT(KTestName2,"Keyboard Repeat 2");
	_LIT(KTestName3,"Keyboard Repeat 3");
	_LIT(KTestName4,"Keyboard Repeat 4");
	((CTKRepeatStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
	switch(++iTest->iState)
		{
/**

  @SYMTestCaseID GRAPHICS-WSERV-0311
  
  @SYMDEF             DEF081259
 
  @SYMTestCaseDesc Test that a key can be repeatedly struck after a second, then every half second
    
  @SYMTestPriority High
 
  @SYMTestStatus Implemented
 
  @SYMTestActions Simulate a key being struck first after a second and then repeatedly every
  					half second and check the response time to the key strike is correct 
  
  @SYMTestExpectedResults Response time each time the key is struck is correct
 
*/
		case 1:
			((CTKRepeatStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0311"));
			iTest->LogSubTest(KTestName1);
			TestKeyboardRepeatRateL(TTimeIntervalMicroSeconds32(1000000), TTimeIntervalMicroSeconds32(500000));
			break;
/**

  @SYMTestCaseID GRAPHICS-WSERV-0312
  
  @SYMDEF             DEF081259
 
  @SYMTestCaseDesc Test that a key can be repeatedly struck after a 5th of a second, then every 10th of a second
    
  @SYMTestPriority High
 
  @SYMTestStatus Implemented
 
  @SYMTestActions Simulate a key being struck first after a 5th of a second and then repeatedly every
  					10th of a second and check the response time to the key strike is correct 
  
  @SYMTestExpectedResults Response time each time the key is struck is correct
 
*/
		case 2:
			((CTKRepeatStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0312"));
			iTest->LogSubTest(KTestName2);
			TestKeyboardRepeatRateL(TTimeIntervalMicroSeconds32(200000), TTimeIntervalMicroSeconds32(100000));
			break;
/**

  @SYMTestCaseID GRAPHICS-WSERV-0313
  
  @SYMDEF             DEF081259
 
  @SYMTestCaseDesc Test that a key can be repeatedly struck immediately, then every 10th of a second
    
  @SYMTestPriority High
 
  @SYMTestStatus Implemented
 
  @SYMTestActions Simulate a key being struck first immediately and then repeatedly every
  					10th of a second and check the response time to the key strike is correct 
  
  @SYMTestExpectedResults Response time each time the key is struck is correct
 
*/
		case 3:
			((CTKRepeatStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0313"));
			iTest->LogSubTest(KTestName3);
			TestKeyboardRepeatRateL(TTimeIntervalMicroSeconds32(0), TTimeIntervalMicroSeconds32(100000));
			break;
/**

  @SYMTestCaseID GRAPHICS-WSERV-0314
  
  @SYMDEF             DEF081259
 
  @SYMTestCaseDesc Test that a key can be repeatedly struck after a 10 of a second, then every 10th of a second
    
  @SYMTestPriority High
 
  @SYMTestStatus Implemented
 
  @SYMTestActions Simulate a key being struck first after a 10th of a second and then repeatedly every
  					10th of a second and check the response time to the key strike is correct 
  
  @SYMTestExpectedResults Response time each time the key is struck is correct
 
*/

		case 4:
			((CTKRepeatStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0314"));
			iTest->LogSubTest(KTestName4);
			TestKeyboardRepeatRateL(TTimeIntervalMicroSeconds32(100000), TTimeIntervalMicroSeconds32(100000));
			break;
		case 5:
			((CTKRepeatStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
			((CTKRepeatStep*)iStep)->CloseTMSGraphicsStep();
			TestComplete();
			break;
		}
	((CTKRepeatStep*)iStep)->RecordTestResultL();
	}
	
__WS_CONSTRUCT_STEP__(KRepeat)