blob: 060bfc2ae88c996104e09be7bdb1b4f3cbd86df4 [file] [log] [blame]
Prabir Pradhanbaa5c822019-08-30 15:27:05 -07001/*
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
Michael Wrightfe3de7d2020-07-02 19:05:30 +010017// clang-format off
Prabir Pradhan9244aea2020-02-05 20:31:40 -080018#include "../Macros.h"
Michael Wrightfe3de7d2020-07-02 19:05:30 +010019// clang-format on
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070020
21#include "KeyboardInputMapper.h"
22
23namespace android {
24
25// --- Static Definitions ---
26
27static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
28 const int32_t map[][4], size_t mapSize) {
29 if (orientation != DISPLAY_ORIENTATION_0) {
30 for (size_t i = 0; i < mapSize; i++) {
31 if (value == map[i][0]) {
32 return map[i][orientation];
33 }
34 }
35 }
36 return value;
37}
38
39static const int32_t keyCodeRotationMap[][4] = {
40 // key codes enumerated counter-clockwise with the original (unrotated) key first
41 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
42 {AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT},
43 {AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN},
44 {AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT},
45 {AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP},
46 {AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
47 AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT},
48 {AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP,
49 AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN},
50 {AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT,
51 AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT},
52 {AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN,
53 AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP},
54};
55
56static const size_t keyCodeRotationMapSize =
57 sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
58
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070059static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070060 return rotateValueUsingRotationMap(keyCode, orientation, keyCodeRotationMap,
61 keyCodeRotationMapSize);
62}
63
64// --- KeyboardInputMapper ---
65
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080066KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source,
67 int32_t keyboardType)
68 : InputMapper(deviceContext), mSource(source), mKeyboardType(keyboardType) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070069
70KeyboardInputMapper::~KeyboardInputMapper() {}
71
Philip Junker4af3b3d2021-12-14 10:36:55 +010072uint32_t KeyboardInputMapper::getSources() const {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070073 return mSource;
74}
75
76int32_t KeyboardInputMapper::getOrientation() {
77 if (mViewport) {
78 return mViewport->orientation;
79 }
80 return DISPLAY_ORIENTATION_0;
81}
82
83int32_t KeyboardInputMapper::getDisplayId() {
84 if (mViewport) {
85 return mViewport->displayId;
86 }
87 return ADISPLAY_ID_NONE;
88}
89
90void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
91 InputMapper::populateDeviceInfo(info);
92
93 info->setKeyboardType(mKeyboardType);
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080094 info->setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070095}
96
97void KeyboardInputMapper::dump(std::string& dump) {
98 dump += INDENT2 "Keyboard Input Mapper:\n";
99 dumpParameters(dump);
100 dump += StringPrintf(INDENT3 "KeyboardType: %d\n", mKeyboardType);
101 dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation());
102 dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
103 dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700104}
105
106std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
107 nsecs_t when, const InputReaderConfiguration* config) {
Christine Franks1ba71cc2021-04-07 14:37:42 -0700108 if (getDeviceContext().getAssociatedViewport()) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800109 return getDeviceContext().getAssociatedViewport();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700110 }
111
112 // No associated display defined, try to find default display if orientationAware.
113 if (mParameters.orientationAware) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100114 return config->getDisplayViewportByType(ViewportType::INTERNAL);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700115 }
116
117 return std::nullopt;
118}
119
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700120std::list<NotifyArgs> KeyboardInputMapper::configure(nsecs_t when,
121 const InputReaderConfiguration* config,
122 uint32_t changes) {
123 std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700124
125 if (!changes) { // first time only
126 // Configure basic parameters.
127 configureParameters();
128 }
129
130 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
131 mViewport = findViewport(when, config);
132 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700133 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700134}
135
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700136void KeyboardInputMapper::configureParameters() {
137 mParameters.orientationAware = false;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800138 const PropertyMap& config = getDeviceContext().getConfiguration();
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700139 config.tryGetProperty("keyboard.orientationAware", mParameters.orientationAware);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700140
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700141 mParameters.handlesKeyRepeat = false;
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700142 config.tryGetProperty("keyboard.handlesKeyRepeat", mParameters.handlesKeyRepeat);
Powei Fengd041c5d2019-05-03 17:11:33 -0700143
144 mParameters.doNotWakeByDefault = false;
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700145 config.tryGetProperty("keyboard.doNotWakeByDefault", mParameters.doNotWakeByDefault);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700146}
147
148void KeyboardInputMapper::dumpParameters(std::string& dump) {
149 dump += INDENT3 "Parameters:\n";
150 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
151 dump += StringPrintf(INDENT4 "HandlesKeyRepeat: %s\n", toString(mParameters.handlesKeyRepeat));
152}
153
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700154std::list<NotifyArgs> KeyboardInputMapper::reset(nsecs_t when) {
155 std::list<NotifyArgs> out = cancelAllDownKeys(when);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700156 mCurrentHidUsage = 0;
157
158 resetLedState();
159
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700160 out += InputMapper::reset(when);
161 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700162}
163
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700164std::list<NotifyArgs> KeyboardInputMapper::process(const RawEvent* rawEvent) {
165 std::list<NotifyArgs> out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700166 switch (rawEvent->type) {
167 case EV_KEY: {
168 int32_t scanCode = rawEvent->code;
169 int32_t usageCode = mCurrentHidUsage;
170 mCurrentHidUsage = 0;
171
172 if (isKeyboardOrGamepadKey(scanCode)) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700173 out += processKey(rawEvent->when, rawEvent->readTime, rawEvent->value != 0,
174 scanCode, usageCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700175 }
176 break;
177 }
178 case EV_MSC: {
179 if (rawEvent->code == MSC_SCAN) {
180 mCurrentHidUsage = rawEvent->value;
181 }
182 break;
183 }
184 case EV_SYN: {
185 if (rawEvent->code == SYN_REPORT) {
186 mCurrentHidUsage = 0;
187 }
188 }
189 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700190 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700191}
192
193bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -0700194 return scanCode < BTN_MOUSE || scanCode >= BTN_WHEEL ||
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700195 (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) ||
196 (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
197}
198
199bool KeyboardInputMapper::isMediaKey(int32_t keyCode) {
200 switch (keyCode) {
201 case AKEYCODE_MEDIA_PLAY:
202 case AKEYCODE_MEDIA_PAUSE:
203 case AKEYCODE_MEDIA_PLAY_PAUSE:
204 case AKEYCODE_MUTE:
205 case AKEYCODE_HEADSETHOOK:
206 case AKEYCODE_MEDIA_STOP:
207 case AKEYCODE_MEDIA_NEXT:
208 case AKEYCODE_MEDIA_PREVIOUS:
209 case AKEYCODE_MEDIA_REWIND:
210 case AKEYCODE_MEDIA_RECORD:
211 case AKEYCODE_MEDIA_FAST_FORWARD:
212 case AKEYCODE_MEDIA_SKIP_FORWARD:
213 case AKEYCODE_MEDIA_SKIP_BACKWARD:
214 case AKEYCODE_MEDIA_STEP_FORWARD:
215 case AKEYCODE_MEDIA_STEP_BACKWARD:
216 case AKEYCODE_MEDIA_AUDIO_TRACK:
217 case AKEYCODE_VOLUME_UP:
218 case AKEYCODE_VOLUME_DOWN:
219 case AKEYCODE_VOLUME_MUTE:
220 case AKEYCODE_TV_AUDIO_DESCRIPTION:
221 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP:
222 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN:
223 return true;
224 }
225 return false;
226}
227
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700228std::list<NotifyArgs> KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
229 int32_t scanCode, int32_t usageCode) {
230 std::list<NotifyArgs> out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700231 int32_t keyCode;
232 int32_t keyMetaState;
233 uint32_t policyFlags;
234
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800235 if (getDeviceContext().mapKey(scanCode, usageCode, mMetaState, &keyCode, &keyMetaState,
236 &policyFlags)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700237 keyCode = AKEYCODE_UNKNOWN;
238 keyMetaState = mMetaState;
239 policyFlags = 0;
240 }
241
Arthur Hung2141d542022-08-23 07:45:21 +0000242 nsecs_t downTime = when;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700243 if (down) {
244 // Rotate key codes according to orientation if needed.
245 if (mParameters.orientationAware) {
246 keyCode = rotateKeyCode(keyCode, getOrientation());
247 }
248
249 // Add key down.
250 ssize_t keyDownIndex = findKeyDown(scanCode);
251 if (keyDownIndex >= 0) {
252 // key repeat, be sure to use same keycode as before in case of rotation
253 keyCode = mKeyDowns[keyDownIndex].keyCode;
Arthur Hung2141d542022-08-23 07:45:21 +0000254 downTime = mKeyDowns[keyDownIndex].downTime;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700255 } else {
256 // key down
257 if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800258 getContext()->shouldDropVirtualKey(when, keyCode, scanCode)) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700259 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700260 }
261 if (policyFlags & POLICY_FLAG_GESTURE) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700262 out += getDeviceContext().cancelTouch(when, readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700263 }
264
265 KeyDown keyDown;
266 keyDown.keyCode = keyCode;
267 keyDown.scanCode = scanCode;
Arthur Hung2141d542022-08-23 07:45:21 +0000268 keyDown.downTime = when;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700269 mKeyDowns.push_back(keyDown);
270 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700271 } else {
272 // Remove key down.
273 ssize_t keyDownIndex = findKeyDown(scanCode);
274 if (keyDownIndex >= 0) {
275 // key up, be sure to use same keycode as before in case of rotation
276 keyCode = mKeyDowns[keyDownIndex].keyCode;
Arthur Hung2141d542022-08-23 07:45:21 +0000277 downTime = mKeyDowns[keyDownIndex].downTime;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700278 mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex);
279 } else {
280 // key was not actually down
281 ALOGI("Dropping key up from device %s because the key was not down. "
282 "keyCode=%d, scanCode=%d",
283 getDeviceName().c_str(), keyCode, scanCode);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700284 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700285 }
286 }
287
288 if (updateMetaStateIfNeeded(keyCode, down)) {
289 // If global meta state changed send it along with the key.
290 // If it has not changed then we'll use what keymap gave us,
291 // since key replacement logic might temporarily reset a few
292 // meta bits for given key.
293 keyMetaState = mMetaState;
294 }
295
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700296 // Key down on external an keyboard should wake the device.
297 // We don't do this for internal keyboards to prevent them from waking up in your pocket.
Powei Fengd041c5d2019-05-03 17:11:33 -0700298 // For internal keyboards and devices for which the default wake behavior is explicitly
299 // prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
300 // wake key individually.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700301 // TODO: Use the input device configuration to control this behavior more finely.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800302 if (down && getDeviceContext().isExternal() && !mParameters.doNotWakeByDefault &&
Powei Fengd041c5d2019-05-03 17:11:33 -0700303 !isMediaKey(keyCode)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700304 policyFlags |= POLICY_FLAG_WAKE;
305 }
306
307 if (mParameters.handlesKeyRepeat) {
308 policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
309 }
310
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700311 out.push_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, getDeviceId(), mSource,
312 getDisplayId(), policyFlags,
313 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
314 AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState,
315 downTime));
316 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700317}
318
319ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
320 size_t n = mKeyDowns.size();
321 for (size_t i = 0; i < n; i++) {
322 if (mKeyDowns[i].scanCode == scanCode) {
323 return i;
324 }
325 }
326 return -1;
327}
328
329int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800330 return getDeviceContext().getKeyCodeState(keyCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700331}
332
333int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800334 return getDeviceContext().getScanCodeState(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700335}
336
Philip Junker4af3b3d2021-12-14 10:36:55 +0100337int32_t KeyboardInputMapper::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
338 return getDeviceContext().getKeyCodeForKeyLocation(locationKeyCode);
339}
340
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700341bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask,
342 const std::vector<int32_t>& keyCodes,
343 uint8_t* outFlags) {
344 return getDeviceContext().markSupportedKeyCodes(keyCodes, outFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700345}
346
347int32_t KeyboardInputMapper::getMetaState() {
348 return mMetaState;
349}
350
Arthur Hungcb40a002021-08-03 14:31:01 +0000351bool KeyboardInputMapper::updateMetaState(int32_t keyCode) {
352 if (!android::isMetaKey(keyCode) || !getDeviceContext().hasKeyCode(keyCode)) {
353 return false;
354 }
355
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700356 updateMetaStateIfNeeded(keyCode, false);
Arthur Hungcb40a002021-08-03 14:31:01 +0000357 return true;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700358}
359
360bool KeyboardInputMapper::updateMetaStateIfNeeded(int32_t keyCode, bool down) {
361 int32_t oldMetaState = mMetaState;
362 int32_t newMetaState = android::updateMetaState(keyCode, down, oldMetaState);
arthurhungc903df12020-08-11 15:08:42 +0800363 int32_t metaStateChanged = oldMetaState ^ newMetaState;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700364 if (metaStateChanged) {
365 mMetaState = newMetaState;
arthurhungc903df12020-08-11 15:08:42 +0800366 constexpr int32_t allLedMetaState =
367 AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON;
368 if ((metaStateChanged & allLedMetaState) != 0) {
369 getContext()->updateLedMetaState(newMetaState & allLedMetaState);
370 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700371 getContext()->updateGlobalMetaState();
372 }
373
374 return metaStateChanged;
375}
376
377void KeyboardInputMapper::resetLedState() {
378 initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
379 initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
380 initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
381
382 updateLedState(true);
383}
384
385void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800386 ledState.avail = getDeviceContext().hasLed(led);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700387 ledState.on = false;
388}
389
390void KeyboardInputMapper::updateLedState(bool reset) {
Arthur Hungfb3cc112022-04-13 07:39:50 +0000391 // Clear the local led state then union the global led state.
392 mMetaState &= ~(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON);
arthurhungc903df12020-08-11 15:08:42 +0800393 mMetaState |= getContext()->getLedMetaState();
Chris Yea52ade12020-08-27 16:49:20 -0700394
395 constexpr int32_t META_NUM = 3;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700396 const std::vector<int32_t> keyCodes{AKEYCODE_CAPS_LOCK, AKEYCODE_NUM_LOCK,
397 AKEYCODE_SCROLL_LOCK};
Chris Yea52ade12020-08-27 16:49:20 -0700398 const std::array<int32_t, META_NUM> metaCodes = {AMETA_CAPS_LOCK_ON, AMETA_NUM_LOCK_ON,
399 AMETA_SCROLL_LOCK_ON};
400 std::array<uint8_t, META_NUM> flags = {0, 0, 0};
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700401 bool hasKeyLayout = getDeviceContext().markSupportedKeyCodes(keyCodes, flags.data());
Chris Yea52ade12020-08-27 16:49:20 -0700402 // If the device doesn't have the physical meta key it shouldn't generate the corresponding
403 // meta state.
404 if (hasKeyLayout) {
405 for (int i = 0; i < META_NUM; i++) {
406 if (!flags[i]) {
407 mMetaState &= ~metaCodes[i];
408 }
409 }
410 }
411
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700412 updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK, AMETA_CAPS_LOCK_ON, reset);
413 updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK, AMETA_NUM_LOCK_ON, reset);
414 updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, reset);
415}
416
417void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState, int32_t led,
418 int32_t modifier, bool reset) {
419 if (ledState.avail) {
420 bool desiredState = (mMetaState & modifier) != 0;
421 if (reset || ledState.on != desiredState) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800422 getDeviceContext().setLedState(led, desiredState);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700423 ledState.on = desiredState;
424 }
425 }
426}
427
428std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() {
429 if (mViewport) {
430 return std::make_optional(mViewport->displayId);
431 }
432 return std::nullopt;
433}
434
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700435std::list<NotifyArgs> KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) {
436 std::list<NotifyArgs> out;
Arthur Hung2141d542022-08-23 07:45:21 +0000437 size_t n = mKeyDowns.size();
438 for (size_t i = 0; i < n; i++) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700439 out.push_back(NotifyKeyArgs(getContext()->getNextId(), when,
440 systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource,
441 getDisplayId(), 0 /*policyFlags*/, AKEY_EVENT_ACTION_UP,
442 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED,
443 mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
444 mKeyDowns[i].downTime));
Arthur Hung2141d542022-08-23 07:45:21 +0000445 }
446 mKeyDowns.clear();
447 mMetaState = AMETA_NONE;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700448 return out;
Arthur Hung2141d542022-08-23 07:45:21 +0000449}
450
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700451} // namespace android