blob: c63c1797a9102823bde81bc72d8454f2c29ff2c2 [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
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080024#include "CursorInputMapper.h"
25#include "ExternalStylusInputMapper.h"
26#include "InputReaderContext.h"
27#include "JoystickInputMapper.h"
28#include "KeyboardInputMapper.h"
29#include "MultiTouchInputMapper.h"
30#include "RotaryEncoderInputMapper.h"
31#include "SingleTouchInputMapper.h"
32#include "SwitchInputMapper.h"
33#include "VibratorInputMapper.h"
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070034
35namespace android {
36
37InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080038 const InputDeviceIdentifier& identifier)
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070039 : mContext(context),
40 mId(id),
41 mGeneration(generation),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080042 mControllerNumber(0),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070043 mIdentifier(identifier),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080044 mClasses(0),
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070045 mSources(0),
46 mIsExternal(false),
47 mHasMic(false),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080048 mDropUntilNextSync(false) {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070049
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080050InputDevice::~InputDevice() {}
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070051
52bool InputDevice::isEnabled() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080053 if (!hasEventHubDevices()) {
54 return false;
55 }
56 // devices are either all enabled or all disabled, so we only need to check the first
57 auto& devicePair = mDevices.begin()->second;
58 auto& contextPtr = devicePair.first;
59 return contextPtr->isDeviceEnabled();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070060}
61
62void InputDevice::setEnabled(bool enabled, nsecs_t when) {
63 if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) {
64 ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", "
65 "but the corresponding viewport is not found",
66 getName().c_str(), *mAssociatedDisplayPort);
67 enabled = false;
68 }
69
70 if (isEnabled() == enabled) {
71 return;
72 }
73
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080074 // When resetting some devices, the driver needs to be queried to ensure that a proper reset is
75 // performed. The querying must happen when the device is enabled, so we reset after enabling
76 // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070077 if (enabled) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080078 for_each_subdevice([](auto& context) { context.enableDevice(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070079 reset(when);
80 } else {
81 reset(when);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080082 for_each_subdevice([](auto& context) { context.disableDevice(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070083 }
84 // Must change generation to flag this device as changed
85 bumpGeneration();
86}
87
88void InputDevice::dump(std::string& dump) {
89 InputDeviceInfo deviceInfo;
90 getDeviceInfo(&deviceInfo);
91
92 dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
93 deviceInfo.getDisplayName().c_str());
94 dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
95 dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
96 dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
97 if (mAssociatedDisplayPort) {
98 dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
99 } else {
100 dump += "<none>\n";
101 }
102 dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
103 dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
104 dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
105
106 const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
107 if (!ranges.empty()) {
108 dump += INDENT2 "Motion Ranges:\n";
109 for (size_t i = 0; i < ranges.size(); i++) {
110 const InputDeviceInfo::MotionRange& range = ranges[i];
Chris Ye4958d062020-08-20 13:21:10 -0700111 const char* label = InputEventLookup::getAxisLabel(range.axis);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700112 char name[32];
113 if (label) {
114 strncpy(name, label, sizeof(name));
115 name[sizeof(name) - 1] = '\0';
116 } else {
117 snprintf(name, sizeof(name), "%d", range.axis);
118 }
119 dump += StringPrintf(INDENT3
120 "%s: source=0x%08x, "
121 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
122 name, range.source, range.min, range.max, range.flat, range.fuzz,
123 range.resolution);
124 }
125 }
126
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800127 for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700128}
129
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800130void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
131 if (mDevices.find(eventHubId) != mDevices.end()) {
132 return;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800133 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800134 std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
Chris Ye1b0c7342020-07-28 21:57:03 -0700135 Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800136 std::vector<std::unique_ptr<InputMapper>> mappers;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800137
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800138 // Check if we should skip population
139 if (!populateMappers) {
140 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
141 return;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800142 }
143
144 // Switch-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700145 if (classes.test(InputDeviceClass::SWITCH)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800146 mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800147 }
148
149 // Scroll wheel-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700150 if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800151 mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800152 }
153
154 // Vibrator-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700155 if (classes.test(InputDeviceClass::VIBRATOR)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800156 mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800157 }
158
159 // Keyboard-like devices.
160 uint32_t keyboardSource = 0;
161 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
Chris Ye1b0c7342020-07-28 21:57:03 -0700162 if (classes.test(InputDeviceClass::KEYBOARD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800163 keyboardSource |= AINPUT_SOURCE_KEYBOARD;
164 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700165 if (classes.test(InputDeviceClass::ALPHAKEY)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800166 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
167 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700168 if (classes.test(InputDeviceClass::DPAD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800169 keyboardSource |= AINPUT_SOURCE_DPAD;
170 }
Chris Ye1b0c7342020-07-28 21:57:03 -0700171 if (classes.test(InputDeviceClass::GAMEPAD)) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800172 keyboardSource |= AINPUT_SOURCE_GAMEPAD;
173 }
174
175 if (keyboardSource != 0) {
176 mappers.push_back(
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800177 std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800178 }
179
180 // Cursor-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700181 if (classes.test(InputDeviceClass::CURSOR)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800182 mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800183 }
184
185 // Touchscreens and touchpad devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700186 if (classes.test(InputDeviceClass::TOUCH_MT)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800187 mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
Chris Ye1b0c7342020-07-28 21:57:03 -0700188 } else if (classes.test(InputDeviceClass::TOUCH)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800189 mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800190 }
191
192 // Joystick-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700193 if (classes.test(InputDeviceClass::JOYSTICK)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800194 mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800195 }
196
197 // External stylus-like devices.
Chris Ye1b0c7342020-07-28 21:57:03 -0700198 if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800199 mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800200 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800201
202 // insert the context into the devices set
203 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
204}
205
206void InputDevice::removeEventHubDevice(int32_t eventHubId) {
207 mDevices.erase(eventHubId);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700208}
209
210void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
211 uint32_t changes) {
212 mSources = 0;
Chris Ye1b0c7342020-07-28 21:57:03 -0700213 mClasses = Flags<InputDeviceClass>(0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800214 mControllerNumber = 0;
215
216 for_each_subdevice([this](InputDeviceContext& context) {
217 mClasses |= context.getDeviceClasses();
218 int32_t controllerNumber = context.getDeviceControllerNumber();
219 if (controllerNumber > 0) {
220 if (mControllerNumber && mControllerNumber != controllerNumber) {
221 ALOGW("InputDevice::configure(): composite device contains multiple unique "
222 "controller numbers");
223 }
224 mControllerNumber = controllerNumber;
225 }
226 });
227
Chris Ye1b0c7342020-07-28 21:57:03 -0700228 mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
229 mHasMic = mClasses.test(InputDeviceClass::MIC);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700230
231 if (!isIgnored()) {
232 if (!changes) { // first time only
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800233 mConfiguration.clear();
234 for_each_subdevice([this](InputDeviceContext& context) {
235 PropertyMap configuration;
236 context.getConfiguration(&configuration);
237 mConfiguration.addAll(&configuration);
238 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700239 }
240
241 if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
Chris Ye1b0c7342020-07-28 21:57:03 -0700242 if (!mClasses.test(InputDeviceClass::VIRTUAL)) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700243 sp<KeyCharacterMap> keyboardLayout =
244 mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800245 bool shouldBumpGeneration = false;
246 for_each_subdevice(
247 [&keyboardLayout, &shouldBumpGeneration](InputDeviceContext& context) {
248 if (context.setKeyboardLayoutOverlay(keyboardLayout)) {
249 shouldBumpGeneration = true;
250 }
251 });
252 if (shouldBumpGeneration) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700253 bumpGeneration();
254 }
255 }
256 }
257
258 if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
Chris Ye1b0c7342020-07-28 21:57:03 -0700259 if (!(mClasses.test(InputDeviceClass::VIRTUAL))) {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700260 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
261 if (mAlias != alias) {
262 mAlias = alias;
263 bumpGeneration();
264 }
265 }
266 }
267
268 if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
269 auto it = config->disabledDevices.find(mId);
270 bool enabled = it == config->disabledDevices.end();
271 setEnabled(enabled, when);
272 }
273
274 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
275 // In most situations, no port will be specified.
276 mAssociatedDisplayPort = std::nullopt;
277 mAssociatedViewport = std::nullopt;
278 // Find the display port that corresponds to the current input port.
279 const std::string& inputPort = mIdentifier.location;
280 if (!inputPort.empty()) {
281 const std::unordered_map<std::string, uint8_t>& ports = config->portAssociations;
282 const auto& displayPort = ports.find(inputPort);
283 if (displayPort != ports.end()) {
284 mAssociatedDisplayPort = std::make_optional(displayPort->second);
285 }
286 }
287
288 // If the device was explicitly disabled by the user, it would be present in the
289 // "disabledDevices" list. If it is associated with a specific display, and it was not
290 // explicitly disabled, then enable/disable the device based on whether we can find the
291 // corresponding viewport.
292 bool enabled = (config->disabledDevices.find(mId) == config->disabledDevices.end());
293 if (mAssociatedDisplayPort) {
294 mAssociatedViewport = config->getDisplayViewportByPort(*mAssociatedDisplayPort);
295 if (!mAssociatedViewport) {
296 ALOGW("Input device %s should be associated with display on port %" PRIu8 ", "
297 "but the corresponding viewport is not found.",
298 getName().c_str(), *mAssociatedDisplayPort);
299 enabled = false;
300 }
301 }
302
303 if (changes) {
304 // For first-time configuration, only allow device to be disabled after mappers have
305 // finished configuring. This is because we need to read some of the properties from
306 // the device's open fd.
307 setEnabled(enabled, when);
308 }
309 }
310
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800311 for_each_mapper([this, when, config, changes](InputMapper& mapper) {
312 mapper.configure(when, config, changes);
313 mSources |= mapper.getSources();
314 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700315
316 // If a device is just plugged but it might be disabled, we need to update some info like
317 // axis range of touch from each InputMapper first, then disable it.
318 if (!changes) {
319 setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when);
320 }
321 }
322}
323
324void InputDevice::reset(nsecs_t when) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800325 for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700326
327 mContext->updateGlobalMetaState();
328
329 notifyReset(when);
330}
331
332void InputDevice::process(const RawEvent* rawEvents, size_t count) {
333 // Process all of the events in order for each mapper.
334 // We cannot simply ask each mapper to process them in bulk because mappers may
335 // have side-effects that must be interleaved. For example, joystick movement events and
336 // gamepad button presses are handled by different mappers but they should be dispatched
337 // in the order received.
338 for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
339#if DEBUG_RAW_EVENTS
340 ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
341 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when);
342#endif
343
344 if (mDropUntilNextSync) {
345 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
346 mDropUntilNextSync = false;
347#if DEBUG_RAW_EVENTS
348 ALOGD("Recovered from input event buffer overrun.");
349#endif
350 } else {
351#if DEBUG_RAW_EVENTS
352 ALOGD("Dropped input event while waiting for next input sync.");
353#endif
354 }
355 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
356 ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
357 mDropUntilNextSync = true;
358 reset(rawEvent->when);
359 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800360 for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
361 mapper.process(rawEvent);
362 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700363 }
364 --count;
365 }
366}
367
368void InputDevice::timeoutExpired(nsecs_t when) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800369 for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700370}
371
372void InputDevice::updateExternalStylusState(const StylusState& state) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800373 for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700374}
375
376void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
377 outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
378 mHasMic);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800379 for_each_mapper(
380 [outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700381}
382
383int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
384 return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
385}
386
387int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
388 return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
389}
390
391int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
392 return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
393}
394
395int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
396 int32_t result = AKEY_STATE_UNKNOWN;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800397 for (auto& deviceEntry : mDevices) {
398 auto& devicePair = deviceEntry.second;
399 auto& mappers = devicePair.second;
400 for (auto& mapperPtr : mappers) {
401 InputMapper& mapper = *mapperPtr;
402 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
403 // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
404 // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
405 int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
406 if (currentResult >= AKEY_STATE_DOWN) {
407 return currentResult;
408 } else if (currentResult == AKEY_STATE_UP) {
409 result = currentResult;
410 }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700411 }
412 }
413 }
414 return result;
415}
416
417bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
418 const int32_t* keyCodes, uint8_t* outFlags) {
419 bool result = false;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800420 for_each_mapper([&result, sourceMask, numCodes, keyCodes, outFlags](InputMapper& mapper) {
421 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
422 result |= mapper.markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700423 }
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800424 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700425 return result;
426}
427
Nathaniel R. Lewiscacd69a2019-08-12 22:07:00 +0000428void InputDevice::vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700429 int32_t token) {
Nathaniel R. Lewiscacd69a2019-08-12 22:07:00 +0000430 for_each_mapper([pattern, repeat, token](InputMapper& mapper) {
431 mapper.vibrate(pattern, repeat, token);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800432 });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700433}
434
435void InputDevice::cancelVibrate(int32_t token) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800436 for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700437}
438
439void InputDevice::cancelTouch(nsecs_t when) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800440 for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700441}
442
443int32_t InputDevice::getMetaState() {
444 int32_t result = 0;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800445 for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700446 return result;
447}
448
449void InputDevice::updateMetaState(int32_t keyCode) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800450 for_each_mapper([keyCode](InputMapper& mapper) { mapper.updateMetaState(keyCode); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700451}
452
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700453void InputDevice::bumpGeneration() {
454 mGeneration = mContext->bumpGeneration();
455}
456
457void InputDevice::notifyReset(nsecs_t when) {
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800458 NotifyDeviceResetArgs args(mContext->getNextId(), when, mId);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700459 mContext->getListener()->notifyDeviceReset(&args);
460}
461
462std::optional<int32_t> InputDevice::getAssociatedDisplayId() {
463 // Check if we had associated to the specific display.
464 if (mAssociatedViewport) {
465 return mAssociatedViewport->displayId;
466 }
467
468 // No associated display port, check if some InputMapper is associated.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800469 return first_in_mappers<int32_t>(
470 [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700471}
472
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800473// returns the number of mappers associated with the device
474size_t InputDevice::getMapperCount() {
475 size_t count = 0;
476 for (auto& deviceEntry : mDevices) {
477 auto& devicePair = deviceEntry.second;
478 auto& mappers = devicePair.second;
479 count += mappers.size();
480 }
481 return count;
482}
483
484InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800485 : mDevice(device),
486 mContext(device.getContext()),
487 mEventHub(device.getContext()->getEventHub()),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800488 mId(eventHubId),
489 mDeviceId(device.getId()) {}
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800490
491InputDeviceContext::~InputDeviceContext() {}
492
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700493} // namespace android