1 /* 2 * Copyright (C) 2008 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 #define LOG_TAG "KeyCharacterMap" 18 19 #include <stdlib.h> 20 #include <string.h> 21 22 #if HAVE_ANDROID_OS 23 #include <binder/Parcel.h> 24 #endif 25 26 #include <android/keycodes.h> 27 #include <input/InputEventLabels.h> 28 #include <input/Keyboard.h> 29 #include <input/KeyCharacterMap.h> 30 31 #include <utils/Log.h> 32 #include <utils/Errors.h> 33 #include <utils/Tokenizer.h> 34 #include <utils/Timers.h> 35 36 // Enables debug output for the parser. 37 #define DEBUG_PARSER 0 38 39 // Enables debug output for parser performance. 40 #define DEBUG_PARSER_PERFORMANCE 0 41 42 // Enables debug output for mapping. 43 #define DEBUG_MAPPING 0 44 45 46 namespace android { 47 48 static const char* WHITESPACE = " \t\r"; 49 static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:"; 50 51 struct Modifier { 52 const char* label; 53 int32_t metaState; 54 }; 55 static const Modifier modifiers[] = { 56 { "shift", AMETA_SHIFT_ON }, 57 { "lshift", AMETA_SHIFT_LEFT_ON }, 58 { "rshift", AMETA_SHIFT_RIGHT_ON }, 59 { "alt", AMETA_ALT_ON }, 60 { "lalt", AMETA_ALT_LEFT_ON }, 61 { "ralt", AMETA_ALT_RIGHT_ON }, 62 { "ctrl", AMETA_CTRL_ON }, 63 { "lctrl", AMETA_CTRL_LEFT_ON }, 64 { "rctrl", AMETA_CTRL_RIGHT_ON }, 65 { "meta", AMETA_META_ON }, 66 { "lmeta", AMETA_META_LEFT_ON }, 67 { "rmeta", AMETA_META_RIGHT_ON }, 68 { "sym", AMETA_SYM_ON }, 69 { "fn", AMETA_FUNCTION_ON }, 70 { "capslock", AMETA_CAPS_LOCK_ON }, 71 { "numlock", AMETA_NUM_LOCK_ON }, 72 { "scrolllock", AMETA_SCROLL_LOCK_ON }, 73 }; 74 75 #if DEBUG_MAPPING 76 static String8 toString(const char16_t* chars, size_t numChars) { 77 String8 result; 78 for (size_t i = 0; i < numChars; i++) { 79 result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]); 80 } 81 return result; 82 } 83 #endif 84 85 86 // --- KeyCharacterMap --- 87 88 sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap(); 89 90 KeyCharacterMap::KeyCharacterMap() : 91 mType(KEYBOARD_TYPE_UNKNOWN) { 92 } 93 94 KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) : 95 RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode), 96 mKeysByUsageCode(other.mKeysByUsageCode) { 97 for (size_t i = 0; i < other.mKeys.size(); i++) { 98 mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i))); 99 } 100 } 101 102 KeyCharacterMap::~KeyCharacterMap() { 103 for (size_t i = 0; i < mKeys.size(); i++) { 104 Key* key = mKeys.editValueAt(i); 105 delete key; 106 } 107 } 108 109 status_t KeyCharacterMap::load(const String8& filename, 110 Format format, sp<KeyCharacterMap>* outMap) { 111 outMap->clear(); 112 113 Tokenizer* tokenizer; 114 status_t status = Tokenizer::open(filename, &tokenizer); 115 if (status) { 116 ALOGE("Error %d opening key character map file %s.", status, filename.string()); 117 } else { 118 status = load(tokenizer, format, outMap); 119 delete tokenizer; 120 } 121 return status; 122 } 123 124 status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents, 125 Format format, sp<KeyCharacterMap>* outMap) { 126 outMap->clear(); 127 128 Tokenizer* tokenizer; 129 status_t status = Tokenizer::fromContents(filename, contents, &tokenizer); 130 if (status) { 131 ALOGE("Error %d opening key character map.", status); 132 } else { 133 status = load(tokenizer, format, outMap); 134 delete tokenizer; 135 } 136 return status; 137 } 138 139 status_t KeyCharacterMap::load(Tokenizer* tokenizer, 140 Format format, sp<KeyCharacterMap>* outMap) { 141 status_t status = OK; 142 sp<KeyCharacterMap> map = new KeyCharacterMap(); 143 if (!map.get()) { 144 ALOGE("Error allocating key character map."); 145 status = NO_MEMORY; 146 } else { 147 #if DEBUG_PARSER_PERFORMANCE 148 nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); 149 #endif 150 Parser parser(map.get(), tokenizer, format); 151 status = parser.parse(); 152 #if DEBUG_PARSER_PERFORMANCE 153 nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; 154 ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.", 155 tokenizer->getFilename().string(), tokenizer->getLineNumber(), 156 elapsedTime / 1000000.0); 157 #endif 158 if (!status) { 159 *outMap = map; 160 } 161 } 162 return status; 163 } 164 165 sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base, 166 const sp<KeyCharacterMap>& overlay) { 167 if (overlay == NULL) { 168 return base; 169 } 170 if (base == NULL) { 171 return overlay; 172 } 173 174 sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get()); 175 for (size_t i = 0; i < overlay->mKeys.size(); i++) { 176 int32_t keyCode = overlay->mKeys.keyAt(i); 177 Key* key = overlay->mKeys.valueAt(i); 178 ssize_t oldIndex = map->mKeys.indexOfKey(keyCode); 179 if (oldIndex >= 0) { 180 delete map->mKeys.valueAt(oldIndex); 181 map->mKeys.editValueAt(oldIndex) = new Key(*key); 182 } else { 183 map->mKeys.add(keyCode, new Key(*key)); 184 } 185 } 186 187 for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) { 188 map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i), 189 overlay->mKeysByScanCode.valueAt(i)); 190 } 191 192 for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) { 193 map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i), 194 overlay->mKeysByUsageCode.valueAt(i)); 195 } 196 return map; 197 } 198 199 sp<KeyCharacterMap> KeyCharacterMap::empty() { 200 return sEmpty; 201 } 202 203 int32_t KeyCharacterMap::getKeyboardType() const { 204 return mType; 205 } 206 207 char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const { 208 char16_t result = 0; 209 const Key* key; 210 if (getKey(keyCode, &key)) { 211 result = key->label; 212 } 213 #if DEBUG_MAPPING 214 ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result); 215 #endif 216 return result; 217 } 218 219 char16_t KeyCharacterMap::getNumber(int32_t keyCode) const { 220 char16_t result = 0; 221 const Key* key; 222 if (getKey(keyCode, &key)) { 223 result = key->number; 224 } 225 #if DEBUG_MAPPING 226 ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result); 227 #endif 228 return result; 229 } 230 231 char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const { 232 char16_t result = 0; 233 const Key* key; 234 const Behavior* behavior; 235 if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { 236 result = behavior->character; 237 } 238 #if DEBUG_MAPPING 239 ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result); 240 #endif 241 return result; 242 } 243 244 bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState, 245 FallbackAction* outFallbackAction) const { 246 outFallbackAction->keyCode = 0; 247 outFallbackAction->metaState = 0; 248 249 bool result = false; 250 const Key* key; 251 const Behavior* behavior; 252 if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { 253 if (behavior->fallbackKeyCode) { 254 outFallbackAction->keyCode = behavior->fallbackKeyCode; 255 outFallbackAction->metaState = metaState & ~behavior->metaState; 256 result = true; 257 } 258 } 259 #if DEBUG_MAPPING 260 ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, " 261 "fallback keyCode=%d, fallback metaState=0x%08x.", 262 keyCode, metaState, result ? "true" : "false", 263 outFallbackAction->keyCode, outFallbackAction->metaState); 264 #endif 265 return result; 266 } 267 268 char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars, 269 int32_t metaState) const { 270 char16_t result = 0; 271 const Key* key; 272 if (getKey(keyCode, &key)) { 273 // Try to find the most general behavior that maps to this character. 274 // For example, the base key behavior will usually be last in the list. 275 // However, if we find a perfect meta state match for one behavior then use that one. 276 for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) { 277 if (behavior->character) { 278 for (size_t i = 0; i < numChars; i++) { 279 if (behavior->character == chars[i]) { 280 result = behavior->character; 281 if ((behavior->metaState & metaState) == behavior->metaState) { 282 goto ExactMatch; 283 } 284 break; 285 } 286 } 287 } 288 } 289 ExactMatch: ; 290 } 291 #if DEBUG_MAPPING 292 ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.", 293 keyCode, toString(chars, numChars).string(), metaState, result); 294 #endif 295 return result; 296 } 297 298 bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, 299 Vector<KeyEvent>& outEvents) const { 300 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 301 302 for (size_t i = 0; i < numChars; i++) { 303 int32_t keyCode, metaState; 304 char16_t ch = chars[i]; 305 if (!findKey(ch, &keyCode, &metaState)) { 306 #if DEBUG_MAPPING 307 ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.", 308 deviceId, toString(chars, numChars).string(), ch); 309 #endif 310 return false; 311 } 312 313 int32_t currentMetaState = 0; 314 addMetaKeys(outEvents, deviceId, metaState, true, now, ¤tMetaState); 315 addKey(outEvents, deviceId, keyCode, currentMetaState, true, now); 316 addKey(outEvents, deviceId, keyCode, currentMetaState, false, now); 317 addMetaKeys(outEvents, deviceId, metaState, false, now, ¤tMetaState); 318 } 319 #if DEBUG_MAPPING 320 ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.", 321 deviceId, toString(chars, numChars).string(), int32_t(outEvents.size())); 322 for (size_t i = 0; i < outEvents.size(); i++) { 323 ALOGD(" Key: keyCode=%d, metaState=0x%08x, %s.", 324 outEvents[i].getKeyCode(), outEvents[i].getMetaState(), 325 outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up"); 326 } 327 #endif 328 return true; 329 } 330 331 status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const { 332 if (usageCode) { 333 ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); 334 if (index >= 0) { 335 #if DEBUG_MAPPING 336 ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", 337 scanCode, usageCode, *outKeyCode); 338 #endif 339 *outKeyCode = mKeysByUsageCode.valueAt(index); 340 return OK; 341 } 342 } 343 if (scanCode) { 344 ssize_t index = mKeysByScanCode.indexOfKey(scanCode); 345 if (index >= 0) { 346 #if DEBUG_MAPPING 347 ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", 348 scanCode, usageCode, *outKeyCode); 349 #endif 350 *outKeyCode = mKeysByScanCode.valueAt(index); 351 return OK; 352 } 353 } 354 355 #if DEBUG_MAPPING 356 ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); 357 #endif 358 *outKeyCode = AKEYCODE_UNKNOWN; 359 return NAME_NOT_FOUND; 360 } 361 362 bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { 363 ssize_t index = mKeys.indexOfKey(keyCode); 364 if (index >= 0) { 365 *outKey = mKeys.valueAt(index); 366 return true; 367 } 368 return false; 369 } 370 371 bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState, 372 const Key** outKey, const Behavior** outBehavior) const { 373 const Key* key; 374 if (getKey(keyCode, &key)) { 375 const Behavior* behavior = key->firstBehavior; 376 while (behavior) { 377 if (matchesMetaState(metaState, behavior->metaState)) { 378 *outKey = key; 379 *outBehavior = behavior; 380 return true; 381 } 382 behavior = behavior->next; 383 } 384 } 385 return false; 386 } 387 388 bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) { 389 // Behavior must have at least the set of meta states specified. 390 // And if the key event has CTRL, ALT or META then the behavior must exactly 391 // match those, taking into account that a behavior can specify that it handles 392 // one, both or either of a left/right modifier pair. 393 if ((eventMetaState & behaviorMetaState) == behaviorMetaState) { 394 const int32_t EXACT_META_STATES = 395 AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON 396 | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON 397 | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON; 398 int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES; 399 if (behaviorMetaState & AMETA_CTRL_ON) { 400 unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); 401 } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { 402 unmatchedMetaState &= ~AMETA_CTRL_ON; 403 } 404 if (behaviorMetaState & AMETA_ALT_ON) { 405 unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); 406 } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { 407 unmatchedMetaState &= ~AMETA_ALT_ON; 408 } 409 if (behaviorMetaState & AMETA_META_ON) { 410 unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON); 411 } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) { 412 unmatchedMetaState &= ~AMETA_META_ON; 413 } 414 return !unmatchedMetaState; 415 } 416 return false; 417 } 418 419 bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const { 420 if (!ch) { 421 return false; 422 } 423 424 for (size_t i = 0; i < mKeys.size(); i++) { 425 const Key* key = mKeys.valueAt(i); 426 427 // Try to find the most general behavior that maps to this character. 428 // For example, the base key behavior will usually be last in the list. 429 const Behavior* found = NULL; 430 for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) { 431 if (behavior->character == ch) { 432 found = behavior; 433 } 434 } 435 if (found) { 436 *outKeyCode = mKeys.keyAt(i); 437 *outMetaState = found->metaState; 438 return true; 439 } 440 } 441 return false; 442 } 443 444 void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents, 445 int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) { 446 outEvents.push(); 447 KeyEvent& event = outEvents.editTop(); 448 event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD, 449 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, 450 0, keyCode, 0, metaState, 0, time, time); 451 } 452 453 void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents, 454 int32_t deviceId, int32_t metaState, bool down, nsecs_t time, 455 int32_t* currentMetaState) { 456 // Add and remove meta keys symmetrically. 457 if (down) { 458 addLockedMetaKey(outEvents, deviceId, metaState, time, 459 AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState); 460 addLockedMetaKey(outEvents, deviceId, metaState, time, 461 AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState); 462 addLockedMetaKey(outEvents, deviceId, metaState, time, 463 AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState); 464 465 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 466 AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON, 467 AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON, 468 AMETA_SHIFT_ON, currentMetaState); 469 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 470 AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON, 471 AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON, 472 AMETA_ALT_ON, currentMetaState); 473 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 474 AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON, 475 AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON, 476 AMETA_CTRL_ON, currentMetaState); 477 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 478 AKEYCODE_META_LEFT, AMETA_META_LEFT_ON, 479 AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON, 480 AMETA_META_ON, currentMetaState); 481 482 addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 483 AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState); 484 addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time, 485 AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState); 486 } else { 487 addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 488 AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState); 489 addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 490 AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState); 491 492 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 493 AKEYCODE_META_LEFT, AMETA_META_LEFT_ON, 494 AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON, 495 AMETA_META_ON, currentMetaState); 496 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 497 AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON, 498 AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON, 499 AMETA_CTRL_ON, currentMetaState); 500 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 501 AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON, 502 AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON, 503 AMETA_ALT_ON, currentMetaState); 504 addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time, 505 AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON, 506 AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON, 507 AMETA_SHIFT_ON, currentMetaState); 508 509 addLockedMetaKey(outEvents, deviceId, metaState, time, 510 AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState); 511 addLockedMetaKey(outEvents, deviceId, metaState, time, 512 AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState); 513 addLockedMetaKey(outEvents, deviceId, metaState, time, 514 AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState); 515 } 516 } 517 518 bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents, 519 int32_t deviceId, int32_t metaState, bool down, nsecs_t time, 520 int32_t keyCode, int32_t keyMetaState, 521 int32_t* currentMetaState) { 522 if ((metaState & keyMetaState) == keyMetaState) { 523 *currentMetaState = updateMetaState(keyCode, down, *currentMetaState); 524 addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time); 525 return true; 526 } 527 return false; 528 } 529 530 void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents, 531 int32_t deviceId, int32_t metaState, bool down, nsecs_t time, 532 int32_t leftKeyCode, int32_t leftKeyMetaState, 533 int32_t rightKeyCode, int32_t rightKeyMetaState, 534 int32_t eitherKeyMetaState, 535 int32_t* currentMetaState) { 536 bool specific = false; 537 specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time, 538 leftKeyCode, leftKeyMetaState, currentMetaState); 539 specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time, 540 rightKeyCode, rightKeyMetaState, currentMetaState); 541 542 if (!specific) { 543 addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time, 544 leftKeyCode, eitherKeyMetaState, currentMetaState); 545 } 546 } 547 548 void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents, 549 int32_t deviceId, int32_t metaState, nsecs_t time, 550 int32_t keyCode, int32_t keyMetaState, 551 int32_t* currentMetaState) { 552 if ((metaState & keyMetaState) == keyMetaState) { 553 *currentMetaState = updateMetaState(keyCode, true, *currentMetaState); 554 addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time); 555 *currentMetaState = updateMetaState(keyCode, false, *currentMetaState); 556 addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time); 557 } 558 } 559 560 #if HAVE_ANDROID_OS 561 sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { 562 sp<KeyCharacterMap> map = new KeyCharacterMap(); 563 map->mType = parcel->readInt32(); 564 size_t numKeys = parcel->readInt32(); 565 if (parcel->errorCheck()) { 566 return NULL; 567 } 568 569 for (size_t i = 0; i < numKeys; i++) { 570 int32_t keyCode = parcel->readInt32(); 571 char16_t label = parcel->readInt32(); 572 char16_t number = parcel->readInt32(); 573 if (parcel->errorCheck()) { 574 return NULL; 575 } 576 577 Key* key = new Key(); 578 key->label = label; 579 key->number = number; 580 map->mKeys.add(keyCode, key); 581 582 Behavior* lastBehavior = NULL; 583 while (parcel->readInt32()) { 584 int32_t metaState = parcel->readInt32(); 585 char16_t character = parcel->readInt32(); 586 int32_t fallbackKeyCode = parcel->readInt32(); 587 if (parcel->errorCheck()) { 588 return NULL; 589 } 590 591 Behavior* behavior = new Behavior(); 592 behavior->metaState = metaState; 593 behavior->character = character; 594 behavior->fallbackKeyCode = fallbackKeyCode; 595 if (lastBehavior) { 596 lastBehavior->next = behavior; 597 } else { 598 key->firstBehavior = behavior; 599 } 600 lastBehavior = behavior; 601 } 602 603 if (parcel->errorCheck()) { 604 return NULL; 605 } 606 } 607 return map; 608 } 609 610 void KeyCharacterMap::writeToParcel(Parcel* parcel) const { 611 parcel->writeInt32(mType); 612 613 size_t numKeys = mKeys.size(); 614 parcel->writeInt32(numKeys); 615 for (size_t i = 0; i < numKeys; i++) { 616 int32_t keyCode = mKeys.keyAt(i); 617 const Key* key = mKeys.valueAt(i); 618 parcel->writeInt32(keyCode); 619 parcel->writeInt32(key->label); 620 parcel->writeInt32(key->number); 621 for (const Behavior* behavior = key->firstBehavior; behavior != NULL; 622 behavior = behavior->next) { 623 parcel->writeInt32(1); 624 parcel->writeInt32(behavior->metaState); 625 parcel->writeInt32(behavior->character); 626 parcel->writeInt32(behavior->fallbackKeyCode); 627 } 628 parcel->writeInt32(0); 629 } 630 } 631 #endif 632 633 634 // --- KeyCharacterMap::Key --- 635 636 KeyCharacterMap::Key::Key() : 637 label(0), number(0), firstBehavior(NULL) { 638 } 639 640 KeyCharacterMap::Key::Key(const Key& other) : 641 label(other.label), number(other.number), 642 firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) { 643 } 644 645 KeyCharacterMap::Key::~Key() { 646 Behavior* behavior = firstBehavior; 647 while (behavior) { 648 Behavior* next = behavior->next; 649 delete behavior; 650 behavior = next; 651 } 652 } 653 654 655 // --- KeyCharacterMap::Behavior --- 656 657 KeyCharacterMap::Behavior::Behavior() : 658 next(NULL), metaState(0), character(0), fallbackKeyCode(0) { 659 } 660 661 KeyCharacterMap::Behavior::Behavior(const Behavior& other) : 662 next(other.next ? new Behavior(*other.next) : NULL), 663 metaState(other.metaState), character(other.character), 664 fallbackKeyCode(other.fallbackKeyCode) { 665 } 666 667 668 // --- KeyCharacterMap::Parser --- 669 670 KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) : 671 mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) { 672 } 673 674 KeyCharacterMap::Parser::~Parser() { 675 } 676 677 status_t KeyCharacterMap::Parser::parse() { 678 while (!mTokenizer->isEof()) { 679 #if DEBUG_PARSER 680 ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(), 681 mTokenizer->peekRemainderOfLine().string()); 682 #endif 683 684 mTokenizer->skipDelimiters(WHITESPACE); 685 686 if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') { 687 switch (mState) { 688 case STATE_TOP: { 689 String8 keywordToken = mTokenizer->nextToken(WHITESPACE); 690 if (keywordToken == "type") { 691 mTokenizer->skipDelimiters(WHITESPACE); 692 status_t status = parseType(); 693 if (status) return status; 694 } else if (keywordToken == "map") { 695 mTokenizer->skipDelimiters(WHITESPACE); 696 status_t status = parseMap(); 697 if (status) return status; 698 } else if (keywordToken == "key") { 699 mTokenizer->skipDelimiters(WHITESPACE); 700 status_t status = parseKey(); 701 if (status) return status; 702 } else { 703 ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(), 704 keywordToken.string()); 705 return BAD_VALUE; 706 } 707 break; 708 } 709 710 case STATE_KEY: { 711 status_t status = parseKeyProperty(); 712 if (status) return status; 713 break; 714 } 715 } 716 717 mTokenizer->skipDelimiters(WHITESPACE); 718 if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') { 719 ALOGE("%s: Expected end of line or trailing comment, got '%s'.", 720 mTokenizer->getLocation().string(), 721 mTokenizer->peekRemainderOfLine().string()); 722 return BAD_VALUE; 723 } 724 } 725 726 mTokenizer->nextLine(); 727 } 728 729 if (mState != STATE_TOP) { 730 ALOGE("%s: Unterminated key description at end of file.", 731 mTokenizer->getLocation().string()); 732 return BAD_VALUE; 733 } 734 735 if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) { 736 ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.", 737 mTokenizer->getLocation().string()); 738 return BAD_VALUE; 739 } 740 741 if (mFormat == FORMAT_BASE) { 742 if (mMap->mType == KEYBOARD_TYPE_OVERLAY) { 743 ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.", 744 mTokenizer->getLocation().string()); 745 return BAD_VALUE; 746 } 747 } else if (mFormat == FORMAT_OVERLAY) { 748 if (mMap->mType != KEYBOARD_TYPE_OVERLAY) { 749 ALOGE("%s: Overlay keyboard layout missing required keyboard " 750 "'type OVERLAY' declaration.", 751 mTokenizer->getLocation().string()); 752 return BAD_VALUE; 753 } 754 } 755 756 return NO_ERROR; 757 } 758 759 status_t KeyCharacterMap::Parser::parseType() { 760 if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) { 761 ALOGE("%s: Duplicate keyboard 'type' declaration.", 762 mTokenizer->getLocation().string()); 763 return BAD_VALUE; 764 } 765 766 KeyboardType type; 767 String8 typeToken = mTokenizer->nextToken(WHITESPACE); 768 if (typeToken == "NUMERIC") { 769 type = KEYBOARD_TYPE_NUMERIC; 770 } else if (typeToken == "PREDICTIVE") { 771 type = KEYBOARD_TYPE_PREDICTIVE; 772 } else if (typeToken == "ALPHA") { 773 type = KEYBOARD_TYPE_ALPHA; 774 } else if (typeToken == "FULL") { 775 type = KEYBOARD_TYPE_FULL; 776 } else if (typeToken == "SPECIAL_FUNCTION") { 777 type = KEYBOARD_TYPE_SPECIAL_FUNCTION; 778 } else if (typeToken == "OVERLAY") { 779 type = KEYBOARD_TYPE_OVERLAY; 780 } else { 781 ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(), 782 typeToken.string()); 783 return BAD_VALUE; 784 } 785 786 #if DEBUG_PARSER 787 ALOGD("Parsed type: type=%d.", type); 788 #endif 789 mMap->mType = type; 790 return NO_ERROR; 791 } 792 793 status_t KeyCharacterMap::Parser::parseMap() { 794 String8 keywordToken = mTokenizer->nextToken(WHITESPACE); 795 if (keywordToken == "key") { 796 mTokenizer->skipDelimiters(WHITESPACE); 797 return parseMapKey(); 798 } 799 ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(), 800 keywordToken.string()); 801 return BAD_VALUE; 802 } 803 804 status_t KeyCharacterMap::Parser::parseMapKey() { 805 String8 codeToken = mTokenizer->nextToken(WHITESPACE); 806 bool mapUsage = false; 807 if (codeToken == "usage") { 808 mapUsage = true; 809 mTokenizer->skipDelimiters(WHITESPACE); 810 codeToken = mTokenizer->nextToken(WHITESPACE); 811 } 812 813 char* end; 814 int32_t code = int32_t(strtol(codeToken.string(), &end, 0)); 815 if (*end) { 816 ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(), 817 mapUsage ? "usage" : "scan code", codeToken.string()); 818 return BAD_VALUE; 819 } 820 KeyedVector<int32_t, int32_t>& map = 821 mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode; 822 if (map.indexOfKey(code) >= 0) { 823 ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(), 824 mapUsage ? "usage" : "scan code", codeToken.string()); 825 return BAD_VALUE; 826 } 827 828 mTokenizer->skipDelimiters(WHITESPACE); 829 String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); 830 int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); 831 if (!keyCode) { 832 ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), 833 keyCodeToken.string()); 834 return BAD_VALUE; 835 } 836 837 #if DEBUG_PARSER 838 ALOGD("Parsed map key %s: code=%d, keyCode=%d.", 839 mapUsage ? "usage" : "scan code", code, keyCode); 840 #endif 841 map.add(code, keyCode); 842 return NO_ERROR; 843 } 844 845 status_t KeyCharacterMap::Parser::parseKey() { 846 String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE); 847 int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string()); 848 if (!keyCode) { 849 ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(), 850 keyCodeToken.string()); 851 return BAD_VALUE; 852 } 853 if (mMap->mKeys.indexOfKey(keyCode) >= 0) { 854 ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(), 855 keyCodeToken.string()); 856 return BAD_VALUE; 857 } 858 859 mTokenizer->skipDelimiters(WHITESPACE); 860 String8 openBraceToken = mTokenizer->nextToken(WHITESPACE); 861 if (openBraceToken != "{") { 862 ALOGE("%s: Expected '{' after key code label, got '%s'.", 863 mTokenizer->getLocation().string(), openBraceToken.string()); 864 return BAD_VALUE; 865 } 866 867 #if DEBUG_PARSER 868 ALOGD("Parsed beginning of key: keyCode=%d.", keyCode); 869 #endif 870 mKeyCode = keyCode; 871 mMap->mKeys.add(keyCode, new Key()); 872 mState = STATE_KEY; 873 return NO_ERROR; 874 } 875 876 status_t KeyCharacterMap::Parser::parseKeyProperty() { 877 Key* key = mMap->mKeys.valueFor(mKeyCode); 878 String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); 879 if (token == "}") { 880 mState = STATE_TOP; 881 return finishKey(key); 882 } 883 884 Vector<Property> properties; 885 886 // Parse all comma-delimited property names up to the first colon. 887 for (;;) { 888 if (token == "label") { 889 properties.add(Property(PROPERTY_LABEL)); 890 } else if (token == "number") { 891 properties.add(Property(PROPERTY_NUMBER)); 892 } else { 893 int32_t metaState; 894 status_t status = parseModifier(token, &metaState); 895 if (status) { 896 ALOGE("%s: Expected a property name or modifier, got '%s'.", 897 mTokenizer->getLocation().string(), token.string()); 898 return status; 899 } 900 properties.add(Property(PROPERTY_META, metaState)); 901 } 902 903 mTokenizer->skipDelimiters(WHITESPACE); 904 if (!mTokenizer->isEol()) { 905 char ch = mTokenizer->nextChar(); 906 if (ch == ':') { 907 break; 908 } else if (ch == ',') { 909 mTokenizer->skipDelimiters(WHITESPACE); 910 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); 911 continue; 912 } 913 } 914 915 ALOGE("%s: Expected ',' or ':' after property name.", 916 mTokenizer->getLocation().string()); 917 return BAD_VALUE; 918 } 919 920 // Parse behavior after the colon. 921 mTokenizer->skipDelimiters(WHITESPACE); 922 923 Behavior behavior; 924 bool haveCharacter = false; 925 bool haveFallback = false; 926 927 do { 928 char ch = mTokenizer->peekChar(); 929 if (ch == '\'') { 930 char16_t character; 931 status_t status = parseCharacterLiteral(&character); 932 if (status || !character) { 933 ALOGE("%s: Invalid character literal for key.", 934 mTokenizer->getLocation().string()); 935 return BAD_VALUE; 936 } 937 if (haveCharacter) { 938 ALOGE("%s: Cannot combine multiple character literals or 'none'.", 939 mTokenizer->getLocation().string()); 940 return BAD_VALUE; 941 } 942 behavior.character = character; 943 haveCharacter = true; 944 } else { 945 token = mTokenizer->nextToken(WHITESPACE); 946 if (token == "none") { 947 if (haveCharacter) { 948 ALOGE("%s: Cannot combine multiple character literals or 'none'.", 949 mTokenizer->getLocation().string()); 950 return BAD_VALUE; 951 } 952 haveCharacter = true; 953 } else if (token == "fallback") { 954 mTokenizer->skipDelimiters(WHITESPACE); 955 token = mTokenizer->nextToken(WHITESPACE); 956 int32_t keyCode = getKeyCodeByLabel(token.string()); 957 if (!keyCode) { 958 ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.", 959 mTokenizer->getLocation().string(), 960 token.string()); 961 return BAD_VALUE; 962 } 963 if (haveFallback) { 964 ALOGE("%s: Cannot combine multiple fallback key codes.", 965 mTokenizer->getLocation().string()); 966 return BAD_VALUE; 967 } 968 behavior.fallbackKeyCode = keyCode; 969 haveFallback = true; 970 } else { 971 ALOGE("%s: Expected a key behavior after ':'.", 972 mTokenizer->getLocation().string()); 973 return BAD_VALUE; 974 } 975 } 976 977 mTokenizer->skipDelimiters(WHITESPACE); 978 } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#'); 979 980 // Add the behavior. 981 for (size_t i = 0; i < properties.size(); i++) { 982 const Property& property = properties.itemAt(i); 983 switch (property.property) { 984 case PROPERTY_LABEL: 985 if (key->label) { 986 ALOGE("%s: Duplicate label for key.", 987 mTokenizer->getLocation().string()); 988 return BAD_VALUE; 989 } 990 key->label = behavior.character; 991 #if DEBUG_PARSER 992 ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label); 993 #endif 994 break; 995 case PROPERTY_NUMBER: 996 if (key->number) { 997 ALOGE("%s: Duplicate number for key.", 998 mTokenizer->getLocation().string()); 999 return BAD_VALUE; 1000 } 1001 key->number = behavior.character; 1002 #if DEBUG_PARSER 1003 ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number); 1004 #endif 1005 break; 1006 case PROPERTY_META: { 1007 for (Behavior* b = key->firstBehavior; b; b = b->next) { 1008 if (b->metaState == property.metaState) { 1009 ALOGE("%s: Duplicate key behavior for modifier.", 1010 mTokenizer->getLocation().string()); 1011 return BAD_VALUE; 1012 } 1013 } 1014 Behavior* newBehavior = new Behavior(behavior); 1015 newBehavior->metaState = property.metaState; 1016 newBehavior->next = key->firstBehavior; 1017 key->firstBehavior = newBehavior; 1018 #if DEBUG_PARSER 1019 ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode, 1020 newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode); 1021 #endif 1022 break; 1023 } 1024 } 1025 } 1026 return NO_ERROR; 1027 } 1028 1029 status_t KeyCharacterMap::Parser::finishKey(Key* key) { 1030 // Fill in default number property. 1031 if (!key->number) { 1032 char16_t digit = 0; 1033 char16_t symbol = 0; 1034 for (Behavior* b = key->firstBehavior; b; b = b->next) { 1035 char16_t ch = b->character; 1036 if (ch) { 1037 if (ch >= '0' && ch <= '9') { 1038 digit = ch; 1039 } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*' 1040 || ch == '-' || ch == '+' || ch == ',' || ch == '.' 1041 || ch == '\'' || ch == ':' || ch == ';' || ch == '/') { 1042 symbol = ch; 1043 } 1044 } 1045 } 1046 key->number = digit ? digit : symbol; 1047 } 1048 return NO_ERROR; 1049 } 1050 1051 status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) { 1052 if (token == "base") { 1053 *outMetaState = 0; 1054 return NO_ERROR; 1055 } 1056 1057 int32_t combinedMeta = 0; 1058 1059 const char* str = token.string(); 1060 const char* start = str; 1061 for (const char* cur = str; ; cur++) { 1062 char ch = *cur; 1063 if (ch == '+' || ch == '\0') { 1064 size_t len = cur - start; 1065 int32_t metaState = 0; 1066 for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) { 1067 if (strlen(modifiers[i].label) == len 1068 && strncmp(modifiers[i].label, start, len) == 0) { 1069 metaState = modifiers[i].metaState; 1070 break; 1071 } 1072 } 1073 if (!metaState) { 1074 return BAD_VALUE; 1075 } 1076 if (combinedMeta & metaState) { 1077 ALOGE("%s: Duplicate modifier combination '%s'.", 1078 mTokenizer->getLocation().string(), token.string()); 1079 return BAD_VALUE; 1080 } 1081 1082 combinedMeta |= metaState; 1083 start = cur + 1; 1084 1085 if (ch == '\0') { 1086 break; 1087 } 1088 } 1089 } 1090 *outMetaState = combinedMeta; 1091 return NO_ERROR; 1092 } 1093 1094 status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) { 1095 char ch = mTokenizer->nextChar(); 1096 if (ch != '\'') { 1097 goto Error; 1098 } 1099 1100 ch = mTokenizer->nextChar(); 1101 if (ch == '\\') { 1102 // Escape sequence. 1103 ch = mTokenizer->nextChar(); 1104 if (ch == 'n') { 1105 *outCharacter = '\n'; 1106 } else if (ch == 't') { 1107 *outCharacter = '\t'; 1108 } else if (ch == '\\') { 1109 *outCharacter = '\\'; 1110 } else if (ch == '\'') { 1111 *outCharacter = '\''; 1112 } else if (ch == '"') { 1113 *outCharacter = '"'; 1114 } else if (ch == 'u') { 1115 *outCharacter = 0; 1116 for (int i = 0; i < 4; i++) { 1117 ch = mTokenizer->nextChar(); 1118 int digit; 1119 if (ch >= '0' && ch <= '9') { 1120 digit = ch - '0'; 1121 } else if (ch >= 'A' && ch <= 'F') { 1122 digit = ch - 'A' + 10; 1123 } else if (ch >= 'a' && ch <= 'f') { 1124 digit = ch - 'a' + 10; 1125 } else { 1126 goto Error; 1127 } 1128 *outCharacter = (*outCharacter << 4) | digit; 1129 } 1130 } else { 1131 goto Error; 1132 } 1133 } else if (ch >= 32 && ch <= 126 && ch != '\'') { 1134 // ASCII literal character. 1135 *outCharacter = ch; 1136 } else { 1137 goto Error; 1138 } 1139 1140 ch = mTokenizer->nextChar(); 1141 if (ch != '\'') { 1142 goto Error; 1143 } 1144 1145 // Ensure that we consumed the entire token. 1146 if (mTokenizer->nextToken(WHITESPACE).isEmpty()) { 1147 return NO_ERROR; 1148 } 1149 1150 Error: 1151 ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string()); 1152 return BAD_VALUE; 1153 } 1154 1155 } // namespace android 1156