Merge branch 'security-aosp-qt-release' into int/10/fp2
* security-aosp-qt-release:
Backport of Win-specific suppression of potentially rogue construct that can engage in directory traversal on the host.
Change-Id: I14d4f0e33fd28c4f1aa7449c154634232db1e915
diff --git a/adb/Android.bp b/adb/Android.bp
index 01e00dd..8cc47b1 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -410,6 +410,11 @@
"remount",
],
},
+ fp2_use_appops_su: {
+ cflags: [
+ "-DFP2_USE_APPOPS_SU",
+ ],
+ },
},
target: {
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index e2a17c5..8dd85d7 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1668,17 +1668,29 @@
return 0;
}
} else if (!strcmp(argv[0], "rescue")) {
+ // adb rescue getprop
// adb rescue getprop <prop>
// adb rescue install <filename>
// adb rescue wipe userdata
- if (argc != 3) error_exit("rescue requires two arguments");
+ if (argc < 2) error_exit("rescue requires at least one argument");
if (!strcmp(argv[1], "getprop")) {
- return adb_connect_command(android::base::StringPrintf("rescue-getprop:%s", argv[2]));
+ if (argc == 2) {
+ return adb_connect_command("rescue-getprop:");
+ }
+ if (argc == 3) {
+ return adb_connect_command(
+ android::base::StringPrintf("rescue-getprop:%s", argv[2]));
+ }
+ error_exit("invalid rescue getprop arguments");
} else if (!strcmp(argv[1], "install")) {
+ if (argc != 3) error_exit("rescue install requires two arguments");
if (adb_sideload_install(argv[2], true /* rescue_mode */) != 0) {
return 1;
}
- } else if (!strcmp(argv[1], "wipe") && !strcmp(argv[2], "userdata")) {
+ } else if (!strcmp(argv[1], "wipe")) {
+ if (argc != 3 || strcmp(argv[2], "userdata") != 0) {
+ error_exit("invalid rescue wipe arguments");
+ }
return adb_wipe_devices();
} else {
error_exit("invalid rescue argument");
diff --git a/adb/daemon/restart_service.cpp b/adb/daemon/restart_service.cpp
index 16d2627..be72824 100644
--- a/adb/daemon/restart_service.cpp
+++ b/adb/daemon/restart_service.cpp
@@ -28,6 +28,11 @@
#include "adb_io.h"
#include "adb_unique_fd.h"
+#ifdef FP2_USE_APPOPS_SU
+#include "adb.h"
+#include "adb_utils.h"
+#endif
+
void restart_root_service(unique_fd fd) {
if (getuid() == 0) {
WriteFdExactly(fd.get(), "adbd is already running as root\n");
@@ -37,6 +42,16 @@
WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
return;
}
+#ifdef FP2_USE_APPOPS_SU
+ int root_access = android::base::GetIntProperty("persist.sys.root_access", 0);
+ std::string build_type = android::base::GetProperty("ro.build.type", "");
+
+ if (build_type != "eng" && (root_access & 2) != 2) {
+ WriteFdExactly(fd, "root access is disabled by system setting - "
+ "enable in Settings -> System -> Developer options\n");
+ return;
+ }
+#endif
LOG(INFO) << "adbd restarting as root";
android::base::SetProperty("service.adb.root", "1");
diff --git a/code_coverage/Android.mk b/code_coverage/Android.mk
new file mode 100644
index 0000000..80ab36b
--- /dev/null
+++ b/code_coverage/Android.mk
@@ -0,0 +1,37 @@
+# policies to allow processes inside minijail to dump code coverage information
+#
+
+LOCAL_PATH := $(call my-dir)
+
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := code_coverage.policy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MULTILIB := both
+
+ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64))
+LOCAL_MODULE_STEM_32 := code_coverage.arm.policy
+LOCAL_MODULE_STEM_64 := code_coverage.arm64.policy
+endif
+
+ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64))
+LOCAL_MODULE_STEM_32 := code_coverage.x86.policy
+LOCAL_MODULE_STEM_64 := code_coverage.x86_64.policy
+endif
+
+# different files for different configurations
+ifeq ($(NATIVE_COVERAGE),true)
+LOCAL_SRC_FILES_arm := seccomp_policy/code_coverage.arm.policy
+LOCAL_SRC_FILES_arm64 := seccomp_policy/code_coverage.arm64.policy
+LOCAL_SRC_FILES_x86 := seccomp_policy/code_coverage.x86.policy
+LOCAL_SRC_FILES_x86_64 := seccomp_policy/code_coverage.x86_64.policy
+else
+LOCAL_SRC_FILES_arm := empty_policy/code_coverage.arm.policy
+LOCAL_SRC_FILES_arm64 := empty_policy/code_coverage.arm64.policy
+LOCAL_SRC_FILES_x86 := empty_policy/code_coverage.x86.policy
+LOCAL_SRC_FILES_x86_64 := empty_policy/code_coverage.x86_64.policy
+endif
+
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
+include $(BUILD_PREBUILT)
diff --git a/code_coverage/empty_policy/code_coverage.arm.policy b/code_coverage/empty_policy/code_coverage.arm.policy
new file mode 100644
index 0000000..4c9132b
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.arm.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.arm.policy
diff --git a/code_coverage/empty_policy/code_coverage.arm64.policy b/code_coverage/empty_policy/code_coverage.arm64.policy
new file mode 100644
index 0000000..dc5c35a
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.arm64.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.arm64.policy
diff --git a/code_coverage/empty_policy/code_coverage.x86.policy b/code_coverage/empty_policy/code_coverage.x86.policy
new file mode 100644
index 0000000..044f34c
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.x86.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.x86.policy
diff --git a/code_coverage/empty_policy/code_coverage.x86_64.policy b/code_coverage/empty_policy/code_coverage.x86_64.policy
new file mode 100644
index 0000000..6dcd22d
--- /dev/null
+++ b/code_coverage/empty_policy/code_coverage.x86_64.policy
@@ -0,0 +1,2 @@
+# empty unless code_coverage is enabled.
+# code_coverage.x86_64.policy
diff --git a/code_coverage/seccomp_policy/code_coverage.arm.policy b/code_coverage/seccomp_policy/code_coverage.arm.policy
new file mode 100644
index 0000000..d6784e3
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.arm.policy
@@ -0,0 +1,14 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+gettimeofday: 1
+prctl: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.arm64.policy b/code_coverage/seccomp_policy/code_coverage.arm64.policy
new file mode 100644
index 0000000..4c3dd26
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.arm64.policy
@@ -0,0 +1,13 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
+prctl: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.policy.def b/code_coverage/seccomp_policy/code_coverage.policy.def
new file mode 100644
index 0000000..f136084
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.policy.def
@@ -0,0 +1,51 @@
+// SECCOMP_MODE_STRICT
+//
+// minijail allowances for code coverage
+// this is processed with generate.sh, so we can use appropriate directives
+// size specific: __LP64__ for 64 bit, else 32 bit
+// arch specific: __arm__, __aarch64__, __i386__, __x86_64__
+
+// includes *all* syscalls used during the coverage dumping
+// no skipping just because they might have been in another policy file.
+
+// coverage tool uses different operations on different passes
+// 1st: uses write() to fill the file
+// 2nd-Nth: uses mmap() to update in place
+
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+
+#if defined(__LP64__)
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
+#else
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+#endif
+
+#if defined(__arm__)
+gettimeofday: 1
+#endif
+
+#if defined(__i386__)
+madvise: 1
+#endif
+
+#if defined(__arm__)
+prctl: 1
+#elif defined(__aarch64__)
+prctl: 1
+#endif
+
diff --git a/code_coverage/seccomp_policy/code_coverage.x86.policy b/code_coverage/seccomp_policy/code_coverage.x86.policy
new file mode 100644
index 0000000..24ff8b9
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.x86.policy
@@ -0,0 +1,13 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl64: 1
+fstat64: 1
+geteuid32: 1
+_llseek: 1
+mmap2: 1
+sigreturn: 1
+madvise: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.x86_64.policy b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
new file mode 100644
index 0000000..3081036
--- /dev/null
+++ b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
@@ -0,0 +1,12 @@
+close: 1
+mkdirat: 1
+msync: 1
+munmap: 1
+openat: 1
+write: 1
+fcntl: 1
+fstat: 1
+geteuid: 1
+lseek: 1
+mmap: 1
+rt_sigreturn: 1
diff --git a/code_coverage/seccomp_policy/generate.sh b/code_coverage/seccomp_policy/generate.sh
new file mode 100755
index 0000000..ae582c6
--- /dev/null
+++ b/code_coverage/seccomp_policy/generate.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# generate the arch-specific files from the generic one
+
+set -ex
+
+cd "$(dirname "$0")"
+CPP='cpp -undef -E -P code_coverage.policy.def'
+$CPP -D__arm__ -o code_coverage.arm.policy
+$CPP -D__aarch64__ -D__LP64__ -o code_coverage.arm64.policy
+$CPP -D__i386__ -o code_coverage.x86.policy
+$CPP -D__x86_64__ -D__LP64__ -o code_coverage.x86_64.policy
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 64df53e..1f249c5 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -176,7 +176,7 @@
if (crasher_pid != -1) {
kill(crasher_pid, SIGKILL);
int status;
- waitpid(crasher_pid, &status, WUNTRACED);
+ TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, WUNTRACED));
}
android::base::SetProperty(kWaitForGdbKey, previous_wait_for_gdb ? "1" : "0");
@@ -195,8 +195,7 @@
void CrasherTest::FinishIntercept(int* result) {
InterceptResponse response;
- // Timeout for tombstoned intercept is 10 seconds.
- ssize_t rc = TIMEOUT(20, read(intercept_fd.get(), &response, sizeof(response)));
+ ssize_t rc = TIMEOUT(30, read(intercept_fd.get(), &response, sizeof(response)));
if (rc == -1) {
FAIL() << "failed to read response from tombstoned: " << strerror(errno);
} else if (rc == 0) {
@@ -233,7 +232,7 @@
FAIL() << "crasher pipe uninitialized";
}
- ssize_t rc = write(crasher_pipe.get(), "\n", 1);
+ ssize_t rc = TEMP_FAILURE_RETRY(write(crasher_pipe.get(), "\n", 1));
if (rc == -1) {
FAIL() << "failed to write to crasher pipe: " << strerror(errno);
} else if (rc == 0) {
@@ -243,9 +242,10 @@
void CrasherTest::AssertDeath(int signo) {
int status;
- pid_t pid = TIMEOUT(5, waitpid(crasher_pid, &status, 0));
+ pid_t pid = TIMEOUT(30, waitpid(crasher_pid, &status, 0));
if (pid != crasher_pid) {
- printf("failed to wait for crasher (pid %d)\n", crasher_pid);
+ printf("failed to wait for crasher (expected pid %d, return value %d): %s\n", crasher_pid, pid,
+ strerror(errno));
sleep(100);
FAIL() << "failed to wait for crasher: " << strerror(errno);
}
@@ -440,7 +440,7 @@
FinishCrasher();
int status;
- ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, WUNTRACED));
+ ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, WUNTRACED)));
ASSERT_TRUE(WIFSTOPPED(status));
ASSERT_EQ(SIGSTOP, WSTOPSIG(status));
@@ -608,7 +608,7 @@
PLOG(FATAL) << "tmpfile failed";
}
- unique_fd tmp_fd(dup(fileno(tmp_file)));
+ unique_fd tmp_fd(TEMP_FAILURE_RETRY(dup(fileno(tmp_file))));
if (!android::base::WriteStringToFd(policy, tmp_fd.get())) {
PLOG(FATAL) << "failed to write policy to tmpfile";
}
@@ -821,7 +821,7 @@
FinishCrasher();
int status;
- ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, 0));
+ ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, 0)));
ASSERT_TRUE(WIFSTOPPED(status));
ASSERT_EQ(SIGABRT, WSTOPSIG(status));
@@ -836,7 +836,7 @@
regex += R"( \(.+debuggerd_test)";
ASSERT_MATCH(result, regex.c_str());
- ASSERT_EQ(crasher_pid, waitpid(crasher_pid, &status, 0));
+ ASSERT_EQ(crasher_pid, TEMP_FAILURE_RETRY(waitpid(crasher_pid, &status, 0)));
ASSERT_TRUE(WIFSTOPPED(status));
ASSERT_EQ(SIGABRT, WSTOPSIG(status));
@@ -850,7 +850,7 @@
StartProcess([]() {
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
- unique_fd fd(open("/dev/null", O_RDONLY | O_CLOEXEC));
+ unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY | O_CLOEXEC)));
if (fd == -1) {
abort();
}
@@ -885,13 +885,13 @@
raise(DEBUGGER_SIGNAL);
errno = 0;
- rc = waitpid(-1, &status, __WALL | __WNOTHREAD);
+ rc = TEMP_FAILURE_RETRY(waitpid(-1, &status, __WALL | __WNOTHREAD));
if (rc != -1 || errno != ECHILD) {
errx(2, "second waitpid returned %d (%s), expected failure with ECHILD", rc, strerror(errno));
}
_exit(0);
} else {
- rc = waitpid(forkpid, &status, 0);
+ rc = TEMP_FAILURE_RETRY(waitpid(forkpid, &status, 0));
ASSERT_EQ(forkpid, rc);
ASSERT_TRUE(WIFEXITED(status));
ASSERT_EQ(0, WEXITSTATUS(status));
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c8caa67..f3a5074 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -141,7 +141,6 @@
{ nullptr, "boot_other.img", "boot.sig", "boot", true, ImageType::Normal },
{ "cache", "cache.img", "cache.sig", "cache", true, ImageType::Extra },
{ "dtbo", "dtbo.img", "dtbo.sig", "dtbo", true, ImageType::BootCritical },
- { "dts", "dt.img", "dt.sig", "dts", true, ImageType::BootCritical },
{ "odm", "odm.img", "odm.sig", "odm", true, ImageType::Normal },
{ "product", "product.img", "product.sig", "product", true, ImageType::Normal },
{ "product_services",
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index f1ce125..f753f54 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -245,11 +245,11 @@
if (should_force_check(*fs_stat)) {
ret = android_fork_execvp_ext(
ARRAY_SIZE(e2fsck_forced_argv), const_cast<char**>(e2fsck_forced_argv), &status,
- true, LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0);
+ true, LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), nullptr, 0);
} else {
ret = android_fork_execvp_ext(
ARRAY_SIZE(e2fsck_argv), const_cast<char**>(e2fsck_argv), &status, true,
- LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0);
+ LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), nullptr, 0);
}
if (ret < 0) {
@@ -263,13 +263,19 @@
}
} else if (is_f2fs(fs_type)) {
const char* f2fs_fsck_argv[] = {F2FS_FSCK_BIN, "-a", blk_device.c_str()};
- LINFO << "Running " << F2FS_FSCK_BIN << " -a " << realpath(blk_device);
+ const char* f2fs_fsck_forced_argv[] = {F2FS_FSCK_BIN, "-f", blk_device.c_str()};
- ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv),
- const_cast<char **>(f2fs_fsck_argv),
- &status, true, LOG_KLOG | LOG_FILE,
- true, const_cast<char *>(FSCK_LOG_FILE),
- NULL, 0);
+ if (should_force_check(*fs_stat)) {
+ LINFO << "Running " << F2FS_FSCK_BIN << " -f " << realpath(blk_device);
+ ret = android_fork_execvp_ext(
+ ARRAY_SIZE(f2fs_fsck_forced_argv), const_cast<char**>(f2fs_fsck_forced_argv), &status,
+ true, LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), nullptr, 0);
+ } else {
+ LINFO << "Running " << F2FS_FSCK_BIN << " -a " << realpath(blk_device);
+ ret = android_fork_execvp_ext(
+ ARRAY_SIZE(f2fs_fsck_argv), const_cast<char**>(f2fs_fsck_argv), &status, true,
+ LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), nullptr, 0);
+ }
if (ret < 0) {
/* No need to check for error in fork, we can't really handle it now */
LERROR << "Failed trying to run " << F2FS_FSCK_BIN;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 7df7cfd..22b0585 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -790,15 +790,16 @@
FstabEntry BuildGsiSystemFstabEntry() {
// .logical_partition_name is required to look up AVB Hashtree descriptors.
- FstabEntry system = {
- .blk_device = "system_gsi",
- .mount_point = "/system",
- .fs_type = "ext4",
- .flags = MS_RDONLY,
- .fs_options = "barrier=1",
- // could add more keys separated by ':'.
- .avb_keys = "/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey",
- .logical_partition_name = "system"};
+ FstabEntry system = {.blk_device = "system_gsi",
+ .mount_point = "/system",
+ .fs_type = "ext4",
+ .flags = MS_RDONLY,
+ .fs_options = "barrier=1",
+ // could add more keys separated by ':'.
+ .avb_keys =
+ "/avb/q-gsi.avbpubkey:/avb/q-developer-gsi.avbpubkey:"
+ "/avb/r-developer-gsi.avbpubkey:/avb/s-developer-gsi.avbpubkey",
+ .logical_partition_name = "system"};
system.fs_mgr_flags.wait = true;
system.fs_mgr_flags.logical = true;
system.fs_mgr_flags.first_stage_mount = true;
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 0a6014d..f21d529 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -32,7 +32,6 @@
#include <unistd.h>
#include <algorithm>
-#include <map>
#include <memory>
#include <string>
#include <vector>
@@ -517,10 +516,166 @@
return ret;
}
+bool fs_mgr_overlayfs_set_shared_mount(const std::string& mount_point, bool shared_flag) {
+ auto ret = mount(nullptr, mount_point.c_str(), nullptr, shared_flag ? MS_SHARED : MS_PRIVATE,
+ nullptr);
+ if (ret) {
+ PERROR << "__mount(target=" << mount_point
+ << ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
+ return false;
+ }
+ return true;
+}
+
+bool fs_mgr_overlayfs_move_mount(const std::string& source, const std::string& target) {
+ auto ret = mount(source.c_str(), target.c_str(), nullptr, MS_MOVE, nullptr);
+ if (ret) {
+ PERROR << "__mount(source=" << source << ",target=" << target << ",flag=MS_MOVE)=" << ret;
+ return false;
+ }
+ return true;
+}
+
+struct mount_info {
+ std::string mount_point;
+ bool shared_flag;
+};
+
+std::vector<mount_info> ReadMountinfoFromFile(const std::string& path) {
+ std::vector<mount_info> info;
+
+ auto file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+ if (!file) {
+ PERROR << __FUNCTION__ << "(): cannot open file: '" << path << "'";
+ return info;
+ }
+
+ ssize_t len;
+ size_t alloc_len = 0;
+ char* line = nullptr;
+ while ((len = getline(&line, &alloc_len, file.get())) != -1) {
+ /* if the last character is a newline, shorten the string by 1 byte */
+ if (line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ }
+
+ static constexpr char delim[] = " \t";
+ char* save_ptr;
+ if (!strtok_r(line, delim, &save_ptr)) {
+ LERROR << "Error parsing mount ID";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing parent ID";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing mount source";
+ break;
+ }
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing root";
+ break;
+ }
+
+ char* p;
+ if (!(p = strtok_r(nullptr, delim, &save_ptr))) {
+ LERROR << "Error parsing mount_point";
+ break;
+ }
+ mount_info entry = {p, false};
+
+ if (!strtok_r(nullptr, delim, &save_ptr)) {
+ LERROR << "Error parsing mount_flags";
+ break;
+ }
+
+ while ((p = strtok_r(nullptr, delim, &save_ptr))) {
+ if ((p[0] == '-') && (p[1] == '\0')) break;
+ if (android::base::StartsWith(p, "shared:")) entry.shared_flag = true;
+ }
+ if (!p) {
+ LERROR << "Error parsing fields";
+ break;
+ }
+ info.emplace_back(std::move(entry));
+ }
+
+ free(line);
+ if (info.empty()) {
+ LERROR << __FUNCTION__ << "(): failed to load mountinfo from : '" << path << "'";
+ }
+ return info;
+}
+
bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
auto options = fs_mgr_get_overlayfs_options(mount_point);
if (options.empty()) return false;
+ auto retval = true;
+ auto save_errno = errno;
+
+ struct move_entry {
+ std::string mount_point;
+ std::string dir;
+ bool shared_flag;
+ };
+ std::vector<move_entry> move;
+ auto parent_private = false;
+ auto parent_made_private = false;
+ auto dev_private = false;
+ auto dev_made_private = false;
+ for (auto& entry : ReadMountinfoFromFile("/proc/self/mountinfo")) {
+ if ((entry.mount_point == mount_point) && !entry.shared_flag) {
+ parent_private = true;
+ }
+ if ((entry.mount_point == "/dev") && !entry.shared_flag) {
+ dev_private = true;
+ }
+
+ if (!android::base::StartsWith(entry.mount_point, mount_point + "/")) {
+ continue;
+ }
+ if (std::find_if(move.begin(), move.end(), [&entry](const auto& it) {
+ return android::base::StartsWith(entry.mount_point, it.mount_point + "/");
+ }) != move.end()) {
+ continue;
+ }
+
+ // use as the bound directory in /dev.
+ auto new_context = fs_mgr_get_context(entry.mount_point);
+ if (!new_context.empty() && setfscreatecon(new_context.c_str())) {
+ PERROR << "setfscreatecon " << new_context;
+ }
+ move_entry new_entry = {std::move(entry.mount_point), "/dev/TemporaryDir-XXXXXX",
+ entry.shared_flag};
+ const auto target = mkdtemp(new_entry.dir.data());
+ if (!target) {
+ retval = false;
+ save_errno = errno;
+ PERROR << "temporary directory for MS_BIND";
+ setfscreatecon(nullptr);
+ continue;
+ }
+ setfscreatecon(nullptr);
+
+ if (!parent_private && !parent_made_private) {
+ parent_made_private = fs_mgr_overlayfs_set_shared_mount(mount_point, false);
+ }
+ if (new_entry.shared_flag) {
+ new_entry.shared_flag = fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, false);
+ }
+ if (!fs_mgr_overlayfs_move_mount(new_entry.mount_point, new_entry.dir)) {
+ retval = false;
+ save_errno = errno;
+ if (new_entry.shared_flag) {
+ fs_mgr_overlayfs_set_shared_mount(new_entry.mount_point, true);
+ }
+ continue;
+ }
+ move.emplace_back(std::move(new_entry));
+ }
+
// hijack __mount() report format to help triage
auto report = "__mount(source=overlay,target="s + mount_point + ",type=overlay";
const auto opt_list = android::base::Split(options, ",");
@@ -535,12 +690,38 @@
auto ret = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_RELATIME,
options.c_str());
if (ret) {
+ retval = false;
+ save_errno = errno;
PERROR << report << ret;
- return false;
} else {
LINFO << report << ret;
- return true;
}
+
+ // Move submounts back.
+ for (const auto& entry : move) {
+ if (!dev_private && !dev_made_private) {
+ dev_made_private = fs_mgr_overlayfs_set_shared_mount("/dev", false);
+ }
+
+ if (!fs_mgr_overlayfs_move_mount(entry.dir, entry.mount_point)) {
+ retval = false;
+ save_errno = errno;
+ } else if (entry.shared_flag &&
+ !fs_mgr_overlayfs_set_shared_mount(entry.mount_point, true)) {
+ retval = false;
+ save_errno = errno;
+ }
+ rmdir(entry.dir.c_str());
+ }
+ if (dev_made_private) {
+ fs_mgr_overlayfs_set_shared_mount("/dev", true);
+ }
+ if (parent_made_private) {
+ fs_mgr_overlayfs_set_shared_mount(mount_point, true);
+ }
+
+ errno = save_errno;
+ return retval;
}
// Mount kScratchMountPoint
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 06c8176..f6e5830 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -583,6 +583,20 @@
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryChargeCounterPath = path;
+ else if (strcmp(name, "battery") == 0) {
+ // On Qualcomm chipsets, the value might come from the
+ // "QPNP PMIC Battery Management System driver", which
+ // creates sysfs entries separate from the "battery"
+ // node.
+ path.clear();
+ path.appendFormat("%s/bms/charge_counter",
+ POWER_SUPPLY_SYSFS_PATH);
+ if (access(path, R_OK) == 0) {
+ KLOG_INFO(LOG_TAG, "Reading charge_counter from "
+ "bms instead of the battery driver.");
+ mHealthdConfig->batteryChargeCounterPath = path;
+ }
+ }
}
if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 0e5aa4f..5345caf 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -37,6 +37,7 @@
#include <sys/socket.h>
#include <cutils/android_get_control_file.h>
+#include <cutils/android_reboot.h>
#include <cutils/klog.h>
#include <cutils/misc.h>
#include <cutils/properties.h>
@@ -155,39 +156,63 @@
static animation::frame default_animation_frames[] = {
{
- .disp_time = 750,
+ .disp_time = 500,
+ .min_level = 0,
+ .max_level = 9,
+ .surface = NULL,
+ },
+ {
+ .disp_time = 500,
.min_level = 0,
.max_level = 19,
.surface = NULL,
},
{
- .disp_time = 750,
+ .disp_time = 500,
+ .min_level = 0,
+ .max_level = 29,
+ .surface = NULL,
+ },
+ {
+ .disp_time = 500,
.min_level = 0,
.max_level = 39,
.surface = NULL,
},
{
- .disp_time = 750,
+ .disp_time = 500,
+ .min_level = 0,
+ .max_level = 49,
+ .surface = NULL,
+ },
+ {
+ .disp_time = 500,
.min_level = 0,
.max_level = 59,
.surface = NULL,
},
{
- .disp_time = 750,
+ .disp_time = 500,
+ .min_level = 0,
+ .max_level = 69,
+ .surface = NULL,
+ },
+ {
+ .disp_time = 500,
.min_level = 0,
.max_level = 79,
.surface = NULL,
},
{
- .disp_time = 750,
- .min_level = 80,
- .max_level = 95,
+ .disp_time = 500,
+ .min_level = 0,
+ .max_level = 89,
.surface = NULL,
},
{
- .disp_time = 750,
+ .disp_time = 500,
.min_level = 0,
- .max_level = 100,
+ .max_level = 97,
.surface = NULL,
},
};
@@ -515,6 +540,8 @@
static void handle_power_supply_state(charger* charger, int64_t now) {
if (!charger->have_battery_state) return;
+ healthd_board_mode_charger_battery_update(batt_prop);
+
if (!charger->charger_connected) {
request_suspend(false);
if (charger->next_pwr_check == -1) {
@@ -681,6 +708,11 @@
LOGW("--------------- STARTING CHARGER MODE ---------------\n");
+ if (!healthd_board_mode_charger_init()) {
+ LOGE("healthd_mode_charger_init failed restarting\n");
+ android_reboot(ANDROID_RB_RESTART2, 0, 0);
+ }
+
ret = ev_init(std::bind(&input_callback, charger, std::placeholders::_1, std::placeholders::_2));
if (!ret) {
epollfd = ev_get_epollfd();
diff --git a/healthd/images/battery_scale.png b/healthd/images/battery_scale.png
index 2ae8f0f..231f627 100644
--- a/healthd/images/battery_scale.png
+++ b/healthd/images/battery_scale.png
Binary files differ
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index a900071..f992a1d 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -127,4 +127,12 @@
int healthd_board_battery_update(struct android::BatteryProperties *props);
+// This API is called to update the battery/charging status by using the user
+// noticeable method other then the animation, such as: LEDs
+void healthd_board_mode_charger_battery_update(struct android::BatteryProperties *batt_prop);
+
+// This API is used to handle some board specific charger mode initialization,
+// such as: checking the charging is enabled or not.
+int healthd_board_mode_charger_init(void);
+
#endif /* _HEALTHD_H_ */
diff --git a/init/Android.bp b/init/Android.bp
index 6be7290..4893484 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -136,6 +136,7 @@
"ueventd.cpp",
"ueventd_parser.cpp",
"util.cpp",
+ "vendor_init.cpp",
],
whole_static_libs: ["libcap", "com.android.sysprop.apex"],
header_libs: ["bootimg_headers"],
@@ -150,6 +151,12 @@
exclude_shared_libs: ["libbinder", "libutils"],
},
},
+
+ product_variables: {
+ target_init_vendor_lib: {
+ whole_static_libs: ["%s"],
+ },
+ },
}
cc_binary {
diff --git a/init/NOTICE b/init/NOTICE
index c5b1efa..383d0f5 100644
--- a/init/NOTICE
+++ b/init/NOTICE
@@ -188,3 +188,29 @@
END OF TERMS AND CONDITIONS
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/init/property_service.cpp b/init/property_service.cpp
index f2c7462..421ffd8 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -64,6 +64,7 @@
#include "selinux.h"
#include "subcontext.h"
#include "util.h"
+#include "vendor_init.h"
using namespace std::literals;
@@ -765,6 +766,10 @@
for (const auto& persistent_property_record : persistent_properties.properties()) {
property_set(persistent_property_record.name(), persistent_property_record.value());
}
+
+ // Load vendor persistent properties
+ vendor_load_persist_properties();
+
persistent_properties_loaded = true;
property_set("ro.persistent_properties.ready", "true");
}
@@ -912,10 +917,15 @@
}
}
+ // Update with vendor-specific property runtime overrides
+ vendor_load_properties();
+
property_initialize_ro_product_props();
property_derive_build_fingerprint();
- update_sys_usb_config();
+ if (android::base::GetBoolProperty("ro.persistent_properties.ready", false)) {
+ update_sys_usb_config();
+ }
}
static int SelinuxAuditCallback(void* data, security_class_t /*cls*/, char* buf, size_t len) {
diff --git a/init/reboot_utils.cpp b/init/reboot_utils.cpp
index d1a712f..de085cc 100644
--- a/init/reboot_utils.cpp
+++ b/init/reboot_utils.cpp
@@ -21,11 +21,12 @@
#include <string>
-#include "android-base/file.h"
-#include "android-base/logging.h"
-#include "android-base/strings.h"
-#include "backtrace/Backtrace.h"
-#include "cutils/android_reboot.h"
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <backtrace/Backtrace.h>
+#include <cutils/android_reboot.h>
#include "capabilities.h"
@@ -93,7 +94,14 @@
break;
case ANDROID_RB_THERMOFF:
- reboot(RB_POWER_OFF);
+ if (android::base::GetBoolProperty("ro.thermal_warmreset", false)) {
+ LOG(INFO) << "Try to trigger a warm reset for thermal shutdown";
+ static constexpr const char kThermalShutdownTarget[] = "shutdown,thermal";
+ syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, kThermalShutdownTarget);
+ } else {
+ reboot(RB_POWER_OFF);
+ }
break;
}
// In normal case, reboot should not return.
diff --git a/init/service.cpp b/init/service.cpp
index ccc37b7..2db548e 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -387,6 +387,7 @@
LOG(ERROR) << "updatable process '" << name_ << "' exited 4 times "
<< (boot_completed ? "in 4 minutes" : "before boot completed");
// Notifies update_verifier and apexd
+ property_set("ro.init.updatable_crashing_process_name", name_);
property_set("ro.init.updatable_crashing", "1");
}
}
diff --git a/init/vendor_init.cpp b/init/vendor_init.cpp
new file mode 100644
index 0000000..9848f2e
--- /dev/null
+++ b/init/vendor_init.cpp
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vendor_init.h"
+
+/* init vendor override stubs */
+
+__attribute__ ((weak))
+void vendor_load_properties()
+{
+}
+
+__attribute__ ((weak))
+void vendor_load_persist_properties()
+{
+}
diff --git a/init/vendor_init.h b/init/vendor_init.h
new file mode 100644
index 0000000..5523f92
--- /dev/null
+++ b/init/vendor_init.h
@@ -0,0 +1,34 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INIT_VENDOR__H__
+#define __INIT_VENDOR__H__
+extern void vendor_load_properties(void);
+extern void vendor_load_persist_properties(void);
+#endif /* __INIT_VENDOR__H__ */
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index a5f4f0e..a1f4319 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -197,7 +197,7 @@
// the following two files are INTENTIONALLY set-uid, but they
// are NOT included on user builds.
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
- { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
+ { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
// the following files have enhanced capabilities and ARE included
// in user builds.
diff --git a/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
index a16c3fd..a6e7f69 100644
--- a/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
+++ b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <set>
#include <string>
#include <vector>
#include <unordered_map>
@@ -33,6 +34,7 @@
: inode_(inode), size_(size), count_(count), exporter_(exporter), name_(name) {
total_refs_ = 0;
}
+ DmaBuffer() = default;
~DmaBuffer() = default;
// Adds one file descriptor reference for the given pid
@@ -54,11 +56,13 @@
ino_t inode() const { return inode_; }
uint64_t total_refs() const { return total_refs_; }
uint64_t count() const { return count_; };
+ const std::set<pid_t>& pids() const { return pids_; }
const std::string& name() const { return name_; }
const std::string& exporter() const { return exporter_; }
void SetName(const std::string& name) { name_ = name; }
void SetExporter(const std::string& exporter) { exporter_ = exporter; }
void SetCount(uint64_t count) { count_ = count; }
+ uint64_t Pss() const { return size_ / pids_.size(); }
bool operator==(const DmaBuffer& rhs) {
return (inode_ == rhs.inode()) && (size_ == rhs.size()) && (name_ == rhs.name()) &&
@@ -70,6 +74,7 @@
uint64_t size_;
uint64_t count_;
uint64_t total_refs_;
+ std::set<pid_t> pids_;
std::string exporter_;
std::string name_;
std::unordered_map<pid_t, int> fdrefs_;
@@ -80,6 +85,7 @@
auto [it, inserted] = map->insert(std::make_pair(pid, 1));
if (!inserted)
it->second++;
+ pids_.insert(pid);
}
};
diff --git a/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp b/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp
index 0851fb3..48901b1 100644
--- a/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp
+++ b/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp
@@ -16,17 +16,19 @@
#include <dirent.h>
#include <errno.h>
+#include <getopt.h>
#include <inttypes.h>
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <iostream>
#include <fstream>
+#include <iostream>
+#include <map>
+#include <set>
#include <sstream>
#include <string>
#include <vector>
-#include <map>
-#include <set>
#include <android-base/stringprintf.h>
#include <dmabufinfo/dmabufinfo.h>
@@ -35,15 +37,16 @@
[[noreturn]] static void usage(int exit_status) {
fprintf(stderr,
- "Usage: %s [PID] \n"
- "\t If PID is supplied, the dmabuf information for this process is shown.\n"
- "\t Otherwise, shows the information for all processes.\n",
+ "Usage: %s [-ah] [PID] \n"
+ "-a\t show all dma buffers (ion) in big table, [buffer x process] grid \n"
+ "-h\t show this help\n"
+ " \t If PID is supplied, the dmabuf information for that process is shown.\n",
getprogname());
exit(exit_status);
}
-static std::string GetProcessBaseName(pid_t pid) {
+static std::string GetProcessComm(const pid_t pid) {
std::string pid_path = android::base::StringPrintf("/proc/%d/comm", pid);
std::ifstream in{pid_path};
if (!in) return std::string("N/A");
@@ -53,133 +56,211 @@
return line;
}
-static void AddPidsToSet(const std::unordered_map<pid_t, int>& map, std::set<pid_t>* set)
-{
- for (auto it = map.begin(); it != map.end(); ++it)
- set->insert(it->first);
-}
-
-static void PrintDmaBufInfo(const std::vector<DmaBuffer>& bufs) {
- std::set<pid_t> pid_set;
- std::map<pid_t, int> pid_column;
-
+static void PrintDmaBufTable(const std::vector<DmaBuffer>& bufs) {
if (bufs.empty()) {
- std::cout << "dmabuf info not found ¯\\_(ツ)_/¯" << std::endl;
+ printf("dmabuf info not found ¯\\_(ツ)_/¯\n");
return;
}
// Find all unique pids in the input vector, create a set
- for (int i = 0; i < bufs.size(); i++) {
- AddPidsToSet(bufs[i].fdrefs(), &pid_set);
- AddPidsToSet(bufs[i].maprefs(), &pid_set);
+ std::set<pid_t> pid_set;
+ for (auto& buf : bufs) {
+ pid_set.insert(buf.pids().begin(), buf.pids().end());
}
- int pid_count = 0;
+ // Format the header string spaced and separated with '|'
+ printf(" Dmabuf Inode | Size | Ref Counts |");
+ for (auto pid : pid_set) {
+ printf("%16s:%-5d |", GetProcessComm(pid).c_str(), pid);
+ }
+ printf("\n");
- std::cout << "\t\t\t\t\t\t";
+ // holds per-process dmabuf size in kB
+ std::map<pid_t, uint64_t> per_pid_size = {};
+ uint64_t dmabuf_total_size = 0;
- // Create a map to convert each unique pid into a column number
- for (auto it = pid_set.begin(); it != pid_set.end(); ++it, ++pid_count) {
- pid_column.insert(std::make_pair(*it, pid_count));
- std::cout << ::android::base::StringPrintf("[pid: % 4d]\t", *it);
+ // Iterate through all dmabufs and collect per-process sizes, refs
+ for (auto& buf : bufs) {
+ printf("%16ju |%13" PRIu64 " kB |%16" PRIu64 " |", static_cast<uintmax_t>(buf.inode()),
+ buf.size() / 1024, buf.total_refs());
+ // Iterate through each process to find out per-process references for each buffer,
+ // gather total size used by each process etc.
+ for (pid_t pid : pid_set) {
+ int pid_refs = 0;
+ if (buf.fdrefs().count(pid) == 1) {
+ // Get the total number of ref counts the process is holding
+ // on this buffer. We don't differentiate between mmap or fd.
+ pid_refs += buf.fdrefs().at(pid);
+ if (buf.maprefs().count(pid) == 1) {
+ pid_refs += buf.maprefs().at(pid);
+ }
+ }
+
+ if (pid_refs) {
+ // Add up the per-pid total size. Note that if a buffer is mapped
+ // in 2 different processes, the size will be shown as mapped or opened
+ // in both processes. This is intended for visibility.
+ //
+ // If one wants to get the total *unique* dma buffers, they can simply
+ // sum the size of all dma bufs shown by the tool
+ per_pid_size[pid] += buf.size() / 1024;
+ printf("%17d refs |", pid_refs);
+ } else {
+ printf("%22s |", "--");
+ }
+ }
+ dmabuf_total_size += buf.size() / 1024;
+ printf("\n");
}
- std::cout << std::endl << "\t\t\t\t\t\t";
+ printf("------------------------------------\n");
+ printf("%-16s %13" PRIu64 " kB |%16s |", "TOTALS", dmabuf_total_size, "n/a");
+ for (auto pid : pid_set) {
+ printf("%19" PRIu64 " kB |", per_pid_size[pid]);
+ }
+ printf("\n");
- for (auto it = pid_set.begin(); it != pid_set.end(); ++it) {
- std::cout << ::android::base::StringPrintf("%16s",
- GetProcessBaseName(*it).c_str());
+ return;
+}
+
+static void PrintDmaBufPerProcess(const std::vector<DmaBuffer>& bufs) {
+ if (bufs.empty()) {
+ printf("dmabuf info not found ¯\\_(ツ)_/¯\n");
+ return;
}
- std::cout << std::endl << "\tinode\t\tsize\t\tcount\t";
- for (int i = 0; i < pid_count; i++) {
- std::cout << "fd\tmap\t";
+ // Create a reverse map from pid to dmabufs
+ std::unordered_map<pid_t, std::set<ino_t>> pid_to_inodes = {};
+ uint64_t total_size = 0; // Total size of dmabufs in the system
+ uint64_t kernel_rss = 0; // Total size of dmabufs NOT mapped or opened by a process
+ for (auto& buf : bufs) {
+ for (auto pid : buf.pids()) {
+ pid_to_inodes[pid].insert(buf.inode());
+ }
+ total_size += buf.size();
+ if (buf.fdrefs().empty() && buf.maprefs().empty()) {
+ kernel_rss += buf.size();
+ }
}
- std::cout << std::endl;
+ // Create an inode to dmabuf map. We know inodes are unique..
+ std::unordered_map<ino_t, DmaBuffer> inode_to_dmabuf;
+ for (auto buf : bufs) {
+ inode_to_dmabuf[buf.inode()] = buf;
+ }
- auto fds = std::make_unique<int[]>(pid_count);
- auto maps = std::make_unique<int[]>(pid_count);
- auto pss = std::make_unique<long[]>(pid_count);
+ uint64_t total_rss = 0, total_pss = 0;
+ for (auto& [pid, inodes] : pid_to_inodes) {
+ uint64_t pss = 0;
+ uint64_t rss = 0;
- memset(pss.get(), 0, sizeof(long) * pid_count);
+ printf("%16s:%-5d\n", GetProcessComm(pid).c_str(), pid);
+ printf("%22s %16s %16s %16s %16s\n", "Name", "Rss", "Pss", "nr_procs", "Inode");
+ for (auto& inode : inodes) {
+ DmaBuffer& buf = inode_to_dmabuf[inode];
+ printf("%22s %13" PRIu64 " kB %13" PRIu64 " kB %16zu %16" PRIuMAX "\n",
+ buf.name().empty() ? "<unknown>" : buf.name().c_str(), buf.size() / 1024,
+ buf.Pss() / 1024, buf.pids().size(), static_cast<uintmax_t>(buf.inode()));
+ rss += buf.size();
+ pss += buf.Pss();
+ }
+ printf("%22s %13" PRIu64 " kB %13" PRIu64 " kB %16s\n", "PROCESS TOTAL", rss / 1024,
+ pss / 1024, "");
+ printf("----------------------\n");
+ total_rss += rss;
+ total_pss += pss;
+ }
+ printf("dmabuf total: %" PRIu64 " kB kernel_rss: %" PRIu64 " kB userspace_rss: %" PRIu64
+ " kB userspace_pss: %" PRIu64 " kB\n ",
+ total_size / 1024, kernel_rss / 1024, total_rss / 1024, total_pss / 1024);
+}
- for (auto buf = bufs.begin(); buf != bufs.end(); ++buf) {
+static bool ReadDmaBufs(std::vector<DmaBuffer>* bufs) {
+ bufs->clear();
- std::cout << ::android::base::StringPrintf("%16lu\t%10" PRIu64 "\t%" PRIu64 "\t",
- buf->inode(),buf->size(), buf->count());
+ if (!ReadDmaBufInfo(bufs)) {
+ fprintf(stderr, "debugfs entry for dmabuf not available, skipping\n");
+ return false;
+ }
- memset(fds.get(), 0, sizeof(int) * pid_count);
- memset(maps.get(), 0, sizeof(int) * pid_count);
+ std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
+ if (!dir) {
+ fprintf(stderr, "Failed to open /proc directory\n");
+ bufs->clear();
+ return false;
+ }
- for (auto it = buf->fdrefs().begin(); it != buf->fdrefs().end(); ++it) {
- fds[pid_column[it->first]] = it->second;
- pss[pid_column[it->first]] += buf->size() * it->second / buf->count();
+ struct dirent* dent;
+ while ((dent = readdir(dir.get()))) {
+ if (dent->d_type != DT_DIR) continue;
+
+ int pid = atoi(dent->d_name);
+ if (pid == 0) {
+ continue;
}
- for (auto it = buf->maprefs().begin(); it != buf->maprefs().end(); ++it) {
- maps[pid_column[it->first]] = it->second;
- pss[pid_column[it->first]] += buf->size() * it->second / buf->count();
+ if (!AppendDmaBufInfo(pid, bufs)) {
+ fprintf(stderr, "Unable to read dmabuf info for pid %d\n", pid);
+ bufs->clear();
+ return false;
}
+ }
- for (int i = 0; i < pid_count; i++) {
- std::cout << ::android::base::StringPrintf("%d\t%d\t", fds[i], maps[i]);
- }
- std::cout << std::endl;
- }
- std::cout << "-----------------------------------------" << std::endl;
- std::cout << "PSS ";
- for (int i = 0; i < pid_count; i++) {
- std::cout << ::android::base::StringPrintf("%15ldK", pss[i] / 1024);
- }
- std::cout << std::endl;
+ return true;
}
int main(int argc, char* argv[]) {
- pid_t pid = -1;
- std::vector<DmaBuffer> bufs;
- bool show_all = true;
+ struct option longopts[] = {{"all", no_argument, nullptr, 'a'},
+ {"help", no_argument, nullptr, 'h'},
+ {0, 0, nullptr, 0}};
- if (argc > 1) {
- if (sscanf(argv[1], "%d", &pid) == 1) {
- show_all = false;
+ int opt;
+ bool show_table = false;
+ while ((opt = getopt_long(argc, argv, "ah", longopts, nullptr)) != -1) {
+ switch (opt) {
+ case 'a':
+ show_table = true;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ default:
+ usage(EXIT_FAILURE);
}
- else {
+ }
+
+ pid_t pid = -1;
+ if (optind < argc) {
+ if (show_table) {
+ fprintf(stderr, "Invalid arguments: -a does not need arguments\n");
+ usage(EXIT_FAILURE);
+ }
+ if (optind != (argc - 1)) {
+ fprintf(stderr, "Invalid arguments - only one [PID] argument is allowed\n");
+ usage(EXIT_FAILURE);
+ }
+ pid = atoi(argv[optind]);
+ if (pid == 0) {
+ fprintf(stderr, "Invalid process id %s\n", argv[optind]);
usage(EXIT_FAILURE);
}
}
- if (show_all) {
- if (!ReadDmaBufInfo(&bufs)) {
- std::cerr << "debugfs entry for dmabuf not available, skipping" << std::endl;
- bufs.clear();
- }
- std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
- if (!dir) {
- std::cerr << "Failed to open /proc directory" << std::endl;
+ std::vector<DmaBuffer> bufs;
+ if (pid != -1) {
+ if (!ReadDmaBufInfo(pid, &bufs)) {
+ fprintf(stderr, "Unable to read dmabuf info for %d\n", pid);
exit(EXIT_FAILURE);
}
- struct dirent* dent;
- while ((dent = readdir(dir.get()))) {
- if (dent->d_type != DT_DIR) continue;
-
- int matched = sscanf(dent->d_name, "%d", &pid);
- if (matched != 1) {
- continue;
- }
-
- if (!AppendDmaBufInfo(pid, &bufs)) {
- std::cerr << "Unable to read dmabuf info for pid " << pid << std::endl;
- exit(EXIT_FAILURE);
- }
- }
} else {
- if (!ReadDmaBufInfo(pid, &bufs)) {
- std::cerr << "Unable to read dmabuf info" << std::endl;
- exit(EXIT_FAILURE);
- }
+ if (!ReadDmaBufs(&bufs)) exit(EXIT_FAILURE);
}
- PrintDmaBufInfo(bufs);
+
+ // Show the old dmabuf table, inode x process
+ if (show_table) {
+ PrintDmaBufTable(bufs);
+ return 0;
+ }
+
+ PrintDmaBufPerProcess(bufs);
+
return 0;
}
-
-
diff --git a/libmeminfo/pageacct.cpp b/libmeminfo/pageacct.cpp
index 0a26c08..cb17af8 100644
--- a/libmeminfo/pageacct.cpp
+++ b/libmeminfo/pageacct.cpp
@@ -81,7 +81,8 @@
if (!InitPageAcct()) return false;
}
- if (pread64(kpageflags_fd_, flags, sizeof(uint64_t), pfn * sizeof(uint64_t)) < 0) {
+ if (pread64(kpageflags_fd_, flags, sizeof(uint64_t), pfn * sizeof(uint64_t)) !=
+ sizeof(uint64_t)) {
PLOG(ERROR) << "Failed to read page flags for page " << pfn;
return false;
}
@@ -95,7 +96,8 @@
if (!InitPageAcct()) return false;
}
- if (pread64(kpagecount_fd_, mapcount, sizeof(uint64_t), pfn * sizeof(uint64_t)) < 0) {
+ if (pread64(kpagecount_fd_, mapcount, sizeof(uint64_t), pfn * sizeof(uint64_t)) !=
+ sizeof(uint64_t)) {
PLOG(ERROR) << "Failed to read map count for page " << pfn;
return false;
}
@@ -130,7 +132,7 @@
off64_t offset = pfn_to_idle_bitmap_offset(pfn);
uint64_t idle_bits;
- if (pread64(pageidle_fd_, &idle_bits, sizeof(uint64_t), offset) < 0) {
+ if (pread64(pageidle_fd_, &idle_bits, sizeof(uint64_t), offset) != sizeof(uint64_t)) {
PLOG(ERROR) << "Failed to read page idle bitmap for page " << pfn;
return -errno;
}
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 934d65c..a8b43c1 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -27,6 +27,7 @@
#include <memory>
#include <string>
#include <utility>
+#include <vector>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -278,68 +279,89 @@
bool ProcMemInfo::ReadVmaStats(int pagemap_fd, Vma& vma, bool get_wss, bool use_pageidle) {
PageAcct& pinfo = PageAcct::Instance();
- uint64_t pagesz = getpagesize();
- uint64_t num_pages = (vma.end - vma.start) / pagesz;
-
- std::unique_ptr<uint64_t[]> pg_frames(new uint64_t[num_pages]);
- uint64_t first = vma.start / pagesz;
- if (pread64(pagemap_fd, pg_frames.get(), num_pages * sizeof(uint64_t),
- first * sizeof(uint64_t)) < 0) {
- PLOG(ERROR) << "Failed to read page frames from page map for pid: " << pid_;
+ if (get_wss && use_pageidle && !pinfo.InitPageAcct(true)) {
+ LOG(ERROR) << "Failed to init idle page accounting";
return false;
}
- if (get_wss && use_pageidle) {
- if (!pinfo.InitPageAcct(true)) {
- LOG(ERROR) << "Failed to init idle page accounting";
- return false;
- }
- }
+ uint64_t pagesz = getpagesize();
+ size_t num_pages = (vma.end - vma.start) / pagesz;
+ size_t first_page = vma.start / pagesz;
- std::unique_ptr<uint64_t[]> pg_flags(new uint64_t[num_pages]);
- std::unique_ptr<uint64_t[]> pg_counts(new uint64_t[num_pages]);
- for (uint64_t i = 0; i < num_pages; ++i) {
+ std::vector<uint64_t> page_cache;
+ size_t cur_page_cache_index = 0;
+ size_t num_in_page_cache = 0;
+ size_t num_leftover_pages = num_pages;
+ for (size_t cur_page = first_page; cur_page < first_page + num_pages; ++cur_page) {
if (!get_wss) {
vma.usage.vss += pagesz;
}
- uint64_t p = pg_frames[i];
- if (!PAGE_PRESENT(p) && !PAGE_SWAPPED(p)) continue;
- if (PAGE_SWAPPED(p)) {
+ // Cache page map data.
+ if (cur_page_cache_index == num_in_page_cache) {
+ static constexpr size_t kMaxPages = 2048;
+ num_leftover_pages -= num_in_page_cache;
+ if (num_leftover_pages > kMaxPages) {
+ num_in_page_cache = kMaxPages;
+ } else {
+ num_in_page_cache = num_leftover_pages;
+ }
+ page_cache.resize(num_in_page_cache);
+ size_t total_bytes = page_cache.size() * sizeof(uint64_t);
+ ssize_t bytes = pread64(pagemap_fd, page_cache.data(), total_bytes,
+ cur_page * sizeof(uint64_t));
+ if (bytes != total_bytes) {
+ if (bytes == -1) {
+ PLOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
+ << cur_page * sizeof(uint64_t);
+ } else {
+ LOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
+ << cur_page * sizeof(uint64_t) << std::dec << " read bytes " << bytes
+ << " expected bytes " << total_bytes;
+ }
+ return false;
+ }
+ cur_page_cache_index = 0;
+ }
+
+ uint64_t page_info = page_cache[cur_page_cache_index++];
+ if (!PAGE_PRESENT(page_info) && !PAGE_SWAPPED(page_info)) continue;
+
+ if (PAGE_SWAPPED(page_info)) {
vma.usage.swap += pagesz;
- swap_offsets_.emplace_back(PAGE_SWAP_OFFSET(p));
+ swap_offsets_.emplace_back(PAGE_SWAP_OFFSET(page_info));
continue;
}
- uint64_t page_frame = PAGE_PFN(p);
- if (!pinfo.PageFlags(page_frame, &pg_flags[i])) {
+ uint64_t page_frame = PAGE_PFN(page_info);
+ uint64_t cur_page_flags;
+ if (!pinfo.PageFlags(page_frame, &cur_page_flags)) {
LOG(ERROR) << "Failed to get page flags for " << page_frame << " in process " << pid_;
swap_offsets_.clear();
return false;
}
// skip unwanted pages from the count
- if ((pg_flags[i] & pgflags_mask_) != pgflags_) continue;
+ if ((cur_page_flags & pgflags_mask_) != pgflags_) continue;
- if (!pinfo.PageMapCount(page_frame, &pg_counts[i])) {
+ uint64_t cur_page_counts;
+ if (!pinfo.PageMapCount(page_frame, &cur_page_counts)) {
LOG(ERROR) << "Failed to get page count for " << page_frame << " in process " << pid_;
swap_offsets_.clear();
return false;
}
// Page was unmapped between the presence check at the beginning of the loop and here.
- if (pg_counts[i] == 0) {
- pg_frames[i] = 0;
- pg_flags[i] = 0;
+ if (cur_page_counts == 0) {
continue;
}
- bool is_dirty = !!(pg_flags[i] & (1 << KPF_DIRTY));
- bool is_private = (pg_counts[i] == 1);
+ bool is_dirty = !!(cur_page_flags & (1 << KPF_DIRTY));
+ bool is_private = (cur_page_counts == 1);
// Working set
if (get_wss) {
bool is_referenced = use_pageidle ? (pinfo.IsPageIdle(page_frame) == 1)
- : !!(pg_flags[i] & (1 << KPF_REFERENCED));
+ : !!(cur_page_flags & (1 << KPF_REFERENCED));
if (!is_referenced) {
continue;
}
@@ -351,7 +373,7 @@
vma.usage.rss += pagesz;
vma.usage.uss += is_private ? pagesz : 0;
- vma.usage.pss += pagesz / pg_counts[i];
+ vma.usage.pss += pagesz / cur_page_counts;
if (is_private) {
vma.usage.private_dirty += is_dirty ? pagesz : 0;
vma.usage.private_clean += is_dirty ? 0 : pagesz;
diff --git a/libmeminfo/tools/procrank.cpp b/libmeminfo/tools/procrank.cpp
index cb3757d..1e44ff9 100644
--- a/libmeminfo/tools/procrank.cpp
+++ b/libmeminfo/tools/procrank.cpp
@@ -348,7 +348,7 @@
auto rss_sort = [](ProcessRecord& a, ProcessRecord& b) {
MemUsage stats_a = show_wss ? a.Wss() : a.Usage();
MemUsage stats_b = show_wss ? b.Wss() : b.Usage();
- return reverse_sort ? stats_a.rss < stats_b.pss : stats_a.pss > stats_b.pss;
+ return reverse_sort ? stats_a.rss < stats_b.rss : stats_a.rss > stats_b.rss;
};
auto vss_sort = [](ProcessRecord& a, ProcessRecord& b) {
diff --git a/libmeminfo/vts/AndroidTest.xml b/libmeminfo/vts/AndroidTest.xml
index 530d16e..9614025 100644
--- a/libmeminfo/vts/AndroidTest.xml
+++ b/libmeminfo/vts/AndroidTest.xml
@@ -24,6 +24,7 @@
<option name="binary-test-source" value="_32bit::DATA/nativetest/vts_meminfo_test/vts_meminfo_test" />
<option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_meminfo_test/vts_meminfo_test" />
<option name="binary-test-type" value="gtest"/>
+ <option name="precondition-first-api-level" value="29" />
<option name="test-timeout" value="10m"/>
</test>
</configuration>
diff --git a/libsystem/include/system/camera.h b/libsystem/include/system/camera.h
index 2ca90c3..990edcf 100644
--- a/libsystem/include/system/camera.h
+++ b/libsystem/include/system/camera.h
@@ -88,9 +88,20 @@
// Notify on autofocus start and stop. This is useful in continuous
// autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE.
CAMERA_MSG_FOCUS_MOVE = 0x0800, // notifyCallback
+ CAMERA_MSG_VENDOR_START = 0x1000,
+ CAMERA_MSG_STATS_DATA = CAMERA_MSG_VENDOR_START,
+ CAMERA_MSG_META_DATA = 0x2000,
+ CAMERA_MSG_VENDOR_END = 0x8000,
CAMERA_MSG_ALL_MSGS = 0xFFFF
};
+/** meta data type in CameraMetaDataCallback */
+enum {
+ CAMERA_META_DATA_ASD = 0x001, //ASD data
+ CAMERA_META_DATA_FD = 0x002, //FD/FP data
+ CAMERA_META_DATA_HDR = 0x003, //Auto HDR data
+};
+
/** cmdType in sendCommand functions */
enum {
CAMERA_CMD_START_SMOOTH_ZOOM = 1,
@@ -189,7 +200,25 @@
* IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags
* of SW_READ_OFTEN.
*/
- CAMERA_CMD_SET_VIDEO_FORMAT = 11
+ CAMERA_CMD_SET_VIDEO_FORMAT = 11,
+
+ CAMERA_CMD_VENDOR_START = 20,
+ /**
+ * Commands to enable/disable preview histogram
+ *
+ * Based on user's input to enable/disable histogram from the camera
+ * UI, send the appropriate command to the HAL to turn on/off the histogram
+ * stats and start sending the data to the application.
+ */
+ CAMERA_CMD_HISTOGRAM_ON = CAMERA_CMD_VENDOR_START,
+ CAMERA_CMD_HISTOGRAM_OFF = CAMERA_CMD_VENDOR_START + 1,
+ CAMERA_CMD_HISTOGRAM_SEND_DATA = CAMERA_CMD_VENDOR_START + 2,
+ CAMERA_CMD_LONGSHOT_ON = CAMERA_CMD_VENDOR_START + 3,
+ CAMERA_CMD_LONGSHOT_OFF = CAMERA_CMD_VENDOR_START + 4,
+ CAMERA_CMD_STOP_LONGSHOT = CAMERA_CMD_VENDOR_START + 5,
+ CAMERA_CMD_METADATA_ON = CAMERA_CMD_VENDOR_START + 6,
+ CAMERA_CMD_METADATA_OFF = CAMERA_CMD_VENDOR_START + 7,
+ CAMERA_CMD_VENDOR_END = 200,
};
/** camera fatal errors */
@@ -284,10 +313,32 @@
* -2000, -2000 if this is not supported.
*/
int32_t mouth[2];
+ int32_t smile_degree;
+ int32_t smile_score;
+ int32_t blink_detected;
+ int32_t face_recognised;
+ int32_t gaze_angle;
+ int32_t updown_dir;
+ int32_t leftright_dir;
+ int32_t roll_dir;
+ int32_t left_right_gaze;
+ int32_t top_bottom_gaze;
+ int32_t leye_blink;
+ int32_t reye_blink;
} camera_face_t;
/**
+ * The information of a data type received in a camera frame.
+ */
+typedef enum {
+ /** Data buffer */
+ CAMERA_FRAME_DATA_BUF = 0x000,
+ /** File descriptor */
+ CAMERA_FRAME_DATA_FD = 0x100
+} camera_frame_data_type_t;
+
+/**
* The metadata of the frame data.
*/
typedef struct camera_frame_metadata {
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index c2ee061..7c5a466 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -79,6 +79,7 @@
#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes"
#define ZONEINFO_PATH "/proc/zoneinfo"
#define MEMINFO_PATH "/proc/meminfo"
+#define PROC_STATUS_TGID_FIELD "Tgid:"
#define LINE_MAX 128
/* Android Logger event logtags (see event.logtags) */
@@ -551,6 +552,49 @@
(to->tv_nsec - from->tv_nsec) / (long)NS_PER_MS;
}
+static int proc_get_tgid(int pid) {
+ char path[PATH_MAX];
+ char buf[PAGE_SIZE];
+ int fd;
+ ssize_t size;
+ char *pos;
+ int64_t tgid = -1;
+
+ snprintf(path, PATH_MAX, "/proc/%d/status", pid);
+ fd = open(path, O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ return -1;
+ }
+
+ size = read_all(fd, buf, sizeof(buf) - 1);
+ if (size < 0) {
+ goto out;
+ }
+ buf[size] = 0;
+
+ pos = buf;
+ while (true) {
+ pos = strstr(pos, PROC_STATUS_TGID_FIELD);
+ /* Stop if TGID tag not found or found at the line beginning */
+ if (pos == NULL || pos == buf || pos[-1] == '\n') {
+ break;
+ }
+ pos++;
+ }
+
+ if (pos == NULL) {
+ goto out;
+ }
+
+ pos += strlen(PROC_STATUS_TGID_FIELD);
+ while (*pos == ' ') pos++;
+ parse_int64(pos, &tgid);
+
+out:
+ close(fd);
+ return (int)tgid;
+}
+
static void cmd_procprio(LMKD_CTRL_PACKET packet) {
struct proc *procp;
char path[80];
@@ -559,6 +603,7 @@
struct lmk_procprio params;
bool is_system_server;
struct passwd *pwdrec;
+ int tgid;
lmkd_pack_get_procprio(packet, ¶ms);
@@ -568,6 +613,14 @@
return;
}
+ /* Check if registered process is a thread group leader */
+ tgid = proc_get_tgid(params.pid);
+ if (tgid >= 0 && tgid != params.pid) {
+ ALOGE("Attempt to register a task that is not a thread group leader (tid %d, tgid %d)",
+ params.pid, tgid);
+ return;
+ }
+
/* gid containing AID_READPROC required */
/* CAP_SYS_RESOURCE required */
/* CAP_DAC_OVERRIDE required */
@@ -1332,6 +1385,7 @@
static int kill_one_process(struct proc* procp, int min_oom_score) {
int pid = procp->pid;
uid_t uid = procp->uid;
+ int tgid;
char *taskname;
int tasksize;
int r;
@@ -1345,6 +1399,12 @@
(void)(min_oom_score);
#endif
+ tgid = proc_get_tgid(pid);
+ if (tgid >= 0 && tgid != pid) {
+ ALOGE("Possible pid reuse detected (pid %d, tgid %d)!", pid, tgid);
+ goto out;
+ }
+
taskname = proc_get_name(pid);
if (!taskname) {
goto out;
diff --git a/mkbootimg/mkbootimg.py b/mkbootimg/mkbootimg.py
index 92b11a5..f0c958b 100644
--- a/mkbootimg/mkbootimg.py
+++ b/mkbootimg/mkbootimg.py
@@ -79,7 +79,7 @@
args.base + args.second_offset, # physical load addr
args.base + args.tags_offset, # physical addr for kernel tags
args.pagesize, # flash page size we assume
- args.header_version, # version of bootimage header
+ max(args.header_version, filesize(args.dt)), # version of bootimage header or dt size in bytes
(args.os_version << 11) | args.os_patch_level)) # os version and patch level
args.output.write(pack('16s', args.board.encode())) # asciiz product name
args.output.write(pack('512s', args.cmdline[:512].encode()))
@@ -88,6 +88,7 @@
update_sha(sha, args.kernel)
update_sha(sha, args.ramdisk)
update_sha(sha, args.second)
+ update_sha(sha, args.dt)
if args.header_version > 0:
update_sha(sha, args.recovery_dtbo)
@@ -203,15 +204,22 @@
parser.add_argument('--id', help='print the image ID on standard output',
action='store_true')
parser.add_argument('--header_version', help='boot image header version', type=parse_int, default=0)
+ parser.add_argument('--dt', help='path to the device tree image', type=FileType('rb'))
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'),
required=True)
- return parser.parse_args()
+
+ args = parser.parse_args()
+ if args.header_version > 0 and args.dt != None:
+ raise ValueError('header_version and dt cannot be set at the same time')
+
+ return args
def write_data(args):
write_padded_file(args.output, args.kernel, args.pagesize)
write_padded_file(args.output, args.ramdisk, args.pagesize)
write_padded_file(args.output, args.second, args.pagesize)
+ write_padded_file(args.output, args.dt, args.pagesize)
if args.header_version > 0:
write_padded_file(args.output, args.recovery_dtbo, args.pagesize)
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index f484550..6846a69 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -375,9 +375,11 @@
{"audio_hal.period_size", "u:object_r:default_prop:s0"},
{"bluetooth.enable_timeout_ms", "u:object_r:bluetooth_prop:s0"},
{"dalvik.vm.appimageformat", "u:object_r:dalvik_prop:s0"},
+ {"dalvik.vm.boot-dex2oat-cpu-set", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.boot-dex2oat-threads", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.dex2oat-Xms", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.dex2oat-Xmx", "u:object_r:dalvik_prop:s0"},
+ {"dalvik.vm.dex2oat-cpu-set", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.dex2oat-threads", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.dexopt.secondary", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.heapgrowthlimit", "u:object_r:dalvik_prop:s0"},
@@ -388,6 +390,7 @@
{"dalvik.vm.heaptargetutilization", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.image-dex2oat-Xms", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.image-dex2oat-Xmx", "u:object_r:dalvik_prop:s0"},
+ {"dalvik.vm.image-dex2oat-cpu-set", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.image-dex2oat-threads", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.isa.arm.features", "u:object_r:dalvik_prop:s0"},
{"dalvik.vm.isa.arm.variant", "u:object_r:dalvik_prop:s0"},
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 7ff1588..24b3999 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -89,7 +89,7 @@
EXPORT_GLOBAL_GCOV_OPTIONS :=
ifeq ($(NATIVE_COVERAGE),true)
- EXPORT_GLOBAL_GCOV_OPTIONS := export GCOV_PREFIX /data/misc/gcov
+ EXPORT_GLOBAL_GCOV_OPTIONS := export GCOV_PREFIX /data/misc/trace
endif
# Put it here instead of in init.rc module definition,
diff --git a/rootdir/avb/Android.mk b/rootdir/avb/Android.mk
index 5dc019c..f96ffdd 100644
--- a/rootdir/avb/Android.mk
+++ b/rootdir/avb/Android.mk
@@ -16,6 +16,21 @@
include $(BUILD_PREBUILT)
#######################################
+# q-developer-gsi.avbpubkey
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := q-developer-gsi.avbpubkey
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
+else
+LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
+endif
+
+include $(BUILD_PREBUILT)
+
+#######################################
# r-gsi.avbpubkey
include $(CLEAR_VARS)
@@ -31,6 +46,21 @@
include $(BUILD_PREBUILT)
#######################################
+# r-developer-gsi.avbpubkey
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := r-developer-gsi.avbpubkey
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
+else
+LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
+endif
+
+include $(BUILD_PREBUILT)
+
+#######################################
# s-gsi.avbpubkey
include $(CLEAR_VARS)
@@ -44,3 +74,18 @@
endif
include $(BUILD_PREBUILT)
+
+#######################################
+# s-developer-gsi.avbpubkey
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := s-developer-gsi.avbpubkey
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
+else
+LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
+endif
+
+include $(BUILD_PREBUILT)
diff --git a/rootdir/avb/q-developer-gsi.avbpubkey b/rootdir/avb/q-developer-gsi.avbpubkey
new file mode 100644
index 0000000..0ace69d
--- /dev/null
+++ b/rootdir/avb/q-developer-gsi.avbpubkey
Binary files differ
diff --git a/rootdir/avb/r-developer-gsi.avbpubkey b/rootdir/avb/r-developer-gsi.avbpubkey
new file mode 100644
index 0000000..aac39cc
--- /dev/null
+++ b/rootdir/avb/r-developer-gsi.avbpubkey
Binary files differ
diff --git a/rootdir/avb/s-developer-gsi.avbpubkey b/rootdir/avb/s-developer-gsi.avbpubkey
new file mode 100644
index 0000000..f0a6c11
--- /dev/null
+++ b/rootdir/avb/s-developer-gsi.avbpubkey
Binary files differ
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 84b308d..c95f60f 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -143,6 +143,7 @@
# TODO(b/122876336): Remove libpac.so once it's migrated to Webview
namespace.default.link.runtime.shared_libs += libpac.so
+namespace.default.link.runtime.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
# When libnetd_resolv.so can't be found in the default namespace, search for it
# in the resolv namespace. Don't allow any other libraries from the resolv namespace
@@ -363,7 +364,7 @@
# The "vndk" namespace links to "default" namespace for LLNDK libs and links to
# "sphal" namespace for vendor libs. The ordering matters. The "default"
# namespace has higher priority than the "sphal" namespace.
-namespace.vndk.links = default,sphal
+namespace.vndk.links = default,sphal,runtime
# When these NDK libs are required inside this namespace, then it is redirected
# to the default namespace. This is possible since their ABI is stable across
@@ -371,6 +372,8 @@
namespace.vndk.link.default.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+namespace.vndk.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
+
# Allow VNDK-SP extensions to use vendor libraries
namespace.vndk.link.sphal.allow_all_shared_libs = true
@@ -423,8 +426,10 @@
namespace.default.asan.permitted.paths += /data/asan/vendor
namespace.default.asan.permitted.paths += /vendor
-namespace.default.links = system,vndk%VNDK_IN_SYSTEM_NS%
-namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
+namespace.default.links = system,vndk%VNDK_IN_SYSTEM_NS%,runtime
+namespace.default.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
+namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
+namespace.default.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
namespace.default.link.vndk_in_system.shared_libs = %VNDK_USING_CORE_VARIANT_LIBRARIES%
namespace.default.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
namespace.default.link.vndk.shared_libs += %VNDK_CORE_LIBRARIES%
@@ -477,13 +482,15 @@
# Android releases. The links here should be identical to that of the
# 'vndk_in_system' namespace, except for the link between 'vndk' and
# 'vndk_in_system'.
-namespace.vndk.links = system,default%VNDK_IN_SYSTEM_NS%
+namespace.vndk.links = system,default%VNDK_IN_SYSTEM_NS%,runtime
namespace.vndk.link.system.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
namespace.vndk.link.default.allow_all_shared_libs = true
+namespace.vndk.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
+
namespace.vndk.link.vndk_in_system.shared_libs = %VNDK_USING_CORE_VARIANT_LIBRARIES%
###############################################################################
@@ -515,6 +522,7 @@
namespace.system.link.runtime.shared_libs += libnativeloader.so
# Workaround for b/124772622
namespace.system.link.runtime.shared_libs += libandroidicu.so
+namespace.system.link.runtime.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
###############################################################################
# "vndk_in_system" namespace
@@ -553,7 +561,8 @@
# 1. 'vndk_in_system' needs to be freely linked back to 'vndk'.
# 2. 'vndk_in_system' does not need to link to 'default', as any library that
# requires anything vendor would not be a vndk_in_system library.
-namespace.vndk_in_system.links = vndk,system
+namespace.vndk_in_system.links = vndk,system,runtime
+namespace.vndk_in_system.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
namespace.vndk_in_system.link.system.shared_libs = %LLNDK_LIBRARIES%
namespace.vndk_in_system.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -596,6 +605,7 @@
# TODO(b/122876336): Remove libpac.so once it's migrated to Webview
namespace.default.link.runtime.shared_libs += libpac.so
+namespace.default.link.runtime.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
namespace.default.link.resolv.shared_libs = libnetd_resolv.so
@@ -684,3 +694,5 @@
namespace.default.search.paths = /system/${LIB}
namespace.default.search.paths += /%PRODUCT%/${LIB}
namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
+
+namespace.default.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 5db7698..5642559 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -417,6 +417,7 @@
# TODO(b/122876336): Remove libpac.so once it's migrated to Webview
namespace.default.link.runtime.shared_libs += libpac.so
+namespace.default.link.runtime.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
namespace.default.link.resolv.shared_libs = libnetd_resolv.so
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 893998c..e898d4d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -680,6 +680,12 @@
# to make it too large, since it may bring userdata loss, if they
# are not aware of using fsync()/sync() to prepare sudden power-cut.
write /sys/fs/f2fs/${dev.mnt.blk.data}/cp_interval 200
+ write /sys/fs/f2fs/${dev.mnt.blk.data}/gc_urgent_sleep_time 50
+
+ # limit discard size to 128MB in order to avoid long IO latency
+ # for filesystem tuning first (dm or sda)
+ # Note that, if dm-<num> is used, sda/mmcblk0 should be tuned in vendor/init.rc
+ write /sys/devices/virtual/block/${dev.mnt.blk.data}/queue/discard_max_bytes 134217728
# Permissions for System Server and daemons.
chown radio system /sys/android_power/state
@@ -796,6 +802,9 @@
on property:sys.boot_completed=1
bootchart stop
+ # Setup per_boot directory so other .rc could start to use it on boot_completed
+ exec - system system -- /bin/rm -rf /data/per_boot
+ mkdir /data/per_boot 0700 system system
# system server cannot write to /proc/sys files,
# and chown/chmod does not work for /proc/sys/ entries.
diff --git a/rootdir/update_and_install_ld_config.mk b/rootdir/update_and_install_ld_config.mk
index f62c3df..1282868 100644
--- a/rootdir/update_and_install_ld_config.mk
+++ b/rootdir/update_and_install_ld_config.mk
@@ -88,7 +88,7 @@
# $(2): output file with the filtered list of lib names
$(LOCAL_BUILT_MODULE): private-filter-out-private-libs = \
paste -sd ":" $(1) > $(2) && \
- cat $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) | xargs -n 1 -I privatelib bash -c "sed -i.bak 's/privatelib//' $(2)" && \
+ while read -r privatelib; do sed -i.bak "s/$$privatelib//" $(2) ; done < $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) && \
sed -i.bak -e 's/::\+/:/g ; s/^:\+// ; s/:\+$$//' $(2) && \
rm -f $(2).bak
$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES_FILE := $(llndk_libraries_file)
@@ -139,8 +139,9 @@
endif
$(hide) echo -n > $(PRIVATE_INTERMEDIATES_DIR)/private_llndk && \
- cat $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) | \
- xargs -n 1 -I privatelib bash -c "(grep privatelib $(PRIVATE_LLNDK_LIBRARIES_FILE) || true) >> $(PRIVATE_INTERMEDIATES_DIR)/private_llndk" && \
+ while read -r privatelib; \
+ do (grep $$privatelib $(PRIVATE_LLNDK_LIBRARIES_FILE) || true) >> $(PRIVATE_INTERMEDIATES_DIR)/private_llndk ; \
+ done < $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) && \
paste -sd ":" $(PRIVATE_INTERMEDIATES_DIR)/private_llndk | \
sed -i.bak -e "s?%PRIVATE_LLNDK_LIBRARIES%?$$(cat -)?g" $@
diff --git a/usbd/usbd.cpp b/usbd/usbd.cpp
index 191fb92..6e24d8e 100644
--- a/usbd/usbd.cpp
+++ b/usbd/usbd.cpp
@@ -24,8 +24,6 @@
#include <hidl/HidlTransportSupport.h>
-#define PERSISTENT_USB_CONFIG "persist.sys.usb.config"
-
using android::base::GetProperty;
using android::base::SetProperty;
using android::hardware::configureRpcThreadpool;
@@ -34,14 +32,15 @@
using android::hardware::Return;
int main(int /*argc*/, char** /*argv*/) {
- configureRpcThreadpool(1, true /*callerWillJoin*/);
+ if (GetProperty("ro.bootmode", "") == "charger") exit(0);
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
android::sp<IUsbGadget> gadget = IUsbGadget::getService();
Return<void> ret;
if (gadget != nullptr) {
LOG(INFO) << "Usb HAL found.";
- std::string function = GetProperty(PERSISTENT_USB_CONFIG, "");
+ std::string function = GetProperty("persist.sys.usb.config", "");
if (function == "adb") {
LOG(INFO) << "peristent prop is adb";
SetProperty("ctl.start", "adbd");