blob: 3e23fa6c84be2c889c945273ed4f31f957b585d5 [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
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800351bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800352 if (now < mDisableVirtualKeysTimeout) {
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800353 ALOGI("Dropping virtual key from device because virtual keys are "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700354 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800355 (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800356 return true;
357 } else {
358 return false;
359 }
360}
361
362void InputReader::fadePointerLocked() {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000363 for (auto& devicePair : mDevices) {
364 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800365 device->fadePointer();
366 }
367}
368
369void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
370 if (when < mNextTimeout) {
371 mNextTimeout = when;
372 mEventHub->wake();
373 }
374}
375
376int32_t InputReader::bumpGenerationLocked() {
377 return ++mGeneration;
378}
379
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800380void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800381 AutoMutex _l(mLock);
382 getInputDevicesLocked(outInputDevices);
383}
384
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800385void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800386 outInputDevices.clear();
387
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000388 for (auto& devicePair : mDevices) {
389 InputDevice* device = devicePair.second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800390 if (!device->isIgnored()) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800391 InputDeviceInfo info;
392 device->getDeviceInfo(&info);
393 outInputDevices.push_back(info);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800394 }
395 }
396}
397
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700398int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800399 AutoMutex _l(mLock);
400
401 return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
402}
403
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700404int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800405 AutoMutex _l(mLock);
406
407 return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
408}
409
410int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
411 AutoMutex _l(mLock);
412
413 return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
414}
415
416int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700417 GetStateFunc getStateFunc) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800418 int32_t result = AKEY_STATE_UNKNOWN;
419 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000420 auto deviceIt = mDevices.find(deviceId);
421 if (deviceIt != mDevices.end()) {
422 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700423 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800424 result = (device->*getStateFunc)(sourceMask, code);
425 }
426 }
427 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000428 for (auto& devicePair : mDevices) {
429 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700430 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800431 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
432 // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
433 int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
434 if (currentResult >= AKEY_STATE_DOWN) {
435 return currentResult;
436 } else if (currentResult == AKEY_STATE_UP) {
437 result = currentResult;
438 }
439 }
440 }
441 }
442 return result;
443}
444
Andrii Kulian763a3a42016-03-08 10:46:16 -0800445void InputReader::toggleCapsLockState(int32_t deviceId) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000446 auto deviceIt = mDevices.find(deviceId);
447 if (deviceIt == mDevices.end()) {
Andrii Kulian763a3a42016-03-08 10:46:16 -0800448 ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
449 return;
450 }
451
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000452 InputDevice* device = deviceIt->second;
Andrii Kulian763a3a42016-03-08 10:46:16 -0800453 if (device->isIgnored()) {
454 return;
455 }
456
457 device->updateMetaState(AKEYCODE_CAPS_LOCK);
458}
459
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700460bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
461 const int32_t* keyCodes, uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800462 AutoMutex _l(mLock);
463
464 memset(outFlags, 0, numCodes);
465 return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
466}
467
468bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700469 size_t numCodes, const int32_t* keyCodes,
470 uint8_t* outFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471 bool result = false;
472 if (deviceId >= 0) {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000473 auto deviceIt = mDevices.find(deviceId);
474 if (deviceIt != mDevices.end()) {
475 InputDevice* device = deviceIt->second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700476 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
477 result = device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 }
479 }
480 } else {
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000481 for (auto& devicePair : mDevices) {
482 InputDevice* device = devicePair.second;
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700483 if (!device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
484 result |= device->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800485 }
486 }
487 }
488 return result;
489}
490
491void InputReader::requestRefreshConfiguration(uint32_t changes) {
492 AutoMutex _l(mLock);
493
494 if (changes) {
495 bool needWake = !mConfigurationChangesToRefresh;
496 mConfigurationChangesToRefresh |= changes;
497
498 if (needWake) {
499 mEventHub->wake();
500 }
501 }
502}
503
504void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700505 ssize_t repeat, int32_t token) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800506 AutoMutex _l(mLock);
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000507 auto deviceIt = mDevices.find(deviceId);
508 if (deviceIt != mDevices.end()) {
509 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800510 device->vibrate(pattern, patternSize, repeat, token);
511 }
512}
513
514void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
515 AutoMutex _l(mLock);
516
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000517 auto deviceIt = mDevices.find(deviceId);
518 if (deviceIt != mDevices.end()) {
519 InputDevice* device = deviceIt->second;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800520 device->cancelVibrate(token);
521 }
522}
523
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700524bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
525 AutoMutex _l(mLock);
526
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000527 auto deviceIt = mDevices.find(deviceId);
528 if (deviceIt != mDevices.end()) {
529 InputDevice* device = deviceIt->second;
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700530 return device->isEnabled();
531 }
532 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
533 return false;
534}
535
Arthur Hungc23540e2018-11-29 20:42:11 +0800536bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
537 AutoMutex _l(mLock);
538
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000539 auto deviceIt = mDevices.find(deviceId);
540 if (deviceIt == mDevices.end()) {
Arthur Hungc23540e2018-11-29 20:42:11 +0800541 ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
542 return false;
543 }
544
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000545 InputDevice* device = deviceIt->second;
Arthur Hung2c9a3342019-07-23 14:18:59 +0800546 if (!device->isEnabled()) {
547 ALOGW("Ignoring disabled device %s", device->getName().c_str());
548 return false;
549 }
550
551 std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId();
Arthur Hungc23540e2018-11-29 20:42:11 +0800552 // No associated display. By default, can dispatch to all displays.
553 if (!associatedDisplayId) {
554 return true;
555 }
556
557 if (*associatedDisplayId == ADISPLAY_ID_NONE) {
Arthur Hung2c9a3342019-07-23 14:18:59 +0800558 ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str());
Arthur Hungc23540e2018-11-29 20:42:11 +0800559 return true;
560 }
561
562 return *associatedDisplayId == displayId;
563}
564
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800565void InputReader::dump(std::string& dump) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566 AutoMutex _l(mLock);
567
568 mEventHub->dump(dump);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800569 dump += "\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800571 dump += "Input Reader State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572
Nathaniel R. Lewis10793a62019-11-05 02:17:02 +0000573 for (const auto& devicePair : mDevices) {
574 InputDevice* const device = devicePair.second;
575 device->dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800576 }
577
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800578 dump += INDENT "Configuration:\n";
579 dump += INDENT2 "ExcludedDeviceNames: [";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800580 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
581 if (i != 0) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800582 dump += ", ";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583 }
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100584 dump += mConfig.excludedDeviceNames[i];
Michael Wrightd02c5b62014-02-10 15:10:22 -0800585 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800586 dump += "]\n";
587 dump += StringPrintf(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700588 mConfig.virtualKeyQuietTime * 0.000001f);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800590 dump += StringPrintf(INDENT2 "PointerVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700591 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
592 "acceleration=%0.3f\n",
593 mConfig.pointerVelocityControlParameters.scale,
594 mConfig.pointerVelocityControlParameters.lowThreshold,
595 mConfig.pointerVelocityControlParameters.highThreshold,
596 mConfig.pointerVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800597
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800598 dump += StringPrintf(INDENT2 "WheelVelocityControlParameters: "
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700599 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
600 "acceleration=%0.3f\n",
601 mConfig.wheelVelocityControlParameters.scale,
602 mConfig.wheelVelocityControlParameters.lowThreshold,
603 mConfig.wheelVelocityControlParameters.highThreshold,
604 mConfig.wheelVelocityControlParameters.acceleration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800605
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800606 dump += StringPrintf(INDENT2 "PointerGesture:\n");
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700607 dump += StringPrintf(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled));
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800608 dump += StringPrintf(INDENT3 "QuietInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700609 mConfig.pointerGestureQuietInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800610 dump += StringPrintf(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700611 mConfig.pointerGestureDragMinSwitchSpeed);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800612 dump += StringPrintf(INDENT3 "TapInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700613 mConfig.pointerGestureTapInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800614 dump += StringPrintf(INDENT3 "TapDragInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700615 mConfig.pointerGestureTapDragInterval * 0.000001f);
616 dump += StringPrintf(INDENT3 "TapSlop: %0.1fpx\n", mConfig.pointerGestureTapSlop);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800617 dump += StringPrintf(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700618 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800619 dump += StringPrintf(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700620 mConfig.pointerGestureMultitouchMinDistance);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800621 dump += StringPrintf(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700622 mConfig.pointerGestureSwipeTransitionAngleCosine);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800623 dump += StringPrintf(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700624 mConfig.pointerGestureSwipeMaxWidthRatio);
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800625 dump += StringPrintf(INDENT3 "MovementSpeedRatio: %0.1f\n",
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700626 mConfig.pointerGestureMovementSpeedRatio);
627 dump += StringPrintf(INDENT3 "ZoomSpeedRatio: %0.1f\n", mConfig.pointerGestureZoomSpeedRatio);
Santos Cordonfa5cf462017-04-05 10:37:00 -0700628
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800629 dump += INDENT3 "Viewports:\n";
Santos Cordonfa5cf462017-04-05 10:37:00 -0700630 mConfig.dump(dump);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631}
632
633void InputReader::monitor() {
634 // Acquire and release the lock to ensure that the reader has not deadlocked.
635 mLock.lock();
636 mEventHub->wake();
637 mReaderIsAliveCondition.wait(mLock);
638 mLock.unlock();
639
640 // Check the EventHub
641 mEventHub->monitor();
642}
643
Michael Wrightd02c5b62014-02-10 15:10:22 -0800644// --- InputReader::ContextImpl ---
645
Prabir Pradhanda7c00c2019-08-29 14:12:42 -0700646InputReader::ContextImpl::ContextImpl(InputReader* reader) : mReader(reader) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800647
648void InputReader::ContextImpl::updateGlobalMetaState() {
649 // lock is already held by the input loop
650 mReader->updateGlobalMetaStateLocked();
651}
652
653int32_t InputReader::ContextImpl::getGlobalMetaState() {
654 // lock is already held by the input loop
655 return mReader->getGlobalMetaStateLocked();
656}
657
658void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
659 // lock is already held by the input loop
660 mReader->disableVirtualKeysUntilLocked(time);
661}
662
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800663bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, int32_t keyCode,
664 int32_t scanCode) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800665 // lock is already held by the input loop
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800666 return mReader->shouldDropVirtualKeyLocked(now, keyCode, scanCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800667}
668
669void InputReader::ContextImpl::fadePointer() {
670 // lock is already held by the input loop
671 mReader->fadePointerLocked();
672}
673
674void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
675 // lock is already held by the input loop
676 mReader->requestTimeoutAtTimeLocked(when);
677}
678
679int32_t InputReader::ContextImpl::bumpGeneration() {
680 // lock is already held by the input loop
681 return mReader->bumpGenerationLocked();
682}
683
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800684void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
Michael Wright842500e2015-03-13 17:32:02 -0700685 // lock is already held by whatever called refreshConfigurationLocked
686 mReader->getExternalStylusDevicesLocked(outDevices);
687}
688
689void InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
690 mReader->dispatchExternalStylusState(state);
691}
692
Michael Wrightd02c5b62014-02-10 15:10:22 -0800693InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
694 return mReader->mPolicy.get();
695}
696
697InputListenerInterface* InputReader::ContextImpl::getListener() {
698 return mReader->mQueuedListener.get();
699}
700
701EventHubInterface* InputReader::ContextImpl::getEventHub() {
702 return mReader->mEventHub.get();
703}
704
Prabir Pradhan42611e02018-11-27 14:04:02 -0800705uint32_t InputReader::ContextImpl::getNextSequenceNum() {
706 return (mReader->mNextSequenceNum)++;
707}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800708
Michael Wrightd02c5b62014-02-10 15:10:22 -0800709} // namespace android