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