xref: /aosp_15_r20/frameworks/native/services/inputflinger/reader/InputDevice.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "Macros.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include "InputDevice.h"
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <android/sysprop/InputProperties.sysprop.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <ftl/flags.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #include "CursorInputMapper.h"
27*38e8c45fSAndroid Build Coastguard Worker #include "ExternalStylusInputMapper.h"
28*38e8c45fSAndroid Build Coastguard Worker #include "InputReaderContext.h"
29*38e8c45fSAndroid Build Coastguard Worker #include "JoystickInputMapper.h"
30*38e8c45fSAndroid Build Coastguard Worker #include "KeyboardInputMapper.h"
31*38e8c45fSAndroid Build Coastguard Worker #include "MultiTouchInputMapper.h"
32*38e8c45fSAndroid Build Coastguard Worker #include "PeripheralController.h"
33*38e8c45fSAndroid Build Coastguard Worker #include "RotaryEncoderInputMapper.h"
34*38e8c45fSAndroid Build Coastguard Worker #include "SensorInputMapper.h"
35*38e8c45fSAndroid Build Coastguard Worker #include "SingleTouchInputMapper.h"
36*38e8c45fSAndroid Build Coastguard Worker #include "SwitchInputMapper.h"
37*38e8c45fSAndroid Build Coastguard Worker #include "TouchpadInputMapper.h"
38*38e8c45fSAndroid Build Coastguard Worker #include "VibratorInputMapper.h"
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker namespace android {
41*38e8c45fSAndroid Build Coastguard Worker 
InputDevice(InputReaderContext * context,int32_t id,int32_t generation,const InputDeviceIdentifier & identifier)42*38e8c45fSAndroid Build Coastguard Worker InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
43*38e8c45fSAndroid Build Coastguard Worker                          const InputDeviceIdentifier& identifier)
44*38e8c45fSAndroid Build Coastguard Worker       : mContext(context),
45*38e8c45fSAndroid Build Coastguard Worker         mId(id),
46*38e8c45fSAndroid Build Coastguard Worker         mGeneration(generation),
47*38e8c45fSAndroid Build Coastguard Worker         mControllerNumber(0),
48*38e8c45fSAndroid Build Coastguard Worker         mIdentifier(identifier),
49*38e8c45fSAndroid Build Coastguard Worker         mClasses(0),
50*38e8c45fSAndroid Build Coastguard Worker         mSources(0),
51*38e8c45fSAndroid Build Coastguard Worker         mIsWaking(false),
52*38e8c45fSAndroid Build Coastguard Worker         mIsExternal(false),
53*38e8c45fSAndroid Build Coastguard Worker         mHasMic(false),
54*38e8c45fSAndroid Build Coastguard Worker         mDropUntilNextSync(false) {}
55*38e8c45fSAndroid Build Coastguard Worker 
~InputDevice()56*38e8c45fSAndroid Build Coastguard Worker InputDevice::~InputDevice() {}
57*38e8c45fSAndroid Build Coastguard Worker 
isEnabled()58*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::isEnabled() {
59*38e8c45fSAndroid Build Coastguard Worker     if (!hasEventHubDevices()) {
60*38e8c45fSAndroid Build Coastguard Worker         return false;
61*38e8c45fSAndroid Build Coastguard Worker     }
62*38e8c45fSAndroid Build Coastguard Worker     // An input device composed of sub devices can be individually enabled or disabled.
63*38e8c45fSAndroid Build Coastguard Worker     // If any of the sub device is enabled then the input device is considered as enabled.
64*38e8c45fSAndroid Build Coastguard Worker     bool enabled = false;
65*38e8c45fSAndroid Build Coastguard Worker     for_each_subdevice([&enabled](auto& context) { enabled |= context.isDeviceEnabled(); });
66*38e8c45fSAndroid Build Coastguard Worker     return enabled;
67*38e8c45fSAndroid Build Coastguard Worker }
68*38e8c45fSAndroid Build Coastguard Worker 
updateEnableState(nsecs_t when,const InputReaderConfiguration & readerConfig,bool forceEnable)69*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::updateEnableState(nsecs_t when,
70*38e8c45fSAndroid Build Coastguard Worker                                                      const InputReaderConfiguration& readerConfig,
71*38e8c45fSAndroid Build Coastguard Worker                                                      bool forceEnable) {
72*38e8c45fSAndroid Build Coastguard Worker     bool enable = forceEnable;
73*38e8c45fSAndroid Build Coastguard Worker     if (!forceEnable) {
74*38e8c45fSAndroid Build Coastguard Worker         // If the device was explicitly disabled by the user, it would be present in the
75*38e8c45fSAndroid Build Coastguard Worker         // "disabledDevices" list. This device should be disabled.
76*38e8c45fSAndroid Build Coastguard Worker         enable = readerConfig.disabledDevices.find(mId) == readerConfig.disabledDevices.end();
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker         // If a device is associated with a specific display but there is no
79*38e8c45fSAndroid Build Coastguard Worker         // associated DisplayViewport, don't enable the device.
80*38e8c45fSAndroid Build Coastguard Worker         if (enable && (mAssociatedDisplayPort || mAssociatedDisplayUniqueIdByPort) &&
81*38e8c45fSAndroid Build Coastguard Worker             !mAssociatedViewport) {
82*38e8c45fSAndroid Build Coastguard Worker             const std::string desc = mAssociatedDisplayPort
83*38e8c45fSAndroid Build Coastguard Worker                     ? "port " + std::to_string(*mAssociatedDisplayPort)
84*38e8c45fSAndroid Build Coastguard Worker                     : "uniqueId " + *mAssociatedDisplayUniqueIdByPort;
85*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Cannot enable input device %s because it is associated "
86*38e8c45fSAndroid Build Coastguard Worker                   "with %s, but the corresponding viewport is not found",
87*38e8c45fSAndroid Build Coastguard Worker                   getName().c_str(), desc.c_str());
88*38e8c45fSAndroid Build Coastguard Worker             enable = false;
89*38e8c45fSAndroid Build Coastguard Worker         }
90*38e8c45fSAndroid Build Coastguard Worker     }
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
93*38e8c45fSAndroid Build Coastguard Worker     if (isEnabled() == enable) {
94*38e8c45fSAndroid Build Coastguard Worker         return out;
95*38e8c45fSAndroid Build Coastguard Worker     }
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     // When resetting some devices, the driver needs to be queried to ensure that a proper reset is
98*38e8c45fSAndroid Build Coastguard Worker     // performed. The querying must happen when the device is enabled, so we reset after enabling
99*38e8c45fSAndroid Build Coastguard Worker     // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information.
100*38e8c45fSAndroid Build Coastguard Worker     if (enable) {
101*38e8c45fSAndroid Build Coastguard Worker         for_each_subdevice([](auto& context) { context.enableDevice(); });
102*38e8c45fSAndroid Build Coastguard Worker         out += reset(when);
103*38e8c45fSAndroid Build Coastguard Worker     } else {
104*38e8c45fSAndroid Build Coastguard Worker         out += reset(when);
105*38e8c45fSAndroid Build Coastguard Worker         for_each_subdevice([](auto& context) { context.disableDevice(); });
106*38e8c45fSAndroid Build Coastguard Worker     }
107*38e8c45fSAndroid Build Coastguard Worker     // Must change generation to flag this device as changed
108*38e8c45fSAndroid Build Coastguard Worker     bumpGeneration();
109*38e8c45fSAndroid Build Coastguard Worker     return out;
110*38e8c45fSAndroid Build Coastguard Worker }
111*38e8c45fSAndroid Build Coastguard Worker 
dump(std::string & dump,const std::string & eventHubDevStr)112*38e8c45fSAndroid Build Coastguard Worker void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
113*38e8c45fSAndroid Build Coastguard Worker     InputDeviceInfo deviceInfo = getDeviceInfo();
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "Device %d: %s\n", deviceInfo.getId(),
116*38e8c45fSAndroid Build Coastguard Worker                          deviceInfo.getDisplayName().c_str());
117*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "%s", eventHubDevStr.c_str());
118*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "Generation: %d\n", mGeneration);
119*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
120*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "IsWaking: %s\n", toString(mIsWaking));
121*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "AssociatedDisplayPort: ");
122*38e8c45fSAndroid Build Coastguard Worker     if (mAssociatedDisplayPort) {
123*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf("%" PRIu8 "\n", *mAssociatedDisplayPort);
124*38e8c45fSAndroid Build Coastguard Worker     } else {
125*38e8c45fSAndroid Build Coastguard Worker         dump += "<none>\n";
126*38e8c45fSAndroid Build Coastguard Worker     }
127*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueIdByPort: ");
128*38e8c45fSAndroid Build Coastguard Worker     if (mAssociatedDisplayUniqueIdByPort) {
129*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf("%s\n", mAssociatedDisplayUniqueIdByPort->c_str());
130*38e8c45fSAndroid Build Coastguard Worker     } else {
131*38e8c45fSAndroid Build Coastguard Worker         dump += "<none>\n";
132*38e8c45fSAndroid Build Coastguard Worker     }
133*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueIdByDescriptor: ");
134*38e8c45fSAndroid Build Coastguard Worker     if (mAssociatedDisplayUniqueIdByDescriptor) {
135*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf("%s\n", mAssociatedDisplayUniqueIdByDescriptor->c_str());
136*38e8c45fSAndroid Build Coastguard Worker     } else {
137*38e8c45fSAndroid Build Coastguard Worker         dump += "<none>\n";
138*38e8c45fSAndroid Build Coastguard Worker     }
139*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "HasMic:     %s\n", toString(mHasMic));
140*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "Sources: %s\n",
141*38e8c45fSAndroid Build Coastguard Worker                          inputEventSourceToString(deviceInfo.getSources()).c_str());
142*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
143*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "ControllerNum: %d\n", deviceInfo.getControllerNumber());
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker     const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
146*38e8c45fSAndroid Build Coastguard Worker     if (!ranges.empty()) {
147*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT2 "Motion Ranges:\n";
148*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < ranges.size(); i++) {
149*38e8c45fSAndroid Build Coastguard Worker             const InputDeviceInfo::MotionRange& range = ranges[i];
150*38e8c45fSAndroid Build Coastguard Worker             const char* label = InputEventLookup::getAxisLabel(range.axis);
151*38e8c45fSAndroid Build Coastguard Worker             char name[32];
152*38e8c45fSAndroid Build Coastguard Worker             if (label) {
153*38e8c45fSAndroid Build Coastguard Worker                 strncpy(name, label, sizeof(name));
154*38e8c45fSAndroid Build Coastguard Worker                 name[sizeof(name) - 1] = '\0';
155*38e8c45fSAndroid Build Coastguard Worker             } else {
156*38e8c45fSAndroid Build Coastguard Worker                 snprintf(name, sizeof(name), "%d", range.axis);
157*38e8c45fSAndroid Build Coastguard Worker             }
158*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT3
159*38e8c45fSAndroid Build Coastguard Worker                                  "%s: source=%s, "
160*38e8c45fSAndroid Build Coastguard Worker                                  "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
161*38e8c45fSAndroid Build Coastguard Worker                                  name, inputEventSourceToString(range.source).c_str(), range.min,
162*38e8c45fSAndroid Build Coastguard Worker                                  range.max, range.flat, range.fuzz, range.resolution);
163*38e8c45fSAndroid Build Coastguard Worker         }
164*38e8c45fSAndroid Build Coastguard Worker     }
165*38e8c45fSAndroid Build Coastguard Worker 
166*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); });
167*38e8c45fSAndroid Build Coastguard Worker     if (mController) {
168*38e8c45fSAndroid Build Coastguard Worker         mController->dump(dump);
169*38e8c45fSAndroid Build Coastguard Worker     }
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker 
addEmptyEventHubDevice(int32_t eventHubId)172*38e8c45fSAndroid Build Coastguard Worker void InputDevice::addEmptyEventHubDevice(int32_t eventHubId) {
173*38e8c45fSAndroid Build Coastguard Worker     if (mDevices.find(eventHubId) != mDevices.end()) {
174*38e8c45fSAndroid Build Coastguard Worker         return;
175*38e8c45fSAndroid Build Coastguard Worker     }
176*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
177*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<InputMapper>> mappers;
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker     mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
180*38e8c45fSAndroid Build Coastguard Worker }
181*38e8c45fSAndroid Build Coastguard Worker 
addEventHubDevice(nsecs_t when,int32_t eventHubId,const InputReaderConfiguration & readerConfig)182*38e8c45fSAndroid Build Coastguard Worker [[nodiscard]] std::list<NotifyArgs> InputDevice::addEventHubDevice(
183*38e8c45fSAndroid Build Coastguard Worker         nsecs_t when, int32_t eventHubId, const InputReaderConfiguration& readerConfig) {
184*38e8c45fSAndroid Build Coastguard Worker     if (mDevices.find(eventHubId) != mDevices.end()) {
185*38e8c45fSAndroid Build Coastguard Worker         return {};
186*38e8c45fSAndroid Build Coastguard Worker     }
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker     // Add an empty device configure and keep it enabled to allow mapper population with correct
189*38e8c45fSAndroid Build Coastguard Worker     // configuration/context,
190*38e8c45fSAndroid Build Coastguard Worker     // Note: we need to ensure device is kept enabled till mappers are configured
191*38e8c45fSAndroid Build Coastguard Worker     // TODO: b/281852638 refactor tests to remove this flag and reliance on the empty device
192*38e8c45fSAndroid Build Coastguard Worker     addEmptyEventHubDevice(eventHubId);
193*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out = configureInternal(when, readerConfig, {}, /*forceEnable=*/true);
194*38e8c45fSAndroid Build Coastguard Worker 
195*38e8c45fSAndroid Build Coastguard Worker     DevicePair& devicePair = mDevices[eventHubId];
196*38e8c45fSAndroid Build Coastguard Worker     devicePair.second = createMappers(*devicePair.first, readerConfig);
197*38e8c45fSAndroid Build Coastguard Worker 
198*38e8c45fSAndroid Build Coastguard Worker     // Must change generation to flag this device as changed
199*38e8c45fSAndroid Build Coastguard Worker     bumpGeneration();
200*38e8c45fSAndroid Build Coastguard Worker     return out;
201*38e8c45fSAndroid Build Coastguard Worker }
202*38e8c45fSAndroid Build Coastguard Worker 
removeEventHubDevice(int32_t eventHubId)203*38e8c45fSAndroid Build Coastguard Worker void InputDevice::removeEventHubDevice(int32_t eventHubId) {
204*38e8c45fSAndroid Build Coastguard Worker     if (mController != nullptr && mController->getEventHubId() == eventHubId) {
205*38e8c45fSAndroid Build Coastguard Worker         // Delete mController, since the corresponding eventhub device is going away
206*38e8c45fSAndroid Build Coastguard Worker         mController = nullptr;
207*38e8c45fSAndroid Build Coastguard Worker     }
208*38e8c45fSAndroid Build Coastguard Worker     mDevices.erase(eventHubId);
209*38e8c45fSAndroid Build Coastguard Worker }
210*38e8c45fSAndroid Build Coastguard Worker 
configure(nsecs_t when,const InputReaderConfiguration & readerConfig,ConfigurationChanges changes)211*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::configure(nsecs_t when,
212*38e8c45fSAndroid Build Coastguard Worker                                              const InputReaderConfiguration& readerConfig,
213*38e8c45fSAndroid Build Coastguard Worker                                              ConfigurationChanges changes) {
214*38e8c45fSAndroid Build Coastguard Worker     return configureInternal(when, readerConfig, changes);
215*38e8c45fSAndroid Build Coastguard Worker }
configureInternal(nsecs_t when,const InputReaderConfiguration & readerConfig,ConfigurationChanges changes,bool forceEnable)216*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::configureInternal(nsecs_t when,
217*38e8c45fSAndroid Build Coastguard Worker                                                      const InputReaderConfiguration& readerConfig,
218*38e8c45fSAndroid Build Coastguard Worker                                                      ConfigurationChanges changes,
219*38e8c45fSAndroid Build Coastguard Worker                                                      bool forceEnable) {
220*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
221*38e8c45fSAndroid Build Coastguard Worker     mSources = 0;
222*38e8c45fSAndroid Build Coastguard Worker     mClasses = ftl::Flags<InputDeviceClass>(0);
223*38e8c45fSAndroid Build Coastguard Worker     mControllerNumber = 0;
224*38e8c45fSAndroid Build Coastguard Worker 
225*38e8c45fSAndroid Build Coastguard Worker     for_each_subdevice([this](InputDeviceContext& context) {
226*38e8c45fSAndroid Build Coastguard Worker         mClasses |= context.getDeviceClasses();
227*38e8c45fSAndroid Build Coastguard Worker         int32_t controllerNumber = context.getDeviceControllerNumber();
228*38e8c45fSAndroid Build Coastguard Worker         if (controllerNumber > 0) {
229*38e8c45fSAndroid Build Coastguard Worker             if (mControllerNumber && mControllerNumber != controllerNumber) {
230*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("InputDevice::configure(): composite device contains multiple unique "
231*38e8c45fSAndroid Build Coastguard Worker                       "controller numbers");
232*38e8c45fSAndroid Build Coastguard Worker             }
233*38e8c45fSAndroid Build Coastguard Worker             mControllerNumber = controllerNumber;
234*38e8c45fSAndroid Build Coastguard Worker         }
235*38e8c45fSAndroid Build Coastguard Worker     });
236*38e8c45fSAndroid Build Coastguard Worker 
237*38e8c45fSAndroid Build Coastguard Worker     mIsExternal = mClasses.test(InputDeviceClass::EXTERNAL);
238*38e8c45fSAndroid Build Coastguard Worker     mHasMic = mClasses.test(InputDeviceClass::MIC);
239*38e8c45fSAndroid Build Coastguard Worker 
240*38e8c45fSAndroid Build Coastguard Worker     // Update keyboard type
241*38e8c45fSAndroid Build Coastguard Worker     if (mClasses.test(InputDeviceClass::KEYBOARD)) {
242*38e8c45fSAndroid Build Coastguard Worker         mContext->getKeyboardClassifier().notifyKeyboardChanged(mId, mIdentifier, mClasses.get());
243*38e8c45fSAndroid Build Coastguard Worker         mKeyboardType = mContext->getKeyboardClassifier().getKeyboardType(mId);
244*38e8c45fSAndroid Build Coastguard Worker     }
245*38e8c45fSAndroid Build Coastguard Worker 
246*38e8c45fSAndroid Build Coastguard Worker     using Change = InputReaderConfiguration::Change;
247*38e8c45fSAndroid Build Coastguard Worker 
248*38e8c45fSAndroid Build Coastguard Worker     if (!changes.any() || !isIgnored()) {
249*38e8c45fSAndroid Build Coastguard Worker         // Full configuration should happen the first time configure is called
250*38e8c45fSAndroid Build Coastguard Worker         // and when the device type is changed. Changing a device type can
251*38e8c45fSAndroid Build Coastguard Worker         // affect various other parameters so should result in a
252*38e8c45fSAndroid Build Coastguard Worker         // reconfiguration.
253*38e8c45fSAndroid Build Coastguard Worker         if (!changes.any() || changes.test(Change::DEVICE_TYPE)) {
254*38e8c45fSAndroid Build Coastguard Worker             mConfiguration.clear();
255*38e8c45fSAndroid Build Coastguard Worker             for_each_subdevice([this](InputDeviceContext& context) {
256*38e8c45fSAndroid Build Coastguard Worker                 std::optional<PropertyMap> configuration =
257*38e8c45fSAndroid Build Coastguard Worker                         getEventHub()->getConfiguration(context.getEventHubId());
258*38e8c45fSAndroid Build Coastguard Worker                 if (configuration) {
259*38e8c45fSAndroid Build Coastguard Worker                     mConfiguration.addAll(&(*configuration));
260*38e8c45fSAndroid Build Coastguard Worker                 }
261*38e8c45fSAndroid Build Coastguard Worker             });
262*38e8c45fSAndroid Build Coastguard Worker 
263*38e8c45fSAndroid Build Coastguard Worker             mAssociatedDeviceType =
264*38e8c45fSAndroid Build Coastguard Worker                     getValueByKey(readerConfig.deviceTypeAssociations, mIdentifier.location);
265*38e8c45fSAndroid Build Coastguard Worker             mIsWaking = mConfiguration.getBool("device.wake").value_or(false);
266*38e8c45fSAndroid Build Coastguard Worker             mShouldSmoothScroll = mConfiguration.getBool("device.viewBehavior_smoothScroll");
267*38e8c45fSAndroid Build Coastguard Worker         }
268*38e8c45fSAndroid Build Coastguard Worker 
269*38e8c45fSAndroid Build Coastguard Worker         if (!changes.any() || changes.test(Change::DEVICE_ALIAS)) {
270*38e8c45fSAndroid Build Coastguard Worker             if (!(mClasses.test(InputDeviceClass::VIRTUAL))) {
271*38e8c45fSAndroid Build Coastguard Worker                 std::string alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
272*38e8c45fSAndroid Build Coastguard Worker                 if (mAlias != alias) {
273*38e8c45fSAndroid Build Coastguard Worker                     mAlias = alias;
274*38e8c45fSAndroid Build Coastguard Worker                     bumpGeneration();
275*38e8c45fSAndroid Build Coastguard Worker                 }
276*38e8c45fSAndroid Build Coastguard Worker             }
277*38e8c45fSAndroid Build Coastguard Worker         }
278*38e8c45fSAndroid Build Coastguard Worker 
279*38e8c45fSAndroid Build Coastguard Worker         if (!changes.any() || changes.test(Change::DISPLAY_INFO)) {
280*38e8c45fSAndroid Build Coastguard Worker             const auto oldAssociatedDisplayId = getAssociatedDisplayId();
281*38e8c45fSAndroid Build Coastguard Worker 
282*38e8c45fSAndroid Build Coastguard Worker             // In most situations, no port or name will be specified.
283*38e8c45fSAndroid Build Coastguard Worker             mAssociatedDisplayPort = std::nullopt;
284*38e8c45fSAndroid Build Coastguard Worker             mAssociatedDisplayUniqueIdByPort = std::nullopt;
285*38e8c45fSAndroid Build Coastguard Worker             mAssociatedViewport = std::nullopt;
286*38e8c45fSAndroid Build Coastguard Worker             // Find the display port that corresponds to the current input device descriptor
287*38e8c45fSAndroid Build Coastguard Worker             const std::string& inputDeviceDescriptor = mIdentifier.descriptor;
288*38e8c45fSAndroid Build Coastguard Worker             if (!inputDeviceDescriptor.empty()) {
289*38e8c45fSAndroid Build Coastguard Worker                 const std::unordered_map<std::string, uint8_t>& ports =
290*38e8c45fSAndroid Build Coastguard Worker                         readerConfig.inputPortToDisplayPortAssociations;
291*38e8c45fSAndroid Build Coastguard Worker                 const auto& displayPort = ports.find(inputDeviceDescriptor);
292*38e8c45fSAndroid Build Coastguard Worker                 if (displayPort != ports.end()) {
293*38e8c45fSAndroid Build Coastguard Worker                     mAssociatedDisplayPort = std::make_optional(displayPort->second);
294*38e8c45fSAndroid Build Coastguard Worker                 } else {
295*38e8c45fSAndroid Build Coastguard Worker                     const std::unordered_map<std::string, std::string>&
296*38e8c45fSAndroid Build Coastguard Worker                             displayUniqueIdsByDescriptor =
297*38e8c45fSAndroid Build Coastguard Worker                                     readerConfig.inputDeviceDescriptorToDisplayUniqueIdAssociations;
298*38e8c45fSAndroid Build Coastguard Worker                     const auto& displayUniqueIdByDescriptor =
299*38e8c45fSAndroid Build Coastguard Worker                             displayUniqueIdsByDescriptor.find(inputDeviceDescriptor);
300*38e8c45fSAndroid Build Coastguard Worker                     if (displayUniqueIdByDescriptor != displayUniqueIdsByDescriptor.end()) {
301*38e8c45fSAndroid Build Coastguard Worker                         mAssociatedDisplayUniqueIdByDescriptor =
302*38e8c45fSAndroid Build Coastguard Worker                                 displayUniqueIdByDescriptor->second;
303*38e8c45fSAndroid Build Coastguard Worker                     }
304*38e8c45fSAndroid Build Coastguard Worker                 }
305*38e8c45fSAndroid Build Coastguard Worker             }
306*38e8c45fSAndroid Build Coastguard Worker             // Find the display port that corresponds to the current input port.
307*38e8c45fSAndroid Build Coastguard Worker             const std::string& inputPort = mIdentifier.location;
308*38e8c45fSAndroid Build Coastguard Worker             if (!inputPort.empty()) {
309*38e8c45fSAndroid Build Coastguard Worker                 const std::unordered_map<std::string, uint8_t>& ports =
310*38e8c45fSAndroid Build Coastguard Worker                         readerConfig.inputPortToDisplayPortAssociations;
311*38e8c45fSAndroid Build Coastguard Worker                 const auto& displayPort = ports.find(inputPort);
312*38e8c45fSAndroid Build Coastguard Worker                 if (displayPort != ports.end()) {
313*38e8c45fSAndroid Build Coastguard Worker                     mAssociatedDisplayPort = std::make_optional(displayPort->second);
314*38e8c45fSAndroid Build Coastguard Worker                 } else {
315*38e8c45fSAndroid Build Coastguard Worker                     const std::unordered_map<std::string, std::string>& displayUniqueIdsByPort =
316*38e8c45fSAndroid Build Coastguard Worker                             readerConfig.inputPortToDisplayUniqueIdAssociations;
317*38e8c45fSAndroid Build Coastguard Worker                     const auto& displayUniqueIdByPort = displayUniqueIdsByPort.find(inputPort);
318*38e8c45fSAndroid Build Coastguard Worker                     if (displayUniqueIdByPort != displayUniqueIdsByPort.end()) {
319*38e8c45fSAndroid Build Coastguard Worker                         mAssociatedDisplayUniqueIdByPort = displayUniqueIdByPort->second;
320*38e8c45fSAndroid Build Coastguard Worker                     }
321*38e8c45fSAndroid Build Coastguard Worker                 }
322*38e8c45fSAndroid Build Coastguard Worker             }
323*38e8c45fSAndroid Build Coastguard Worker 
324*38e8c45fSAndroid Build Coastguard Worker             // If it is associated with a specific display, then find the corresponding viewport
325*38e8c45fSAndroid Build Coastguard Worker             // which will be used to enable/disable the device.
326*38e8c45fSAndroid Build Coastguard Worker             if (mAssociatedDisplayPort) {
327*38e8c45fSAndroid Build Coastguard Worker                 mAssociatedViewport =
328*38e8c45fSAndroid Build Coastguard Worker                         readerConfig.getDisplayViewportByPort(*mAssociatedDisplayPort);
329*38e8c45fSAndroid Build Coastguard Worker                 if (!mAssociatedViewport) {
330*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Input device %s should be associated with display on port %" PRIu8 ", "
331*38e8c45fSAndroid Build Coastguard Worker                           "but the corresponding viewport is not found.",
332*38e8c45fSAndroid Build Coastguard Worker                           getName().c_str(), *mAssociatedDisplayPort);
333*38e8c45fSAndroid Build Coastguard Worker                 }
334*38e8c45fSAndroid Build Coastguard Worker             } else if (mAssociatedDisplayUniqueIdByDescriptor != std::nullopt) {
335*38e8c45fSAndroid Build Coastguard Worker                 mAssociatedViewport = readerConfig.getDisplayViewportByUniqueId(
336*38e8c45fSAndroid Build Coastguard Worker                         *mAssociatedDisplayUniqueIdByDescriptor);
337*38e8c45fSAndroid Build Coastguard Worker                 if (!mAssociatedViewport) {
338*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Input device %s should be associated with display %s but the "
339*38e8c45fSAndroid Build Coastguard Worker                           "corresponding viewport cannot be found",
340*38e8c45fSAndroid Build Coastguard Worker                           getName().c_str(), mAssociatedDisplayUniqueIdByDescriptor->c_str());
341*38e8c45fSAndroid Build Coastguard Worker                 }
342*38e8c45fSAndroid Build Coastguard Worker             } else if (mAssociatedDisplayUniqueIdByPort != std::nullopt) {
343*38e8c45fSAndroid Build Coastguard Worker                 mAssociatedViewport = readerConfig.getDisplayViewportByUniqueId(
344*38e8c45fSAndroid Build Coastguard Worker                         *mAssociatedDisplayUniqueIdByPort);
345*38e8c45fSAndroid Build Coastguard Worker                 if (!mAssociatedViewport) {
346*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Input device %s should be associated with display %s but the "
347*38e8c45fSAndroid Build Coastguard Worker                           "corresponding viewport cannot be found",
348*38e8c45fSAndroid Build Coastguard Worker                           getName().c_str(), mAssociatedDisplayUniqueIdByPort->c_str());
349*38e8c45fSAndroid Build Coastguard Worker                 }
350*38e8c45fSAndroid Build Coastguard Worker             }
351*38e8c45fSAndroid Build Coastguard Worker 
352*38e8c45fSAndroid Build Coastguard Worker             if (getAssociatedDisplayId() != oldAssociatedDisplayId) {
353*38e8c45fSAndroid Build Coastguard Worker                 bumpGeneration();
354*38e8c45fSAndroid Build Coastguard Worker             }
355*38e8c45fSAndroid Build Coastguard Worker         }
356*38e8c45fSAndroid Build Coastguard Worker 
357*38e8c45fSAndroid Build Coastguard Worker         for_each_mapper([this, when, &readerConfig, changes, &out](InputMapper& mapper) {
358*38e8c45fSAndroid Build Coastguard Worker             out += mapper.reconfigure(when, readerConfig, changes);
359*38e8c45fSAndroid Build Coastguard Worker             mSources |= mapper.getSources();
360*38e8c45fSAndroid Build Coastguard Worker         });
361*38e8c45fSAndroid Build Coastguard Worker 
362*38e8c45fSAndroid Build Coastguard Worker         if (!changes.any() || changes.test(Change::ENABLED_STATE) ||
363*38e8c45fSAndroid Build Coastguard Worker             changes.test(Change::DISPLAY_INFO)) {
364*38e8c45fSAndroid Build Coastguard Worker             // Whether a device is enabled can depend on the display association,
365*38e8c45fSAndroid Build Coastguard Worker             // so update the enabled state when there is a change in display info.
366*38e8c45fSAndroid Build Coastguard Worker             out += updateEnableState(when, readerConfig, forceEnable);
367*38e8c45fSAndroid Build Coastguard Worker         }
368*38e8c45fSAndroid Build Coastguard Worker 
369*38e8c45fSAndroid Build Coastguard Worker         if (!changes.any() || changes.test(InputReaderConfiguration::Change::KEY_REMAPPING)) {
370*38e8c45fSAndroid Build Coastguard Worker             const bool isFullKeyboard =
371*38e8c45fSAndroid Build Coastguard Worker                     (mSources & AINPUT_SOURCE_KEYBOARD) == AINPUT_SOURCE_KEYBOARD &&
372*38e8c45fSAndroid Build Coastguard Worker                     mKeyboardType == KeyboardType::ALPHABETIC;
373*38e8c45fSAndroid Build Coastguard Worker             if (isFullKeyboard) {
374*38e8c45fSAndroid Build Coastguard Worker                 for_each_subdevice([&readerConfig](auto& context) {
375*38e8c45fSAndroid Build Coastguard Worker                     context.setKeyRemapping(readerConfig.keyRemapping);
376*38e8c45fSAndroid Build Coastguard Worker                 });
377*38e8c45fSAndroid Build Coastguard Worker                 bumpGeneration();
378*38e8c45fSAndroid Build Coastguard Worker             }
379*38e8c45fSAndroid Build Coastguard Worker         }
380*38e8c45fSAndroid Build Coastguard Worker     }
381*38e8c45fSAndroid Build Coastguard Worker     return out;
382*38e8c45fSAndroid Build Coastguard Worker }
383*38e8c45fSAndroid Build Coastguard Worker 
reset(nsecs_t when)384*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::reset(nsecs_t when) {
385*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
386*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.reset(when); });
387*38e8c45fSAndroid Build Coastguard Worker 
388*38e8c45fSAndroid Build Coastguard Worker     mContext->updateGlobalMetaState();
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker     out.push_back(notifyReset(when));
391*38e8c45fSAndroid Build Coastguard Worker     return out;
392*38e8c45fSAndroid Build Coastguard Worker }
393*38e8c45fSAndroid Build Coastguard Worker 
process(const RawEvent * rawEvents,size_t count)394*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t count) {
395*38e8c45fSAndroid Build Coastguard Worker     // Process all of the events in order for each mapper.
396*38e8c45fSAndroid Build Coastguard Worker     // We cannot simply ask each mapper to process them in bulk because mappers may
397*38e8c45fSAndroid Build Coastguard Worker     // have side-effects that must be interleaved.  For example, joystick movement events and
398*38e8c45fSAndroid Build Coastguard Worker     // gamepad button presses are handled by different mappers but they should be dispatched
399*38e8c45fSAndroid Build Coastguard Worker     // in the order received.
400*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
401*38e8c45fSAndroid Build Coastguard Worker     for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
402*38e8c45fSAndroid Build Coastguard Worker         if (debugRawEvents()) {
403*38e8c45fSAndroid Build Coastguard Worker             const auto [type, code, value] =
404*38e8c45fSAndroid Build Coastguard Worker                     InputEventLookup::getLinuxEvdevLabel(rawEvent->type, rawEvent->code,
405*38e8c45fSAndroid Build Coastguard Worker                                                          rawEvent->value);
406*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Input event: eventHubDevice=%d type=%s code=%s value=%s when=%" PRId64,
407*38e8c45fSAndroid Build Coastguard Worker                   rawEvent->deviceId, type.c_str(), code.c_str(), value.c_str(), rawEvent->when);
408*38e8c45fSAndroid Build Coastguard Worker         }
409*38e8c45fSAndroid Build Coastguard Worker 
410*38e8c45fSAndroid Build Coastguard Worker         if (mDropUntilNextSync) {
411*38e8c45fSAndroid Build Coastguard Worker             if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
412*38e8c45fSAndroid Build Coastguard Worker                 out += reset(rawEvent->when);
413*38e8c45fSAndroid Build Coastguard Worker                 mDropUntilNextSync = false;
414*38e8c45fSAndroid Build Coastguard Worker                 ALOGD_IF(debugRawEvents(), "Recovered from input event buffer overrun.");
415*38e8c45fSAndroid Build Coastguard Worker             } else {
416*38e8c45fSAndroid Build Coastguard Worker                 ALOGD_IF(debugRawEvents(),
417*38e8c45fSAndroid Build Coastguard Worker                          "Dropped input event while waiting for next input sync.");
418*38e8c45fSAndroid Build Coastguard Worker             }
419*38e8c45fSAndroid Build Coastguard Worker         } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
420*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
421*38e8c45fSAndroid Build Coastguard Worker             mDropUntilNextSync = true;
422*38e8c45fSAndroid Build Coastguard Worker         } else {
423*38e8c45fSAndroid Build Coastguard Worker             for_each_mapper_in_subdevice(rawEvent->deviceId, [&](InputMapper& mapper) {
424*38e8c45fSAndroid Build Coastguard Worker                 out += mapper.process(*rawEvent);
425*38e8c45fSAndroid Build Coastguard Worker             });
426*38e8c45fSAndroid Build Coastguard Worker         }
427*38e8c45fSAndroid Build Coastguard Worker         --count;
428*38e8c45fSAndroid Build Coastguard Worker     }
429*38e8c45fSAndroid Build Coastguard Worker     postProcess(out);
430*38e8c45fSAndroid Build Coastguard Worker     return out;
431*38e8c45fSAndroid Build Coastguard Worker }
432*38e8c45fSAndroid Build Coastguard Worker 
postProcess(std::list<NotifyArgs> & args) const433*38e8c45fSAndroid Build Coastguard Worker void InputDevice::postProcess(std::list<NotifyArgs>& args) const {
434*38e8c45fSAndroid Build Coastguard Worker     if (mIsWaking) {
435*38e8c45fSAndroid Build Coastguard Worker         // Update policy flags to request wake for the `NotifyArgs` that come from waking devices.
436*38e8c45fSAndroid Build Coastguard Worker         for (auto& arg : args) {
437*38e8c45fSAndroid Build Coastguard Worker             if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) {
438*38e8c45fSAndroid Build Coastguard Worker                 notifyMotionArgs->policyFlags |= POLICY_FLAG_WAKE;
439*38e8c45fSAndroid Build Coastguard Worker             } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) {
440*38e8c45fSAndroid Build Coastguard Worker                 notifySwitchArgs->policyFlags |= POLICY_FLAG_WAKE;
441*38e8c45fSAndroid Build Coastguard Worker             } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) {
442*38e8c45fSAndroid Build Coastguard Worker                 notifyKeyArgs->policyFlags |= POLICY_FLAG_WAKE;
443*38e8c45fSAndroid Build Coastguard Worker             }
444*38e8c45fSAndroid Build Coastguard Worker         }
445*38e8c45fSAndroid Build Coastguard Worker     }
446*38e8c45fSAndroid Build Coastguard Worker }
447*38e8c45fSAndroid Build Coastguard Worker 
timeoutExpired(nsecs_t when)448*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) {
449*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
450*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); });
451*38e8c45fSAndroid Build Coastguard Worker     return out;
452*38e8c45fSAndroid Build Coastguard Worker }
453*38e8c45fSAndroid Build Coastguard Worker 
updateExternalStylusState(const StylusState & state)454*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::updateExternalStylusState(const StylusState& state) {
455*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
456*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.updateExternalStylusState(state); });
457*38e8c45fSAndroid Build Coastguard Worker     return out;
458*38e8c45fSAndroid Build Coastguard Worker }
459*38e8c45fSAndroid Build Coastguard Worker 
getDeviceInfo()460*38e8c45fSAndroid Build Coastguard Worker InputDeviceInfo InputDevice::getDeviceInfo() {
461*38e8c45fSAndroid Build Coastguard Worker     InputDeviceInfo outDeviceInfo;
462*38e8c45fSAndroid Build Coastguard Worker     outDeviceInfo.initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
463*38e8c45fSAndroid Build Coastguard Worker                              mHasMic,
464*38e8c45fSAndroid Build Coastguard Worker                              getAssociatedDisplayId().value_or(ui::LogicalDisplayId::INVALID),
465*38e8c45fSAndroid Build Coastguard Worker                              {mShouldSmoothScroll}, isEnabled());
466*38e8c45fSAndroid Build Coastguard Worker     outDeviceInfo.setKeyboardType(static_cast<int32_t>(mKeyboardType));
467*38e8c45fSAndroid Build Coastguard Worker 
468*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper(
469*38e8c45fSAndroid Build Coastguard Worker             [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
470*38e8c45fSAndroid Build Coastguard Worker 
471*38e8c45fSAndroid Build Coastguard Worker     if (mController) {
472*38e8c45fSAndroid Build Coastguard Worker         mController->populateDeviceInfo(&outDeviceInfo);
473*38e8c45fSAndroid Build Coastguard Worker     }
474*38e8c45fSAndroid Build Coastguard Worker     return outDeviceInfo;
475*38e8c45fSAndroid Build Coastguard Worker }
476*38e8c45fSAndroid Build Coastguard Worker 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)477*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
478*38e8c45fSAndroid Build Coastguard Worker     return getState(sourceMask, keyCode, &InputMapper::getKeyCodeState);
479*38e8c45fSAndroid Build Coastguard Worker }
480*38e8c45fSAndroid Build Coastguard Worker 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)481*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
482*38e8c45fSAndroid Build Coastguard Worker     return getState(sourceMask, scanCode, &InputMapper::getScanCodeState);
483*38e8c45fSAndroid Build Coastguard Worker }
484*38e8c45fSAndroid Build Coastguard Worker 
getSwitchState(uint32_t sourceMask,int32_t switchCode)485*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
486*38e8c45fSAndroid Build Coastguard Worker     return getState(sourceMask, switchCode, &InputMapper::getSwitchState);
487*38e8c45fSAndroid Build Coastguard Worker }
488*38e8c45fSAndroid Build Coastguard Worker 
getState(uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)489*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
490*38e8c45fSAndroid Build Coastguard Worker     int32_t result = AKEY_STATE_UNKNOWN;
491*38e8c45fSAndroid Build Coastguard Worker     for (auto& deviceEntry : mDevices) {
492*38e8c45fSAndroid Build Coastguard Worker         auto& devicePair = deviceEntry.second;
493*38e8c45fSAndroid Build Coastguard Worker         auto& mappers = devicePair.second;
494*38e8c45fSAndroid Build Coastguard Worker         for (auto& mapperPtr : mappers) {
495*38e8c45fSAndroid Build Coastguard Worker             InputMapper& mapper = *mapperPtr;
496*38e8c45fSAndroid Build Coastguard Worker             if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
497*38e8c45fSAndroid Build Coastguard Worker                 // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
498*38e8c45fSAndroid Build Coastguard Worker                 // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
499*38e8c45fSAndroid Build Coastguard Worker                 int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code);
500*38e8c45fSAndroid Build Coastguard Worker                 if (currentResult >= AKEY_STATE_DOWN) {
501*38e8c45fSAndroid Build Coastguard Worker                     return currentResult;
502*38e8c45fSAndroid Build Coastguard Worker                 } else if (currentResult == AKEY_STATE_UP) {
503*38e8c45fSAndroid Build Coastguard Worker                     result = currentResult;
504*38e8c45fSAndroid Build Coastguard Worker                 }
505*38e8c45fSAndroid Build Coastguard Worker             }
506*38e8c45fSAndroid Build Coastguard Worker         }
507*38e8c45fSAndroid Build Coastguard Worker     }
508*38e8c45fSAndroid Build Coastguard Worker     return result;
509*38e8c45fSAndroid Build Coastguard Worker }
510*38e8c45fSAndroid Build Coastguard Worker 
createMappers(InputDeviceContext & contextPtr,const InputReaderConfiguration & readerConfig)511*38e8c45fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<InputMapper>> InputDevice::createMappers(
512*38e8c45fSAndroid Build Coastguard Worker         InputDeviceContext& contextPtr, const InputReaderConfiguration& readerConfig) {
513*38e8c45fSAndroid Build Coastguard Worker     ftl::Flags<InputDeviceClass> classes = contextPtr.getDeviceClasses();
514*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<InputMapper>> mappers;
515*38e8c45fSAndroid Build Coastguard Worker 
516*38e8c45fSAndroid Build Coastguard Worker     // Switch-like devices.
517*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::SWITCH)) {
518*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<SwitchInputMapper>(contextPtr, readerConfig));
519*38e8c45fSAndroid Build Coastguard Worker     }
520*38e8c45fSAndroid Build Coastguard Worker 
521*38e8c45fSAndroid Build Coastguard Worker     // Scroll wheel-like devices.
522*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::ROTARY_ENCODER)) {
523*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<RotaryEncoderInputMapper>(contextPtr, readerConfig));
524*38e8c45fSAndroid Build Coastguard Worker     }
525*38e8c45fSAndroid Build Coastguard Worker 
526*38e8c45fSAndroid Build Coastguard Worker     // Vibrator-like devices.
527*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::VIBRATOR)) {
528*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<VibratorInputMapper>(contextPtr, readerConfig));
529*38e8c45fSAndroid Build Coastguard Worker     }
530*38e8c45fSAndroid Build Coastguard Worker 
531*38e8c45fSAndroid Build Coastguard Worker     // Battery-like devices or light-containing devices.
532*38e8c45fSAndroid Build Coastguard Worker     // PeripheralController will be created with associated EventHub device.
533*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::BATTERY) || classes.test(InputDeviceClass::LIGHT)) {
534*38e8c45fSAndroid Build Coastguard Worker         mController = std::make_unique<PeripheralController>(contextPtr);
535*38e8c45fSAndroid Build Coastguard Worker     }
536*38e8c45fSAndroid Build Coastguard Worker 
537*38e8c45fSAndroid Build Coastguard Worker     // Keyboard-like devices.
538*38e8c45fSAndroid Build Coastguard Worker     uint32_t keyboardSource = 0;
539*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::KEYBOARD)) {
540*38e8c45fSAndroid Build Coastguard Worker         keyboardSource |= AINPUT_SOURCE_KEYBOARD;
541*38e8c45fSAndroid Build Coastguard Worker     }
542*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::DPAD)) {
543*38e8c45fSAndroid Build Coastguard Worker         keyboardSource |= AINPUT_SOURCE_DPAD;
544*38e8c45fSAndroid Build Coastguard Worker     }
545*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::GAMEPAD)) {
546*38e8c45fSAndroid Build Coastguard Worker         keyboardSource |= AINPUT_SOURCE_GAMEPAD;
547*38e8c45fSAndroid Build Coastguard Worker     }
548*38e8c45fSAndroid Build Coastguard Worker 
549*38e8c45fSAndroid Build Coastguard Worker     if (keyboardSource != 0) {
550*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(
551*38e8c45fSAndroid Build Coastguard Worker                 createInputMapper<KeyboardInputMapper>(contextPtr, readerConfig, keyboardSource));
552*38e8c45fSAndroid Build Coastguard Worker     }
553*38e8c45fSAndroid Build Coastguard Worker 
554*38e8c45fSAndroid Build Coastguard Worker     // Cursor-like devices.
555*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::CURSOR)) {
556*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<CursorInputMapper>(contextPtr, readerConfig));
557*38e8c45fSAndroid Build Coastguard Worker     }
558*38e8c45fSAndroid Build Coastguard Worker 
559*38e8c45fSAndroid Build Coastguard Worker     // Touchscreens and touchpad devices.
560*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::TOUCHPAD) && classes.test(InputDeviceClass::TOUCH_MT)) {
561*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<TouchpadInputMapper>(contextPtr, readerConfig));
562*38e8c45fSAndroid Build Coastguard Worker     } else if (classes.test(InputDeviceClass::TOUCH_MT)) {
563*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<MultiTouchInputMapper>(contextPtr, readerConfig));
564*38e8c45fSAndroid Build Coastguard Worker     } else if (classes.test(InputDeviceClass::TOUCH)) {
565*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<SingleTouchInputMapper>(contextPtr, readerConfig));
566*38e8c45fSAndroid Build Coastguard Worker     }
567*38e8c45fSAndroid Build Coastguard Worker 
568*38e8c45fSAndroid Build Coastguard Worker     // Joystick-like devices.
569*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::JOYSTICK)) {
570*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<JoystickInputMapper>(contextPtr, readerConfig));
571*38e8c45fSAndroid Build Coastguard Worker     }
572*38e8c45fSAndroid Build Coastguard Worker 
573*38e8c45fSAndroid Build Coastguard Worker     // Motion sensor enabled devices.
574*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::SENSOR)) {
575*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<SensorInputMapper>(contextPtr, readerConfig));
576*38e8c45fSAndroid Build Coastguard Worker     }
577*38e8c45fSAndroid Build Coastguard Worker 
578*38e8c45fSAndroid Build Coastguard Worker     // External stylus-like devices.
579*38e8c45fSAndroid Build Coastguard Worker     if (classes.test(InputDeviceClass::EXTERNAL_STYLUS)) {
580*38e8c45fSAndroid Build Coastguard Worker         mappers.push_back(createInputMapper<ExternalStylusInputMapper>(contextPtr, readerConfig));
581*38e8c45fSAndroid Build Coastguard Worker     }
582*38e8c45fSAndroid Build Coastguard Worker     return mappers;
583*38e8c45fSAndroid Build Coastguard Worker }
584*38e8c45fSAndroid Build Coastguard Worker 
markSupportedKeyCodes(uint32_t sourceMask,const std::vector<int32_t> & keyCodes,uint8_t * outFlags)585*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
586*38e8c45fSAndroid Build Coastguard Worker                                         uint8_t* outFlags) {
587*38e8c45fSAndroid Build Coastguard Worker     bool result = false;
588*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&result, sourceMask, keyCodes, outFlags](InputMapper& mapper) {
589*38e8c45fSAndroid Build Coastguard Worker         if (sourcesMatchMask(mapper.getSources(), sourceMask)) {
590*38e8c45fSAndroid Build Coastguard Worker             result |= mapper.markSupportedKeyCodes(sourceMask, keyCodes, outFlags);
591*38e8c45fSAndroid Build Coastguard Worker         }
592*38e8c45fSAndroid Build Coastguard Worker     });
593*38e8c45fSAndroid Build Coastguard Worker     return result;
594*38e8c45fSAndroid Build Coastguard Worker }
595*38e8c45fSAndroid Build Coastguard Worker 
getKeyCodeForKeyLocation(int32_t locationKeyCode) const596*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getKeyCodeForKeyLocation(int32_t locationKeyCode) const {
597*38e8c45fSAndroid Build Coastguard Worker     std::optional<int32_t> result = first_in_mappers<int32_t>(
598*38e8c45fSAndroid Build Coastguard Worker             [locationKeyCode](const InputMapper& mapper) -> std::optional<int32_t> const {
599*38e8c45fSAndroid Build Coastguard Worker                 if (sourcesMatchMask(mapper.getSources(), AINPUT_SOURCE_KEYBOARD)) {
600*38e8c45fSAndroid Build Coastguard Worker                     return std::make_optional(mapper.getKeyCodeForKeyLocation(locationKeyCode));
601*38e8c45fSAndroid Build Coastguard Worker                 }
602*38e8c45fSAndroid Build Coastguard Worker                 return std::nullopt;
603*38e8c45fSAndroid Build Coastguard Worker             });
604*38e8c45fSAndroid Build Coastguard Worker     if (!result) {
605*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Failed to get key code for key location: No matching InputMapper with source mask "
606*38e8c45fSAndroid Build Coastguard Worker               "KEYBOARD found. The provided input device with id %d has sources %s.",
607*38e8c45fSAndroid Build Coastguard Worker               getId(), inputEventSourceToString(getSources()).c_str());
608*38e8c45fSAndroid Build Coastguard Worker         return AKEYCODE_UNKNOWN;
609*38e8c45fSAndroid Build Coastguard Worker     }
610*38e8c45fSAndroid Build Coastguard Worker     return *result;
611*38e8c45fSAndroid Build Coastguard Worker }
612*38e8c45fSAndroid Build Coastguard Worker 
vibrate(const VibrationSequence & sequence,ssize_t repeat,int32_t token)613*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat,
614*38e8c45fSAndroid Build Coastguard Worker                                            int32_t token) {
615*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
616*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.vibrate(sequence, repeat, token); });
617*38e8c45fSAndroid Build Coastguard Worker     return out;
618*38e8c45fSAndroid Build Coastguard Worker }
619*38e8c45fSAndroid Build Coastguard Worker 
cancelVibrate(int32_t token)620*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::cancelVibrate(int32_t token) {
621*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
622*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelVibrate(token); });
623*38e8c45fSAndroid Build Coastguard Worker     return out;
624*38e8c45fSAndroid Build Coastguard Worker }
625*38e8c45fSAndroid Build Coastguard Worker 
isVibrating()626*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::isVibrating() {
627*38e8c45fSAndroid Build Coastguard Worker     bool vibrating = false;
628*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); });
629*38e8c45fSAndroid Build Coastguard Worker     return vibrating;
630*38e8c45fSAndroid Build Coastguard Worker }
631*38e8c45fSAndroid Build Coastguard Worker 
632*38e8c45fSAndroid Build Coastguard Worker /* There's no guarantee the IDs provided by the different mappers are unique, so if we have two
633*38e8c45fSAndroid Build Coastguard Worker  * different vibration mappers then we could have duplicate IDs.
634*38e8c45fSAndroid Build Coastguard Worker  * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities,
635*38e8c45fSAndroid Build Coastguard Worker  * we would definitely have duplicate IDs.
636*38e8c45fSAndroid Build Coastguard Worker  */
getVibratorIds()637*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> InputDevice::getVibratorIds() {
638*38e8c45fSAndroid Build Coastguard Worker     std::vector<int32_t> vibrators;
639*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&vibrators](InputMapper& mapper) {
640*38e8c45fSAndroid Build Coastguard Worker         std::vector<int32_t> devVibs = mapper.getVibratorIds();
641*38e8c45fSAndroid Build Coastguard Worker         vibrators.reserve(vibrators.size() + devVibs.size());
642*38e8c45fSAndroid Build Coastguard Worker         vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end());
643*38e8c45fSAndroid Build Coastguard Worker     });
644*38e8c45fSAndroid Build Coastguard Worker     return vibrators;
645*38e8c45fSAndroid Build Coastguard Worker }
646*38e8c45fSAndroid Build Coastguard Worker 
enableSensor(InputDeviceSensorType sensorType,std::chrono::microseconds samplingPeriod,std::chrono::microseconds maxBatchReportLatency)647*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::enableSensor(InputDeviceSensorType sensorType,
648*38e8c45fSAndroid Build Coastguard Worker                                std::chrono::microseconds samplingPeriod,
649*38e8c45fSAndroid Build Coastguard Worker                                std::chrono::microseconds maxBatchReportLatency) {
650*38e8c45fSAndroid Build Coastguard Worker     bool success = true;
651*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper(
652*38e8c45fSAndroid Build Coastguard Worker             [&success, sensorType, samplingPeriod, maxBatchReportLatency](InputMapper& mapper) {
653*38e8c45fSAndroid Build Coastguard Worker                 success &= mapper.enableSensor(sensorType, samplingPeriod, maxBatchReportLatency);
654*38e8c45fSAndroid Build Coastguard Worker             });
655*38e8c45fSAndroid Build Coastguard Worker     return success;
656*38e8c45fSAndroid Build Coastguard Worker }
657*38e8c45fSAndroid Build Coastguard Worker 
disableSensor(InputDeviceSensorType sensorType)658*38e8c45fSAndroid Build Coastguard Worker void InputDevice::disableSensor(InputDeviceSensorType sensorType) {
659*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([sensorType](InputMapper& mapper) { mapper.disableSensor(sensorType); });
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker 
flushSensor(InputDeviceSensorType sensorType)662*38e8c45fSAndroid Build Coastguard Worker void InputDevice::flushSensor(InputDeviceSensorType sensorType) {
663*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); });
664*38e8c45fSAndroid Build Coastguard Worker }
665*38e8c45fSAndroid Build Coastguard Worker 
cancelTouch(nsecs_t when,nsecs_t readTime)666*38e8c45fSAndroid Build Coastguard Worker std::list<NotifyArgs> InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) {
667*38e8c45fSAndroid Build Coastguard Worker     std::list<NotifyArgs> out;
668*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelTouch(when, readTime); });
669*38e8c45fSAndroid Build Coastguard Worker     return out;
670*38e8c45fSAndroid Build Coastguard Worker }
671*38e8c45fSAndroid Build Coastguard Worker 
setLightColor(int32_t lightId,int32_t color)672*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::setLightColor(int32_t lightId, int32_t color) {
673*38e8c45fSAndroid Build Coastguard Worker     return mController ? mController->setLightColor(lightId, color) : false;
674*38e8c45fSAndroid Build Coastguard Worker }
675*38e8c45fSAndroid Build Coastguard Worker 
setLightPlayerId(int32_t lightId,int32_t playerId)676*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::setLightPlayerId(int32_t lightId, int32_t playerId) {
677*38e8c45fSAndroid Build Coastguard Worker     return mController ? mController->setLightPlayerId(lightId, playerId) : false;
678*38e8c45fSAndroid Build Coastguard Worker }
679*38e8c45fSAndroid Build Coastguard Worker 
getLightColor(int32_t lightId)680*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> InputDevice::getLightColor(int32_t lightId) {
681*38e8c45fSAndroid Build Coastguard Worker     return mController ? mController->getLightColor(lightId) : std::nullopt;
682*38e8c45fSAndroid Build Coastguard Worker }
683*38e8c45fSAndroid Build Coastguard Worker 
getLightPlayerId(int32_t lightId)684*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> InputDevice::getLightPlayerId(int32_t lightId) {
685*38e8c45fSAndroid Build Coastguard Worker     return mController ? mController->getLightPlayerId(lightId) : std::nullopt;
686*38e8c45fSAndroid Build Coastguard Worker }
687*38e8c45fSAndroid Build Coastguard Worker 
getMetaState()688*38e8c45fSAndroid Build Coastguard Worker int32_t InputDevice::getMetaState() {
689*38e8c45fSAndroid Build Coastguard Worker     int32_t result = 0;
690*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); });
691*38e8c45fSAndroid Build Coastguard Worker     return result;
692*38e8c45fSAndroid Build Coastguard Worker }
693*38e8c45fSAndroid Build Coastguard Worker 
bumpGeneration()694*38e8c45fSAndroid Build Coastguard Worker void InputDevice::bumpGeneration() {
695*38e8c45fSAndroid Build Coastguard Worker     mGeneration = mContext->bumpGeneration();
696*38e8c45fSAndroid Build Coastguard Worker }
697*38e8c45fSAndroid Build Coastguard Worker 
notifyReset(nsecs_t when)698*38e8c45fSAndroid Build Coastguard Worker NotifyDeviceResetArgs InputDevice::notifyReset(nsecs_t when) {
699*38e8c45fSAndroid Build Coastguard Worker     return NotifyDeviceResetArgs(mContext->getNextId(), when, mId);
700*38e8c45fSAndroid Build Coastguard Worker }
701*38e8c45fSAndroid Build Coastguard Worker 
getAssociatedDisplayId()702*38e8c45fSAndroid Build Coastguard Worker std::optional<ui::LogicalDisplayId> InputDevice::getAssociatedDisplayId() {
703*38e8c45fSAndroid Build Coastguard Worker     // Check if we had associated to the specific display.
704*38e8c45fSAndroid Build Coastguard Worker     if (mAssociatedViewport) {
705*38e8c45fSAndroid Build Coastguard Worker         return mAssociatedViewport->displayId;
706*38e8c45fSAndroid Build Coastguard Worker     }
707*38e8c45fSAndroid Build Coastguard Worker 
708*38e8c45fSAndroid Build Coastguard Worker     // No associated display port, check if some InputMapper is associated.
709*38e8c45fSAndroid Build Coastguard Worker     return first_in_mappers<ui::LogicalDisplayId>(
710*38e8c45fSAndroid Build Coastguard Worker             [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
711*38e8c45fSAndroid Build Coastguard Worker }
712*38e8c45fSAndroid Build Coastguard Worker 
713*38e8c45fSAndroid Build Coastguard Worker // returns the number of mappers associated with the device
getMapperCount()714*38e8c45fSAndroid Build Coastguard Worker size_t InputDevice::getMapperCount() {
715*38e8c45fSAndroid Build Coastguard Worker     size_t count = 0;
716*38e8c45fSAndroid Build Coastguard Worker     for (auto& deviceEntry : mDevices) {
717*38e8c45fSAndroid Build Coastguard Worker         auto& devicePair = deviceEntry.second;
718*38e8c45fSAndroid Build Coastguard Worker         auto& mappers = devicePair.second;
719*38e8c45fSAndroid Build Coastguard Worker         count += mappers.size();
720*38e8c45fSAndroid Build Coastguard Worker     }
721*38e8c45fSAndroid Build Coastguard Worker     return count;
722*38e8c45fSAndroid Build Coastguard Worker }
723*38e8c45fSAndroid Build Coastguard Worker 
getTouchpadHardwareProperties()724*38e8c45fSAndroid Build Coastguard Worker std::optional<HardwareProperties> InputDevice::getTouchpadHardwareProperties() {
725*38e8c45fSAndroid Build Coastguard Worker     std::optional<HardwareProperties> result = first_in_mappers<HardwareProperties>(
726*38e8c45fSAndroid Build Coastguard Worker             [](InputMapper& mapper) -> std::optional<HardwareProperties> {
727*38e8c45fSAndroid Build Coastguard Worker                 return mapper.getTouchpadHardwareProperties();
728*38e8c45fSAndroid Build Coastguard Worker             });
729*38e8c45fSAndroid Build Coastguard Worker 
730*38e8c45fSAndroid Build Coastguard Worker     return result;
731*38e8c45fSAndroid Build Coastguard Worker }
732*38e8c45fSAndroid Build Coastguard Worker 
updateLedState(bool reset)733*38e8c45fSAndroid Build Coastguard Worker void InputDevice::updateLedState(bool reset) {
734*38e8c45fSAndroid Build Coastguard Worker     for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); });
735*38e8c45fSAndroid Build Coastguard Worker }
736*38e8c45fSAndroid Build Coastguard Worker 
getBatteryEventHubId() const737*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> InputDevice::getBatteryEventHubId() const {
738*38e8c45fSAndroid Build Coastguard Worker     return mController ? std::make_optional(mController->getEventHubId()) : std::nullopt;
739*38e8c45fSAndroid Build Coastguard Worker }
740*38e8c45fSAndroid Build Coastguard Worker 
setKeyboardType(KeyboardType keyboardType)741*38e8c45fSAndroid Build Coastguard Worker void InputDevice::setKeyboardType(KeyboardType keyboardType) {
742*38e8c45fSAndroid Build Coastguard Worker     if (mKeyboardType != keyboardType) {
743*38e8c45fSAndroid Build Coastguard Worker         mKeyboardType = keyboardType;
744*38e8c45fSAndroid Build Coastguard Worker         bumpGeneration();
745*38e8c45fSAndroid Build Coastguard Worker     }
746*38e8c45fSAndroid Build Coastguard Worker }
747*38e8c45fSAndroid Build Coastguard Worker 
setKernelWakeEnabled(bool enabled)748*38e8c45fSAndroid Build Coastguard Worker bool InputDevice::setKernelWakeEnabled(bool enabled) {
749*38e8c45fSAndroid Build Coastguard Worker     bool success = false;
750*38e8c45fSAndroid Build Coastguard Worker     for_each_subdevice([&enabled, &success](InputDeviceContext& context) {
751*38e8c45fSAndroid Build Coastguard Worker         success |= context.setKernelWakeEnabled(enabled);
752*38e8c45fSAndroid Build Coastguard Worker     });
753*38e8c45fSAndroid Build Coastguard Worker     return success;
754*38e8c45fSAndroid Build Coastguard Worker }
755*38e8c45fSAndroid Build Coastguard Worker 
InputDeviceContext(InputDevice & device,int32_t eventHubId)756*38e8c45fSAndroid Build Coastguard Worker InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId)
757*38e8c45fSAndroid Build Coastguard Worker       : mDevice(device),
758*38e8c45fSAndroid Build Coastguard Worker         mContext(device.getContext()),
759*38e8c45fSAndroid Build Coastguard Worker         mEventHub(device.getContext()->getEventHub()),
760*38e8c45fSAndroid Build Coastguard Worker         mId(eventHubId),
761*38e8c45fSAndroid Build Coastguard Worker         mDeviceId(device.getId()) {}
762*38e8c45fSAndroid Build Coastguard Worker 
~InputDeviceContext()763*38e8c45fSAndroid Build Coastguard Worker InputDeviceContext::~InputDeviceContext() {}
764*38e8c45fSAndroid Build Coastguard Worker 
765*38e8c45fSAndroid Build Coastguard Worker } // namespace android
766