blob: dd1abeb7a471ca7bd0065517a1e40e7b00e91316 [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
17#include "Macros.h"
18
19#include "InputDevice.h"
20
Chris Ye1b0c7342020-07-28 21:57:03 -070021#include <input/Flags.h>
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080022#include <algorithm>
23
Kim Low03ea0352020-11-06 12:45:07 -080024#include "BatteryInputMapper.h"
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080025#include "CursorInputMapper.h"
26#include "ExternalStylusInputMapper.h"
27#include "InputReaderContext.h"
28#include "JoystickInputMapper.h"
29#include "KeyboardInputMapper.h"
Chris Ye3fdbfef2021-01-06 18:45:18 -080030#include "LightInputMapper.h"
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080031#include "MultiTouchInputMapper.h"
32#include "RotaryEncoderInputMapper.h"
Chris Yef59a2f42020-10-16 12:55:26 -070033#include "SensorInputMapper.h"
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080034#include "SingleTouchInputMapper.h"
35#include "SwitchInputMapper.h"
36#include "VibratorInputMapper.h"
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070037
38namespace android {
39
40InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080041 const InputDeviceIdentifier& identifier)
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070042 : mContext(context),
43 mId(id),
44 mGeneration(generation),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080045 mControllerNumber(0),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070046 mIdentifier(identifier),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080047 mClasses(0),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070048 mSources(0),
49 mIsExternal(false),
50 mHasMic(false),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080051 mDropUntilNextSync(false) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070052
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080053InputDevice::~InputDevice() {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070054
55bool InputDevice::isEnabled() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080056 if (!hasEventHubDevices()) {
57 return false;
58 }
Chris Yee14523a2020-12-19 13:46:00 -080059 // 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;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070064}
65
66void 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
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080078 // 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.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070081 if (enabled) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080082 for_each_subdevice([](auto& context) { context.enableDevice(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070083 reset(when);
84 } else {
85 reset(when);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080086 for_each_subdevice([](auto& context) { context.disableDevice(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070087 }
88 // Must change generation to flag this device as changed
89 bumpGeneration();
90}
91
Chris Yee7310032020-09-22 15:36:28 -070092void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070093 InputDeviceInfo deviceInfo;
94 getDeviceInfo(&deviceInfo);
95
96 dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
97 deviceInfo.getDisplayName().c_str());
Chris Yee7310032020-09-22 15:36:28 -070098 dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070099 dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
100 dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
101 dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
102 if (mAssociatedDisplayPort) {
103 dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
104 } else {
105 dump += "<none>\n";
106 }
107 dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
108 dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
109 dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
Chris Yee7310032020-09-22 15:36:28 -0700110 dump += StringPrintf(INDENT2 "ControllerNum: %d\n", deviceInfo.getControllerNumber());
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700111
112 const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
113 if (!ranges.empty()) {
114 dump += INDENT2 "Motion Ranges:\n";
115 for (size_t i = 0; i < ranges.size(); i++) {
116 const InputDeviceInfo::MotionRange& range = ranges[i];
Chris Ye4958d062020-08-20 13:21:10 -0700117 const char* label = InputEventLookup::getAxisLabel(range.axis);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700118 char name[32];
119 if (label) {
120 strncpy(name, label, sizeof(name));
121 name[sizeof(name) - 1] = '\0';
122 } else {
123 snprintf(name, sizeof(name), "%d", range.axis);
124 }
125 dump += StringPrintf(INDENT3
126 "%s: source=0x%08x, "
127 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
128 name, range.source, range.min, range.max, range.flat, range.fuzz,
129 range.resolution);
130 }
131 }
132
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800133 for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700134}
135
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800136void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
137 if (mDevices.find(eventHubId) != mDevices.end()) {
138 return;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800139 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800140 std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
Chris Ye1b0c7342020-07-28 21:57:03 -0700141 Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800142 std::vector<std::unique_ptr<InputMapper>> mappers;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800143
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800144 // Check if we should skip population
145 if (!populateMappers) {
146 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
147 return;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800148 }
149
150 // Switch-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700151 if (classes.test(InputDeviceClass::SWITCH)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800152 mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800153 }
154
155 // Scroll wheel-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700156 if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800157 mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800158 }
159
160 // Vibrator-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700161 if (classes.test(InputDeviceClass::VIBRATOR)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800162 mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800163 }
164
Chris Ye3fdbfef2021-01-06 18:45:18 -0800165 // Battery-like devices. Only one battery mapper for each EventHub device.
Kim Low03ea0352020-11-06 12:45:07 -0800166 if (classes.test(InputDeviceClass::BATTERY)) {
Chris Ye3fdbfef2021-01-06 18:45:18 -0800167 InputDeviceInfo deviceInfo;
168 getDeviceInfo(&deviceInfo);
169 if (!deviceInfo.hasBattery()) {
170 mappers.push_back(std::make_unique<BatteryInputMapper>(*contextPtr));
171 }
172 }
173
174 // Light-containing devices. Only one light mapper for each EventHub device.
175 if (classes.test(InputDeviceClass::LIGHT)) {
176 InputDeviceInfo deviceInfo;
177 getDeviceInfo(&deviceInfo);
178 if (deviceInfo.getLightIds().empty()) {
179 mappers.push_back(std::make_unique<LightInputMapper>(*contextPtr));
180 }
Kim Low03ea0352020-11-06 12:45:07 -0800181 }
182
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800183 // Keyboard-like devices.
184 uint32_t keyboardSource = 0;
185 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
Chris Ye1b0c7342020-07-28 21:57:03 -0700186 if (classes.test(InputDeviceClass::KEYBOARD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800187 keyboardSource |= AINPUT_SOURCE_KEYBOARD;
188 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700189 if (classes.test(InputDeviceClass::ALPHAKEY)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800190 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
191 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700192 if (classes.test(InputDeviceClass::DPAD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800193 keyboardSource |= AINPUT_SOURCE_DPAD;
194 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700195 if (classes.test(InputDeviceClass::GAMEPAD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800196 keyboardSource |= AINPUT_SOURCE_GAMEPAD;
197 }
198
199 if (keyboardSource != 0) {
200 mappers.push_back(
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800201 std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800202 }
203
204 // Cursor-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700205 if (classes.test(InputDeviceClass::CURSOR)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800206 mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800207 }
208
209 // Touchscreens and touchpad devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700210 if (classes.test(InputDeviceClass::TOUCH_MT)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800211 mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
Chris Ye1b0c7342020-07-28 21:57:03 -0700212 } else if (classes.test(InputDeviceClass::TOUCH)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800213 mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800214 }
215
216 // Joystick-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700217 if (classes.test(InputDeviceClass::JOYSTICK)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800218 mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800219 }
220
Chris Yef59a2f42020-10-16 12:55:26 -0700221 // Motion sensor enabled devices.
222 if (classes.test(InputDeviceClass::SENSOR)) {
223 mappers.push_back(std::make_unique<SensorInputMapper>(*contextPtr));
224 }
225
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800226 // External stylus-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700227 if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800228 mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800229 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800230
231 // insert the context into the devices set
232 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
Chris Yee7310032020-09-22 15:36:28 -0700233 // Must change generation to flag this device as changed
234 bumpGeneration();
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800235}
236
237void InputDevice::removeEventHubDevice(int32_t eventHubId) {
238 mDevices.erase(eventHubId);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700239}
240
241void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
242 uint32_t changes) {
243 mSources = 0;
Chris Ye1b0c7342020-07-28 21:57:03 -0700244 mClasses = Flags<InputDeviceClass>(0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800245 mControllerNumber = 0;
246
247 for_each_subdevice([this](InputDeviceContext& context) {
248 mClasses |= context.getDeviceClasses();
249 int32_t controllerNumber = context.getDeviceControllerNumber();
250 if (controllerNumber > 0) {
251 if (mControllerNumber && mControllerNumber != controllerNumber) {
252 ALOGW("InputDevice::configure(): composite device contains multiple unique "
253 "controller numbers");
254 }
255 mControllerNumber = controllerNumber;
256 }
257 });
258
Chris Ye1b0c7342020-07-28 21:57:03 -0700259 mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
260 mHasMic = mClasses.test(InputDeviceClass::MIC);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700261
262 if (!isIgnored()) {
263 if (!changes) { // first time only
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800264 mConfiguration.clear();
265 for_each_subdevice([this](InputDeviceContext& context) {
266 PropertyMap configuration;
267 context.getConfiguration(&configuration);
268 mConfiguration.addAll(&configuration);
269 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700270 }
271
272 if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
Chris Ye1b0c7342020-07-28 21:57:03 -0700273 if (!mClasses.test(InputDeviceClass::VIRTUAL)) {
Chris Ye3a1e4462020-08-12 10:13:15 -0700274 std::shared_ptr<KeyCharacterMap> keyboardLayout =
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700275 mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800276 bool shouldBumpGeneration = false;
277 for_each_subdevice(
278 [&keyboardLayout, &shouldBumpGeneration](InputDeviceContext& context) {
279 if (context.setKeyboardLayoutOverlay(keyboardLayout)) {
280 shouldBumpGeneration = true;
281 }
282 });
283 if (shouldBumpGeneration) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700284 bumpGeneration();
285 }
286 }
287 }
288
289 if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
Chris Ye1b0c7342020-07-28 21:57:03 -0700290 if (!(mClasses.test(InputDeviceClass::VIRTUAL))) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700291 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
292 if (mAlias != alias) {
293 mAlias = alias;
294 bumpGeneration();
295 }
296 }
297 }
298
299 if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
300 auto it = config->disabledDevices.find(mId);
301 bool enabled = it == config->disabledDevices.end();
302 setEnabled(enabled, when);
303 }
304
305 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
306 // In most situations, no port will be specified.
307 mAssociatedDisplayPort = std::nullopt;
308 mAssociatedViewport = std::nullopt;
309 // Find the display port that corresponds to the current input port.
310 const std::string& inputPort = mIdentifier.location;
311 if (!inputPort.empty()) {
312 const std::unordered_map<std::string, uint8_t>& ports = config->portAssociations;
313 const auto& displayPort = ports.find(inputPort);
314 if (displayPort != ports.end()) {
315 mAssociatedDisplayPort = std::make_optional(displayPort->second);
316 }
317 }
318
319 // If the device was explicitly disabled by the user, it would be present in the
320 // "disabledDevices" list. If it is associated with a specific display, and it was not
321 // explicitly disabled, then enable/disable the device based on whether we can find the
322 // corresponding viewport.
323 bool enabled = (config->disabledDevices.find(mId) == config->disabledDevices.end());
324 if (mAssociatedDisplayPort) {
325 mAssociatedViewport = config->getDisplayViewportByPort(*mAssociatedDisplayPort);
326 if (!mAssociatedViewport) {
327 ALOGW("Input device %s should be associated with display on port %" PRIu8 ", "
328 "but the corresponding viewport is not found.",
329 getName().c_str(), *mAssociatedDisplayPort);
330 enabled = false;
331 }
332 }
333
334 if (changes) {
335 // For first-time configuration, only allow device to be disabled after mappers have
336 // finished configuring. This is because we need to read some of the properties from
337 // the device's open fd.
338 setEnabled(enabled, when);
339 }
340 }
341
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800342 for_each_mapper([this, when, config, changes](InputMapper& mapper) {
343 mapper.configure(when, config, changes);
344 mSources |= mapper.getSources();
345 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700346
347 // If a device is just plugged but it might be disabled, we need to update some info like
348 // axis range of touch from each InputMapper first, then disable it.
349 if (!changes) {
350 setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when);
351 }
352 }
353}
354
355void InputDevice::reset(nsecs_t when) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800356 for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700357
358 mContext->updateGlobalMetaState();
359
360 notifyReset(when);
361}
362
363void InputDevice::process(const RawEvent* rawEvents, size_t count) {
364 // Process all of the events in order for each mapper.
365 // We cannot simply ask each mapper to process them in bulk because mappers may
366 // have side-effects that must be interleaved. For example, joystick movement events and
367 // gamepad button presses are handled by different mappers but they should be dispatched
368 // in the order received.
369 for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
370#if DEBUG_RAW_EVENTS
371 ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
372 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when);
373#endif
374
375 if (mDropUntilNextSync) {
376 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
377 mDropUntilNextSync = false;
378#if DEBUG_RAW_EVENTS
379 ALOGD("Recovered from input event buffer overrun.");
380#endif
381 } else {
382#if DEBUG_RAW_EVENTS
383 ALOGD("Dropped input event while waiting for next input sync.");
384#endif
385 }
386 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
387 ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
388 mDropUntilNextSync = true;
389 reset(rawEvent->when);
390 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800391 for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
392 mapper.process(rawEvent);
393 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700394 }
395 --count;
396 }
397}
398
399void InputDevice::timeoutExpired(nsecs_t when) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800400 for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700401}
402
403void InputDevice::updateExternalStylusState(const StylusState& state) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800404 for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700405}
406
407void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
408 outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
409 mHasMic);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800410 for_each_mapper(
411 [outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700412}
413
414int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
415 return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
416}
417
418int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
419 return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
420}
421
422int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
423 return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
424}
425
426int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
427 int32_t result = AKEY_STATE_UNKNOWN;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800428 for (auto& deviceEntry : mDevices) {
429 auto& devicePair = deviceEntry.second;
430 auto& mappers = devicePair.second;
431 for (auto& mapperPtr : mappers) {
432 InputMapper& mapper = *mapperPtr;
433 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
434 // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
435 // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
436 int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
437 if (currentResult >= AKEY_STATE_DOWN) {
438 return currentResult;
439 } else if (currentResult == AKEY_STATE_UP) {
440 result = currentResult;
441 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700442 }
443 }
444 }
445 return result;
446}
447
448bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
449 const int32_t* keyCodes, uint8_t* outFlags) {
450 bool result = false;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800451 for_each_mapper([&result, sourceMask, numCodes, keyCodes, outFlags](InputMapper& mapper) {
452 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
453 result |= mapper.markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700454 }
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800455 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700456 return result;
457}
458
Chris Ye87143712020-11-10 05:05:58 +0000459void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) {
460 for_each_mapper([sequence, repeat, token](InputMapper& mapper) {
461 mapper.vibrate(sequence, repeat, token);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800462 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700463}
464
465void InputDevice::cancelVibrate(int32_t token) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800466 for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700467}
468
Chris Ye87143712020-11-10 05:05:58 +0000469bool InputDevice::isVibrating() {
470 bool vibrating = false;
471 for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); });
472 return vibrating;
473}
474
475/* There's no guarantee the IDs provided by the different mappers are unique, so if we have two
476 * different vibration mappers then we could have duplicate IDs.
477 * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities,
478 * we would definitely have duplicate IDs.
479 */
480std::vector<int32_t> InputDevice::getVibratorIds() {
481 std::vector<int32_t> vibrators;
482 for_each_mapper([&vibrators](InputMapper& mapper) {
483 std::vector<int32_t> devVibs = mapper.getVibratorIds();
484 vibrators.reserve(vibrators.size() + devVibs.size());
485 vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end());
486 });
487 return vibrators;
488}
489
Chris Yef59a2f42020-10-16 12:55:26 -0700490bool InputDevice::enableSensor(InputDeviceSensorType sensorType,
491 std::chrono::microseconds samplingPeriod,
492 std::chrono::microseconds maxBatchReportLatency) {
493 bool success = true;
494 for_each_mapper(
495 [&success, sensorType, samplingPeriod, maxBatchReportLatency](InputMapper& mapper) {
496 success &= mapper.enableSensor(sensorType, samplingPeriod, maxBatchReportLatency);
497 });
498 return success;
499}
500
501void InputDevice::disableSensor(InputDeviceSensorType sensorType) {
502 for_each_mapper([sensorType](InputMapper& mapper) { mapper.disableSensor(sensorType); });
503}
504
505void InputDevice::flushSensor(InputDeviceSensorType sensorType) {
506 for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); });
507}
508
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000509void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) {
510 for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700511}
512
Kim Low03ea0352020-11-06 12:45:07 -0800513std::optional<int32_t> InputDevice::getBatteryCapacity() {
514 return first_in_mappers<int32_t>(
515 [](InputMapper& mapper) { return mapper.getBatteryCapacity(); });
516}
517
518std::optional<int32_t> InputDevice::getBatteryStatus() {
519 return first_in_mappers<int32_t>([](InputMapper& mapper) { return mapper.getBatteryStatus(); });
520}
521
Chris Ye3fdbfef2021-01-06 18:45:18 -0800522bool InputDevice::setLightColor(int32_t lightId, int32_t color) {
523 bool success = true;
524 for_each_mapper([&success, lightId, color](InputMapper& mapper) {
525 success &= mapper.setLightColor(lightId, color);
526 });
527 return success;
528}
529
530bool InputDevice::setLightPlayerId(int32_t lightId, int32_t playerId) {
531 bool success = true;
532 for_each_mapper([&success, lightId, playerId](InputMapper& mapper) {
533 success &= mapper.setLightPlayerId(lightId, playerId);
534 });
535 return success;
536}
537
538std::optional<int32_t> InputDevice::getLightColor(int32_t lightId) {
539 return first_in_mappers<int32_t>(
540 [lightId](InputMapper& mapper) { return mapper.getLightColor(lightId); });
541}
542
543std::optional<int32_t> InputDevice::getLightPlayerId(int32_t lightId) {
544 return first_in_mappers<int32_t>(
545 [lightId](InputMapper& mapper) { return mapper.getLightPlayerId(lightId); });
546}
547
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700548int32_t InputDevice::getMetaState() {
549 int32_t result = 0;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800550 for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700551 return result;
552}
553
554void InputDevice::updateMetaState(int32_t keyCode) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800555 for_each_mapper([keyCode](InputMapper& mapper) { mapper.updateMetaState(keyCode); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700556}
557
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700558void InputDevice::bumpGeneration() {
559 mGeneration = mContext->bumpGeneration();
560}
561
562void InputDevice::notifyReset(nsecs_t when) {
Siarhei Vishniakouf2f073b2021-02-09 21:59:56 +0000563 NotifyDeviceResetArgs args(mContext->getNextId(), when, mId);
564 mContext->getListener()->notifyDeviceReset(&args);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700565}
566
567std::optional<int32_t> InputDevice::getAssociatedDisplayId() {
568 // Check if we had associated to the specific display.
569 if (mAssociatedViewport) {
570 return mAssociatedViewport->displayId;
571 }
572
573 // No associated display port, check if some InputMapper is associated.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800574 return first_in_mappers<int32_t>(
575 [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700576}
577
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800578// returns the number of mappers associated with the device
579size_t InputDevice::getMapperCount() {
580 size_t count = 0;
581 for (auto& deviceEntry : mDevices) {
582 auto& devicePair = deviceEntry.second;
583 auto& mappers = devicePair.second;
584 count += mappers.size();
585 }
586 return count;
587}
588
arthurhungc903df12020-08-11 15:08:42 +0800589void InputDevice::updateLedState(bool reset) {
590 for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); });
591}
592
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800593InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800594 : mDevice(device),
595 mContext(device.getContext()),
596 mEventHub(device.getContext()->getEventHub()),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800597 mId(eventHubId),
598 mDeviceId(device.getId()) {}
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800599
600InputDeviceContext::~InputDeviceContext() {}
601
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700602} // namespace android