ueventd: Break devices.cpp into discrete classes
devices.cpp handles too many things for creating one class. This
change breaks it up into various files and classes.
* Parsing is moved to ueventd_parser.cpp
* Reading from the uevent socket and Cold booting is moved to a
UeventListener class, in uevent_listener.cpp
* Firmware handling is moved to firmware_handler.cpp
* The remaining contents form a DeviceHandler class within devices.cpp
Bug: 33785894
Test: boot bullhead x40, observe no major differences in /dev and /sys
Test: boot sailfish x40, observe no major differences in /dev and /sys
Test: init unit tests
Change-Id: I846a2e5995fbb344c7a8e349065c18a934fa6aba
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 8c0c574..bd21a3e 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -18,7 +18,6 @@
#include <ctype.h>
#include <fcntl.h>
-#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,9 +29,44 @@
#include <selinux/selinux.h>
#include "devices.h"
+#include "firmware_handler.h"
#include "log.h"
+#include "uevent_listener.h"
+#include "ueventd_parser.h"
#include "util.h"
+DeviceHandler CreateDeviceHandler() {
+ Parser parser;
+
+ std::vector<Subsystem> subsystems;
+ parser.AddSectionParser("subsystem", std::make_unique<SubsystemParser>(&subsystems));
+
+ using namespace std::placeholders;
+ std::vector<SysfsPermissions> sysfs_permissions;
+ std::vector<Permissions> dev_permissions;
+ parser.AddSingleLineParser(
+ "/sys/", std::bind(ParsePermissionsLine, _1, _2, &sysfs_permissions, nullptr));
+ parser.AddSingleLineParser("/dev/",
+ std::bind(ParsePermissionsLine, _1, _2, nullptr, &dev_permissions));
+
+ parser.ParseConfig("/ueventd.rc");
+ parser.ParseConfig("/vendor/ueventd.rc");
+ parser.ParseConfig("/odm/ueventd.rc");
+
+ /*
+ * keep the current product name base configuration so
+ * we remain backwards compatible and allow it to override
+ * everything
+ * TODO: cleanup platform ueventd.rc to remove vendor specific
+ * device node entries (b/34968103)
+ */
+ std::string hardware = android::base::GetProperty("ro.hardware", "");
+ parser.ParseConfig("/ueventd." + hardware + ".rc");
+
+ return DeviceHandler(std::move(dev_permissions), std::move(sysfs_permissions),
+ std::move(subsystems));
+}
+
int ueventd_main(int argc, char **argv)
{
/*
@@ -57,41 +91,26 @@
cb.func_log = selinux_klog_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
- Parser& parser = Parser::GetInstance();
- parser.AddSectionParser("subsystem", std::make_unique<SubsystemParser>());
- using namespace std::placeholders;
- parser.AddSingleLineParser("/sys/", std::bind(ParsePermissionsLine, _1, _2, true));
- parser.AddSingleLineParser("/dev/", std::bind(ParsePermissionsLine, _1, _2, false));
- parser.ParseConfig("/ueventd.rc");
- parser.ParseConfig("/vendor/ueventd.rc");
- parser.ParseConfig("/odm/ueventd.rc");
+ DeviceHandler device_handler = CreateDeviceHandler();
+ UeventListener uevent_listener;
- /*
- * keep the current product name base configuration so
- * we remain backwards compatible and allow it to override
- * everything
- * TODO: cleanup platform ueventd.rc to remove vendor specific
- * device node entries (b/34968103)
- */
- std::string hardware = android::base::GetProperty("ro.hardware", "");
- parser.ParseConfig("/ueventd." + hardware + ".rc");
+ if (access(COLDBOOT_DONE, F_OK) != 0) {
+ Timer t;
- device_init();
+ uevent_listener.RegenerateUevents([&device_handler](const Uevent& uevent) {
+ HandleFirmwareEvent(uevent);
+ device_handler.HandleDeviceEvent(uevent);
+ return RegenerationAction::kContinue;
+ });
- pollfd ufd;
- ufd.events = POLLIN;
- ufd.fd = get_device_fd();
-
- while (true) {
- ufd.revents = 0;
- int nr = poll(&ufd, 1, -1);
- if (nr <= 0) {
- continue;
- }
- if (ufd.revents & POLLIN) {
- handle_device_fd();
- }
+ close(open(COLDBOOT_DONE, O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
+ LOG(INFO) << "Coldboot took " << t;
}
+ uevent_listener.DoPolling([&device_handler](const Uevent& uevent) {
+ HandleFirmwareEvent(uevent);
+ device_handler.HandleDeviceEvent(uevent);
+ });
+
return 0;
}