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