blob: 8327ed8e3058d5e5b1956c751af8a14ba76cb98d [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),
49 mNextSequenceNum(1),
50 mGlobalMetaState(0),
51 mGeneration(1),
52 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
187void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000188 if (mDevices.find(deviceId) != mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
190 return;
191 }
192
193 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
194 uint32_t classes = mEventHub->getDeviceClasses(deviceId);
195 int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
196
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000197 std::shared_ptr<InputDevice> device =
198 createDeviceLocked(deviceId, controllerNumber, identifier, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 device->configure(when, &mConfig, 0);
200 device->reset(when);
201
202 if (device->isIgnored()) {
203 ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700204 identifier.name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700206 ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, identifier.name.c_str(),
207 device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 }
209
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000210 mDevices.emplace(deviceId, device);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 bumpGenerationLocked();
Michael Wright842500e2015-03-13 17:32:02 -0700212
213 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
214 notifyExternalStylusPresenceChanged();
215 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216}
217
218void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000219 auto deviceIt = mDevices.find(deviceId);
220 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
222 return;
223 }
224
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000225 std::shared_ptr<InputDevice> device = std::move(deviceIt->second);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000226 mDevices.erase(deviceIt);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 bumpGenerationLocked();
228
229 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700230 ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)", device->getId(),
231 device->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700233 ALOGI("Device removed: id=%d, name='%s', sources=0x%08x", device->getId(),
234 device->getName().c_str(), device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 }
236
Michael Wright842500e2015-03-13 17:32:02 -0700237 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
238 notifyExternalStylusPresenceChanged();
239 }
240
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241 device->reset(when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242}
243
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000244std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
245 int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier,
246 uint32_t classes) {
247 std::shared_ptr<InputDevice> device =
248 std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700249 controllerNumber, identifier, classes);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800250 device->populateMappers();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 return device;
252}
253
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700254void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents,
255 size_t count) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000256 auto deviceIt = mDevices.find(deviceId);
257 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 ALOGW("Discarding event for unknown deviceId %d.", deviceId);
259 return;
260 }
261
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000262 std::shared_ptr<InputDevice>& device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700264 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 return;
266 }
267
268 device->process(rawEvents, count);
269}
270
271void InputReader::timeoutExpiredLocked(nsecs_t when) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000272 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000273 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800274 if (!device->isIgnored()) {
275 device->timeoutExpired(when);
276 }
277 }
278}
279
280void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
281 // Reset global meta state because it depends on the list of all configured devices.
282 updateGlobalMetaStateLocked();
283
284 // Enqueue configuration changed.
Prabir Pradhan42611e02018-11-27 14:04:02 -0800285 NotifyConfigurationChangedArgs args(mContext.getNextSequenceNum(), when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800286 mQueuedListener->notifyConfigurationChanged(&args);
287}
288
289void InputReader::refreshConfigurationLocked(uint32_t changes) {
290 mPolicy->getReaderConfiguration(&mConfig);
291 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
292
293 if (changes) {
Siarhei Vishniakouc5ae0dc2019-07-10 15:51:18 -0700294 ALOGI("Reconfiguring input devices, changes=%s",
295 InputReaderConfiguration::changesToString(changes).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
297
298 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
299 mEventHub->requestReopenDevices();
300 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000301 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000302 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800303 device->configure(now, &mConfig, changes);
304 }
305 }
306 }
307}
308
309void InputReader::updateGlobalMetaStateLocked() {
310 mGlobalMetaState = 0;
311
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000312 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000313 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800314 mGlobalMetaState |= device->getMetaState();
315 }
316}
317
318int32_t InputReader::getGlobalMetaStateLocked() {
319 return mGlobalMetaState;
320}
321
Michael Wright842500e2015-03-13 17:32:02 -0700322void InputReader::notifyExternalStylusPresenceChanged() {
323 refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
324}
325
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800326void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000327 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000328 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700329 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800330 InputDeviceInfo info;
331 device->getDeviceInfo(&info);
332 outDevices.push_back(info);
Michael Wright842500e2015-03-13 17:32:02 -0700333 }
334 }
335}
336
337void InputReader::dispatchExternalStylusState(const StylusState& state) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000338 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000339 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700340 device->updateExternalStylusState(state);
341 }
342}
343
Michael Wrightd02c5b62014-02-10 15:10:22 -0800344void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
345 mDisableVirtualKeysTimeout = time;
346}
347
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800348bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800349 if (now < mDisableVirtualKeysTimeout) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800350 ALOGI("Dropping virtual key from device because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700351 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800352 (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353 return true;
354 } else {
355 return false;
356 }
357}
358
359void InputReader::fadePointerLocked() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000360 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000361 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800362 device->fadePointer();
363 }
364}
365
366void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
367 if (when < mNextTimeout) {
368 mNextTimeout = when;
369 mEventHub->wake();
370 }
371}
372
373int32_t InputReader::bumpGenerationLocked() {
374 return ++mGeneration;
375}
376
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800377void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800378 AutoMutex _l(mLock);
379 getInputDevicesLocked(outInputDevices);
380}
381
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800382void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800383 outInputDevices.clear();
384
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000385 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000386 std::shared_ptr<InputDevice>& device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800387 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800388 InputDeviceInfo info;
389 device->getDeviceInfo(&info);
390 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800391 }
392 }
393}
394
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700395int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800396 AutoMutex _l(mLock);
397
398 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
399}
400
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700401int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800402 AutoMutex _l(mLock);
403
404 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
405}
406
407int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
408 AutoMutex _l(mLock);
409
410 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
411}
412
413int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700414 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800415 int32_t result = AKEY_STATE_UNKNOWN;
416 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000417 auto deviceIt = mDevices.find(deviceId);
418 if (deviceIt != mDevices.end()) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000419 std::shared_ptr<InputDevice>& device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700420 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000421 result = (device.get()->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800422 }
423 }
424 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000425 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000426 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700427 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800428 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
429 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000430 int32_t currentResult = (device.get()->*getStateFunc)(sourceMask, code);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800431 if (currentResult >= AKEY_STATE_DOWN) {
432 return currentResult;
433 } else if (currentResult == AKEY_STATE_UP) {
434 result = currentResult;
435 }
436 }
437 }
438 }
439 return result;
440}
441
Andrii Kulian763a3a42016-03-08 10:46:16 -0800442void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000443 auto deviceIt = mDevices.find(deviceId);
444 if (deviceIt == mDevices.end()) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800445 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
446 return;
447 }
448
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000449 std::shared_ptr<InputDevice>& device = deviceIt->second;
Andrii Kulian763a3a42016-03-08 10:46:16 -0800450 if (device->isIgnored()) {
451 return;
452 }
453
454 device->updateMetaState(AKEYCODE_CAPS_LOCK);
455}
456
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700457bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
458 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 AutoMutex _l(mLock);
460
461 memset(outFlags, 0, numCodes);
462 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
463}
464
465bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700466 size_t numCodes, const int32_t* keyCodes,
467 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800468 bool result = false;
469 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000470 auto deviceIt = mDevices.find(deviceId);
471 if (deviceIt != mDevices.end()) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000472 std::shared_ptr<InputDevice>& device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700473 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
474 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800475 }
476 }
477 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000478 for (auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000479 std::shared_ptr<InputDevice>& device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700480 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
481 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800482 }
483 }
484 }
485 return result;
486}
487
488void InputReader::requestRefreshConfiguration(uint32_t changes) {
489 AutoMutex _l(mLock);
490
491 if (changes) {
492 bool needWake = !mConfigurationChangesToRefresh;
493 mConfigurationChangesToRefresh |= changes;
494
495 if (needWake) {
496 mEventHub->wake();
497 }
498 }
499}
500
501void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700502 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800503 AutoMutex _l(mLock);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000504 auto deviceIt = mDevices.find(deviceId);
505 if (deviceIt != mDevices.end()) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000506 std::shared_ptr<InputDevice>& device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800507 device->vibrate(pattern, patternSize, repeat, token);
508 }
509}
510
511void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
512 AutoMutex _l(mLock);
513
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000514 auto deviceIt = mDevices.find(deviceId);
515 if (deviceIt != mDevices.end()) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000516 std::shared_ptr<InputDevice>& device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800517 device->cancelVibrate(token);
518 }
519}
520
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700521bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
522 AutoMutex _l(mLock);
523
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000524 auto deviceIt = mDevices.find(deviceId);
525 if (deviceIt != mDevices.end()) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000526 std::shared_ptr<InputDevice>& device = deviceIt->second;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700527 return device->isEnabled();
528 }
529 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
530 return false;
531}
532
Arthur Hungc23540e2018-11-29 20:42:11 +0800533bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
534 AutoMutex _l(mLock);
535
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000536 auto deviceIt = mDevices.find(deviceId);
537 if (deviceIt == mDevices.end()) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800538 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
539 return false;
540 }
541
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000542 std::shared_ptr<InputDevice>& device = deviceIt->second;
Arthur Hung2c9a3342019-07-23 14:18:59 +0800543 if (!device->isEnabled()) {
544 ALOGW("Ignoring disabled device %s", device->getName().c_str());
545 return false;
546 }
547
548 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800549 // No associated display. By default, can dispatch to all displays.
550 if (!associatedDisplayId) {
551 return true;
552 }
553
554 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800555 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800556 return true;
557 }
558
559 return *associatedDisplayId == displayId;
560}
561
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800562void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800563 AutoMutex _l(mLock);
564
565 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800566 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800567
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800568 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800569
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000570 for (const auto& devicePair : mDevices) {
Nathaniel R. Lewis0cab12d2019-11-05 02:17:02 +0000571 const std::shared_ptr<InputDevice>& device = devicePair.second;
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000572 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800573 }
574
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800575 dump += INDENT "Configuration:\n";
576 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800577 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
578 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800579 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100581 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800583 dump += "]\n";
584 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700585 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800587 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700588 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
589 "acceleration=%0.3f\n",
590 mConfig.pointerVelocityControlParameters.scale,
591 mConfig.pointerVelocityControlParameters.lowThreshold,
592 mConfig.pointerVelocityControlParameters.highThreshold,
593 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800594
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800595 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700596 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
597 "acceleration=%0.3f\n",
598 mConfig.wheelVelocityControlParameters.scale,
599 mConfig.wheelVelocityControlParameters.lowThreshold,
600 mConfig.wheelVelocityControlParameters.highThreshold,
601 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800602
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800603 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700604 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800605 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700606 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800607 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700608 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800609 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700610 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800611 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700612 mConfig.pointerGestureTapDragInterval * 0.000001f);
613 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800614 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700615 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800616 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700617 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800618 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700619 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800620 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700621 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800622 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700623 mConfig.pointerGestureMovementSpeedRatio);
624 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700625
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800626 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700627 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800628}
629
630void InputReader::monitor() {
631 // Acquire and release the lock to ensure that the reader has not deadlocked.
632 mLock.lock();
633 mEventHub->wake();
634 mReaderIsAliveCondition.wait(mLock);
635 mLock.unlock();
636
637 // Check the EventHub
638 mEventHub->monitor();
639}
640
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641// --- InputReader::ContextImpl ---
642
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700643InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800644
645void InputReader::ContextImpl::updateGlobalMetaState() {
646 // lock is already held by the input loop
647 mReader->updateGlobalMetaStateLocked();
648}
649
650int32_t InputReader::ContextImpl::getGlobalMetaState() {
651 // lock is already held by the input loop
652 return mReader->getGlobalMetaStateLocked();
653}
654
655void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
656 // lock is already held by the input loop
657 mReader->disableVirtualKeysUntilLocked(time);
658}
659
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800660bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, int32_t keyCode,
661 int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800662 // lock is already held by the input loop
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800663 return mReader->shouldDropVirtualKeyLocked(now, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800664}
665
666void InputReader::ContextImpl::fadePointer() {
667 // lock is already held by the input loop
668 mReader->fadePointerLocked();
669}
670
671void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
672 // lock is already held by the input loop
673 mReader->requestTimeoutAtTimeLocked(when);
674}
675
676int32_t InputReader::ContextImpl::bumpGeneration() {
677 // lock is already held by the input loop
678 return mReader->bumpGenerationLocked();
679}
680
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800681void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
Michael Wright842500e2015-03-13 17:32:02 -0700682 // lock is already held by whatever called refreshConfigurationLocked
683 mReader->getExternalStylusDevicesLocked(outDevices);
684}
685
686void InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
687 mReader->dispatchExternalStylusState(state);
688}
689
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
691 return mReader->mPolicy.get();
692}
693
694InputListenerInterface* InputReader::ContextImpl::getListener() {
695 return mReader->mQueuedListener.get();
696}
697
698EventHubInterface* InputReader::ContextImpl::getEventHub() {
699 return mReader->mEventHub.get();
700}
701
Prabir Pradhan42611e02018-11-27 14:04:02 -0800702uint32_t InputReader::ContextImpl::getNextSequenceNum() {
703 return (mReader->mNextSequenceNum)++;
704}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800705
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706} // namespace android