MonkeySourceScriptpublic class MonkeySourceScript extends Object implements MonkeyEventSourcemonkey event queue. It takes a script to produce events
sample script format:
type= raw events
count= 10
speed= 1.0
captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
0.06666667,0,0.0,0.0,65539,0)
captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
captureDispatchFlip(true)
... |
Fields Summary |
---|
private int | mEventCountInScript | private int | mVerbose | private double | mSpeed | private String | mScriptFileName | private LinkedList | mQ | private static final String | HEADER_TYPE | private static final String | HEADER_COUNT | private static final String | HEADER_SPEED | private long | mLastRecordedDownTimeKey | private long | mLastRecordedDownTimeMotion | private long | mLastExportDownTimeKey | private long | mLastExportDownTimeMotion | private long | mLastExportEventTime | private long | mLastRecordedEventTime | private static final boolean | THIS_DEBUG | private static final long | SLEEP_COMPENSATE_DIFF | private static final int | MAX_ONE_TIME_READS | private static final int | POLICY_ADDITIONAL_EVENT_COUNT | private static final String | EVENT_KEYWORD_POINTER | private static final String | EVENT_KEYWORD_TRACKBALL | private static final String | EVENT_KEYWORD_KEY | private static final String | EVENT_KEYWORD_FLIP | private static final String | STARTING_DATA_LINE | private boolean | mFileOpened | FileInputStream | mFStream | DataInputStream | mInputStream | BufferedReader | mBufferReader |
Constructors Summary |
---|
public MonkeySourceScript(String filename)
mScriptFileName = filename;
|
Methods Summary |
---|
private void | addHomeKeyEvent()add home key press/release event to the queue
MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HOME);
mQ.addLast(e);
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HOME);
mQ.addLast(e);
| private void | adjustKeyEventTime(MonkeyKeyEvent e)adjust key downtime and eventtime according to both
recorded values and current system time
if (e.getEventTime() < 0) {
return;
}
long thisDownTime = 0;
long thisEventTime = 0;
long expectedDelay = 0;
if (mLastRecordedEventTime <= 0) {
// first time event
thisDownTime = SystemClock.uptimeMillis();
thisEventTime = thisDownTime;
} else {
if (e.getDownTime() != mLastRecordedDownTimeKey) {
thisDownTime = e.getDownTime();
} else {
thisDownTime = mLastExportDownTimeKey;
}
expectedDelay = (long) ((e.getEventTime() -
mLastRecordedEventTime) * mSpeed);
thisEventTime = mLastExportEventTime + expectedDelay;
// add sleep to simulate everything in recording
needSleep(expectedDelay - SLEEP_COMPENSATE_DIFF);
}
mLastRecordedDownTimeKey = e.getDownTime();
mLastRecordedEventTime = e.getEventTime();
e.setDownTime(thisDownTime);
e.setEventTime(thisEventTime);
mLastExportDownTimeKey = thisDownTime;
mLastExportEventTime = thisEventTime;
| private void | adjustMotionEventTime(MonkeyMotionEvent e)adjust motion downtime and eventtime according to both
recorded values and current system time
if (e.getEventTime() < 0) {
return;
}
long thisDownTime = 0;
long thisEventTime = 0;
long expectedDelay = 0;
if (mLastRecordedEventTime <= 0) {
// first time event
thisDownTime = SystemClock.uptimeMillis();
thisEventTime = thisDownTime;
} else {
if (e.getDownTime() != mLastRecordedDownTimeMotion) {
thisDownTime = e.getDownTime();
} else {
thisDownTime = mLastExportDownTimeMotion;
}
expectedDelay = (long) ((e.getEventTime() -
mLastRecordedEventTime) * mSpeed);
thisEventTime = mLastExportEventTime + expectedDelay;
// add sleep to simulate everything in recording
needSleep(expectedDelay - SLEEP_COMPENSATE_DIFF);
}
mLastRecordedDownTimeMotion = e.getDownTime();
mLastRecordedEventTime = e.getEventTime();
e.setDownTime(thisDownTime);
e.setEventTime(thisEventTime);
mLastExportDownTimeMotion = thisDownTime;
mLastExportEventTime = thisEventTime;
| private void | closeFile()
mFileOpened = false;
if (THIS_DEBUG) {
System.out.println("closing script file");
}
try {
mFStream.close();
mInputStream.close();
} catch (IOException e) {
System.out.println(e);
}
| public MonkeyEvent | getNextEvent()if the queue is empty, we generate events first
long recordedEventTime = -1;
if (mQ.isEmpty()) {
readNextBatch();
}
MonkeyEvent e = mQ.getFirst();
mQ.removeFirst();
if (e.getEventType() == MonkeyEvent.EVENT_TYPE_KEY) {
adjustKeyEventTime((MonkeyKeyEvent) e);
} else if (e.getEventType() == MonkeyEvent.EVENT_TYPE_POINTER ||
e.getEventType() == MonkeyEvent.EVENT_TYPE_TRACKBALL) {
adjustMotionEventTime((MonkeyMotionEvent) e);
}
return e;
| public int | getOneRoundEventCount()
//plus one home key down and up event
return mEventCountInScript + POLICY_ADDITIONAL_EVENT_COUNT;
| private void | needSleep(long time)sleep for a period of given time, introducing latency among events
if (time < 1) {
return;
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
| private void | processLine(java.lang.String s)
int index1 = s.indexOf('(");
int index2 = s.indexOf(')");
if (index1 < 0 || index2 < 0) {
return;
}
StringTokenizer st = new StringTokenizer(
s.substring(index1 + 1, index2), ",");
if (s.indexOf(EVENT_KEYWORD_KEY) >= 0) {
// key events
try {
long downTime = Long.parseLong(st.nextToken());
long eventTime = Long.parseLong(st.nextToken());
int action = Integer.parseInt(st.nextToken());
int code = Integer.parseInt(st.nextToken());
int repeat = Integer.parseInt(st.nextToken());
int metaState = Integer.parseInt(st.nextToken());
int device = Integer.parseInt(st.nextToken());
int scancode = Integer.parseInt(st.nextToken());
MonkeyKeyEvent e = new MonkeyKeyEvent(downTime, eventTime,
action, code, repeat, metaState, device, scancode);
mQ.addLast(e);
} catch (NumberFormatException e) {
// something wrong with this line in the script
}
} else if (s.indexOf(EVENT_KEYWORD_POINTER) >= 0 ||
s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0) {
// trackball/pointer event
try {
long downTime = Long.parseLong(st.nextToken());
long eventTime = Long.parseLong(st.nextToken());
int action = Integer.parseInt(st.nextToken());
float x = Float.parseFloat(st.nextToken());
float y = Float.parseFloat(st.nextToken());
float pressure = Float.parseFloat(st.nextToken());
float size = Float.parseFloat(st.nextToken());
int metaState = Integer.parseInt(st.nextToken());
float xPrecision = Float.parseFloat(st.nextToken());
float yPrecision = Float.parseFloat(st.nextToken());
int device = Integer.parseInt(st.nextToken());
int edgeFlags = Integer.parseInt(st.nextToken());
int type = MonkeyEvent.EVENT_TYPE_TRACKBALL;
if (s.indexOf("Pointer") > 0) {
type = MonkeyEvent.EVENT_TYPE_POINTER;
}
MonkeyMotionEvent e = new MonkeyMotionEvent(type, downTime, eventTime,
action, x, y, pressure, size, metaState, xPrecision, yPrecision,
device, edgeFlags);
mQ.addLast(e);
} catch (NumberFormatException e) {
// we ignore this event
}
} else if (s.indexOf(EVENT_KEYWORD_FLIP) >= 0) {
boolean keyboardOpen = Boolean.parseBoolean(st.nextToken());
MonkeyFlipEvent e = new MonkeyFlipEvent(keyboardOpen);
mQ.addLast(e);
}
| private boolean | readNextBatch()read next batch of events from the provided script file
String sLine = null;
int readCount = 0;
if (THIS_DEBUG) {
System.out.println("readNextBatch(): reading next batch of events");
}
if (!mFileOpened) {
if (!readScriptHeader()) {
closeFile();
return false;
}
resetValue();
/*
* In order to allow the Monkey to replay captured events multiple times
* we need to define a default start UI, which is the home screen
* Otherwise, it won't be accurate since the captured events
* could end anywhere
*/
addHomeKeyEvent();
}
try {
while (readCount++ < MAX_ONE_TIME_READS &&
(sLine = mBufferReader.readLine()) != null) {
sLine = sLine.trim();
processLine(sLine);
}
} catch (IOException e) {
System.err.println(e);
return false;
}
if (sLine == null) {
// to the end of the file
if (THIS_DEBUG) {
System.out.println("readNextBatch(): to the end of file");
}
closeFile();
}
return true;
| private boolean | readScriptHeader()
mEventCountInScript = -1;
mFileOpened = false;
try {
if (THIS_DEBUG) {
System.out.println("reading script header");
}
mFStream = new FileInputStream(mScriptFileName);
mInputStream = new DataInputStream(mFStream);
mBufferReader = new BufferedReader(
new InputStreamReader(mInputStream));
String sLine;
while ((sLine = mBufferReader.readLine()) != null) {
sLine = sLine.trim();
if (sLine.indexOf(HEADER_TYPE) >= 0) {
// at this point, we only have one type of script
} else if (sLine.indexOf(HEADER_COUNT) >= 0) {
try {
mEventCountInScript = Integer.parseInt(sLine.substring(
HEADER_COUNT.length() + 1).trim());
} catch (NumberFormatException e) {
System.err.println(e);
}
} else if (sLine.indexOf(HEADER_SPEED) >= 0) {
try {
mSpeed = Double.parseDouble(sLine.substring(
HEADER_SPEED.length() + 1).trim());
} catch (NumberFormatException e) {
System.err.println(e);
}
} else if (sLine.indexOf(STARTING_DATA_LINE) >= 0) {
// header ends until we read the start data mark
mFileOpened = true;
if (THIS_DEBUG) {
System.out.println("read script header success");
}
return true;
}
}
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
if (THIS_DEBUG) {
System.out.println("Error in reading script header");
}
return false;
| private void | resetValue()
mLastRecordedDownTimeKey = 0;
mLastRecordedDownTimeMotion = 0;
mLastExportDownTimeKey = 0;
mLastExportDownTimeMotion = 0;
mLastRecordedEventTime = -1;
mLastExportEventTime = -1;
| public void | setVerbose(int verbose)
mVerbose = verbose;
| public boolean | validate()check whether we can successfully read the header of the script file
boolean b = readNextBatch();
if (mVerbose > 0) {
System.out.println("Replaying " + mEventCountInScript +
" events with speed " + mSpeed);
}
return b;
|
|