testexecfw/useremul/src/RandomTest.cpp
author Johnson Ma <johnson.ma@nokia.com>
Mon, 08 Mar 2010 15:03:44 +0800
changeset 0 3e07fef1e154
permissions -rw-r--r--
Initial EPL Contribution

/*------------------------------------------------------------------
 -
 * Software Name : UserEmulator
 * Version       : v4.2.1309
 * 
 * Copyright (c) 2009 France Telecom. All rights reserved.
 * This software is distributed under the License 
 * "Eclipse Public License - v 1.0" the text of which is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * France Telecom 
 *
 * Contributors:
 *------------------------------------------------------------------
 -
 * File Name: RandomTest.cpp
 * 
 * Created: 13/08/2009
 * Author(s): Marcell Kiss, Reshma Sandeep Das
 *   
 * Description:
 * Random test class
 *------------------------------------------------------------------
 -
 *
 */

// System Includes
#include <e32math.h>
#include <APGTASK.H>
#include <APGWGNAM.H>
#include <aknnotewrappers.h>
// User Includes
#include "RandomTest.h"

// Constants
#define KOkButton 167
#define KBackspace 1

#define TESTSTEPSNUMBER 40
#define COUNTERFOROK 200

// Uid of the Aactive Idle framework (3.1 devices)
const TUid KUidStandBy1 = { 0x101fd64c };
// Uid of the Aactive Idle framework (3.2 devices)
const TUid KUidStandBy = { 0x102750f0 };
// Uid of the Active Idle framework (5.0 devices)
const TUid KUidStandby50 = {0x20017CD9};

enum {ETap=0,EDoubleTap,EFlick,EDrag,EKeys,EKeys1,EKeys2,EKeys3};
const TInt KMaxChance = 200;
const TInt KShortFlickDist = 40;
const TInt KEventTypeMax = 8;
const TInt KScancodeMax = 65535;
const TInt KLogAppAtStep = 100;

const TInt KLSK = 164;
const TInt KRSK = 165;

// ======== MEMBER FUNCTIONS ========

CRandomTest::CRandomTest(MKeyObserver& aObserver,RWsSession& aRWsSession,CSettings& aSettings,RApaLsSession& aSession,CLogger& aLogger)
:CActive(EPriorityNormal),iObserver(aObserver),iRWsSession(&aRWsSession),iSettings(aSettings),iSession(aSession),iLogger(aLogger)
{
}
 
CRandomTest::~CRandomTest()
{	
    iSlotUIDs.Close();
	Cancel();
	iTimer.Close();
}
 
CRandomTest* CRandomTest::NewL(MKeyObserver& aObserver,RWsSession& aRWsSession,CSettings& aSettings,RApaLsSession& aSession,CLogger& aLogger)
{
	CRandomTest* me = CRandomTest::NewLC(aObserver,aRWsSession,aSettings,aSession,aLogger);
	CleanupStack::Pop(me);
    return me;
}

CRandomTest* CRandomTest::NewLC(MKeyObserver& aObserver,RWsSession& aRWsSession,CSettings& aSettings,RApaLsSession& aSession,CLogger& aLogger)
	{
	CRandomTest* me = new (ELeave) CRandomTest(aObserver,aRWsSession,aSettings,aSession,aLogger);
	CleanupStack::PushL(me);
	me->ConstructL();
	return me;
	}
// ----------------------------------------------------------
// Second phase constructor
// ----------------------------------------------------------
// 
void CRandomTest::ConstructL(void)
{
	CActiveScheduler::Add(this);
	iTimer.CreateLocal();
}
 
