// 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)