Loading init/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,8 @@ cc_binary { "action_parser.cpp", "capabilities.cpp", "descriptors.cpp", "epoll.cpp", "keychords.cpp", "import_parser.cpp", "host_init_parser.cpp", "host_init_stubs.cpp", Loading init/init.cpp +23 −1 Original line number Diff line number Diff line Loading @@ -553,6 +553,25 @@ static void InstallSignalFdHandler(Epoll* epoll) { } } void HandleKeychord(int id) { // 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 (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } } int main(int argc, char** argv) { if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); Loading Loading @@ -732,7 +751,10 @@ int main(int argc, char** argv) { am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction( [&epoll](const BuiltinArguments& args) -> Result<Success> { KeychordInit(&epoll); for (const auto& svc : ServiceList::GetInstance()) { svc->set_keychord_id(GetKeychordId(svc->keycodes())); } KeychordInit(&epoll, HandleKeychord); return Success(); }, "KeychordInit"); Loading init/keychords.cpp +15 −39 Original line number Diff line number Diff line Loading @@ -33,10 +33,6 @@ #include <vector> #include <android-base/logging.h> #include <android-base/properties.h> #include "init.h" #include "service.h" namespace android { namespace init { Loading @@ -45,6 +41,7 @@ namespace { int keychords_count; Epoll* epoll; std::function<void(int)> handle_keychord; struct KeychordEntry { const std::vector<int> keycodes; Loading Loading @@ -124,25 +121,6 @@ constexpr char kDevicePath[] = "/dev/input"; std::map<std::string, int> keychord_registration; void HandleKeychord(int id) { // 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 (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } } void KeychordLambdaCheck() { for (auto& e : keychord_entries) { bool found = true; Loading @@ -156,7 +134,7 @@ void KeychordLambdaCheck() { if (!found) continue; if (e.notified) continue; e.notified = true; HandleKeychord(e.id); handle_keychord(e.id); } } Loading @@ -169,12 +147,12 @@ void KeychordLambdaHandler(int fd) { } bool KeychordGeteventEnable(int fd) { static bool EviocsmaskSupported = true; // Make sure it is an event channel, should pass this ioctl call int version; if (::ioctl(fd, EVIOCGVERSION, &version)) return false; #ifdef EVIOCSMASK static auto EviocsmaskSupported = true; if (EviocsmaskSupported) { KeychordMask mask(EV_KEY); mask.SetBit(EV_KEY); Loading @@ -187,6 +165,7 @@ bool KeychordGeteventEnable(int fd) { EviocsmaskSupported = false; } } #endif KeychordMask mask; for (auto& e : keychord_entries) { Loading @@ -202,6 +181,7 @@ bool KeychordGeteventEnable(int fd) { if (res == -1) return false; if (!(available & mask)) return false; #ifdef EVIOCSMASK if (EviocsmaskSupported) { input_mask msg = {}; msg.type = EV_KEY; Loading @@ -209,6 +189,7 @@ bool KeychordGeteventEnable(int fd) { msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data()); ::ioctl(fd, EVIOCSMASK, &msg); } #endif KeychordMask set(mask.size()); res = ::ioctl(fd, EVIOCGKEY(res), set.data()); Loading Loading @@ -299,23 +280,18 @@ void GeteventOpenDevice() { if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler); } void AddServiceKeycodes(Service* svc) { if (svc->keycodes().empty()) return; for (auto& code : svc->keycodes()) { if ((code < 0) || (code >= KEY_MAX)) return; } } // namespace int GetKeychordId(const std::vector<int>& keycodes) { if (keycodes.empty()) return 0; ++keychords_count; keychord_entries.emplace_back(KeychordEntry(svc->keycodes(), keychords_count)); svc->set_keychord_id(keychords_count); keychord_entries.emplace_back(KeychordEntry(keycodes, keychords_count)); return keychords_count; } } // namespace void KeychordInit(Epoll* init_epoll) { void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler) { epoll = init_epoll; for (const auto& service : ServiceList::GetInstance()) { AddServiceKeycodes(service.get()); } handle_keychord = handler; if (keychords_count) GeteventOpenDevice(); } Loading init/keychords.h +5 −1 Original line number Diff line number Diff line Loading @@ -17,12 +17,16 @@ #ifndef _INIT_KEYCHORDS_H_ #define _INIT_KEYCHORDS_H_ #include <functional> #include <vector> #include "epoll.h" namespace android { namespace init { void KeychordInit(Epoll* init_epoll); void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler); int GetKeychordId(const std::vector<int>& keycodes); } // namespace init } // namespace android Loading init/service.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <fcntl.h> #include <inttypes.h> #include <linux/input.h> #include <linux/securebits.h> #include <sched.h> #include <sys/mount.h> Loading Loading @@ -544,10 +545,13 @@ Result<Success> Service::ParseIoprio(const std::vector<std::string>& args) { Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) { for (std::size_t i = 1; i < args.size(); i++) { int code; if (ParseInt(args[i], &code)) { if (ParseInt(args[i], &code, 0, KEY_MAX)) { for (auto& key : keycodes_) { if (key == code) return Error() << "duplicate keycode: " << args[i]; } keycodes_.emplace_back(code); } else { LOG(WARNING) << "ignoring invalid keycode: " << args[i]; return Error() << "invalid keycode: " << args[i]; } } return Success(); Loading Loading
init/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,8 @@ cc_binary { "action_parser.cpp", "capabilities.cpp", "descriptors.cpp", "epoll.cpp", "keychords.cpp", "import_parser.cpp", "host_init_parser.cpp", "host_init_stubs.cpp", Loading
init/init.cpp +23 −1 Original line number Diff line number Diff line Loading @@ -553,6 +553,25 @@ static void InstallSignalFdHandler(Epoll* epoll) { } } void HandleKeychord(int id) { // 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 (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } } int main(int argc, char** argv) { if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); Loading Loading @@ -732,7 +751,10 @@ int main(int argc, char** argv) { am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction( [&epoll](const BuiltinArguments& args) -> Result<Success> { KeychordInit(&epoll); for (const auto& svc : ServiceList::GetInstance()) { svc->set_keychord_id(GetKeychordId(svc->keycodes())); } KeychordInit(&epoll, HandleKeychord); return Success(); }, "KeychordInit"); Loading
init/keychords.cpp +15 −39 Original line number Diff line number Diff line Loading @@ -33,10 +33,6 @@ #include <vector> #include <android-base/logging.h> #include <android-base/properties.h> #include "init.h" #include "service.h" namespace android { namespace init { Loading @@ -45,6 +41,7 @@ namespace { int keychords_count; Epoll* epoll; std::function<void(int)> handle_keychord; struct KeychordEntry { const std::vector<int> keycodes; Loading Loading @@ -124,25 +121,6 @@ constexpr char kDevicePath[] = "/dev/input"; std::map<std::string, int> keychord_registration; void HandleKeychord(int id) { // 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 (auto result = svc->Start(); !result) { LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id << ": " << result.error(); } } else { LOG(ERROR) << "Service for keychord " << id << " not found"; } } else { LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled"; } } void KeychordLambdaCheck() { for (auto& e : keychord_entries) { bool found = true; Loading @@ -156,7 +134,7 @@ void KeychordLambdaCheck() { if (!found) continue; if (e.notified) continue; e.notified = true; HandleKeychord(e.id); handle_keychord(e.id); } } Loading @@ -169,12 +147,12 @@ void KeychordLambdaHandler(int fd) { } bool KeychordGeteventEnable(int fd) { static bool EviocsmaskSupported = true; // Make sure it is an event channel, should pass this ioctl call int version; if (::ioctl(fd, EVIOCGVERSION, &version)) return false; #ifdef EVIOCSMASK static auto EviocsmaskSupported = true; if (EviocsmaskSupported) { KeychordMask mask(EV_KEY); mask.SetBit(EV_KEY); Loading @@ -187,6 +165,7 @@ bool KeychordGeteventEnable(int fd) { EviocsmaskSupported = false; } } #endif KeychordMask mask; for (auto& e : keychord_entries) { Loading @@ -202,6 +181,7 @@ bool KeychordGeteventEnable(int fd) { if (res == -1) return false; if (!(available & mask)) return false; #ifdef EVIOCSMASK if (EviocsmaskSupported) { input_mask msg = {}; msg.type = EV_KEY; Loading @@ -209,6 +189,7 @@ bool KeychordGeteventEnable(int fd) { msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data()); ::ioctl(fd, EVIOCSMASK, &msg); } #endif KeychordMask set(mask.size()); res = ::ioctl(fd, EVIOCGKEY(res), set.data()); Loading Loading @@ -299,23 +280,18 @@ void GeteventOpenDevice() { if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler); } void AddServiceKeycodes(Service* svc) { if (svc->keycodes().empty()) return; for (auto& code : svc->keycodes()) { if ((code < 0) || (code >= KEY_MAX)) return; } } // namespace int GetKeychordId(const std::vector<int>& keycodes) { if (keycodes.empty()) return 0; ++keychords_count; keychord_entries.emplace_back(KeychordEntry(svc->keycodes(), keychords_count)); svc->set_keychord_id(keychords_count); keychord_entries.emplace_back(KeychordEntry(keycodes, keychords_count)); return keychords_count; } } // namespace void KeychordInit(Epoll* init_epoll) { void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler) { epoll = init_epoll; for (const auto& service : ServiceList::GetInstance()) { AddServiceKeycodes(service.get()); } handle_keychord = handler; if (keychords_count) GeteventOpenDevice(); } Loading
init/keychords.h +5 −1 Original line number Diff line number Diff line Loading @@ -17,12 +17,16 @@ #ifndef _INIT_KEYCHORDS_H_ #define _INIT_KEYCHORDS_H_ #include <functional> #include <vector> #include "epoll.h" namespace android { namespace init { void KeychordInit(Epoll* init_epoll); void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler); int GetKeychordId(const std::vector<int>& keycodes); } // namespace init } // namespace android Loading
init/service.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <fcntl.h> #include <inttypes.h> #include <linux/input.h> #include <linux/securebits.h> #include <sched.h> #include <sys/mount.h> Loading Loading @@ -544,10 +545,13 @@ Result<Success> Service::ParseIoprio(const std::vector<std::string>& args) { Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) { for (std::size_t i = 1; i < args.size(); i++) { int code; if (ParseInt(args[i], &code)) { if (ParseInt(args[i], &code, 0, KEY_MAX)) { for (auto& key : keycodes_) { if (key == code) return Error() << "duplicate keycode: " << args[i]; } keycodes_.emplace_back(code); } else { LOG(WARNING) << "ignoring invalid keycode: " << args[i]; return Error() << "invalid keycode: " << args[i]; } } return Success(); Loading