// ----------------------------------------------------------
// Starts random test
// ----------------------------------------------------------
//
void CRandomTest::StartRandomTestL()
{
	Cancel();
	iAppTestCounter = 0;
	iAppNameLoggingCounter = 0;
	iCounterForOkButton = 0;
	iCantStartAppToTest = ETrue;
	
	if(iSettings.iRandomTestAppIdStatus)
		{
		_LIT(KCantStartApp,"Can't start app %d.\n");
		TUid uid;
		
		TThreadId threadId;
		TBuf<KBuffer128> buf;
		TBuf<KBuffer12> CurrentAppUid;
		TBuf<KBuffer256> RandomTestAppIDs;
		RandomTestAppIDs.Copy(iSettings.iRandomTestAppID);
		TUint32 k;
		TInt res;
		TInt pos=0;
		TInt i=1;
		_LIT(KCommaZero,",0");
		
		// 'Close' string by these chars
		RandomTestAppIDs.Append(KCommaZero);
	
	    while((pos=RandomTestAppIDs.Locate(','))!=KErrNotFound)
	       {
	       k=0;
	       if(RandomTestAppIDs.Left(pos).Length()<=10)
	           CurrentAppUid = RandomTestAppIDs.Left(pos);
	       else
	           CurrentAppUid.Copy(KEMPTYTEXT);
	           
	       CurrentAppUid.Trim();
	       RandomTestAppIDs.Copy(RandomTestAppIDs.Right(RandomTestAppIDs.Length()-pos-1));
	       
		
		    // Converts decimal or hexa uid to integer
            if(CurrentAppUid.Left(2).Compare(KHEX)==0)
                {
                TLex id1(CurrentAppUid.Right(CurrentAppUid.Length()-2));
                res = id1.Val(k,EHex);
                }
            else
                {
                TLex id1(CurrentAppUid);
                res = id1.Val(k,EDecimal);
                }
            
            TInt doc_res=0;
            // Starts test application
            if(res==KErrNone)
                {
                uid.iUid = k;
                doc_res=iSession.StartDocument(KN, uid ,threadId);
                User::After(KWait01);
                }
            if(doc_res==KErrNone && res==KErrNone)
                {
                iSlotUIDs.Append(uid);
                }
            else
                {
                buf.Format(KCantStartApp, i);
                iLogger.WriteLogL(buf,EFalse);
                }
                
           i++;
           }
                
		User::After(KWait02);
		}		
	// Starts timer
	iTimer.After(iStatus,KWait02);
	SetActive();
}
// --------------------------------------------
// Stops random test (The active object)
// --------------------------------------------
//
void CRandomTest::CancelRandomTest()
    {
    Cancel();
    }

// --------------------------------------------
// Restarts random test (The active object)
// --------------------------------------------
//
void CRandomTest::RestartRandomTest()
    {
    iTimer.After(iStatus,KWait02);
    SetActive();
    }
    
// --------------------------------------------
// Stops random test
// --------------------------------------------
//
void CRandomTest::StopRandomTest()
	{
	if(iSettings.iRandomTestAppIdStatus)
		{
		// Stops test apps if uids were valid and apps are running
		for(TInt t=0;t<iSlotUIDs.Count();t++)
		    {
            if(iSlotUIDs[t].iUid!=0)
                {
                TApaTaskList taskList1(*iRWsSession);
                TApaTask task1 = taskList1.FindApp(iSlotUIDs[t]);
                if (task1.Exists())
                    {
                    task1.EndTask();
                    User::After(KWait01);
                    }
                }
		    }
		iSlotUIDs.Reset();
		}
	Cancel();
    }
// ----------------------------------------------------------
// CActive object cancel function
// ----------------------------------------------------------
//
void CRandomTest::DoCancel()
{
	iTimer.Cancel();
}

// -----------------------------------------
// Checks if given Uid is in test list
// -----------------------------------------
//
TBool CRandomTest::IsUidInTestList(TUid aUid)
    {
    TInt res=EFalse;
    for(TInt t=0;t<iSlotUIDs.Count();t++)
            if(iSlotUIDs[t].iUid==aUid.iUid)
                {
                res=ETrue;
                break;
                }
                
    return res;
    }

