Loading init/init.cpp +20 −12 Original line number Diff line number Diff line Loading @@ -553,22 +553,30 @@ static void InstallSignalFdHandler(Epoll* epoll) { } } void HandleKeychord(int id) { void HandleKeychord(const std::vector<int>& keycodes) { // Only handle keychords if adb is enabled. std::string adb_enabled = android::base::GetProperty("init.svc.adbd", ""); if (adb_enabled == "running") { Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id); if (svc) { LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << id; if (adb_enabled != "running") { LOG(WARNING) << "Not starting service for keychord " << android::base::Join(keycodes, ' ') << " because ADB is disabled"; return; } auto found = false; for (const auto& service : ServiceList::GetInstance()) { auto svc = service.get(); if (svc->keycodes() == keycodes) { found = true; LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << android::base::Join(keycodes, ' '); if (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << android::base::Join(keycodes, ' ') << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } if (!found) { LOG(ERROR) << "Service for keychord " << android::base::Join(keycodes, ' ') << " not found"; } } Loading Loading @@ -753,7 +761,7 @@ int main(int argc, char** argv) { am.QueueBuiltinAction( [&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> { for (const auto& svc : ServiceList::GetInstance()) { svc->set_keychord_id(keychords.GetId(svc->keycodes())); keychords.Register(svc->keycodes()); } keychords.Start(&epoll, HandleKeychord); return Success(); Loading init/keychords.cpp +15 −18 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ namespace android { namespace init { Keychords::Keychords() : epoll_(nullptr), count_(0), inotify_fd_(-1) {} Keychords::Keychords() : epoll_(nullptr), inotify_fd_(-1) {} Keychords::~Keychords() noexcept { if (inotify_fd_ >= 0) { Loading Loading @@ -108,23 +108,22 @@ void Keychords::Mask::operator|=(const Keychords::Mask& rval) { } } Keychords::Entry::Entry(const std::vector<int>& keycodes, int id) : keycodes(keycodes), id(id), notified(false) {} Keychords::Entry::Entry() : notified(false) {} void Keychords::LambdaCheck() { for (auto& e : entries_) { for (auto& [keycodes, entry] : entries_) { auto found = true; for (auto& code : e.keycodes) { for (auto& code : keycodes) { if (!current_.GetBit(code)) { e.notified = false; entry.notified = false; found = false; break; } } if (!found) continue; if (e.notified) continue; e.notified = true; handler_(e.id); if (entry.notified) continue; entry.notified = true; handler_(keycodes); } } Loading Loading @@ -158,8 +157,8 @@ bool Keychords::GeteventEnable(int fd) { #endif Keychords::Mask mask; for (auto& e : entries_) { for (auto& code : e.keycodes) { for (auto& [keycodes, entry] : entries_) { for (auto& code : keycodes) { mask.resize(code); mask.SetBit(code); } Loading Loading @@ -271,17 +270,15 @@ void Keychords::GeteventOpenDevice() { } } int Keychords::GetId(const std::vector<int>& keycodes) { if (keycodes.empty()) return 0; ++count_; entries_.emplace_back(Entry(keycodes, count_)); return count_; void Keychords::Register(const std::vector<int>& keycodes) { if (keycodes.empty()) return; entries_.try_emplace(keycodes, Entry()); } void Keychords::Start(Epoll* epoll, std::function<void(int)> handler) { void Keychords::Start(Epoll* epoll, std::function<void(const std::vector<int>&)> handler) { epoll_ = epoll; handler_ = handler; if (count_) GeteventOpenDevice(); if (entries_.size()) GeteventOpenDevice(); } } // namespace init Loading init/keychords.h +5 −8 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ class Keychords { Keychords& operator=(Keychords&&) = delete; ~Keychords() noexcept; int GetId(const std::vector<int>& keycodes); void Start(Epoll* epoll, std::function<void(int)> handler); void Register(const std::vector<int>& keycodes); void Start(Epoll* epoll, std::function<void(const std::vector<int>&)> handler); private: // Bit management Loading Loading @@ -65,10 +65,8 @@ class Keychords { }; struct Entry { Entry(const std::vector<int>& keycodes, int id); Entry(); const std::vector<int> keycodes; const int id; bool notified; }; Loading @@ -84,12 +82,11 @@ class Keychords { void GeteventCloseDevice(const std::string& device); Epoll* epoll_; std::function<void(int)> handler_; std::function<void(const std::vector<int>&)> handler_; std::map<std::string, int> registration_; int count_; std::vector<Entry> entries_; std::map<const std::vector<int>, Entry> entries_; Mask current_; Loading init/service.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -228,7 +228,6 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, seclabel_(seclabel), onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0, "onrestart", {}), keychord_id_(0), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), Loading Loading @@ -548,7 +547,7 @@ Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) { for (auto& key : keycodes_) { if (key == code) return Error() << "duplicate keycode: " << args[i]; } keycodes_.emplace_back(code); keycodes_.insert(std::upper_bound(keycodes_.begin(), keycodes_.end(), code), code); } else { return Error() << "invalid keycode: " << args[i]; } Loading init/service.h +1 −4 Original line number Diff line number Diff line Loading @@ -108,8 +108,6 @@ class Service { const std::vector<gid_t>& supp_gids() const { return supp_gids_; } const std::string& seclabel() const { return seclabel_; } const std::vector<int>& keycodes() const { return keycodes_; } int keychord_id() const { return keychord_id_; } void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; } IoSchedClass ioprio_class() const { return ioprio_class_; } int ioprio_pri() const { return ioprio_pri_; } const std::set<std::string>& interfaces() const { return interfaces_; } Loading Loading @@ -199,9 +197,8 @@ class Service { std::set<std::string> interfaces_; // e.g. some.package.foo@1.0::IBaz/instance-name // keycodes for triggering this service via /dev/keychord // keycodes for triggering this service via /dev/input/input* std::vector<int> keycodes_; int keychord_id_; IoSchedClass ioprio_class_; int ioprio_pri_; Loading Loading
init/init.cpp +20 −12 Original line number Diff line number Diff line Loading @@ -553,22 +553,30 @@ static void InstallSignalFdHandler(Epoll* epoll) { } } void HandleKeychord(int id) { void HandleKeychord(const std::vector<int>& keycodes) { // Only handle keychords if adb is enabled. std::string adb_enabled = android::base::GetProperty("init.svc.adbd", ""); if (adb_enabled == "running") { Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id); if (svc) { LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << id; if (adb_enabled != "running") { LOG(WARNING) << "Not starting service for keychord " << android::base::Join(keycodes, ' ') << " because ADB is disabled"; return; } auto found = false; for (const auto& service : ServiceList::GetInstance()) { auto svc = service.get(); if (svc->keycodes() == keycodes) { found = true; LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << android::base::Join(keycodes, ' '); if (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << android::base::Join(keycodes, ' ') << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } if (!found) { LOG(ERROR) << "Service for keychord " << android::base::Join(keycodes, ' ') << " not found"; } } Loading Loading @@ -753,7 +761,7 @@ int main(int argc, char** argv) { am.QueueBuiltinAction( [&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> { for (const auto& svc : ServiceList::GetInstance()) { svc->set_keychord_id(keychords.GetId(svc->keycodes())); keychords.Register(svc->keycodes()); } keychords.Start(&epoll, HandleKeychord); return Success(); Loading
init/keychords.cpp +15 −18 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ namespace android { namespace init { Keychords::Keychords() : epoll_(nullptr), count_(0), inotify_fd_(-1) {} Keychords::Keychords() : epoll_(nullptr), inotify_fd_(-1) {} Keychords::~Keychords() noexcept { if (inotify_fd_ >= 0) { Loading Loading @@ -108,23 +108,22 @@ void Keychords::Mask::operator|=(const Keychords::Mask& rval) { } } Keychords::Entry::Entry(const std::vector<int>& keycodes, int id) : keycodes(keycodes), id(id), notified(false) {} Keychords::Entry::Entry() : notified(false) {} void Keychords::LambdaCheck() { for (auto& e : entries_) { for (auto& [keycodes, entry] : entries_) { auto found = true; for (auto& code : e.keycodes) { for (auto& code : keycodes) { if (!current_.GetBit(code)) { e.notified = false; entry.notified = false; found = false; break; } } if (!found) continue; if (e.notified) continue; e.notified = true; handler_(e.id); if (entry.notified) continue; entry.notified = true; handler_(keycodes); } } Loading Loading @@ -158,8 +157,8 @@ bool Keychords::GeteventEnable(int fd) { #endif Keychords::Mask mask; for (auto& e : entries_) { for (auto& code : e.keycodes) { for (auto& [keycodes, entry] : entries_) { for (auto& code : keycodes) { mask.resize(code); mask.SetBit(code); } Loading Loading @@ -271,17 +270,15 @@ void Keychords::GeteventOpenDevice() { } } int Keychords::GetId(const std::vector<int>& keycodes) { if (keycodes.empty()) return 0; ++count_; entries_.emplace_back(Entry(keycodes, count_)); return count_; void Keychords::Register(const std::vector<int>& keycodes) { if (keycodes.empty()) return; entries_.try_emplace(keycodes, Entry()); } void Keychords::Start(Epoll* epoll, std::function<void(int)> handler) { void Keychords::Start(Epoll* epoll, std::function<void(const std::vector<int>&)> handler) { epoll_ = epoll; handler_ = handler; if (count_) GeteventOpenDevice(); if (entries_.size()) GeteventOpenDevice(); } } // namespace init Loading
init/keychords.h +5 −8 Original line number Diff line number Diff line Loading @@ -36,8 +36,8 @@ class Keychords { Keychords& operator=(Keychords&&) = delete; ~Keychords() noexcept; int GetId(const std::vector<int>& keycodes); void Start(Epoll* epoll, std::function<void(int)> handler); void Register(const std::vector<int>& keycodes); void Start(Epoll* epoll, std::function<void(const std::vector<int>&)> handler); private: // Bit management Loading Loading @@ -65,10 +65,8 @@ class Keychords { }; struct Entry { Entry(const std::vector<int>& keycodes, int id); Entry(); const std::vector<int> keycodes; const int id; bool notified; }; Loading @@ -84,12 +82,11 @@ class Keychords { void GeteventCloseDevice(const std::string& device); Epoll* epoll_; std::function<void(int)> handler_; std::function<void(const std::vector<int>&)> handler_; std::map<std::string, int> registration_; int count_; std::vector<Entry> entries_; std::map<const std::vector<int>, Entry> entries_; Mask current_; Loading
init/service.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -228,7 +228,6 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, seclabel_(seclabel), onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0, "onrestart", {}), keychord_id_(0), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), priority_(0), Loading Loading @@ -548,7 +547,7 @@ Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) { for (auto& key : keycodes_) { if (key == code) return Error() << "duplicate keycode: " << args[i]; } keycodes_.emplace_back(code); keycodes_.insert(std::upper_bound(keycodes_.begin(), keycodes_.end(), code), code); } else { return Error() << "invalid keycode: " << args[i]; } Loading
init/service.h +1 −4 Original line number Diff line number Diff line Loading @@ -108,8 +108,6 @@ class Service { const std::vector<gid_t>& supp_gids() const { return supp_gids_; } const std::string& seclabel() const { return seclabel_; } const std::vector<int>& keycodes() const { return keycodes_; } int keychord_id() const { return keychord_id_; } void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; } IoSchedClass ioprio_class() const { return ioprio_class_; } int ioprio_pri() const { return ioprio_pri_; } const std::set<std::string>& interfaces() const { return interfaces_; } Loading Loading @@ -199,9 +197,8 @@ class Service { std::set<std::string> interfaces_; // e.g. some.package.foo@1.0::IBaz/instance-name // keycodes for triggering this service via /dev/keychord // keycodes for triggering this service via /dev/input/input* std::vector<int> keycodes_; int keychord_id_; IoSchedClass ioprio_class_; int ioprio_pri_; Loading