blob: 657a13486547aa7cdc326458ce9f0fdeefcef4ed [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),
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070049 mGlobalMetaState(0),
50 mGeneration(1),
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -080051 mNextInputDeviceId(END_RESERVED_ID),
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -070052 mDisableVirtualKeysTimeout(LLONG_MIN),
53 mNextTimeout(LLONG_MAX),
Michael Wrightd02c5b62014-02-10 15:10:22 -080054 mConfigurationChangesToRefresh(0) {
55 mQueuedListener = new QueuedInputListener(listener);
56
57 { // acquire lock
58 AutoMutex _l(mLock);
59
60 refreshConfigurationLocked(0);
61 updateGlobalMetaStateLocked();
62 } // release lock
63}
64
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +000065InputReader::~InputReader() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Prabir Pradhan28efc192019-11-05 01:10:04 +000067status_t InputReader::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070068 if (mThread) {
Prabir Pradhan28efc192019-11-05 01:10:04 +000069 return ALREADY_EXISTS;
70 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070071 mThread = std::make_unique<InputThread>(
72 "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
73 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000074}
75
76status_t InputReader::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070077 if (mThread && mThread->isCallingThread()) {
78 ALOGE("InputReader cannot be stopped from its own thread!");
Prabir Pradhan28efc192019-11-05 01:10:04 +000079 return INVALID_OPERATION;
80 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070081 mThread.reset();
82 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000083}
84
Michael Wrightd02c5b62014-02-10 15:10:22 -080085void InputReader::loopOnce() {
86 int32_t oldGeneration;
87 int32_t timeoutMillis;
88 bool inputDevicesChanged = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +080089 std::vector<InputDeviceInfo> inputDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -080090 { // acquire lock
91 AutoMutex _l(mLock);
92
93 oldGeneration = mGeneration;
94 timeoutMillis = -1;
95
96 uint32_t changes = mConfigurationChangesToRefresh;
97 if (changes) {
98 mConfigurationChangesToRefresh = 0;
99 timeoutMillis = 0;
100 refreshConfigurationLocked(changes);
101 } else if (mNextTimeout != LLONG_MAX) {
102 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
103 timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
104 }
105 } // release lock
106
107 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
108
109 { // acquire lock
110 AutoMutex _l(mLock);
111 mReaderIsAliveCondition.broadcast();
112
113 if (count) {
114 processEventsLocked(mEventBuffer, count);
115 }
116
117 if (mNextTimeout != LLONG_MAX) {
118 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
119 if (now >= mNextTimeout) {
120#if DEBUG_RAW_EVENTS
121 ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
122#endif
123 mNextTimeout = LLONG_MAX;
124 timeoutExpiredLocked(now);
125 }
126 }
127
128 if (oldGeneration != mGeneration) {
129 inputDevicesChanged = true;
130 getInputDevicesLocked(inputDevices);
131 }
132 } // release lock
133
134 // Send out a message that the describes the changed input devices.
135 if (inputDevicesChanged) {
136 mPolicy->notifyInputDevicesChanged(inputDevices);
137 }
138
139 // Flush queued events out to the listener.
140 // This must happen outside of the lock because the listener could potentially call
141 // back into the InputReader's methods, such as getScanCodeState, or become blocked
142 // on another thread similarly waiting to acquire the InputReader lock thereby
143 // resulting in a deadlock. This situation is actually quite plausible because the
144 // listener is actually the input dispatcher, which calls into the window manager,
145 // which occasionally calls into the input reader.
146 mQueuedListener->flush();
147}
148
149void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
150 for (const RawEvent* rawEvent = rawEvents; count;) {
151 int32_t type = rawEvent->type;
152 size_t batchSize = 1;
153 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
154 int32_t deviceId = rawEvent->deviceId;
155 while (batchSize < count) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700156 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
157 rawEvent[batchSize].deviceId != deviceId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158 break;
159 }
160 batchSize += 1;
161 }
162#if DEBUG_RAW_EVENTS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700163 ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164#endif
165 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
166 } else {
167 switch (rawEvent->type) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700168 case EventHubInterface::DEVICE_ADDED:
169 addDeviceLocked(rawEvent->when, rawEvent->deviceId);
170 break;
171 case EventHubInterface::DEVICE_REMOVED:
172 removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
173 break;
174 case EventHubInterface::FINISHED_DEVICE_SCAN:
175 handleConfigurationChangedLocked(rawEvent->when);
176 break;
177 default:
178 ALOG_ASSERT(false); // can't happen
179 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 }
181 }
182 count -= batchSize;
183 rawEvent += batchSize;
184 }
185}
186
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800187void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
188 if (mDevices.find(eventHubId) != mDevices.end()) {
189 ALOGW("Ignoring spurious device added event for eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190 return;
191 }
192
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800193 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
194 std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195 device->configure(when, &mConfig, 0);
196 device->reset(when);
197
198 if (device->isIgnored()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800199 ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
200 "(ignored non-input device)",
201 device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800203 ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=0x%08x",
204 device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700205 device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 }
207
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800208 mDevices.emplace(eventHubId, device);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 bumpGenerationLocked();
Michael Wright842500e2015-03-13 17:32:02 -0700210
211 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
212 notifyExternalStylusPresenceChanged();
213 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214}
215
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800216void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) {
217 auto deviceIt = mDevices.find(eventHubId);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000218 if (deviceIt == mDevices.end()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800219 ALOGW("Ignoring spurious device removed event for eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800220 return;
221 }
222
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000223 std::shared_ptr<InputDevice> device = std::move(deviceIt->second);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000224 mDevices.erase(deviceIt);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800225 bumpGenerationLocked();
226
227 if (device->isIgnored()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800228 ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
229 "(ignored non-input device)",
230 device->getId(), eventHubId, device->getName().c_str(),
231 device->getDescriptor().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 } else {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800233 ALOGI("Device removed: id=%d, eventHubId=%d, name='%s', descriptor='%s', sources=0x%08x",
234 device->getId(), eventHubId, device->getName().c_str(),
235 device->getDescriptor().c_str(), device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 }
237
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800238 device->removeEventHubDevice(eventHubId);
239
Michael Wright842500e2015-03-13 17:32:02 -0700240 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
241 notifyExternalStylusPresenceChanged();
242 }
243
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800244 if (device->hasEventHubDevices()) {
245 device->configure(when, &mConfig, 0);
246 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800247 device->reset(when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248}
249
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000250std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800251 int32_t eventHubId, const InputDeviceIdentifier& identifier) {
252 auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
253 return devicePair.second->getDescriptor().size() && identifier.descriptor.size() &&
254 devicePair.second->getDescriptor() == identifier.descriptor;
255 });
256
257 std::shared_ptr<InputDevice> device;
258 if (deviceIt != mDevices.end()) {
259 device = deviceIt->second;
260 } else {
261 int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
262 device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
263 identifier);
264 }
265 device->addEventHubDevice(eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800266 return device;
267}
268
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800269void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700270 size_t count) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800271 auto deviceIt = mDevices.find(eventHubId);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000272 if (deviceIt == mDevices.end()) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800273 ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800274 return;
275 }
276
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000277 std::shared_ptr<InputDevice>& device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700279 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800280 return;
281 }
282
283 device->process(rawEvents, count);
284}
285
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800286InputDevice* InputReader::findInputDevice(int32_t deviceId) {
287 auto deviceIt =
288 std::find_if(mDevices.begin(), mDevices.end(), [deviceId](const auto& devicePair) {
289 return devicePair.second->getId() == deviceId;
290 });
291 if (deviceIt != mDevices.end()) {
292 return deviceIt->second.get();
293 }
294 return nullptr;
295}
296
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297void InputReader::timeoutExpiredLocked(nsecs_t when) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000298 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000299 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800300 if (!device->isIgnored()) {
301 device->timeoutExpired(when);
302 }
303 }
304}
305
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800306int32_t InputReader::nextInputDeviceIdLocked() {
307 return ++mNextInputDeviceId;
308}
309
Michael Wrightd02c5b62014-02-10 15:10:22 -0800310void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
311 // Reset global meta state because it depends on the list of all configured devices.
312 updateGlobalMetaStateLocked();
313
314 // Enqueue configuration changed.
Garfield Tan6a5a14e2020-01-28 13:24:04 -0800315 NotifyConfigurationChangedArgs args(mContext.getNextId(), when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800316 mQueuedListener->notifyConfigurationChanged(&args);
317}
318
319void InputReader::refreshConfigurationLocked(uint32_t changes) {
320 mPolicy->getReaderConfiguration(&mConfig);
321 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
322
323 if (changes) {
Siarhei Vishniakouc5ae0dc2019-07-10 15:51:18 -0700324 ALOGI("Reconfiguring input devices, changes=%s",
325 InputReaderConfiguration::changesToString(changes).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800326 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
327
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800328 if (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO) {
329 updatePointerDisplayLocked();
330 }
331
Michael Wrightd02c5b62014-02-10 15:10:22 -0800332 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
333 mEventHub->requestReopenDevices();
334 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000335 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000336 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800337 device->configure(now, &mConfig, changes);
338 }
339 }
340 }
341}
342
343void InputReader::updateGlobalMetaStateLocked() {
344 mGlobalMetaState = 0;
345
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000346 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000347 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800348 mGlobalMetaState |= device->getMetaState();
349 }
350}
351
352int32_t InputReader::getGlobalMetaStateLocked() {
353 return mGlobalMetaState;
354}
355
Michael Wright842500e2015-03-13 17:32:02 -0700356void InputReader::notifyExternalStylusPresenceChanged() {
357 refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
358}
359
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800360void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000361 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000362 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700363 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800364 InputDeviceInfo info;
365 device->getDeviceInfo(&info);
366 outDevices.push_back(info);
Michael Wright842500e2015-03-13 17:32:02 -0700367 }
368 }
369}
370
371void InputReader::dispatchExternalStylusState(const StylusState& state) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000372 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000373 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700374 device->updateExternalStylusState(state);
375 }
376}
377
Michael Wrightd02c5b62014-02-10 15:10:22 -0800378void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
379 mDisableVirtualKeysTimeout = time;
380}
381
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800382bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800383 if (now < mDisableVirtualKeysTimeout) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800384 ALOGI("Dropping virtual key from device because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700385 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800386 (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800387 return true;
388 } else {
389 return false;
390 }
391}
392
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800393sp<PointerControllerInterface> InputReader::getPointerControllerLocked(int32_t deviceId) {
394 sp<PointerControllerInterface> controller = mPointerController.promote();
395 if (controller == nullptr) {
396 controller = mPolicy->obtainPointerController(deviceId);
397 mPointerController = controller;
398 updatePointerDisplayLocked();
399 }
400 return controller;
401}
402
403void InputReader::updatePointerDisplayLocked() {
404 sp<PointerControllerInterface> controller = mPointerController.promote();
405 if (controller == nullptr) {
406 return;
407 }
408
409 std::optional<DisplayViewport> viewport =
410 mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId);
411 if (!viewport) {
412 ALOGW("Can't find the designated viewport with ID %" PRId32 " to update cursor input "
413 "mapper. Fall back to default display",
414 mConfig.defaultPointerDisplayId);
415 viewport = mConfig.getDisplayViewportById(ADISPLAY_ID_DEFAULT);
416 }
417 if (!viewport) {
418 ALOGE("Still can't find a viable viewport to update cursor input mapper. Skip setting it to"
419 " PointerController.");
420 return;
421 }
422
423 controller->setDisplayViewport(*viewport);
424}
425
Michael Wrightd02c5b62014-02-10 15:10:22 -0800426void InputReader::fadePointerLocked() {
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -0800427 sp<PointerControllerInterface> controller = mPointerController.promote();
428 if (controller != nullptr) {
429 controller->fade(PointerControllerInterface::TRANSITION_GRADUAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800430 }
431}
432
433void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
434 if (when < mNextTimeout) {
435 mNextTimeout = when;
436 mEventHub->wake();
437 }
438}
439
440int32_t InputReader::bumpGenerationLocked() {
441 return ++mGeneration;
442}
443
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800444void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445 AutoMutex _l(mLock);
446 getInputDevicesLocked(outInputDevices);
447}
448
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800449void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800450 outInputDevices.clear();
451
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000452 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000453 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800454 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800455 InputDeviceInfo info;
456 device->getDeviceInfo(&info);
457 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800458 }
459 }
460}
461
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700462int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800463 AutoMutex _l(mLock);
464
465 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
466}
467
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700468int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800469 AutoMutex _l(mLock);
470
471 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
472}
473
474int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
475 AutoMutex _l(mLock);
476
477 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
478}
479
480int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700481 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800482 int32_t result = AKEY_STATE_UNKNOWN;
483 if (deviceId >= 0) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800484 InputDevice* device = findInputDevice(deviceId);
485 if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
486 result = (device->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800487 }
488 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000489 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000490 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700491 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800492 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
493 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000494 int32_t currentResult = (device.get()->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800495 if (currentResult >= AKEY_STATE_DOWN) {
496 return currentResult;
497 } else if (currentResult == AKEY_STATE_UP) {
498 result = currentResult;
499 }
500 }
501 }
502 }
503 return result;
504}
505
Andrii Kulian763a3a42016-03-08 10:46:16 -0800506void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800507 InputDevice* device = findInputDevice(deviceId);
508 if (!device) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800509 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
510 return;
511 }
512
Andrii Kulian763a3a42016-03-08 10:46:16 -0800513 if (device->isIgnored()) {
514 return;
515 }
516
517 device->updateMetaState(AKEYCODE_CAPS_LOCK);
518}
519
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700520bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
521 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800522 AutoMutex _l(mLock);
523
524 memset(outFlags, 0, numCodes);
525 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
526}
527
528bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700529 size_t numCodes, const int32_t* keyCodes,
530 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800531 bool result = false;
532 if (deviceId >= 0) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800533 InputDevice* device = findInputDevice(deviceId);
534 if (device && !device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
535 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800536 }
537 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000538 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000539 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700540 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
541 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800542 }
543 }
544 }
545 return result;
546}
547
548void InputReader::requestRefreshConfiguration(uint32_t changes) {
549 AutoMutex _l(mLock);
550
551 if (changes) {
552 bool needWake = !mConfigurationChangesToRefresh;
553 mConfigurationChangesToRefresh |= changes;
554
555 if (needWake) {
556 mEventHub->wake();
557 }
558 }
559}
560
561void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700562 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800563 AutoMutex _l(mLock);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800564 InputDevice* device = findInputDevice(deviceId);
565 if (device) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566 device->vibrate(pattern, patternSize, repeat, token);
567 }
568}
569
570void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
571 AutoMutex _l(mLock);
572
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800573 InputDevice* device = findInputDevice(deviceId);
574 if (device) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800575 device->cancelVibrate(token);
576 }
577}
578
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700579bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
580 AutoMutex _l(mLock);
581
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800582 InputDevice* device = findInputDevice(deviceId);
583 if (device) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700584 return device->isEnabled();
585 }
586 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
587 return false;
588}
589
Arthur Hungc23540e2018-11-29 20:42:11 +0800590bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
591 AutoMutex _l(mLock);
592
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800593 InputDevice* device = findInputDevice(deviceId);
594 if (!device) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800595 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
596 return false;
597 }
598
Arthur Hung2c9a3342019-07-23 14:18:59 +0800599 if (!device->isEnabled()) {
600 ALOGW("Ignoring disabled device %s", device->getName().c_str());
601 return false;
602 }
603
604 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800605 // No associated display. By default, can dispatch to all displays.
606 if (!associatedDisplayId) {
607 return true;
608 }
609
610 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800611 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800612 return true;
613 }
614
615 return *associatedDisplayId == displayId;
616}
617
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800618void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800619 AutoMutex _l(mLock);
620
621 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800622 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800623
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800624 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800625
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000626 for (const auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000627 const std::shared_ptr<InputDevice>& device = devicePair.second;
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000628 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800629 }
630
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800631 dump += INDENT "Configuration:\n";
632 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800633 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
634 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800635 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800636 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100637 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800638 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800639 dump += "]\n";
640 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700641 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800642
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800643 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700644 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
645 "acceleration=%0.3f\n",
646 mConfig.pointerVelocityControlParameters.scale,
647 mConfig.pointerVelocityControlParameters.lowThreshold,
648 mConfig.pointerVelocityControlParameters.highThreshold,
649 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800650
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800651 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700652 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
653 "acceleration=%0.3f\n",
654 mConfig.wheelVelocityControlParameters.scale,
655 mConfig.wheelVelocityControlParameters.lowThreshold,
656 mConfig.wheelVelocityControlParameters.highThreshold,
657 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800658
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800659 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700660 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800661 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700662 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800663 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700664 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800665 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700666 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800667 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700668 mConfig.pointerGestureTapDragInterval * 0.000001f);
669 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800670 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700671 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800672 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700673 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800674 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700675 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800676 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700677 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800678 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700679 mConfig.pointerGestureMovementSpeedRatio);
680 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700681
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800682 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700683 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684}
685
686void InputReader::monitor() {
687 // Acquire and release the lock to ensure that the reader has not deadlocked.
688 mLock.lock();
689 mEventHub->wake();
690 mReaderIsAliveCondition.wait(mLock);
691 mLock.unlock();
692
693 // Check the EventHub
694 mEventHub->monitor();
695}
696
Michael Wrightd02c5b62014-02-10 15:10:22 -0800697// --- InputReader::ContextImpl ---
698
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800699InputReader::ContextImpl::ContextImpl(InputReader* reader)
700 : mReader(reader), mIdGenerator(IdGenerator::Source::INPUT_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() {
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800765 return mIdGenerator.nextId();
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