Skip to content

Commit 07ee341

Browse files
Jeff BrownAndroid (Google) Code Review
authored andcommitted
Merge "Add tap and swipe capabilities to the "input" tool."
2 parents bdfe770 + 797e446 commit 07ee341

File tree

1 file changed

+88
-49
lines changed
  • cmds/input/src/com/android/commands/input

1 file changed

+88
-49
lines changed

cmds/input/src/com/android/commands/input/Input.java

Lines changed: 88 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
2323
import android.view.IWindowManager;
2424
import android.view.KeyCharacterMap;
2525
import android.view.KeyEvent;
26+
import android.view.MotionEvent;
2627

2728
/**
2829
* Command that sends key events to the device, either by their keycode, or by
2930
* desired character output.
3031
*/
3132

3233
public class Input {
34+
private static final String TAG = "Input";
35+
36+
private IWindowManager mWindowManager;
3337

3438
/**
3539
* Command-line entry point.
@@ -40,6 +44,13 @@ public static void main(String[] args) {
4044
(new Input()).run(args);
4145
}
4246

47+
private IWindowManager getWindowManager() {
48+
if (mWindowManager == null) {
49+
mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
50+
}
51+
return mWindowManager;
52+
}
53+
4354
private void run(String[] args) {
4455
if (args.length < 1) {
4556
showUsage();
@@ -48,19 +59,37 @@ private void run(String[] args) {
4859

4960
String command = args[0];
5061

51-
if (command.equals("text")) {
52-
sendText(args[1]);
53-
} else if (command.equals("keyevent")) {
54-
sendKeyEvent(args[1]);
55-
} else if (command.equals("motionevent")) {
56-
System.err.println("Error: motionevent not yet supported.");
57-
return;
58-
}
59-
else {
60-
System.err.println("Error: Unknown command: " + command);
61-
showUsage();
62-
return;
62+
try {
63+
if (command.equals("text")) {
64+
if (args.length == 2) {
65+
sendText(args[1]);
66+
return;
67+
}
68+
} else if (command.equals("keyevent")) {
69+
if (args.length == 2) {
70+
sendKeyEvent(Integer.parseInt(args[1]));
71+
return;
72+
}
73+
} else if (command.equals("tap")) {
74+
if (args.length == 3) {
75+
sendTap(Float.parseFloat(args[1]), Float.parseFloat(args[2]));
76+
return;
77+
}
78+
} else if (command.equals("swipe")) {
79+
if (args.length == 5) {
80+
sendSwipe(Float.parseFloat(args[1]), Float.parseFloat(args[2]),
81+
Float.parseFloat(args[3]), Float.parseFloat(args[4]));
82+
return;
83+
}
84+
} else {
85+
System.err.println("Error: Unknown command: " + command);
86+
showUsage();
87+
return;
88+
}
89+
} catch (NumberFormatException ex) {
6390
}
91+
System.err.println("Error: Invalid arguments for command: " + command);
92+
showUsage();
6493
}
6594

6695
/**
@@ -69,7 +98,6 @@ private void run(String[] args) {
6998
*
7099
* @param text is a string of characters you want to input to the device.
71100
*/
72-
73101
private void sendText(String text) {
74102

75103
StringBuffer buff = new StringBuffer(text);
@@ -90,55 +118,66 @@ private void sendText(String text) {
90118

91119
char[] chars = buff.toString().toCharArray();
92120

93-
KeyCharacterMap mKeyCharacterMap = KeyCharacterMap.
94-
load(KeyCharacterMap.VIRTUAL_KEYBOARD);
95-
96-
KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
97-
121+
KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
122+
KeyEvent[] events = kcm.getEvents(chars);
98123
for(int i = 0; i < events.length; i++) {
99-
KeyEvent event = events[i];
100-
Log.i("SendKeyEvent", Integer.toString(event.getKeyCode()));
101-
try {
102-
(IWindowManager.Stub
103-
.asInterface(ServiceManager.getService("window")))
104-
.injectKeyEvent(event, true);
105-
} catch (RemoteException e) {
106-
Log.i("Input", "DeadOjbectException");
107-
}
124+
injectKeyEvent(events[i]);
108125
}
109126
}
110127

111-
/**
112-
* Send a single key event.
113-
*
114-
* @param event is a string representing the keycode of the key event you
115-
* want to execute.
116-
*/
117-
private void sendKeyEvent(String event) {
118-
int eventCode = Integer.parseInt(event);
128+
private void sendKeyEvent(int keyCode) {
119129
long now = SystemClock.uptimeMillis();
120-
Log.i("SendKeyEvent", event);
130+
injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
131+
injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
132+
}
133+
134+
private void sendTap(float x, float y) {
135+
long now = SystemClock.uptimeMillis();
136+
injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, 0));
137+
injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x, y, 0));
138+
}
139+
140+
private void sendSwipe(float x1, float y1, float x2, float y2) {
141+
final int NUM_STEPS = 11;
142+
long now = SystemClock.uptimeMillis();
143+
injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x1, y1, 0));
144+
for (int i = 1; i < NUM_STEPS; i++) {
145+
float alpha = (float)i / NUM_STEPS;
146+
injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_MOVE,
147+
lerp(x1, x2, alpha), lerp(y1, y2, alpha), 0));
148+
}
149+
injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x2, y2, 0));
150+
}
151+
152+
private void injectKeyEvent(KeyEvent event) {
153+
try {
154+
Log.i(TAG, "InjectKeyEvent: " + event);
155+
getWindowManager().injectKeyEvent(event, true);
156+
} catch (RemoteException ex) {
157+
Log.i(TAG, "RemoteException", ex);
158+
}
159+
}
160+
161+
private void injectPointerEvent(MotionEvent event) {
121162
try {
122-
KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode, 0);
123-
KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);
124-
(IWindowManager.Stub
125-
.asInterface(ServiceManager.getService("window")))
126-
.injectKeyEvent(down, true);
127-
(IWindowManager.Stub
128-
.asInterface(ServiceManager.getService("window")))
129-
.injectKeyEvent(up, true);
130-
} catch (RemoteException e) {
131-
Log.i("Input", "DeadOjbectException");
163+
Log.i("Input", "InjectPointerEvent: " + event);
164+
getWindowManager().injectPointerEvent(event, true);
165+
} catch (RemoteException ex) {
166+
Log.i(TAG, "RemoteException", ex);
167+
} finally {
168+
event.recycle();
132169
}
133170
}
134171

135-
private void sendMotionEvent(long downTime, int action, float x, float y,
136-
float pressure, float size) {
172+
private static final float lerp(float a, float b, float alpha) {
173+
return (b - a) * alpha + a;
137174
}
138175

139176
private void showUsage() {
140177
System.err.println("usage: input [text|keyevent]");
141178
System.err.println(" input text <string>");
142-
System.err.println(" input keyevent <event_code>");
179+
System.err.println(" input keyevent <key code>");
180+
System.err.println(" input tap <x> <y>");
181+
System.err.println(" input swipe <x1> <y1> <x2> <y2>");
143182
}
144183
}

0 commit comments

Comments
 (0)