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 #include "Macros.h"
18
19 #include "InputDevice.h"
20
21 #include <algorithm>
22
23 #include <ftl/flags.h>
24
25 #include "CursorInputMapper.h"
26 #include "ExternalStylusInputMapper.h"
27 #include "InputReaderContext.h"
28 #include "JoystickInputMapper.h"
29 #include "KeyboardInputMapper.h"
30 #include "MultiTouchInputMapper.h"
31 #include "PeripheralController.h"
32 #include "RotaryEncoderInputMapper.h"
33 #include "SensorInputMapper.h"
34 #include "SingleTouchInputMapper.h"
35 #include "SwitchInputMapper.h"
36 #include "VibratorInputMapper.h"
37
38 namespace android {
39
InputDevice(InputReaderContext * context,int32_t id,int32_t generation,const InputDeviceIdentifier & identifier)40 InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
41 const InputDeviceIdentifier& identifier)
42 : mContext(context),
43 mId(id),
44 mGeneration(generation),
45 mControllerNumber(0),
46 mIdentifier(identifier),
47 mClasses(0),
48 mSources(0),
49 mIsExternal(false),
50 mHasMic(false),
51 mDropUntilNextSync(false) {}
52
~InputDevice()53 InputDevice::~InputDevice() {}
54
isEnabled()55 bool InputDevice::isEnabled() {
56 if (!hasEventHubDevices()) {
57 return false;
58 }
59 // An input device composed of sub devices can be individually enabled or disabled.
60 // If any of the sub device is enabled then the input device is considered as enabled.
61 bool enabled = false;
62 for_each_subdevice([&enabled](auto& context) { enabled |= context.isDeviceEnabled(); });
63 return enabled;
64 }
65
setEnabled(bool enabled,nsecs_t when)66 void InputDevice::setEnabled(bool enabled, nsecs_t when) {
67 if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) {
68 ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", "
69 "but the corresponding viewport is not found",
70 getName().c_str(), *mAssociatedDisplayPort);
71 enabled = false;
72 }
73
74 if (isEnabled() == enabled) {
75 return;
76 }
77
78 // When resetting some devices, the driver needs to be queried to ensure that a proper reset is
79 // performed. The querying must happen when the device is enabled, so we reset after enabling
80 // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information.
81 if (enabled) {
82 for_each_subdevice([](auto& context) { context.enableDevice(); });
83 reset(when);
84 } else {
85 reset(when);
86 for_each_subdevice([](auto& context) { context.disableDevice(); });
87 }
88 // Must change generation to flag this device as changed
89 bumpGeneration();
90 }
91
dump(std::string & dump,const std::string & eventHubDevStr)92 void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
93 InputDeviceInfo deviceInfo = getDeviceInfo();
94
95 dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
96 deviceInfo.getDisplayName().c_str());
97 dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str());
98 dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
99 dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
100 dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
101 if (mAssociatedDisplayPort) {
102 dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
103 } else {
104 dump += "<none>\n";
105 }
106 dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueId: ");
107 if (mAssociatedDisplayUniqueId) {
108 dump += StringPrintf("%s\n", mAssociatedDisplayUniqueId->c_str());
109 } else {
110 dump += "<none>\n";
111 }
112 dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
113 dump += StringPrintf(INDENT2 "Sources: %s\n",
114 inputEventSourceToString(deviceInfo.getSources()).c_str());
115 dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
116 dump += StringPrintf(INDENT2 "ControllerNum: %d\n", deviceInfo.getControllerNumber());
117
118 const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
119 if (!ranges.empty()) {
120 dump += INDENT2 "Motion Ranges:\n";
121 for (size_t i = 0; i < ranges.size(); i++) {
122 const InputDeviceInfo::MotionRange& range = ranges[i];
123 const char* label = InputEventLookup::getAxisLabel(range.axis);
124 char name[32];
125 if (label) {
126 strncpy(name, label, sizeof(name));
127 name[sizeof(name) - 1] = '\0';
128 } else {
129 snprintf(name, sizeof(name), "%d", range.axis);
130 }
131 dump += StringPrintf(INDENT3
132 "%s: source=%s, "
133 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
134 name, inputEventSourceToString(range.source).c_str(), range.min,
135 range.max, range.flat, range.fuzz, range.resolution);
136 }
137 }
138
139 for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
140 if (mController) {
141 mController->dump(dump);
142 }
143 }
144
addEventHubDevice(int32_t eventHubId,bool populateMappers)145 void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
146 if (mDevices.find(eventHubId) != mDevices.end()) {
147 return;
148 }
149 std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
150 ftl::Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
151 std::vector<std::unique_ptr<InputMapper>> mappers;
152
153 // Check if we should skip population
154 if (!populateMappers) {
155 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
156 return;
157 }
158
159 // Switch-like devices.
160 if (classes.test(InputDeviceClass::SWITCH)) {
161 mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
162 }
163
164 // Scroll wheel-like devices.
165 if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
166 mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
167 }
168
169 // Vibrator-like devices.
170 if (classes.test(InputDeviceClass::VIBRATOR)) {
171 mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
172 }
173
174 // Battery-like devices or light-containing devices.
175 // PeripheralController will be created with associated EventHub device.
176 if (classes.test(InputDeviceClass::BATTERY) || classes.test(InputDeviceClass::LIGHT)) {
177 mController = std::make_unique<PeripheralController>(*contextPtr);
178 }
179
180 // Keyboard-like devices.
181 uint32_t keyboardSource = 0;
182 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
183 if (classes.test(InputDeviceClass::KEYBOARD)) {
184 keyboardSource |= AINPUT_SOURCE_KEYBOARD;
185 }
186 if (classes.test(InputDeviceClass::ALPHAKEY)) {
187 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
188 }
189 if (classes.test(InputDeviceClass::DPAD)) {
190 keyboardSource |= AINPUT_SOURCE_DPAD;
191 }
192 if (classes.test(InputDeviceClass::GAMEPAD)) {
193 keyboardSource |= AINPUT_SOURCE_GAMEPAD;
194 }
195
196 if (keyboardSource != 0) {
197 mappers.push_back(
198 std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
199 }
200
201 // Cursor-like devices.
202 if (classes.test(InputDeviceClass::CURSOR)) {
203 mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
204 }
205
206 // Touchscreens and touchpad devices.
207 if (classes.test(InputDeviceClass::TOUCH_MT)) {
208 mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
209 } else if (classes.test(InputDeviceClass::TOUCH)) {
210 mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
211 }
212
213 // Joystick-like devices.
214 if (classes.test(InputDeviceClass::JOYSTICK)) {
215 mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
216 }
217
218 // Motion sensor enabled devices.
219 if (classes.test(InputDeviceClass::SENSOR)) {
220 mappers.push_back(std::make_unique<SensorInputMapper>(*contextPtr));
221 }
222
223 // External stylus-like devices.
224 if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
225 mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
226 }
227
228 // insert the context into the devices set
229 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
230 // Must change generation to flag this device as changed
231 bumpGeneration();
232 }
233
removeEventHubDevice(int32_t eventHubId)234 void InputDevice::removeEventHubDevice(int32_t eventHubId) {
235 if (mController != nullptr && mController->getEventHubId() == eventHubId) {
236 // Delete mController, since the corresponding eventhub device is going away
237 mController = nullptr;
238 }
239 mDevices.erase(eventHubId);
240 }
241
configure(nsecs_t when,const InputReaderConfiguration * config,uint32_t changes)242 void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
243 uint32_t changes) {
244 mSources = 0;
245 mClasses = ftl::Flags<InputDeviceClass>(0);
246 mControllerNumber = 0;
247
248 for_each_subdevice([this](InputDeviceContext& context) {
249 mClasses |= context.getDeviceClasses();
250 int32_t controllerNumber = context.getDeviceControllerNumber();
251 if (controllerNumber > 0) {
252 if (mControllerNumber && mControllerNumber != controllerNumber) {
253 ALOGW("InputDevice::configure(): composite device contains multiple unique "
254 "controller numbers");
255 }
256 mControllerNumber = controllerNumber;
257 }
258 });
259
260 mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
261 mHasMic = mClasses.test(InputDeviceClass::MIC);
262
263 if (!isIgnored()) {
264 if (!changes) { // first time only
265 mConfiguration.clear();
266 for_each_subdevice([this](InputDeviceContext& context) {
267 PropertyMap configuration;
268 context.getConfiguration(&configuration);
269 mConfiguration.addAll(&configuration);
270 });
271 }
272
273 if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
274 if (!mClasses.test(InputDeviceClass::VIRTUAL)) {
275 std::shared_ptr<KeyCharacterMap> keyboardLayout =
276 mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
277 bool shouldBumpGeneration = false;
278 for_each_subdevice(
279 [&keyboardLayout, &shouldBumpGeneration](InputDeviceContext& context) {
280 if (context.setKeyboardLayoutOverlay(keyboardLayout)) {
281 shouldBumpGeneration = true;
282 }
283 });
284 if (shouldBumpGeneration) {
285 bumpGeneration();
286 }
287 }
288 }
289
290 if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
291 if (!(mClasses.test(InputDeviceClass::VIRTUAL))) {
292 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
293 if (mAlias != alias) {
294 mAlias = alias;
295 bumpGeneration();
296 }
297 }
298 }
299
300 if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
301 auto it = config->disabledDevices.find(mId);
302 bool enabled = it == config->disabledDevices.end();
303 setEnabled(enabled, when);
304 }
305
306 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
307 // In most situations, no port or name will be specified.
308 mAssociatedDisplayPort = std::nullopt;
309 mAssociatedDisplayUniqueId = std::nullopt;
310 mAssociatedViewport = std::nullopt;
311 // Find the display port that corresponds to the current input port.
312 const std::string& inputPort = mIdentifier.location;
313 if (!inputPort.empty()) {
314 const std::unordered_map<std::string, uint8_t>& ports = config->portAssociations;
315 const auto& displayPort = ports.find(inputPort);
316 if (displayPort != ports.end()) {
317 mAssociatedDisplayPort = std::make_optional(displayPort->second);
318 } else {
319 const std::unordered_map<std::string, std::string>& displayUniqueIds =
320 config->uniqueIdAssociations;
321 const auto& displayUniqueId = displayUniqueIds.find(inputPort);
322 if (displayUniqueId != displayUniqueIds.end()) {
323 mAssociatedDisplayUniqueId = displayUniqueId->second;
324 }
325 }
326 }
327
328 // If the device was explicitly disabled by the user, it would be present in the
329 // "disabledDevices" list. If it is associated with a specific display, and it was not
330 // explicitly disabled, then enable/disable the device based on whether we can find the
331 // corresponding viewport.
332 bool enabled = (config->disabledDevices.find(mId) == config->disabledDevices.end());
333 if (mAssociatedDisplayPort) {
334 mAssociatedViewport = config->getDisplayViewportByPort(*mAssociatedDisplayPort);
335 if (!mAssociatedViewport) {
336 ALOGW("Input device %s should be associated with display on port %" PRIu8 ", "
337 "but the corresponding viewport is not found.",
338 getName().c_str(), *mAssociatedDisplayPort);
339 enabled = false;
340 }
341 } else if (mAssociatedDisplayUniqueId != std::nullopt) {
342 mAssociatedViewport =
343 config->getDisplayViewportByUniqueId(*mAssociatedDisplayUniqueId);
344 if (!mAssociatedViewport) {
345 ALOGW("Input device %s should be associated with display %s but the "
346 "corresponding viewport cannot be found",
347 getName().c_str(), mAssociatedDisplayUniqueId->c_str());
348 enabled = false;
349 }
350 }
351
352 if (changes) {
353 // For first-time configuration, only allow device to be disabled after mappers have
354 // finished configuring. This is because we need to read some of the properties from
355 // the device's open fd.
356 setEnabled(enabled, when);
357 }
358 }
359
360 for_each_mapper([this, when, config, changes](InputMapper& mapper) {
361 mapper.configure(when, config, changes);
362 mSources |= mapper.getSources();
363 });
364
365 // If a device is just plugged but it might be disabled, we need to update some info like
366 // axis range of touch from each InputMapper first, then disable it.
367 if (!changes) {
368 setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when);
369 }
370 }
371 }
372
reset(nsecs_t when)373 void InputDevice::reset(nsecs_t when) {
374 for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); });
375
376 mContext->updateGlobalMetaState();
377
378 notifyReset(when);
379 }
380
process(const RawEvent * rawEvents,size_t count)381 void InputDevice::process(const RawEvent* rawEvents, size_t count) {
382 // Process all of the events in order for each mapper.
383 // We cannot simply ask each mapper to process them in bulk because mappers may
384 // have side-effects that must be interleaved. For example, joystick movement events and
385 // gamepad button presses are handled by different mappers but they should be dispatched
386 // in the order received.
387 for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
388 if (DEBUG_RAW_EVENTS) {
389 ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
390 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
391 rawEvent->when);
392 }
393
394 if (mDropUntilNextSync) {
395 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
396 mDropUntilNextSync = false;
397 if (DEBUG_RAW_EVENTS) {
398 ALOGD("Recovered from input event buffer overrun.");
399 }
400 } else {
401 if (DEBUG_RAW_EVENTS) {
402 ALOGD("Dropped input event while waiting for next input sync.");
403 }
404 }
405 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
406 ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
407 mDropUntilNextSync = true;
408 reset(rawEvent->when);
409 } else {
410 for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
411 mapper.process(rawEvent);
412 });
413 }
414 --count;
415 }
416 }
417
timeoutExpired(nsecs_t when)418 void InputDevice::timeoutExpired(nsecs_t when) {
419 for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); });
420 }
421
updateExternalStylusState(const StylusState & state)422 void InputDevice::updateExternalStylusState(const StylusState& state) {
423 for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); });
424 }
425
getDeviceInfo()426 InputDeviceInfo InputDevice::getDeviceInfo() {
427 InputDeviceInfo outDeviceInfo;
428 outDeviceInfo.initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
429 mHasMic);
430 for_each_mapper(
431 [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(&outDeviceInfo); });
432
433 if (mController) {
434 mController->populateDeviceInfo(&outDeviceInfo);
435 }
436 return outDeviceInfo;
437 }
438
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)439 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
440 return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
441 }
442
getScanCodeState(uint32_t sourceMask,int32_t scanCode)443 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
444 return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
445 }
446
getSwitchState(uint32_t sourceMask,int32_t switchCode)447 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
448 return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
449 }
450
getState(uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)451 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
452 int32_t result = AKEY_STATE_UNKNOWN;
453 for (auto& deviceEntry : mDevices) {
454 auto& devicePair = deviceEntry.second;
455 auto& mappers = devicePair.second;
456 for (auto& mapperPtr : mappers) {
457 InputMapper& mapper = *mapperPtr;
458 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
459 // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
460 // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
461 int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
462 if (currentResult >= AKEY_STATE_DOWN) {
463 return currentResult;
464 } else if (currentResult == AKEY_STATE_UP) {
465 result = currentResult;
466 }
467 }
468 }
469 }
470 return result;
471 }
472
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)473 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
474 const int32_t* keyCodes, uint8_t* outFlags) {
475 bool result = false;
476 for_each_mapper([&result, sourceMask, numCodes, keyCodes, outFlags](InputMapper& mapper) {
477 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
478 result |= mapper.markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
479 }
480 });
481 return result;
482 }
483
getKeyCodeForKeyLocation(int32_t locationKeyCode) const484 int32_t InputDevice::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
485 std::optional<int32_t> result = first_in_mappers<int32_t>(
486 [locationKeyCode](const InputMapper& mapper) -> std::optional<int32_t> const {
487 if (sourcesMatchMask(mapper.getSources(), AINPUT_SOURCE_KEYBOARD)) {
488 return std::make_optional(mapper.getKeyCodeForKeyLocation(locationKeyCode));
489 }
490 return std::nullopt;
491 });
492 if (!result) {
493 ALOGE("Failed to get key code for key location: No matching InputMapper with source mask "
494 "KEYBOARD found. The provided input device with id %d has sources %s.",
495 getId(), inputEventSourceToString(getSources()).c_str());
496 return AKEYCODE_UNKNOWN;
497 }
498 return *result;
499 }
500
vibrate(const VibrationSequence & sequence,ssize_t repeat,int32_t token)501 void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) {
502 for_each_mapper([sequence, repeat, token](InputMapper& mapper) {
503 mapper.vibrate(sequence, repeat, token);
504 });
505 }
506
cancelVibrate(int32_t token)507 void InputDevice::cancelVibrate(int32_t token) {
508 for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); });
509 }
510
isVibrating()511 bool InputDevice::isVibrating() {
512 bool vibrating = false;
513 for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); });
514 return vibrating;
515 }
516
517 /* There's no guarantee the IDs provided by the different mappers are unique, so if we have two
518 * different vibration mappers then we could have duplicate IDs.
519 * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities,
520 * we would definitely have duplicate IDs.
521 */
getVibratorIds()522 std::vector<int32_t> InputDevice::getVibratorIds() {
523 std::vector<int32_t> vibrators;
524 for_each_mapper([&vibrators](InputMapper& mapper) {
525 std::vector<int32_t> devVibs = mapper.getVibratorIds();
526 vibrators.reserve(vibrators.size() + devVibs.size());
527 vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end());
528 });
529 return vibrators;
530 }
531
enableSensor(InputDeviceSensorType sensorType,std::chrono::microseconds samplingPeriod,std::chrono::microseconds maxBatchReportLatency)532 bool InputDevice::enableSensor(InputDeviceSensorType sensorType,
533 std::chrono::microseconds samplingPeriod,
534 std::chrono::microseconds maxBatchReportLatency) {
535 bool success = true;
536 for_each_mapper(
537 [&success, sensorType, samplingPeriod, maxBatchReportLatency](InputMapper& mapper) {
538 success &= mapper.enableSensor(sensorType, samplingPeriod, maxBatchReportLatency);
539 });
540 return success;
541 }
542
disableSensor(InputDeviceSensorType sensorType)543 void InputDevice::disableSensor(InputDeviceSensorType sensorType) {
544 for_each_mapper([sensorType](InputMapper& mapper) { mapper.disableSensor(sensorType); });
545 }
546
flushSensor(InputDeviceSensorType sensorType)547 void InputDevice::flushSensor(InputDeviceSensorType sensorType) {
548 for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); });
549 }
550
cancelTouch(nsecs_t when,nsecs_t readTime)551 void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) {
552 for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); });
553 }
554
getBatteryCapacity()555 std::optional<int32_t> InputDevice::getBatteryCapacity() {
556 return mController ? mController->getBatteryCapacity(DEFAULT_BATTERY_ID) : std::nullopt;
557 }
558
getBatteryStatus()559 std::optional<int32_t> InputDevice::getBatteryStatus() {
560 return mController ? mController->getBatteryStatus(DEFAULT_BATTERY_ID) : std::nullopt;
561 }
562
setLightColor(int32_t lightId,int32_t color)563 bool InputDevice::setLightColor(int32_t lightId, int32_t color) {
564 return mController ? mController->setLightColor(lightId, color) : false;
565 }
566
setLightPlayerId(int32_t lightId,int32_t playerId)567 bool InputDevice::setLightPlayerId(int32_t lightId, int32_t playerId) {
568 return mController ? mController->setLightPlayerId(lightId, playerId) : false;
569 }
570
getLightColor(int32_t lightId)571 std::optional<int32_t> InputDevice::getLightColor(int32_t lightId) {
572 return mController ? mController->getLightColor(lightId) : std::nullopt;
573 }
574
getLightPlayerId(int32_t lightId)575 std::optional<int32_t> InputDevice::getLightPlayerId(int32_t lightId) {
576 return mController ? mController->getLightPlayerId(lightId) : std::nullopt;
577 }
578
getMetaState()579 int32_t InputDevice::getMetaState() {
580 int32_t result = 0;
581 for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); });
582 return result;
583 }
584
updateMetaState(int32_t keyCode)585 void InputDevice::updateMetaState(int32_t keyCode) {
586 first_in_mappers<bool>([keyCode](InputMapper& mapper) {
587 if (sourcesMatchMask(mapper.getSources(), AINPUT_SOURCE_KEYBOARD) &&
588 mapper.updateMetaState(keyCode)) {
589 return std::make_optional(true);
590 }
591 return std::optional<bool>();
592 });
593 }
594
bumpGeneration()595 void InputDevice::bumpGeneration() {
596 mGeneration = mContext->bumpGeneration();
597 }
598
notifyReset(nsecs_t when)599 void InputDevice::notifyReset(nsecs_t when) {
600 NotifyDeviceResetArgs args(mContext->getNextId(), when, mId);
601 mContext->getListener().notifyDeviceReset(&args);
602 }
603
getAssociatedDisplayId()604 std::optional<int32_t> InputDevice::getAssociatedDisplayId() {
605 // Check if we had associated to the specific display.
606 if (mAssociatedViewport) {
607 return mAssociatedViewport->displayId;
608 }
609
610 // No associated display port, check if some InputMapper is associated.
611 return first_in_mappers<int32_t>(
612 [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
613 }
614
615 // returns the number of mappers associated with the device
getMapperCount()616 size_t InputDevice::getMapperCount() {
617 size_t count = 0;
618 for (auto& deviceEntry : mDevices) {
619 auto& devicePair = deviceEntry.second;
620 auto& mappers = devicePair.second;
621 count += mappers.size();
622 }
623 return count;
624 }
625
updateLedState(bool reset)626 void InputDevice::updateLedState(bool reset) {
627 for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); });
628 }
629
InputDeviceContext(InputDevice & device,int32_t eventHubId)630 InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
631 : mDevice(device),
632 mContext(device.getContext()),
633 mEventHub(device.getContext()->getEventHub()),
634 mId(eventHubId),
635 mDeviceId(device.getId()) {}
636
~InputDeviceContext()637 InputDeviceContext::~InputDeviceContext() {}
638
639 } // namespace android
640