// ----------------------------------------------------------
// CActive object RunL function
// Runs test on test apps
// ----------------------------------------------------------
//
void CRandomTest::RunL()
{
	// For screen light
	User::ResetInactivityTime();
	// Gets screen width and height
	TInt MaxX = iSettings.iAppRect.Width();
	TInt MaxY = iSettings.iAppRect.Height();
	// Gets random coordinates for random pointer events
	TInt x = Math::Random()%MaxX*2;
	TInt y = Math::Random()%MaxY*2;
	// Repets value for long key press
	TInt repeats = Math::Random()%2;
	// Decides which key press event will be sent
	TInt chance = Math::Random()%KMaxChance;
	// Decides which event will be  sent (pointer/key press)
	TInt randomevent = Math::Random()%KEventTypeMax;
	
	// Sends Ok button press event according to counter 
	if(iCounterForOkButton++ > COUNTERFOROK)
		{// Ok button press event
		iCounterForOkButton = 0;
		repeats = 0;
		chance = KMaxChance-20;
		randomevent = EKeys;
		}
	
	TWsEvent wsEvent;
	TKeyEvent& keyEvent(*wsEvent.Key());
	
	TRawEvent event;
	TRawEvent event1;
	TRawEvent event2;
	TRawEvent event3;
	
	// Log foreground app's name
	CApaWindowGroupName* gn = CApaWindowGroupName::NewLC(*iRWsSession, iRWsSession->GetFocusWindowGroup());
	TApaAppInfo appInfo;
	RApaLsSession ApaLs;
	User::LeaveIfError(ApaLs.Connect());
	ApaLs.GetAppInfo(appInfo, gn->AppUid());
	
	
	// If one of our apps is in foreground then don't close it just send it to background
	if(appInfo.iUid == KUidPanicCapturer )
	{ 
		TApaTaskList taskList(*iRWsSession);
		TApaTask task = taskList.FindApp(appInfo.iUid);

		if (task.Exists())
			task.SendToBackground();
		CleanupStack::PopAndDestroy(gn);
		ApaLs.Close();
		
		iTimer.After(iStatus,KWait01);
		SetActive();
						
		return;
	}
	// If app in foreground is different now or it's there for a long time then log it's name
	else if(iLastAppName.Compare(appInfo.iCaption)!=0 || iAppNameLoggingCounter++>KLogAppAtStep )
		{
		iAppNameLoggingCounter = 0;
		iLastAppName.Zero();
		iLastAppName.Copy(appInfo.iCaption);
		TBuf<KBuffer540> buf;
		_LIT(KText,"Launched app.: ");
		_LIT(KNL,"\n");
		buf.Copy(KText);
		buf.Append(iLastAppName);
		buf.Append(KNL);
		iLogger.WriteLogL(buf,EFalse);
		}
	CleanupStack::PopAndDestroy(gn);
	ApaLs.Close();
	
	// If random test run is on in Settings dialog...
	if(iSettings.iRandomTestAppIdStatus)
		{
		TThreadId threadId; // not used
		// Bring given ID's app to foreground
		TUid uid;
		uid.iUid = 0;
		
		// Decides which test app should be in foreground
		TInt count = iAppTestCounter/TESTSTEPSNUMBER;
		
		if(iSlotUIDs.Count()>count)
		      uid = iSlotUIDs[count];
		else
		    {
		    iAppTestCounter=0;
		    if(iSlotUIDs.Count()>0)
		      uid = iSlotUIDs[0];
		    }
		
		iAppTestCounter++;
		
		
		// If app in foreground is not one of our test apps then close it.
		if( iSlotUIDs.Count()>0 )
			{
			TApaTaskList taskList(*iRWsSession);
			TApaTask task = taskList.FindApp(uid);
			
			if( !IsUidInTestList(appInfo.iUid) && appInfo.iUid.iUid!=0x100058b3 && 
			                 appInfo.iUid.iUid!=_UID3 ) // Don't close telephony app. and User Emulator (exceptions)
				{
				TApaTask task1 = taskList.FindApp(appInfo.iUid);
				if (task1.Exists())
					{
					task1.EndTask();
					User::After(KWait01);
					}
				}
			// If our test app is not in foreground then bring it to foreground
			if (task.Exists())
				task.BringToForeground();
			else
			    // If it's not started then start it
				iSession.StartDocument(KN, uid ,threadId);
			}
		else
			{
			// If there's no valid app uid display error message
			if(iCantStartAppToTest)
				{
				_LIT(KNoValid,"No valid application to start! Random test ends.");
				iCantStartAppToTest = EFalse;
				CAknErrorNote* errorNote = new (ELeave) CAknErrorNote(ETrue);
				errorNote->ExecuteLD(KNoValid);
				iObserver.RandomTestEndsL();
				return;
				}
			
			iTimer.After(iStatus,KWait05);
			SetActive();
			
			return;
			}
		}
	
	// Run pointer test if device enables it otherwise key events only
	if(!AknLayoutUtils::PenEnabled())
		randomevent = EKeys;
	
	// Events
	switch(randomevent)
		{
		case ETap:
			 event.Set(TRawEvent::EButton1Down, x, y);
			 iRWsSession->SimulateRawEvent(event);
			 User::After(KWait01);
			 event1.Set(TRawEvent::EButton1Up, x, y);
			 iRWsSession->SimulateRawEvent(event1);
		break;
		case EDoubleTap:			 
			 event.Set(TRawEvent::EButton1Down, x, y);
			 iRWsSession->SimulateRawEvent(event);
			 User::After(KWait01);
			 event1.Set(TRawEvent::EButton1Up, x, y);
			 iRWsSession->SimulateRawEvent(event1);
			 User::After(KWait01);
			 event2.Set(TRawEvent::EButton1Down, x, y);
			 iRWsSession->SimulateRawEvent(event2);
			 User::After(KWait01);
			 event3.Set(TRawEvent::EButton1Up, x, y);
			 iRWsSession->SimulateRawEvent(event3);
		break;
		case EFlick:
			event.Set(TRawEvent::EButton1Down, x, y);
			iRWsSession->SimulateRawEvent(event);
			User::After(KWait01);
		
			event1.Set(TRawEvent::EPointerMove, x+KShortFlickDist, y+KShortFlickDist);
			iRWsSession->SimulateRawEvent(event1);
			User::After(KWait01);
			
			event2.Set(TRawEvent::EButton1Up, x+KShortFlickDist, y+KShortFlickDist);
			iRWsSession->SimulateRawEvent(event2);
		break;
		case EDrag:
			event.Set(TRawEvent::EButton1Down, x, y);
			iRWsSession->SimulateRawEvent(event);
			User::After(KWait01);
			
			event1.Set(TRawEvent::EPointerMove, x+KShortFlickDist, y);
			iRWsSession->SimulateRawEvent(event1);
			User::After(KWait01);
			
			event2.Set(TRawEvent::EPointerMove, x+KShortFlickDist,y+KShortFlickDist);
			iRWsSession->SimulateRawEvent(event2);
			User::After(KWait01);
			
			event3.Set(TRawEvent::EButton1Up, x+KShortFlickDist, y+KShortFlickDist);
			iRWsSession->SimulateRawEvent(event3);
		break;
		case EKeys:
		case EKeys1:
		case EKeys2:
		case EKeys3:
		default:
			CApaWindowGroupName* gn = CApaWindowGroupName::NewLC(*iRWsSession, iRWsSession->GetFocusWindowGroup());
			TUid foreTaskUid = gn->AppUid();
			CleanupStack::PopAndDestroy(gn);
			
			iRWsSession->GetFocusWindowGroup();
			keyEvent.iModifiers=0;
			
			// Increasing the chance of menu, ok, arrow ,etc. keys
			if( chance > KMaxChance-120)
				{
				if(chance<KMaxChance-100)
					keyEvent.iScanCode = EStdKeyDevice0;
				else if(chance<KMaxChance-80)
					keyEvent.iScanCode = EStdKeyDevice1;
				else if(chance<KMaxChance-70)
					keyEvent.iScanCode = EStdKeyUpArrow;
				else if(chance<KMaxChance-60)
					keyEvent.iScanCode = EStdKeyDownArrow;
				else if(chance<KMaxChance-50)
					keyEvent.iScanCode = EStdKeyLeftArrow;
				else if(chance<KMaxChance-40)
					keyEvent.iScanCode = EStdKeyRightArrow;
				else if(chance<KMaxChance-10)
					keyEvent.iScanCode = EStdKeyApplication0;
				else if(chance<=KMaxChance)
					keyEvent.iScanCode = EStdKeyBackspace;
				}
			else
				keyEvent.iScanCode = Math::Random()%KScancodeMax;
			
			if(iSettings.iRandomTestAppIdStatus)
				{
				// If there is valid uid application -> no menu button push
				// It's for random tests without predefined test apps
				while(keyEvent.iScanCode ==  EStdKeyApplication0 || keyEvent.iCode == EKeyDevice2)
					keyEvent.iScanCode = Math::Random()%KScancodeMax;
					 
				}
			
			// Sends the key event
		  keyEvent.iCode = keyEvent.iScanCode;
			
			
		  TRawEvent lEventDown;
		  lEventDown.Set(TRawEvent::EKeyDown, keyEvent.iScanCode);
		  UserSvr::AddEvent(lEventDown);

		  User::After(KWait01);
											
		  // long key press
		  if(repeats>0)
			 User::After((KWait01*12)*repeats); // 1.2 sec * repeats
											
		  TRawEvent lEventUp;
		  lEventUp.Set(TRawEvent::EKeyUp, keyEvent.iScanCode);
		  UserSvr::AddEvent(lEventUp);
			
		break;
		}
	// Restart timer
	iTimer.After(iStatus,KWait01);
	SetActive();
}