blob: 2998cc9619ae6a58d37b9f5bf85570db51a0546c [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
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080021#include <android-base/stringprintf.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070022#include <errno.h>
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080023#include <input/Keyboard.h>
24#include <input/VirtualKeyMap.h>
Michael Wright842500e2015-03-13 17:32:02 -070025#include <inttypes.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070026#include <limits.h>
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080027#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070028#include <math.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080029#include <stddef.h>
30#include <stdlib.h>
31#include <unistd.h>
Prabir Pradhan28efc192019-11-05 01:10:04 +000032#include <utils/Errors.h>
Prabir Pradhan28efc192019-11-05 01:10:04 +000033#include <utils/Thread.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080034
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -080035#include "InputDevice.h"
36
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080037using android::base::StringPrintf;
38
Michael Wrightd02c5b62014-02-10 15:10:22 -080039namespace android {
40
Prabir Pradhan28efc192019-11-05 01:10:04 +000041// --- InputReader ---
42
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070043InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
44 const sp<InputReaderPolicyInterface>& policy,
45 const sp<InputListenerInterface>& listener)
46 : mContext(this),
47 mEventHub(eventHub),
48 mPolicy(policy),
Garfield Tan6a5a14e2020-01-28 13:24:04 -080049 mNextId(1),
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070050 mGlobalMetaState(0),
51 mGeneration(1),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080052 mNextInputDeviceId(END_RESERVED_ID),
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070053 mDisableVirtualKeysTimeout(LLONG_MIN),
54 mNextTimeout(LLONG_MAX),
Michael Wrightd02c5b62014-02-10 15:10:22 -080055 mConfigurationChangesToRefresh(0) {
56 mQueuedListener = new QueuedInputListener(listener);
57
58 { // acquire lock
59 AutoMutex _l(mLock);
60
61 refreshConfigurationLocked(0);
62 updateGlobalMetaStateLocked();
63 } // release lock
64}
65
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +000066InputReader::~InputReader() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -080067
Prabir Pradhan28efc192019-11-05 01:10:04 +000068status_t InputReader::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070069 if (mThread) {
Prabir Pradhan28efc192019-11-05 01:10:04 +000070 return ALREADY_EXISTS;
71 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070072 mThread = std::make_unique<InputThread>(
73 "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
74 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000075}
76
77status_t InputReader::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070078 if (mThread && mThread->isCallingThread()) {
79 ALOGE("InputReader cannot be stopped from its own thread!");
Prabir Pradhan28efc192019-11-05 01:10:04 +000080 return INVALID_OPERATION;
81 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070082 mThread.reset();
83 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000084}
85
Michael Wrightd02c5b62014-02-10 15:10:22 -080086void InputReader::loopOnce() {
87 int32_t oldGeneration;
88 int32_t timeoutMillis;
89 bool inputDevicesChanged = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +080090 std::vector<InputDeviceInfo> inputDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -080091 { // acquire lock
92 AutoMutex _l(mLock);
93
94 oldGeneration = mGeneration;
95 timeoutMillis = -1;
96
97 uint32_t changes = mConfigurationChangesToRefresh;
98 if (changes) {
99 mConfigurationChangesToRefresh = 0;
100 timeoutMillis = 0;
101 refreshConfigurationLocked(changes);
102 } else if (mNextTimeout != LLONG_MAX) {
103 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
104 timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
105 }
106 } // release lock
107
108 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
109
110 { // acquire lock
111 AutoMutex _l(mLock);
112 mReaderIsAliveCondition.broadcast();
113
114 if (count) {
115 processEventsLocked(mEventBuffer, count);
116 }
117
118 if (mNextTimeout != LLONG_MAX) {
119 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
120 if (now >= mNextTimeout) {
121#if DEBUG_RAW_EVENTS
122 ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
123#endif
124 mNextTimeout = LLONG_MAX;
125 timeoutExpiredLocked(now);
126 }
127 }
128
129 if (oldGeneration != mGeneration) {
130 inputDevicesChanged = true;
131 getInputDevicesLocked(inputDevices);
132 }
133 } // release lock
134
135 // Send out a message that the describes the changed input devices.
136 if (inputDevicesChanged) {
137 mPolicy->notifyInputDevicesChanged(inputDevices);
138 }
139
140 // Flush queued events out to the listener.
141 // This must happen outside of the lock because the listener could potentially call
142 // back into the InputReader's methods, such as getScanCodeState, or become blocked
143 // on another thread similarly waiting to acquire the InputReader lock thereby
144 // resulting in a deadlock. This situation is actually quite plausible because the
145 // listener is actually the input dispatcher, which calls into the window manager,
146 // which occasionally calls into the input reader.
147 mQueuedListener->flush();
148}
149
150void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
151 for (const RawEvent* rawEvent = rawEvents; count;) {
152 int32_t type = rawEvent->type;
153 size_t batchSize = 1;
154 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
155 int32_t deviceId = rawEvent->deviceId;
156 while (batchSize < count) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700157 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
158 rawEvent[batchSize].deviceId != deviceId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800159 break;
160 }
161 batchSize += 1;
162 }
163#if DEBUG_RAW_EVENTS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700164 ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165#endif
166 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
167 } else {
168 switch (rawEvent->type) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700169 case EventHubInterface::DEVICE_ADDED:
170 addDeviceLocked(rawEvent->when, rawEvent->deviceId);
171 break;
172 case EventHubInterface::DEVICE_REMOVED:
173 removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
174 break;
175 case EventHubInterface::FINISHED_DEVICE_SCAN:
176 handleConfigurationChangedLocked(rawEvent->when);
177 break;
178 default:
179 ALOG_ASSERT(false); // can't happen
180 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 }
182 }
183 count -= batchSize;
184 rawEvent += batchSize;
185 }
186}
187
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800188void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
189 if (mDevices.find(eventHubId) != mDevices.end()) {
190 ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return;
192 }
193
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800194 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
195 std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 device->configure(when, &mConfig, 0);
197 device->reset(when);
198
199 if (device->isIgnored()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800200 ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
201 "(ignored non-input device)",
202 device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800204 ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=0x%08x",
205 device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700206 device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800207 }
208
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800209 mDevices.emplace(eventHubId, device);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800210 bumpGenerationLocked();
Michael Wright842500e2015-03-13 17:32:02 -0700211
212 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
213 notifyExternalStylusPresenceChanged();
214 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215}
216
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800217void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) {
218 auto deviceIt = mDevices.find(eventHubId);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000219 if (deviceIt == mDevices.end()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800220 ALOGW("Ignoring spurious device removed event for eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 return;
222 }
223
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000224 std::shared_ptr<InputDevice> device = std::move(deviceIt->second);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000225 mDevices.erase(deviceIt);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 bumpGenerationLocked();
227
228 if (device->isIgnored()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800229 ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
230 "(ignored non-input device)",
231 device->getId(), eventHubId, device->getName().c_str(),
232 device->getDescriptor().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800234 ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s', sources=0x%08x",
235 device->getId(), eventHubId, device->getName().c_str(),
236 device->getDescriptor().c_str(), device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 }
238
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800239 device->removeEventHubDevice(eventHubId);
240
Michael Wright842500e2015-03-13 17:32:02 -0700241 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
242 notifyExternalStylusPresenceChanged();
243 }
244
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800245 if (device->hasEventHubDevices()) {
246 device->configure(when, &mConfig, 0);
247 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 device->reset(when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249}
250
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000251std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800252 int32_t eventHubId, const InputDeviceIdentifier& identifier) {
253 auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
254 return devicePair.second->getDescriptor().size() && identifier.descriptor.size() &&
255 devicePair.second->getDescriptor() == identifier.descriptor;
256 });
257
258 std::shared_ptr<InputDevice> device;
259 if (deviceIt != mDevices.end()) {
260 device = deviceIt->second;
261 } else {
262 int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
263 device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
264 identifier);
265 }
266 device->addEventHubDevice(eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 return device;
268}
269
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800270void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700271 size_t count) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800272 auto deviceIt = mDevices.find(eventHubId);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000273 if (deviceIt == mDevices.end()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800274 ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800275 return;
276 }
277
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000278 std::shared_ptr<InputDevice>& device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800279 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700280 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281 return;
282 }
283
284 device->process(rawEvents, count);
285}
286
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800287InputDevice* InputReader::findInputDevice(int32_t deviceId) {
288 auto deviceIt =
289 std::find_if(mDevices.begin(), mDevices.end(), [deviceId](const auto& devicePair) {
290 return devicePair.second->getId() == deviceId;
291 });
292 if (deviceIt != mDevices.end()) {
293 return deviceIt->second.get();
294 }
295 return nullptr;
296}
297
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298void InputReader::timeoutExpiredLocked(nsecs_t when) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000299 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000300 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800301 if (!device->isIgnored()) {
302 device->timeoutExpired(when);
303 }
304 }
305}
306
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800307int32_t InputReader::nextInputDeviceIdLocked() {
308 return ++mNextInputDeviceId;
309}
310
Michael Wrightd02c5b62014-02-10 15:10:22 -0800311void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
312 // Reset global meta state because it depends on the list of all configured devices.
313 updateGlobalMetaStateLocked();
314
315 // Enqueue configuration changed.
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800316 NotifyConfigurationChangedArgs args(mContext.getNextId(), when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800317 mQueuedListener->notifyConfigurationChanged(&args);
318}
319
320void InputReader::refreshConfigurationLocked(uint32_t changes) {
321 mPolicy->getReaderConfiguration(&mConfig);
322 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
323
324 if (changes) {
Siarhei Vishniakouc5ae0dc2019-07-10 15:51:18 -0700325 ALOGI("Reconfiguring input devices, changes=%s",
326 InputReaderConfiguration::changesToString(changes).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800327 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
328
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800329 if (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO) {
330 updatePointerDisplayLocked();
331 }
332
Michael Wrightd02c5b62014-02-10 15:10:22 -0800333 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
334 mEventHub->requestReopenDevices();
335 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000336 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000337 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800338 device->configure(now, &mConfig, changes);
339 }
340 }
341 }
342}
343
344void InputReader::updateGlobalMetaStateLocked() {
345 mGlobalMetaState = 0;
346
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000347 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000348 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800349 mGlobalMetaState |= device->getMetaState();
350 }
351}
352
353int32_t InputReader::getGlobalMetaStateLocked() {
354 return mGlobalMetaState;
355}
356
Michael Wright842500e2015-03-13 17:32:02 -0700357void InputReader::notifyExternalStylusPresenceChanged() {
358 refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
359}
360
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800361void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000362 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000363 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700364 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800365 InputDeviceInfo info;
366 device->getDeviceInfo(&info);
367 outDevices.push_back(info);
Michael Wright842500e2015-03-13 17:32:02 -0700368 }
369 }
370}
371
372void InputReader::dispatchExternalStylusState(const StylusState& state) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000373 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000374 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700375 device->updateExternalStylusState(state);
376 }
377}
378
Michael Wrightd02c5b62014-02-10 15:10:22 -0800379void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
380 mDisableVirtualKeysTimeout = time;
381}
382
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800383bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800384 if (now < mDisableVirtualKeysTimeout) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800385 ALOGI("Dropping virtual key from device because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700386 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800387 (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800388 return true;
389 } else {
390 return false;
391 }
392}
393
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800394sp<PointerControllerInterface> InputReader::getPointerControllerLocked(int32_t deviceId) {
395 sp<PointerControllerInterface> controller = mPointerController.promote();
396 if (controller == nullptr) {
397 controller = mPolicy->obtainPointerController(deviceId);
398 mPointerController = controller;
399 updatePointerDisplayLocked();
400 }
401 return controller;
402}
403
404void InputReader::updatePointerDisplayLocked() {
405 sp<PointerControllerInterface> controller = mPointerController.promote();
406 if (controller == nullptr) {
407 return;
408 }
409
410 std::optional<DisplayViewport> viewport =
411 mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId);
412 if (!viewport) {
413 ALOGW("Can't find the designated viewport with ID %" PRId32 " to update cursor input "
414 "mapper. Fall back to default display",
415 mConfig.defaultPointerDisplayId);
416 viewport = mConfig.getDisplayViewportById(ADISPLAY_ID_DEFAULT);
417 }
418 if (!viewport) {
419 ALOGE("Still can't find a viable viewport to update cursor input mapper. Skip setting it to"
420 " PointerController.");
421 return;
422 }
423
424 controller->setDisplayViewport(*viewport);
425}
426
Michael Wrightd02c5b62014-02-10 15:10:22 -0800427void InputReader::fadePointerLocked() {
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800428 sp<PointerControllerInterface> controller = mPointerController.promote();
429 if (controller != nullptr) {
430 controller->fade(PointerControllerInterface::TRANSITION_GRADUAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800431 }
432}
433
434void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
435 if (when < mNextTimeout) {
436 mNextTimeout = when;
437 mEventHub->wake();
438 }
439}
440
441int32_t InputReader::bumpGenerationLocked() {
442 return ++mGeneration;
443}
444
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800445void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800446 AutoMutex _l(mLock);
447 getInputDevicesLocked(outInputDevices);
448}
449
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800450void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800451 outInputDevices.clear();
452
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000453 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000454 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800455 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800456 InputDeviceInfo info;
457 device->getDeviceInfo(&info);
458 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 }
460 }
461}
462
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700463int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464 AutoMutex _l(mLock);
465
466 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
467}
468
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700469int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470 AutoMutex _l(mLock);
471
472 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
473}
474
475int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
476 AutoMutex _l(mLock);
477
478 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
479}
480
481int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700482 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800483 int32_t result = AKEY_STATE_UNKNOWN;
484 if (deviceId >= 0) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800485 InputDevice* device = findInputDevice(deviceId);
486 if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
487 result = (device->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800488 }
489 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000490 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000491 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700492 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800493 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
494 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000495 int32_t currentResult = (device.get()->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496 if (currentResult >= AKEY_STATE_DOWN) {
497 return currentResult;
498 } else if (currentResult == AKEY_STATE_UP) {
499 result = currentResult;
500 }
501 }
502 }
503 }
504 return result;
505}
506
Andrii Kulian763a3a42016-03-08 10:46:16 -0800507void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800508 InputDevice* device = findInputDevice(deviceId);
509 if (!device) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800510 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
511 return;
512 }
513
Andrii Kulian763a3a42016-03-08 10:46:16 -0800514 if (device->isIgnored()) {
515 return;
516 }
517
518 device->updateMetaState(AKEYCODE_CAPS_LOCK);
519}
520
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700521bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
522 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800523 AutoMutex _l(mLock);
524
525 memset(outFlags, 0, numCodes);
526 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
527}
528
529bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700530 size_t numCodes, const int32_t* keyCodes,
531 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800532 bool result = false;
533 if (deviceId >= 0) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800534 InputDevice* device = findInputDevice(deviceId);
535 if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
536 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800537 }
538 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000539 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000540 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700541 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
542 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800543 }
544 }
545 }
546 return result;
547}
548
549void InputReader::requestRefreshConfiguration(uint32_t changes) {
550 AutoMutex _l(mLock);
551
552 if (changes) {
553 bool needWake = !mConfigurationChangesToRefresh;
554 mConfigurationChangesToRefresh |= changes;
555
556 if (needWake) {
557 mEventHub->wake();
558 }
559 }
560}
561
562void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700563 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800564 AutoMutex _l(mLock);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800565 InputDevice* device = findInputDevice(deviceId);
566 if (device) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800567 device->vibrate(pattern, patternSize, repeat, token);
568 }
569}
570
571void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
572 AutoMutex _l(mLock);
573
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800574 InputDevice* device = findInputDevice(deviceId);
575 if (device) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800576 device->cancelVibrate(token);
577 }
578}
579
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700580bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
581 AutoMutex _l(mLock);
582
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800583 InputDevice* device = findInputDevice(deviceId);
584 if (device) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700585 return device->isEnabled();
586 }
587 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
588 return false;
589}
590
Arthur Hungc23540e2018-11-29 20:42:11 +0800591bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
592 AutoMutex _l(mLock);
593
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800594 InputDevice* device = findInputDevice(deviceId);
595 if (!device) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800596 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
597 return false;
598 }
599
Arthur Hung2c9a3342019-07-23 14:18:59 +0800600 if (!device->isEnabled()) {
601 ALOGW("Ignoring disabled device %s", device->getName().c_str());
602 return false;
603 }
604
605 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800606 // No associated display. By default, can dispatch to all displays.
607 if (!associatedDisplayId) {
608 return true;
609 }
610
611 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800612 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800613 return true;
614 }
615
616 return *associatedDisplayId == displayId;
617}
618
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800619void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800620 AutoMutex _l(mLock);
621
622 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800623 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800625 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800626
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000627 for (const auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000628 const std::shared_ptr<InputDevice>& device = devicePair.second;
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000629 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800630 }
631
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800632 dump += INDENT "Configuration:\n";
633 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
635 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800636 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100638 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800639 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800640 dump += "]\n";
641 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700642 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800644 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700645 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
646 "acceleration=%0.3f\n",
647 mConfig.pointerVelocityControlParameters.scale,
648 mConfig.pointerVelocityControlParameters.lowThreshold,
649 mConfig.pointerVelocityControlParameters.highThreshold,
650 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800652 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700653 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
654 "acceleration=%0.3f\n",
655 mConfig.wheelVelocityControlParameters.scale,
656 mConfig.wheelVelocityControlParameters.lowThreshold,
657 mConfig.wheelVelocityControlParameters.highThreshold,
658 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800659
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800660 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700661 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800662 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700663 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800664 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700665 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800666 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700667 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800668 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700669 mConfig.pointerGestureTapDragInterval * 0.000001f);
670 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800671 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700672 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800673 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700674 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800675 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700676 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800677 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700678 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800679 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700680 mConfig.pointerGestureMovementSpeedRatio);
681 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700682
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800683 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700684 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685}
686
687void InputReader::monitor() {
688 // Acquire and release the lock to ensure that the reader has not deadlocked.
689 mLock.lock();
690 mEventHub->wake();
691 mReaderIsAliveCondition.wait(mLock);
692 mLock.unlock();
693
694 // Check the EventHub
695 mEventHub->monitor();
696}
697
Michael Wrightd02c5b62014-02-10 15:10:22 -0800698// --- InputReader::ContextImpl ---
699
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700700InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800701
702void InputReader::ContextImpl::updateGlobalMetaState() {
703 // lock is already held by the input loop
704 mReader->updateGlobalMetaStateLocked();
705}
706
707int32_t InputReader::ContextImpl::getGlobalMetaState() {
708 // lock is already held by the input loop
709 return mReader->getGlobalMetaStateLocked();
710}
711
712void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
713 // lock is already held by the input loop
714 mReader->disableVirtualKeysUntilLocked(time);
715}
716
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800717bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, int32_t keyCode,
718 int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719 // lock is already held by the input loop
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800720 return mReader->shouldDropVirtualKeyLocked(now, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800721}
722
723void InputReader::ContextImpl::fadePointer() {
724 // lock is already held by the input loop
725 mReader->fadePointerLocked();
726}
727
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800728sp<PointerControllerInterface> InputReader::ContextImpl::getPointerController(int32_t deviceId) {
729 // lock is already held by the input loop
730 return mReader->getPointerControllerLocked(deviceId);
731}
732
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
734 // lock is already held by the input loop
735 mReader->requestTimeoutAtTimeLocked(when);
736}
737
738int32_t InputReader::ContextImpl::bumpGeneration() {
739 // lock is already held by the input loop
740 return mReader->bumpGenerationLocked();
741}
742
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800743void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
Michael Wright842500e2015-03-13 17:32:02 -0700744 // lock is already held by whatever called refreshConfigurationLocked
745 mReader->getExternalStylusDevicesLocked(outDevices);
746}
747
748void InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
749 mReader->dispatchExternalStylusState(state);
750}
751
Michael Wrightd02c5b62014-02-10 15:10:22 -0800752InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
753 return mReader->mPolicy.get();
754}
755
756InputListenerInterface* InputReader::ContextImpl::getListener() {
757 return mReader->mQueuedListener.get();
758}
759
760EventHubInterface* InputReader::ContextImpl::getEventHub() {
761 return mReader->mEventHub.get();
762}
763
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800764int32_t InputReader::ContextImpl::getNextId() {
765 return (mReader->mNextId)++;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800766}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767
Michael Wrightd02c5b62014-02-10 15:10:22 -0800768} // namespace android