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 "InputMapper.h"
22 
23 namespace android {
24 
InputDevice(InputReaderContext * context,int32_t id,int32_t generation,int32_t controllerNumber,const InputDeviceIdentifier & identifier,uint32_t classes)25 InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
26                          int32_t controllerNumber, const InputDeviceIdentifier& identifier,
27                          uint32_t classes)
28       : mContext(context),
29         mId(id),
30         mGeneration(generation),
31         mControllerNumber(controllerNumber),
32         mIdentifier(identifier),
33         mClasses(classes),
34         mSources(0),
35         mIsExternal(false),
36         mHasMic(false),
37         mDropUntilNextSync(false) {}
38 
~InputDevice()39 InputDevice::~InputDevice() {
40     size_t numMappers = mMappers.size();
41     for (size_t i = 0; i < numMappers; i++) {
42         delete mMappers[i];
43     }
44     mMappers.clear();
45 }
46 
isEnabled()47 bool InputDevice::isEnabled() {
48     return getEventHub()->isDeviceEnabled(mId);
49 }
50 
setEnabled(bool enabled,nsecs_t when)51 void InputDevice::setEnabled(bool enabled, nsecs_t when) {
52     if (isEnabled() == enabled) {
53         return;
54     }
55 
56     if (enabled) {
57         getEventHub()->enableDevice(mId);
58         reset(when);
59     } else {
60         reset(when);
61         getEventHub()->disableDevice(mId);
62     }
63     // Must change generation to flag this device as changed
64     bumpGeneration();
65 }
66 
dump(std::string & dump)67 void InputDevice::dump(std::string& dump) {
68     InputDeviceInfo deviceInfo;
69     getDeviceInfo(&deviceInfo);
70 
71     dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
72                          deviceInfo.getDisplayName().c_str());
73     dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
74     dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
75     dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
76     if (mAssociatedDisplayPort) {
77         dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
78     } else {
79         dump += "<none>\n";
80     }
81     dump += StringPrintf(INDENT2 "HasMic:     %s\n", toString(mHasMic));
82     dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
83     dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
84 
85     const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
86     if (!ranges.empty()) {
87         dump += INDENT2 "Motion Ranges:\n";
88         for (size_t i = 0; i < ranges.size(); i++) {
89             const InputDeviceInfo::MotionRange& range = ranges[i];
90             const char* label = getAxisLabel(range.axis);
91             char name[32];
92             if (label) {
93                 strncpy(name, label, sizeof(name));
94                 name[sizeof(name) - 1] = '\0';
95             } else {
96                 snprintf(name, sizeof(name), "%d", range.axis);
97             }
98             dump += StringPrintf(INDENT3
99                                  "%s: source=0x%08x, "
100                                  "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
101                                  name, range.source, range.min, range.max, range.flat, range.fuzz,
102                                  range.resolution);
103         }
104     }
105 
106     size_t numMappers = mMappers.size();
107     for (size_t i = 0; i < numMappers; i++) {
108         InputMapper* mapper = mMappers[i];
109         mapper->dump(dump);
110     }
111 }
112 
addMapper(InputMapper * mapper)113 void InputDevice::addMapper(InputMapper* mapper) {
114     mMappers.push_back(mapper);
115 }
116 
configure(nsecs_t when,const InputReaderConfiguration * config,uint32_t changes)117 void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config,
118                             uint32_t changes) {
119     mSources = 0;
120 
121     if (!isIgnored()) {
122         if (!changes) { // first time only
123             mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
124         }
125 
126         if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
127             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
128                 sp<KeyCharacterMap> keyboardLayout =
129                         mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
130                 if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
131                     bumpGeneration();
132                 }
133             }
134         }
135 
136         if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
137             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
138                 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
139                 if (mAlias != alias) {
140                     mAlias = alias;
141                     bumpGeneration();
142                 }
143             }
144         }
145 
146         if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) {
147             ssize_t index = config->disabledDevices.indexOf(mId);
148             bool enabled = index < 0;
149             setEnabled(enabled, when);
150         }
151 
152         if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
153             // In most situations, no port will be specified.
154             mAssociatedDisplayPort = std::nullopt;
155             // Find the display port that corresponds to the current input port.
156             const std::string& inputPort = mIdentifier.location;
157             if (!inputPort.empty()) {
158                 const std::unordered_map<std::string, uint8_t>& ports = config->portAssociations;
159                 const auto& displayPort = ports.find(inputPort);
160                 if (displayPort != ports.end()) {
161                     mAssociatedDisplayPort = std::make_optional(displayPort->second);
162                 }
163             }
164         }
165 
166         for (InputMapper* mapper : mMappers) {
167             mapper->configure(when, config, changes);
168             mSources |= mapper->getSources();
169         }
170     }
171 }
172 
reset(nsecs_t when)173 void InputDevice::reset(nsecs_t when) {
174     for (InputMapper* mapper : mMappers) {
175         mapper->reset(when);
176     }
177 
178     mContext->updateGlobalMetaState();
179 
180     notifyReset(when);
181 }
182 
process(const RawEvent * rawEvents,size_t count)183 void InputDevice::process(const RawEvent* rawEvents, size_t count) {
184     // Process all of the events in order for each mapper.
185     // We cannot simply ask each mapper to process them in bulk because mappers may
186     // have side-effects that must be interleaved.  For example, joystick movement events and
187     // gamepad button presses are handled by different mappers but they should be dispatched
188     // in the order received.
189     for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
190 #if DEBUG_RAW_EVENTS
191         ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
192               rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when);
193 #endif
194 
195         if (mDropUntilNextSync) {
196             if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
197                 mDropUntilNextSync = false;
198 #if DEBUG_RAW_EVENTS
199                 ALOGD("Recovered from input event buffer overrun.");
200 #endif
201             } else {
202 #if DEBUG_RAW_EVENTS
203                 ALOGD("Dropped input event while waiting for next input sync.");
204 #endif
205             }
206         } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
207             ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
208             mDropUntilNextSync = true;
209             reset(rawEvent->when);
210         } else {
211             for (InputMapper* mapper : mMappers) {
212                 mapper->process(rawEvent);
213             }
214         }
215         --count;
216     }
217 }
218 
timeoutExpired(nsecs_t when)219 void InputDevice::timeoutExpired(nsecs_t when) {
220     for (InputMapper* mapper : mMappers) {
221         mapper->timeoutExpired(when);
222     }
223 }
224 
updateExternalStylusState(const StylusState & state)225 void InputDevice::updateExternalStylusState(const StylusState& state) {
226     for (InputMapper* mapper : mMappers) {
227         mapper->updateExternalStylusState(state);
228     }
229 }
230 
getDeviceInfo(InputDeviceInfo * outDeviceInfo)231 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
232     outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
233                               mHasMic);
234     for (InputMapper* mapper : mMappers) {
235         mapper->populateDeviceInfo(outDeviceInfo);
236     }
237 }
238 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)239 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
240     return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
241 }
242 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)243 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
244     return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
245 }
246 
getSwitchState(uint32_t sourceMask,int32_t switchCode)247 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
248     return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
249 }
250 
getState(uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)251 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
252     int32_t result = AKEY_STATE_UNKNOWN;
253     for (InputMapper* mapper : mMappers) {
254         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
255             // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
256             // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
257             int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
258             if (currentResult >= AKEY_STATE_DOWN) {
259                 return currentResult;
260             } else if (currentResult == AKEY_STATE_UP) {
261                 result = currentResult;
262             }
263         }
264     }
265     return result;
266 }
267 
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)268 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
269                                         const int32_t* keyCodes, uint8_t* outFlags) {
270     bool result = false;
271     for (InputMapper* mapper : mMappers) {
272         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
273             result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
274         }
275     }
276     return result;
277 }
278 
vibrate(const nsecs_t * pattern,size_t patternSize,ssize_t repeat,int32_t token)279 void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
280                           int32_t token) {
281     for (InputMapper* mapper : mMappers) {
282         mapper->vibrate(pattern, patternSize, repeat, token);
283     }
284 }
285 
cancelVibrate(int32_t token)286 void InputDevice::cancelVibrate(int32_t token) {
287     for (InputMapper* mapper : mMappers) {
288         mapper->cancelVibrate(token);
289     }
290 }
291 
cancelTouch(nsecs_t when)292 void InputDevice::cancelTouch(nsecs_t when) {
293     for (InputMapper* mapper : mMappers) {
294         mapper->cancelTouch(when);
295     }
296 }
297 
getMetaState()298 int32_t InputDevice::getMetaState() {
299     int32_t result = 0;
300     for (InputMapper* mapper : mMappers) {
301         result |= mapper->getMetaState();
302     }
303     return result;
304 }
305 
updateMetaState(int32_t keyCode)306 void InputDevice::updateMetaState(int32_t keyCode) {
307     for (InputMapper* mapper : mMappers) {
308         mapper->updateMetaState(keyCode);
309     }
310 }
311 
fadePointer()312 void InputDevice::fadePointer() {
313     for (InputMapper* mapper : mMappers) {
314         mapper->fadePointer();
315     }
316 }
317 
bumpGeneration()318 void InputDevice::bumpGeneration() {
319     mGeneration = mContext->bumpGeneration();
320 }
321 
notifyReset(nsecs_t when)322 void InputDevice::notifyReset(nsecs_t when) {
323     NotifyDeviceResetArgs args(mContext->getNextSequenceNum(), when, mId);
324     mContext->getListener()->notifyDeviceReset(&args);
325 }
326 
getAssociatedDisplay()327 std::optional<int32_t> InputDevice::getAssociatedDisplay() {
328     for (InputMapper* mapper : mMappers) {
329         std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplay();
330         if (associatedDisplayId) {
331             return associatedDisplayId;
332         }
333     }
334 
335     return std::nullopt;
336 }
337 
338 } // namespace android
339