Merge "init: refactor keychord for testing"
This commit is contained in:
commit
16dd3582b7
5 changed files with 52 additions and 44 deletions
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
@ -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");
|
||||
|
|
|
@ -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 {
|
||||
|
@ -45,6 +41,7 @@ namespace {
|
|||
|
||||
int keychords_count;
|
||||
Epoll* epoll;
|
||||
std::function<void(int)> handle_keychord;
|
||||
|
||||
struct KeychordEntry {
|
||||
const std::vector<int> keycodes;
|
||||
|
@ -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;
|
||||
|
@ -156,7 +134,7 @@ void KeychordLambdaCheck() {
|
|||
if (!found) continue;
|
||||
if (e.notified) continue;
|
||||
e.notified = true;
|
||||
HandleKeychord(e.id);
|
||||
handle_keychord(e.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -187,6 +165,7 @@ bool KeychordGeteventEnable(int fd) {
|
|||
EviocsmaskSupported = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
KeychordMask mask;
|
||||
for (auto& e : keychord_entries) {
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
++keychords_count;
|
||||
keychord_entries.emplace_back(KeychordEntry(svc->keycodes(), keychords_count));
|
||||
svc->set_keychord_id(keychords_count);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void KeychordInit(Epoll* init_epoll) {
|
||||
int GetKeychordId(const std::vector<int>& keycodes) {
|
||||
if (keycodes.empty()) return 0;
|
||||
++keychords_count;
|
||||
keychord_entries.emplace_back(KeychordEntry(keycodes, keychords_count));
|
||||
return keychords_count;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -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…
Reference in a new issue