blob: 010729a6d306dab0f6368ed367ddac1a0f932968 [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
65InputReader::~InputReader() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +000066 for (auto& devicePair : mDevices) {
67 delete devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -080068 }
69}
70
Prabir Pradhan28efc192019-11-05 01:10:04 +000071status_t InputReader::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070072 if (mThread) {
Prabir Pradhan28efc192019-11-05 01:10:04 +000073 return ALREADY_EXISTS;
74 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070075 mThread = std::make_unique<InputThread>(
76 "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
77 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000078}
79
80status_t InputReader::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070081 if (mThread && mThread->isCallingThread()) {
82 ALOGE("InputReader cannot be stopped from its own thread!");
Prabir Pradhan28efc192019-11-05 01:10:04 +000083 return INVALID_OPERATION;
84 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -070085 mThread.reset();
86 return OK;
Prabir Pradhan28efc192019-11-05 01:10:04 +000087}
88
Michael Wrightd02c5b62014-02-10 15:10:22 -080089void InputReader::loopOnce() {
90 int32_t oldGeneration;
91 int32_t timeoutMillis;
92 bool inputDevicesChanged = false;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +080093 std::vector<InputDeviceInfo> inputDevices;
Michael Wrightd02c5b62014-02-10 15:10:22 -080094 { // acquire lock
95 AutoMutex _l(mLock);
96
97 oldGeneration = mGeneration;
98 timeoutMillis = -1;
99
100 uint32_t changes = mConfigurationChangesToRefresh;
101 if (changes) {
102 mConfigurationChangesToRefresh = 0;
103 timeoutMillis = 0;
104 refreshConfigurationLocked(changes);
105 } else if (mNextTimeout != LLONG_MAX) {
106 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
107 timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
108 }
109 } // release lock
110
111 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
112
113 { // acquire lock
114 AutoMutex _l(mLock);
115 mReaderIsAliveCondition.broadcast();
116
117 if (count) {
118 processEventsLocked(mEventBuffer, count);
119 }
120
121 if (mNextTimeout != LLONG_MAX) {
122 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
123 if (now >= mNextTimeout) {
124#if DEBUG_RAW_EVENTS
125 ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
126#endif
127 mNextTimeout = LLONG_MAX;
128 timeoutExpiredLocked(now);
129 }
130 }
131
132 if (oldGeneration != mGeneration) {
133 inputDevicesChanged = true;
134 getInputDevicesLocked(inputDevices);
135 }
136 } // release lock
137
138 // Send out a message that the describes the changed input devices.
139 if (inputDevicesChanged) {
140 mPolicy->notifyInputDevicesChanged(inputDevices);
141 }
142
143 // Flush queued events out to the listener.
144 // This must happen outside of the lock because the listener could potentially call
145 // back into the InputReader's methods, such as getScanCodeState, or become blocked
146 // on another thread similarly waiting to acquire the InputReader lock thereby
147 // resulting in a deadlock. This situation is actually quite plausible because the
148 // listener is actually the input dispatcher, which calls into the window manager,
149 // which occasionally calls into the input reader.
150 mQueuedListener->flush();
151}
152
153void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
154 for (const RawEvent* rawEvent = rawEvents; count;) {
155 int32_t type = rawEvent->type;
156 size_t batchSize = 1;
157 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
158 int32_t deviceId = rawEvent->deviceId;
159 while (batchSize < count) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700160 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
161 rawEvent[batchSize].deviceId != deviceId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162 break;
163 }
164 batchSize += 1;
165 }
166#if DEBUG_RAW_EVENTS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700167 ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168#endif
169 processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
170 } else {
171 switch (rawEvent->type) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700172 case EventHubInterface::DEVICE_ADDED:
173 addDeviceLocked(rawEvent->when, rawEvent->deviceId);
174 break;
175 case EventHubInterface::DEVICE_REMOVED:
176 removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
177 break;
178 case EventHubInterface::FINISHED_DEVICE_SCAN:
179 handleConfigurationChangedLocked(rawEvent->when);
180 break;
181 default:
182 ALOG_ASSERT(false); // can't happen
183 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 }
185 }
186 count -= batchSize;
187 rawEvent += batchSize;
188 }
189}
190
191void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000192 if (mDevices.find(deviceId) != mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
194 return;
195 }
196
197 InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
198 uint32_t classes = mEventHub->getDeviceClasses(deviceId);
199 int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
200
201 InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
202 device->configure(when, &mConfig, 0);
203 device->reset(when);
204
205 if (device->isIgnored()) {
206 ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700207 identifier.name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700209 ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, identifier.name.c_str(),
210 device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 }
212
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000213 mDevices.insert({deviceId, device});
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 bumpGenerationLocked();
Michael Wright842500e2015-03-13 17:32:02 -0700215
216 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
217 notifyExternalStylusPresenceChanged();
218 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219}
220
221void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000222 auto deviceIt = mDevices.find(deviceId);
223 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
225 return;
226 }
227
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000228 InputDevice* device = deviceIt->second;
229 mDevices.erase(deviceIt);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800230 bumpGenerationLocked();
231
232 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700233 ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)", device->getId(),
234 device->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 } else {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700236 ALOGI("Device removed: id=%d, name='%s', sources=0x%08x", device->getId(),
237 device->getName().c_str(), device->getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 }
239
Michael Wright842500e2015-03-13 17:32:02 -0700240 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
241 notifyExternalStylusPresenceChanged();
242 }
243
Michael Wrightd02c5b62014-02-10 15:10:22 -0800244 device->reset(when);
245 delete device;
246}
247
248InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700249 const InputDeviceIdentifier& identifier,
250 uint32_t classes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700252 controllerNumber, identifier, classes);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800253 device->populateMappers();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 return device;
255}
256
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700257void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents,
258 size_t count) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000259 auto deviceIt = mDevices.find(deviceId);
260 if (deviceIt == mDevices.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261 ALOGW("Discarding event for unknown deviceId %d.", deviceId);
262 return;
263 }
264
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000265 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800266 if (device->isIgnored()) {
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700267 // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268 return;
269 }
270
271 device->process(rawEvents, count);
272}
273
274void InputReader::timeoutExpiredLocked(nsecs_t when) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000275 for (auto& devicePair : mDevices) {
276 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800277 if (!device->isIgnored()) {
278 device->timeoutExpired(when);
279 }
280 }
281}
282
283void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
284 // Reset global meta state because it depends on the list of all configured devices.
285 updateGlobalMetaStateLocked();
286
287 // Enqueue configuration changed.
Prabir Pradhan42611e02018-11-27 14:04:02 -0800288 NotifyConfigurationChangedArgs args(mContext.getNextSequenceNum(), when);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800289 mQueuedListener->notifyConfigurationChanged(&args);
290}
291
292void InputReader::refreshConfigurationLocked(uint32_t changes) {
293 mPolicy->getReaderConfiguration(&mConfig);
294 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
295
296 if (changes) {
Siarhei Vishniakouc5ae0dc2019-07-10 15:51:18 -0700297 ALOGI("Reconfiguring input devices, changes=%s",
298 InputReaderConfiguration::changesToString(changes).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800299 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
300
301 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
302 mEventHub->requestReopenDevices();
303 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000304 for (auto& devicePair : mDevices) {
305 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800306 device->configure(now, &mConfig, changes);
307 }
308 }
309 }
310}
311
312void InputReader::updateGlobalMetaStateLocked() {
313 mGlobalMetaState = 0;
314
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000315 for (auto& devicePair : mDevices) {
316 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800317 mGlobalMetaState |= device->getMetaState();
318 }
319}
320
321int32_t InputReader::getGlobalMetaStateLocked() {
322 return mGlobalMetaState;
323}
324
Michael Wright842500e2015-03-13 17:32:02 -0700325void InputReader::notifyExternalStylusPresenceChanged() {
326 refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
327}
328
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800329void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000330 for (auto& devicePair : mDevices) {
331 InputDevice* device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700332 if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800333 InputDeviceInfo info;
334 device->getDeviceInfo(&info);
335 outDevices.push_back(info);
Michael Wright842500e2015-03-13 17:32:02 -0700336 }
337 }
338}
339
340void InputReader::dispatchExternalStylusState(const StylusState& state) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000341 for (auto& devicePair : mDevices) {
342 InputDevice* device = devicePair.second;
Michael Wright842500e2015-03-13 17:32:02 -0700343 device->updateExternalStylusState(state);
344 }
345}
346
Michael Wrightd02c5b62014-02-10 15:10:22 -0800347void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
348 mDisableVirtualKeysTimeout = time;
349}
350
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700351bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
352 int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353 if (now < mDisableVirtualKeysTimeout) {
354 ALOGI("Dropping virtual key from device %s because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700355 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
356 device->getName().c_str(), (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode,
357 scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800358 return true;
359 } else {
360 return false;
361 }
362}
363
364void InputReader::fadePointerLocked() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000365 for (auto& devicePair : mDevices) {
366 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800367 device->fadePointer();
368 }
369}
370
371void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
372 if (when < mNextTimeout) {
373 mNextTimeout = when;
374 mEventHub->wake();
375 }
376}
377
378int32_t InputReader::bumpGenerationLocked() {
379 return ++mGeneration;
380}
381
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800382void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800383 AutoMutex _l(mLock);
384 getInputDevicesLocked(outInputDevices);
385}
386
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800387void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800388 outInputDevices.clear();
389
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000390 for (auto& devicePair : mDevices) {
391 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800392 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800393 InputDeviceInfo info;
394 device->getDeviceInfo(&info);
395 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800396 }
397 }
398}
399
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700400int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800401 AutoMutex _l(mLock);
402
403 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
404}
405
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700406int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800407 AutoMutex _l(mLock);
408
409 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
410}
411
412int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
413 AutoMutex _l(mLock);
414
415 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
416}
417
418int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700419 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800420 int32_t result = AKEY_STATE_UNKNOWN;
421 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000422 auto deviceIt = mDevices.find(deviceId);
423 if (deviceIt != mDevices.end()) {
424 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700425 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800426 result = (device->*getStateFunc)(sourceMask, code);
427 }
428 }
429 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000430 for (auto& devicePair : mDevices) {
431 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700432 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800433 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
434 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
435 int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
436 if (currentResult >= AKEY_STATE_DOWN) {
437 return currentResult;
438 } else if (currentResult == AKEY_STATE_UP) {
439 result = currentResult;
440 }
441 }
442 }
443 }
444 return result;
445}
446
Andrii Kulian763a3a42016-03-08 10:46:16 -0800447void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000448 auto deviceIt = mDevices.find(deviceId);
449 if (deviceIt == mDevices.end()) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800450 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
451 return;
452 }
453
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000454 InputDevice* device = deviceIt->second;
Andrii Kulian763a3a42016-03-08 10:46:16 -0800455 if (device->isIgnored()) {
456 return;
457 }
458
459 device->updateMetaState(AKEYCODE_CAPS_LOCK);
460}
461
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700462bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
463 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800464 AutoMutex _l(mLock);
465
466 memset(outFlags, 0, numCodes);
467 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
468}
469
470bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700471 size_t numCodes, const int32_t* keyCodes,
472 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800473 bool result = false;
474 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000475 auto deviceIt = mDevices.find(deviceId);
476 if (deviceIt != mDevices.end()) {
477 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700478 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
479 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800480 }
481 }
482 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000483 for (auto& devicePair : mDevices) {
484 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700485 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
486 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800487 }
488 }
489 }
490 return result;
491}
492
493void InputReader::requestRefreshConfiguration(uint32_t changes) {
494 AutoMutex _l(mLock);
495
496 if (changes) {
497 bool needWake = !mConfigurationChangesToRefresh;
498 mConfigurationChangesToRefresh |= changes;
499
500 if (needWake) {
501 mEventHub->wake();
502 }
503 }
504}
505
506void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700507 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800508 AutoMutex _l(mLock);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000509 auto deviceIt = mDevices.find(deviceId);
510 if (deviceIt != mDevices.end()) {
511 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512 device->vibrate(pattern, patternSize, repeat, token);
513 }
514}
515
516void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
517 AutoMutex _l(mLock);
518
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000519 auto deviceIt = mDevices.find(deviceId);
520 if (deviceIt != mDevices.end()) {
521 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800522 device->cancelVibrate(token);
523 }
524}
525
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700526bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
527 AutoMutex _l(mLock);
528
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000529 auto deviceIt = mDevices.find(deviceId);
530 if (deviceIt != mDevices.end()) {
531 InputDevice* device = deviceIt->second;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700532 return device->isEnabled();
533 }
534 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
535 return false;
536}
537
Arthur Hungc23540e2018-11-29 20:42:11 +0800538bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
539 AutoMutex _l(mLock);
540
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000541 auto deviceIt = mDevices.find(deviceId);
542 if (deviceIt == mDevices.end()) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800543 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
544 return false;
545 }
546
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000547 InputDevice* device = deviceIt->second;
Arthur Hung2c9a3342019-07-23 14:18:59 +0800548 if (!device->isEnabled()) {
549 ALOGW("Ignoring disabled device %s", device->getName().c_str());
550 return false;
551 }
552
553 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800554 // No associated display. By default, can dispatch to all displays.
555 if (!associatedDisplayId) {
556 return true;
557 }
558
559 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800560 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800561 return true;
562 }
563
564 return *associatedDisplayId == displayId;
565}
566
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800567void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568 AutoMutex _l(mLock);
569
570 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800571 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800573 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800574
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000575 for (const auto& devicePair : mDevices) {
576 InputDevice* const device = devicePair.second;
577 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578 }
579
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800580 dump += INDENT "Configuration:\n";
581 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
583 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800584 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100586 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800587 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800588 dump += "]\n";
589 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700590 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800591
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800592 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700593 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
594 "acceleration=%0.3f\n",
595 mConfig.pointerVelocityControlParameters.scale,
596 mConfig.pointerVelocityControlParameters.lowThreshold,
597 mConfig.pointerVelocityControlParameters.highThreshold,
598 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800599
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800600 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700601 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
602 "acceleration=%0.3f\n",
603 mConfig.wheelVelocityControlParameters.scale,
604 mConfig.wheelVelocityControlParameters.lowThreshold,
605 mConfig.wheelVelocityControlParameters.highThreshold,
606 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800607
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800608 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700609 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800610 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700611 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800612 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700613 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800614 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700615 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800616 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700617 mConfig.pointerGestureTapDragInterval * 0.000001f);
618 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800619 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700620 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800621 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700622 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800623 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700624 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800625 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700626 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800627 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700628 mConfig.pointerGestureMovementSpeedRatio);
629 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700630
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800631 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700632 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800633}
634
635void InputReader::monitor() {
636 // Acquire and release the lock to ensure that the reader has not deadlocked.
637 mLock.lock();
638 mEventHub->wake();
639 mReaderIsAliveCondition.wait(mLock);
640 mLock.unlock();
641
642 // Check the EventHub
643 mEventHub->monitor();
644}
645
Michael Wrightd02c5b62014-02-10 15:10:22 -0800646// --- InputReader::ContextImpl ---
647
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700648InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800649
650void InputReader::ContextImpl::updateGlobalMetaState() {
651 // lock is already held by the input loop
652 mReader->updateGlobalMetaStateLocked();
653}
654
655int32_t InputReader::ContextImpl::getGlobalMetaState() {
656 // lock is already held by the input loop
657 return mReader->getGlobalMetaStateLocked();
658}
659
660void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
661 // lock is already held by the input loop
662 mReader->disableVirtualKeysUntilLocked(time);
663}
664
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700665bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, InputDevice* device,
666 int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667 // lock is already held by the input loop
668 return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
669}
670
671void InputReader::ContextImpl::fadePointer() {
672 // lock is already held by the input loop
673 mReader->fadePointerLocked();
674}
675
676void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
677 // lock is already held by the input loop
678 mReader->requestTimeoutAtTimeLocked(when);
679}
680
681int32_t InputReader::ContextImpl::bumpGeneration() {
682 // lock is already held by the input loop
683 return mReader->bumpGenerationLocked();
684}
685
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800686void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
Michael Wright842500e2015-03-13 17:32:02 -0700687 // lock is already held by whatever called refreshConfigurationLocked
688 mReader->getExternalStylusDevicesLocked(outDevices);
689}
690
691void InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
692 mReader->dispatchExternalStylusState(state);
693}
694
Michael Wrightd02c5b62014-02-10 15:10:22 -0800695InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
696 return mReader->mPolicy.get();
697}
698
699InputListenerInterface* InputReader::ContextImpl::getListener() {
700 return mReader->mQueuedListener.get();
701}
702
703EventHubInterface* InputReader::ContextImpl::getEventHub() {
704 return mReader->mEventHub.get();
705}
706
Prabir Pradhan42611e02018-11-27 14:04:02 -0800707uint32_t InputReader::ContextImpl::getNextSequenceNum() {
708 return (mReader->mNextSequenceNum)++;
709}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710
Michael Wrightd02c5b62014-02-10 15:10:22 -0800711} // namespace android