summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2018-05-16 17:10:24 -0500
committerMark Salyzyn2018-05-29 15:20:19 -0500
commiteca25076343945f901c7f631aad5e915c14c1a56 (patch)
tree4f20292ea17582f6b464d08ca355afd92a899199
parente82401e592c6c45eca854525c91530ef8422db40 (diff)
downloadplatform-system-core-eca25076343945f901c7f631aad5e915c14c1a56.tar.gz
platform-system-core-eca25076343945f901c7f631aad5e915c14c1a56.tar.xz
platform-system-core-eca25076343945f901c7f631aad5e915c14c1a56.zip
init: refactor keychord for testing
Move things around so that keychords.cpp is independent of service and init and can be individually tested with few dependencies. Permits also rolling out the keychords as a class in a future commit. Improve parser checking. Test: init_tests Bug: 64114943 Change-Id: I82570bc6269ed478db784ec38a8bc916da2be2be
-rw-r--r--init/Android.bp2
-rw-r--r--init/init.cpp24
-rw-r--r--init/keychords.cpp54
-rw-r--r--init/keychords.h6
-rw-r--r--init/service.cpp8
5 files changed, 51 insertions, 43 deletions
diff --git a/init/Android.bp b/init/Android.bp
index 63f3fca50..a3083c121 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -232,6 +232,8 @@ cc_binary {
232 "action_parser.cpp", 232 "action_parser.cpp",
233 "capabilities.cpp", 233 "capabilities.cpp",
234 "descriptors.cpp", 234 "descriptors.cpp",
235 "epoll.cpp",
236 "keychords.cpp",
235 "import_parser.cpp", 237 "import_parser.cpp",
236 "host_init_parser.cpp", 238 "host_init_parser.cpp",
237 "host_init_stubs.cpp", 239 "host_init_stubs.cpp",
diff --git a/init/init.cpp b/init/init.cpp
index fd9a90cd7..43242b2dc 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -553,6 +553,25 @@ static void InstallSignalFdHandler(Epoll* epoll) {
553 } 553 }
554} 554}
555 555
556void HandleKeychord(int id) {
557 // Only handle keychords if adb is enabled.
558 std::string adb_enabled = android::base::GetProperty("init.svc.adbd", "");
559 if (adb_enabled == "running") {
560 Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id);
561 if (svc) {
562 LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << id;
563 if (auto result = svc->Start(); !result) {
564 LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id
565 << ": " << result.error();
566 }
567 } else {
568 LOG(ERROR) << "Service for keychord " << id << " not found";
569 }
570 } else {
571 LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled";
572 }
573}
574
556int main(int argc, char** argv) { 575int main(int argc, char** argv) {
557 if (!strcmp(basename(argv[0]), "ueventd")) { 576 if (!strcmp(basename(argv[0]), "ueventd")) {
558 return ueventd_main(argc, argv); 577 return ueventd_main(argc, argv);
@@ -732,7 +751,10 @@ int main(int argc, char** argv) {
732 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); 751 am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
733 am.QueueBuiltinAction( 752 am.QueueBuiltinAction(
734 [&epoll](const BuiltinArguments& args) -> Result<Success> { 753 [&epoll](const BuiltinArguments& args) -> Result<Success> {
735 KeychordInit(&epoll); 754 for (const auto& svc : ServiceList::GetInstance()) {
755 svc->set_keychord_id(GetKeychordId(svc->keycodes()));
756 }
757 KeychordInit(&epoll, HandleKeychord);
736 return Success(); 758 return Success();
737 }, 759 },
738 "KeychordInit"); 760 "KeychordInit");
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 418cdeb22..1a8f2aea3 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -33,10 +33,6 @@
33#include <vector> 33#include <vector>
34 34
35#include <android-base/logging.h> 35#include <android-base/logging.h>
36#include <android-base/properties.h>
37
38#include "init.h"
39#include "service.h"
40 36
41namespace android { 37namespace android {
42namespace init { 38namespace init {
@@ -45,6 +41,7 @@ namespace {
45 41
46int keychords_count; 42int keychords_count;
47Epoll* epoll; 43Epoll* epoll;
44std::function<void(int)> handle_keychord;
48 45
49struct KeychordEntry { 46struct KeychordEntry {
50 const std::vector<int> keycodes; 47 const std::vector<int> keycodes;
@@ -124,25 +121,6 @@ constexpr char kDevicePath[] = "/dev/input";
124 121
125std::map<std::string, int> keychord_registration; 122std::map<std::string, int> keychord_registration;
126 123
127void HandleKeychord(int id) {
128 // Only handle keychords if adb is enabled.
129 std::string adb_enabled = android::base::GetProperty("init.svc.adbd", "");
130 if (adb_enabled == "running") {
131 Service* svc = ServiceList::GetInstance().FindService(id, &Service::keychord_id);
132 if (svc) {
133 LOG(INFO) << "Starting service '" << svc->name() << "' from keychord " << id;
134 if (auto result = svc->Start(); !result) {
135 LOG(ERROR) << "Could not start service '" << svc->name() << "' from keychord " << id
136 << ": " << result.error();
137 }
138 } else {
139 LOG(ERROR) << "Service for keychord " << id << " not found";
140 }
141 } else {
142 LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled";
143 }
144}
145
146void KeychordLambdaCheck() { 124void KeychordLambdaCheck() {
147 for (auto& e : keychord_entries) { 125 for (auto& e : keychord_entries) {
148 bool found = true; 126 bool found = true;
@@ -156,7 +134,7 @@ void KeychordLambdaCheck() {
156 if (!found) continue; 134 if (!found) continue;
157 if (e.notified) continue; 135 if (e.notified) continue;
158 e.notified = true; 136 e.notified = true;
159 HandleKeychord(e.id); 137 handle_keychord(e.id);
160 } 138 }
161} 139}
162 140
@@ -169,12 +147,12 @@ void KeychordLambdaHandler(int fd) {
169} 147}
170 148
171bool KeychordGeteventEnable(int fd) { 149bool KeychordGeteventEnable(int fd) {
172 static bool EviocsmaskSupported = true;
173
174 // Make sure it is an event channel, should pass this ioctl call 150 // Make sure it is an event channel, should pass this ioctl call
175 int version; 151 int version;
176 if (::ioctl(fd, EVIOCGVERSION, &version)) return false; 152 if (::ioctl(fd, EVIOCGVERSION, &version)) return false;
177 153
154#ifdef EVIOCSMASK
155 static auto EviocsmaskSupported = true;
178 if (EviocsmaskSupported) { 156 if (EviocsmaskSupported) {
179 KeychordMask mask(EV_KEY); 157 KeychordMask mask(EV_KEY);
180 mask.SetBit(EV_KEY); 158 mask.SetBit(EV_KEY);
@@ -187,6 +165,7 @@ bool KeychordGeteventEnable(int fd) {
187 EviocsmaskSupported = false; 165 EviocsmaskSupported = false;
188 } 166 }
189 } 167 }
168#endif
190 169
191 KeychordMask mask; 170 KeychordMask mask;
192 for (auto& e : keychord_entries) { 171 for (auto& e : keychord_entries) {
@@ -202,6 +181,7 @@ bool KeychordGeteventEnable(int fd) {
202 if (res == -1) return false; 181 if (res == -1) return false;
203 if (!(available & mask)) return false; 182 if (!(available & mask)) return false;
204 183
184#ifdef EVIOCSMASK
205 if (EviocsmaskSupported) { 185 if (EviocsmaskSupported) {
206 input_mask msg = {}; 186 input_mask msg = {};
207 msg.type = EV_KEY; 187 msg.type = EV_KEY;
@@ -209,6 +189,7 @@ bool KeychordGeteventEnable(int fd) {
209 msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data()); 189 msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
210 ::ioctl(fd, EVIOCSMASK, &msg); 190 ::ioctl(fd, EVIOCSMASK, &msg);
211 } 191 }
192#endif
212 193
213 KeychordMask set(mask.size()); 194 KeychordMask set(mask.size());
214 res = ::ioctl(fd, EVIOCGKEY(res), set.data()); 195 res = ::ioctl(fd, EVIOCGKEY(res), set.data());
@@ -299,23 +280,18 @@ void GeteventOpenDevice() {
299 if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler); 280 if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler);
300} 281}
301 282
302void AddServiceKeycodes(Service* svc) { 283} // namespace
303 if (svc->keycodes().empty()) return; 284
304 for (auto& code : svc->keycodes()) { 285int GetKeychordId(const std::vector<int>& keycodes) {
305 if ((code < 0) || (code >= KEY_MAX)) return; 286 if (keycodes.empty()) return 0;
306 }
307 ++keychords_count; 287 ++keychords_count;
308 keychord_entries.emplace_back(KeychordEntry(svc->keycodes(), keychords_count)); 288 keychord_entries.emplace_back(KeychordEntry(keycodes, keychords_count));
309 svc->set_keychord_id(keychords_count); 289 return keychords_count;
310} 290}
311 291
312} // namespace 292void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler) {
313
314void KeychordInit(Epoll* init_epoll) {
315 epoll = init_epoll; 293 epoll = init_epoll;
316 for (const auto& service : ServiceList::GetInstance()) { 294 handle_keychord = handler;
317 AddServiceKeycodes(service.get());
318 }
319 if (keychords_count) GeteventOpenDevice(); 295 if (keychords_count) GeteventOpenDevice();
320} 296}
321 297
diff --git a/init/keychords.h b/init/keychords.h
index f3aecbb56..f273c8c2e 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -17,12 +17,16 @@
17#ifndef _INIT_KEYCHORDS_H_ 17#ifndef _INIT_KEYCHORDS_H_
18#define _INIT_KEYCHORDS_H_ 18#define _INIT_KEYCHORDS_H_
19 19
20#include <functional>
21#include <vector>
22
20#include "epoll.h" 23#include "epoll.h"
21 24
22namespace android { 25namespace android {
23namespace init { 26namespace init {
24 27
25void KeychordInit(Epoll* init_epoll); 28void KeychordInit(Epoll* init_epoll, std::function<void(int)> handler);
29int GetKeychordId(const std::vector<int>& keycodes);
26 30
27} // namespace init 31} // namespace init
28} // namespace android 32} // namespace android
diff --git a/init/service.cpp b/init/service.cpp
index 0e08d9bba..5778a93b0 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -18,6 +18,7 @@
18 18
19#include <fcntl.h> 19#include <fcntl.h>
20#include <inttypes.h> 20#include <inttypes.h>
21#include <linux/input.h>
21#include <linux/securebits.h> 22#include <linux/securebits.h>
22#include <sched.h> 23#include <sched.h>
23#include <sys/mount.h> 24#include <sys/mount.h>
@@ -544,10 +545,13 @@ Result<Success> Service::ParseIoprio(const std::vector<std::string>& args) {
544Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) { 545Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) {
545 for (std::size_t i = 1; i < args.size(); i++) { 546 for (std::size_t i = 1; i < args.size(); i++) {
546 int code; 547 int code;
547 if (ParseInt(args[i], &code)) { 548 if (ParseInt(args[i], &code, 0, KEY_MAX)) {
549 for (auto& key : keycodes_) {
550 if (key == code) return Error() << "duplicate keycode: " << args[i];
551 }
548 keycodes_.emplace_back(code); 552 keycodes_.emplace_back(code);
549 } else { 553 } else {
550 LOG(WARNING) << "ignoring invalid keycode: " << args[i]; 554 return Error() << "invalid keycode: " << args[i];
551 } 555 }
552 } 556 }
553 return Success(); 557 return Success();