• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.layoutlib.bridge.util;
18 
19 import android.util.TimeUtils;
20 import android.view.InputDevice;
21 import android.view.KeyEvent;
22 
23 import java.awt.Toolkit;
24 
25 import static android.view.KeyEvent.KEYCODE_0;
26 import static android.view.KeyEvent.KEYCODE_1;
27 import static android.view.KeyEvent.KEYCODE_2;
28 import static android.view.KeyEvent.KEYCODE_3;
29 import static android.view.KeyEvent.KEYCODE_4;
30 import static android.view.KeyEvent.KEYCODE_5;
31 import static android.view.KeyEvent.KEYCODE_6;
32 import static android.view.KeyEvent.KEYCODE_7;
33 import static android.view.KeyEvent.KEYCODE_8;
34 import static android.view.KeyEvent.KEYCODE_9;
35 import static android.view.KeyEvent.KEYCODE_A;
36 import static android.view.KeyEvent.KEYCODE_ALT_LEFT;
37 import static android.view.KeyEvent.KEYCODE_ALT_RIGHT;
38 import static android.view.KeyEvent.KEYCODE_APOSTROPHE;
39 import static android.view.KeyEvent.KEYCODE_B;
40 import static android.view.KeyEvent.KEYCODE_BACKSLASH;
41 import static android.view.KeyEvent.KEYCODE_BREAK;
42 import static android.view.KeyEvent.KEYCODE_C;
43 import static android.view.KeyEvent.KEYCODE_COMMA;
44 import static android.view.KeyEvent.KEYCODE_CTRL_LEFT;
45 import static android.view.KeyEvent.KEYCODE_CTRL_RIGHT;
46 import static android.view.KeyEvent.KEYCODE_D;
47 import static android.view.KeyEvent.KEYCODE_DEL;
48 import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
49 import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
50 import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
51 import static android.view.KeyEvent.KEYCODE_DPAD_UP;
52 import static android.view.KeyEvent.KEYCODE_E;
53 import static android.view.KeyEvent.KEYCODE_ENTER;
54 import static android.view.KeyEvent.KEYCODE_EQUALS;
55 import static android.view.KeyEvent.KEYCODE_ESCAPE;
56 import static android.view.KeyEvent.KEYCODE_F;
57 import static android.view.KeyEvent.KEYCODE_F1;
58 import static android.view.KeyEvent.KEYCODE_F10;
59 import static android.view.KeyEvent.KEYCODE_F11;
60 import static android.view.KeyEvent.KEYCODE_F12;
61 import static android.view.KeyEvent.KEYCODE_F2;
62 import static android.view.KeyEvent.KEYCODE_F3;
63 import static android.view.KeyEvent.KEYCODE_F4;
64 import static android.view.KeyEvent.KEYCODE_F5;
65 import static android.view.KeyEvent.KEYCODE_F6;
66 import static android.view.KeyEvent.KEYCODE_F7;
67 import static android.view.KeyEvent.KEYCODE_F8;
68 import static android.view.KeyEvent.KEYCODE_F9;
69 import static android.view.KeyEvent.KEYCODE_FORWARD_DEL;
70 import static android.view.KeyEvent.KEYCODE_G;
71 import static android.view.KeyEvent.KEYCODE_GRAVE;
72 import static android.view.KeyEvent.KEYCODE_H;
73 import static android.view.KeyEvent.KEYCODE_I;
74 import static android.view.KeyEvent.KEYCODE_INSERT;
75 import static android.view.KeyEvent.KEYCODE_J;
76 import static android.view.KeyEvent.KEYCODE_K;
77 import static android.view.KeyEvent.KEYCODE_L;
78 import static android.view.KeyEvent.KEYCODE_LEFT_BRACKET;
79 import static android.view.KeyEvent.KEYCODE_M;
80 import static android.view.KeyEvent.KEYCODE_META_LEFT;
81 import static android.view.KeyEvent.KEYCODE_META_RIGHT;
82 import static android.view.KeyEvent.KEYCODE_MINUS;
83 import static android.view.KeyEvent.KEYCODE_MOVE_END;
84 import static android.view.KeyEvent.KEYCODE_MOVE_HOME;
85 import static android.view.KeyEvent.KEYCODE_N;
86 import static android.view.KeyEvent.KEYCODE_NUMPAD_0;
87 import static android.view.KeyEvent.KEYCODE_NUMPAD_1;
88 import static android.view.KeyEvent.KEYCODE_NUMPAD_2;
89 import static android.view.KeyEvent.KEYCODE_NUMPAD_3;
90 import static android.view.KeyEvent.KEYCODE_NUMPAD_4;
91 import static android.view.KeyEvent.KEYCODE_NUMPAD_5;
92 import static android.view.KeyEvent.KEYCODE_NUMPAD_6;
93 import static android.view.KeyEvent.KEYCODE_NUMPAD_7;
94 import static android.view.KeyEvent.KEYCODE_NUMPAD_8;
95 import static android.view.KeyEvent.KEYCODE_NUMPAD_9;
96 import static android.view.KeyEvent.KEYCODE_NUMPAD_ADD;
97 import static android.view.KeyEvent.KEYCODE_NUMPAD_COMMA;
98 import static android.view.KeyEvent.KEYCODE_NUMPAD_DIVIDE;
99 import static android.view.KeyEvent.KEYCODE_NUMPAD_DOT;
100 import static android.view.KeyEvent.KEYCODE_NUMPAD_MULTIPLY;
101 import static android.view.KeyEvent.KEYCODE_NUMPAD_SUBTRACT;
102 import static android.view.KeyEvent.KEYCODE_O;
103 import static android.view.KeyEvent.KEYCODE_P;
104 import static android.view.KeyEvent.KEYCODE_PAGE_DOWN;
105 import static android.view.KeyEvent.KEYCODE_PAGE_UP;
106 import static android.view.KeyEvent.KEYCODE_PERIOD;
107 import static android.view.KeyEvent.KEYCODE_Q;
108 import static android.view.KeyEvent.KEYCODE_R;
109 import static android.view.KeyEvent.KEYCODE_RIGHT_BRACKET;
110 import static android.view.KeyEvent.KEYCODE_S;
111 import static android.view.KeyEvent.KEYCODE_SEMICOLON;
112 import static android.view.KeyEvent.KEYCODE_SHIFT_LEFT;
113 import static android.view.KeyEvent.KEYCODE_SHIFT_RIGHT;
114 import static android.view.KeyEvent.KEYCODE_SLASH;
115 import static android.view.KeyEvent.KEYCODE_SPACE;
116 import static android.view.KeyEvent.KEYCODE_T;
117 import static android.view.KeyEvent.KEYCODE_TAB;
118 import static android.view.KeyEvent.KEYCODE_U;
119 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
120 import static android.view.KeyEvent.KEYCODE_V;
121 import static android.view.KeyEvent.KEYCODE_W;
122 import static android.view.KeyEvent.KEYCODE_X;
123 import static android.view.KeyEvent.KEYCODE_Y;
124 import static android.view.KeyEvent.KEYCODE_Z;
125 import static java.awt.event.KeyEvent.KEY_LOCATION_RIGHT;
126 import static java.awt.event.KeyEvent.VK_0;
127 import static java.awt.event.KeyEvent.VK_1;
128 import static java.awt.event.KeyEvent.VK_2;
129 import static java.awt.event.KeyEvent.VK_3;
130 import static java.awt.event.KeyEvent.VK_4;
131 import static java.awt.event.KeyEvent.VK_5;
132 import static java.awt.event.KeyEvent.VK_6;
133 import static java.awt.event.KeyEvent.VK_7;
134 import static java.awt.event.KeyEvent.VK_8;
135 import static java.awt.event.KeyEvent.VK_9;
136 import static java.awt.event.KeyEvent.VK_A;
137 import static java.awt.event.KeyEvent.VK_ADD;
138 import static java.awt.event.KeyEvent.VK_ALT;
139 import static java.awt.event.KeyEvent.VK_ALT_GRAPH;
140 import static java.awt.event.KeyEvent.VK_B;
141 import static java.awt.event.KeyEvent.VK_BACK_QUOTE;
142 import static java.awt.event.KeyEvent.VK_BACK_SLASH;
143 import static java.awt.event.KeyEvent.VK_BACK_SPACE;
144 import static java.awt.event.KeyEvent.VK_C;
145 import static java.awt.event.KeyEvent.VK_CAPS_LOCK;
146 import static java.awt.event.KeyEvent.VK_CLOSE_BRACKET;
147 import static java.awt.event.KeyEvent.VK_COMMA;
148 import static java.awt.event.KeyEvent.VK_CONTROL;
149 import static java.awt.event.KeyEvent.VK_D;
150 import static java.awt.event.KeyEvent.VK_DECIMAL;
151 import static java.awt.event.KeyEvent.VK_DELETE;
152 import static java.awt.event.KeyEvent.VK_DIVIDE;
153 import static java.awt.event.KeyEvent.VK_DOWN;
154 import static java.awt.event.KeyEvent.VK_E;
155 import static java.awt.event.KeyEvent.VK_END;
156 import static java.awt.event.KeyEvent.VK_ENTER;
157 import static java.awt.event.KeyEvent.VK_EQUALS;
158 import static java.awt.event.KeyEvent.VK_ESCAPE;
159 import static java.awt.event.KeyEvent.VK_F;
160 import static java.awt.event.KeyEvent.VK_F1;
161 import static java.awt.event.KeyEvent.VK_F10;
162 import static java.awt.event.KeyEvent.VK_F11;
163 import static java.awt.event.KeyEvent.VK_F12;
164 import static java.awt.event.KeyEvent.VK_F2;
165 import static java.awt.event.KeyEvent.VK_F3;
166 import static java.awt.event.KeyEvent.VK_F4;
167 import static java.awt.event.KeyEvent.VK_F5;
168 import static java.awt.event.KeyEvent.VK_F6;
169 import static java.awt.event.KeyEvent.VK_F7;
170 import static java.awt.event.KeyEvent.VK_F8;
171 import static java.awt.event.KeyEvent.VK_F9;
172 import static java.awt.event.KeyEvent.VK_G;
173 import static java.awt.event.KeyEvent.VK_H;
174 import static java.awt.event.KeyEvent.VK_HOME;
175 import static java.awt.event.KeyEvent.VK_I;
176 import static java.awt.event.KeyEvent.VK_INSERT;
177 import static java.awt.event.KeyEvent.VK_J;
178 import static java.awt.event.KeyEvent.VK_K;
179 import static java.awt.event.KeyEvent.VK_L;
180 import static java.awt.event.KeyEvent.VK_LEFT;
181 import static java.awt.event.KeyEvent.VK_M;
182 import static java.awt.event.KeyEvent.VK_META;
183 import static java.awt.event.KeyEvent.VK_MINUS;
184 import static java.awt.event.KeyEvent.VK_MULTIPLY;
185 import static java.awt.event.KeyEvent.VK_N;
186 import static java.awt.event.KeyEvent.VK_NUMPAD0;
187 import static java.awt.event.KeyEvent.VK_NUMPAD1;
188 import static java.awt.event.KeyEvent.VK_NUMPAD2;
189 import static java.awt.event.KeyEvent.VK_NUMPAD3;
190 import static java.awt.event.KeyEvent.VK_NUMPAD4;
191 import static java.awt.event.KeyEvent.VK_NUMPAD5;
192 import static java.awt.event.KeyEvent.VK_NUMPAD6;
193 import static java.awt.event.KeyEvent.VK_NUMPAD7;
194 import static java.awt.event.KeyEvent.VK_NUMPAD8;
195 import static java.awt.event.KeyEvent.VK_NUMPAD9;
196 import static java.awt.event.KeyEvent.VK_NUM_LOCK;
197 import static java.awt.event.KeyEvent.VK_O;
198 import static java.awt.event.KeyEvent.VK_OPEN_BRACKET;
199 import static java.awt.event.KeyEvent.VK_P;
200 import static java.awt.event.KeyEvent.VK_PAGE_DOWN;
201 import static java.awt.event.KeyEvent.VK_PAGE_UP;
202 import static java.awt.event.KeyEvent.VK_PAUSE;
203 import static java.awt.event.KeyEvent.VK_PERIOD;
204 import static java.awt.event.KeyEvent.VK_Q;
205 import static java.awt.event.KeyEvent.VK_QUOTE;
206 import static java.awt.event.KeyEvent.VK_R;
207 import static java.awt.event.KeyEvent.VK_RIGHT;
208 import static java.awt.event.KeyEvent.VK_S;
209 import static java.awt.event.KeyEvent.VK_SEMICOLON;
210 import static java.awt.event.KeyEvent.VK_SEPARATOR;
211 import static java.awt.event.KeyEvent.VK_SHIFT;
212 import static java.awt.event.KeyEvent.VK_SLASH;
213 import static java.awt.event.KeyEvent.VK_SPACE;
214 import static java.awt.event.KeyEvent.VK_SUBTRACT;
215 import static java.awt.event.KeyEvent.VK_T;
216 import static java.awt.event.KeyEvent.VK_TAB;
217 import static java.awt.event.KeyEvent.VK_U;
218 import static java.awt.event.KeyEvent.VK_UP;
219 import static java.awt.event.KeyEvent.VK_V;
220 import static java.awt.event.KeyEvent.VK_W;
221 import static java.awt.event.KeyEvent.VK_X;
222 import static java.awt.event.KeyEvent.VK_Y;
223 import static java.awt.event.KeyEvent.VK_Z;
224 
225 public class KeyEventHandling {
226 
227     /**
228      * Creates an Android KeyEvent from a Java KeyEvent
229      */
javaToAndroidKeyEvent(java.awt.event.KeyEvent event, long downTimeNanos, long currentTimeNanos)230     public static KeyEvent javaToAndroidKeyEvent(java.awt.event.KeyEvent event, long downTimeNanos,
231             long currentTimeNanos) {
232         int androidKeyCode = javaToAndroidKeyCode(event.getKeyCode(), event.getKeyLocation());
233         int metaState = 0;
234         if (event.isAltDown() | event.isAltGraphDown()) {
235             metaState |= KeyEvent.META_ALT_ON;
236         }
237         if (event.isMetaDown()) {
238             metaState |= KeyEvent.META_META_ON;
239         }
240         if (event.isControlDown()) {
241             metaState |= KeyEvent.META_CTRL_ON;
242         }
243         if (event.isShiftDown()) {
244             metaState |= KeyEvent.META_SHIFT_ON;
245         }
246         try {
247             if (Toolkit.getDefaultToolkit().getLockingKeyState(VK_CAPS_LOCK)) {
248                 metaState |= KeyEvent.META_CAPS_LOCK_ON;
249             }
250             if (Toolkit.getDefaultToolkit().getLockingKeyState(VK_NUM_LOCK)) {
251                 metaState |= KeyEvent.META_NUM_LOCK_ON;
252             }
253         } catch (UnsupportedOperationException ignore) {
254         }
255         int keyEventType;
256         if (event.getID() == java.awt.event.KeyEvent.KEY_PRESSED) {
257             keyEventType = KeyEvent.ACTION_DOWN;
258         } else {
259             keyEventType = KeyEvent.ACTION_UP;
260         }
261         // Use deviceId 1 as that corresponds to the Generic keyboard.
262         return KeyEvent.obtain(downTimeNanos / TimeUtils.NANOS_PER_MS,
263                 currentTimeNanos / TimeUtils.NANOS_PER_MS, keyEventType, androidKeyCode, 0,
264                 metaState, 1, 0, 0, InputDevice.SOURCE_KEYBOARD, null);
265     }
266 
javaToAndroidKeyCode(int keyCode, int location)267     private static int javaToAndroidKeyCode(int keyCode, int location) {
268         switch(keyCode) {
269             case VK_0: return KEYCODE_0;
270             case VK_1: return KEYCODE_1;
271             case VK_2: return KEYCODE_2;
272             case VK_3: return KEYCODE_3;
273             case VK_4: return KEYCODE_4;
274             case VK_5: return KEYCODE_5;
275             case VK_6: return KEYCODE_6;
276             case VK_7: return KEYCODE_7;
277             case VK_8: return KEYCODE_8;
278             case VK_9: return KEYCODE_9;
279 
280             case VK_A: return KEYCODE_A;
281             case VK_B: return KEYCODE_B;
282             case VK_C: return KEYCODE_C;
283             case VK_D: return KEYCODE_D;
284             case VK_E: return KEYCODE_E;
285             case VK_F: return KEYCODE_F;
286             case VK_G: return KEYCODE_G;
287             case VK_H: return KEYCODE_H;
288             case VK_I: return KEYCODE_I;
289             case VK_J: return KEYCODE_J;
290             case VK_K: return KEYCODE_K;
291             case VK_L: return KEYCODE_L;
292             case VK_M: return KEYCODE_M;
293             case VK_N: return KEYCODE_N;
294             case VK_O: return KEYCODE_O;
295             case VK_P: return KEYCODE_P;
296             case VK_Q: return KEYCODE_Q;
297             case VK_R: return KEYCODE_R;
298             case VK_S: return KEYCODE_S;
299             case VK_T: return KEYCODE_T;
300             case VK_U: return KEYCODE_U;
301             case VK_V: return KEYCODE_V;
302             case VK_W: return KEYCODE_W;
303             case VK_X: return KEYCODE_X;
304             case VK_Y: return KEYCODE_Y;
305             case VK_Z: return KEYCODE_Z;
306 
307             case VK_SPACE: return KEYCODE_SPACE;
308             case VK_ENTER: return KEYCODE_ENTER;
309             case VK_TAB: return KEYCODE_TAB;
310             case VK_COMMA: return KEYCODE_COMMA;
311             case VK_PERIOD: return KEYCODE_PERIOD;
312             case VK_SLASH: return KEYCODE_SLASH;
313             case VK_BACK_QUOTE: return KEYCODE_GRAVE;
314             case VK_MINUS: return KEYCODE_MINUS;
315             case VK_EQUALS: return KEYCODE_EQUALS;
316             case VK_OPEN_BRACKET: return KEYCODE_LEFT_BRACKET;
317             case VK_CLOSE_BRACKET: return KEYCODE_RIGHT_BRACKET;
318             case VK_BACK_SLASH: return KEYCODE_BACKSLASH;
319             case VK_SEMICOLON: return KEYCODE_SEMICOLON;
320             case VK_QUOTE: return KEYCODE_APOSTROPHE;
321 
322             case VK_ESCAPE: return KEYCODE_ESCAPE;
323             case VK_BACK_SPACE: return KEYCODE_DEL;
324 
325             case VK_NUMPAD0: return KEYCODE_NUMPAD_0;
326             case VK_NUMPAD1: return KEYCODE_NUMPAD_1;
327             case VK_NUMPAD2: return KEYCODE_NUMPAD_2;
328             case VK_NUMPAD3: return KEYCODE_NUMPAD_3;
329             case VK_NUMPAD4: return KEYCODE_NUMPAD_4;
330             case VK_NUMPAD5: return KEYCODE_NUMPAD_5;
331             case VK_NUMPAD6: return KEYCODE_NUMPAD_6;
332             case VK_NUMPAD7: return KEYCODE_NUMPAD_7;
333             case VK_NUMPAD8: return KEYCODE_NUMPAD_8;
334             case VK_NUMPAD9: return KEYCODE_NUMPAD_9;
335             case VK_MULTIPLY: return KEYCODE_NUMPAD_MULTIPLY;
336             case VK_ADD: return KEYCODE_NUMPAD_ADD;
337             case VK_SEPARATOR: return KEYCODE_NUMPAD_COMMA;
338             case VK_SUBTRACT: return KEYCODE_NUMPAD_SUBTRACT;
339             case VK_DECIMAL: return KEYCODE_NUMPAD_DOT;
340             case VK_DIVIDE: return KEYCODE_NUMPAD_DIVIDE;
341 
342             case VK_DOWN: return KEYCODE_DPAD_DOWN;
343             case VK_LEFT: return KEYCODE_DPAD_LEFT;
344             case VK_RIGHT: return KEYCODE_DPAD_RIGHT;
345             case VK_UP: return KEYCODE_DPAD_UP;
346 
347             case VK_ALT: return KEYCODE_ALT_LEFT;
348             case VK_ALT_GRAPH: return KEYCODE_ALT_RIGHT;
349             case VK_SHIFT: {
350                 if (location == KEY_LOCATION_RIGHT) {
351                     return KEYCODE_SHIFT_RIGHT;
352                 } else {
353                     return KEYCODE_SHIFT_LEFT;
354                 }
355             }
356             case VK_CONTROL: {
357                 if (location == KEY_LOCATION_RIGHT) {
358                     return KEYCODE_CTRL_RIGHT;
359                 } else {
360                     return KEYCODE_CTRL_LEFT;
361                 }
362             }
363             case VK_META: {
364                 if (location == KEY_LOCATION_RIGHT) {
365                     return KEYCODE_META_RIGHT;
366                 } else {
367                     return KEYCODE_META_LEFT;
368                 }
369             }
370 
371             case VK_PAGE_DOWN: return KEYCODE_PAGE_DOWN;
372             case VK_PAGE_UP: return KEYCODE_PAGE_UP;
373             case VK_INSERT: return KEYCODE_INSERT;
374             case VK_DELETE: return KEYCODE_FORWARD_DEL;
375             case VK_HOME: return KEYCODE_MOVE_HOME;
376             case VK_END: return KEYCODE_MOVE_END;
377             case VK_PAUSE: return KEYCODE_BREAK;
378 
379             case VK_F1: return KEYCODE_F1;
380             case VK_F2: return KEYCODE_F2;
381             case VK_F3: return KEYCODE_F3;
382             case VK_F4: return KEYCODE_F4;
383             case VK_F5: return KEYCODE_F5;
384             case VK_F6: return KEYCODE_F6;
385             case VK_F7: return KEYCODE_F7;
386             case VK_F8: return KEYCODE_F8;
387             case VK_F9: return KEYCODE_F9;
388             case VK_F10: return KEYCODE_F10;
389             case VK_F11: return KEYCODE_F11;
390             case VK_F12: return KEYCODE_F12;
391         }
392 
393         return KEYCODE_UNKNOWN;
394     }
395 }
396