Merge "[NETD-BPF#11] libgpumem includes WaitForProgsLoaded.h"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index eb9a51d..7ef26bf 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -6,6 +6,7 @@
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
cmds/idlcli/
+ cmds/installd/
cmds/servicemanager/
include/input/
include/powermanager/
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 783a475..6459443 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -239,7 +239,7 @@
} },
{ "memory", "Memory", 0, {
{ OPT, "events/mm_event/mm_event_record/enable" },
- { OPT, "events/kmem/rss_stat/enable" },
+ { OPT, "events/synthetic/rss_stat_throttled/enable" },
{ OPT, "events/kmem/ion_heap_grow/enable" },
{ OPT, "events/kmem/ion_heap_shrink/enable" },
{ OPT, "events/ion/ion_stat/enable" },
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 74dbf4b..a2491e5 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -86,9 +86,11 @@
shared_libs: [
"android.hardware.dumpstate@1.0",
"android.hardware.dumpstate@1.1",
+ "android.hardware.dumpstate-V1-ndk",
"libziparchive",
"libbase",
"libbinder",
+ "libbinder_ndk",
"libcrypto",
"libcutils",
"libdebuggerd_client",
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index ba25a5a..77915d5 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -192,7 +192,7 @@
dprintf(fd, "progress:\n");
ds_->progress_->Dump(fd, " ");
dprintf(fd, "args: %s\n", ds_->options_->args.c_str());
- dprintf(fd, "bugreport_mode: %s\n", ds_->options_->bugreport_mode.c_str());
+ dprintf(fd, "bugreport_mode: %s\n", ds_->options_->bugreport_mode_string.c_str());
dprintf(fd, "version: %s\n", ds_->version_.c_str());
dprintf(fd, "bugreport_dir: %s\n", destination.c_str());
dprintf(fd, "screenshot_path: %s\n", ds_->screenshot_path_.c_str());
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index eab72f4..32e680d 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -57,12 +57,15 @@
#include <utility>
#include <vector>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
#include <android/content/pm/IPackageManagerNative.h>
#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
#include <android/hardware/dumpstate/1.1/IDumpstateDevice.h>
@@ -89,11 +92,10 @@
#include "DumpstateService.h"
#include "dumpstate.h"
-using IDumpstateDevice_1_0 = ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
-using IDumpstateDevice_1_1 = ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
-using ::android::hardware::dumpstate::V1_1::DumpstateMode;
-using ::android::hardware::dumpstate::V1_1::DumpstateStatus;
-using ::android::hardware::dumpstate::V1_1::toString;
+namespace dumpstate_hal_hidl_1_0 = android::hardware::dumpstate::V1_0;
+namespace dumpstate_hal_hidl = android::hardware::dumpstate::V1_1;
+namespace dumpstate_hal_aidl = aidl::android::hardware::dumpstate;
+
using ::std::literals::chrono_literals::operator""ms;
using ::std::literals::chrono_literals::operator""s;
using ::std::placeholders::_1;
@@ -807,7 +809,7 @@
printf("Bugreport format version: %s\n", version_.c_str());
printf("Dumpstate info: id=%d pid=%d dry_run=%d parallel_run=%d args=%s bugreport_mode=%s\n",
id_, pid_, PropertiesHelper::IsDryRun(), PropertiesHelper::IsParallelRun(),
- options_->args.c_str(), options_->bugreport_mode.c_str());
+ options_->args.c_str(), options_->bugreport_mode_string.c_str());
printf("\n");
}
@@ -2199,6 +2201,194 @@
return RunStatus::OK;
}
+static dumpstate_hal_hidl::DumpstateMode GetDumpstateHalModeHidl(
+ const Dumpstate::BugreportMode bugreport_mode) {
+ switch (bugreport_mode) {
+ case Dumpstate::BugreportMode::BUGREPORT_FULL:
+ return dumpstate_hal_hidl::DumpstateMode::FULL;
+ case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
+ return dumpstate_hal_hidl::DumpstateMode::INTERACTIVE;
+ case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
+ return dumpstate_hal_hidl::DumpstateMode::REMOTE;
+ case Dumpstate::BugreportMode::BUGREPORT_WEAR:
+ return dumpstate_hal_hidl::DumpstateMode::WEAR;
+ case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
+ return dumpstate_hal_hidl::DumpstateMode::CONNECTIVITY;
+ case Dumpstate::BugreportMode::BUGREPORT_WIFI:
+ return dumpstate_hal_hidl::DumpstateMode::WIFI;
+ case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+ return dumpstate_hal_hidl::DumpstateMode::DEFAULT;
+ }
+ return dumpstate_hal_hidl::DumpstateMode::DEFAULT;
+}
+
+static dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode GetDumpstateHalModeAidl(
+ const Dumpstate::BugreportMode bugreport_mode) {
+ switch (bugreport_mode) {
+ case Dumpstate::BugreportMode::BUGREPORT_FULL:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::FULL;
+ case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::INTERACTIVE;
+ case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::REMOTE;
+ case Dumpstate::BugreportMode::BUGREPORT_WEAR:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::WEAR;
+ case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::CONNECTIVITY;
+ case Dumpstate::BugreportMode::BUGREPORT_WIFI:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::WIFI;
+ case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::DEFAULT;
+ }
+ return dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode::DEFAULT;
+}
+
+static void DoDumpstateBoardHidl(
+ const sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_1_0,
+ const std::vector<::ndk::ScopedFileDescriptor>& dumpstate_fds,
+ const Dumpstate::BugreportMode bugreport_mode,
+ const size_t timeout_sec) {
+
+ using ScopedNativeHandle =
+ std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
+ ScopedNativeHandle handle(native_handle_create(static_cast<int>(dumpstate_fds.size()), 0),
+ [](native_handle_t* handle) {
+ // we don't close file handle's here
+ // via native_handle_close(handle)
+ // instead we let dumpstate_fds close the file handles when
+ // dumpstate_fds gets destroyed
+ native_handle_delete(handle);
+ });
+ if (handle == nullptr) {
+ MYLOGE("Could not create native_handle for dumpstate HAL\n");
+ return;
+ }
+
+ for (size_t i = 0; i < dumpstate_fds.size(); i++) {
+ handle.get()->data[i] = dumpstate_fds[i].get();
+ }
+
+ // Prefer version 1.1 if available. New devices launching with R are no longer allowed to
+ // implement just 1.0.
+ const char* descriptor_to_kill;
+ using DumpstateBoardTask = std::packaged_task<bool()>;
+ DumpstateBoardTask dumpstate_board_task;
+ sp<dumpstate_hal_hidl::IDumpstateDevice> dumpstate_hal(
+ dumpstate_hal_hidl::IDumpstateDevice::castFrom(dumpstate_hal_1_0));
+ if (dumpstate_hal != nullptr) {
+ MYLOGI("Using IDumpstateDevice v1.1 HIDL HAL");
+
+ dumpstate_hal_hidl::DumpstateMode dumpstate_hal_mode =
+ GetDumpstateHalModeHidl(bugreport_mode);
+
+ descriptor_to_kill = dumpstate_hal_hidl::IDumpstateDevice::descriptor;
+ dumpstate_board_task =
+ DumpstateBoardTask([timeout_sec, dumpstate_hal_mode, dumpstate_hal, &handle]() -> bool {
+ ::android::hardware::Return<dumpstate_hal_hidl::DumpstateStatus> status =
+ dumpstate_hal->dumpstateBoard_1_1(handle.get(), dumpstate_hal_mode,
+ SEC_TO_MSEC(timeout_sec));
+ if (!status.isOk()) {
+ MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
+ return false;
+ } else if (status != dumpstate_hal_hidl::DumpstateStatus::OK) {
+ MYLOGE("dumpstateBoard failed with DumpstateStatus::%s\n",
+ dumpstate_hal_hidl::toString(status).c_str());
+ return false;
+ }
+ return true;
+ });
+ } else {
+ MYLOGI("Using IDumpstateDevice v1.0 HIDL HAL");
+
+ descriptor_to_kill = dumpstate_hal_hidl_1_0::IDumpstateDevice::descriptor;
+ dumpstate_board_task = DumpstateBoardTask([dumpstate_hal_1_0, &handle]() -> bool {
+ ::android::hardware::Return<void> status =
+ dumpstate_hal_1_0->dumpstateBoard(handle.get());
+ if (!status.isOk()) {
+ MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
+ return false;
+ }
+ return true;
+ });
+ }
+ auto result = dumpstate_board_task.get_future();
+ std::thread(std::move(dumpstate_board_task)).detach();
+
+ if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
+ MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate HAL\n", timeout_sec);
+ if (!android::base::SetProperty(
+ "ctl.interface_restart",
+ android::base::StringPrintf("%s/default", descriptor_to_kill))) {
+ MYLOGE("Couldn't restart dumpstate HAL\n");
+ }
+ }
+ // Wait some time for init to kill dumpstate vendor HAL
+ constexpr size_t killing_timeout_sec = 10;
+ if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
+ MYLOGE(
+ "killing dumpstateBoard timed out after %zus, continue and "
+ "there might be racing in content\n",
+ killing_timeout_sec);
+ }
+}
+
+static void DoDumpstateBoardAidl(
+ const std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> dumpstate_hal,
+ const std::vector<::ndk::ScopedFileDescriptor>& dumpstate_fds,
+ const Dumpstate::BugreportMode bugreport_mode, const size_t timeout_sec) {
+ MYLOGI("Using IDumpstateDevice AIDL HAL");
+
+ const char* descriptor_to_kill;
+ using DumpstateBoardTask = std::packaged_task<bool()>;
+ DumpstateBoardTask dumpstate_board_task;
+ dumpstate_hal_aidl::IDumpstateDevice::DumpstateMode dumpstate_hal_mode =
+ GetDumpstateHalModeAidl(bugreport_mode);
+
+ descriptor_to_kill = dumpstate_hal_aidl::IDumpstateDevice::descriptor;
+ dumpstate_board_task = DumpstateBoardTask([dumpstate_hal, &dumpstate_fds, dumpstate_hal_mode,
+ timeout_sec]() -> bool {
+ auto status = dumpstate_hal->dumpstateBoard(dumpstate_fds, dumpstate_hal_mode, timeout_sec);
+
+ if (!status.isOk()) {
+ MYLOGE("dumpstateBoard failed: %s\n", status.getDescription().c_str());
+ return false;
+ }
+ return true;
+ });
+ auto result = dumpstate_board_task.get_future();
+ std::thread(std::move(dumpstate_board_task)).detach();
+
+ if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
+ MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate HAL\n", timeout_sec);
+ if (!android::base::SetProperty(
+ "ctl.interface_restart",
+ android::base::StringPrintf("%s/default", descriptor_to_kill))) {
+ MYLOGE("Couldn't restart dumpstate HAL\n");
+ }
+ }
+ // Wait some time for init to kill dumpstate vendor HAL
+ constexpr size_t killing_timeout_sec = 10;
+ if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
+ MYLOGE(
+ "killing dumpstateBoard timed out after %zus, continue and "
+ "there might be racing in content\n",
+ killing_timeout_sec);
+ }
+}
+
+static std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> GetDumpstateBoardAidlService() {
+ const std::string aidl_instance_name =
+ std::string(dumpstate_hal_aidl::IDumpstateDevice::descriptor) + "/default";
+
+ if (!AServiceManager_isDeclared(aidl_instance_name.c_str())) {
+ return nullptr;
+ }
+
+ ndk::SpAIBinder dumpstateBinder(AServiceManager_waitForService(aidl_instance_name.c_str()));
+
+ return dumpstate_hal_aidl::IDumpstateDevice::fromBinder(dumpstateBinder);
+}
+
void Dumpstate::DumpstateBoard(int out_fd) {
dprintf(out_fd, "========================================================\n");
dprintf(out_fd, "== Board\n");
@@ -2220,8 +2410,7 @@
if (mount_debugfs) {
RunCommand("mount debugfs", {"mount", "-t", "debugfs", "debugfs", "/sys/kernel/debug"},
AS_ROOT_20);
- RunCommand("chmod debugfs", {"chmod", "0755", "/sys/kernel/debug"},
- AS_ROOT_20);
+ RunCommand("chmod debugfs", {"chmod", "0755", "/sys/kernel/debug"}, AS_ROOT_20);
}
std::vector<std::string> paths;
@@ -2233,23 +2422,31 @@
std::bind([](std::string path) { android::os::UnlinkAndLogOnError(path); }, paths[i])));
}
- sp<IDumpstateDevice_1_0> dumpstate_device_1_0(IDumpstateDevice_1_0::getService());
- if (dumpstate_device_1_0 == nullptr) {
- MYLOGE("No IDumpstateDevice implementation\n");
+ // get dumpstate HAL AIDL implementation
+ std::shared_ptr<dumpstate_hal_aidl::IDumpstateDevice> dumpstate_hal_handle_aidl(
+ GetDumpstateBoardAidlService());
+ if (dumpstate_hal_handle_aidl == nullptr) {
+ MYLOGI("No IDumpstateDevice AIDL implementation\n");
+ }
+
+ // get dumpstate HAL HIDL implementation, only if AIDL HAL implementation not found
+ sp<dumpstate_hal_hidl_1_0::IDumpstateDevice> dumpstate_hal_handle_hidl_1_0 = nullptr;
+ if (dumpstate_hal_handle_aidl == nullptr) {
+ dumpstate_hal_handle_hidl_1_0 = dumpstate_hal_hidl_1_0::IDumpstateDevice::getService();
+ if (dumpstate_hal_handle_hidl_1_0 == nullptr) {
+ MYLOGI("No IDumpstateDevice HIDL implementation\n");
+ }
+ }
+
+ // if neither HIDL nor AIDL implementation found, then return
+ if (dumpstate_hal_handle_hidl_1_0 == nullptr && dumpstate_hal_handle_aidl == nullptr) {
+ MYLOGE("Could not find IDumpstateDevice implementation\n");
return;
}
- using ScopedNativeHandle =
- std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
- ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
- [](native_handle_t* handle) {
- native_handle_close(handle);
- native_handle_delete(handle);
- });
- if (handle == nullptr) {
- MYLOGE("Could not create native_handle\n");
- return;
- }
+ // this is used to hold the file descriptors and when this variable goes out of scope
+ // the file descriptors are closed
+ std::vector<::ndk::ScopedFileDescriptor> dumpstate_fds;
// TODO(128270426): Check for consent in between?
for (size_t i = 0; i < paths.size(); i++) {
@@ -2262,65 +2459,26 @@
MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
return;
}
- handle.get()->data[i] = fd.release();
+
+ dumpstate_fds.emplace_back(fd.release());
+ // we call fd.release() here to make sure "fd" does not get closed
+ // after "fd" goes out of scope after this block.
+ // "fd" will be closed when "dumpstate_fds" goes out of scope
+ // i.e. when we exit this function
}
// Given that bugreport is required to diagnose failures, it's better to set an arbitrary amount
// of timeout for IDumpstateDevice than to block the rest of bugreport. In the timeout case, we
// will kill the HAL and grab whatever it dumped in time.
constexpr size_t timeout_sec = 30;
- // Prefer version 1.1 if available. New devices launching with R are no longer allowed to
- // implement just 1.0.
- const char* descriptor_to_kill;
- using DumpstateBoardTask = std::packaged_task<bool()>;
- DumpstateBoardTask dumpstate_board_task;
- sp<IDumpstateDevice_1_1> dumpstate_device_1_1(
- IDumpstateDevice_1_1::castFrom(dumpstate_device_1_0));
- if (dumpstate_device_1_1 != nullptr) {
- MYLOGI("Using IDumpstateDevice v1.1");
- descriptor_to_kill = IDumpstateDevice_1_1::descriptor;
- dumpstate_board_task = DumpstateBoardTask([this, dumpstate_device_1_1, &handle]() -> bool {
- ::android::hardware::Return<DumpstateStatus> status =
- dumpstate_device_1_1->dumpstateBoard_1_1(handle.get(), options_->dumpstate_hal_mode,
- SEC_TO_MSEC(timeout_sec));
- if (!status.isOk()) {
- MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
- return false;
- } else if (status != DumpstateStatus::OK) {
- MYLOGE("dumpstateBoard failed with DumpstateStatus::%s\n", toString(status).c_str());
- return false;
- }
- return true;
- });
- } else {
- MYLOGI("Using IDumpstateDevice v1.0");
- descriptor_to_kill = IDumpstateDevice_1_0::descriptor;
- dumpstate_board_task = DumpstateBoardTask([dumpstate_device_1_0, &handle]() -> bool {
- ::android::hardware::Return<void> status =
- dumpstate_device_1_0->dumpstateBoard(handle.get());
- if (!status.isOk()) {
- MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
- return false;
- }
- return true;
- });
- }
- auto result = dumpstate_board_task.get_future();
- std::thread(std::move(dumpstate_board_task)).detach();
- if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
- MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate vendor HAL\n", timeout_sec);
- if (!android::base::SetProperty(
- "ctl.interface_restart",
- android::base::StringPrintf("%s/default", descriptor_to_kill))) {
- MYLOGE("Couldn't restart dumpstate HAL\n");
- }
- }
- // Wait some time for init to kill dumpstate vendor HAL
- constexpr size_t killing_timeout_sec = 10;
- if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
- MYLOGE("killing dumpstateBoard timed out after %zus, continue and "
- "there might be racing in content\n", killing_timeout_sec);
+ if (dumpstate_hal_handle_aidl != nullptr) {
+ DoDumpstateBoardAidl(dumpstate_hal_handle_aidl, dumpstate_fds, options_->bugreport_mode,
+ timeout_sec);
+ } else if (dumpstate_hal_handle_hidl_1_0 != nullptr) {
+ // run HIDL HAL only if AIDL HAL not found
+ DoDumpstateBoardHidl(dumpstate_hal_handle_hidl_1_0, dumpstate_fds, options_->bugreport_mode,
+ timeout_sec);
}
if (mount_debugfs) {
@@ -2333,9 +2491,8 @@
auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
for (size_t i = 0; i < paths.size(); i++) {
struct stat s;
- if (fstat(handle.get()->data[i], &s) == -1) {
- MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
- strerror(errno));
+ if (fstat(dumpstate_fds[i].get(), &s) == -1) {
+ MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(), strerror(errno));
file_sizes[i] = -1;
continue;
}
@@ -2574,40 +2731,35 @@
bool is_screenshot_requested) {
// Modify com.android.shell.BugreportProgressService#isDefaultScreenshotRequired as well for
// default system screenshots.
- options->bugreport_mode = ModeToString(mode);
+ options->bugreport_mode = mode;
+ options->bugreport_mode_string = ModeToString(mode);
switch (mode) {
case Dumpstate::BugreportMode::BUGREPORT_FULL:
options->do_screenshot = is_screenshot_requested;
- options->dumpstate_hal_mode = DumpstateMode::FULL;
break;
case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
// Currently, the dumpstate binder is only used by Shell to update progress.
options->do_progress_updates = true;
options->do_screenshot = is_screenshot_requested;
- options->dumpstate_hal_mode = DumpstateMode::INTERACTIVE;
break;
case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
options->do_vibrate = false;
options->is_remote_mode = true;
options->do_screenshot = false;
- options->dumpstate_hal_mode = DumpstateMode::REMOTE;
break;
case Dumpstate::BugreportMode::BUGREPORT_WEAR:
options->do_progress_updates = true;
options->do_screenshot = is_screenshot_requested;
- options->dumpstate_hal_mode = DumpstateMode::WEAR;
break;
// TODO(b/148168577) rename TELEPHONY everywhere to CONNECTIVITY.
case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
options->telephony_only = true;
options->do_progress_updates = true;
options->do_screenshot = false;
- options->dumpstate_hal_mode = DumpstateMode::CONNECTIVITY;
break;
case Dumpstate::BugreportMode::BUGREPORT_WIFI:
options->wifi_only = true;
options->do_screenshot = false;
- options->dumpstate_hal_mode = DumpstateMode::WIFI;
break;
case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
break;
@@ -2618,13 +2770,14 @@
MYLOGI(
"do_vibrate: %d stream_to_socket: %d progress_updates_to_socket: %d do_screenshot: %d "
"is_remote_mode: %d show_header_only: %d telephony_only: %d "
- "wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s dumpstate_hal_mode: %s "
+ "wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s "
"limited_only: %d args: %s\n",
options.do_vibrate, options.stream_to_socket, options.progress_updates_to_socket,
options.do_screenshot, options.is_remote_mode, options.show_header_only,
options.telephony_only, options.wifi_only,
- options.do_progress_updates, options.bugreport_fd.get(), options.bugreport_mode.c_str(),
- toString(options.dumpstate_hal_mode).c_str(), options.limited_only, options.args.c_str());
+ options.do_progress_updates, options.bugreport_fd.get(),
+ options.bugreport_mode_string.c_str(),
+ options.limited_only, options.args.c_str());
}
void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
@@ -2838,7 +2991,7 @@
}
MYLOGI("dumpstate info: id=%d, args='%s', bugreport_mode= %s bugreport format version: %s\n",
- id_, options_->args.c_str(), options_->bugreport_mode.c_str(), version_.c_str());
+ id_, options_->args.c_str(), options_->bugreport_mode_string.c_str(), version_.c_str());
do_early_screenshot_ = options_->do_progress_updates;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 3722383..773e292 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -25,6 +25,7 @@
#include <string>
#include <vector>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
#include <android-base/macros.h>
#include <android-base/unique_fd.h>
#include <android/hardware/dumpstate/1.1/types.h>
@@ -400,19 +401,18 @@
bool limited_only = false;
// Whether progress updates should be published.
bool do_progress_updates = false;
- // The mode we'll use when calling IDumpstateDevice::dumpstateBoard.
+ // this is used to derive dumpstate HAL bug report mode
// TODO(b/148168577) get rid of the AIDL values, replace them with the HAL values instead.
// The HAL is actually an API surface that can be validated, while the AIDL is not (@hide).
- ::android::hardware::dumpstate::V1_1::DumpstateMode dumpstate_hal_mode =
- ::android::hardware::dumpstate::V1_1::DumpstateMode::DEFAULT;
+ BugreportMode bugreport_mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
// File descriptor to output zip file. Takes precedence over out_dir.
android::base::unique_fd bugreport_fd;
// File descriptor to screenshot file.
android::base::unique_fd screenshot_fd;
// Custom output directory.
std::string out_dir;
- // Bugreport mode of the bugreport.
- std::string bugreport_mode;
+ // Bugreport mode of the bugreport as a string
+ std::string bugreport_mode_string;
// Command-line arguments as string
std::string args;
// Notification title and description
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index db508b5..42beb2b 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <thread>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
@@ -47,6 +48,7 @@
namespace os {
namespace dumpstate {
+using DumpstateDeviceAidl = ::aidl::android::hardware::dumpstate::IDumpstateDevice;
using ::android::hardware::dumpstate::V1_1::DumpstateMode;
using ::testing::EndsWith;
using ::testing::Eq;
@@ -186,7 +188,6 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.limited_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
@@ -210,7 +211,6 @@
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.stream_to_socket);
EXPECT_FALSE(options_.limited_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
@@ -234,13 +234,11 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.limited_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeFullBugReport) {
options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
EXPECT_TRUE(options_.do_screenshot);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::FULL);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -256,7 +254,6 @@
options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
EXPECT_TRUE(options_.do_progress_updates);
EXPECT_TRUE(options_.do_screenshot);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::INTERACTIVE);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -272,7 +269,6 @@
EXPECT_TRUE(options_.is_remote_mode);
EXPECT_FALSE(options_.do_vibrate);
EXPECT_FALSE(options_.do_screenshot);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::REMOTE);
// Other options retain default values
EXPECT_FALSE(options_.progress_updates_to_socket);
@@ -286,7 +282,7 @@
options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
EXPECT_TRUE(options_.do_screenshot);
EXPECT_TRUE(options_.do_progress_updates);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WEAR);
+
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -302,7 +298,6 @@
EXPECT_FALSE(options_.do_screenshot);
EXPECT_TRUE(options_.telephony_only);
EXPECT_TRUE(options_.do_progress_updates);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::CONNECTIVITY);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -317,7 +312,6 @@
options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
EXPECT_FALSE(options_.do_screenshot);
EXPECT_TRUE(options_.wifi_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WIFI);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -354,7 +348,6 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.stream_to_socket);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
@@ -371,7 +364,6 @@
EXPECT_EQ(status, Dumpstate::RunStatus::OK);
EXPECT_TRUE(options_.do_screenshot);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
// Other options retain default values
EXPECT_TRUE(options_.do_vibrate);
@@ -408,7 +400,6 @@
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.limited_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializePartial2) {
@@ -436,7 +427,6 @@
EXPECT_FALSE(options_.stream_to_socket);
EXPECT_FALSE(options_.progress_updates_to_socket);
EXPECT_FALSE(options_.limited_only);
- EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
}
TEST_F(DumpOptionsTest, InitializeHelp) {
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 3f180d9..faa8485 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -45,6 +45,7 @@
"libprocessgroup",
"libselinux",
"libutils",
+ "libziparchive",
"server_configurable_flags",
],
static_libs: [
@@ -267,6 +268,7 @@
"libprocessgroup",
"libselinux",
"libutils",
+ "libziparchive",
"server_configurable_flags",
],
}
diff --git a/cmds/installd/CacheItem.cpp b/cmds/installd/CacheItem.cpp
index e29ff4c..27690a3 100644
--- a/cmds/installd/CacheItem.cpp
+++ b/cmds/installd/CacheItem.cpp
@@ -116,6 +116,7 @@
break;
}
}
+ fts_close(fts);
} else {
if (tombstone) {
if (truncate(path.c_str(), 0) != 0) {
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 39ef0b5..373a70a 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -77,6 +77,8 @@
#define LOG_TAG "installd"
#endif
+// #define GRANULAR_LOCKS
+
using android::base::ParseUint;
using android::base::StringPrintf;
using std::endl;
@@ -265,6 +267,104 @@
} \
}
+#ifdef GRANULAR_LOCKS
+
+/**
+ * This class obtains in constructor and keeps the local strong pointer to the RefLock.
+ * On destruction, it checks if there are any other strong pointers, and remove the map entry if
+ * this was the last one.
+ */
+template <class Key, class Mutex>
+struct LocalLockHolder {
+ using WeakPointer = std::weak_ptr<Mutex>;
+ using StrongPointer = std::shared_ptr<Mutex>;
+ using Map = std::unordered_map<Key, WeakPointer>;
+ using MapLock = std::recursive_mutex;
+
+ LocalLockHolder(Key key, Map& map, MapLock& mapLock)
+ : mKey(std::move(key)), mMap(map), mMapLock(mapLock) {
+ std::lock_guard lock(mMapLock);
+ auto& weakPtr = mMap[mKey];
+
+ // Check if the RefLock is still alive.
+ mRefLock = weakPtr.lock();
+ if (!mRefLock) {
+ // Create a new lock.
+ mRefLock = std::make_shared<Mutex>();
+ weakPtr = mRefLock;
+ }
+ }
+ LocalLockHolder(LocalLockHolder&& other) noexcept
+ : mKey(std::move(other.mKey)),
+ mMap(other.mMap),
+ mMapLock(other.mMapLock),
+ mRefLock(std::move(other.mRefLock)) {
+ other.mRefLock.reset();
+ }
+ ~LocalLockHolder() {
+ if (!mRefLock) {
+ return;
+ }
+
+ std::lock_guard lock(mMapLock);
+ // Clear the strong pointer.
+ mRefLock.reset();
+ auto found = mMap.find(mKey);
+ if (found == mMap.end()) {
+ return;
+ }
+ const auto& weakPtr = found->second;
+ // If this was the last pointer then it's ok to remove the map entry.
+ if (weakPtr.expired()) {
+ mMap.erase(found);
+ }
+ }
+
+ void lock() { mRefLock->lock(); }
+ void unlock() { mRefLock->unlock(); }
+ void lock_shared() { mRefLock->lock_shared(); }
+ void unlock_shared() { mRefLock->unlock_shared(); }
+
+private:
+ Key mKey;
+ Map& mMap;
+ MapLock& mMapLock;
+ StrongPointer mRefLock;
+};
+
+using UserLock = LocalLockHolder<userid_t, std::shared_mutex>;
+using UserWriteLockGuard = std::unique_lock<UserLock>;
+using UserReadLockGuard = std::shared_lock<UserLock>;
+
+using PackageLock = LocalLockHolder<std::string, std::recursive_mutex>;
+using PackageLockGuard = std::lock_guard<PackageLock>;
+
+#define LOCK_USER() \
+ UserLock localUserLock(userId, mUserIdLock, mLock); \
+ UserWriteLockGuard userLock(localUserLock)
+
+#define LOCK_USER_READ() \
+ UserLock localUserLock(userId, mUserIdLock, mLock); \
+ UserReadLockGuard userLock(localUserLock)
+
+#define LOCK_PACKAGE() \
+ PackageLock localPackageLock(packageName, mPackageNameLock, mLock); \
+ PackageLockGuard packageLock(localPackageLock)
+
+#define LOCK_PACKAGE_USER() \
+ LOCK_USER_READ(); \
+ LOCK_PACKAGE()
+
+#else
+
+#define LOCK_USER() std::lock_guard lock(mLock)
+#define LOCK_PACKAGE() std::lock_guard lock(mLock)
+#define LOCK_PACKAGE_USER() \
+ (void)userId; \
+ std::lock_guard lock(mLock)
+
+#endif // GRANULAR_LOCKS
+
} // namespace
status_t InstalldNativeService::start() {
@@ -288,8 +388,6 @@
return PERMISSION_DENIED;
}
- std::lock_guard<std::recursive_mutex> lock(mLock);
-
{
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
dprintf(fd, "Storage mounts:\n");
@@ -543,14 +641,13 @@
return ok();
}
-binder::Status InstalldNativeService::createAppData(const std::optional<std::string>& uuid,
- const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
- int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
- int64_t* _aidl_return) {
+binder::Status InstalldNativeService::createAppDataLocked(
+ const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
+ int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
+ int32_t targetSdkVersion, int64_t* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
const char* pkgname = packageName.c_str();
@@ -619,10 +716,22 @@
}
binder::Status InstalldNativeService::createAppData(
+ const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
+ int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo,
+ int32_t targetSdkVersion, int64_t* _aidl_return) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID(uuid);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+ LOCK_PACKAGE_USER();
+ return createAppDataLocked(uuid, packageName, userId, flags, appId, previousAppId, seInfo,
+ targetSdkVersion, _aidl_return);
+}
+
+binder::Status InstalldNativeService::createAppData(
const android::os::CreateAppDataArgs& args,
android::os::CreateAppDataResult* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ // Locking is performed depeer in the callstack.
int64_t ceDataInode = -1;
auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
@@ -637,7 +746,7 @@
const std::vector<android::os::CreateAppDataArgs>& args,
std::vector<android::os::CreateAppDataResult>* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ // Locking is performed depeer in the callstack.
std::vector<android::os::CreateAppDataResult> results;
for (const auto &arg : args) {
@@ -654,7 +763,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
const char* pkgname = packageName.c_str();
@@ -698,7 +807,7 @@
const std::string& profileName) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
binder::Status res = ok();
if (!clear_primary_reference_profile(packageName, profileName)) {
@@ -715,7 +824,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
const char* pkgname = packageName.c_str();
@@ -812,7 +921,7 @@
binder::Status InstalldNativeService::destroyAppProfiles(const std::string& packageName) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
binder::Status res = ok();
std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
@@ -832,7 +941,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
const char* pkgname = packageName.c_str();
@@ -903,15 +1012,15 @@
int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
- std::lock_guard<std::recursive_mutex> lock(mLock);
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
- for (auto user : get_known_users(uuid_)) {
+ for (auto userId : get_known_users(uuid_)) {
+ LOCK_USER();
ATRACE_BEGIN("fixup user");
FTS* fts;
FTSENT* p;
- auto ce_path = create_data_user_ce_path(uuid_, user);
- auto de_path = create_data_user_de_path(uuid_, user);
+ auto ce_path = create_data_user_ce_path(uuid_, userId);
+ auto de_path = create_data_user_de_path(uuid_, userId);
char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(), nullptr };
if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
return error("Failed to fts_open");
@@ -1018,14 +1127,14 @@
return logwrap_fork_execvp(ARRAY_SIZE(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
}
-binder::Status InstalldNativeService::snapshotAppData(
- const std::optional<std::string>& volumeUuid,
- const std::string& packageName, int32_t user, int32_t snapshotId,
- int32_t storageFlags, int64_t* _aidl_return) {
+binder::Status InstalldNativeService::snapshotAppData(const std::optional<std::string>& volumeUuid,
+ const std::string& packageName,
+ int32_t userId, int32_t snapshotId,
+ int32_t storageFlags, int64_t* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
const char* package_name = packageName.c_str();
@@ -1038,19 +1147,19 @@
bool clear_ce_on_exit = false;
bool clear_de_on_exit = false;
- auto deleter = [&clear_ce_on_exit, &clear_de_on_exit, &volume_uuid, &user, &package_name,
- &snapshotId] {
+ auto deleter = [&clear_ce_on_exit, &clear_de_on_exit, &volume_uuid, &userId, &package_name,
+ &snapshotId] {
if (clear_de_on_exit) {
- auto to = create_data_misc_de_rollback_package_path(volume_uuid, user, snapshotId,
- package_name);
+ auto to = create_data_misc_de_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
LOG(WARNING) << "Failed to delete app data snapshot: " << to;
}
}
if (clear_ce_on_exit) {
- auto to = create_data_misc_ce_rollback_package_path(volume_uuid, user, snapshotId,
- package_name);
+ auto to = create_data_misc_ce_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
LOG(WARNING) << "Failed to delete app data snapshot: " << to;
}
@@ -1060,10 +1169,11 @@
auto scope_guard = android::base::make_scope_guard(deleter);
if (storageFlags & FLAG_STORAGE_DE) {
- auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
- auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
- auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
- snapshotId, package_name);
+ auto from = create_data_user_de_package_path(volume_uuid, userId, package_name);
+ auto to = create_data_misc_de_rollback_path(volume_uuid, userId, snapshotId);
+ auto rollback_package_path =
+ create_data_misc_de_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
if (rc != 0) {
@@ -1087,15 +1197,15 @@
}
// The app may not have any data at all, in which case it's OK to skip here.
- auto from_ce = create_data_user_ce_package_path(volume_uuid, user, package_name);
+ auto from_ce = create_data_user_ce_package_path(volume_uuid, userId, package_name);
if (access(from_ce.c_str(), F_OK) != 0) {
LOG(INFO) << "Missing source " << from_ce;
return ok();
}
// ce_data_inode is not needed when FLAG_CLEAR_CACHE_ONLY is set.
- binder::Status clear_cache_result = clearAppData(volumeUuid, packageName, user,
- storageFlags | FLAG_CLEAR_CACHE_ONLY, 0);
+ binder::Status clear_cache_result =
+ clearAppData(volumeUuid, packageName, userId, storageFlags | FLAG_CLEAR_CACHE_ONLY, 0);
if (!clear_cache_result.isOk()) {
// It should be fine to continue snapshot if we for some reason failed
// to clear cache.
@@ -1103,8 +1213,9 @@
}
// ce_data_inode is not needed when FLAG_CLEAR_CODE_CACHE_ONLY is set.
- binder::Status clear_code_cache_result = clearAppData(volumeUuid, packageName, user,
- storageFlags | FLAG_CLEAR_CODE_CACHE_ONLY, 0);
+ binder::Status clear_code_cache_result =
+ clearAppData(volumeUuid, packageName, userId, storageFlags | FLAG_CLEAR_CODE_CACHE_ONLY,
+ 0);
if (!clear_code_cache_result.isOk()) {
// It should be fine to continue snapshot if we for some reason failed
// to clear code_cache.
@@ -1112,10 +1223,11 @@
}
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, snapshotId);
- auto rollback_package_path = create_data_misc_ce_rollback_package_path(volume_uuid, user,
- snapshotId, package_name);
+ auto from = create_data_user_ce_package_path(volume_uuid, userId, package_name);
+ auto to = create_data_misc_ce_rollback_path(volume_uuid, userId, snapshotId);
+ auto rollback_package_path =
+ create_data_misc_ce_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
if (rc != 0) {
@@ -1134,8 +1246,9 @@
return res;
}
if (_aidl_return != nullptr) {
- auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user,
- snapshotId, package_name);
+ auto ce_snapshot_path =
+ create_data_misc_ce_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
rc = get_path_inode(ce_snapshot_path, reinterpret_cast<ino_t*>(_aidl_return));
if (rc != 0) {
res = error(rc, "Failed to get_path_inode for " + ce_snapshot_path);
@@ -1150,20 +1263,20 @@
binder::Status InstalldNativeService::restoreAppDataSnapshot(
const std::optional<std::string>& volumeUuid, const std::string& packageName,
- const int32_t appId, const std::string& seInfo, const int32_t user,
+ const int32_t appId, const std::string& seInfo, const int32_t userId,
const int32_t snapshotId, int32_t storageFlags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
const char* package_name = packageName.c_str();
- auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid,
- user, snapshotId, package_name);
- auto from_de = create_data_misc_de_rollback_package_path(volume_uuid,
- user, snapshotId, package_name);
+ auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
+ auto from_de = create_data_misc_de_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name);
const bool needs_ce_rollback = (storageFlags & FLAG_STORAGE_CE) &&
(access(from_ce.c_str(), F_OK) == 0);
@@ -1183,14 +1296,14 @@
// It's fine to pass 0 as ceDataInode here, because restoreAppDataSnapshot
// can only be called when user unlocks the phone, meaning that CE user data
// is decrypted.
- binder::Status res = clearAppData(volumeUuid, packageName, user, storageFlags,
- 0 /* ceDataInode */);
+ binder::Status res =
+ clearAppData(volumeUuid, packageName, userId, storageFlags, 0 /* ceDataInode */);
if (!res.isOk()) {
return res;
}
if (needs_ce_rollback) {
- auto to_ce = create_data_user_ce_path(volume_uuid, user);
+ auto to_ce = create_data_user_ce_path(volume_uuid, userId);
int rc = copy_directory_recursive(from_ce.c_str(), to_ce.c_str());
if (rc != 0) {
res = error(rc, "Failed copying " + from_ce + " to " + to_ce);
@@ -1200,11 +1313,11 @@
}
if (needs_de_rollback) {
- auto to_de = create_data_user_de_path(volume_uuid, user);
+ auto to_de = create_data_user_de_path(volume_uuid, userId);
int rc = copy_directory_recursive(from_de.c_str(), to_de.c_str());
if (rc != 0) {
if (needs_ce_rollback) {
- auto ce_data = create_data_user_ce_package_path(volume_uuid, user, package_name);
+ auto ce_data = create_data_user_ce_package_path(volume_uuid, userId, package_name);
LOG(WARNING) << "de_data rollback failed. Erasing rolled back ce_data " << ce_data;
if (delete_dir_contents(ce_data.c_str(), 1, nullptr) != 0) {
LOG(WARNING) << "Failed to delete rolled back ce_data " << ce_data;
@@ -1217,24 +1330,24 @@
}
// Finally, restore the SELinux label on the app data.
- return restoreconAppData(volumeUuid, packageName, user, storageFlags, appId, seInfo);
+ return restoreconAppData(volumeUuid, packageName, userId, storageFlags, appId, seInfo);
}
binder::Status InstalldNativeService::destroyAppDataSnapshot(
- const std::optional<std::string> &volumeUuid, const std::string& packageName,
- const int32_t user, const int64_t ceSnapshotInode, const int32_t snapshotId,
+ const std::optional<std::string>& volumeUuid, const std::string& packageName,
+ const int32_t userId, const int64_t ceSnapshotInode, const int32_t snapshotId,
int32_t storageFlags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
const char* package_name = packageName.c_str();
if (storageFlags & FLAG_STORAGE_DE) {
- auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid,
- user, snapshotId, package_name);
+ auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid, userId,
+ snapshotId, package_name);
int res = delete_dir_contents_and_dir(de_snapshot_path, true /* ignore_if_missing */);
if (res != 0) {
@@ -1243,8 +1356,9 @@
}
if (storageFlags & FLAG_STORAGE_CE) {
- auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid,
- user, snapshotId, package_name, ceSnapshotInode);
+ auto ce_snapshot_path =
+ create_data_misc_ce_rollback_package_path(volume_uuid, userId, snapshotId,
+ package_name, ceSnapshotInode);
int res = delete_dir_contents_and_dir(ce_snapshot_path, true /* ignore_if_missing */);
if (res != 0) {
return error(res, "Failed clearing snapshot " + ce_snapshot_path);
@@ -1254,15 +1368,15 @@
}
binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified(
- const std::optional<std::string> &volumeUuid, const int32_t user,
+ const std::optional<std::string>& volumeUuid, const int32_t userId,
const std::vector<int32_t>& retainSnapshotIds) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_USER();
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
- auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, user);
+ auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, userId);
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(base_path.c_str()), closedir);
if (!dir) {
@@ -1280,8 +1394,8 @@
if (parse_ok &&
std::find(retainSnapshotIds.begin(), retainSnapshotIds.end(),
snapshot_id) == retainSnapshotIds.end()) {
- auto rollback_path = create_data_misc_ce_rollback_path(
- volume_uuid, user, snapshot_id);
+ auto rollback_path =
+ create_data_misc_ce_rollback_path(volume_uuid, userId, snapshot_id);
int res = delete_dir_contents_and_dir(rollback_path, true /* ignore_if_missing */);
if (res != 0) {
return error(res, "Failed clearing snapshot " + rollback_path);
@@ -1299,7 +1413,7 @@
CHECK_ARGUMENT_UUID(fromUuid);
CHECK_ARGUMENT_UUID(toUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
const char* from_uuid = fromUuid ? fromUuid->c_str() : nullptr;
const char* to_uuid = toUuid ? toUuid->c_str() : nullptr;
@@ -1327,24 +1441,25 @@
}
// Copy private data for all known users
- for (auto user : users) {
+ for (auto userId : users) {
+ LOCK_USER();
// Data source may not exist for all users; that's okay
- auto from_ce = create_data_user_ce_package_path(from_uuid, user, package_name);
+ auto from_ce = create_data_user_ce_package_path(from_uuid, userId, package_name);
if (access(from_ce.c_str(), F_OK) != 0) {
LOG(INFO) << "Missing source " << from_ce;
continue;
}
- if (!createAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId,
- /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr).isOk()) {
+ if (!createAppDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
+ appId, /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr)
+ .isOk()) {
res = error("Failed to create package target");
goto fail;
}
-
{
- auto from = create_data_user_de_package_path(from_uuid, user, package_name);
- auto to = create_data_user_de_path(to_uuid, user);
+ auto from = create_data_user_de_package_path(from_uuid, userId, package_name);
+ auto to = create_data_user_de_path(to_uuid, userId);
int rc = copy_directory_recursive(from.c_str(), to.c_str());
if (rc != 0) {
@@ -1353,8 +1468,8 @@
}
}
{
- auto from = create_data_user_ce_package_path(from_uuid, user, package_name);
- auto to = create_data_user_ce_path(to_uuid, user);
+ auto from = create_data_user_ce_package_path(from_uuid, userId, package_name);
+ auto to = create_data_user_ce_path(to_uuid, userId);
int rc = copy_directory_recursive(from.c_str(), to.c_str());
if (rc != 0) {
@@ -1363,8 +1478,9 @@
}
}
- if (!restoreconAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
- appId, seInfo).isOk()) {
+ if (!restoreconAppDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
+ appId, seInfo)
+ .isOk()) {
res = error("Failed to restorecon");
goto fail;
}
@@ -1382,15 +1498,16 @@
LOG(WARNING) << "Failed to rollback " << to_app_package_path;
}
}
- for (auto user : users) {
+ for (auto userId : users) {
+ LOCK_USER();
{
- auto to = create_data_user_de_package_path(to_uuid, user, package_name);
+ auto to = create_data_user_de_package_path(to_uuid, userId, package_name);
if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
LOG(WARNING) << "Failed to rollback " << to;
}
}
{
- auto to = create_data_user_ce_package_path(to_uuid, user, package_name);
+ auto to = create_data_user_ce_package_path(to_uuid, userId, package_name);
if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
LOG(WARNING) << "Failed to rollback " << to;
}
@@ -1403,7 +1520,7 @@
int32_t userId, int32_t userSerial ATTRIBUTE_UNUSED, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
if (flags & FLAG_STORAGE_DE) {
@@ -1421,7 +1538,7 @@
int32_t userId, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
binder::Status res = ok();
@@ -1458,7 +1575,9 @@
int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+#ifndef GRANULAR_LOCKS
+ std::lock_guard lock(mLock);
+#endif // !GRANULAR_LOCKS
auto uuidString = uuid.value_or("");
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
@@ -1485,13 +1604,24 @@
// 1. Create trackers for every known UID
ATRACE_BEGIN("create");
+ const auto users = get_known_users(uuid_);
+#ifdef GRANULAR_LOCKS
+ std::vector<UserLock> userLocks;
+ userLocks.reserve(users.size());
+ std::vector<UserWriteLockGuard> lockGuards;
+ lockGuards.reserve(users.size());
+#endif // GRANULAR_LOCKS
std::unordered_map<uid_t, std::shared_ptr<CacheTracker>> trackers;
- for (auto user : get_known_users(uuid_)) {
+ for (auto userId : users) {
+#ifdef GRANULAR_LOCKS
+ userLocks.emplace_back(userId, mUserIdLock, mLock);
+ lockGuards.emplace_back(userLocks.back());
+#endif // GRANULAR_LOCKS
FTS *fts;
FTSENT *p;
- auto ce_path = create_data_user_ce_path(uuid_, user);
- auto de_path = create_data_user_de_path(uuid_, user);
- auto media_path = findDataMediaPath(uuid, user) + "/Android/data/";
+ auto ce_path = create_data_user_ce_path(uuid_, userId);
+ auto de_path = create_data_user_de_path(uuid_, userId);
+ auto media_path = findDataMediaPath(uuid, userId) + "/Android/data/";
char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(),
(char*) media_path.c_str(), nullptr };
if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
@@ -1627,7 +1757,6 @@
const std::string& instructionSet) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(codePath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
char dex_path[PKG_PATH_MAX];
@@ -2343,7 +2472,7 @@
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
}
#ifdef ENABLE_STORAGE_CRATES
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
auto retVector = std::vector<std::optional<CrateMetadata>>();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
@@ -2389,7 +2518,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
#ifdef ENABLE_STORAGE_CRATES
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
auto retVector = std::vector<std::optional<CrateMetadata>>();
@@ -2446,7 +2575,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(codePath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
*_aidl_return = dump_profiles(uid, packageName, profileName, codePath);
return ok();
@@ -2458,7 +2587,7 @@
bool* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
*_aidl_return = copy_system_profile(systemProfile, packageUid, packageName, profileName);
return ok();
}
@@ -2468,7 +2597,7 @@
const std::string& profileName, int* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
*_aidl_return = analyze_primary_profiles(uid, packageName, profileName);
return ok();
@@ -2479,7 +2608,7 @@
const std::string& classpath, bool* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
*_aidl_return = create_profile_snapshot(appId, packageName, profileName, classpath);
return ok();
@@ -2489,7 +2618,7 @@
const std::string& profileName) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
std::string snapshot = create_snapshot_profile_path(packageName, profileName);
if ((unlink(snapshot.c_str()) != 0) && (errno != ENOENT)) {
@@ -2520,7 +2649,8 @@
}
CHECK_ARGUMENT_PATH(outputPath);
CHECK_ARGUMENT_PATH(dexMetadataPath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ const auto userId = multiuser_get_user_id(uid);
+ LOCK_PACKAGE_USER();
const char* oat_dir = getCStr(outputPath);
const char* instruction_set = instructionSet.c_str();
@@ -2571,7 +2701,7 @@
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(nativeLibPath32);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
const char* pkgname = packageName.c_str();
@@ -2662,7 +2792,16 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
+ return restoreconAppDataLocked(uuid, packageName, userId, flags, appId, seInfo);
+}
+
+binder::Status InstalldNativeService::restoreconAppDataLocked(
+ const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId,
+ int32_t flags, int32_t appId, const std::string& seInfo) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID(uuid);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
binder::Status res = ok();
@@ -2692,7 +2831,7 @@
const std::string& instructionSet) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(oatDir);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
const char* oat_dir = oatDir.c_str();
const char* instruction_set = instructionSet.c_str();
@@ -2717,7 +2856,7 @@
binder::Status InstalldNativeService::rmPackageDir(const std::string& packageDir) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(packageDir);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
if (validate_apk_path(packageDir.c_str())) {
return error("Invalid path " + packageDir);
@@ -2733,7 +2872,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(fromBase);
CHECK_ARGUMENT_PATH(toBase);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
const char* relative_path = relativePath.c_str();
const char* from_base = fromBase.c_str();
@@ -2763,7 +2902,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(apkPath);
CHECK_ARGUMENT_PATH(outputPath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
const char* apk_path = apkPath.c_str();
const char* instruction_set = instructionSet.c_str();
@@ -2779,7 +2918,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(apkPath);
CHECK_ARGUMENT_PATH(outputPath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
const char* apk_path = apkPath.c_str();
const char* instruction_set = instructionSet.c_str();
@@ -2812,7 +2951,7 @@
android::base::unique_fd verityInputAshmem, int32_t contentSize) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(filePath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
return ok();
@@ -2894,7 +3033,7 @@
const std::vector<uint8_t>& expectedHash) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(filePath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE();
if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
return ok();
@@ -2933,7 +3072,8 @@
CHECK_ARGUMENT_UUID(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(dexPath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ const auto userId = multiuser_get_user_id(uid);
+ LOCK_PACKAGE_USER();
bool result = android::installd::reconcile_secondary_dex_file(
dexPath, packageName, uid, isas, volumeUuid, storage_flag, _aidl_return);
@@ -3013,8 +3153,9 @@
const char* uuid_ = uuid->c_str();
+ std::lock_guard<std::recursive_mutex> lock(mMountsLock);
+
std::string mirrorVolCePath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_));
- std::lock_guard<std::recursive_mutex> lock(mLock);
if (fs_prepare_dir(mirrorVolCePath.c_str(), 0711, AID_SYSTEM, AID_SYSTEM) != 0) {
return error("Failed to create CE mirror");
}
@@ -3083,8 +3224,9 @@
std::string mirrorCeVolPath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_));
std::string mirrorDeVolPath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_));
+ std::lock_guard<std::recursive_mutex> lock(mMountsLock);
+
// Unmount CE storage
- std::lock_guard<std::recursive_mutex> lock(mLock);
if (TEMP_FAILURE_RETRY(umount(mirrorCeVolPath.c_str())) != 0) {
if (errno != ENOENT) {
res = error(StringPrintf("Failed to umount %s %s", mirrorCeVolPath.c_str(),
@@ -3133,7 +3275,7 @@
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(codePath);
- std::lock_guard<std::recursive_mutex> lock(mLock);
+ LOCK_PACKAGE_USER();
*_aidl_return = prepare_app_profile(packageName, userId, appId, profileName, codePath,
dexMetadata);
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 8cfda01..09581bb 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -21,8 +21,9 @@
#include <inttypes.h>
#include <unistd.h>
-#include <vector>
+#include <shared_mutex>
#include <unordered_map>
+#include <vector>
#include <android-base/macros.h>
#include <binder/BinderService.h>
@@ -49,6 +50,11 @@
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
int64_t* _aidl_return);
+ binder::Status createAppDataLocked(const std::optional<std::string>& uuid,
+ const std::string& packageName, int32_t userId,
+ int32_t flags, int32_t appId, int32_t previousAppId,
+ const std::string& seInfo, int32_t targetSdkVersion,
+ int64_t* _aidl_return);
binder::Status createAppData(
const android::os::CreateAppDataArgs& args,
@@ -60,6 +66,9 @@
binder::Status restoreconAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
const std::string& seInfo);
+ binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid,
+ const std::string& packageName, int32_t userId,
+ int32_t flags, int32_t appId, const std::string& seInfo);
binder::Status migrateAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags);
binder::Status clearAppData(const std::optional<std::string>& uuid,
@@ -181,6 +190,8 @@
private:
std::recursive_mutex mLock;
+ std::unordered_map<userid_t, std::weak_ptr<std::shared_mutex>> mUserIdLock;
+ std::unordered_map<std::string, std::weak_ptr<std::recursive_mutex>> mPackageNameLock;
std::recursive_mutex mMountsLock;
std::recursive_mutex mQuotasLock;
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index f3ec63f..2bcf2d4 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -52,6 +52,7 @@
#include <server_configurable_flags/get_flags.h>
#include <system/thread_defs.h>
#include <utils/Mutex.h>
+#include <ziparchive/zip_archive.h>
#include "dexopt.h"
#include "dexopt_return_codes.h"
@@ -459,8 +460,8 @@
});
}
-static unique_fd open_spnashot_profile(uid_t uid, const std::string& package_name,
- const std::string& location) {
+static unique_fd open_snapshot_profile(uid_t uid, const std::string& package_name,
+ const std::string& location) {
std::string profile = create_snapshot_profile_path(package_name, location);
return open_profile(uid, profile, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
}
@@ -2562,7 +2563,7 @@
const std::string& classpath) {
int app_shared_gid = multiuser_get_shared_gid(/*user_id*/ 0, app_id);
- unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name);
+ unique_fd snapshot_fd = open_snapshot_profile(AID_SYSTEM, package_name, profile_name);
if (snapshot_fd < 0) {
return false;
}
@@ -2636,7 +2637,7 @@
}
// Open and create the snapshot profile.
- unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name);
+ unique_fd snapshot_fd = open_snapshot_profile(AID_SYSTEM, package_name, profile_name);
// Collect all non empty profiles.
// The collection will traverse all applications profiles and find the non empty files.
@@ -2738,6 +2739,20 @@
}
}
+static bool check_profile_exists_in_dexmetadata(const std::string& dex_metadata) {
+ ZipArchiveHandle zip = nullptr;
+ if (OpenArchive(dex_metadata.c_str(), &zip) != 0) {
+ PLOG(ERROR) << "Failed to open dm '" << dex_metadata << "'";
+ return false;
+ }
+
+ ZipEntry64 entry;
+ int result = FindEntry(zip, "primary.prof", &entry);
+ CloseArchive(zip);
+
+ return result != 0 ? false : true;
+}
+
bool prepare_app_profile(const std::string& package_name,
userid_t user_id,
appid_t app_id,
@@ -2754,7 +2769,7 @@
}
// Check if we need to install the profile from the dex metadata.
- if (!dex_metadata) {
+ if (!dex_metadata || !check_profile_exists_in_dexmetadata(dex_metadata->c_str())) {
return true;
}
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 7082017..13e15ca 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -48,6 +48,7 @@
"libasync_safe",
"libdiskusage",
"libinstalld",
+ "libziparchive",
"liblog",
"liblogwrap",
],
@@ -89,6 +90,7 @@
"libasync_safe",
"libdiskusage",
"libinstalld",
+ "libziparchive",
"liblog",
"liblogwrap",
],
diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp
index 863cdfe..72f5f4b 100644
--- a/cmds/installd/tests/installd_cache_test.cpp
+++ b/cmds/installd/tests/installd_cache_test.cpp
@@ -122,6 +122,7 @@
service = new InstalldNativeService();
testUuid = kTestUuid;
+ system("rm -rf /data/local/tmp/user");
system("mkdir -p /data/local/tmp/user/0");
}
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 1e7559d..8edb3bf 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -107,6 +107,7 @@
service = new InstalldNativeService();
testUuid = kTestUuid;
+ system("rm -rf /data/local/tmp/user");
system("mkdir -p /data/local/tmp/user/0");
init_globals_from_data_and_root();
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 4e44ac7..4374abe 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -28,6 +28,9 @@
#ifndef VENDORSERVICEMANAGER
#include <vintf/VintfObject.h>
+#ifdef __ANDROID_RECOVERY__
+#include <vintf/VintfObjectRecovery.h>
+#endif // __ANDROID_RECOVERY__
#include <vintf/constants.h>
#endif // !VENDORSERVICEMANAGER
@@ -37,16 +40,33 @@
namespace android {
#ifndef VENDORSERVICEMANAGER
+
struct ManifestWithDescription {
std::shared_ptr<const vintf::HalManifest> manifest;
const char* description;
};
+static std::vector<ManifestWithDescription> GetManifestsWithDescription() {
+#ifdef __ANDROID_RECOVERY__
+ auto vintfObject = vintf::VintfObjectRecovery::GetInstance();
+ if (vintfObject == nullptr) {
+ LOG(ERROR) << "NULL VintfObjectRecovery!";
+ return {};
+ }
+ return {ManifestWithDescription{vintfObject->getRecoveryHalManifest(), "recovery"}};
+#else
+ auto vintfObject = vintf::VintfObject::GetInstance();
+ if (vintfObject == nullptr) {
+ LOG(ERROR) << "NULL VintfObject!";
+ return {};
+ }
+ return {ManifestWithDescription{vintfObject->getDeviceHalManifest(), "device"},
+ ManifestWithDescription{vintfObject->getFrameworkHalManifest(), "framework"}};
+#endif
+}
+
// func true -> stop search and forEachManifest will return true
static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
- for (const ManifestWithDescription& mwd : {
- ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
- ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
- }) {
+ for (const ManifestWithDescription& mwd : GetManifestsWithDescription()) {
if (mwd.manifest == nullptr) {
LOG(ERROR) << "NULL VINTF MANIFEST!: " << mwd.description;
// note, we explicitly do not retry here, so that we can detect VINTF
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 8270ae5..d8101fa 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -202,7 +202,7 @@
sanitize: {
misc_undefined: ["integer"],
},
- min_sdk_version: "29",
+ min_sdk_version: "30",
tidy: true,
tidy_flags: [
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 8f4f0f0..7027a4b 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -824,7 +824,7 @@
const size_t padded = pad_size(len);
- // sanity check for integer overflow
+ // check for integer overflow
if (mDataPos+padded < mDataPos) {
return nullptr;
}
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 0ad400b..c903998 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -365,6 +365,8 @@
ScopedFileDescriptor(ScopedFileDescriptor&&) = default;
ScopedFileDescriptor& operator=(ScopedFileDescriptor&&) = default;
+ ScopedFileDescriptor dup() const { return ScopedFileDescriptor(::dup(get())); }
+
bool operator!=(const ScopedFileDescriptor& rhs) const { return get() != rhs.get(); }
bool operator<(const ScopedFileDescriptor& rhs) const { return get() < rhs.get(); }
bool operator<=(const ScopedFileDescriptor& rhs) const { return get() <= rhs.get(); }
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index d09ac83..3d2eddf 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -1027,16 +1027,20 @@
#[macro_export]
macro_rules! declare_binder_enum {
{
+ $( #[$attr:meta] )*
$enum:ident : [$backing:ty; $size:expr] {
$( $name:ident = $value:expr, )*
}
} => {
+ $( #[$attr] )*
#[derive(Debug, Default, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
+ #[allow(missing_docs)]
pub struct $enum(pub $backing);
impl $enum {
- $( pub const $name: Self = Self($value); )*
+ $( #[allow(missing_docs)] pub const $name: Self = Self($value); )*
#[inline(always)]
+ #[allow(missing_docs)]
pub const fn enum_values() -> [Self; $size] {
[$(Self::$name),*]
}
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 1fd2ead..40359b4 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -16,7 +16,7 @@
//! Rust Binder crate integration tests
-use binder::declare_binder_interface;
+use binder::{declare_binder_enum, declare_binder_interface};
use binder::parcel::BorrowedParcel;
use binder::{
Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode,
@@ -294,6 +294,23 @@
impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {}
+declare_binder_enum! {
+ TestEnum : [i32; 3] {
+ FOO = 1,
+ BAR = 2,
+ BAZ = 3,
+ }
+}
+
+declare_binder_enum! {
+ #[deprecated(since = "1.0.0")]
+ TestDeprecatedEnum : [i32; 3] {
+ FOO = 1,
+ BAR = 2,
+ BAZ = 3,
+ }
+}
+
#[cfg(test)]
mod tests {
use selinux_bindgen as selinux_sys;
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index d1cd397..fa3b260 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -965,6 +965,13 @@
VkResult result = EnumerateDeviceExtensionProperties(physical_dev, nullptr,
&count, nullptr);
if (result == VK_SUCCESS && count) {
+ // Work-around a race condition during Android start-up, that can result
+ // in the second call to EnumerateDeviceExtensionProperties having
+ // another extension. That causes the second call to return
+ // VK_INCOMPLETE. A work-around is to add 1 to "count" and ask for one
+ // more extension property. See: http://anglebug.com/6715 and
+ // internal-to-Google b/206733351.
+ count++;
driver_extensions_ = AllocateDriverExtensionArray(count);
result = (driver_extensions_)
? EnumerateDeviceExtensionProperties(
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 2715587..8c54a0e 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -537,30 +537,6 @@
}
}
-int get_min_buffer_count(ANativeWindow* window,
- uint32_t* out_min_buffer_count) {
- constexpr int kExtraBuffers = 2;
-
- int err;
- int min_undequeued_buffers;
- err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &min_undequeued_buffers);
- if (err != android::OK || min_undequeued_buffers < 0) {
- ALOGE(
- "NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) "
- "value=%d",
- strerror(-err), err, min_undequeued_buffers);
- if (err == android::OK) {
- err = android::UNKNOWN_ERROR;
- }
- return err;
- }
-
- *out_min_buffer_count =
- static_cast<uint32_t>(min_undequeued_buffers + kExtraBuffers);
- return android::OK;
-}
-
} // anonymous namespace
VKAPI_ATTR
@@ -675,7 +651,7 @@
strerror(-err), err);
return VK_ERROR_SURFACE_LOST_KHR;
}
- capabilities->minImageCount = max_buffer_count == 1 ? 1 : 2;
+ capabilities->minImageCount = std::min(max_buffer_count, 3);
capabilities->maxImageCount = static_cast<uint32_t>(max_buffer_count);
capabilities->currentExtent =
@@ -872,13 +848,18 @@
int err;
int query_value;
- uint32_t min_buffer_count;
ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
- err = get_min_buffer_count(window, &min_buffer_count);
- if (err != android::OK) {
+ err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+ &query_value);
+ if (err != android::OK || query_value < 0) {
+ ALOGE(
+ "NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) "
+ "value=%d",
+ strerror(-err), err, query_value);
return VK_ERROR_SURFACE_LOST_KHR;
}
+ uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value);
if (err != android::OK || query_value < 0) {
@@ -889,7 +870,7 @@
uint32_t max_buffer_count = static_cast<uint32_t>(query_value);
std::vector<VkPresentModeKHR> present_modes;
- if (min_buffer_count < max_buffer_count)
+ if (min_undequeued_buffers + 1 < max_buffer_count)
present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR);
present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
@@ -1210,14 +1191,19 @@
}
}
- uint32_t min_buffer_count;
- err = get_min_buffer_count(window, &min_buffer_count);
- if (err != android::OK) {
+ int query_value;
+ err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+ &query_value);
+ if (err != android::OK || query_value < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
+ query_value);
return VK_ERROR_SURFACE_LOST_KHR;
}
-
- uint32_t num_images =
- std::max(min_buffer_count, create_info->minImageCount);
+ uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
+ const auto mailbox_num_images = std::max(3u, create_info->minImageCount);
+ const auto requested_images =
+ swap_interval ? create_info->minImageCount : mailbox_num_images;
+ uint32_t num_images = requested_images - 1 + min_undequeued_buffers;
// Lower layer insists that we have at least two buffers. This is wasteful
// and we'd like to relax it in the shared case, but not all the pieces are