1 /*
2 * Copyright (C) 2019 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 // clang-format off
18 #include "../Macros.h"
19 // clang-format on
20
21 #include "KeyboardInputMapper.h"
22
23 #include <ftl/enum.h>
24 #include <input/KeyboardClassifier.h>
25 #include <ui/Rotation.h>
26
27 namespace android {
28
29 // --- Static Definitions ---
30
rotateKeyCode(int32_t keyCode,ui::Rotation orientation)31 static int32_t rotateKeyCode(int32_t keyCode, ui::Rotation orientation) {
32 static constexpr int32_t KEYCODE_ROTATION_MAP[][4] = {
33 // key codes enumerated counter-clockwise with the original (unrotated) key first
34 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
35 {AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT},
36 {AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN},
37 {AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT},
38 {AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP},
39 {AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
40 AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT},
41 {AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP,
42 AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN},
43 {AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT,
44 AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT},
45 {AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN,
46 AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP},
47 };
48
49 if (orientation != ui::ROTATION_0) {
50 for (const auto& rotation : KEYCODE_ROTATION_MAP) {
51 if (rotation[static_cast<size_t>(ui::ROTATION_0)] == keyCode) {
52 return rotation[static_cast<size_t>(orientation)];
53 }
54 }
55 }
56 return keyCode;
57 }
58
isSupportedScanCode(int32_t scanCode)59 static bool isSupportedScanCode(int32_t scanCode) {
60 // KeyboardInputMapper handles keys from keyboards, gamepads, and styluses.
61 return scanCode < BTN_MOUSE || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI) ||
62 scanCode == BTN_STYLUS || scanCode == BTN_STYLUS2 || scanCode == BTN_STYLUS3 ||
63 scanCode >= BTN_WHEEL;
64 }
65
isMediaKey(int32_t keyCode)66 static bool isMediaKey(int32_t keyCode) {
67 switch (keyCode) {
68 case AKEYCODE_MEDIA_PLAY:
69 case AKEYCODE_MEDIA_PAUSE:
70 case AKEYCODE_MEDIA_PLAY_PAUSE:
71 case AKEYCODE_MUTE:
72 case AKEYCODE_HEADSETHOOK:
73 case AKEYCODE_MEDIA_STOP:
74 case AKEYCODE_MEDIA_NEXT:
75 case AKEYCODE_MEDIA_PREVIOUS:
76 case AKEYCODE_MEDIA_REWIND:
77 case AKEYCODE_MEDIA_RECORD:
78 case AKEYCODE_MEDIA_FAST_FORWARD:
79 case AKEYCODE_MEDIA_SKIP_FORWARD:
80 case AKEYCODE_MEDIA_SKIP_BACKWARD:
81 case AKEYCODE_MEDIA_STEP_FORWARD:
82 case AKEYCODE_MEDIA_STEP_BACKWARD:
83 case AKEYCODE_MEDIA_AUDIO_TRACK:
84 case AKEYCODE_VOLUME_UP:
85 case AKEYCODE_VOLUME_DOWN:
86 case AKEYCODE_VOLUME_MUTE:
87 case AKEYCODE_TV_AUDIO_DESCRIPTION:
88 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP:
89 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN:
90 return true;
91 default:
92 return false;
93 }
94 }
95
96 // --- KeyboardInputMapper ---
97
KeyboardInputMapper(InputDeviceContext & deviceContext,const InputReaderConfiguration & readerConfig,uint32_t source)98 KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext,
99 const InputReaderConfiguration& readerConfig,
100 uint32_t source)
101 : InputMapper(deviceContext, readerConfig), mMapperSource(source) {}
102
getSources() const103 uint32_t KeyboardInputMapper::getSources() const {
104 return mMapperSource;
105 }
106
getOrientation()107 ui::Rotation KeyboardInputMapper::getOrientation() {
108 if (mViewport) {
109 return mViewport->orientation;
110 }
111 return ui::ROTATION_0;
112 }
113
getDisplayId()114 ui::LogicalDisplayId KeyboardInputMapper::getDisplayId() {
115 if (mViewport) {
116 return mViewport->displayId;
117 }
118 return ui::LogicalDisplayId::INVALID;
119 }
120
getKeyboardLayoutInfo() const121 std::optional<KeyboardLayoutInfo> KeyboardInputMapper::getKeyboardLayoutInfo() const {
122 if (mKeyboardLayoutInfo) {
123 return mKeyboardLayoutInfo;
124 }
125 std::optional<RawLayoutInfo> layoutInfo = getDeviceContext().getRawLayoutInfo();
126 if (!layoutInfo) {
127 return std::nullopt;
128 }
129 return KeyboardLayoutInfo(layoutInfo->languageTag, layoutInfo->layoutType);
130 }
131
populateDeviceInfo(InputDeviceInfo & info)132 void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
133 InputMapper::populateDeviceInfo(info);
134
135 if (const auto kcm = getDeviceContext().getKeyCharacterMap(); kcm != nullptr) {
136 info.setKeyCharacterMap(std::make_unique<KeyCharacterMap>(*kcm));
137 }
138
139 std::optional keyboardLayoutInfo = getKeyboardLayoutInfo();
140 if (keyboardLayoutInfo) {
141 info.setKeyboardLayoutInfo(*keyboardLayoutInfo);
142 }
143 }
144
dump(std::string & dump)145 void KeyboardInputMapper::dump(std::string& dump) {
146 dump += INDENT2 "Keyboard Input Mapper:\n";
147 dumpParameters(dump);
148 dump += StringPrintf(INDENT3 "Orientation: %s\n", ftl::enum_string(getOrientation()).c_str());
149 dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
150 dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState);
151 dump += INDENT3 "KeyboardLayoutInfo: ";
152 if (mKeyboardLayoutInfo) {
153 dump += mKeyboardLayoutInfo->languageTag + ", " + mKeyboardLayoutInfo->layoutType + "\n";
154 } else {
155 dump += "<not set>\n";
156 }
157 }
158
findViewport(const InputReaderConfiguration & readerConfig)159 std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
160 const InputReaderConfiguration& readerConfig) {
161 if (getDeviceContext().getAssociatedViewport()) {
162 return getDeviceContext().getAssociatedViewport();
163 }
164
165 // No associated display defined, try to find default display if orientationAware.
166 if (mParameters.orientationAware) {
167 return readerConfig.getDisplayViewportByType(ViewportType::INTERNAL);
168 }
169
170 return std::nullopt;
171 }
172
reconfigure(nsecs_t when,const InputReaderConfiguration & config,ConfigurationChanges changes)173 std::list<NotifyArgs> KeyboardInputMapper::reconfigure(nsecs_t when,
174 const InputReaderConfiguration& config,
175 ConfigurationChanges changes) {
176 std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
177
178 if (!changes.any()) { // first time only
179 // Configure basic parameters.
180 configureParameters();
181 }
182
183 if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
184 mViewport = findViewport(config);
185 }
186
187 if (!changes.any() ||
188 changes.test(InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION)) {
189 std::optional<KeyboardLayoutInfo> newKeyboardLayoutInfo =
190 getValueByKey(config.keyboardLayoutAssociations, getDeviceContext().getLocation());
191 if (mKeyboardLayoutInfo != newKeyboardLayoutInfo) {
192 mKeyboardLayoutInfo = newKeyboardLayoutInfo;
193 // Also update keyboard layout overlay as soon as we find the new layout info
194 updateKeyboardLayoutOverlay();
195 bumpGeneration();
196 }
197 }
198
199 if (!changes.any() || changes.test(InputReaderConfiguration::Change::KEYBOARD_LAYOUTS)) {
200 if (!getDeviceContext().getDeviceClasses().test(InputDeviceClass::VIRTUAL) &&
201 updateKeyboardLayoutOverlay()) {
202 bumpGeneration();
203 }
204 }
205 return out;
206 }
207
updateKeyboardLayoutOverlay()208 bool KeyboardInputMapper::updateKeyboardLayoutOverlay() {
209 std::shared_ptr<KeyCharacterMap> keyboardLayout =
210 getDeviceContext()
211 .getContext()
212 ->getPolicy()
213 ->getKeyboardLayoutOverlay(getDeviceContext().getDeviceIdentifier(),
214 getKeyboardLayoutInfo());
215 return getDeviceContext().setKeyboardLayoutOverlay(keyboardLayout);
216 }
217
configureParameters()218 void KeyboardInputMapper::configureParameters() {
219 const PropertyMap& config = getDeviceContext().getConfiguration();
220 mParameters.orientationAware = config.getBool("keyboard.orientationAware").value_or(false);
221 mParameters.handlesKeyRepeat = config.getBool("keyboard.handlesKeyRepeat").value_or(false);
222 mParameters.doNotWakeByDefault = config.getBool("keyboard.doNotWakeByDefault").value_or(false);
223 }
224
dumpParameters(std::string & dump) const225 void KeyboardInputMapper::dumpParameters(std::string& dump) const {
226 dump += INDENT3 "Parameters:\n";
227 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
228 dump += StringPrintf(INDENT4 "HandlesKeyRepeat: %s\n", toString(mParameters.handlesKeyRepeat));
229 }
230
reset(nsecs_t when)231 std::list<NotifyArgs> KeyboardInputMapper::reset(nsecs_t when) {
232 std::list<NotifyArgs> out = cancelAllDownKeys(when);
233 mHidUsageAccumulator.reset();
234
235 resetLedState();
236
237 out += InputMapper::reset(when);
238 return out;
239 }
240
process(const RawEvent & rawEvent)241 std::list<NotifyArgs> KeyboardInputMapper::process(const RawEvent& rawEvent) {
242 std::list<NotifyArgs> out;
243 mHidUsageAccumulator.process(rawEvent);
244 switch (rawEvent.type) {
245 case EV_KEY: {
246 // Skip processing repeated keys (value == 2) since auto repeat is handled by Android
247 // internally.
248 if (rawEvent.value == 2) {
249 break;
250 }
251
252 const int32_t scanCode = rawEvent.code;
253 if (isSupportedScanCode(scanCode)) {
254 out += processKey(rawEvent.when, rawEvent.readTime, rawEvent.value != 0, scanCode,
255 mHidUsageAccumulator.consumeCurrentHidUsage());
256 }
257 break;
258 }
259 }
260 return out;
261 }
262
processKey(nsecs_t when,nsecs_t readTime,bool down,int32_t scanCode,int32_t usageCode)263 std::list<NotifyArgs> KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
264 int32_t scanCode, int32_t usageCode) {
265 std::list<NotifyArgs> out;
266 int32_t keyCode;
267 int32_t keyMetaState;
268 uint32_t policyFlags;
269 int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
270
271 if (getDeviceContext().mapKey(scanCode, usageCode, mMetaState, &keyCode, &keyMetaState,
272 &policyFlags)) {
273 keyCode = AKEYCODE_UNKNOWN;
274 keyMetaState = mMetaState;
275 policyFlags = 0;
276 }
277
278 nsecs_t downTime = when;
279 std::optional<size_t> keyDownIndex = findKeyDownIndex(scanCode);
280 if (down) {
281 // Rotate key codes according to orientation if needed.
282 if (mParameters.orientationAware) {
283 keyCode = rotateKeyCode(keyCode, getOrientation());
284 }
285
286 // Add key down.
287 if (keyDownIndex) {
288 // key repeat, be sure to use same keycode as before in case of rotation
289 keyCode = mKeyDowns[*keyDownIndex].keyCode;
290 downTime = mKeyDowns[*keyDownIndex].downTime;
291 flags = mKeyDowns[*keyDownIndex].flags;
292 } else {
293 // key down
294 if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
295 getContext()->shouldDropVirtualKey(when, keyCode, scanCode)) {
296 return out;
297 }
298 if (policyFlags & POLICY_FLAG_GESTURE) {
299 out += getDeviceContext().cancelTouch(when, readTime);
300 flags |= AKEY_EVENT_FLAG_KEEP_TOUCH_MODE;
301 }
302
303 KeyDown keyDown;
304 keyDown.keyCode = keyCode;
305 keyDown.scanCode = scanCode;
306 keyDown.downTime = when;
307 keyDown.flags = flags;
308 mKeyDowns.push_back(keyDown);
309 }
310 onKeyDownProcessed(downTime);
311 } else {
312 // Remove key down.
313 if (keyDownIndex) {
314 // key up, be sure to use same keycode as before in case of rotation
315 keyCode = mKeyDowns[*keyDownIndex].keyCode;
316 downTime = mKeyDowns[*keyDownIndex].downTime;
317 flags = mKeyDowns[*keyDownIndex].flags;
318 mKeyDowns.erase(mKeyDowns.begin() + *keyDownIndex);
319 } else {
320 // key was not actually down
321 ALOGI("Dropping key up from device %s because the key was not down. "
322 "keyCode=%d, scanCode=%d",
323 getDeviceName().c_str(), keyCode, scanCode);
324 return out;
325 }
326 }
327
328 if (updateMetaStateIfNeeded(keyCode, down)) {
329 // If global meta state changed send it along with the key.
330 // If it has not changed then we'll use what keymap gave us,
331 // since key replacement logic might temporarily reset a few
332 // meta bits for given key.
333 keyMetaState = mMetaState;
334 }
335
336 DeviceId deviceId = getDeviceId();
337
338 // On first down: Process key for keyboard classification (will send reconfiguration if the
339 // keyboard type change)
340 if (down && !keyDownIndex) {
341 KeyboardClassifier& classifier = getDeviceContext().getContext()->getKeyboardClassifier();
342 classifier.processKey(deviceId, scanCode, keyMetaState);
343 getDeviceContext().setKeyboardType(classifier.getKeyboardType(deviceId));
344 }
345
346 KeyboardType keyboardType = getDeviceContext().getKeyboardType();
347 // Any key down on an external keyboard or internal alphanumeric keyboard should wake the
348 // device. We don't do this for non-alphanumeric internal keyboards to prevent them from
349 // waking up in your pocket.
350 // For internal keyboards and devices for which the default wake behavior is explicitly
351 // prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
352 // wake key individually.
353 if (down && !mParameters.doNotWakeByDefault &&
354 (getDeviceContext().isExternal() || wakeOnAlphabeticKeyboard(keyboardType)) &&
355 !(keyboardType != KeyboardType::ALPHABETIC && isMediaKey(keyCode))) {
356 policyFlags |= POLICY_FLAG_WAKE;
357 }
358
359 if (mParameters.handlesKeyRepeat) {
360 policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
361 }
362
363 out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, deviceId,
364 getEventSource(), getDisplayId(), policyFlags,
365 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, flags,
366 keyCode, scanCode, keyMetaState, downTime));
367 return out;
368 }
369
findKeyDownIndex(int32_t scanCode)370 std::optional<size_t> KeyboardInputMapper::findKeyDownIndex(int32_t scanCode) {
371 size_t n = mKeyDowns.size();
372 for (size_t i = 0; i < n; i++) {
373 if (mKeyDowns[i].scanCode == scanCode) {
374 return i;
375 }
376 }
377 return {};
378 }
379
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)380 int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
381 return getDeviceContext().getKeyCodeState(keyCode);
382 }
383
getScanCodeState(uint32_t sourceMask,int32_t scanCode)384 int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
385 return getDeviceContext().getScanCodeState(scanCode);
386 }
387
getKeyCodeForKeyLocation(int32_t locationKeyCode) const388 int32_t KeyboardInputMapper::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
389 return getDeviceContext().getKeyCodeForKeyLocation(locationKeyCode);
390 }
391
markSupportedKeyCodes(uint32_t sourceMask,const std::vector<int32_t> & keyCodes,uint8_t * outFlags)392 bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask,
393 const std::vector<int32_t>& keyCodes,
394 uint8_t* outFlags) {
395 return getDeviceContext().markSupportedKeyCodes(keyCodes, outFlags);
396 }
397
getMetaState()398 int32_t KeyboardInputMapper::getMetaState() {
399 return mMetaState;
400 }
401
updateMetaStateIfNeeded(int32_t keyCode,bool down)402 bool KeyboardInputMapper::updateMetaStateIfNeeded(int32_t keyCode, bool down) {
403 int32_t oldMetaState = mMetaState;
404 int32_t newMetaState = android::updateMetaState(keyCode, down, oldMetaState);
405 int32_t metaStateChanged = oldMetaState ^ newMetaState;
406 if (metaStateChanged) {
407 mMetaState = newMetaState;
408 constexpr int32_t allLedMetaState =
409 AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON;
410 if ((metaStateChanged & allLedMetaState) != 0) {
411 getContext()->updateLedMetaState(newMetaState & allLedMetaState);
412 }
413 getContext()->updateGlobalMetaState();
414 }
415
416 return metaStateChanged;
417 }
418
resetLedState()419 void KeyboardInputMapper::resetLedState() {
420 initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
421 initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
422 initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
423
424 updateLedState(true);
425 }
426
initializeLedState(LedState & ledState,int32_t led)427 void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
428 ledState.avail = getDeviceContext().hasLed(led);
429 ledState.on = false;
430 }
431
updateLedState(bool reset)432 void KeyboardInputMapper::updateLedState(bool reset) {
433 // Clear the local led state then union the global led state.
434 mMetaState &= ~(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON);
435 mMetaState |= getContext()->getLedMetaState();
436
437 std::vector<int32_t> keyCodesToCheck{AKEYCODE_NUM_LOCK, AKEYCODE_SCROLL_LOCK};
438 std::vector<int32_t> metaCodes{AMETA_NUM_LOCK_ON, AMETA_SCROLL_LOCK_ON};
439 // Check for physical CapsLock key only for non-alphabetic keyboards. For Alphabetic
440 // keyboards, we will allow Caps Lock even if there is no physical CapsLock key.
441 if (getDeviceContext().getKeyboardType() != KeyboardType::ALPHABETIC) {
442 keyCodesToCheck.push_back(AKEYCODE_CAPS_LOCK);
443 metaCodes.push_back(AMETA_CAPS_LOCK_ON);
444 }
445 size_t size = keyCodesToCheck.size();
446 std::vector<uint8_t> flags(size, 0);
447 bool hasKeyLayout = getDeviceContext().markSupportedKeyCodes(keyCodesToCheck, flags.data());
448 // If the device doesn't have the physical meta key it shouldn't generate the corresponding
449 // meta state.
450 if (hasKeyLayout) {
451 for (size_t i = 0; i < size; i++) {
452 if (!flags[i]) {
453 mMetaState &= ~metaCodes[i];
454 }
455 }
456 }
457
458 updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK, AMETA_CAPS_LOCK_ON, reset);
459 updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK, AMETA_NUM_LOCK_ON, reset);
460 updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, reset);
461 }
462
updateLedStateForModifier(LedState & ledState,int32_t led,int32_t modifier,bool reset)463 void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState, int32_t led,
464 int32_t modifier, bool reset) {
465 if (ledState.avail) {
466 bool desiredState = (mMetaState & modifier) != 0;
467 if (reset || ledState.on != desiredState) {
468 getDeviceContext().setLedState(led, desiredState);
469 ledState.on = desiredState;
470 }
471 }
472 }
473
getAssociatedDisplayId()474 std::optional<ui::LogicalDisplayId> KeyboardInputMapper::getAssociatedDisplayId() {
475 if (mViewport) {
476 return std::make_optional(mViewport->displayId);
477 }
478 return std::nullopt;
479 }
480
cancelAllDownKeys(nsecs_t when)481 std::list<NotifyArgs> KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) {
482 std::list<NotifyArgs> out;
483 size_t n = mKeyDowns.size();
484 for (size_t i = 0; i < n; i++) {
485 out.emplace_back(
486 NotifyKeyArgs(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC),
487 getDeviceId(), getEventSource(), getDisplayId(), /*policyFlags=*/0,
488 AKEY_EVENT_ACTION_UP, mKeyDowns[i].flags | AKEY_EVENT_FLAG_CANCELED,
489 mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
490 mKeyDowns[i].downTime));
491 }
492 mKeyDowns.clear();
493 mMetaState = AMETA_NONE;
494 return out;
495 }
496
onKeyDownProcessed(nsecs_t downTime)497 void KeyboardInputMapper::onKeyDownProcessed(nsecs_t downTime) {
498 InputReaderContext& context = *getContext();
499 context.setLastKeyDownTimestamp(downTime);
500 }
501
getEventSource() const502 uint32_t KeyboardInputMapper::getEventSource() const {
503 // For all input events generated by this mapper, use the source that's shared across all
504 // KeyboardInputMappers for this device in case there are more than one.
505 static constexpr auto ALL_KEYBOARD_SOURCES =
506 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD;
507 const auto deviceSources = getDeviceContext().getDeviceSources();
508 LOG_ALWAYS_FATAL_IF((deviceSources & mMapperSource) != mMapperSource);
509 return deviceSources & ALL_KEYBOARD_SOURCES;
510 }
511
wakeOnAlphabeticKeyboard(const KeyboardType keyboardType) const512 bool KeyboardInputMapper::wakeOnAlphabeticKeyboard(const KeyboardType keyboardType) const {
513 return mEnableAlphabeticKeyboardWakeFlag && (KeyboardType::ALPHABETIC == keyboardType);
514 }
515
516 } // namespace android
517