summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2025-03-21 11:20:36 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-21 11:20:36 -0700
commit723823999c27d41ea835edbd43b3090db334c8cc (patch)
tree2c6f2a7dd2ac6a5ef24abbf664260eb566fcad4a
parent026a16762022129a6bc79765e14510f7504187be (diff)
parenta8f88542870080dac70919becd0aa706e29b76b4 (diff)
Merge changes from topic "getSysfsRootPath" into main
* changes: EventHub: Re-open Devices serially when AssociatedDevice changes InputReader: Add getter API for the sysfs node path of an InputDevice
-rw-r--r--services/inputflinger/include/InputReaderBase.h3
-rw-r--r--services/inputflinger/reader/EventHub.cpp167
-rw-r--r--services/inputflinger/reader/InputDevice.cpp6
-rw-r--r--services/inputflinger/reader/InputReader.cpp10
-rw-r--r--services/inputflinger/reader/include/EventHub.h6
-rw-r--r--services/inputflinger/reader/include/InputDevice.h6
-rw-r--r--services/inputflinger/reader/include/InputReader.h2
-rw-r--r--services/inputflinger/tests/FakeEventHub.cpp8
-rw-r--r--services/inputflinger/tests/FakeEventHub.h1
-rw-r--r--services/inputflinger/tests/InputReader_test.cpp16
-rw-r--r--services/inputflinger/tests/InterfaceMocks.h1
-rw-r--r--services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp5
-rw-r--r--services/inputflinger/tests/fuzzers/MapperHelpers.h1
13 files changed, 170 insertions, 62 deletions
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 608bec4a0c..c8432005a4 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -443,6 +443,9 @@ public:
/* Get the Bluetooth address of an input device, if known. */
virtual std::optional<std::string> getBluetoothAddress(int32_t deviceId) const = 0;
+ /* Gets the sysfs root path for this device. Returns an empty path if there is none. */
+ virtual std::filesystem::path getSysfsRootPath(int32_t deviceId) const = 0;
+
/* Sysfs node change reported. Recreate device if required to incorporate the new sysfs nodes */
virtual void sysfsNodeChanged(const std::string& sysfsNodePath) = 0;
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 784baea6f3..559bc0aa7a 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -246,7 +246,7 @@ static nsecs_t processEventTimestamp(const struct input_event& event) {
/**
* Returns the sysfs root path of the input device.
*/
-static std::optional<std::filesystem::path> getSysfsRootPath(const char* devicePath) {
+static std::optional<std::filesystem::path> getSysfsRootForEvdevDevicePath(const char* devicePath) {
std::error_code errorCode;
// Stat the device path to get the major and minor number of the character file
@@ -1619,7 +1619,7 @@ void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) {
std::shared_ptr<const EventHub::AssociatedDevice> EventHub::obtainAssociatedDeviceLocked(
const std::filesystem::path& devicePath, const std::shared_ptr<PropertyMap>& config) const {
const std::optional<std::filesystem::path> sysfsRootPathOpt =
- getSysfsRootPath(devicePath.c_str());
+ getSysfsRootForEvdevDevicePath(devicePath.c_str());
if (!sysfsRootPathOpt) {
return nullptr;
}
@@ -1899,58 +1899,87 @@ std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) {
handleSysfsNodeChangeNotificationsLocked();
- // Report any devices that had last been added/removed.
- for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
- std::unique_ptr<Device> device = std::move(*it);
- ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str());
- const int32_t deviceId = (device->id == mBuiltInKeyboardId)
- ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID
- : device->id;
- events.push_back({
- .when = now,
- .deviceId = deviceId,
- .type = DEVICE_REMOVED,
- });
- it = mClosingDevices.erase(it);
- if (events.size() == EVENT_BUFFER_SIZE) {
- break;
+ // Use a do-while loop to ensure that we drain the closing and opening devices loop
+ // at least once, even if there are no devices to re-open.
+ do {
+ if (!mDeviceIdsToReopen.empty()) {
+ // If there are devices that need to be re-opened, ensure that we re-open them
+ // one at a time to send the DEVICE_REMOVED and DEVICE_ADDED notifications for
+ // each before moving on to the next. This is to avoid notifying all device
+ // removals and additions in one batch, which could cause additional unnecessary
+ // device added/removed notifications for merged InputDevices from InputReader.
+ const int32_t deviceId = mDeviceIdsToReopen.back();
+ mDeviceIdsToReopen.erase(mDeviceIdsToReopen.end() - 1);
+ if (auto it = mDevices.find(deviceId); it != mDevices.end()) {
+ ALOGI("Reopening input device: id=%d, name=%s", it->second->id,
+ it->second->identifier.name.c_str());
+ const auto path = it->second->path;
+ closeDeviceLocked(*it->second);
+ openDeviceLocked(path);
+ }
}
- }
- if (mNeedToScanDevices) {
- mNeedToScanDevices = false;
- scanDevicesLocked();
- }
-
- while (!mOpeningDevices.empty()) {
- std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
- mOpeningDevices.pop_back();
- ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
- const int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
- events.push_back({
- .when = now,
- .deviceId = deviceId,
- .type = DEVICE_ADDED,
- });
-
- // Try to find a matching video device by comparing device names
- for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
- it++) {
- std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
- if (tryAddVideoDeviceLocked(*device, videoDevice)) {
- // videoDevice was transferred to 'device'
- it = mUnattachedVideoDevices.erase(it);
+ // Report any devices that had last been added/removed.
+ for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
+ std::unique_ptr<Device> device = std::move(*it);
+ ALOGV("Reporting device closed: id=%d, name=%s\n", device->id,
+ device->path.c_str());
+ const int32_t deviceId = (device->id == mBuiltInKeyboardId)
+ ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID
+ : device->id;
+ events.push_back({
+ .when = now,
+ .deviceId = deviceId,
+ .type = DEVICE_REMOVED,
+ });
+ it = mClosingDevices.erase(it);
+ if (events.size() == EVENT_BUFFER_SIZE) {
break;
}
}
- auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
- if (!inserted) {
- ALOGW("Device id %d exists, replaced.", device->id);
+ if (mNeedToScanDevices) {
+ mNeedToScanDevices = false;
+ scanDevicesLocked();
}
- if (events.size() == EVENT_BUFFER_SIZE) {
- break;
+
+ while (!mOpeningDevices.empty()) {
+ std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
+ mOpeningDevices.pop_back();
+ ALOGV("Reporting device opened: id=%d, name=%s\n", device->id,
+ device->path.c_str());
+ const int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
+ events.push_back({
+ .when = now,
+ .deviceId = deviceId,
+ .type = DEVICE_ADDED,
+ });
+
+ // Try to find a matching video device by comparing device names
+ for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
+ it++) {
+ std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
+ if (tryAddVideoDeviceLocked(*device, videoDevice)) {
+ // videoDevice was transferred to 'device'
+ it = mUnattachedVideoDevices.erase(it);
+ break;
+ }
+ }
+
+ auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
+ if (!inserted) {
+ ALOGW("Device id %d exists, replaced.", device->id);
+ }
+ if (events.size() == EVENT_BUFFER_SIZE) {
+ break;
+ }
}
+
+ // Perform this loop of re-opening devices so that we re-open one device at a time.
+ } while (!mDeviceIdsToReopen.empty());
+
+ if (events.size() == EVENT_BUFFER_SIZE) {
+ break;
}
// Grab the next input event.
@@ -2666,6 +2695,18 @@ status_t EventHub::disableDevice(int32_t deviceId) {
return device->disable();
}
+std::filesystem::path EventHub::getSysfsRootPath(int32_t deviceId) const {
+ std::scoped_lock _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device == nullptr) {
+ ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__);
+ return {};
+ }
+
+ return device->associatedDevice ? device->associatedDevice->sysfsRootPath
+ : std::filesystem::path{};
+}
+
// TODO(b/274755573): Shift to uevent handling on native side and remove this method
// Currently using Java UEventObserver to trigger this which uses UEvent infrastructure that uses a
// NETLINK socket to observe UEvents. We can create similar infrastructure on Eventhub side to
@@ -2688,8 +2729,10 @@ void EventHub::handleSysfsNodeChangeNotificationsLocked() {
// Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
// testing the same node multiple times.
+ // TODO(b/281822656): Notify InputReader separately when an AssociatedDevice changes,
+ // instead of needing to re-open all of Devices that are associated with it.
std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices;
- auto isAssociatedDeviceChanged = [&testedDevices, &changedNodes](const Device& dev) {
+ auto shouldReopenDevice = [&testedDevices, &changedNodes](const Device& dev) {
if (!dev.associatedDevice) {
return false;
}
@@ -2710,31 +2753,33 @@ void EventHub::handleSysfsNodeChangeNotificationsLocked() {
auto reloadedDevice = AssociatedDevice(dev.associatedDevice->sysfsRootPath,
dev.associatedDevice->baseDevConfig);
const bool changed = *dev.associatedDevice != reloadedDevice;
+ if (changed) {
+ ALOGI("sysfsNodeChanged: Identified change in sysfs nodes for device: %s",
+ dev.identifier.name.c_str());
+ }
testedDevices.emplace(dev.associatedDevice, changed);
return changed;
};
- std::set<Device*> devicesToReopen;
-
- // Check in opening devices.
+ // Check in opening devices. These can be re-opened directly because we have not yet notified
+ // the Reader about these devices.
for (const auto& dev : mOpeningDevices) {
- if (isAssociatedDeviceChanged(*dev)) {
- devicesToReopen.emplace(dev.get());
+ if (shouldReopenDevice(*dev)) {
+ ALOGI("Reopening input device from mOpeningDevices: id=%d, name=%s", dev->id,
+ dev->identifier.name.c_str());
+ const auto path = dev->path;
+ closeDeviceLocked(*dev); // The Device object is deleted by this function.
+ openDeviceLocked(path);
}
}
- // Check in already added devices.
+ // Check in already added devices. Add them to the re-opening list so they can be
+ // re-opened serially.
for (const auto& [id, dev] : mDevices) {
- if (isAssociatedDeviceChanged(*dev)) {
- devicesToReopen.emplace(dev.get());
+ if (shouldReopenDevice(*dev)) {
+ mDeviceIdsToReopen.emplace_back(dev->id);
}
}
-
- for (auto* device : devicesToReopen) {
- const auto path = device->path;
- closeDeviceLocked(*device); // The Device object is deleted by this function.
- openDeviceLocked(path);
- }
}
void EventHub::createVirtualKeyboardLocked() {
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 5e42d57f06..594dcba144 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -136,6 +136,8 @@ void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
} else {
dump += "<none>\n";
}
+ dump += StringPrintf(INDENT2 "SysfsRootPath: %s\n",
+ mSysfsRootPath.empty() ? "<none>" : mSysfsRootPath.c_str());
dump += StringPrintf(INDENT2 "HasMic: %s\n", toString(mHasMic));
dump += StringPrintf(INDENT2 "Sources: %s\n",
inputEventSourceToString(deviceInfo.getSources()).c_str());
@@ -195,6 +197,10 @@ void InputDevice::addEmptyEventHubDevice(int32_t eventHubId) {
DevicePair& devicePair = mDevices[eventHubId];
devicePair.second = createMappers(*devicePair.first, readerConfig);
+ if (mSysfsRootPath.empty()) {
+ mSysfsRootPath = devicePair.first->getSysfsRootPath();
+ }
+
// Must change generation to flag this device as changed
bumpGeneration();
return out;
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index f2f70c4a10..74ef972848 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -917,6 +917,16 @@ bool InputReader::canDispatchToDisplay(int32_t deviceId, ui::LogicalDisplayId di
return *associatedDisplayId == displayId;
}
+std::filesystem::path InputReader::getSysfsRootPath(int32_t deviceId) const {
+ std::scoped_lock _l(mLock);
+
+ const InputDevice* device = findInputDeviceLocked(deviceId);
+ if (!device) {
+ return {};
+ }
+ return device->getSysfsRootPath();
+}
+
void InputReader::sysfsNodeChanged(const std::string& sysfsNodePath) {
mEventHub->sysfsNodeChanged(sysfsNodePath);
mEventHub->wake();
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 913f8f8d1d..9f3a57c265 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -399,6 +399,9 @@ public:
/* Disable an input device. Closes file descriptor to that device. */
virtual status_t disableDevice(int32_t deviceId) = 0;
+ /* Gets the sysfs root path for this device. Returns an empty path if there is none. */
+ virtual std::filesystem::path getSysfsRootPath(int32_t deviceId) const = 0;
+
/* Sysfs node changed. Reopen the Eventhub device if any new Peripheral like Light, Battery,
* etc. is detected. */
virtual void sysfsNodeChanged(const std::string& sysfsNodePath) = 0;
@@ -614,6 +617,8 @@ public:
status_t disableDevice(int32_t deviceId) override final;
+ std::filesystem::path getSysfsRootPath(int32_t deviceId) const override final;
+
void sysfsNodeChanged(const std::string& sysfsNodePath) override final;
bool setKernelWakeEnabled(int32_t deviceId, bool enabled) override final;
@@ -810,6 +815,7 @@ private:
bool mNeedToReopenDevices;
bool mNeedToScanDevices;
std::vector<std::string> mExcludedDevices;
+ std::vector<int32_t> mDeviceIdsToReopen;
int mEpollFd;
int mINotifyFd;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 4744dd0e4e..a1a8891940 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -81,6 +81,8 @@ public:
inline virtual KeyboardType getKeyboardType() const { return mKeyboardType; }
+ inline std::filesystem::path getSysfsRootPath() const { return mSysfsRootPath; }
+
bool isEnabled();
void dump(std::string& dump, const std::string& eventHubDevStr);
@@ -209,6 +211,7 @@ private:
bool mHasMic;
bool mDropUntilNextSync;
std::optional<bool> mShouldSmoothScroll;
+ std::filesystem::path mSysfsRootPath;
typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
@@ -471,6 +474,9 @@ public:
inline void setKeyboardType(KeyboardType keyboardType) {
return mDevice.setKeyboardType(keyboardType);
}
+ inline std::filesystem::path getSysfsRootPath() const {
+ return mEventHub->getSysfsRootPath(mId);
+ }
inline bool setKernelWakeEnabled(bool enabled) {
return mEventHub->setKernelWakeEnabled(mId, enabled);
}
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 6a259373df..9212d37966 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -118,6 +118,8 @@ public:
std::optional<std::string> getBluetoothAddress(int32_t deviceId) const override;
+ std::filesystem::path getSysfsRootPath(int32_t deviceId) const override;
+
void sysfsNodeChanged(const std::string& sysfsNodePath) override;
DeviceId getLastUsedInputDeviceId() override;
diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp
index e72c440480..8987b99525 100644
--- a/services/inputflinger/tests/FakeEventHub.cpp
+++ b/services/inputflinger/tests/FakeEventHub.cpp
@@ -627,6 +627,14 @@ void FakeEventHub::setSysfsRootPath(int32_t deviceId, std::string sysfsRootPath)
device->sysfsRootPath = sysfsRootPath;
}
+std::filesystem::path FakeEventHub::getSysfsRootPath(int32_t deviceId) const {
+ Device* device = getDevice(deviceId);
+ if (device == nullptr) {
+ return {};
+ }
+ return device->sysfsRootPath;
+}
+
void FakeEventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
int32_t foundDeviceId = -1;
Device* foundDevice = nullptr;
diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h
index 143b93b245..1cd33c1c98 100644
--- a/services/inputflinger/tests/FakeEventHub.h
+++ b/services/inputflinger/tests/FakeEventHub.h
@@ -222,6 +222,7 @@ private:
std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override;
std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
int32_t deviceId, int32_t lightId) const override;
+ std::filesystem::path getSysfsRootPath(int32_t deviceId) const override;
void sysfsNodeChanged(const std::string& sysfsNodePath) override;
void dump(std::string&) const override {}
void monitor() const override {}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 43d2378f61..d1d8192395 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -611,8 +611,10 @@ protected:
}
void addDevice(int32_t eventHubId, const std::string& name,
- ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
+ ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration,
+ std::string sysfsRootPath = "") {
mFakeEventHub->addDevice(eventHubId, name, classes);
+ mFakeEventHub->setSysfsRootPath(eventHubId, sysfsRootPath);
if (configuration) {
mFakeEventHub->addConfigurationMap(eventHubId, configuration);
@@ -664,6 +666,18 @@ TEST_F(InputReaderTest, PolicyGetInputDevices) {
ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
}
+TEST_F(InputReaderTest, GetSysfsRootPath) {
+ constexpr std::string SYSFS_ROOT = "xyz";
+ ASSERT_NO_FATAL_FAILURE(
+ addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr, SYSFS_ROOT));
+
+ // Should also have received a notification describing the new input device.
+ ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
+ InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
+
+ ASSERT_EQ(SYSFS_ROOT, mReader->getSysfsRootPath(inputDevice.getId()).string());
+}
+
TEST_F(InputReaderTest, InputDeviceRecreatedOnSysfsNodeChanged) {
ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
mFakeEventHub->setSysfsRootPath(1, "xyz");
diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h
index d4e4bb00f7..8eded2e279 100644
--- a/services/inputflinger/tests/InterfaceMocks.h
+++ b/services/inputflinger/tests/InterfaceMocks.h
@@ -181,6 +181,7 @@ public:
MOCK_METHOD(bool, isDeviceEnabled, (int32_t deviceId), (const, override));
MOCK_METHOD(status_t, enableDevice, (int32_t deviceId), (override));
MOCK_METHOD(status_t, disableDevice, (int32_t deviceId), (override));
+ MOCK_METHOD(std::filesystem::path, getSysfsRootPath, (int32_t deviceId), (const, override));
MOCK_METHOD(void, sysfsNodeChanged, (const std::string& sysfsNodePath), (override));
MOCK_METHOD(bool, setKernelWakeEnabled, (int32_t deviceId, bool enabled), (override));
};
diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
index 6be922dfdb..0c8ba50776 100644
--- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
@@ -165,6 +165,10 @@ public:
return reader->getBluetoothAddress(deviceId);
}
+ std::filesystem::path getSysfsRootPath(int32_t deviceId) const {
+ return reader->getSysfsRootPath(deviceId);
+ }
+
void sysfsNodeChanged(const std::string& sysfsNodePath) {
reader->sysfsNodeChanged(sysfsNodePath);
}
@@ -297,6 +301,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()));
},
[&]() -> void { reader->getBluetoothAddress(fdp->ConsumeIntegral<int32_t>()); },
+ [&]() -> void { reader->getSysfsRootPath(fdp->ConsumeIntegral<int32_t>()); },
})();
}
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index 9a5903981b..f619c48f3f 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -296,6 +296,7 @@ public:
bool isDeviceEnabled(int32_t deviceId) const override { return mFdp->ConsumeBool(); }
status_t enableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
status_t disableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
+ std::filesystem::path getSysfsRootPath(int32_t deviceId) const override { return {}; }
void sysfsNodeChanged(const std::string& sysfsNodePath) override {}
bool setKernelWakeEnabled(int32_t deviceId, bool enabled) override {
return mFdp->ConsumeBool();