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 "CursorInputMapper.h"
24 #include "ExternalStylusInputMapper.h"
25 #include "InputReaderContext.h"
26 #include "JoystickInputMapper.h"
27 #include "KeyboardInputMapper.h"
28 #include "MultiTouchInputMapper.h"
29 #include "RotaryEncoderInputMapper.h"
30 #include "SingleTouchInputMapper.h"
31 #include "SwitchInputMapper.h"
32 #include "VibratorInputMapper.h"
33
34 namespace android {
35
InputDevice(InputReaderContext * context,int32_t id,int32_t generation,const InputDeviceIdentifier & identifier)36 InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
37 const InputDeviceIdentifier& identifier)
38 : mContext(context),
39 mId(id),
40 mGeneration(generation),
41 mControllerNumber(0),
42 mIdentifier(identifier),
43 mClasses(0),
44 mSources(0),
45 mIsExternal(false),
46 mHasMic(false),
47 mDropUntilNextSync(false) {}
48
~InputDevice()49 InputDevice::~InputDevice() {}
50
isEnabled()51 bool InputDevice::isEnabled() {
52 if (!hasEventHubDevices()) {
53 return false;
54 }
55 // devices are either all enabled or all disabled, so we only need to check the first
56 auto& devicePair = mDevices.begin()->second;
57 auto& contextPtr = devicePair.first;
58 return contextPtr->isDeviceEnabled();
59 }
60
setEnabled(bool enabled,nsecs_t when)61 void InputDevice::setEnabled(bool enabled, nsecs_t when) {
62 if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) {
63 ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", "
64 "but the corresponding viewport is not found",
65 getName().c_str(), *mAssociatedDisplayPort);
66 enabled = false;
67 }
68
69 if (isEnabled() == enabled) {
70 return;
71 }
72
73 // When resetting some devices, the driver needs to be queried to ensure that a proper reset is
74 // performed. The querying must happen when the device is enabled, so we reset after enabling
75 // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information.
76 if (enabled) {
77 for_each_subdevice([](auto& context) { context.enableDevice(); });
78 reset(when);
79 } else {
80 reset(when);
81 for_each_subdevice([](auto& context) { context.disableDevice(); });
82 }
83 // Must change generation to flag this device as changed
84 bumpGeneration();
85 }
86
dump(std::string & dump)87 void InputDevice::dump(std::string& dump) {
88 InputDeviceInfo deviceInfo;
89 getDeviceInfo(&deviceInfo);
90
91 dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
92 deviceInfo.getDisplayName().c_str());
93 dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
94 dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
95 dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
96 if (mAssociatedDisplayPort) {
97 dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
98 } else {
99 dump += "<none>\n";
100 }
101 dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
102 dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
103 dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
104
105 const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
106 if (!ranges.empty()) {
107 dump += INDENT2 "Motion Ranges:\n";
108 for (size_t i = 0; i < ranges.size(); i++) {
109 const InputDeviceInfo::MotionRange& range = ranges[i];
110 const char* label = getAxisLabel(range.axis);
111 char name[32];
112 if (label) {
113 strncpy(name, label, sizeof(name));
114 name[sizeof(name) - 1] = '\0';
115 } else {
116 snprintf(name, sizeof(name), "%d", range.axis);
117 }
118 dump += StringPrintf(INDENT3
119 "%s: source=0x%08x, "
120 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
121 name, range.source, range.min, range.max, range.flat, range.fuzz,
122 range.resolution);
123 }
124 }
125
126 for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
127 }
128
addEventHubDevice(int32_t eventHubId,bool populateMappers)129 void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
130 if (mDevices.find(eventHubId) != mDevices.end()) {
131 return;
132 }
133 std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
134 uint32_t classes = contextPtr->getDeviceClasses();
135 std::vector<std::unique_ptr<InputMapper>> mappers;
136
137 // Check if we should skip population
138 if (!populateMappers) {
139 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
140 return;
141 }
142
143 // Switch-like devices.
144 if (classes & INPUT_DEVICE_CLASS_SWITCH) {
145 mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
146 }
147
148 // Scroll wheel-like devices.
149 if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
150 mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
151 }
152
153 // Vibrator-like devices.
154 if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
155 mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
156 }
157
158 // Keyboard-like devices.
159 uint32_t keyboardSource = 0;
160 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
161 if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
162 keyboardSource |= AINPUT_SOURCE_KEYBOARD;
163 }
164 if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
165 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
166 }
167 if (classes & INPUT_DEVICE_CLASS_DPAD) {
168 keyboardSource |= AINPUT_SOURCE_DPAD;
169 }
170 if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
171 keyboardSource |= AINPUT_SOURCE_GAMEPAD;
172 }
173
174 if (keyboardSource != 0) {
175 mappers.push_back(
176 std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
177 }
178
179 // Cursor-like devices.
180 if (classes & INPUT_DEVICE_CLASS_CURSOR) {
181 mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
182 }
183
184 // Touchscreens and touchpad devices.
185 if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
186 mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
187 } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
188 mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
189 }
190
191 // Joystick-like devices.
192 if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
193 mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
194 }
195
196 // External stylus-like devices.
197 if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
198 mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
199 }
200
201 // insert the context into the devices set
202 mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
203 }
204
removeEventHubDevice(int32_t eventHubId)205 void InputDevice::removeEventHubDevice(int32_t eventHubId) {
206 mDevices.erase(eventHubId);
207 }
208
configure(nsecs_t when,const InputReaderConfiguration * config,uint32_t changes)209 void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
210 uint32_t changes) {
211 mSources = 0;
212 mClasses = 0;
213 mControllerNumber = 0;
214
215 for_each_subdevice([this](InputDeviceContext& context) {
216 mClasses |= context.getDeviceClasses();
217 int32_t controllerNumber = context.getDeviceControllerNumber();
218 if (controllerNumber > 0) {
219 if (mControllerNumber && mControllerNumber != controllerNumber) {
220 ALOGW("InputDevice::configure(): composite device contains multiple unique "
221 "controller numbers");
222 }
223 mControllerNumber = controllerNumber;
224 }
225 });
226
227 mIsExternal = !!(mClasses & INPUT_DEVICE_CLASS_EXTERNAL);
228 mHasMic = !!(mClasses & INPUT_DEVICE_CLASS_MIC);
229
230 if (!isIgnored()) {
231 if (!changes) { // first time only
232 mConfiguration.clear();
233 for_each_subdevice([this](InputDeviceContext& context) {
234 PropertyMap configuration;
235 context.getConfiguration(&configuration);
236 mConfiguration.addAll(&configuration);
237 });
238 }
239
240 if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
241 if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
242 sp<KeyCharacterMap> keyboardLayout =
243 mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
244 bool shouldBumpGeneration = false;
245 for_each_subdevice(
246 [&keyboardLayout, &shouldBumpGeneration](InputDeviceContext& context) {
247 if (context.setKeyboardLayoutOverlay(keyboardLayout)) {
248 shouldBumpGeneration = true;
249 }
250 });
251 if (shouldBumpGeneration) {
252 bumpGeneration();
253 }
254 }
255 }
256
257 if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
258 if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
259 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
260 if (mAlias != alias) {
261 mAlias = alias;
262 bumpGeneration();
263 }
264 }
265 }
266
267 if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
268 auto it = config->disabledDevices.find(mId);
269 bool enabled = it == config->disabledDevices.end();
270 setEnabled(enabled, when);
271 }
272
273 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
274 // In most situations, no port will be specified.
275 mAssociatedDisplayPort = std::nullopt;
276 mAssociatedViewport = std::nullopt;
277 // Find the display port that corresponds to the current input port.
278 const std::string& inputPort = mIdentifier.location;
279 if (!inputPort.empty()) {
280 const std::unordered_map<std::string, uint8_t>& ports = config->portAssociations;
281 const auto& displayPort = ports.find(inputPort);
282 if (displayPort != ports.end()) {
283 mAssociatedDisplayPort = std::make_optional(displayPort->second);
284 }
285 }
286
287 // If the device was explicitly disabled by the user, it would be present in the
288 // "disabledDevices" list. If it is associated with a specific display, and it was not
289 // explicitly disabled, then enable/disable the device based on whether we can find the
290 // corresponding viewport.
291 bool enabled = (config->disabledDevices.find(mId) == config->disabledDevices.end());
292 if (mAssociatedDisplayPort) {
293 mAssociatedViewport = config->getDisplayViewportByPort(*mAssociatedDisplayPort);
294 if (!mAssociatedViewport) {
295 ALOGW("Input device %s should be associated with display on port %" PRIu8 ", "
296 "but the corresponding viewport is not found.",
297 getName().c_str(), *mAssociatedDisplayPort);
298 enabled = false;
299 }
300 }
301
302 if (changes) {
303 // For first-time configuration, only allow device to be disabled after mappers have
304 // finished configuring. This is because we need to read some of the properties from
305 // the device's open fd.
306 setEnabled(enabled, when);
307 }
308 }
309
310 for_each_mapper([this, when, config, changes](InputMapper& mapper) {
311 mapper.configure(when, config, changes);
312 mSources |= mapper.getSources();
313 });
314
315 // If a device is just plugged but it might be disabled, we need to update some info like
316 // axis range of touch from each InputMapper first, then disable it.
317 if (!changes) {
318 setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when);
319 }
320 }
321 }
322
reset(nsecs_t when)323 void InputDevice::reset(nsecs_t when) {
324 for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); });
325
326 mContext->updateGlobalMetaState();
327
328 notifyReset(when);
329 }
330
process(const RawEvent * rawEvents,size_t count)331 void InputDevice::process(const RawEvent* rawEvents, size_t count) {
332 // Process all of the events in order for each mapper.
333 // We cannot simply ask each mapper to process them in bulk because mappers may
334 // have side-effects that must be interleaved. For example, joystick movement events and
335 // gamepad button presses are handled by different mappers but they should be dispatched
336 // in the order received.
337 for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
338 #if DEBUG_RAW_EVENTS
339 ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
340 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when);
341 #endif
342
343 if (mDropUntilNextSync) {
344 if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
345 mDropUntilNextSync = false;
346 #if DEBUG_RAW_EVENTS
347 ALOGD("Recovered from input event buffer overrun.");
348 #endif
349 } else {
350 #if DEBUG_RAW_EVENTS
351 ALOGD("Dropped input event while waiting for next input sync.");
352 #endif
353 }
354 } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
355 ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
356 mDropUntilNextSync = true;
357 reset(rawEvent->when);
358 } else {
359 for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
360 mapper.process(rawEvent);
361 });
362 }
363 --count;
364 }
365 }
366
timeoutExpired(nsecs_t when)367 void InputDevice::timeoutExpired(nsecs_t when) {
368 for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); });
369 }
370
updateExternalStylusState(const StylusState & state)371 void InputDevice::updateExternalStylusState(const StylusState& state) {
372 for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); });
373 }
374
getDeviceInfo(InputDeviceInfo * outDeviceInfo)375 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
376 outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
377 mHasMic);
378 for_each_mapper(
379 [outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
380 }
381
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)382 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
383 return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
384 }
385
getScanCodeState(uint32_t sourceMask,int32_t scanCode)386 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
387 return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
388 }
389
getSwitchState(uint32_t sourceMask,int32_t switchCode)390 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
391 return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
392 }
393
getState(uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)394 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
395 int32_t result = AKEY_STATE_UNKNOWN;
396 for (auto& deviceEntry : mDevices) {
397 auto& devicePair = deviceEntry.second;
398 auto& mappers = devicePair.second;
399 for (auto& mapperPtr : mappers) {
400 InputMapper& mapper = *mapperPtr;
401 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
402 // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
403 // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
404 int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
405 if (currentResult >= AKEY_STATE_DOWN) {
406 return currentResult;
407 } else if (currentResult == AKEY_STATE_UP) {
408 result = currentResult;
409 }
410 }
411 }
412 }
413 return result;
414 }
415
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)416 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
417 const int32_t* keyCodes, uint8_t* outFlags) {
418 bool result = false;
419 for_each_mapper([&result, sourceMask, numCodes, keyCodes, outFlags](InputMapper& mapper) {
420 if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
421 result |= mapper.markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
422 }
423 });
424 return result;
425 }
426
vibrate(const nsecs_t * pattern,size_t patternSize,ssize_t repeat,int32_t token)427 void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
428 int32_t token) {
429 for_each_mapper([pattern, patternSize, repeat, token](InputMapper& mapper) {
430 mapper.vibrate(pattern, patternSize, repeat, token);
431 });
432 }
433
cancelVibrate(int32_t token)434 void InputDevice::cancelVibrate(int32_t token) {
435 for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); });
436 }
437
cancelTouch(nsecs_t when)438 void InputDevice::cancelTouch(nsecs_t when) {
439 for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); });
440 }
441
getMetaState()442 int32_t InputDevice::getMetaState() {
443 int32_t result = 0;
444 for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); });
445 return result;
446 }
447
updateMetaState(int32_t keyCode)448 void InputDevice::updateMetaState(int32_t keyCode) {
449 for_each_mapper([keyCode](InputMapper& mapper) { mapper.updateMetaState(keyCode); });
450 }
451
bumpGeneration()452 void InputDevice::bumpGeneration() {
453 mGeneration = mContext->bumpGeneration();
454 }
455
notifyReset(nsecs_t when)456 void InputDevice::notifyReset(nsecs_t when) {
457 NotifyDeviceResetArgs args(mContext->getNextId(), when, mId);
458 mContext->getListener()->notifyDeviceReset(&args);
459 }
460
getAssociatedDisplayId()461 std::optional<int32_t> InputDevice::getAssociatedDisplayId() {
462 // Check if we had associated to the specific display.
463 if (mAssociatedViewport) {
464 return mAssociatedViewport->displayId;
465 }
466
467 // No associated display port, check if some InputMapper is associated.
468 return first_in_mappers<int32_t>(
469 [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
470 }
471
472 // returns the number of mappers associated with the device
getMapperCount()473 size_t InputDevice::getMapperCount() {
474 size_t count = 0;
475 for (auto& deviceEntry : mDevices) {
476 auto& devicePair = deviceEntry.second;
477 auto& mappers = devicePair.second;
478 count += mappers.size();
479 }
480 return count;
481 }
482
InputDeviceContext(InputDevice & device,int32_t eventHubId)483 InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
484 : mDevice(device),
485 mContext(device.getContext()),
486 mEventHub(device.getContext()->getEventHub()),
487 mId(eventHubId),
488 mDeviceId(device.getId()) {}
489
~InputDeviceContext()490 InputDeviceContext::~InputDeviceContext() {}
491
492 } // namespace android
493