blob: fa38186e9280d320a120cfc2ce4d4d9e13cfcf7c [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
Prabir Pradhan2197cb42022-10-11 02:56:14 +000027static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
28 static constexpr int32_t KEYCODE_ROTATION_MAP[][4] = {
29 // key codes enumerated counter-clockwise with the original (unrotated) key first
30 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
31 {AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT},
32 {AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN},
33 {AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT},
34 {AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP},
35 {AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
36 AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT},
37 {AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP,
38 AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN},
39 {AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT,
40 AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT},
41 {AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN,
42 AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP},
43 };
44
45 LOG_ALWAYS_FATAL_IF(orientation < 0 || orientation > 3, "Invalid orientation: %d", orientation);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070046 if (orientation != DISPLAY_ORIENTATION_0) {
Prabir Pradhan2197cb42022-10-11 02:56:14 +000047 for (const auto& rotation : KEYCODE_ROTATION_MAP) {
48 if (rotation[DISPLAY_ORIENTATION_0] == keyCode) {
49 return rotation[orientation];
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070050 }
51 }
52 }
Prabir Pradhan2197cb42022-10-11 02:56:14 +000053 return keyCode;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070054}
55
Prabir Pradhan2197cb42022-10-11 02:56:14 +000056static bool isKeyboardOrGamepadKey(int32_t scanCode) {
57 return scanCode < BTN_MOUSE || scanCode >= BTN_WHEEL ||
58 (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) ||
59 (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
60}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070061
Prabir Pradhan2197cb42022-10-11 02:56:14 +000062static bool isMediaKey(int32_t keyCode) {
63 switch (keyCode) {
64 case AKEYCODE_MEDIA_PLAY:
65 case AKEYCODE_MEDIA_PAUSE:
66 case AKEYCODE_MEDIA_PLAY_PAUSE:
67 case AKEYCODE_MUTE:
68 case AKEYCODE_HEADSETHOOK:
69 case AKEYCODE_MEDIA_STOP:
70 case AKEYCODE_MEDIA_NEXT:
71 case AKEYCODE_MEDIA_PREVIOUS:
72 case AKEYCODE_MEDIA_REWIND:
73 case AKEYCODE_MEDIA_RECORD:
74 case AKEYCODE_MEDIA_FAST_FORWARD:
75 case AKEYCODE_MEDIA_SKIP_FORWARD:
76 case AKEYCODE_MEDIA_SKIP_BACKWARD:
77 case AKEYCODE_MEDIA_STEP_FORWARD:
78 case AKEYCODE_MEDIA_STEP_BACKWARD:
79 case AKEYCODE_MEDIA_AUDIO_TRACK:
80 case AKEYCODE_VOLUME_UP:
81 case AKEYCODE_VOLUME_DOWN:
82 case AKEYCODE_VOLUME_MUTE:
83 case AKEYCODE_TV_AUDIO_DESCRIPTION:
84 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP:
85 case AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN:
86 return true;
87 default:
88 return false;
89 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070090}
91
92// --- KeyboardInputMapper ---
93
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -080094KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source,
95 int32_t keyboardType)
96 : InputMapper(deviceContext), mSource(source), mKeyboardType(keyboardType) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070097
Philip Junker4af3b3d2021-12-14 10:36:55 +010098uint32_t KeyboardInputMapper::getSources() const {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070099 return mSource;
100}
101
102int32_t KeyboardInputMapper::getOrientation() {
103 if (mViewport) {
104 return mViewport->orientation;
105 }
106 return DISPLAY_ORIENTATION_0;
107}
108
109int32_t KeyboardInputMapper::getDisplayId() {
110 if (mViewport) {
111 return mViewport->displayId;
112 }
113 return ADISPLAY_ID_NONE;
114}
115
116void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
117 InputMapper::populateDeviceInfo(info);
118
119 info->setKeyboardType(mKeyboardType);
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800120 info->setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700121}
122
123void KeyboardInputMapper::dump(std::string& dump) {
124 dump += INDENT2 "Keyboard Input Mapper:\n";
125 dumpParameters(dump);
126 dump += StringPrintf(INDENT3 "KeyboardType: %d\n", mKeyboardType);
127 dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation());
128 dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
129 dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700130}
131
132std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000133 const InputReaderConfiguration* config) {
Christine Franks1ba71cc2021-04-07 14:37:42 -0700134 if (getDeviceContext().getAssociatedViewport()) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800135 return getDeviceContext().getAssociatedViewport();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700136 }
137
138 // No associated display defined, try to find default display if orientationAware.
139 if (mParameters.orientationAware) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100140 return config->getDisplayViewportByType(ViewportType::INTERNAL);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700141 }
142
143 return std::nullopt;
144}
145
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700146std::list<NotifyArgs> KeyboardInputMapper::configure(nsecs_t when,
147 const InputReaderConfiguration* config,
148 uint32_t changes) {
149 std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700150
151 if (!changes) { // first time only
152 // Configure basic parameters.
153 configureParameters();
154 }
155
156 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000157 mViewport = findViewport(config);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700158 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700159 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700160}
161
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700162void KeyboardInputMapper::configureParameters() {
163 mParameters.orientationAware = false;
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800164 const PropertyMap& config = getDeviceContext().getConfiguration();
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700165 config.tryGetProperty("keyboard.orientationAware", mParameters.orientationAware);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700166
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700167 mParameters.handlesKeyRepeat = false;
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700168 config.tryGetProperty("keyboard.handlesKeyRepeat", mParameters.handlesKeyRepeat);
Powei Fengd041c5d2019-05-03 17:11:33 -0700169
170 mParameters.doNotWakeByDefault = false;
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -0700171 config.tryGetProperty("keyboard.doNotWakeByDefault", mParameters.doNotWakeByDefault);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700172}
173
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000174void KeyboardInputMapper::dumpParameters(std::string& dump) const {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700175 dump += INDENT3 "Parameters:\n";
176 dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
177 dump += StringPrintf(INDENT4 "HandlesKeyRepeat: %s\n", toString(mParameters.handlesKeyRepeat));
178}
179
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700180std::list<NotifyArgs> KeyboardInputMapper::reset(nsecs_t when) {
181 std::list<NotifyArgs> out = cancelAllDownKeys(when);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700182 mCurrentHidUsage = 0;
183
184 resetLedState();
185
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700186 out += InputMapper::reset(when);
187 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700188}
189
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700190std::list<NotifyArgs> KeyboardInputMapper::process(const RawEvent* rawEvent) {
191 std::list<NotifyArgs> out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700192 switch (rawEvent->type) {
193 case EV_KEY: {
194 int32_t scanCode = rawEvent->code;
195 int32_t usageCode = mCurrentHidUsage;
196 mCurrentHidUsage = 0;
197
198 if (isKeyboardOrGamepadKey(scanCode)) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700199 out += processKey(rawEvent->when, rawEvent->readTime, rawEvent->value != 0,
200 scanCode, usageCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700201 }
202 break;
203 }
204 case EV_MSC: {
205 if (rawEvent->code == MSC_SCAN) {
206 mCurrentHidUsage = rawEvent->value;
207 }
208 break;
209 }
210 case EV_SYN: {
211 if (rawEvent->code == SYN_REPORT) {
212 mCurrentHidUsage = 0;
213 }
214 }
215 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700216 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700217}
218
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700219std::list<NotifyArgs> KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
220 int32_t scanCode, int32_t usageCode) {
221 std::list<NotifyArgs> out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700222 int32_t keyCode;
223 int32_t keyMetaState;
224 uint32_t policyFlags;
225
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800226 if (getDeviceContext().mapKey(scanCode, usageCode, mMetaState, &keyCode, &keyMetaState,
227 &policyFlags)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700228 keyCode = AKEYCODE_UNKNOWN;
229 keyMetaState = mMetaState;
230 policyFlags = 0;
231 }
232
Arthur Hung2141d542022-08-23 07:45:21 +0000233 nsecs_t downTime = when;
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000234 std::optional<size_t> keyDownIndex = findKeyDownIndex(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700235 if (down) {
236 // Rotate key codes according to orientation if needed.
237 if (mParameters.orientationAware) {
238 keyCode = rotateKeyCode(keyCode, getOrientation());
239 }
240
241 // Add key down.
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000242 if (keyDownIndex) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700243 // key repeat, be sure to use same keycode as before in case of rotation
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000244 keyCode = mKeyDowns[*keyDownIndex].keyCode;
245 downTime = mKeyDowns[*keyDownIndex].downTime;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700246 } else {
247 // key down
248 if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800249 getContext()->shouldDropVirtualKey(when, keyCode, scanCode)) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700250 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700251 }
252 if (policyFlags & POLICY_FLAG_GESTURE) {
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700253 out += getDeviceContext().cancelTouch(when, readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700254 }
255
256 KeyDown keyDown;
257 keyDown.keyCode = keyCode;
258 keyDown.scanCode = scanCode;
Arthur Hung2141d542022-08-23 07:45:21 +0000259 keyDown.downTime = when;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700260 mKeyDowns.push_back(keyDown);
261 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700262 } else {
263 // Remove key down.
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000264 if (keyDownIndex) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700265 // key up, be sure to use same keycode as before in case of rotation
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000266 keyCode = mKeyDowns[*keyDownIndex].keyCode;
267 downTime = mKeyDowns[*keyDownIndex].downTime;
268 mKeyDowns.erase(mKeyDowns.begin() + *keyDownIndex);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700269 } else {
270 // key was not actually down
271 ALOGI("Dropping key up from device %s because the key was not down. "
272 "keyCode=%d, scanCode=%d",
273 getDeviceName().c_str(), keyCode, scanCode);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700274 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700275 }
276 }
277
278 if (updateMetaStateIfNeeded(keyCode, down)) {
279 // If global meta state changed send it along with the key.
280 // If it has not changed then we'll use what keymap gave us,
281 // since key replacement logic might temporarily reset a few
282 // meta bits for given key.
283 keyMetaState = mMetaState;
284 }
285
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700286 // Key down on external an keyboard should wake the device.
287 // We don't do this for internal keyboards to prevent them from waking up in your pocket.
Powei Fengd041c5d2019-05-03 17:11:33 -0700288 // For internal keyboards and devices for which the default wake behavior is explicitly
289 // prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
290 // wake key individually.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700291 // TODO: Use the input device configuration to control this behavior more finely.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800292 if (down && getDeviceContext().isExternal() && !mParameters.doNotWakeByDefault &&
Powei Fengd041c5d2019-05-03 17:11:33 -0700293 !isMediaKey(keyCode)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700294 policyFlags |= POLICY_FLAG_WAKE;
295 }
296
297 if (mParameters.handlesKeyRepeat) {
298 policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
299 }
300
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000301 out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
302 mSource, getDisplayId(), policyFlags,
303 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
304 AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState,
305 downTime));
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700306 return out;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700307}
308
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000309std::optional<size_t> KeyboardInputMapper::findKeyDownIndex(int32_t scanCode) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700310 size_t n = mKeyDowns.size();
311 for (size_t i = 0; i < n; i++) {
312 if (mKeyDowns[i].scanCode == scanCode) {
313 return i;
314 }
315 }
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000316 return {};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700317}
318
319int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800320 return getDeviceContext().getKeyCodeState(keyCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700321}
322
323int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800324 return getDeviceContext().getScanCodeState(scanCode);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700325}
326
Philip Junker4af3b3d2021-12-14 10:36:55 +0100327int32_t KeyboardInputMapper::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
328 return getDeviceContext().getKeyCodeForKeyLocation(locationKeyCode);
329}
330
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700331bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask,
332 const std::vector<int32_t>& keyCodes,
333 uint8_t* outFlags) {
334 return getDeviceContext().markSupportedKeyCodes(keyCodes, outFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700335}
336
337int32_t KeyboardInputMapper::getMetaState() {
338 return mMetaState;
339}
340
Arthur Hungcb40a002021-08-03 14:31:01 +0000341bool KeyboardInputMapper::updateMetaState(int32_t keyCode) {
342 if (!android::isMetaKey(keyCode) || !getDeviceContext().hasKeyCode(keyCode)) {
343 return false;
344 }
345
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700346 updateMetaStateIfNeeded(keyCode, false);
Arthur Hungcb40a002021-08-03 14:31:01 +0000347 return true;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700348}
349
350bool KeyboardInputMapper::updateMetaStateIfNeeded(int32_t keyCode, bool down) {
351 int32_t oldMetaState = mMetaState;
352 int32_t newMetaState = android::updateMetaState(keyCode, down, oldMetaState);
arthurhungc903df12020-08-11 15:08:42 +0800353 int32_t metaStateChanged = oldMetaState ^ newMetaState;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700354 if (metaStateChanged) {
355 mMetaState = newMetaState;
arthurhungc903df12020-08-11 15:08:42 +0800356 constexpr int32_t allLedMetaState =
357 AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON;
358 if ((metaStateChanged & allLedMetaState) != 0) {
359 getContext()->updateLedMetaState(newMetaState & allLedMetaState);
360 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700361 getContext()->updateGlobalMetaState();
362 }
363
364 return metaStateChanged;
365}
366
367void KeyboardInputMapper::resetLedState() {
368 initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
369 initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
370 initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
371
372 updateLedState(true);
373}
374
375void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800376 ledState.avail = getDeviceContext().hasLed(led);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700377 ledState.on = false;
378}
379
380void KeyboardInputMapper::updateLedState(bool reset) {
Arthur Hungfb3cc112022-04-13 07:39:50 +0000381 // Clear the local led state then union the global led state.
382 mMetaState &= ~(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON);
arthurhungc903df12020-08-11 15:08:42 +0800383 mMetaState |= getContext()->getLedMetaState();
Chris Yea52ade12020-08-27 16:49:20 -0700384
385 constexpr int32_t META_NUM = 3;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700386 const std::vector<int32_t> keyCodes{AKEYCODE_CAPS_LOCK, AKEYCODE_NUM_LOCK,
387 AKEYCODE_SCROLL_LOCK};
Chris Yea52ade12020-08-27 16:49:20 -0700388 const std::array<int32_t, META_NUM> metaCodes = {AMETA_CAPS_LOCK_ON, AMETA_NUM_LOCK_ON,
389 AMETA_SCROLL_LOCK_ON};
390 std::array<uint8_t, META_NUM> flags = {0, 0, 0};
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700391 bool hasKeyLayout = getDeviceContext().markSupportedKeyCodes(keyCodes, flags.data());
Chris Yea52ade12020-08-27 16:49:20 -0700392 // If the device doesn't have the physical meta key it shouldn't generate the corresponding
393 // meta state.
394 if (hasKeyLayout) {
395 for (int i = 0; i < META_NUM; i++) {
396 if (!flags[i]) {
397 mMetaState &= ~metaCodes[i];
398 }
399 }
400 }
401
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700402 updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK, AMETA_CAPS_LOCK_ON, reset);
403 updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK, AMETA_NUM_LOCK_ON, reset);
404 updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, reset);
405}
406
407void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState, int32_t led,
408 int32_t modifier, bool reset) {
409 if (ledState.avail) {
410 bool desiredState = (mMetaState & modifier) != 0;
411 if (reset || ledState.on != desiredState) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800412 getDeviceContext().setLedState(led, desiredState);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700413 ledState.on = desiredState;
414 }
415 }
416}
417
418std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() {
419 if (mViewport) {
420 return std::make_optional(mViewport->displayId);
421 }
422 return std::nullopt;
423}
424
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700425std::list<NotifyArgs> KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) {
426 std::list<NotifyArgs> out;
Arthur Hung2141d542022-08-23 07:45:21 +0000427 size_t n = mKeyDowns.size();
428 for (size_t i = 0; i < n; i++) {
Prabir Pradhan2197cb42022-10-11 02:56:14 +0000429 out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when,
430 systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource,
431 getDisplayId(), 0 /*policyFlags*/, AKEY_EVENT_ACTION_UP,
432 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED,
433 mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
434 mKeyDowns[i].downTime));
Arthur Hung2141d542022-08-23 07:45:21 +0000435 }
436 mKeyDowns.clear();
437 mMetaState = AMETA_NONE;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700438 return out;
Arthur Hung2141d542022-08-23 07:45:21 +0000439}
440
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700441} // namespace android