xref: /aosp_15_r20/frameworks/native/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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