xref: /aosp_15_r20/frameworks/native/services/inputflinger/tests/FakeEventHub.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2022 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 "FakeEventHub.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <optional>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <linux/input-event-codes.h>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include "TestConstants.h"
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker namespace android {
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker const std::string FakeEventHub::BATTERY_DEVPATH = "/sys/devices/mydevice/power_supply/mybattery";
30*38e8c45fSAndroid Build Coastguard Worker 
~FakeEventHub()31*38e8c45fSAndroid Build Coastguard Worker FakeEventHub::~FakeEventHub() {
32*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < mDevices.size(); i++) {
33*38e8c45fSAndroid Build Coastguard Worker         delete mDevices.valueAt(i);
34*38e8c45fSAndroid Build Coastguard Worker     }
35*38e8c45fSAndroid Build Coastguard Worker }
36*38e8c45fSAndroid Build Coastguard Worker 
addDevice(int32_t deviceId,const std::string & name,ftl::Flags<InputDeviceClass> classes,int bus)37*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addDevice(int32_t deviceId, const std::string& name,
38*38e8c45fSAndroid Build Coastguard Worker                              ftl::Flags<InputDeviceClass> classes, int bus) {
39*38e8c45fSAndroid Build Coastguard Worker     Device* device = new Device(classes);
40*38e8c45fSAndroid Build Coastguard Worker     device->identifier.name = name;
41*38e8c45fSAndroid Build Coastguard Worker     device->identifier.bus = bus;
42*38e8c45fSAndroid Build Coastguard Worker     mDevices.add(deviceId, device);
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker     enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
45*38e8c45fSAndroid Build Coastguard Worker }
46*38e8c45fSAndroid Build Coastguard Worker 
removeDevice(int32_t deviceId)47*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::removeDevice(int32_t deviceId) {
48*38e8c45fSAndroid Build Coastguard Worker     delete mDevices.valueFor(deviceId);
49*38e8c45fSAndroid Build Coastguard Worker     mDevices.removeItem(deviceId);
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker     enqueueEvent(ARBITRARY_TIME, READ_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
52*38e8c45fSAndroid Build Coastguard Worker }
53*38e8c45fSAndroid Build Coastguard Worker 
isDeviceEnabled(int32_t deviceId) const54*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::isDeviceEnabled(int32_t deviceId) const {
55*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
56*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
57*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
58*38e8c45fSAndroid Build Coastguard Worker         return false;
59*38e8c45fSAndroid Build Coastguard Worker     }
60*38e8c45fSAndroid Build Coastguard Worker     return device->enabled;
61*38e8c45fSAndroid Build Coastguard Worker }
62*38e8c45fSAndroid Build Coastguard Worker 
enableDevice(int32_t deviceId)63*38e8c45fSAndroid Build Coastguard Worker status_t FakeEventHub::enableDevice(int32_t deviceId) {
64*38e8c45fSAndroid Build Coastguard Worker     status_t result;
65*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
66*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
67*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
68*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
69*38e8c45fSAndroid Build Coastguard Worker     }
70*38e8c45fSAndroid Build Coastguard Worker     if (device->enabled) {
71*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Duplicate call to %s, device %" PRId32 " already enabled", __func__, deviceId);
72*38e8c45fSAndroid Build Coastguard Worker         return OK;
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker     result = device->enable();
75*38e8c45fSAndroid Build Coastguard Worker     return result;
76*38e8c45fSAndroid Build Coastguard Worker }
77*38e8c45fSAndroid Build Coastguard Worker 
disableDevice(int32_t deviceId)78*38e8c45fSAndroid Build Coastguard Worker status_t FakeEventHub::disableDevice(int32_t deviceId) {
79*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
80*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
81*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Incorrect device id=%" PRId32 " provided to %s", deviceId, __func__);
82*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
83*38e8c45fSAndroid Build Coastguard Worker     }
84*38e8c45fSAndroid Build Coastguard Worker     if (!device->enabled) {
85*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Duplicate call to %s, device %" PRId32 " already disabled", __func__, deviceId);
86*38e8c45fSAndroid Build Coastguard Worker         return OK;
87*38e8c45fSAndroid Build Coastguard Worker     }
88*38e8c45fSAndroid Build Coastguard Worker     return device->disable();
89*38e8c45fSAndroid Build Coastguard Worker }
90*38e8c45fSAndroid Build Coastguard Worker 
addConfigurationProperty(int32_t deviceId,const char * key,const char * value)91*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addConfigurationProperty(int32_t deviceId, const char* key, const char* value) {
92*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->configuration.addProperty(key, value);
93*38e8c45fSAndroid Build Coastguard Worker }
94*38e8c45fSAndroid Build Coastguard Worker 
addConfigurationMap(int32_t deviceId,const PropertyMap * configuration)95*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
96*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->configuration.addAll(configuration);
97*38e8c45fSAndroid Build Coastguard Worker }
98*38e8c45fSAndroid Build Coastguard Worker 
addAbsoluteAxis(int32_t deviceId,int axis,int32_t minValue,int32_t maxValue,int flat,int fuzz,int resolution)99*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addAbsoluteAxis(int32_t deviceId, int axis, int32_t minValue, int32_t maxValue,
100*38e8c45fSAndroid Build Coastguard Worker                                    int flat, int fuzz, int resolution) {
101*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker     RawAbsoluteAxisInfo info;
104*38e8c45fSAndroid Build Coastguard Worker     info.minValue = minValue;
105*38e8c45fSAndroid Build Coastguard Worker     info.maxValue = maxValue;
106*38e8c45fSAndroid Build Coastguard Worker     info.flat = flat;
107*38e8c45fSAndroid Build Coastguard Worker     info.fuzz = fuzz;
108*38e8c45fSAndroid Build Coastguard Worker     info.resolution = resolution;
109*38e8c45fSAndroid Build Coastguard Worker     device->absoluteAxes.add(axis, info);
110*38e8c45fSAndroid Build Coastguard Worker }
111*38e8c45fSAndroid Build Coastguard Worker 
addRelativeAxis(int32_t deviceId,int32_t axis)112*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addRelativeAxis(int32_t deviceId, int32_t axis) {
113*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->relativeAxes.add(axis, true);
114*38e8c45fSAndroid Build Coastguard Worker }
115*38e8c45fSAndroid Build Coastguard Worker 
setKeyCodeState(int32_t deviceId,int32_t keyCode,int32_t state)116*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
117*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->keyCodeStates.replaceValueFor(keyCode, state);
118*38e8c45fSAndroid Build Coastguard Worker }
119*38e8c45fSAndroid Build Coastguard Worker 
setRawLayoutInfo(int32_t deviceId,RawLayoutInfo info)120*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setRawLayoutInfo(int32_t deviceId, RawLayoutInfo info) {
121*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->layoutInfo = info;
122*38e8c45fSAndroid Build Coastguard Worker }
123*38e8c45fSAndroid Build Coastguard Worker 
setScanCodeState(int32_t deviceId,int32_t scanCode,int32_t state)124*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
125*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->scanCodeStates.replaceValueFor(scanCode, state);
126*38e8c45fSAndroid Build Coastguard Worker }
127*38e8c45fSAndroid Build Coastguard Worker 
setSwitchState(int32_t deviceId,int32_t switchCode,int32_t state)128*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
129*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->switchStates.replaceValueFor(switchCode, state);
130*38e8c45fSAndroid Build Coastguard Worker }
131*38e8c45fSAndroid Build Coastguard Worker 
setAbsoluteAxisValue(int32_t deviceId,int32_t axis,int32_t value)132*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
133*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->absoluteAxisValue.replaceValueFor(axis, value);
134*38e8c45fSAndroid Build Coastguard Worker }
135*38e8c45fSAndroid Build Coastguard Worker 
addKey(int32_t deviceId,int32_t scanCode,int32_t usageCode,int32_t keyCode,uint32_t flags)136*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t keyCode,
137*38e8c45fSAndroid Build Coastguard Worker                           uint32_t flags) {
138*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
139*38e8c45fSAndroid Build Coastguard Worker     KeyInfo info;
140*38e8c45fSAndroid Build Coastguard Worker     info.keyCode = keyCode;
141*38e8c45fSAndroid Build Coastguard Worker     info.flags = flags;
142*38e8c45fSAndroid Build Coastguard Worker     if (scanCode) {
143*38e8c45fSAndroid Build Coastguard Worker         device->keysByScanCode.add(scanCode, info);
144*38e8c45fSAndroid Build Coastguard Worker     }
145*38e8c45fSAndroid Build Coastguard Worker     if (usageCode) {
146*38e8c45fSAndroid Build Coastguard Worker         device->keysByUsageCode.add(usageCode, info);
147*38e8c45fSAndroid Build Coastguard Worker     }
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker 
addKeyCodeMapping(int32_t deviceId,int32_t fromKeyCode,int32_t toKeyCode)150*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addKeyCodeMapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) {
151*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->keyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
152*38e8c45fSAndroid Build Coastguard Worker }
153*38e8c45fSAndroid Build Coastguard Worker 
setKeyRemapping(int32_t deviceId,const std::map<int32_t,int32_t> & keyRemapping) const154*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setKeyRemapping(int32_t deviceId,
155*38e8c45fSAndroid Build Coastguard Worker                                    const std::map<int32_t, int32_t>& keyRemapping) const {
156*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
157*38e8c45fSAndroid Build Coastguard Worker     device->keyRemapping = keyRemapping;
158*38e8c45fSAndroid Build Coastguard Worker }
159*38e8c45fSAndroid Build Coastguard Worker 
addLed(int32_t deviceId,int32_t led,bool initialState)160*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addLed(int32_t deviceId, int32_t led, bool initialState) {
161*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->leds.add(led, initialState);
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker 
addSensorAxis(int32_t deviceId,int32_t absCode,InputDeviceSensorType sensorType,int32_t sensorDataIndex)164*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addSensorAxis(int32_t deviceId, int32_t absCode,
165*38e8c45fSAndroid Build Coastguard Worker                                  InputDeviceSensorType sensorType, int32_t sensorDataIndex) {
166*38e8c45fSAndroid Build Coastguard Worker     SensorInfo info;
167*38e8c45fSAndroid Build Coastguard Worker     info.sensorType = sensorType;
168*38e8c45fSAndroid Build Coastguard Worker     info.sensorDataIndex = sensorDataIndex;
169*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->sensorsByAbsCode.emplace(absCode, info);
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker 
setMscEvent(int32_t deviceId,int32_t mscEvent)172*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setMscEvent(int32_t deviceId, int32_t mscEvent) {
173*38e8c45fSAndroid Build Coastguard Worker     typename BitArray<MSC_MAX>::Buffer buffer;
174*38e8c45fSAndroid Build Coastguard Worker     buffer[mscEvent / 32] = 1 << mscEvent % 32;
175*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->mscBitmask.loadFromBuffer(buffer);
176*38e8c45fSAndroid Build Coastguard Worker }
177*38e8c45fSAndroid Build Coastguard Worker 
addRawLightInfo(int32_t rawId,RawLightInfo && info)178*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addRawLightInfo(int32_t rawId, RawLightInfo&& info) {
179*38e8c45fSAndroid Build Coastguard Worker     mRawLightInfos.emplace(rawId, std::move(info));
180*38e8c45fSAndroid Build Coastguard Worker }
181*38e8c45fSAndroid Build Coastguard Worker 
fakeLightBrightness(int32_t rawId,int32_t brightness)182*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::fakeLightBrightness(int32_t rawId, int32_t brightness) {
183*38e8c45fSAndroid Build Coastguard Worker     mLightBrightness.emplace(rawId, brightness);
184*38e8c45fSAndroid Build Coastguard Worker }
185*38e8c45fSAndroid Build Coastguard Worker 
fakeLightIntensities(int32_t rawId,const std::unordered_map<LightColor,int32_t> intensities)186*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::fakeLightIntensities(int32_t rawId,
187*38e8c45fSAndroid Build Coastguard Worker                                         const std::unordered_map<LightColor, int32_t> intensities) {
188*38e8c45fSAndroid Build Coastguard Worker     mLightIntensities.emplace(rawId, std::move(intensities));
189*38e8c45fSAndroid Build Coastguard Worker }
190*38e8c45fSAndroid Build Coastguard Worker 
getLedState(int32_t deviceId,int32_t led)191*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::getLedState(int32_t deviceId, int32_t led) {
192*38e8c45fSAndroid Build Coastguard Worker     return getDevice(deviceId)->leds.valueFor(led);
193*38e8c45fSAndroid Build Coastguard Worker }
194*38e8c45fSAndroid Build Coastguard Worker 
getExcludedDevices()195*38e8c45fSAndroid Build Coastguard Worker std::vector<std::string>& FakeEventHub::getExcludedDevices() {
196*38e8c45fSAndroid Build Coastguard Worker     return mExcludedDevices;
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker 
addVirtualKeyDefinition(int32_t deviceId,const VirtualKeyDefinition & definition)199*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::addVirtualKeyDefinition(int32_t deviceId,
200*38e8c45fSAndroid Build Coastguard Worker                                            const VirtualKeyDefinition& definition) {
201*38e8c45fSAndroid Build Coastguard Worker     getDevice(deviceId)->virtualKeys.push_back(definition);
202*38e8c45fSAndroid Build Coastguard Worker }
203*38e8c45fSAndroid Build Coastguard Worker 
enqueueEvent(nsecs_t when,nsecs_t readTime,int32_t deviceId,int32_t type,int32_t code,int32_t value)204*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::enqueueEvent(nsecs_t when, nsecs_t readTime, int32_t deviceId, int32_t type,
205*38e8c45fSAndroid Build Coastguard Worker                                 int32_t code, int32_t value) {
206*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock<std::mutex> lock(mLock);
207*38e8c45fSAndroid Build Coastguard Worker     RawEvent event;
208*38e8c45fSAndroid Build Coastguard Worker     event.when = when;
209*38e8c45fSAndroid Build Coastguard Worker     event.readTime = readTime;
210*38e8c45fSAndroid Build Coastguard Worker     event.deviceId = deviceId;
211*38e8c45fSAndroid Build Coastguard Worker     event.type = type;
212*38e8c45fSAndroid Build Coastguard Worker     event.code = code;
213*38e8c45fSAndroid Build Coastguard Worker     event.value = value;
214*38e8c45fSAndroid Build Coastguard Worker     mEvents.push_back(event);
215*38e8c45fSAndroid Build Coastguard Worker 
216*38e8c45fSAndroid Build Coastguard Worker     if (type == EV_ABS) {
217*38e8c45fSAndroid Build Coastguard Worker         setAbsoluteAxisValue(deviceId, code, value);
218*38e8c45fSAndroid Build Coastguard Worker     }
219*38e8c45fSAndroid Build Coastguard Worker }
220*38e8c45fSAndroid Build Coastguard Worker 
setVideoFrames(std::unordered_map<int32_t,std::vector<TouchVideoFrame>> videoFrames)221*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setVideoFrames(
222*38e8c45fSAndroid Build Coastguard Worker         std::unordered_map<int32_t /*deviceId*/, std::vector<TouchVideoFrame>> videoFrames) {
223*38e8c45fSAndroid Build Coastguard Worker     mVideoFrames = std::move(videoFrames);
224*38e8c45fSAndroid Build Coastguard Worker }
225*38e8c45fSAndroid Build Coastguard Worker 
assertQueueIsEmpty()226*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::assertQueueIsEmpty() {
227*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mLock);
228*38e8c45fSAndroid Build Coastguard Worker     base::ScopedLockAssertion assumeLocked(mLock);
229*38e8c45fSAndroid Build Coastguard Worker     const bool queueIsEmpty =
230*38e8c45fSAndroid Build Coastguard Worker             mEventsCondition.wait_for(lock, WAIT_TIMEOUT,
231*38e8c45fSAndroid Build Coastguard Worker                                       [this]() REQUIRES(mLock) { return mEvents.size() == 0; });
232*38e8c45fSAndroid Build Coastguard Worker     if (!queueIsEmpty) {
233*38e8c45fSAndroid Build Coastguard Worker         FAIL() << "Timed out waiting for EventHub queue to be emptied.";
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker 
getDevice(int32_t deviceId) const237*38e8c45fSAndroid Build Coastguard Worker FakeEventHub::Device* FakeEventHub::getDevice(int32_t deviceId) const {
238*38e8c45fSAndroid Build Coastguard Worker     ssize_t index = mDevices.indexOfKey(deviceId);
239*38e8c45fSAndroid Build Coastguard Worker     return index >= 0 ? mDevices.valueAt(index) : nullptr;
240*38e8c45fSAndroid Build Coastguard Worker }
241*38e8c45fSAndroid Build Coastguard Worker 
getDeviceClasses(int32_t deviceId) const242*38e8c45fSAndroid Build Coastguard Worker ftl::Flags<InputDeviceClass> FakeEventHub::getDeviceClasses(int32_t deviceId) const {
243*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
244*38e8c45fSAndroid Build Coastguard Worker     return device ? device->classes : ftl::Flags<InputDeviceClass>(0);
245*38e8c45fSAndroid Build Coastguard Worker }
246*38e8c45fSAndroid Build Coastguard Worker 
getDeviceIdentifier(int32_t deviceId) const247*38e8c45fSAndroid Build Coastguard Worker InputDeviceIdentifier FakeEventHub::getDeviceIdentifier(int32_t deviceId) const {
248*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
249*38e8c45fSAndroid Build Coastguard Worker     return device ? device->identifier : InputDeviceIdentifier();
250*38e8c45fSAndroid Build Coastguard Worker }
251*38e8c45fSAndroid Build Coastguard Worker 
getDeviceControllerNumber(int32_t) const252*38e8c45fSAndroid Build Coastguard Worker int32_t FakeEventHub::getDeviceControllerNumber(int32_t) const {
253*38e8c45fSAndroid Build Coastguard Worker     return 0;
254*38e8c45fSAndroid Build Coastguard Worker }
255*38e8c45fSAndroid Build Coastguard Worker 
getConfiguration(int32_t deviceId) const256*38e8c45fSAndroid Build Coastguard Worker std::optional<PropertyMap> FakeEventHub::getConfiguration(int32_t deviceId) const {
257*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
258*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
259*38e8c45fSAndroid Build Coastguard Worker         return {};
260*38e8c45fSAndroid Build Coastguard Worker     }
261*38e8c45fSAndroid Build Coastguard Worker     return device->configuration;
262*38e8c45fSAndroid Build Coastguard Worker }
263*38e8c45fSAndroid Build Coastguard Worker 
getAbsoluteAxisInfo(int32_t deviceId,int axis) const264*38e8c45fSAndroid Build Coastguard Worker std::optional<RawAbsoluteAxisInfo> FakeEventHub::getAbsoluteAxisInfo(int32_t deviceId,
265*38e8c45fSAndroid Build Coastguard Worker                                                                      int axis) const {
266*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
267*38e8c45fSAndroid Build Coastguard Worker     if (device) {
268*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->absoluteAxes.indexOfKey(axis);
269*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
270*38e8c45fSAndroid Build Coastguard Worker             return device->absoluteAxes.valueAt(index);
271*38e8c45fSAndroid Build Coastguard Worker         }
272*38e8c45fSAndroid Build Coastguard Worker     }
273*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
274*38e8c45fSAndroid Build Coastguard Worker }
275*38e8c45fSAndroid Build Coastguard Worker 
hasRelativeAxis(int32_t deviceId,int axis) const276*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
277*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
278*38e8c45fSAndroid Build Coastguard Worker     if (device) {
279*38e8c45fSAndroid Build Coastguard Worker         return device->relativeAxes.indexOfKey(axis) >= 0;
280*38e8c45fSAndroid Build Coastguard Worker     }
281*38e8c45fSAndroid Build Coastguard Worker     return false;
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker 
hasInputProperty(int32_t,int) const284*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasInputProperty(int32_t, int) const {
285*38e8c45fSAndroid Build Coastguard Worker     return false;
286*38e8c45fSAndroid Build Coastguard Worker }
287*38e8c45fSAndroid Build Coastguard Worker 
hasMscEvent(int32_t deviceId,int mscEvent) const288*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasMscEvent(int32_t deviceId, int mscEvent) const {
289*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
290*38e8c45fSAndroid Build Coastguard Worker     if (device) {
291*38e8c45fSAndroid Build Coastguard Worker         return mscEvent >= 0 && mscEvent <= MSC_MAX ? device->mscBitmask.test(mscEvent) : false;
292*38e8c45fSAndroid Build Coastguard Worker     }
293*38e8c45fSAndroid Build Coastguard Worker     return false;
294*38e8c45fSAndroid Build Coastguard Worker }
295*38e8c45fSAndroid Build Coastguard Worker 
mapKey(int32_t deviceId,int32_t scanCode,int32_t usageCode,int32_t metaState,int32_t * outKeycode,int32_t * outMetaState,uint32_t * outFlags) const296*38e8c45fSAndroid Build Coastguard Worker status_t FakeEventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
297*38e8c45fSAndroid Build Coastguard Worker                               int32_t metaState, int32_t* outKeycode, int32_t* outMetaState,
298*38e8c45fSAndroid Build Coastguard Worker                               uint32_t* outFlags) const {
299*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
300*38e8c45fSAndroid Build Coastguard Worker     if (device) {
301*38e8c45fSAndroid Build Coastguard Worker         const KeyInfo* key = getKey(device, scanCode, usageCode);
302*38e8c45fSAndroid Build Coastguard Worker         if (key) {
303*38e8c45fSAndroid Build Coastguard Worker             if (outKeycode) {
304*38e8c45fSAndroid Build Coastguard Worker                 auto it = device->keyRemapping.find(key->keyCode);
305*38e8c45fSAndroid Build Coastguard Worker                 *outKeycode = it != device->keyRemapping.end() ? it->second : key->keyCode;
306*38e8c45fSAndroid Build Coastguard Worker             }
307*38e8c45fSAndroid Build Coastguard Worker             if (outFlags) {
308*38e8c45fSAndroid Build Coastguard Worker                 *outFlags = key->flags;
309*38e8c45fSAndroid Build Coastguard Worker             }
310*38e8c45fSAndroid Build Coastguard Worker             if (outMetaState) {
311*38e8c45fSAndroid Build Coastguard Worker                 *outMetaState = metaState;
312*38e8c45fSAndroid Build Coastguard Worker             }
313*38e8c45fSAndroid Build Coastguard Worker             return OK;
314*38e8c45fSAndroid Build Coastguard Worker         }
315*38e8c45fSAndroid Build Coastguard Worker     }
316*38e8c45fSAndroid Build Coastguard Worker     return NAME_NOT_FOUND;
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker 
getKey(Device * device,int32_t scanCode,int32_t usageCode) const319*38e8c45fSAndroid Build Coastguard Worker const FakeEventHub::KeyInfo* FakeEventHub::getKey(Device* device, int32_t scanCode,
320*38e8c45fSAndroid Build Coastguard Worker                                                   int32_t usageCode) const {
321*38e8c45fSAndroid Build Coastguard Worker     if (usageCode) {
322*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
323*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
324*38e8c45fSAndroid Build Coastguard Worker             return &device->keysByUsageCode.valueAt(index);
325*38e8c45fSAndroid Build Coastguard Worker         }
326*38e8c45fSAndroid Build Coastguard Worker     }
327*38e8c45fSAndroid Build Coastguard Worker     if (scanCode) {
328*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
329*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
330*38e8c45fSAndroid Build Coastguard Worker             return &device->keysByScanCode.valueAt(index);
331*38e8c45fSAndroid Build Coastguard Worker         }
332*38e8c45fSAndroid Build Coastguard Worker     }
333*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
334*38e8c45fSAndroid Build Coastguard Worker }
335*38e8c45fSAndroid Build Coastguard Worker 
mapAxis(int32_t,int32_t,AxisInfo *) const336*38e8c45fSAndroid Build Coastguard Worker status_t FakeEventHub::mapAxis(int32_t, int32_t, AxisInfo*) const {
337*38e8c45fSAndroid Build Coastguard Worker     return NAME_NOT_FOUND;
338*38e8c45fSAndroid Build Coastguard Worker }
339*38e8c45fSAndroid Build Coastguard Worker 
mapSensor(int32_t deviceId,int32_t absCode) const340*38e8c45fSAndroid Build Coastguard Worker base::Result<std::pair<InputDeviceSensorType, int32_t>> FakeEventHub::mapSensor(
341*38e8c45fSAndroid Build Coastguard Worker         int32_t deviceId, int32_t absCode) const {
342*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
343*38e8c45fSAndroid Build Coastguard Worker     if (!device) {
344*38e8c45fSAndroid Build Coastguard Worker         return Errorf("Sensor device not found.");
345*38e8c45fSAndroid Build Coastguard Worker     }
346*38e8c45fSAndroid Build Coastguard Worker     auto it = device->sensorsByAbsCode.find(absCode);
347*38e8c45fSAndroid Build Coastguard Worker     if (it == device->sensorsByAbsCode.end()) {
348*38e8c45fSAndroid Build Coastguard Worker         return Errorf("Sensor map not found.");
349*38e8c45fSAndroid Build Coastguard Worker     }
350*38e8c45fSAndroid Build Coastguard Worker     const SensorInfo& info = it->second;
351*38e8c45fSAndroid Build Coastguard Worker     return std::make_pair(info.sensorType, info.sensorDataIndex);
352*38e8c45fSAndroid Build Coastguard Worker }
353*38e8c45fSAndroid Build Coastguard Worker 
setExcludedDevices(const std::vector<std::string> & devices)354*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setExcludedDevices(const std::vector<std::string>& devices) {
355*38e8c45fSAndroid Build Coastguard Worker     mExcludedDevices = devices;
356*38e8c45fSAndroid Build Coastguard Worker }
357*38e8c45fSAndroid Build Coastguard Worker 
getEvents(int)358*38e8c45fSAndroid Build Coastguard Worker std::vector<RawEvent> FakeEventHub::getEvents(int) {
359*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock lock(mLock);
360*38e8c45fSAndroid Build Coastguard Worker 
361*38e8c45fSAndroid Build Coastguard Worker     std::vector<RawEvent> buffer;
362*38e8c45fSAndroid Build Coastguard Worker     std::swap(buffer, mEvents);
363*38e8c45fSAndroid Build Coastguard Worker 
364*38e8c45fSAndroid Build Coastguard Worker     mEventsCondition.notify_all();
365*38e8c45fSAndroid Build Coastguard Worker     return buffer;
366*38e8c45fSAndroid Build Coastguard Worker }
367*38e8c45fSAndroid Build Coastguard Worker 
getVideoFrames(int32_t deviceId)368*38e8c45fSAndroid Build Coastguard Worker std::vector<TouchVideoFrame> FakeEventHub::getVideoFrames(int32_t deviceId) {
369*38e8c45fSAndroid Build Coastguard Worker     auto it = mVideoFrames.find(deviceId);
370*38e8c45fSAndroid Build Coastguard Worker     if (it != mVideoFrames.end()) {
371*38e8c45fSAndroid Build Coastguard Worker         std::vector<TouchVideoFrame> frames = std::move(it->second);
372*38e8c45fSAndroid Build Coastguard Worker         mVideoFrames.erase(deviceId);
373*38e8c45fSAndroid Build Coastguard Worker         return frames;
374*38e8c45fSAndroid Build Coastguard Worker     }
375*38e8c45fSAndroid Build Coastguard Worker     return {};
376*38e8c45fSAndroid Build Coastguard Worker }
377*38e8c45fSAndroid Build Coastguard Worker 
getScanCodeState(int32_t deviceId,int32_t scanCode) const378*38e8c45fSAndroid Build Coastguard Worker int32_t FakeEventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
379*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
380*38e8c45fSAndroid Build Coastguard Worker     if (device) {
381*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
382*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
383*38e8c45fSAndroid Build Coastguard Worker             return device->scanCodeStates.valueAt(index);
384*38e8c45fSAndroid Build Coastguard Worker         }
385*38e8c45fSAndroid Build Coastguard Worker     }
386*38e8c45fSAndroid Build Coastguard Worker     return AKEY_STATE_UNKNOWN;
387*38e8c45fSAndroid Build Coastguard Worker }
388*38e8c45fSAndroid Build Coastguard Worker 
getRawLayoutInfo(int32_t deviceId) const389*38e8c45fSAndroid Build Coastguard Worker std::optional<RawLayoutInfo> FakeEventHub::getRawLayoutInfo(int32_t deviceId) const {
390*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
391*38e8c45fSAndroid Build Coastguard Worker     return device ? device->layoutInfo : std::nullopt;
392*38e8c45fSAndroid Build Coastguard Worker }
393*38e8c45fSAndroid Build Coastguard Worker 
getKeyCodeState(int32_t deviceId,int32_t keyCode) const394*38e8c45fSAndroid Build Coastguard Worker int32_t FakeEventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
395*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
396*38e8c45fSAndroid Build Coastguard Worker     if (device) {
397*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
398*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
399*38e8c45fSAndroid Build Coastguard Worker             return device->keyCodeStates.valueAt(index);
400*38e8c45fSAndroid Build Coastguard Worker         }
401*38e8c45fSAndroid Build Coastguard Worker     }
402*38e8c45fSAndroid Build Coastguard Worker     return AKEY_STATE_UNKNOWN;
403*38e8c45fSAndroid Build Coastguard Worker }
404*38e8c45fSAndroid Build Coastguard Worker 
getSwitchState(int32_t deviceId,int32_t sw) const405*38e8c45fSAndroid Build Coastguard Worker int32_t FakeEventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
406*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
407*38e8c45fSAndroid Build Coastguard Worker     if (device) {
408*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->switchStates.indexOfKey(sw);
409*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
410*38e8c45fSAndroid Build Coastguard Worker             return device->switchStates.valueAt(index);
411*38e8c45fSAndroid Build Coastguard Worker         }
412*38e8c45fSAndroid Build Coastguard Worker     }
413*38e8c45fSAndroid Build Coastguard Worker     return AKEY_STATE_UNKNOWN;
414*38e8c45fSAndroid Build Coastguard Worker }
415*38e8c45fSAndroid Build Coastguard Worker 
getAbsoluteAxisValue(int32_t deviceId,int32_t axis) const416*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> FakeEventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const {
417*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
418*38e8c45fSAndroid Build Coastguard Worker     if (device) {
419*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
420*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
421*38e8c45fSAndroid Build Coastguard Worker             return device->absoluteAxisValue.valueAt(index);
422*38e8c45fSAndroid Build Coastguard Worker         }
423*38e8c45fSAndroid Build Coastguard Worker     }
424*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
425*38e8c45fSAndroid Build Coastguard Worker }
426*38e8c45fSAndroid Build Coastguard Worker 
setMtSlotValues(int32_t deviceId,int32_t axis,const std::vector<int32_t> & values)427*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setMtSlotValues(int32_t deviceId, int32_t axis,
428*38e8c45fSAndroid Build Coastguard Worker                                    const std::vector<int32_t>& values) {
429*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
430*38e8c45fSAndroid Build Coastguard Worker     if (!device) {
431*38e8c45fSAndroid Build Coastguard Worker         FAIL() << "Missing device";
432*38e8c45fSAndroid Build Coastguard Worker     }
433*38e8c45fSAndroid Build Coastguard Worker     device->mtSlotValues[axis] = values;
434*38e8c45fSAndroid Build Coastguard Worker }
435*38e8c45fSAndroid Build Coastguard Worker 
getMtSlotValues(int32_t deviceId,int32_t axis,size_t slotCount) const436*38e8c45fSAndroid Build Coastguard Worker base::Result<std::vector<int32_t>> FakeEventHub::getMtSlotValues(int32_t deviceId, int32_t axis,
437*38e8c45fSAndroid Build Coastguard Worker                                                                  size_t slotCount) const {
438*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
439*38e8c45fSAndroid Build Coastguard Worker     if (!device) {
440*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Missing device";
441*38e8c45fSAndroid Build Coastguard Worker         return base::ResultError("Missing device", UNKNOWN_ERROR);
442*38e8c45fSAndroid Build Coastguard Worker     }
443*38e8c45fSAndroid Build Coastguard Worker     const auto& mtSlotValuesIterator = device->mtSlotValues.find(axis);
444*38e8c45fSAndroid Build Coastguard Worker     if (mtSlotValuesIterator == device->mtSlotValues.end()) {
445*38e8c45fSAndroid Build Coastguard Worker         return base::ResultError("axis not supported", NAME_NOT_FOUND);
446*38e8c45fSAndroid Build Coastguard Worker     }
447*38e8c45fSAndroid Build Coastguard Worker     const auto& mtSlotValues = mtSlotValuesIterator->second;
448*38e8c45fSAndroid Build Coastguard Worker     if (mtSlotValues.size() != slotCount) {
449*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "MtSlot values specified for " << mtSlotValues.size()
450*38e8c45fSAndroid Build Coastguard Worker                       << " slots but expected for " << slotCount << " Slots";
451*38e8c45fSAndroid Build Coastguard Worker         return base::ResultError("Slot count mismatch", NAME_NOT_FOUND);
452*38e8c45fSAndroid Build Coastguard Worker     }
453*38e8c45fSAndroid Build Coastguard Worker     std::vector<int32_t> outValues(slotCount + 1);
454*38e8c45fSAndroid Build Coastguard Worker     outValues[0] = axis;
455*38e8c45fSAndroid Build Coastguard Worker     std::copy(mtSlotValues.begin(), mtSlotValues.end(), outValues.begin() + 1);
456*38e8c45fSAndroid Build Coastguard Worker     return std::move(outValues);
457*38e8c45fSAndroid Build Coastguard Worker }
458*38e8c45fSAndroid Build Coastguard Worker 
getKeyCodeForKeyLocation(int32_t deviceId,int32_t locationKeyCode) const459*38e8c45fSAndroid Build Coastguard Worker int32_t FakeEventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const {
460*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
461*38e8c45fSAndroid Build Coastguard Worker     if (!device) {
462*38e8c45fSAndroid Build Coastguard Worker         return AKEYCODE_UNKNOWN;
463*38e8c45fSAndroid Build Coastguard Worker     }
464*38e8c45fSAndroid Build Coastguard Worker     auto it = device->keyCodeMapping.find(locationKeyCode);
465*38e8c45fSAndroid Build Coastguard Worker     return it != device->keyCodeMapping.end() ? it->second : locationKeyCode;
466*38e8c45fSAndroid Build Coastguard Worker }
467*38e8c45fSAndroid Build Coastguard Worker 
468*38e8c45fSAndroid Build Coastguard Worker // Return true if the device has non-empty key layout.
markSupportedKeyCodes(int32_t deviceId,const std::vector<int32_t> & keyCodes,uint8_t * outFlags) const469*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
470*38e8c45fSAndroid Build Coastguard Worker                                          uint8_t* outFlags) const {
471*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
472*38e8c45fSAndroid Build Coastguard Worker     if (!device) return false;
473*38e8c45fSAndroid Build Coastguard Worker 
474*38e8c45fSAndroid Build Coastguard Worker     bool result = device->keysByScanCode.size() > 0 || device->keysByUsageCode.size() > 0;
475*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < keyCodes.size(); i++) {
476*38e8c45fSAndroid Build Coastguard Worker         for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
477*38e8c45fSAndroid Build Coastguard Worker             if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
478*38e8c45fSAndroid Build Coastguard Worker                 outFlags[i] = 1;
479*38e8c45fSAndroid Build Coastguard Worker             }
480*38e8c45fSAndroid Build Coastguard Worker         }
481*38e8c45fSAndroid Build Coastguard Worker         for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
482*38e8c45fSAndroid Build Coastguard Worker             if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
483*38e8c45fSAndroid Build Coastguard Worker                 outFlags[i] = 1;
484*38e8c45fSAndroid Build Coastguard Worker             }
485*38e8c45fSAndroid Build Coastguard Worker         }
486*38e8c45fSAndroid Build Coastguard Worker     }
487*38e8c45fSAndroid Build Coastguard Worker     return result;
488*38e8c45fSAndroid Build Coastguard Worker }
489*38e8c45fSAndroid Build Coastguard Worker 
hasScanCode(int32_t deviceId,int32_t scanCode) const490*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const {
491*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
492*38e8c45fSAndroid Build Coastguard Worker     if (device) {
493*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
494*38e8c45fSAndroid Build Coastguard Worker         return index >= 0;
495*38e8c45fSAndroid Build Coastguard Worker     }
496*38e8c45fSAndroid Build Coastguard Worker     return false;
497*38e8c45fSAndroid Build Coastguard Worker }
498*38e8c45fSAndroid Build Coastguard Worker 
hasKeyCode(int32_t deviceId,int32_t keyCode) const499*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasKeyCode(int32_t deviceId, int32_t keyCode) const {
500*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
501*38e8c45fSAndroid Build Coastguard Worker     if (!device) {
502*38e8c45fSAndroid Build Coastguard Worker         return false;
503*38e8c45fSAndroid Build Coastguard Worker     }
504*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < device->keysByScanCode.size(); i++) {
505*38e8c45fSAndroid Build Coastguard Worker         if (keyCode == device->keysByScanCode.valueAt(i).keyCode) {
506*38e8c45fSAndroid Build Coastguard Worker             return true;
507*38e8c45fSAndroid Build Coastguard Worker         }
508*38e8c45fSAndroid Build Coastguard Worker     }
509*38e8c45fSAndroid Build Coastguard Worker     for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
510*38e8c45fSAndroid Build Coastguard Worker         if (keyCode == device->keysByUsageCode.valueAt(j).keyCode) {
511*38e8c45fSAndroid Build Coastguard Worker             return true;
512*38e8c45fSAndroid Build Coastguard Worker         }
513*38e8c45fSAndroid Build Coastguard Worker     }
514*38e8c45fSAndroid Build Coastguard Worker     return false;
515*38e8c45fSAndroid Build Coastguard Worker }
516*38e8c45fSAndroid Build Coastguard Worker 
hasLed(int32_t deviceId,int32_t led) const517*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::hasLed(int32_t deviceId, int32_t led) const {
518*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
519*38e8c45fSAndroid Build Coastguard Worker     return device && device->leds.indexOfKey(led) >= 0;
520*38e8c45fSAndroid Build Coastguard Worker }
521*38e8c45fSAndroid Build Coastguard Worker 
setLedState(int32_t deviceId,int32_t led,bool on)522*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
523*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
524*38e8c45fSAndroid Build Coastguard Worker     if (device) {
525*38e8c45fSAndroid Build Coastguard Worker         ssize_t index = device->leds.indexOfKey(led);
526*38e8c45fSAndroid Build Coastguard Worker         if (index >= 0) {
527*38e8c45fSAndroid Build Coastguard Worker             device->leds.replaceValueAt(led, on);
528*38e8c45fSAndroid Build Coastguard Worker         } else {
529*38e8c45fSAndroid Build Coastguard Worker             ADD_FAILURE() << "Attempted to set the state of an LED that the EventHub declared "
530*38e8c45fSAndroid Build Coastguard Worker                              "was not present.  led="
531*38e8c45fSAndroid Build Coastguard Worker                           << led;
532*38e8c45fSAndroid Build Coastguard Worker         }
533*38e8c45fSAndroid Build Coastguard Worker     }
534*38e8c45fSAndroid Build Coastguard Worker }
535*38e8c45fSAndroid Build Coastguard Worker 
getVirtualKeyDefinitions(int32_t deviceId,std::vector<VirtualKeyDefinition> & outVirtualKeys) const536*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::getVirtualKeyDefinitions(
537*38e8c45fSAndroid Build Coastguard Worker         int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
538*38e8c45fSAndroid Build Coastguard Worker     outVirtualKeys.clear();
539*38e8c45fSAndroid Build Coastguard Worker 
540*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
541*38e8c45fSAndroid Build Coastguard Worker     if (device) {
542*38e8c45fSAndroid Build Coastguard Worker         outVirtualKeys = device->virtualKeys;
543*38e8c45fSAndroid Build Coastguard Worker     }
544*38e8c45fSAndroid Build Coastguard Worker }
545*38e8c45fSAndroid Build Coastguard Worker 
getKeyCharacterMap(int32_t) const546*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<KeyCharacterMap> FakeEventHub::getKeyCharacterMap(int32_t) const {
547*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
548*38e8c45fSAndroid Build Coastguard Worker }
549*38e8c45fSAndroid Build Coastguard Worker 
setKeyboardLayoutOverlay(int32_t,std::shared_ptr<KeyCharacterMap>)550*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::setKeyboardLayoutOverlay(int32_t, std::shared_ptr<KeyCharacterMap>) {
551*38e8c45fSAndroid Build Coastguard Worker     return false;
552*38e8c45fSAndroid Build Coastguard Worker }
553*38e8c45fSAndroid Build Coastguard Worker 
getVibratorIds(int32_t deviceId) const554*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> FakeEventHub::getVibratorIds(int32_t deviceId) const {
555*38e8c45fSAndroid Build Coastguard Worker     return mVibrators;
556*38e8c45fSAndroid Build Coastguard Worker }
557*38e8c45fSAndroid Build Coastguard Worker 
getBatteryCapacity(int32_t,int32_t) const558*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> FakeEventHub::getBatteryCapacity(int32_t, int32_t) const {
559*38e8c45fSAndroid Build Coastguard Worker     return BATTERY_CAPACITY;
560*38e8c45fSAndroid Build Coastguard Worker }
561*38e8c45fSAndroid Build Coastguard Worker 
getBatteryStatus(int32_t,int32_t) const562*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> FakeEventHub::getBatteryStatus(int32_t, int32_t) const {
563*38e8c45fSAndroid Build Coastguard Worker     return BATTERY_STATUS;
564*38e8c45fSAndroid Build Coastguard Worker }
565*38e8c45fSAndroid Build Coastguard Worker 
getRawBatteryIds(int32_t deviceId) const566*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> FakeEventHub::getRawBatteryIds(int32_t deviceId) const {
567*38e8c45fSAndroid Build Coastguard Worker     return {DEFAULT_BATTERY};
568*38e8c45fSAndroid Build Coastguard Worker }
569*38e8c45fSAndroid Build Coastguard Worker 
getRawBatteryInfo(int32_t deviceId,int32_t batteryId) const570*38e8c45fSAndroid Build Coastguard Worker std::optional<RawBatteryInfo> FakeEventHub::getRawBatteryInfo(int32_t deviceId,
571*38e8c45fSAndroid Build Coastguard Worker                                                               int32_t batteryId) const {
572*38e8c45fSAndroid Build Coastguard Worker     if (batteryId != DEFAULT_BATTERY) return {};
573*38e8c45fSAndroid Build Coastguard Worker     static const auto BATTERY_INFO = RawBatteryInfo{.id = DEFAULT_BATTERY,
574*38e8c45fSAndroid Build Coastguard Worker                                                     .name = "default battery",
575*38e8c45fSAndroid Build Coastguard Worker                                                     .flags = InputBatteryClass::CAPACITY,
576*38e8c45fSAndroid Build Coastguard Worker                                                     .path = BATTERY_DEVPATH};
577*38e8c45fSAndroid Build Coastguard Worker     return BATTERY_INFO;
578*38e8c45fSAndroid Build Coastguard Worker }
579*38e8c45fSAndroid Build Coastguard Worker 
getRawLightIds(int32_t deviceId) const580*38e8c45fSAndroid Build Coastguard Worker std::vector<int32_t> FakeEventHub::getRawLightIds(int32_t deviceId) const {
581*38e8c45fSAndroid Build Coastguard Worker     std::vector<int32_t> ids;
582*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [rawId, info] : mRawLightInfos) {
583*38e8c45fSAndroid Build Coastguard Worker         ids.push_back(rawId);
584*38e8c45fSAndroid Build Coastguard Worker     }
585*38e8c45fSAndroid Build Coastguard Worker     return ids;
586*38e8c45fSAndroid Build Coastguard Worker }
587*38e8c45fSAndroid Build Coastguard Worker 
getRawLightInfo(int32_t deviceId,int32_t lightId) const588*38e8c45fSAndroid Build Coastguard Worker std::optional<RawLightInfo> FakeEventHub::getRawLightInfo(int32_t deviceId, int32_t lightId) const {
589*38e8c45fSAndroid Build Coastguard Worker     auto it = mRawLightInfos.find(lightId);
590*38e8c45fSAndroid Build Coastguard Worker     if (it == mRawLightInfos.end()) {
591*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
592*38e8c45fSAndroid Build Coastguard Worker     }
593*38e8c45fSAndroid Build Coastguard Worker     return it->second;
594*38e8c45fSAndroid Build Coastguard Worker }
595*38e8c45fSAndroid Build Coastguard Worker 
setLightBrightness(int32_t deviceId,int32_t lightId,int32_t brightness)596*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) {
597*38e8c45fSAndroid Build Coastguard Worker     mLightBrightness.emplace(lightId, brightness);
598*38e8c45fSAndroid Build Coastguard Worker }
599*38e8c45fSAndroid Build Coastguard Worker 
setLightIntensities(int32_t deviceId,int32_t lightId,std::unordered_map<LightColor,int32_t> intensities)600*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setLightIntensities(int32_t deviceId, int32_t lightId,
601*38e8c45fSAndroid Build Coastguard Worker                                        std::unordered_map<LightColor, int32_t> intensities) {
602*38e8c45fSAndroid Build Coastguard Worker     mLightIntensities.emplace(lightId, intensities);
603*38e8c45fSAndroid Build Coastguard Worker };
604*38e8c45fSAndroid Build Coastguard Worker 
getLightBrightness(int32_t deviceId,int32_t lightId) const605*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> FakeEventHub::getLightBrightness(int32_t deviceId, int32_t lightId) const {
606*38e8c45fSAndroid Build Coastguard Worker     auto lightIt = mLightBrightness.find(lightId);
607*38e8c45fSAndroid Build Coastguard Worker     if (lightIt == mLightBrightness.end()) {
608*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
609*38e8c45fSAndroid Build Coastguard Worker     }
610*38e8c45fSAndroid Build Coastguard Worker     return lightIt->second;
611*38e8c45fSAndroid Build Coastguard Worker }
612*38e8c45fSAndroid Build Coastguard Worker 
getLightIntensities(int32_t deviceId,int32_t lightId) const613*38e8c45fSAndroid Build Coastguard Worker std::optional<std::unordered_map<LightColor, int32_t>> FakeEventHub::getLightIntensities(
614*38e8c45fSAndroid Build Coastguard Worker         int32_t deviceId, int32_t lightId) const {
615*38e8c45fSAndroid Build Coastguard Worker     auto lightIt = mLightIntensities.find(lightId);
616*38e8c45fSAndroid Build Coastguard Worker     if (lightIt == mLightIntensities.end()) {
617*38e8c45fSAndroid Build Coastguard Worker         return std::nullopt;
618*38e8c45fSAndroid Build Coastguard Worker     }
619*38e8c45fSAndroid Build Coastguard Worker     return lightIt->second;
620*38e8c45fSAndroid Build Coastguard Worker };
621*38e8c45fSAndroid Build Coastguard Worker 
setSysfsRootPath(int32_t deviceId,std::string sysfsRootPath) const622*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::setSysfsRootPath(int32_t deviceId, std::string sysfsRootPath) const {
623*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
624*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
625*38e8c45fSAndroid Build Coastguard Worker         return;
626*38e8c45fSAndroid Build Coastguard Worker     }
627*38e8c45fSAndroid Build Coastguard Worker     device->sysfsRootPath = sysfsRootPath;
628*38e8c45fSAndroid Build Coastguard Worker }
629*38e8c45fSAndroid Build Coastguard Worker 
sysfsNodeChanged(const std::string & sysfsNodePath)630*38e8c45fSAndroid Build Coastguard Worker void FakeEventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
631*38e8c45fSAndroid Build Coastguard Worker     int32_t foundDeviceId = -1;
632*38e8c45fSAndroid Build Coastguard Worker     Device* foundDevice = nullptr;
633*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < mDevices.size(); i++) {
634*38e8c45fSAndroid Build Coastguard Worker         Device* d = mDevices.valueAt(i);
635*38e8c45fSAndroid Build Coastguard Worker         if (sysfsNodePath.find(d->sysfsRootPath) != std::string::npos) {
636*38e8c45fSAndroid Build Coastguard Worker             foundDeviceId = mDevices.keyAt(i);
637*38e8c45fSAndroid Build Coastguard Worker             foundDevice = d;
638*38e8c45fSAndroid Build Coastguard Worker         }
639*38e8c45fSAndroid Build Coastguard Worker     }
640*38e8c45fSAndroid Build Coastguard Worker     if (foundDevice == nullptr) {
641*38e8c45fSAndroid Build Coastguard Worker         return;
642*38e8c45fSAndroid Build Coastguard Worker     }
643*38e8c45fSAndroid Build Coastguard Worker     // If device sysfs changed -> reopen the device
644*38e8c45fSAndroid Build Coastguard Worker     if (!mRawLightInfos.empty() && !foundDevice->classes.test(InputDeviceClass::LIGHT)) {
645*38e8c45fSAndroid Build Coastguard Worker         InputDeviceIdentifier identifier = foundDevice->identifier;
646*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputDeviceClass> classes = foundDevice->classes;
647*38e8c45fSAndroid Build Coastguard Worker         removeDevice(foundDeviceId);
648*38e8c45fSAndroid Build Coastguard Worker         addDevice(foundDeviceId, identifier.name, classes | InputDeviceClass::LIGHT,
649*38e8c45fSAndroid Build Coastguard Worker                   identifier.bus);
650*38e8c45fSAndroid Build Coastguard Worker     }
651*38e8c45fSAndroid Build Coastguard Worker }
652*38e8c45fSAndroid Build Coastguard Worker 
setKernelWakeEnabled(int32_t deviceId,bool enabled)653*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::setKernelWakeEnabled(int32_t deviceId, bool enabled) {
654*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
655*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
656*38e8c45fSAndroid Build Coastguard Worker         return false;
657*38e8c45fSAndroid Build Coastguard Worker     }
658*38e8c45fSAndroid Build Coastguard Worker     mKernelWakeup.emplace(deviceId, enabled);
659*38e8c45fSAndroid Build Coastguard Worker     return true;
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker 
fakeReadKernelWakeup(int32_t deviceId) const662*38e8c45fSAndroid Build Coastguard Worker bool FakeEventHub::fakeReadKernelWakeup(int32_t deviceId) const {
663*38e8c45fSAndroid Build Coastguard Worker     Device* device = getDevice(deviceId);
664*38e8c45fSAndroid Build Coastguard Worker     if (device == nullptr) {
665*38e8c45fSAndroid Build Coastguard Worker         return false;
666*38e8c45fSAndroid Build Coastguard Worker     }
667*38e8c45fSAndroid Build Coastguard Worker     auto it = mKernelWakeup.find(deviceId);
668*38e8c45fSAndroid Build Coastguard Worker     if (it == mKernelWakeup.end()) {
669*38e8c45fSAndroid Build Coastguard Worker         return false;
670*38e8c45fSAndroid Build Coastguard Worker     }
671*38e8c45fSAndroid Build Coastguard Worker     return it->second;
672*38e8c45fSAndroid Build Coastguard Worker }
673*38e8c45fSAndroid Build Coastguard Worker 
674*38e8c45fSAndroid Build Coastguard Worker } // namespace android
675