From 3faef17986da97e97a394601f87af423f5e50c08 Mon Sep 17 00:00:00 2001 From: Bill Napier Date: Tue, 11 Aug 2009 16:07:38 -0700 Subject: [PATCH] Add "type" command to allow strings to be more easily typed. --- cmds/monkey/README.NETWORK.txt | 5 ++ .../commands/monkey/MonkeyKeyEvent.java | 54 +++++++++++-------- .../commands/monkey/MonkeySourceNetwork.java | 51 ++++++++++++++++-- 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/cmds/monkey/README.NETWORK.txt b/cmds/monkey/README.NETWORK.txt index 1a1ad9c3c..b80cea9f7 100644 --- a/cmds/monkey/README.NETWORK.txt +++ b/cmds/monkey/README.NETWORK.txt @@ -87,6 +87,11 @@ The press command is a shortcut for the key command. The keycode paramter works just like the key command and will automatically send both the up and the down event. +type string + +This command will simulate a user typing the given string on the +keyboard by generating the proper KeyEvents. + OTHER NOTES There are some convenience features added to allow running without diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java index 877ebb576..d9c68af50 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java @@ -23,7 +23,7 @@ import android.view.KeyEvent; /** * monkey key event */ -public class MonkeyKeyEvent extends MonkeyEvent { +public class MonkeyKeyEvent extends MonkeyEvent { private long mDownTime = -1; private int mMetaState = -1; private int mAction = -1; @@ -32,18 +32,25 @@ public class MonkeyKeyEvent extends MonkeyEvent { private int mRepeatCount = -1; private int mDeviceId = -1; private long mEventTime = -1; - + + private KeyEvent keyEvent = null; + public MonkeyKeyEvent(int action, int keycode) { super(EVENT_TYPE_KEY); mAction = action; mKeyCode = keycode; } - + + public MonkeyKeyEvent(KeyEvent e) { + super(EVENT_TYPE_KEY); + keyEvent = e; + } + public MonkeyKeyEvent(long downTime, long eventTime, int action, int code, int repeat, int metaState, int device, int scancode) { super(EVENT_TYPE_KEY); - + mAction = action; mKeyCode = code; mMetaState = metaState; @@ -53,49 +60,52 @@ public class MonkeyKeyEvent extends MonkeyEvent { mDownTime = downTime; mEventTime = eventTime; } - + public int getKeyCode() { return mKeyCode; } - + public int getAction() { return mAction; } - + public long getDownTime() { return mDownTime; } - + public long getEventTime() { return mEventTime; } - + public void setDownTime(long downTime) { mDownTime = downTime; } - + public void setEventTime(long eventTime) { mEventTime = eventTime; } - - /** + + /** * @return the key event - */ + */ private KeyEvent getEvent() { - if (mDeviceId < 0) { - return new KeyEvent(mAction, mKeyCode); - } - - // for scripts - return new KeyEvent(mDownTime, mEventTime, mAction, - mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode); + if (keyEvent == null) { + if (mDeviceId < 0) { + keyEvent = new KeyEvent(mAction, mKeyCode); + } else { + // for scripts + keyEvent = new KeyEvent(mDownTime, mEventTime, mAction, + mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode); + } + } + return keyEvent; } @Override public boolean isThrottlable() { return (getAction() == KeyEvent.ACTION_UP); } - + @Override public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { if (verbose > 1) { @@ -124,7 +134,7 @@ public class MonkeyKeyEvent extends MonkeyEvent { } catch (RemoteException ex) { return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION; } - + return MonkeyEvent.INJECT_SUCCESS; } } diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java index 63e226c7d..5937f09c1 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java @@ -21,6 +21,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.util.Log; +import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; @@ -217,7 +218,7 @@ public class MonkeySourceNetwork implements MonkeyEventSource { try { sleep = Integer.parseInt(sleepStr); } catch (NumberFormatException e) { - Log.e(TAG, "Not a number: " + sleepStr, e); + Log.e(TAG, "Not a number: " + sleepStr, e); } return new MonkeyThrottleEvent(sleep); } @@ -225,6 +226,34 @@ public class MonkeySourceNetwork implements MonkeyEventSource { } } + /** + * Command to type a string + */ + private static class TypeCommand implements MonkeyCommand { + // wake + public MonkeyEvent translateCommand(List command, + CommandQueue queue) { + if (command.size() == 2) { + String str = command.get(1); + + char[] chars = str.toString().toCharArray(); + + // Convert the string to an array of KeyEvent's for + // the built in keymap. + KeyCharacterMap keyCharacterMap = KeyCharacterMap. + load(KeyCharacterMap.BUILT_IN_KEYBOARD); + KeyEvent[] events = keyCharacterMap.getEvents(chars); + + // enqueue all the events we just got. + for (KeyEvent event : events) { + queue.enqueueEvent(new MonkeyKeyEvent(event)); + } + return new MonkeyNoopEvent(); + } + return null; + } + } + /** * Command to wake the device up */ @@ -325,6 +354,7 @@ public class MonkeySourceNetwork implements MonkeyEventSource { COMMAND_MAP.put("wake", new WakeCommand()); COMMAND_MAP.put("tap", new TapCommand()); COMMAND_MAP.put("press", new PressCommand()); + COMMAND_MAP.put("type", new TypeCommand()); } // QUIT command @@ -400,6 +430,17 @@ public class MonkeySourceNetwork implements MonkeyEventSource { output = new PrintWriter(s.getOutputStream(), true); } + /** + * Helper function for commandLineSplit that replaces quoted + * charaters with their real values. + * + * @param input the string to do replacement on. + * @returns the results with the characters replaced. + */ + private static String replaceQuotedChars(String input) { + return input.replace("\\\"", "\""); + } + /** * This function splits the given line into String parts. It obey's quoted * strings and returns them as a single part. @@ -420,22 +461,22 @@ public class MonkeySourceNetwork implements MonkeyEventSource { String cur = tok.nextToken(); if (!insideQuote && cur.startsWith("\"")) { // begin quote - quotedWord.append(cur); + quotedWord.append(replaceQuotedChars(cur)); insideQuote = true; } else if (insideQuote) { // end quote if (cur.endsWith("\"")) { insideQuote = false; - quotedWord.append(cur); + quotedWord.append(" ").append(replaceQuotedChars(cur)); String word = quotedWord.toString(); // trim off the quotes result.add(word.substring(1, word.length() - 1)); } else { - quotedWord.append(cur); + quotedWord.append(" ").append(replaceQuotedChars(cur)); } } else { - result.add(cur); + result.add(replaceQuotedChars(cur)); } } return result;