blob: 2023c6e8dadce9c715c90a6bcd28a36f6e2971e7 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 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
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070017#include "Macros.h"
Michael Wright842500e2015-03-13 17:32:02 -070018
Michael Wrightd02c5b62014-02-10 15:10:22 -080019#include "InputReader.h"
20
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070021#include "CursorInputMapper.h"
22#include "ExternalStylusInputMapper.h"
23#include "InputReaderContext.h"
24#include "JoystickInputMapper.h"
25#include "KeyboardInputMapper.h"
26#include "MultiTouchInputMapper.h"
27#include "RotaryEncoderInputMapper.h"
28#include "SingleTouchInputMapper.h"
29#include "SwitchInputMapper.h"
30#include "VibratorInputMapper.h"
31
Mark Salyzyna5e161b2016-09-29 08:08:05 -070032#include <errno.h>
Michael Wright842500e2015-03-13 17:32:02 -070033#include <inttypes.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070034#include <limits.h>
35#include <math.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080036#include <stddef.h>
37#include <stdlib.h>
38#include <unistd.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070039
Mark Salyzyn7823e122016-09-29 08:08:05 -070040#include <log/log.h>
Prabir Pradhan28efc192019-11-05 01:10:04 +000041#include <utils/Errors.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070042
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080043#include <android-base/stringprintf.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070044#include <input/Keyboard.h>
45#include <input/VirtualKeyMap.h>
Prabir Pradhan28efc192019-11-05 01:10:04 +000046#include <utils/Thread.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080047
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080048using android::base::StringPrintf;
49
Michael Wrightd02c5b62014-02-10 15:10:22 -080050namespace android {
51
Prabir Pradhan28efc192019-11-05 01:10:04 +000052// --- InputReader ---
53
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070054InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
55 const sp<InputReaderPolicyInterface>& policy,
56 const sp<InputListenerInterface>& listener)
57 : mContext(this),
58 mEventHub(eventHub),
59 mPolicy(policy),
60 mNextSequenceNum(1),
61 mGlobalMetaState(0),
62 mGeneration(1),
63 mDisableVirtualKeysTimeout(LLONG_MIN),
64 mNextTimeout(LLONG_MAX),
Michael Wrightd02c5b62014-02-10 15:10:22 -080065 mConfigurationChangesToRefresh(0) {
66 mQueuedListener = new QueuedInputListener(listener);
67
68 { // acquire lock
69 AutoMutex _l(mLock);
70
71 refreshConfigurationLocked(0);
72 updateGlobalMetaStateLocked();
73 } // release lock
74}
75
76InputReader::~InputReader() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +000077 for (auto& devicePair : mDevices) {
78 delete devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -080079 }
80}
81
Prabir Pradhan28efc192019-11-05 01:10:04 +000082status_t InputReader::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070083 if (mThread) {
Prabir Pradhan28efc192019-11-05 01:10:04 +000084 return ALREADY_EXISTS;
85 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070086 mThread = std::make_unique<InputThread>(
87 "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
88 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000089}
90
91status_t InputReader::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070092 if (mThread && mThread->isCallingThread()) {
93 ALOGE("InputReader cannot be stopped from its own thread!");
Prabir Pradhan28efc192019-11-05 01:10:04 +000094 return INVALID_OPERATION;
95 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070096 mThread.reset();
97 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000098}
99
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100void InputReader::loopOnce() {
101 int32_t oldGeneration;
102 int32_t timeoutMillis;
103 bool inputDevicesChanged = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800104 std::vector<InputDeviceInfo> inputDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105 { // acquire lock
106 AutoMutex _l(mLock);
107
108 oldGeneration = mGeneration;
109 timeoutMillis = -1;
110
111 uint32_t changes = mConfigurationChangesToRefresh;
112 if (changes) {
113 mConfigurationChangesToRefresh = 0;
114 timeoutMillis = 0;
115 refreshConfigurationLocked(changes);
116 } else if (mNextTimeout != LLONG_MAX) {
117 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
118 timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
119 }
120 } // release lock
121
122 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
123
124 { // acquire lock
125 AutoMutex _l(mLock);
126 mReaderIsAliveCondition.broadcast();
127
128 if (count) {
129 processEventsLocked(mEventBuffer, count);
130 }
131
132 if (mNextTimeout != LLONG_MAX) {
133 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
134 if (now >= mNextTimeout) {
135#if DEBUG_RAW_EVENTS
136 ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
137#endif
138 mNextTimeout = LLONG_MAX;
139 timeoutExpiredLocked(now);
140 }
141 }
142
143 if (oldGeneration != mGeneration) {
144 inputDevicesChanged = true;
145 getInputDevicesLocked(inputDevices);
146 }
147 } // release lock
148
149 // Send out a message that the describes the changed input devices.
150 if (inputDevicesChanged) {
151 mPolicy->notifyInputDevicesChanged(inputDevices);
152 }
153
154 // Flush queued events out to the listener.
155 // This must happen outside of the lock because the listener could potentially call
156 // back into the InputReader's methods, such as getScanCodeState, or become blocked
157 // on another thread similarly waiting to acquire the InputReader lock thereby
158 // resulting in a deadlock. This situation is actually quite plausible because the
159 // listener is actually the input dispatcher, which calls into the window manager,
160 // which occasionally calls into the input reader.
161 mQueuedListener->flush();
162}
163
164void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
165 for (const RawEvent* rawEvent = rawEvents; count;) {
166 int32_t type = rawEvent->type;
167 size_t batchSize = 1;
168 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
169 int32_t deviceId = rawEvent->deviceId;
170 while (batchSize < count) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700171 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
172 rawEvent[batchSize].deviceId != deviceId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800173 break;
174 }
175 batchSize += 1;
176 }
177#if DEBUG_RAW_EVENTS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700178 ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800179#endif
180 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
181 } else {
182 switch (rawEvent->type) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700183 case EventHubInterface::DEVICE_ADDED:
184 addDeviceLocked(rawEvent->when, rawEvent->deviceId);
185 break;
186 case EventHubInterface::DEVICE_REMOVED:
187 removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
188 break;
189 case EventHubInterface::FINISHED_DEVICE_SCAN:
190 handleConfigurationChangedLocked(rawEvent->when);
191 break;
192 default:
193 ALOG_ASSERT(false); // can't happen
194 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195 }
196 }
197 count -= batchSize;
198 rawEvent += batchSize;
199 }
200}
201
202void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000203 if (mDevices.find(deviceId) != mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
205 return;
206 }
207
208 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
209 uint32_t classes = mEventHub->getDeviceClasses(deviceId);
210 int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
211
212 InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
213 device->configure(when, &mConfig, 0);
214 device->reset(when);
215
216 if (device->isIgnored()) {
217 ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700218 identifier.name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700220 ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, identifier.name.c_str(),
221 device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800222 }
223
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000224 mDevices.insert({deviceId, device});
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 bumpGenerationLocked();
Michael Wright842500e2015-03-13 17:32:02 -0700226
227 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
228 notifyExternalStylusPresenceChanged();
229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230}
231
232void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000233 auto deviceIt = mDevices.find(deviceId);
234 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
236 return;
237 }
238
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000239 InputDevice* device = deviceIt->second;
240 mDevices.erase(deviceIt);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241 bumpGenerationLocked();
242
243 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700244 ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)", device->getId(),
245 device->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700247 ALOGI("Device removed: id=%d, name='%s', sources=0x%08x", device->getId(),
248 device->getName().c_str(), device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249 }
250
Michael Wright842500e2015-03-13 17:32:02 -0700251 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
252 notifyExternalStylusPresenceChanged();
253 }
254
Michael Wrightd02c5b62014-02-10 15:10:22 -0800255 device->reset(when);
256 delete device;
257}
258
259InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700260 const InputDeviceIdentifier& identifier,
261 uint32_t classes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700263 controllerNumber, identifier, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800264
265 // External devices.
266 if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
267 device->setExternal(true);
268 }
269
Tim Kilbourn063ff532015-04-08 10:26:18 -0700270 // Devices with mics.
271 if (classes & INPUT_DEVICE_CLASS_MIC) {
272 device->setMic(true);
273 }
274
Michael Wrightd02c5b62014-02-10 15:10:22 -0800275 // Switch-like devices.
276 if (classes & INPUT_DEVICE_CLASS_SWITCH) {
277 device->addMapper(new SwitchInputMapper(device));
278 }
279
Prashant Malani1941ff52015-08-11 18:29:28 -0700280 // Scroll wheel-like devices.
281 if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
282 device->addMapper(new RotaryEncoderInputMapper(device));
283 }
284
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 // Vibrator-like devices.
286 if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
287 device->addMapper(new VibratorInputMapper(device));
288 }
289
290 // Keyboard-like devices.
291 uint32_t keyboardSource = 0;
292 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
293 if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
294 keyboardSource |= AINPUT_SOURCE_KEYBOARD;
295 }
296 if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
297 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
298 }
299 if (classes & INPUT_DEVICE_CLASS_DPAD) {
300 keyboardSource |= AINPUT_SOURCE_DPAD;
301 }
302 if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
303 keyboardSource |= AINPUT_SOURCE_GAMEPAD;
304 }
305
306 if (keyboardSource != 0) {
307 device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
308 }
309
310 // Cursor-like devices.
311 if (classes & INPUT_DEVICE_CLASS_CURSOR) {
312 device->addMapper(new CursorInputMapper(device));
313 }
314
315 // Touchscreens and touchpad devices.
316 if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
317 device->addMapper(new MultiTouchInputMapper(device));
318 } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
319 device->addMapper(new SingleTouchInputMapper(device));
320 }
321
322 // Joystick-like devices.
323 if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
324 device->addMapper(new JoystickInputMapper(device));
325 }
326
Michael Wright842500e2015-03-13 17:32:02 -0700327 // External stylus-like devices.
328 if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
329 device->addMapper(new ExternalStylusInputMapper(device));
330 }
331
Michael Wrightd02c5b62014-02-10 15:10:22 -0800332 return device;
333}
334
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700335void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents,
336 size_t count) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000337 auto deviceIt = mDevices.find(deviceId);
338 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800339 ALOGW("Discarding event for unknown deviceId %d.", deviceId);
340 return;
341 }
342
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000343 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800344 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700345 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346 return;
347 }
348
349 device->process(rawEvents, count);
350}
351
352void InputReader::timeoutExpiredLocked(nsecs_t when) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000353 for (auto& devicePair : mDevices) {
354 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800355 if (!device->isIgnored()) {
356 device->timeoutExpired(when);
357 }
358 }
359}
360
361void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
362 // Reset global meta state because it depends on the list of all configured devices.
363 updateGlobalMetaStateLocked();
364
365 // Enqueue configuration changed.
Prabir Pradhan42611e02018-11-27 14:04:02 -0800366 NotifyConfigurationChangedArgs args(mContext.getNextSequenceNum(), when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800367 mQueuedListener->notifyConfigurationChanged(&args);
368}
369
370void InputReader::refreshConfigurationLocked(uint32_t changes) {
371 mPolicy->getReaderConfiguration(&mConfig);
372 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
373
374 if (changes) {
Siarhei Vishniakouc5ae0dc2019-07-10 15:51:18 -0700375 ALOGI("Reconfiguring input devices, changes=%s",
376 InputReaderConfiguration::changesToString(changes).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800377 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
378
379 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
380 mEventHub->requestReopenDevices();
381 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000382 for (auto& devicePair : mDevices) {
383 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800384 device->configure(now, &mConfig, changes);
385 }
386 }
387 }
388}
389
390void InputReader::updateGlobalMetaStateLocked() {
391 mGlobalMetaState = 0;
392
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000393 for (auto& devicePair : mDevices) {
394 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800395 mGlobalMetaState |= device->getMetaState();
396 }
397}
398
399int32_t InputReader::getGlobalMetaStateLocked() {
400 return mGlobalMetaState;
401}
402
Michael Wright842500e2015-03-13 17:32:02 -0700403void InputReader::notifyExternalStylusPresenceChanged() {
404 refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
405}
406
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800407void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000408 for (auto& devicePair : mDevices) {
409 InputDevice* device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700410 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800411 InputDeviceInfo info;
412 device->getDeviceInfo(&info);
413 outDevices.push_back(info);
Michael Wright842500e2015-03-13 17:32:02 -0700414 }
415 }
416}
417
418void InputReader::dispatchExternalStylusState(const StylusState& state) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000419 for (auto& devicePair : mDevices) {
420 InputDevice* device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700421 device->updateExternalStylusState(state);
422 }
423}
424
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
426 mDisableVirtualKeysTimeout = time;
427}
428
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700429bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
430 int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800431 if (now < mDisableVirtualKeysTimeout) {
432 ALOGI("Dropping virtual key from device %s because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700433 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
434 device->getName().c_str(), (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode,
435 scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800436 return true;
437 } else {
438 return false;
439 }
440}
441
442void InputReader::fadePointerLocked() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000443 for (auto& devicePair : mDevices) {
444 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445 device->fadePointer();
446 }
447}
448
449void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
450 if (when < mNextTimeout) {
451 mNextTimeout = when;
452 mEventHub->wake();
453 }
454}
455
456int32_t InputReader::bumpGenerationLocked() {
457 return ++mGeneration;
458}
459
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800460void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 AutoMutex _l(mLock);
462 getInputDevicesLocked(outInputDevices);
463}
464
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800465void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800466 outInputDevices.clear();
467
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000468 for (auto& devicePair : mDevices) {
469 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800471 InputDeviceInfo info;
472 device->getDeviceInfo(&info);
473 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800474 }
475 }
476}
477
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700478int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800479 AutoMutex _l(mLock);
480
481 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
482}
483
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700484int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485 AutoMutex _l(mLock);
486
487 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
488}
489
490int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
491 AutoMutex _l(mLock);
492
493 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
494}
495
496int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700497 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800498 int32_t result = AKEY_STATE_UNKNOWN;
499 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000500 auto deviceIt = mDevices.find(deviceId);
501 if (deviceIt != mDevices.end()) {
502 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700503 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800504 result = (device->*getStateFunc)(sourceMask, code);
505 }
506 }
507 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000508 for (auto& devicePair : mDevices) {
509 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700510 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800511 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
512 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
513 int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
514 if (currentResult >= AKEY_STATE_DOWN) {
515 return currentResult;
516 } else if (currentResult == AKEY_STATE_UP) {
517 result = currentResult;
518 }
519 }
520 }
521 }
522 return result;
523}
524
Andrii Kulian763a3a42016-03-08 10:46:16 -0800525void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000526 auto deviceIt = mDevices.find(deviceId);
527 if (deviceIt == mDevices.end()) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800528 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
529 return;
530 }
531
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000532 InputDevice* device = deviceIt->second;
Andrii Kulian763a3a42016-03-08 10:46:16 -0800533 if (device->isIgnored()) {
534 return;
535 }
536
537 device->updateMetaState(AKEYCODE_CAPS_LOCK);
538}
539
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700540bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
541 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800542 AutoMutex _l(mLock);
543
544 memset(outFlags, 0, numCodes);
545 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
546}
547
548bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700549 size_t numCodes, const int32_t* keyCodes,
550 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800551 bool result = false;
552 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000553 auto deviceIt = mDevices.find(deviceId);
554 if (deviceIt != mDevices.end()) {
555 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700556 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
557 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800558 }
559 }
560 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000561 for (auto& devicePair : mDevices) {
562 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700563 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
564 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800565 }
566 }
567 }
568 return result;
569}
570
571void InputReader::requestRefreshConfiguration(uint32_t changes) {
572 AutoMutex _l(mLock);
573
574 if (changes) {
575 bool needWake = !mConfigurationChangesToRefresh;
576 mConfigurationChangesToRefresh |= changes;
577
578 if (needWake) {
579 mEventHub->wake();
580 }
581 }
582}
583
584void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700585 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586 AutoMutex _l(mLock);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000587 auto deviceIt = mDevices.find(deviceId);
588 if (deviceIt != mDevices.end()) {
589 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800590 device->vibrate(pattern, patternSize, repeat, token);
591 }
592}
593
594void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
595 AutoMutex _l(mLock);
596
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000597 auto deviceIt = mDevices.find(deviceId);
598 if (deviceIt != mDevices.end()) {
599 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600 device->cancelVibrate(token);
601 }
602}
603
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700604bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
605 AutoMutex _l(mLock);
606
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000607 auto deviceIt = mDevices.find(deviceId);
608 if (deviceIt != mDevices.end()) {
609 InputDevice* device = deviceIt->second;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700610 return device->isEnabled();
611 }
612 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
613 return false;
614}
615
Arthur Hungc23540e2018-11-29 20:42:11 +0800616bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
617 AutoMutex _l(mLock);
618
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000619 auto deviceIt = mDevices.find(deviceId);
620 if (deviceIt == mDevices.end()) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800621 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
622 return false;
623 }
624
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000625 InputDevice* device = deviceIt->second;
Arthur Hung2c9a3342019-07-23 14:18:59 +0800626 if (!device->isEnabled()) {
627 ALOGW("Ignoring disabled device %s", device->getName().c_str());
628 return false;
629 }
630
631 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800632 // No associated display. By default, can dispatch to all displays.
633 if (!associatedDisplayId) {
634 return true;
635 }
636
637 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800638 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800639 return true;
640 }
641
642 return *associatedDisplayId == displayId;
643}
644
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800645void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800646 AutoMutex _l(mLock);
647
648 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800649 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800650
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800651 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000653 for (const auto& devicePair : mDevices) {
654 InputDevice* const device = devicePair.second;
655 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800656 }
657
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800658 dump += INDENT "Configuration:\n";
659 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800660 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
661 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800662 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800663 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100664 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800666 dump += "]\n";
667 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700668 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800669
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800670 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700671 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
672 "acceleration=%0.3f\n",
673 mConfig.pointerVelocityControlParameters.scale,
674 mConfig.pointerVelocityControlParameters.lowThreshold,
675 mConfig.pointerVelocityControlParameters.highThreshold,
676 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800677
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800678 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700679 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
680 "acceleration=%0.3f\n",
681 mConfig.wheelVelocityControlParameters.scale,
682 mConfig.wheelVelocityControlParameters.lowThreshold,
683 mConfig.wheelVelocityControlParameters.highThreshold,
684 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800686 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700687 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800688 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700689 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800690 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700691 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800692 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700693 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800694 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700695 mConfig.pointerGestureTapDragInterval * 0.000001f);
696 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800697 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700698 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800699 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700700 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800701 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700702 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800703 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700704 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800705 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700706 mConfig.pointerGestureMovementSpeedRatio);
707 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700708
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800709 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700710 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711}
712
713void InputReader::monitor() {
714 // Acquire and release the lock to ensure that the reader has not deadlocked.
715 mLock.lock();
716 mEventHub->wake();
717 mReaderIsAliveCondition.wait(mLock);
718 mLock.unlock();
719
720 // Check the EventHub
721 mEventHub->monitor();
722}
723
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724// --- InputReader::ContextImpl ---
725
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700726InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800727
728void InputReader::ContextImpl::updateGlobalMetaState() {
729 // lock is already held by the input loop
730 mReader->updateGlobalMetaStateLocked();
731}
732
733int32_t InputReader::ContextImpl::getGlobalMetaState() {
734 // lock is already held by the input loop
735 return mReader->getGlobalMetaStateLocked();
736}
737
738void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
739 // lock is already held by the input loop
740 mReader->disableVirtualKeysUntilLocked(time);
741}
742
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700743bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, InputDevice* device,
744 int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800745 // lock is already held by the input loop
746 return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
747}
748
749void InputReader::ContextImpl::fadePointer() {
750 // lock is already held by the input loop
751 mReader->fadePointerLocked();
752}
753
754void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
755 // lock is already held by the input loop
756 mReader->requestTimeoutAtTimeLocked(when);
757}
758
759int32_t InputReader::ContextImpl::bumpGeneration() {
760 // lock is already held by the input loop
761 return mReader->bumpGenerationLocked();
762}
763
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800764void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
Michael Wright842500e2015-03-13 17:32:02 -0700765 // lock is already held by whatever called refreshConfigurationLocked
766 mReader->getExternalStylusDevicesLocked(outDevices);
767}
768
769void InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
770 mReader->dispatchExternalStylusState(state);
771}
772
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
774 return mReader->mPolicy.get();
775}
776
777InputListenerInterface* InputReader::ContextImpl::getListener() {
778 return mReader->mQueuedListener.get();
779}
780
781EventHubInterface* InputReader::ContextImpl::getEventHub() {
782 return mReader->mEventHub.get();
783}
784
Prabir Pradhan42611e02018-11-27 14:04:02 -0800785uint32_t InputReader::ContextImpl::getNextSequenceNum() {
786 return (mReader->mNextSequenceNum)++;
787}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789} // namespace android