Merge "Add vendor dumpsys."
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index fb00508..a282424 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -105,6 +105,12 @@
chmod 0666 /sys/kernel/tracing/events/mm_event/mm_event_record/enable
chmod 0666 /sys/kernel/debug/tracing/events/lowmemorykiller/lowmemory_kill/enable
chmod 0666 /sys/kernel/tracing/events/lowmemorykiller/lowmemory_kill/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/oom/oom_score_adj_update/enable
+ chmod 0666 /sys/kernel/tracing/events/oom/oom_score_adj_update/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/task/task_rename/enable
+ chmod 0666 /sys/kernel/tracing/events/task/task_rename/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/task/task_newtask/enable
+ chmod 0666 /sys/kernel/tracing/events/task/task_newtask/enable
# disk
chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_get_data_block/enable
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index e938b10..28aeff4 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -57,7 +57,6 @@
export_aidl_headers: true,
},
srcs: [
- "binder/android/os/DumpstateOptions.cpp",
":dumpstate_aidl",
],
export_include_dirs: ["binder"],
@@ -68,7 +67,6 @@
srcs: [
"binder/android/os/IDumpstateListener.aidl",
"binder/android/os/IDumpstateToken.aidl",
- //"binder/android/os/DumpstateOptions.aidl",
"binder/android/os/IDumpstate.aidl",
],
path: "binder",
diff --git a/cmds/dumpstate/binder/android/os/DumpstateOptions.aidl b/cmds/dumpstate/binder/android/os/DumpstateOptions.aidl
deleted file mode 100644
index c1a7f15..0000000
--- a/cmds/dumpstate/binder/android/os/DumpstateOptions.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/**
- * Specifies arguments for IDumpstate.
- * {@hide}
- */
-parcelable DumpstateOptions cpp_header "android/os/DumpstateOptions.h";
diff --git a/cmds/dumpstate/binder/android/os/DumpstateOptions.cpp b/cmds/dumpstate/binder/android/os/DumpstateOptions.cpp
deleted file mode 100644
index 5654190..0000000
--- a/cmds/dumpstate/binder/android/os/DumpstateOptions.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android/os/DumpstateOptions.h>
-
-#include <binder/IBinder.h>
-#include <binder/Parcel.h>
-
-namespace android {
-namespace os {
-
-status_t DumpstateOptions::readFromParcel(const ::android::Parcel* parcel) {
- if (status_t err = parcel->readBool(&get_section_details)) {
- return err;
- }
- if (status_t err = parcel->readUtf8FromUtf16(&name)) {
- return err;
- }
- return android::OK;
-}
-
-status_t DumpstateOptions::writeToParcel(::android::Parcel* parcel) const {
- if (status_t err = parcel->writeBool(get_section_details)) {
- return err;
- }
- if (status_t err = parcel->writeUtf8AsUtf16(name)) {
- return err;
- }
- return android::OK;
-}
-
-} // namespace os
-} // namespace android
diff --git a/cmds/dumpstate/binder/android/os/DumpstateOptions.h b/cmds/dumpstate/binder/android/os/DumpstateOptions.h
deleted file mode 100644
index a748e3c..0000000
--- a/cmds/dumpstate/binder/android/os/DumpstateOptions.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright (c) 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_OS_DUMPSTATE_OPTIONS_H_
-#define ANDROID_OS_DUMPSTATE_OPTIONS_H_
-
-#include <binder/Parcelable.h>
-
-namespace android {
-namespace os {
-
-struct DumpstateOptions : public android::Parcelable {
- // If true the caller can get callbacks with per-section progress details.
- bool get_section_details = false;
-
- // Name of the caller.
- std::string name;
-
- status_t writeToParcel(android::Parcel* parcel) const override;
- status_t readFromParcel(const android::Parcel* parcel) override;
-};
-
-} // namespace os
-} // namespace android
-
-#endif // ANDROID_OS_DUMPSTATE_OPTIONS_H_
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index f58535e..b1005d3 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -18,7 +18,6 @@
import android.os.IDumpstateListener;
import android.os.IDumpstateToken;
-import android.os.DumpstateOptions;
/**
* Binder interface for the currently running dumpstate process.
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index f574752..9a8a4c3 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -31,6 +31,7 @@
"libcutils",
"liblog",
"liblogwrap",
+ "libprocessgroup",
"libselinux",
"libutils",
],
@@ -137,10 +138,23 @@
],
clang: true,
- srcs: ["otapreopt_chroot.cpp"],
+ srcs: [
+ "otapreopt_chroot.cpp",
+ "otapreopt_utils.cpp",
+ ],
shared_libs: [
"libbase",
"liblog",
+ "libprotobuf-cpp-full",
+ "libselinux",
+ "libziparchive",
+ ],
+ static_libs: [
+ "libapex",
+ "libapexd",
+ "lib_apex_manifest_proto",
+ "libavb",
+ "libdm",
],
}
@@ -169,6 +183,7 @@
"libbase",
"libcutils",
"liblog",
+ "libprocessgroup",
"libutils",
],
}
@@ -188,6 +203,7 @@
"dexopt.cpp",
"globals.cpp",
"otapreopt.cpp",
+ "otapreopt_utils.cpp",
"utils.cpp",
"view_compiler.cpp",
],
@@ -206,6 +222,7 @@
"libcutils",
"liblog",
"liblogwrap",
+ "libprocessgroup",
"libselinux",
"libutils",
],
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 9e252ee..99f1a18 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -770,11 +770,6 @@
// TODO(narayan): For snapshotAppData as well as restoreAppDataSnapshot, we
// should validate that volumeUuid is either nullptr or TEST, we won't support
// anything else.
-//
-// TODO(narayan): We need to be clearer about the expected behaviour for the
-// case where a snapshot already exists. We either need to clear the contents
-// of the snapshot directory before we make a copy, or we need to ensure that
-// the caller always clears it before requesting a snapshot.
binder::Status InstalldNativeService::snapshotAppData(
const std::unique_ptr<std::string>& volumeUuid,
const std::string& packageName, int32_t user, int32_t storageFlags) {
@@ -819,6 +814,12 @@
auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
auto to = create_data_misc_de_rollback_path(volume_uuid, user);
+ int rd = delete_dir_contents(to, true /* ignore_if_missing */);
+ if (rd != 0) {
+ res = error(rd, "Failed clearing existing snapshot " + to);
+ return res;
+ }
+
int rc = copy_directory_recursive(from.c_str(), to.c_str());
if (rc != 0) {
res = error(rc, "Failed copying " + from + " to " + to);
@@ -830,6 +831,13 @@
if (storageFlags & FLAG_STORAGE_CE) {
auto from = create_data_user_ce_package_path(volume_uuid, user, package_name);
auto to = create_data_misc_ce_rollback_path(volume_uuid, user);
+
+ int rd = delete_dir_contents(to, true /* ignore_if_missing */);
+ if (rd != 0) {
+ res = error(rd, "Failed clearing existing snapshot " + to);
+ return res;
+ }
+
int rc = copy_directory_recursive(from.c_str(), to.c_str());
if (rc != 0) {
res = error(rc, "Failed copying " + from + " to " + to);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 10110a8..940ba79 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -43,6 +43,7 @@
#include <log/log.h> // TODO: Move everything to base/logging.
#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
+#include <processgroup/sched_policy.h>
#include <selinux/android.h>
#include <system/thread_defs.h>
@@ -332,8 +333,7 @@
MapPropertyToArg("dalvik.vm.dex2oat-very-large", "--very-large-app-threshold=%s");
// If the runtime was requested to use libartd.so, we'll run dex2oatd, otherwise dex2oat.
- const char* dex2oat_bin = "/system/bin/dex2oat";
- constexpr const char* kDex2oatDebugPath = "/system/bin/dex2oatd";
+ const char* dex2oat_bin = kDex2oatPath;
// Do not use dex2oatd for release candidates (give dex2oat more soak time).
bool is_release = android::base::GetProperty("ro.build.version.codename", "") == "REL";
if (is_debug_runtime() ||
@@ -641,8 +641,7 @@
const std::vector<std::string>& dex_locations,
bool copy_and_update,
bool store_aggregation_counters) {
- const char* profman_bin =
- is_debug_runtime() ? "/system/bin/profmand" : "/system/bin/profman";
+ const char* profman_bin = is_debug_runtime() ? kProfmanDebugPath: kProfmanPath;
if (copy_and_update) {
CHECK_EQ(1u, profile_fds.size());
@@ -1458,9 +1457,7 @@
const char* class_loader_context) {
CHECK_GE(zip_fd, 0);
const char* dexoptanalyzer_bin =
- is_debug_runtime()
- ? "/system/bin/dexoptanalyzerd"
- : "/system/bin/dexoptanalyzer";
+ is_debug_runtime() ? kDexoptanalyzerDebugPath : kDexoptanalyzerPath;
std::string dex_file_arg = "--dex-file=" + dex_file;
std::string oat_fd_arg = "--oat-fd=" + std::to_string(oat_fd);
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index 0db11e1..5902659 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -32,6 +32,16 @@
static constexpr int DEX2OAT_FOR_BOOT_IMAGE = 2;
static constexpr int DEX2OAT_FOR_FILTER = 3;
+#define ANDROID_RUNTIME_APEX_BIN "/apex/com.android.runtime/bin"
+// Location of binaries in the Android Runtime APEX.
+static constexpr const char* kDex2oatPath = ANDROID_RUNTIME_APEX_BIN "/dex2oat";
+static constexpr const char* kDex2oatDebugPath = ANDROID_RUNTIME_APEX_BIN "/dex2oatd";
+static constexpr const char* kProfmanPath = ANDROID_RUNTIME_APEX_BIN "/profmand";
+static constexpr const char* kProfmanDebugPath = ANDROID_RUNTIME_APEX_BIN "/profmand";
+static constexpr const char* kDexoptanalyzerPath = ANDROID_RUNTIME_APEX_BIN "/dexoptanalyzer";
+static constexpr const char* kDexoptanalyzerDebugPath = ANDROID_RUNTIME_APEX_BIN "/dexoptanalyzerd";
+#undef ANDROID_RUNTIME_APEX_BIN
+
// Clear the reference profile identified by the given profile name.
bool clear_primary_reference_profile(const std::string& pkgname, const std::string& profile_name);
// Clear the current profile identified by the given profile name (for single user).
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index b2e7047..de7b249 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -26,7 +26,6 @@
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/stat.h>
-#include <sys/wait.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
@@ -58,7 +57,6 @@
#define REPLY_MAX 256 /* largest reply allowed */
using android::base::EndsWith;
-using android::base::Join;
using android::base::Split;
using android::base::StartsWith;
using android::base::StringPrintf;
@@ -440,7 +438,7 @@
const char* isa) const {
// This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
std::vector<std::string> cmd;
- cmd.push_back("/system/bin/dex2oat");
+ cmd.push_back(kDex2oatPath);
cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
for (const std::string& boot_part : Split(boot_cp, ":")) {
cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
@@ -619,61 +617,6 @@
// Helpers, mostly taken from ART //
////////////////////////////////////
- // Wrapper on fork/execv to run a command in a subprocess.
- static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) {
- const std::string command_line = Join(arg_vector, ' ');
-
- CHECK_GE(arg_vector.size(), 1U) << command_line;
-
- // Convert the args to char pointers.
- const char* program = arg_vector[0].c_str();
- std::vector<char*> args;
- for (size_t i = 0; i < arg_vector.size(); ++i) {
- const std::string& arg = arg_vector[i];
- char* arg_str = const_cast<char*>(arg.c_str());
- CHECK(arg_str != nullptr) << i;
- args.push_back(arg_str);
- }
- args.push_back(nullptr);
-
- // Fork and exec.
- pid_t pid = fork();
- if (pid == 0) {
- // No allocation allowed between fork and exec.
-
- // Change process groups, so we don't get reaped by ProcessManager.
- setpgid(0, 0);
-
- execv(program, &args[0]);
-
- PLOG(ERROR) << "Failed to execv(" << command_line << ")";
- // _exit to avoid atexit handlers in child.
- _exit(1);
- } else {
- if (pid == -1) {
- *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
- command_line.c_str(), strerror(errno));
- return false;
- }
-
- // wait for subprocess to finish
- int status;
- pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
- if (got_pid != pid) {
- *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
- "wanted %d, got %d: %s",
- command_line.c_str(), pid, got_pid, strerror(errno));
- return false;
- }
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
- command_line.c_str());
- return false;
- }
- }
- return true;
- }
-
// Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc.
static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
constexpr size_t kPageSize = PAGE_SIZE;
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index e90cf3b..9965d58 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <linux/unistd.h>
#include <sys/mount.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <sstream>
@@ -24,6 +25,9 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
+#include <selinux/android.h>
+
+#include <apexd.h>
#include "installd_constants.h"
#include "otapreopt_utils.h"
@@ -138,6 +142,33 @@
UNUSED(product_result);
}
+ // Setup APEX mount point and its security context.
+ static constexpr const char* kPostinstallApexDir = "/postinstall/apex";
+ // The following logic is similar to the one in system/core/rootdir/init.rc:
+ //
+ // mount tmpfs tmpfs /apex nodev noexec nosuid
+ // chmod 0755 /apex
+ // chown root root /apex
+ // restorecon /apex
+ //
+ if (mount("tmpfs", kPostinstallApexDir, "tmpfs", MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr)
+ != 0) {
+ PLOG(ERROR) << "Failed to mount tmpfs in " << kPostinstallApexDir;
+ exit(209);
+ }
+ if (chmod(kPostinstallApexDir, 0755) != 0) {
+ PLOG(ERROR) << "Failed to chmod " << kPostinstallApexDir << " to 0755";
+ exit(210);
+ }
+ if (chown(kPostinstallApexDir, 0, 0) != 0) {
+ PLOG(ERROR) << "Failed to chown " << kPostinstallApexDir << " to root:root";
+ exit(211);
+ }
+ if (selinux_android_restorecon(kPostinstallApexDir, 0) < 0) {
+ PLOG(ERROR) << "Failed to restorecon " << kPostinstallApexDir;
+ exit(212);
+ }
+
// Chdir into /postinstall.
if (chdir("/postinstall") != 0) {
PLOG(ERROR) << "Unable to chdir into /postinstall.";
@@ -155,22 +186,52 @@
exit(205);
}
+ // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
+ // the Android Runtime APEX, as it is required by otapreopt to run dex2oat.
+ // The logic here is (partially) copied and adapted from
+ // system/apex/apexd/apexd_main.cpp.
+ //
+ // Only scan the APEX directory under /system (within the chroot dir).
+ // Note that this leaves around the loop devices created and used by
+ // libapexd's code, but this is fine, as we expect to reboot soon after.
+ apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
+ // Collect activated packages.
+ std::vector<apex::ApexFile> active_packages = apex::getActivePackages();
+
// Now go on and run otapreopt.
- // Incoming: cmd + status-fd + target-slot + cmd... + null | Incoming | = argc + 1
- // Outgoing: cmd + target-slot + cmd... + null | Outgoing | = argc
- const char** argv = new const char*[argc];
-
- argv[0] = "/system/bin/otapreopt";
+ // Incoming: cmd + status-fd + target-slot + cmd... | Incoming | = argc
+ // Outgoing: cmd + target-slot + cmd... | Outgoing | = argc - 1
+ std::vector<std::string> cmd;
+ cmd.reserve(argc);
+ cmd.push_back("/system/bin/otapreopt");
// The first parameter is the status file descriptor, skip.
- for (size_t i = 2; i <= static_cast<size_t>(argc); ++i) {
- argv[i - 1] = arg[i];
+ for (size_t i = 2; i < static_cast<size_t>(argc); ++i) {
+ cmd.push_back(arg[i]);
}
- execv(argv[0], static_cast<char * const *>(const_cast<char**>(argv)));
- PLOG(ERROR) << "execv(OTAPREOPT) failed.";
- exit(99);
+ // Fork and execute otapreopt in its own process.
+ std::string error_msg;
+ bool exec_result = Exec(cmd, &error_msg);
+ if (!exec_result) {
+ LOG(ERROR) << "Running otapreopt failed: " << error_msg;
+ }
+
+ // Tear down the work down by the apexd logic above (i.e. deactivate packages).
+ for (const apex::ApexFile& apex_file : active_packages) {
+ const std::string& package_path = apex_file.GetPath();
+ apex::Status status = apex::deactivatePackage(package_path);
+ if (!status.Ok()) {
+ LOG(ERROR) << "Failed to deactivate " << package_path << ": " << status.ErrorMessage();
+ }
+ }
+
+ if (!exec_result) {
+ exit(213);
+ }
+
+ return 0;
}
} // namespace installd
diff --git a/cmds/installd/otapreopt_utils.cpp b/cmds/installd/otapreopt_utils.cpp
new file mode 100644
index 0000000..124f726
--- /dev/null
+++ b/cmds/installd/otapreopt_utils.cpp
@@ -0,0 +1,88 @@
+/*
+ ** Copyright 2019, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "otapreopt_utils.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+using android::base::Join;
+using android::base::StringPrintf;
+
+namespace android {
+namespace installd {
+
+bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) {
+ const std::string command_line = Join(arg_vector, ' ');
+
+ CHECK_GE(arg_vector.size(), 1U) << command_line;
+
+ // Convert the args to char pointers.
+ const char* program = arg_vector[0].c_str();
+ std::vector<char*> args;
+ for (size_t i = 0; i < arg_vector.size(); ++i) {
+ const std::string& arg = arg_vector[i];
+ char* arg_str = const_cast<char*>(arg.c_str());
+ CHECK(arg_str != nullptr) << i;
+ args.push_back(arg_str);
+ }
+ args.push_back(nullptr);
+
+ // Fork and exec.
+ pid_t pid = fork();
+ if (pid == 0) {
+ // No allocation allowed between fork and exec.
+
+ // Change process groups, so we don't get reaped by ProcessManager.
+ setpgid(0, 0);
+
+ execv(program, &args[0]);
+
+ PLOG(ERROR) << "Failed to execv(" << command_line << ")";
+ // _exit to avoid atexit handlers in child.
+ _exit(1);
+ } else {
+ if (pid == -1) {
+ *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
+ command_line.c_str(), strerror(errno));
+ return false;
+ }
+
+ // wait for subprocess to finish
+ int status;
+ pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
+ if (got_pid != pid) {
+ *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
+ "wanted %d, got %d: %s",
+ command_line.c_str(), pid, got_pid, strerror(errno));
+ return false;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
+ command_line.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace installd
+} // namespace android
diff --git a/cmds/installd/otapreopt_utils.h b/cmds/installd/otapreopt_utils.h
index 436e554..03a6d87 100644
--- a/cmds/installd/otapreopt_utils.h
+++ b/cmds/installd/otapreopt_utils.h
@@ -18,6 +18,8 @@
#define OTAPREOPT_UTILS_H_
#include <regex>
+#include <string>
+#include <vector>
namespace android {
namespace installd {
@@ -28,6 +30,9 @@
return std::regex_match(input, slot_suffix_match, slot_suffix_regex);
}
+// Wrapper on fork/execv to run a command in a subprocess.
+bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg);
+
} // namespace installd
} // namespace android
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 739f33f..9c9db0f 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -28,6 +28,7 @@
"libbinder",
"libcrypto",
"libcutils",
+ "libprocessgroup",
"libselinux",
"libutils",
],
@@ -50,6 +51,7 @@
"libbinder",
"libcrypto",
"libcutils",
+ "libprocessgroup",
"libselinux",
"libutils",
],
@@ -72,6 +74,7 @@
"libbinder",
"libcrypto",
"libcutils",
+ "libprocessgroup",
"libselinux",
"libutils",
],
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 0d46341..6ded4b4 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -363,6 +363,55 @@
ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
}
+TEST_F(ServiceTest, CreateAppDataSnapshot_ClearsExistingSnapshot) {
+ auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0);
+ auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0);
+
+ ASSERT_TRUE(mkdirs(rollback_ce_dir, 700));
+ ASSERT_TRUE(mkdirs(rollback_de_dir, 700));
+
+ auto fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo");
+ auto fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo");
+
+ ASSERT_TRUE(mkdirs(fake_package_ce_path, 700));
+ ASSERT_TRUE(mkdirs(fake_package_de_path, 700));
+
+ auto deleter = [&rollback_ce_dir, &rollback_de_dir,
+ &fake_package_ce_path, &fake_package_de_path]() {
+ delete_dir_contents(rollback_ce_dir, true);
+ delete_dir_contents(rollback_de_dir, true);
+ delete_dir_contents(fake_package_ce_path, true);
+ delete_dir_contents(fake_package_de_path, true);
+ rmdir(rollback_ce_dir.c_str());
+ rmdir(rollback_de_dir.c_str());
+ };
+ auto scope_guard = android::base::make_scope_guard(deleter);
+
+ // Simulate presence of an existing snapshot
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "TEST_CONTENT_CE", rollback_ce_dir + "/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "TEST_CONTENT_DE", rollback_de_dir + "/file1",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ // Create app data.
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "TEST_CONTENT_2_CE", fake_package_ce_path + "/file2",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+ ASSERT_TRUE(android::base::WriteStringToFile(
+ "TEST_CONTENT_2_DE", fake_package_de_path + "/file2",
+ 0700, 10000, 20000, false /* follow_symlinks */));
+
+ ASSERT_TRUE(service->snapshotAppData(std::make_unique<std::string>("TEST"),
+ "com.foo", 0, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
+
+ // Previous snapshot (with data for file1) must be cleared.
+ struct stat sb;
+ ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo/file1").c_str(), &sb));
+ ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo/file1").c_str(), &sb));
+}
+
TEST_F(ServiceTest, RestoreAppDataSnapshot) {
auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0);
auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0);
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 05655c1..0826544 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -39,12 +39,17 @@
],
shared_libs: [
- "libandroid_runtime",
"libbase",
"libbinder",
"libutils",
],
+ required: [
+ // libbinder_ndk may be used by Java and non-Java things. When lower-level things use it,
+ // they shouldn't have to take on the cost of loading libandroid_runtime.
+ "libandroid_runtime",
+ ],
+
version_script: "libbinder_ndk.map.txt",
stubs: {
symbol_file: "libbinder_ndk.map.txt",
diff --git a/libs/binder/ndk/ibinder_jni.cpp b/libs/binder/ndk/ibinder_jni.cpp
index baea2e8..4a31080 100644
--- a/libs/binder/ndk/ibinder_jni.cpp
+++ b/libs/binder/ndk/ibinder_jni.cpp
@@ -17,15 +17,68 @@
#include <android/binder_ibinder_jni.h>
#include "ibinder_internal.h"
-#include <android_util_Binder.h>
+#include <android-base/logging.h>
+#include <binder/IBinder.h>
+
+#include <mutex>
+
+#include <dlfcn.h>
using ::android::IBinder;
-using ::android::ibinderForJavaObject;
-using ::android::javaObjectForIBinder;
using ::android::sp;
+struct LazyAndroidRuntime {
+ typedef sp<IBinder> (*FromJava)(JNIEnv* env, jobject obj);
+ typedef jobject (*ToJava)(JNIEnv* env, const sp<IBinder>& val);
+
+ static FromJava ibinderForJavaObject;
+ static ToJava javaObjectForIBinder;
+
+ static void load() {
+ std::call_once(mLoadFlag, []() {
+ void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY);
+ if (handle == nullptr) {
+ LOG(WARNING) << "Could not open libandroid_runtime.";
+ return;
+ }
+
+ ibinderForJavaObject = reinterpret_cast<FromJava>(
+ dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject"));
+ if (ibinderForJavaObject == nullptr) {
+ LOG(WARNING) << "Could not find ibinderForJavaObject.";
+ // no return
+ }
+
+ javaObjectForIBinder = reinterpret_cast<ToJava>(dlsym(
+ handle, "_ZN7android20javaObjectForIBinderEP7_JNIEnvRKNS_2spINS_7IBinderEEE"));
+ if (javaObjectForIBinder == nullptr) {
+ LOG(WARNING) << "Could not find javaObjectForIBinder.";
+ // no return
+ }
+ });
+ }
+
+ private:
+ static std::once_flag mLoadFlag;
+
+ LazyAndroidRuntime(){};
+};
+
+LazyAndroidRuntime::FromJava LazyAndroidRuntime::ibinderForJavaObject = nullptr;
+LazyAndroidRuntime::ToJava LazyAndroidRuntime::javaObjectForIBinder = nullptr;
+std::once_flag LazyAndroidRuntime::mLoadFlag;
+
AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder) {
- sp<IBinder> ibinder = ibinderForJavaObject(env, binder);
+ if (binder == nullptr) {
+ return nullptr;
+ }
+
+ LazyAndroidRuntime::load();
+ if (LazyAndroidRuntime::ibinderForJavaObject == nullptr) {
+ return nullptr;
+ }
+
+ sp<IBinder> ibinder = (LazyAndroidRuntime::ibinderForJavaObject)(env, binder);
sp<AIBinder> cbinder = ABpBinder::lookupOrCreateFromBinder(ibinder);
AIBinder_incStrong(cbinder.get());
@@ -38,5 +91,10 @@
return nullptr;
}
- return javaObjectForIBinder(env, binder->getBinder());
+ LazyAndroidRuntime::load();
+ if (LazyAndroidRuntime::javaObjectForIBinder == nullptr) {
+ return nullptr;
+ }
+
+ return (LazyAndroidRuntime::javaObjectForIBinder)(env, binder->getBinder());
}
diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS
index 3938e4f..97ead21 100644
--- a/libs/ui/OWNERS
+++ b/libs/ui/OWNERS
@@ -1,5 +1,7 @@
-jiyong@google.com
+lpy@google.com
+marissaw@google.com
mathias@google.com
-olv@google.com
romainguy@google.com
stoza@google.com
+jwcai@google.com
+tianyuj@google.com
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 233e0fc..26e8201 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -47,6 +47,7 @@
"liblog",
"libhardware",
"libnativewindow",
+ "libprocessgroup",
"libutils",
"libEGL",
"libGLESv1_CM",
diff --git a/libs/vr/libvrflinger/vr_flinger.cpp b/libs/vr/libvrflinger/vr_flinger.cpp
index 26aed4f..a27d58d 100644
--- a/libs/vr/libvrflinger/vr_flinger.cpp
+++ b/libs/vr/libvrflinger/vr_flinger.cpp
@@ -12,9 +12,9 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
-#include <cutils/sched_policy.h>
#include <log/log.h>
#include <private/dvr/display_client.h>
+#include <processgroup/sched_policy.h>
#include <sys/prctl.h>
#include <sys/resource.h>
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index ce4daa5..22e7761 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -44,6 +44,7 @@
"liblayers_proto",
"liblog",
"libpdx_default_transport",
+ "libprocessgroup",
"libprotobuf-cpp-lite",
"libsync",
"libtimestats_proto",
@@ -173,6 +174,7 @@
"libhidltransport",
"liblayers_proto",
"liblog",
+ "libprocessgroup",
"libsurfaceflinger",
"libtimestats_proto",
"libutils",
@@ -205,6 +207,7 @@
"libcutils",
"libdl",
"liblog",
+ "libprocessgroup",
],
product_variables: {
// uses jni which may not be available in PDK
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index d0900e9..aefe704 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -21,13 +21,13 @@
#include <android/frameworks/displayservice/1.0/IDisplayService.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <cutils/sched_policy.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <displayservice/DisplayService.h>
#include <hidl/LegacySupport.h>
+#include <processgroup/sched_policy.h>
#include <configstore/Utils.h>
#include "SurfaceFlinger.h"