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