Merge "libbase: add host properties support."
diff --git a/adb/Android.bp b/adb/Android.bp
index 1f41e4f..553473f 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -96,6 +96,7 @@
"adb_io.cpp",
"adb_listeners.cpp",
"adb_trace.cpp",
+ "adb_unique_fd.cpp",
"adb_utils.cpp",
"fdevent.cpp",
"services.cpp",
@@ -276,6 +277,7 @@
cc_library_static {
name: "libadbd",
defaults: ["adb_defaults"],
+ recovery_available: true,
// libminadbd wants both, for some reason.
compile_multilib: "both",
@@ -302,6 +304,7 @@
// adbd must be static, as it is copied into the recovery image.
static_executable: true,
+ recovery_available: true,
srcs: [
"daemon/main.cpp",
diff --git a/adb/adb_unique_fd.cpp b/adb/adb_unique_fd.cpp
new file mode 100644
index 0000000..2079be1
--- /dev/null
+++ b/adb/adb_unique_fd.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "adb_unique_fd.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "sysdeps.h"
+
+#if !defined(_WIN32)
+bool Pipe(unique_fd* read, unique_fd* write, int flags) {
+ int pipefd[2];
+#if !defined(__APPLE__)
+ if (pipe2(pipefd, flags) != 0) {
+ return false;
+ }
+#else
+ // Darwin doesn't have pipe2. Implement it ourselves.
+ if (flags != 0 && (flags & ~(O_CLOEXEC | O_NONBLOCK)) != 0) {
+ errno = EINVAL;
+ return false;
+ }
+
+ if (pipe(pipefd) != 0) {
+ return false;
+ }
+
+ if (flags & O_CLOEXEC) {
+ if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 ||
+ fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) {
+ adb_close(pipefd[0]);
+ adb_close(pipefd[1]);
+ return false;
+ }
+ }
+
+ if (flags & O_NONBLOCK) {
+ if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) != 0 ||
+ fcntl(pipefd[1], F_SETFL, O_NONBLOCK) != 0) {
+ adb_close(pipefd[0]);
+ adb_close(pipefd[1]);
+ return false;
+ }
+ }
+#endif
+
+ read->reset(pipefd[0]);
+ write->reset(pipefd[1]);
+ return true;
+}
+#endif
diff --git a/adb/adb_unique_fd.h b/adb/adb_unique_fd.h
index d1dc9d1..be63262 100644
--- a/adb/adb_unique_fd.h
+++ b/adb/adb_unique_fd.h
@@ -29,44 +29,5 @@
using unique_fd = android::base::unique_fd_impl<AdbCloser>;
#if !defined(_WIN32)
-inline bool Pipe(unique_fd* read, unique_fd* write, int flags = 0) {
- int pipefd[2];
-#if !defined(__APPLE__)
- if (pipe2(pipefd, flags) != 0) {
- return false;
- }
-#else
- // Darwin doesn't have pipe2. Implement it ourselves.
- if (flags != 0 && (flags & ~(O_CLOEXEC | O_NONBLOCK)) != 0) {
- errno = EINVAL;
- return false;
- }
-
- if (pipe(pipefd) != 0) {
- return false;
- }
-
- if (flags & O_CLOEXEC) {
- if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) != 0 ||
- fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) != 0) {
- close(pipefd[0]);
- close(pipefd[1]);
- return false;
- }
- }
-
- if (flags & O_NONBLOCK) {
- if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) != 0 ||
- fcntl(pipefd[1], F_SETFL, O_NONBLOCK) != 0) {
- close(pipefd[0]);
- close(pipefd[1]);
- return false;
- }
- }
-#endif
-
- read->reset(pipefd[0]);
- write->reset(pipefd[1]);
- return true;
-}
+bool Pipe(unique_fd* read, unique_fd* write, int flags = 0);
#endif
diff --git a/base/Android.bp b/base/Android.bp
index 3e51af3..3d80d97 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -93,6 +93,7 @@
name: "libbase",
defaults: ["libbase_defaults"],
vendor_available: true,
+ recovery_available: true,
host_supported: true,
vndk: {
enabled: true,
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 7c28b28..0b13662 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -17,6 +17,7 @@
cc_library_headers {
name: "libdebuggerd_common_headers",
export_include_dirs: ["common/include"],
+ recovery_available: true,
}
cc_library_shared {
@@ -67,6 +68,7 @@
cc_library_static {
name: "libdebuggerd_handler_core",
defaults: ["debuggerd_defaults"],
+ recovery_available: true,
srcs: ["handler/debuggerd_handler.cpp"],
header_libs: [
@@ -88,6 +90,7 @@
cc_library_static {
name: "libdebuggerd_handler",
defaults: ["debuggerd_defaults"],
+ recovery_available: true,
srcs: ["handler/debuggerd_fallback_nop.cpp"],
whole_static_libs: [
@@ -143,6 +146,7 @@
cc_library_static {
name: "libdebuggerd",
defaults: ["debuggerd_defaults"],
+ recovery_available: true,
srcs: [
"libdebuggerd/backtrace.cpp",
diff --git a/demangle/Android.bp b/demangle/Android.bp
index cf6abfd..fd79cf8 100644
--- a/demangle/Android.bp
+++ b/demangle/Android.bp
@@ -36,6 +36,7 @@
name: "libdemangle",
defaults: ["libdemangle_defaults"],
vendor_available: true,
+ recovery_available: true,
srcs: [
"Demangler.cpp",
diff --git a/diagnose_usb/Android.bp b/diagnose_usb/Android.bp
index a7ecf37..6bee28c 100644
--- a/diagnose_usb/Android.bp
+++ b/diagnose_usb/Android.bp
@@ -2,6 +2,7 @@
name: "libdiagnose_usb",
cflags: ["-Wall", "-Wextra", "-Werror"],
host_supported: true,
+ recovery_available: true,
target: {
windows: {
enabled: true,
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 6493262..5aa87d9 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -316,7 +316,8 @@
static int show_help() {
// clang-format off
fprintf(stdout,
-/* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */
+// 1 2 3 4 5 6 7 8
+// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
"usage: fastboot [OPTION...] COMMAND...\n"
"\n"
"flashing:\n"
@@ -324,8 +325,8 @@
" flashall Flash all partitions from $ANDROID_PRODUCT_OUT.\n"
" On A/B devices, flashed slot is set as active.\n"
" Secondary images may be flashed to inactive slot.\n"
- " flash PARTITION [FILENAME]\n"
- " Flash given partition only.\n"
+ " flash PARTITION [FILENAME] Flash given partition, using the image from\n"
+ " $ANDROID_PRODUCT_OUT if no filename is given.\n"
"\n"
"basics:\n"
" devices [-l] List devices in bootloader (-l: with device paths).\n"
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 05dba15..bc3b04b 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -33,6 +33,7 @@
cc_library_static {
name: "libfs_mgr",
defaults: ["fs_mgr_defaults"],
+ recovery_available: true,
export_include_dirs: ["include"],
include_dirs: ["system/vold"],
srcs: [
@@ -79,6 +80,7 @@
cc_library_static {
name: "libfstab",
vendor_available: true,
+ recovery_available: true,
defaults: ["fs_mgr_defaults"],
srcs: [
"fs_mgr_fstab.cpp",
diff --git a/init/Android.bp b/init/Android.bp
index 63f3fca..a3083c1 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -232,6 +232,8 @@
"action_parser.cpp",
"capabilities.cpp",
"descriptors.cpp",
+ "epoll.cpp",
+ "keychords.cpp",
"import_parser.cpp",
"host_init_parser.cpp",
"host_init_stubs.cpp",
diff --git a/init/init.cpp b/init/init.cpp
index fd9a90c..5652c5e 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -553,6 +553,25 @@
}
}
+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);
@@ -730,9 +749,13 @@
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
+ Keychords keychords;
am.QueueBuiltinAction(
- [&epoll](const BuiltinArguments& args) -> Result<Success> {
- KeychordInit(&epoll);
+ [&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
+ for (const auto& svc : ServiceList::GetInstance()) {
+ svc->set_keychord_id(keychords.GetId(svc->keycodes()));
+ }
+ keychords.Start(&epoll, HandleKeychord);
return Success();
},
"KeychordInit");
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 418cdeb..9aa8b2a 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -33,121 +33,89 @@
#include <vector>
#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-#include "init.h"
-#include "service.h"
namespace android {
namespace init {
-namespace {
+Keychords::Keychords() : epoll_(nullptr), count_(0), inotify_fd_(-1) {}
-int keychords_count;
-Epoll* epoll;
-
-struct KeychordEntry {
- const std::vector<int> keycodes;
- bool notified;
- int id;
-
- KeychordEntry(const std::vector<int>& keycodes, int id)
- : keycodes(keycodes), notified(false), id(id) {}
-};
-
-std::vector<KeychordEntry> keychord_entries;
-
-// Bit management
-class KeychordMask {
- private:
- typedef unsigned int mask_t;
- std::vector<mask_t> bits;
- static constexpr size_t bits_per_byte = 8;
-
- public:
- explicit KeychordMask(size_t bit = 0) : bits((bit + sizeof(mask_t) - 1) / sizeof(mask_t), 0) {}
-
- void SetBit(size_t bit, bool value = true) {
- auto idx = bit / (bits_per_byte * sizeof(mask_t));
- if (idx >= bits.size()) return;
- if (value) {
- bits[idx] |= mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t)));
- } else {
- bits[idx] &= ~(mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
- }
+Keychords::~Keychords() noexcept {
+ if (inotify_fd_ >= 0) {
+ epoll_->UnregisterHandler(inotify_fd_);
+ ::close(inotify_fd_);
}
+ while (!registration_.empty()) GeteventCloseDevice(registration_.begin()->first);
+}
- bool GetBit(size_t bit) const {
- auto idx = bit / (bits_per_byte * sizeof(mask_t));
- return bits[idx] & (mask_t(1) << (bit % (bits_per_byte * sizeof(mask_t))));
- }
+Keychords::Mask::Mask(size_t bit) : bits_((bit + sizeof(mask_t) - 1) / sizeof(mask_t), 0) {}
- size_t bytesize() const { return bits.size() * sizeof(mask_t); }
- void* data() { return bits.data(); }
- size_t size() const { return bits.size() * sizeof(mask_t) * bits_per_byte; }
- void resize(size_t bit) {
- auto idx = bit / (bits_per_byte * sizeof(mask_t));
- if (idx >= bits.size()) {
- bits.resize(idx + 1, 0);
- }
- }
-
- operator bool() const {
- for (size_t i = 0; i < bits.size(); ++i) {
- if (bits[i]) return true;
- }
- return false;
- }
-
- KeychordMask operator&(const KeychordMask& rval) const {
- auto len = std::min(bits.size(), rval.bits.size());
- KeychordMask ret;
- ret.bits.resize(len);
- for (size_t i = 0; i < len; ++i) {
- ret.bits[i] = bits[i] & rval.bits[i];
- }
- return ret;
- }
-
- void operator|=(const KeychordMask& rval) {
- size_t len = rval.bits.size();
- bits.resize(len);
- for (size_t i = 0; i < len; ++i) {
- bits[i] |= rval.bits[i];
- }
- }
-};
-
-KeychordMask keychord_current;
-
-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";
- }
+void Keychords::Mask::SetBit(size_t bit, bool value) {
+ auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+ if (idx >= bits_.size()) return;
+ if (value) {
+ bits_[idx] |= mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t)));
} else {
- LOG(WARNING) << "Not starting service for keychord " << id << " because ADB is disabled";
+ bits_[idx] &= ~(mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t))));
}
}
-void KeychordLambdaCheck() {
- for (auto& e : keychord_entries) {
- bool found = true;
+bool Keychords::Mask::GetBit(size_t bit) const {
+ auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+ return bits_[idx] & (mask_t(1) << (bit % (kBitsPerByte * sizeof(mask_t))));
+}
+
+size_t Keychords::Mask::bytesize() const {
+ return bits_.size() * sizeof(mask_t);
+}
+
+void* Keychords::Mask::data() {
+ return bits_.data();
+}
+
+size_t Keychords::Mask::size() const {
+ return bits_.size() * sizeof(mask_t) * kBitsPerByte;
+}
+
+void Keychords::Mask::resize(size_t bit) {
+ auto idx = bit / (kBitsPerByte * sizeof(mask_t));
+ if (idx >= bits_.size()) {
+ bits_.resize(idx + 1, 0);
+ }
+}
+
+Keychords::Mask::operator bool() const {
+ for (size_t i = 0; i < bits_.size(); ++i) {
+ if (bits_[i]) return true;
+ }
+ return false;
+}
+
+Keychords::Mask Keychords::Mask::operator&(const Keychords::Mask& rval) const {
+ auto len = std::min(bits_.size(), rval.bits_.size());
+ Keychords::Mask ret;
+ ret.bits_.resize(len);
+ for (size_t i = 0; i < len; ++i) {
+ ret.bits_[i] = bits_[i] & rval.bits_[i];
+ }
+ return ret;
+}
+
+void Keychords::Mask::operator|=(const Keychords::Mask& rval) {
+ auto len = rval.bits_.size();
+ bits_.resize(len);
+ for (size_t i = 0; i < len; ++i) {
+ bits_[i] |= rval.bits_[i];
+ }
+}
+
+Keychords::Entry::Entry(const std::vector<int>& keycodes, int id)
+ : keycodes(keycodes), id(id), notified(false) {}
+
+void Keychords::LambdaCheck() {
+ for (auto& e : entries_) {
+ auto found = true;
for (auto& code : e.keycodes) {
- if (!keychord_current.GetBit(code)) {
+ if (!current_.GetBit(code)) {
e.notified = false;
found = false;
break;
@@ -156,27 +124,27 @@
if (!found) continue;
if (e.notified) continue;
e.notified = true;
- HandleKeychord(e.id);
+ handler_(e.id);
}
}
-void KeychordLambdaHandler(int fd) {
+void Keychords::LambdaHandler(int fd) {
input_event event;
auto res = TEMP_FAILURE_RETRY(::read(fd, &event, sizeof(event)));
if ((res != sizeof(event)) || (event.type != EV_KEY)) return;
- keychord_current.SetBit(event.code, event.value);
- KeychordLambdaCheck();
+ current_.SetBit(event.code, event.value);
+ LambdaCheck();
}
-bool KeychordGeteventEnable(int fd) {
- static bool EviocsmaskSupported = true;
-
+bool Keychords::GeteventEnable(int fd) {
// 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);
+ Keychords::Mask mask(EV_KEY);
mask.SetBit(EV_KEY);
input_mask msg = {};
msg.type = EV_SYN;
@@ -187,21 +155,23 @@
EviocsmaskSupported = false;
}
}
+#endif
- KeychordMask mask;
- for (auto& e : keychord_entries) {
+ Keychords::Mask mask;
+ for (auto& e : entries_) {
for (auto& code : e.keycodes) {
mask.resize(code);
mask.SetBit(code);
}
}
- keychord_current.resize(mask.size());
- KeychordMask available(mask.size());
+ current_.resize(mask.size());
+ Keychords::Mask available(mask.size());
auto res = ::ioctl(fd, EVIOCGBIT(EV_KEY, available.bytesize()), available.data());
if (res == -1) return false;
if (!(available & mask)) return false;
+#ifdef EVIOCSMASK
if (EviocsmaskSupported) {
input_mask msg = {};
msg.type = EV_KEY;
@@ -209,46 +179,45 @@
msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
::ioctl(fd, EVIOCSMASK, &msg);
}
+#endif
- KeychordMask set(mask.size());
+ Keychords::Mask set(mask.size());
res = ::ioctl(fd, EVIOCGKEY(res), set.data());
if (res > 0) {
- keychord_current |= mask & available & set;
- KeychordLambdaCheck();
+ current_ |= mask & available & set;
+ LambdaCheck();
}
- epoll->RegisterHandler(fd, [fd]() { KeychordLambdaHandler(fd); });
+ epoll_->RegisterHandler(fd, [this, fd]() { this->LambdaHandler(fd); });
return true;
}
-void GeteventOpenDevice(const std::string& device) {
- if (keychord_registration.count(device)) return;
+void Keychords::GeteventOpenDevice(const std::string& device) {
+ if (registration_.count(device)) return;
auto fd = TEMP_FAILURE_RETRY(::open(device.c_str(), O_RDWR | O_CLOEXEC));
if (fd == -1) {
PLOG(ERROR) << "Can not open " << device;
return;
}
- if (!KeychordGeteventEnable(fd)) {
+ if (!GeteventEnable(fd)) {
::close(fd);
} else {
- keychord_registration.emplace(device, fd);
+ registration_.emplace(device, fd);
}
}
-void GeteventCloseDevice(const std::string& device) {
- auto it = keychord_registration.find(device);
- if (it == keychord_registration.end()) return;
+void Keychords::GeteventCloseDevice(const std::string& device) {
+ auto it = registration_.find(device);
+ if (it == registration_.end()) return;
auto fd = (*it).second;
- epoll->UnregisterHandler(fd);
- keychord_registration.erase(it);
+ epoll_->UnregisterHandler(fd);
+ registration_.erase(it);
::close(fd);
}
-int inotify_fd = -1;
+void Keychords::InotifyHandler() {
+ unsigned char buf[512]; // History shows 32-64 bytes typical
-void InotifyHandler() {
- unsigned char buf[512];
-
- auto res = TEMP_FAILURE_RETRY(::read(inotify_fd, buf, sizeof(buf)));
+ auto res = TEMP_FAILURE_RETRY(::read(inotify_fd_, buf, sizeof(buf)));
if (res < 0) {
PLOG(WARNING) << "could not get event";
return;
@@ -274,14 +243,15 @@
}
}
-void GeteventOpenDevice() {
- inotify_fd = ::inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
- if (inotify_fd < 0) {
+void Keychords::GeteventOpenDevice() {
+ inotify_fd_ = ::inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (inotify_fd_ < 0) {
PLOG(WARNING) << "Could not instantiate inotify for " << kDevicePath;
- } else if (::inotify_add_watch(inotify_fd, kDevicePath, IN_DELETE | IN_CREATE | IN_ONLYDIR) < 0) {
+ } else if (::inotify_add_watch(inotify_fd_, kDevicePath, IN_DELETE | IN_CREATE | IN_ONLYDIR) <
+ 0) {
PLOG(WARNING) << "Could not add watch for " << kDevicePath;
- ::close(inotify_fd);
- inotify_fd = -1;
+ ::close(inotify_fd_);
+ inotify_fd_ = -1;
}
std::unique_ptr<DIR, decltype(&closedir)> device(opendir(kDevicePath), closedir);
@@ -296,27 +266,22 @@
}
}
- if (inotify_fd >= 0) epoll->RegisterHandler(inotify_fd, InotifyHandler);
+ if (inotify_fd_ >= 0) {
+ epoll_->RegisterHandler(inotify_fd_, [this]() { this->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);
+int Keychords::GetId(const std::vector<int>& keycodes) {
+ if (keycodes.empty()) return 0;
+ ++count_;
+ entries_.emplace_back(Entry(keycodes, count_));
+ return count_;
}
-} // namespace
-
-void KeychordInit(Epoll* init_epoll) {
- epoll = init_epoll;
- for (const auto& service : ServiceList::GetInstance()) {
- AddServiceKeycodes(service.get());
- }
- if (keychords_count) GeteventOpenDevice();
+void Keychords::Start(Epoll* epoll, std::function<void(int)> handler) {
+ epoll_ = epoll;
+ handler_ = handler;
+ if (count_) GeteventOpenDevice();
}
} // namespace init
diff --git a/init/keychords.h b/init/keychords.h
index f3aecbb..74a9195 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -17,12 +17,84 @@
#ifndef _INIT_KEYCHORDS_H_
#define _INIT_KEYCHORDS_H_
+#include <functional>
+#include <map>
+#include <string>
+#include <vector>
+
#include "epoll.h"
namespace android {
namespace init {
-void KeychordInit(Epoll* init_epoll);
+class Keychords {
+ public:
+ Keychords();
+ Keychords(const Keychords&) = delete;
+ Keychords(Keychords&&) = delete;
+ Keychords& operator=(const Keychords&) = delete;
+ Keychords& operator=(Keychords&&) = delete;
+ ~Keychords() noexcept;
+
+ int GetId(const std::vector<int>& keycodes);
+ void Start(Epoll* epoll, std::function<void(int)> handler);
+
+ private:
+ // Bit management
+ class Mask {
+ public:
+ explicit Mask(size_t bit = 0);
+
+ void SetBit(size_t bit, bool value = true);
+ bool GetBit(size_t bit) const;
+
+ size_t bytesize() const;
+ void* data();
+ size_t size() const;
+ void resize(size_t bit);
+
+ operator bool() const;
+ Mask operator&(const Mask& rval) const;
+ void operator|=(const Mask& rval);
+
+ private:
+ typedef unsigned int mask_t;
+ static constexpr size_t kBitsPerByte = 8;
+
+ std::vector<mask_t> bits_;
+ };
+
+ struct Entry {
+ Entry(const std::vector<int>& keycodes, int id);
+
+ const std::vector<int> keycodes;
+ const int id;
+ bool notified;
+ };
+
+ static constexpr char kDevicePath[] = "/dev/input";
+
+ void LambdaCheck();
+ void LambdaHandler(int fd);
+ void InotifyHandler();
+
+ bool GeteventEnable(int fd);
+ void GeteventOpenDevice(const std::string& device);
+ void GeteventOpenDevice();
+ void GeteventCloseDevice(const std::string& device);
+
+ Epoll* epoll_;
+ std::function<void(int)> handler_;
+
+ std::map<std::string, int> registration_;
+
+ int count_;
+ std::vector<Entry> entries_;
+
+ Mask current_;
+
+ int inotify_fd_;
+};
} // namespace init
} // namespace android
diff --git a/init/service.cpp b/init/service.cpp
index c9ed87f..a698735 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -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>
@@ -543,10 +544,13 @@
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();
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 8a2afea..4ab439d 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -27,6 +27,7 @@
name: "libasyncio",
defaults: ["libasyncio_defaults"],
vendor_available: true,
+ recovery_available: true,
host_supported: true,
srcs: [
"AsyncIO.cpp",
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 0f93dd0..b4bf35f 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -58,6 +58,7 @@
cc_library {
name: "libbacktrace",
vendor_available: false,
+ recovery_available: true,
vndk: {
enabled: true,
support_system_process: true,
@@ -102,8 +103,6 @@
include_dirs: [
"art/runtime",
],
-
- header_libs: ["jni_headers"],
},
android: {
static_libs: ["libasync_safe"],
@@ -112,6 +111,10 @@
cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
exclude_shared_libs: ["libdexfile"],
},
+ recovery: {
+ cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
+ exclude_shared_libs: ["libdexfile"],
+ },
},
whole_static_libs: ["libdemangle"],
}
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 1e3d379..f78a31f 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -46,6 +46,7 @@
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
#include <cutils/atomic.h>
#include <cutils/threads.h>
@@ -1186,49 +1187,45 @@
ASSERT_TRUE(expected_functions.empty()) << "Not all functions found in shared library.";
}
-static const char* CopySharedLibrary() {
-#if defined(__LP64__)
- const char* lib_name = "lib64";
-#else
- const char* lib_name = "lib";
-#endif
+static void CopySharedLibrary(const char* tmp_dir, std::string* tmp_so_name) {
+ std::string system_dir;
#if defined(__BIONIC__)
- const char* tmp_so_name = "/data/local/tmp/libbacktrace_test.so";
- std::string cp_cmd = android::base::StringPrintf("cp /system/%s/libbacktrace_test.so %s",
- lib_name, tmp_so_name);
+ system_dir = "/system/lib";
#else
- const char* tmp_so_name = "/tmp/libbacktrace_test.so";
- if (getenv("ANDROID_HOST_OUT") == NULL) {
- fprintf(stderr, "ANDROID_HOST_OUT not set, make sure you run lunch.");
- return nullptr;
- }
- std::string cp_cmd = android::base::StringPrintf("cp %s/%s/libbacktrace_test.so %s",
- getenv("ANDROID_HOST_OUT"), lib_name,
- tmp_so_name);
+ const char* host_out_env = getenv("ANDROID_HOST_OUT");
+ ASSERT_TRUE(host_out_env != nullptr);
+ system_dir = std::string(host_out_env) + "/lib";
#endif
- // Copy the shared so to a tempory directory.
- system(cp_cmd.c_str());
+#if defined(__LP64__)
+ system_dir += "64";
+#endif
- return tmp_so_name;
+ *tmp_so_name = std::string(tmp_dir) + "/libbacktrace_test.so";
+ std::string cp_cmd =
+ android::base::StringPrintf("cp %s/libbacktrace_test.so %s", system_dir.c_str(), tmp_dir);
+
+ // Copy the shared so to a tempory directory.
+ ASSERT_EQ(0, system(cp_cmd.c_str()));
}
TEST(libbacktrace, check_unreadable_elf_local) {
- const char* tmp_so_name = CopySharedLibrary();
- ASSERT_TRUE(tmp_so_name != nullptr);
+ TemporaryDir td;
+ std::string tmp_so_name;
+ ASSERT_NO_FATAL_FAILURE(CopySharedLibrary(td.path, &tmp_so_name));
struct stat buf;
- ASSERT_TRUE(stat(tmp_so_name, &buf) != -1);
+ ASSERT_TRUE(stat(tmp_so_name.c_str(), &buf) != -1);
uint64_t map_size = buf.st_size;
- int fd = open(tmp_so_name, O_RDONLY);
+ int fd = open(tmp_so_name.c_str(), O_RDONLY);
ASSERT_TRUE(fd != -1);
void* map = mmap(nullptr, map_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
ASSERT_TRUE(map != MAP_FAILED);
close(fd);
- ASSERT_TRUE(unlink(tmp_so_name) != -1);
+ ASSERT_TRUE(unlink(tmp_so_name.c_str()) != -1);
std::vector<std::string> found_functions;
std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS,
@@ -1256,32 +1253,33 @@
}
TEST(libbacktrace, check_unreadable_elf_remote) {
- const char* tmp_so_name = CopySharedLibrary();
- ASSERT_TRUE(tmp_so_name != nullptr);
+ TemporaryDir td;
+ std::string tmp_so_name;
+ ASSERT_NO_FATAL_FAILURE(CopySharedLibrary(td.path, &tmp_so_name));
g_ready = 0;
struct stat buf;
- ASSERT_TRUE(stat(tmp_so_name, &buf) != -1);
+ ASSERT_TRUE(stat(tmp_so_name.c_str(), &buf) != -1);
uint64_t map_size = buf.st_size;
pid_t pid;
if ((pid = fork()) == 0) {
- int fd = open(tmp_so_name, O_RDONLY);
+ int fd = open(tmp_so_name.c_str(), O_RDONLY);
if (fd == -1) {
- fprintf(stderr, "Failed to open file %s: %s\n", tmp_so_name, strerror(errno));
- unlink(tmp_so_name);
+ fprintf(stderr, "Failed to open file %s: %s\n", tmp_so_name.c_str(), strerror(errno));
+ unlink(tmp_so_name.c_str());
exit(0);
}
void* map = mmap(nullptr, map_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
fprintf(stderr, "Failed to map in memory: %s\n", strerror(errno));
- unlink(tmp_so_name);
+ unlink(tmp_so_name.c_str());
exit(0);
}
close(fd);
- if (unlink(tmp_so_name) == -1) {
+ if (unlink(tmp_so_name.c_str()) == -1) {
fprintf(stderr, "Failed to unlink: %s\n", strerror(errno));
exit(0);
}
@@ -1394,11 +1392,13 @@
typedef int (*test_func_t)(int, int, int, int, void (*)(void*), void*);
TEST(libbacktrace, unwind_through_unreadable_elf_local) {
- const char* tmp_so_name = CopySharedLibrary();
- ASSERT_TRUE(tmp_so_name != nullptr);
- void* lib_handle = dlopen(tmp_so_name, RTLD_NOW);
+ TemporaryDir td;
+ std::string tmp_so_name;
+ ASSERT_NO_FATAL_FAILURE(CopySharedLibrary(td.path, &tmp_so_name));
+
+ void* lib_handle = dlopen(tmp_so_name.c_str(), RTLD_NOW);
ASSERT_TRUE(lib_handle != nullptr);
- ASSERT_TRUE(unlink(tmp_so_name) != -1);
+ ASSERT_TRUE(unlink(tmp_so_name.c_str()) != -1);
test_func_t test_func;
test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one"));
@@ -1411,11 +1411,13 @@
}
TEST(libbacktrace, unwind_through_unreadable_elf_remote) {
- const char* tmp_so_name = CopySharedLibrary();
- ASSERT_TRUE(tmp_so_name != nullptr);
- void* lib_handle = dlopen(tmp_so_name, RTLD_NOW);
+ TemporaryDir td;
+ std::string tmp_so_name;
+ ASSERT_NO_FATAL_FAILURE(CopySharedLibrary(td.path, &tmp_so_name));
+
+ void* lib_handle = dlopen(tmp_so_name.c_str(), RTLD_NOW);
ASSERT_TRUE(lib_handle != nullptr);
- ASSERT_TRUE(unlink(tmp_so_name) != -1);
+ ASSERT_TRUE(unlink(tmp_so_name.c_str()) != -1);
test_func_t test_func;
test_func = reinterpret_cast<test_func_t>(dlsym(lib_handle, "test_level_one"));
@@ -1444,7 +1446,8 @@
size_t frame_num;
if (FindFuncFrameInBacktrace(backtrace.get(), reinterpret_cast<uint64_t>(test_func),
- &frame_num)) {
+ &frame_num) &&
+ frame_num != 0) {
VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast<uint64_t>(test_func), frame_num);
done = true;
}
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index 47de12a..e47560f 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -17,6 +17,7 @@
cc_library {
name: "libcrypto_utils",
vendor_available: true,
+ recovery_available: true,
vndk: {
enabled: true,
},
diff --git a/libkeyutils/Android.bp b/libkeyutils/Android.bp
index f3593ff..b388e95 100644
--- a/libkeyutils/Android.bp
+++ b/libkeyutils/Android.bp
@@ -2,6 +2,7 @@
name: "libkeyutils",
cflags: ["-Werror"],
defaults: ["linux_bionic_supported"],
+ recovery_available: true,
export_include_dirs: ["include/"],
local_include_dirs: ["include/"],
srcs: ["keyutils.cpp"],
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index d776b3d..15f03d0 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -27,6 +27,7 @@
name: "libprocinfo",
defaults: ["libprocinfo_defaults"],
vendor_available: true,
+ recovery_available: true,
vndk: {
enabled: true,
},
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index b894656..c7c089f 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -3,6 +3,7 @@
cc_library {
name: "libsparse",
host_supported: true,
+ recovery_available: true,
unique_host_soname: true,
srcs: [
"backed_block.c",
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 435ed94..26be64d 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -38,6 +38,7 @@
cc_library {
name: "libunwindstack",
vendor_available: true,
+ recovery_available: true,
vndk: {
enabled: true,
support_system_process: true,
@@ -94,6 +95,14 @@
],
exclude_shared_libs: ["libdexfile"],
},
+ recovery: {
+ cflags: ["-DNO_LIBDEXFILE_SUPPORT"],
+ exclude_srcs: [
+ "DexFile.cpp",
+ "DexFiles.cpp",
+ ],
+ exclude_shared_libs: ["libdexfile"],
+ },
},
arch: {
diff --git a/logwrapper/Android.bp b/logwrapper/Android.bp
index d4ba4f4..c378646 100644
--- a/logwrapper/Android.bp
+++ b/logwrapper/Android.bp
@@ -12,6 +12,7 @@
cc_library {
name: "liblogwrap",
defaults: ["logwrapper_defaults"],
+ recovery_available: true,
srcs: ["logwrap.c"],
shared_libs: [
"libcutils",
diff --git a/qemu_pipe/Android.bp b/qemu_pipe/Android.bp
index 93c347b..c6bda4a 100644
--- a/qemu_pipe/Android.bp
+++ b/qemu_pipe/Android.bp
@@ -3,6 +3,7 @@
cc_library_static {
name: "libqemu_pipe",
vendor_available: true,
+ recovery_available: true,
sanitize: {
misc_undefined: ["integer"],
},