Merge "Match LZMA SDK 18.05 API."
diff --git a/adb/Android.bp b/adb/Android.bp
index b9a1596..99de54e 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -222,7 +222,6 @@
cc_binary_host {
name: "adb",
- tags: ["debug"],
defaults: ["adb_defaults"],
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 3bf281c..76ca19a 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -365,8 +365,8 @@
switch (p->msg.arg0) {
#if ADB_HOST
case ADB_AUTH_TOKEN:
- if (t->GetConnectionState() == kCsOffline) {
- t->SetConnectionState(kCsUnauthorized);
+ if (t->GetConnectionState() != kCsAuthorizing) {
+ t->SetConnectionState(kCsAuthorizing);
}
send_auth_response(p->payload.data(), p->msg.data_length, t);
break;
@@ -1103,14 +1103,11 @@
if (!strcmp(service, "reconnect-offline")) {
std::string response;
close_usb_devices([&response](const atransport* transport) {
- switch (transport->GetConnectionState()) {
- case kCsOffline:
- case kCsUnauthorized:
- response += "reconnecting " + transport->serial_name() + "\n";
- return true;
- default:
- return false;
+ if (!ConnectionStateIsOnline(transport->GetConnectionState())) {
+ response += "reconnecting " + transport->serial_name() + "\n";
+ return true;
}
+ return false;
});
if (!response.empty()) {
response.resize(response.size() - 1);
diff --git a/adb/adb.h b/adb/adb.h
index 1e58ee1..ede55da 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -95,16 +95,33 @@
enum ConnectionState {
kCsAny = -1,
- kCsOffline = 0,
+
+ kCsConnecting = 0, // Haven't received a response from the device yet.
+ kCsAuthorizing, // Authorizing with keys from ADB_VENDOR_KEYS.
+ kCsUnauthorized, // ADB_VENDOR_KEYS exhausted, fell back to user prompt.
+ kCsNoPerm, // Insufficient permissions to communicate with the device.
+ kCsOffline,
+
kCsBootloader,
kCsDevice,
kCsHost,
kCsRecovery,
- kCsNoPerm, // Insufficient permissions to communicate with the device.
kCsSideload,
- kCsUnauthorized,
};
+inline bool ConnectionStateIsOnline(ConnectionState state) {
+ switch (state) {
+ case kCsBootloader:
+ case kCsDevice:
+ case kCsHost:
+ case kCsRecovery:
+ case kCsSideload:
+ return true;
+ default:
+ return false;
+ }
+}
+
void print_packet(const char* label, apacket* p);
// These use the system (v)fprintf, not the adb prefixed ones defined in sysdeps.h, so they
diff --git a/adb/client/auth.cpp b/adb/client/auth.cpp
index ade2623..0f4dd33 100644
--- a/adb/client/auth.cpp
+++ b/adb/client/auth.cpp
@@ -464,6 +464,7 @@
std::shared_ptr<RSA> key = t->NextKey();
if (key == nullptr) {
// No more private keys to try, send the public key.
+ t->SetConnectionState(kCsUnauthorized);
send_auth_publickey(t);
return;
}
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index e476e07..39983ab 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -149,8 +149,8 @@
" emu COMMAND run emulator console command\n"
"\n"
"app installation:\n"
- " install [-lrtsdg] PACKAGE\n"
- " install-multiple [-lrtsdpg] PACKAGE...\n"
+ " install [-lrtsdg] [--instant] PACKAGE\n"
+ " install-multiple [-lrtsdpg] [--instant] PACKAGE...\n"
" push package(s) to the device and install them\n"
" -l: forward lock application\n"
" -r: replace existing application\n"
@@ -159,6 +159,7 @@
" -d: allow version code downgrade (debuggable packages only)\n"
" -p: partial application install (install-multiple only)\n"
" -g: grant all runtime permissions\n"
+ " --instant: cause the app to be installed as an ephemeral install app\n"
" uninstall [-k] PACKAGE\n"
" remove this app package from the device\n"
" '-k': keep the data and cache directories\n"
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 7bc0165..e567ff4 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -750,7 +750,7 @@
if (!s->transport) {
SendFail(s->peer->fd, "device offline (no transport)");
goto fail;
- } else if (s->transport->GetConnectionState() == kCsOffline) {
+ } else if (!ConnectionStateIsOnline(s->transport->GetConnectionState())) {
/* if there's no remote we fail the connection
** right here and terminate it
*/
diff --git a/adb/transport.cpp b/adb/transport.cpp
index fa7cc8c..be7f8fe 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -708,22 +708,41 @@
}
lock.unlock();
- // Don't return unauthorized devices; the caller can't do anything with them.
- if (result && result->GetConnectionState() == kCsUnauthorized && !accept_any_state) {
- *error_out = "device unauthorized.\n";
- char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
- *error_out += "This adb server's $ADB_VENDOR_KEYS is ";
- *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
- *error_out += "\n";
- *error_out += "Try 'adb kill-server' if that seems wrong.\n";
- *error_out += "Otherwise check for a confirmation dialog on your device.";
- result = nullptr;
- }
+ if (result && !accept_any_state) {
+ // The caller requires an active transport.
+ // Make sure that we're actually connected.
+ ConnectionState state = result->GetConnectionState();
+ switch (state) {
+ case kCsConnecting:
+ *error_out = "device still connecting";
+ result = nullptr;
+ break;
- // Don't return offline devices; the caller can't do anything with them.
- if (result && result->GetConnectionState() == kCsOffline && !accept_any_state) {
- *error_out = "device offline";
- result = nullptr;
+ case kCsAuthorizing:
+ *error_out = "device still authorizing";
+ result = nullptr;
+ break;
+
+ case kCsUnauthorized: {
+ *error_out = "device unauthorized.\n";
+ char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
+ *error_out += "This adb server's $ADB_VENDOR_KEYS is ";
+ *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
+ *error_out += "\n";
+ *error_out += "Try 'adb kill-server' if that seems wrong.\n";
+ *error_out += "Otherwise check for a confirmation dialog on your device.";
+ result = nullptr;
+ break;
+ }
+
+ case kCsOffline:
+ *error_out = "device offline";
+ result = nullptr;
+ break;
+
+ default:
+ break;
+ }
}
if (result) {
@@ -802,6 +821,10 @@
return "sideload";
case kCsUnauthorized:
return "unauthorized";
+ case kCsAuthorizing:
+ return "authorizing";
+ case kCsConnecting:
+ return "connecting";
default:
return "unknown";
}
@@ -1080,7 +1103,7 @@
void register_usb_transport(usb_handle* usb, const char* serial, const char* devpath,
unsigned writeable) {
- atransport* t = new atransport((writeable ? kCsOffline : kCsNoPerm));
+ atransport* t = new atransport((writeable ? kCsConnecting : kCsNoPerm));
D("transport: %p init'ing for usb_handle %p (sn='%s')", t, usb, serial ? serial : "");
init_usb_transport(t, usb);
diff --git a/adb/transport.h b/adb/transport.h
index ebc186b..e1cbc09 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -198,7 +198,7 @@
// class in one go is a very large change. Given how bad our testing is,
// it's better to do this piece by piece.
- atransport(ConnectionState state = kCsOffline)
+ atransport(ConnectionState state = kCsConnecting)
: id(NextTransportId()),
connection_state_(state),
connection_waitable_(std::make_shared<ConnectionWaitable>()),
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index b194bbe..01b8948 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -312,6 +312,7 @@
init : processing action (ro.boot.bootreason=*) from (/system/etc/init/bootstat.rc
init : processing action (sys.boot_completed=1 && sys.logbootcomplete=1) from (/system/etc/init/bootstat.rc
(/system/bin/bootstat --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l)'
+ (/system/bin/bootstat --set_system_boot_reason --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l)'
(/system/bin/bootstat -r post_decrypt_time_elapsed)'
init : Command 'exec - system log -- /system/bin/bootstat --record_boot_complete' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc:
init : Command 'exec - system log -- /system/bin/bootstat --record_boot_reason' action=sys.boot_completed=1 && sys.logbootcomplete=1 (/system/etc/init/bootstat.rc:
@@ -582,9 +583,9 @@
duration_test
case ${TEST} in
bootloader | recovery | cold | hard | warm ) reason=${TEST} ;;
- *) reason=reboot,${TEST} ;;
+ *) reason=reboot,${TEST#optional_} ;;
esac
- adb reboot ${TEST}
+ adb reboot ${TEST#optional_}
wait_for_screen
bootloader_reason=`validate_property ro.boot.bootreason`
EXPECT_PROPERTY ro.boot.bootreason ${bootloader_reason}
@@ -948,6 +949,20 @@
report_bootstat_logs reboot,adb
}
+[ "USAGE: test_rescueparty
+
+rescueparty test
+- adb reboot rescueparty
+- (wait until screen is up, boot has completed)
+- adb shell getprop sys.boot.reason
+- adb shell getprop ro.boot.bootreason
+- NB: should report reboot,rescueparty" ]
+test_optional_rescueparty() {
+ blind_reboot_test
+ echo "WARNING: legacy devices are allowed to fail following ro.boot.bootreason result" >&2
+ EXPECT_PROPERTY ro.boot.bootreason reboot,rescueparty
+}
+
[ "USAGE: test_Its_Just_So_Hard_reboot
Its Just So Hard reboot test:
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 9c556c3..7c28b28 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -112,7 +112,6 @@
"libbase",
"libdebuggerd",
"libbacktrace",
- "libunwind",
"libunwindstack",
"libdexfile",
"liblzma",
@@ -158,7 +157,6 @@
static_libs: [
"libbacktrace",
- "libunwind",
"libunwindstack",
"liblzma",
"libbase",
diff --git a/demangle/Android.mk b/demangle/Android.mk
index e3cfc2a..d8082a9 100644
--- a/demangle/Android.mk
+++ b/demangle/Android.mk
@@ -19,7 +19,6 @@
include $(CLEAR_VARS)
LOCAL_MODULE := demangle_fuzzer
-LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
Demangler.cpp \
demangle_fuzzer.cpp \
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 9bd0628..983e195 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -101,14 +101,13 @@
#
my_dist_files := $(HOST_OUT_EXECUTABLES)/fastboot
-my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX)
-my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX)
-my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
-my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs$(HOST_EXECUTABLE_SUFFIX)
+my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs
+my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid
+my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs
+my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs
$(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files))
ifdef HOST_CROSS_OS
-# Archive fastboot.exe for win_sdk build.
-$(call dist-for-goals,win_sdk,$(ALL_MODULES.host_cross_fastboot.BUILT))
+$(call dist-for-goals,dist_files sdk win_sdk,$(ALL_MODULES.host_cross_fastboot.BUILT))
endif
my_dist_files :=
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 6769fda..e9040df 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1383,7 +1383,7 @@
mount_point = basename(fstab->recs[i].mount_point);
}
- fs_mgr_verity_ioctl_init(io, mount_point);
+ fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, mount_point);
const char* status;
if (ioctl(fd, DM_TABLE_STATUS, io)) {
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 6ea3833..cf6b497 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -303,7 +303,7 @@
static bool load_verity_table(struct dm_ioctl* io, const std::string& dm_device_name, int fd,
uint64_t image_size, const std::string& verity_table) {
- fs_mgr_verity_ioctl_init(io, dm_device_name);
+ fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, dm_device_name);
// The buffer consists of [dm_ioctl][dm_target_spec][verity_params].
char* buffer = (char*)io;
@@ -360,14 +360,14 @@
alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
struct dm_ioctl* io = (struct dm_ioctl*)buffer;
const std::string mount_point(basename(fstab_entry->mount_point));
- if (!fs_mgr_create_verity_device(io, mount_point, fd)) {
+ if (!fs_mgr_dm_create_device(io, mount_point, fd)) {
LERROR << "Couldn't create verity device!";
return false;
}
// Gets the name of the device file.
std::string verity_blk_name;
- if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) {
+ if (!fs_mgr_dm_get_device_name(io, mount_point, fd, &verity_blk_name)) {
LERROR << "Couldn't get verity device number!";
return false;
}
@@ -386,7 +386,7 @@
}
// Activates the device.
- if (!fs_mgr_resume_verity_table(io, mount_point, fd)) {
+ if (!fs_mgr_dm_resume_table(io, mount_point, fd)) {
return false;
}
diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp
index 5f9b118..3a7fae4 100644
--- a/fs_mgr/fs_mgr_dm_ioctl.cpp
+++ b/fs_mgr/fs_mgr_dm_ioctl.cpp
@@ -23,9 +23,9 @@
#include "fs_mgr_priv.h"
#include "fs_mgr_priv_dm_ioctl.h"
-void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name) {
- memset(io, 0, DM_BUF_SIZE);
- io->data_size = DM_BUF_SIZE;
+void fs_mgr_dm_ioctl_init(struct dm_ioctl* io, size_t size, const std::string& name) {
+ memset(io, 0, size);
+ io->data_size = size;
io->data_start = sizeof(struct dm_ioctl);
io->version[0] = 4;
io->version[1] = 0;
@@ -35,8 +35,8 @@
}
}
-bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd) {
- fs_mgr_verity_ioctl_init(io, name);
+bool fs_mgr_dm_create_device(struct dm_ioctl* io, const std::string& name, int fd) {
+ fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
if (ioctl(fd, DM_DEV_CREATE, io)) {
PERROR << "Error creating device mapping";
return false;
@@ -44,8 +44,8 @@
return true;
}
-bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd) {
- fs_mgr_verity_ioctl_init(io, name);
+bool fs_mgr_dm_destroy_device(struct dm_ioctl* io, const std::string& name, int fd) {
+ fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
if (ioctl(fd, DM_DEV_REMOVE, io)) {
PERROR << "Error removing device mapping";
return false;
@@ -53,13 +53,13 @@
return true;
}
-bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd,
- std::string* out_dev_name) {
+bool fs_mgr_dm_get_device_name(struct dm_ioctl* io, const std::string& name, int fd,
+ std::string* out_dev_name) {
FS_MGR_CHECK(out_dev_name != nullptr);
- fs_mgr_verity_ioctl_init(io, name);
+ fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
if (ioctl(fd, DM_DEV_STATUS, io)) {
- PERROR << "Error fetching verity device number";
+ PERROR << "Error fetching device-mapper device number";
return false;
}
@@ -69,10 +69,10 @@
return true;
}
-bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd) {
- fs_mgr_verity_ioctl_init(io, name);
+bool fs_mgr_dm_resume_table(struct dm_ioctl* io, const std::string& name, int fd) {
+ fs_mgr_dm_ioctl_init(io, sizeof(*io), name);
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
- PERROR << "Error activating verity device";
+ PERROR << "Error activating device table";
return false;
}
return true;
diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h
index 792683e..792475d 100644
--- a/fs_mgr/fs_mgr_priv_dm_ioctl.h
+++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h
@@ -20,15 +20,15 @@
#include <linux/dm-ioctl.h>
#include <string>
-void fs_mgr_verity_ioctl_init(struct dm_ioctl* io, const std::string& name);
+void fs_mgr_dm_ioctl_init(struct dm_ioctl* io, size_t size, const std::string& name);
-bool fs_mgr_create_verity_device(struct dm_ioctl* io, const std::string& name, int fd);
+bool fs_mgr_dm_create_device(struct dm_ioctl* io, const std::string& name, int fd);
-bool fs_mgr_destroy_verity_device(struct dm_ioctl* io, const std::string& name, int fd);
+bool fs_mgr_dm_destroy_device(struct dm_ioctl* io, const std::string& name, int fd);
-bool fs_mgr_get_verity_device_name(struct dm_ioctl* io, const std::string& name, int fd,
- std::string* out_dev_name);
+bool fs_mgr_dm_get_device_name(struct dm_ioctl* io, const std::string& name, int fd,
+ std::string* out_dev_name);
-bool fs_mgr_resume_verity_table(struct dm_ioctl* io, const std::string& name, int fd);
+bool fs_mgr_dm_resume_table(struct dm_ioctl* io, const std::string& name, int fd);
#endif /* __CORE_FS_MGR_PRIV_DM_IOCTL_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index d0bb058..fe41f8a 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -258,7 +258,7 @@
char *buffer = (char*) io;
size_t bufsize;
- fs_mgr_verity_ioctl_init(io, name);
+ fs_mgr_dm_ioctl_init(io, DM_BUF_SIZE, name);
struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
@@ -805,13 +805,13 @@
}
// create the device
- if (!fs_mgr_create_verity_device(io, mount_point, fd)) {
+ if (!fs_mgr_dm_create_device(io, mount_point, fd)) {
LERROR << "Couldn't create verity device!";
goto out;
}
// get the name of the device file
- if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) {
+ if (!fs_mgr_dm_get_device_name(io, mount_point, fd, &verity_blk_name)) {
LERROR << "Couldn't get verity device number!";
goto out;
}
@@ -900,7 +900,7 @@
loaded:
// activate the device
- if (!fs_mgr_resume_verity_table(io, mount_point, fd)) {
+ if (!fs_mgr_dm_resume_table(io, mount_point, fd)) {
goto out;
}
@@ -923,7 +923,7 @@
if (!verified_at_boot) {
free(fstab->blk_device);
fstab->blk_device = strdup(verity_blk_name.c_str());
- } else if (!fs_mgr_destroy_verity_device(io, mount_point, fd)) {
+ } else if (!fs_mgr_dm_destroy_device(io, mount_point, fd)) {
LERROR << "Failed to remove verity device " << mount_point.c_str();
goto out;
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 8bd92cc..17d34e1 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -240,6 +240,29 @@
return Success();
}
+static Result<Success> do_interface_restart(const BuiltinArguments& args) {
+ Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
+ if (!svc) return Error() << "interface " << args[1] << " not found";
+ svc->Restart();
+ return Success();
+}
+
+static Result<Success> do_interface_start(const BuiltinArguments& args) {
+ Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
+ if (!svc) return Error() << "interface " << args[1] << " not found";
+ if (auto result = svc->Start(); !result) {
+ return Error() << "Could not start interface: " << result.error();
+ }
+ return Success();
+}
+
+static Result<Success> do_interface_stop(const BuiltinArguments& args) {
+ Service* svc = ServiceList::GetInstance().FindInterface(args[1]);
+ if (!svc) return Error() << "interface " << args[1] << " not found";
+ svc->Stop();
+ return Success();
+}
+
// mkdir <path> [mode] [owner] [group]
static Result<Success> do_mkdir(const BuiltinArguments& args) {
mode_t mode = 0755;
@@ -1050,6 +1073,9 @@
{"init_user0", {0, 0, {false, do_init_user0}}},
{"insmod", {1, kMax, {true, do_insmod}}},
{"installkey", {1, 1, {false, do_installkey}}},
+ {"interface_restart", {1, 1, {false, do_interface_restart}}},
+ {"interface_start", {1, 1, {false, do_interface_start}}},
+ {"interface_stop", {1, 1, {false, do_interface_stop}}},
{"load_persist_props", {0, 0, {false, do_load_persist_props}}},
{"load_system_props", {0, 0, {false, do_load_system_props}}},
{"loglevel", {1, 1, {false, do_loglevel}}},
diff --git a/init/host_init_stubs.cpp b/init/host_init_stubs.cpp
index e6cc08a..4451ac8 100644
--- a/init/host_init_stubs.cpp
+++ b/init/host_init_stubs.cpp
@@ -49,6 +49,10 @@
}
// selinux.h
+bool SelinuxHasVendorInit() {
+ return true;
+}
+
void SelabelInitialize() {}
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) {
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index ddfb7ae..bb241af 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -35,11 +35,6 @@
std::string GetProperty(const std::string& key, const std::string& default_value);
bool GetBoolProperty(const std::string& key, bool default_value);
-template <typename T>
-T GetIntProperty(const std::string&, T default_value, T = std::numeric_limits<T>::min(),
- T = std::numeric_limits<T>::max()) {
- return default_value;
-}
} // namespace base
} // namespace android
@@ -56,6 +51,7 @@
const std::string& source_context, const ucred& cr, std::string* error);
// selinux.h
+bool SelinuxHasVendorInit();
void SelabelInitialize();
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
diff --git a/init/init.cpp b/init/init.cpp
index 0d5690b..645184b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -31,6 +31,10 @@
#include <sys/types.h>
#include <unistd.h>
+#include <map>
+#include <memory>
+#include <optional>
+
#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -43,9 +47,6 @@
#include <private/android_filesystem_config.h>
#include <selinux/android.h>
-#include <memory>
-#include <optional>
-
#include "action_parser.h"
#include "import_parser.h"
#include "init_first_stage.h"
@@ -130,12 +131,31 @@
}
}
-void register_epoll_handler(int fd, void (*fn)()) {
+static std::map<int, std::function<void()>> epoll_handlers;
+
+void register_epoll_handler(int fd, std::function<void()> handler) {
+ auto[it, inserted] = epoll_handlers.emplace(fd, std::move(handler));
+ if (!inserted) {
+ LOG(ERROR) << "Cannot specify two epoll handlers for a given FD";
+ return;
+ }
epoll_event ev;
ev.events = EPOLLIN;
- ev.data.ptr = reinterpret_cast<void*>(fn);
+ // std::map's iterators do not get invalidated until erased, so we use the pointer to the
+ // std::function in the map directly for epoll_ctl.
+ ev.data.ptr = reinterpret_cast<void*>(&it->second);
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
- PLOG(ERROR) << "epoll_ctl failed";
+ PLOG(ERROR) << "epoll_ctl failed to add fd";
+ epoll_handlers.erase(fd);
+ }
+}
+
+void unregister_epoll_handler(int fd) {
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr) == -1) {
+ PLOG(ERROR) << "epoll_ctl failed to remove fd";
+ }
+ if (epoll_handlers.erase(fd) != 1) {
+ LOG(ERROR) << "Attempting to remove epoll handler for FD without an existing handler";
}
}
@@ -277,40 +297,29 @@
const ControlMessageFunction& function = it->second;
- if (function.target == ControlTarget::SERVICE) {
- Service* svc = ServiceList::GetInstance().FindService(name);
- if (svc == nullptr) {
- LOG(ERROR) << "No such service '" << name << "' for ctl." << msg;
- return;
- }
- if (auto result = function.action(svc); !result) {
- LOG(ERROR) << "Could not ctl." << msg << " for service " << name << ": "
- << result.error();
- }
+ Service* svc = nullptr;
+ switch (function.target) {
+ case ControlTarget::SERVICE:
+ svc = ServiceList::GetInstance().FindService(name);
+ break;
+ case ControlTarget::INTERFACE:
+ svc = ServiceList::GetInstance().FindInterface(name);
+ break;
+ default:
+ LOG(ERROR) << "Invalid function target from static map key '" << msg << "': "
+ << static_cast<std::underlying_type<ControlTarget>::type>(function.target);
+ return;
+ }
+
+ if (svc == nullptr) {
+ LOG(ERROR) << "Could not find '" << name << "' for ctl." << msg;
return;
}
- if (function.target == ControlTarget::INTERFACE) {
- for (const auto& svc : ServiceList::GetInstance()) {
- if (svc->interfaces().count(name) == 0) {
- continue;
- }
-
- if (auto result = function.action(svc.get()); !result) {
- LOG(ERROR) << "Could not handle ctl." << msg << " for service " << svc->name()
- << " with interface " << name << ": " << result.error();
- }
-
- return;
- }
-
- LOG(ERROR) << "Could not find service hosting interface " << name;
- return;
+ if (auto result = function.action(svc); !result) {
+ LOG(ERROR) << "Could not ctl." << msg << " for '" << name << "': " << result.error();
}
-
- LOG(ERROR) << "Invalid function target from static map key '" << msg
- << "': " << static_cast<std::underlying_type<ControlTarget>::type>(function.target);
}
static Result<Success> wait_for_coldboot_done_action(const BuiltinArguments& args) {
@@ -334,8 +343,8 @@
return Success();
}
-static Result<Success> keychord_init_action(const BuiltinArguments& args) {
- keychord_init();
+static Result<Success> KeychordInitAction(const BuiltinArguments& args) {
+ KeychordInit();
return Success();
}
@@ -752,7 +761,7 @@
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
- am.QueueBuiltinAction(keychord_init_action, "keychord_init");
+ am.QueueBuiltinAction(KeychordInitAction, "KeychordInit");
am.QueueBuiltinAction(console_init_action, "console_init");
// Trigger all the boot actions to get us started.
@@ -809,7 +818,7 @@
if (nr == -1) {
PLOG(ERROR) << "epoll_wait failed";
} else if (nr == 1) {
- ((void (*)()) ev.data.ptr)();
+ std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr));
}
}
diff --git a/init/init.h b/init/init.h
index d4a0e96..e7c4d8d 100644
--- a/init/init.h
+++ b/init/init.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
+#include <functional>
#include <string>
#include <vector>
@@ -42,7 +43,8 @@
void property_changed(const std::string& name, const std::string& value);
-void register_epoll_handler(int fd, void (*fn)());
+void register_epoll_handler(int fd, std::function<void()> handler);
+void unregister_epoll_handler(int fd);
bool start_waiting_for_property(const char *name, const char *value);
diff --git a/init/keychords.cpp b/init/keychords.cpp
index e686ce1..10c56e3 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -16,13 +16,22 @@
#include "keychords.h"
+#include <dirent.h>
#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/stat.h>
+#include <linux/input.h>
+#include <sys/cdefs.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
-#include <linux/keychord.h>
#include <unistd.h>
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -31,51 +40,89 @@
namespace android {
namespace init {
-static struct input_keychord *keychords = 0;
-static int keychords_count = 0;
-static int keychords_length = 0;
-static int keychord_fd = -1;
+namespace {
-void add_service_keycodes(Service* svc)
-{
- struct input_keychord *keychord;
- size_t i, size;
+int keychords_count;
- if (!svc->keycodes().empty()) {
- /* add a new keychord to the list */
- size = sizeof(*keychord) + svc->keycodes().size() * sizeof(keychord->keycodes[0]);
- keychords = (input_keychord*) realloc(keychords, keychords_length + size);
- if (!keychords) {
- PLOG(ERROR) << "could not allocate keychords";
- keychords_length = 0;
- keychords_count = 0;
- return;
+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))));
}
-
- keychord = (struct input_keychord *)((char *)keychords + keychords_length);
- keychord->version = KEYCHORD_VERSION;
- keychord->id = keychords_count + 1;
- keychord->count = svc->keycodes().size();
- svc->set_keychord_id(keychord->id);
-
- for (i = 0; i < svc->keycodes().size(); i++) {
- keychord->keycodes[i] = svc->keycodes()[i];
- }
- keychords_count++;
- keychords_length += size;
- }
-}
-
-static void handle_keychord() {
- int ret;
- __u16 id;
-
- ret = read(keychord_fd, &id, sizeof(id));
- if (ret != sizeof(id)) {
- PLOG(ERROR) << "could not read keychord id";
- return;
}
+ 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))));
+ }
+
+ 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") {
@@ -94,32 +141,179 @@
}
}
-void keychord_init() {
+void KeychordLambdaCheck() {
+ for (auto& e : keychord_entries) {
+ bool found = true;
+ for (auto& code : e.keycodes) {
+ if (!keychord_current.GetBit(code)) {
+ e.notified = false;
+ found = false;
+ break;
+ }
+ }
+ if (!found) continue;
+ if (e.notified) continue;
+ e.notified = true;
+ HandleKeychord(e.id);
+ }
+}
+
+void KeychordLambdaHandler(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();
+}
+
+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;
+
+ if (EviocsmaskSupported) {
+ KeychordMask mask(EV_KEY);
+ mask.SetBit(EV_KEY);
+ input_mask msg = {};
+ msg.type = EV_SYN;
+ msg.codes_size = mask.bytesize();
+ msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
+ if (::ioctl(fd, EVIOCSMASK, &msg) == -1) {
+ PLOG(WARNING) << "EVIOCSMASK not supported";
+ EviocsmaskSupported = false;
+ }
+ }
+
+ KeychordMask mask;
+ for (auto& e : keychord_entries) {
+ for (auto& code : e.keycodes) {
+ mask.resize(code);
+ mask.SetBit(code);
+ }
+ }
+
+ keychord_current.resize(mask.size());
+ KeychordMask available(mask.size());
+ auto res = ::ioctl(fd, EVIOCGBIT(EV_KEY, available.bytesize()), available.data());
+ if (res == -1) return false;
+ if (!(available & mask)) return false;
+
+ if (EviocsmaskSupported) {
+ input_mask msg = {};
+ msg.type = EV_KEY;
+ msg.codes_size = mask.bytesize();
+ msg.codes_ptr = reinterpret_cast<uintptr_t>(mask.data());
+ ::ioctl(fd, EVIOCSMASK, &msg);
+ }
+
+ KeychordMask set(mask.size());
+ res = ::ioctl(fd, EVIOCGKEY(res), set.data());
+ if (res > 0) {
+ keychord_current |= mask & available & set;
+ KeychordLambdaCheck();
+ }
+ register_epoll_handler(fd, [fd]() { KeychordLambdaHandler(fd); });
+ return true;
+}
+
+void GeteventOpenDevice(const std::string& device) {
+ if (keychord_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)) {
+ ::close(fd);
+ } else {
+ keychord_registration.emplace(device, fd);
+ }
+}
+
+void GeteventCloseDevice(const std::string& device) {
+ auto it = keychord_registration.find(device);
+ if (it == keychord_registration.end()) return;
+ auto fd = (*it).second;
+ unregister_epoll_handler(fd);
+ keychord_registration.erase(it);
+ ::close(fd);
+}
+
+int inotify_fd = -1;
+
+void InotifyHandler() {
+ unsigned char buf[512];
+
+ auto res = TEMP_FAILURE_RETRY(::read(inotify_fd, buf, sizeof(buf)));
+ if (res < 0) {
+ PLOG(WARNING) << "could not get event";
+ return;
+ }
+
+ auto event_buf = buf;
+ while (static_cast<size_t>(res) >= sizeof(inotify_event)) {
+ auto event = reinterpret_cast<inotify_event*>(event_buf);
+ auto event_size = sizeof(inotify_event) + event->len;
+ if (static_cast<size_t>(res) < event_size) break;
+ if (event->len) {
+ std::string devname(kDevicePath);
+ devname += '/';
+ devname += event->name;
+ if (event->mask & IN_CREATE) {
+ GeteventOpenDevice(devname);
+ } else {
+ GeteventCloseDevice(devname);
+ }
+ }
+ res -= event_size;
+ event_buf += event_size;
+ }
+}
+
+void 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) < 0) {
+ PLOG(WARNING) << "Could not add watch for " << kDevicePath;
+ ::close(inotify_fd);
+ inotify_fd = -1;
+ }
+
+ std::unique_ptr<DIR, decltype(&closedir)> device(opendir(kDevicePath), closedir);
+ if (device) {
+ dirent* entry;
+ while ((entry = readdir(device.get()))) {
+ if (entry->d_name[0] == '.') continue;
+ std::string devname(kDevicePath);
+ devname += '/';
+ devname += entry->d_name;
+ GeteventOpenDevice(devname);
+ }
+ }
+
+ if (inotify_fd >= 0) register_epoll_handler(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() {
for (const auto& service : ServiceList::GetInstance()) {
- add_service_keycodes(service.get());
+ AddServiceKeycodes(service.get());
}
-
- // Nothing to do if no services require keychords.
- if (!keychords) {
- return;
- }
-
- keychord_fd = TEMP_FAILURE_RETRY(open("/dev/keychord", O_RDWR | O_CLOEXEC));
- if (keychord_fd == -1) {
- PLOG(ERROR) << "could not open /dev/keychord";
- return;
- }
-
- int ret = write(keychord_fd, keychords, keychords_length);
- if (ret != keychords_length) {
- PLOG(ERROR) << "could not configure /dev/keychord " << ret;
- close(keychord_fd);
- }
-
- free(keychords);
- keychords = nullptr;
-
- register_epoll_handler(keychord_fd, handle_keychord);
+ if (keychords_count) GeteventOpenDevice();
}
} // namespace init
diff --git a/init/keychords.h b/init/keychords.h
index 1c34098..689a3b5 100644
--- a/init/keychords.h
+++ b/init/keychords.h
@@ -22,8 +22,7 @@
namespace android {
namespace init {
-void add_service_keycodes(Service* svc);
-void keychord_init();
+void KeychordInit();
} // namespace init
} // namespace android
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 99d3c83..47e45ef 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -59,12 +59,12 @@
#include "init.h"
#include "persistent_properties.h"
#include "property_type.h"
+#include "selinux.h"
#include "subcontext.h"
#include "util.h"
using namespace std::literals;
-using android::base::GetIntProperty;
using android::base::ReadFileToString;
using android::base::Split;
using android::base::StartsWith;
@@ -542,7 +542,7 @@
size_t flen = 0;
const char* context = kInitContext.c_str();
- if (GetIntProperty("ro.vndk.version", 28) >= 28) {
+ if (SelinuxHasVendorInit()) {
for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
if (StartsWith(filename, path_prefix)) {
context = secontext;
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 6aba9c1..0ba5c4a 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -55,12 +55,14 @@
#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/unique_fd.h>
#include <selinux/android.h>
#include "log.h"
#include "util.h"
+using android::base::ParseInt;
using android::base::Timer;
using android::base::unique_fd;
@@ -453,6 +455,31 @@
selinux_set_callback(SELINUX_CB_LOG, cb);
}
+// This function checks whether the sepolicy supports vendor init.
+bool SelinuxHasVendorInit() {
+ if (!IsSplitPolicyDevice()) {
+ // If this device does not split sepolicy files, vendor_init will be available in the latest
+ // monolithic sepolicy file.
+ return true;
+ }
+
+ std::string version;
+ if (!GetVendorMappingVersion(&version)) {
+ // Return true as the default if we failed to load the vendor sepolicy version.
+ return true;
+ }
+
+ int major_version;
+ std::string major_version_str(version, 0, version.find('.'));
+ if (!ParseInt(major_version_str, &major_version)) {
+ PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str;
+ // Return true as the default if we failed to parse the major version.
+ return true;
+ }
+
+ return major_version >= 28;
+}
+
// selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache
// its value. selinux_android_restorecon() also needs an sehandle for file context look up. It
// will create and store its own copy, but selinux_android_set_sehandle() can be used to provide
diff --git a/init/selinux.h b/init/selinux.h
index 7b880ec..30069b5 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -27,6 +27,7 @@
void SelinuxRestoreContext();
void SelinuxSetupKernelLogging();
+bool SelinuxHasVendorInit();
void SelabelInitialize();
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
diff --git a/init/service.h b/init/service.h
index cf38f69..9cb35b8 100644
--- a/init/service.h
+++ b/init/service.h
@@ -244,6 +244,16 @@
return nullptr;
}
+ Service* FindInterface(const std::string& interface_name) {
+ for (const auto& svc : services_) {
+ if (svc->interfaces().count(interface_name) > 0) {
+ return svc.get();
+ }
+ }
+
+ return nullptr;
+ }
+
void DumpState() const;
auto begin() const { return services_.begin(); }
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 9c0c0bb..267d530 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -30,8 +30,6 @@
#include "util.h"
#if defined(__ANDROID__)
-#include <android-base/properties.h>
-
#include "property_service.h"
#include "selinux.h"
#else
@@ -39,7 +37,6 @@
#endif
using android::base::GetExecutablePath;
-using android::base::GetIntProperty;
using android::base::Join;
using android::base::Socketpair;
using android::base::Split;
@@ -357,7 +354,7 @@
static std::vector<Subcontext> subcontexts;
std::vector<Subcontext>* InitializeSubcontexts() {
- if (GetIntProperty("ro.vndk.version", 28) >= 28) {
+ if (SelinuxHasVendorInit()) {
for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
subcontexts.emplace_back(path_prefix, secontext);
}
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index dd46750..e823257 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -160,6 +160,15 @@
misc_undefined: ["integer"],
},
},
+
+ vendor: {
+ exclude_srcs: [
+ // qtaguid.cpp loads libnetd_client.so with dlopen(). Since
+ // the interface of libnetd_client.so may vary between AOSP
+ // releases, exclude qtaguid.cpp from the VNDK-SP variant.
+ "qtaguid.cpp",
+ ],
+ }
},
shared_libs: ["liblog"],
diff --git a/libcutils/ashmem-host.cpp b/libcutils/ashmem-host.cpp
index b2bec99..bb990d5 100644
--- a/libcutils/ashmem-host.cpp
+++ b/libcutils/ashmem-host.cpp
@@ -24,7 +24,6 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libcutils/canned_fs_config.cpp b/libcutils/canned_fs_config.cpp
index 6b5763b..2772ef0 100644
--- a/libcutils/canned_fs_config.cpp
+++ b/libcutils/canned_fs_config.cpp
@@ -21,7 +21,6 @@
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libcutils/hashmap.cpp b/libcutils/hashmap.cpp
index 65b6ab1..10e3b25 100644
--- a/libcutils/hashmap.cpp
+++ b/libcutils/hashmap.cpp
@@ -21,7 +21,6 @@
#include <cutils/threads.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
#include <sys/types.h>
typedef struct Entry Entry;
diff --git a/libcutils/trace-dev.inc b/libcutils/trace-dev.inc
index f95c6c5..c9580af 100644
--- a/libcutils/trace-dev.inc
+++ b/libcutils/trace-dev.inc
@@ -24,7 +24,6 @@
#include <limits.h>
#include <pthread.h>
#include <stdatomic.h>
-#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp
index 6549b8d..e6e17ce 100644
--- a/libmetricslogger/Android.bp
+++ b/libmetricslogger/Android.bp
@@ -29,6 +29,13 @@
defaults: ["metricslogger_defaults"],
}
+// static version of libmetricslogger, needed by a few art static binaries
+cc_library_static {
+ name: "libmetricslogger_static",
+ srcs: metricslogger_lib_src_files,
+ defaults: ["metricslogger_defaults"],
+}
+
// metricslogger shared library, debug
// -----------------------------------------------------------------------------
cc_library_shared {
diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h
index 189bc4b..2c76869 100644
--- a/libmetricslogger/include/metricslogger/metrics_logger.h
+++ b/libmetricslogger/include/metricslogger/metrics_logger.h
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <log/log_event_list.h>
#include <cstdint>
#include <string>
@@ -32,6 +33,34 @@
// |value| in the field |field|.
void LogMultiAction(int32_t category, int32_t field, const std::string& value);
+// Logs a Tron complex event.
+//
+// A complex event can include data in a structure not suppored by the other
+// log event types above.
+//
+// Note that instances of this class are single use. You must call Record()
+// to write the event to the event log.
+class ComplexEventLogger {
+ private:
+ android_log_event_list logger;
+
+ public:
+ // Create a complex event with category|category|.
+ explicit ComplexEventLogger(int category);
+ // Add tagged data to the event, with the given tag and integer value.
+ void AddTaggedData(int tag, int32_t value);
+ // Add tagged data to the event, with the given tag and string value.
+ void AddTaggedData(int tag, const std::string& value);
+ // Add tagged data to the event, with the given tag and integer value.
+ void AddTaggedData(int tag, int64_t value);
+ // Add tagged data to the event, with the given tag and float value.
+ void AddTaggedData(int tag, float value);
+ // Record this event. This method can only be used once per instance
+ // of ComplexEventLogger. Do not made any subsequent calls to AddTaggedData
+ // after recording an event.
+ void Record();
+};
+
// TODO: replace these with the metric_logger.proto definitions
enum {
LOGBUILDER_CATEGORY = 757,
@@ -44,11 +73,23 @@
ACTION_BOOT = 1098,
FIELD_PLATFORM_REASON = 1099,
+
+ ACTION_HIDDEN_API_ACCESSED = 1391,
+ FIELD_HIDDEN_API_ACCESS_METHOD = 1392,
+ FIELD_HIDDEN_API_ACCESS_DENIED = 1393,
+ FIELD_HIDDEN_API_SIGNATURE = 1394,
};
enum {
TYPE_ACTION = 4,
};
+enum {
+ ACCESS_METHOD_NONE = 0,
+ ACCESS_METHOD_REFLECTION = 1,
+ ACCESS_METHOD_JNI = 2,
+ ACCESS_METHOD_LINKING = 3,
+};
+
} // namespace metricslogger
} // namespace android
diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp
index fdc4407..912fa12 100644
--- a/libmetricslogger/metrics_logger.cpp
+++ b/libmetricslogger/metrics_logger.cpp
@@ -23,9 +23,14 @@
namespace {
+#ifdef __ANDROID__
EventTagMap* kEventTagMap = android_openEventTagMap(nullptr);
const int kSysuiMultiActionTag = android_lookupEventTagNum(
kEventTagMap, "sysui_multi_action", "(content|4)", ANDROID_LOG_UNKNOWN);
+#else
+// android_openEventTagMap does not work on host builds.
+const int kSysuiMultiActionTag = 0;
+#endif
} // namespace
@@ -53,5 +58,29 @@
<< field << value << LOG_ID_EVENTS;
}
+ComplexEventLogger::ComplexEventLogger(int category) : logger(kSysuiMultiActionTag) {
+ logger << LOGBUILDER_CATEGORY << category;
+}
+
+void ComplexEventLogger::AddTaggedData(int tag, int32_t value) {
+ logger << tag << value;
+}
+
+void ComplexEventLogger::AddTaggedData(int tag, const std::string& value) {
+ logger << tag << value;
+}
+
+void ComplexEventLogger::AddTaggedData(int tag, int64_t value) {
+ logger << tag << value;
+}
+
+void ComplexEventLogger::AddTaggedData(int tag, float value) {
+ logger << tag << value;
+}
+
+void ComplexEventLogger::Record() {
+ logger << LOG_ID_EVENTS;
+}
+
} // namespace metricslogger
} // namespace android
diff --git a/logcat/event.logtags b/logcat/event.logtags
index 7c40a77..750761f 100644
--- a/logcat/event.logtags
+++ b/logcat/event.logtags
@@ -67,8 +67,9 @@
# ZygoteInit class preloading ends:
3030 boot_progress_preload_end (time|2|3)
-# Dalvik VM
+# Dalvik VM / ART
20003 dvm_lock_sample (process|3),(main|1|5),(thread|3),(time|1|3),(file|3),(line|1|5),(ownerfile|3),(ownerline|1|5),(sample_percent|1|6)
+20004 art_hidden_api_access (access_method|1),(flags|1),(class|3),(member|3),(type_signature|3)
75000 sqlite_mem_alarm_current (current|1|2)
75001 sqlite_mem_alarm_max (max|1|2)
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index b76160d..27cd9a8 100755
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -112,7 +112,7 @@
std::map<std::string, std::string> LogAudit::populateDenialMap() {
std::ifstream bug_file("/system/etc/selinux/selinux_denial_metadata");
std::string line;
- // allocate a map for the static map pointer in logParse to keep track of,
+ // allocate a map for the static map pointer in auditParse to keep track of,
// this function only runs once
std::map<std::string, std::string> denial_to_bug;
if (bug_file.good()) {
@@ -140,7 +140,8 @@
return "";
}
-void LogAudit::logParse(const std::string& string, std::string* bug_num) {
+void LogAudit::auditParse(const std::string& string, uid_t uid,
+ std::string* bug_num) {
if (!__android_log_is_debuggable()) {
bug_num->assign("");
return;
@@ -162,6 +163,11 @@
} else {
bug_num->assign("");
}
+
+ if (uid >= AID_APP_START && uid <= AID_APP_END) {
+ bug_num->append(" app=");
+ bug_num->append(android::uidToName(uid));
+ }
}
int LogAudit::logPrint(const char* fmt, ...) {
@@ -190,8 +196,27 @@
while ((cp = strstr(str, " "))) {
memmove(cp, cp + 1, strlen(cp + 1) + 1);
}
+ pid_t pid = getpid();
+ pid_t tid = gettid();
+ uid_t uid = AID_LOGD;
+ static const char pid_str[] = " pid=";
+ char* pidptr = strstr(str, pid_str);
+ if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) {
+ cp = pidptr + sizeof(pid_str) - 1;
+ pid = 0;
+ while (isdigit(*cp)) {
+ pid = (pid * 10) + (*cp - '0');
+ ++cp;
+ }
+ tid = pid;
+ logbuf->wrlock();
+ uid = logbuf->pidToUid(pid);
+ logbuf->unlock();
+ memmove(pidptr, cp, strlen(cp) + 1);
+ }
+
bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
- static std::string bug_metadata;
+ static std::string denial_metadata;
if ((fdDmesg >= 0) && initialized) {
struct iovec iov[4];
static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
@@ -228,8 +253,8 @@
last_info ? sizeof(log_info) : sizeof(log_warning);
iov[1].iov_base = last_str;
iov[1].iov_len = strlen(last_str);
- iov[2].iov_base = const_cast<char*>(bug_metadata.c_str());
- iov[2].iov_len = bug_metadata.length();
+ iov[2].iov_base = const_cast<char*>(denial_metadata.c_str());
+ iov[2].iov_len = denial_metadata.length();
if (count > 1) {
iov[3].iov_base = const_cast<char*>(resume);
iov[3].iov_len = strlen(resume);
@@ -249,14 +274,14 @@
last_info = info;
}
if (count == 0) {
- logParse(str, &bug_metadata);
+ auditParse(str, uid, &denial_metadata);
iov[0].iov_base = info ? const_cast<char*>(log_info)
: const_cast<char*>(log_warning);
iov[0].iov_len = info ? sizeof(log_info) : sizeof(log_warning);
iov[1].iov_base = str;
iov[1].iov_len = strlen(str);
- iov[2].iov_base = const_cast<char*>(bug_metadata.c_str());
- iov[2].iov_len = bug_metadata.length();
+ iov[2].iov_base = const_cast<char*>(denial_metadata.c_str());
+ iov[2].iov_len = denial_metadata.length();
iov[3].iov_base = const_cast<char*>(newline);
iov[3].iov_len = strlen(newline);
@@ -269,9 +294,6 @@
return 0;
}
- pid_t pid = getpid();
- pid_t tid = gettid();
- uid_t uid = AID_LOGD;
log_time now;
static const char audit_str[] = " audit(";
@@ -296,29 +318,13 @@
now = log_time(CLOCK_REALTIME);
}
- static const char pid_str[] = " pid=";
- char* pidptr = strstr(str, pid_str);
- if (pidptr && isdigit(pidptr[sizeof(pid_str) - 1])) {
- cp = pidptr + sizeof(pid_str) - 1;
- pid = 0;
- while (isdigit(*cp)) {
- pid = (pid * 10) + (*cp - '0');
- ++cp;
- }
- tid = pid;
- logbuf->wrlock();
- uid = logbuf->pidToUid(pid);
- logbuf->unlock();
- memmove(pidptr, cp, strlen(cp) + 1);
- }
-
// log to events
size_t str_len = strnlen(str, LOGGER_ENTRY_MAX_PAYLOAD);
if (((fdDmesg < 0) || !initialized) && !hasMetadata(str, str_len))
- logParse(str, &bug_metadata);
- str_len = (str_len + bug_metadata.length() <= LOGGER_ENTRY_MAX_PAYLOAD)
- ? str_len + bug_metadata.length()
+ auditParse(str, uid, &denial_metadata);
+ str_len = (str_len + denial_metadata.length() <= LOGGER_ENTRY_MAX_PAYLOAD)
+ ? str_len + denial_metadata.length()
: LOGGER_ENTRY_MAX_PAYLOAD;
size_t message_len = str_len + sizeof(android_log_event_string_t);
@@ -331,10 +337,10 @@
reinterpret_cast<android_log_event_string_t*>(buffer);
event->header.tag = htole32(AUDITD_LOG_TAG);
event->type = EVENT_TYPE_STRING;
- event->length = htole32(message_len);
- memcpy(event->data, str, str_len - bug_metadata.length());
- memcpy(event->data + str_len - bug_metadata.length(),
- bug_metadata.c_str(), bug_metadata.length());
+ event->length = htole32(str_len);
+ memcpy(event->data, str, str_len - denial_metadata.length());
+ memcpy(event->data + str_len - denial_metadata.length(),
+ denial_metadata.c_str(), denial_metadata.length());
rc = logbuf->log(
LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
@@ -380,7 +386,8 @@
prefix_len = LOGGER_ENTRY_MAX_PAYLOAD;
}
size_t suffix_len = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - prefix_len);
- message_len = str_len + prefix_len + suffix_len + bug_metadata.length() + 2;
+ message_len =
+ str_len + prefix_len + suffix_len + denial_metadata.length() + 2;
if (main) { // begin scope for main buffer
char newstr[message_len];
@@ -390,7 +397,7 @@
strncpy(newstr + 1 + str_len, str, prefix_len);
strncpy(newstr + 1 + str_len + prefix_len, ecomm, suffix_len);
strncpy(newstr + 1 + str_len + prefix_len + suffix_len,
- bug_metadata.c_str(), bug_metadata.length());
+ denial_metadata.c_str(), denial_metadata.length());
rc = logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
(message_len <= USHRT_MAX) ? (unsigned short)message_len
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 5904966..c3d7a3e 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -48,7 +48,7 @@
std::map<std::string, std::string> populateDenialMap();
std::string denialParse(const std::string& denial, char terminator,
const std::string& search_term);
- void logParse(const std::string& string, std::string* bug_num);
+ void auditParse(const std::string& string, uid_t uid, std::string* bug_num);
int logPrint(const char* fmt, ...)
__attribute__((__format__(__printf__, 2, 3)));
};
diff --git a/logd/main.cpp b/logd/main.cpp
index 4af0d21..606aa63 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -33,7 +33,6 @@
#include <syslog.h>
#include <unistd.h>
-#include <cstdbool>
#include <memory>
#include <android-base/macros.h>