diff options
| -rw-r--r-- | cmds/dumpstate/Android.bp | 2 | ||||
| -rw-r--r-- | cmds/dumpstate/DumpstateService.cpp | 2 | ||||
| -rw-r--r-- | cmds/dumpstate/dumpstate.cpp | 327 | ||||
| -rw-r--r-- | cmds/dumpstate/dumpstate.h | 10 | ||||
| -rw-r--r-- | cmds/dumpstate/tests/dumpstate_test.cpp | 16 | ||||
| -rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 111 | ||||
| -rw-r--r-- | cmds/installd/InstalldNativeService.h | 14 | ||||
| -rw-r--r-- | cmds/installd/tests/installd_cache_test.cpp | 1 | ||||
| -rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 1 | ||||
| -rw-r--r-- | cmds/servicemanager/ServiceManager.cpp | 28 | ||||
| -rw-r--r-- | libs/binder/rust/src/binder.rs | 6 | ||||
| -rw-r--r-- | libs/binder/rust/tests/integration.rs | 19 | ||||
| -rw-r--r-- | services/gpuservice/gpumem/GpuMem.cpp | 2 | ||||
| -rw-r--r-- | services/sensorservice/Android.bp | 5 | ||||
| -rw-r--r-- | vulkan/libvulkan/api.cpp | 7 | ||||
| -rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 56 |
16 files changed, 428 insertions, 179 deletions
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp index 74dbf4b764..a2491e503f 100644 --- a/cmds/dumpstate/Android.bp +++ b/cmds/dumpstate/Android.bp @@ -86,9 +86,11 @@ cc_defaults { 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 ba25a5a603..77915d5376 100644 --- a/cmds/dumpstate/DumpstateService.cpp +++ b/cmds/dumpstate/DumpstateService.cpp @@ -192,7 +192,7 @@ status_t DumpstateService::dump(int fd, const Vector<String16>&) { 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 eab72f48b0..32e680dfea 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 @@ void Dumpstate::PrintHeader() const { 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 @@ Dumpstate::RunStatus Dumpstate::DumpTraces(const char** path) { 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 @@ void Dumpstate::DumpstateBoard(int out_fd) { 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,24 +2422,32 @@ void Dumpstate::DumpstateBoard(int out_fd) { 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"); - return; + // 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"); } - 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"); + // 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; } + // 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++) { MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str()); @@ -2262,65 +2459,26 @@ void Dumpstate::DumpstateBoard(int out_fd) { 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 @@ void Dumpstate::DumpstateBoard(int out_fd) { 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 @@ static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOpt 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 @@ static void LogDumpOptions(const Dumpstate::DumpOptions& options) { 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 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid, } 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 3722383e9e..773e292b63 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 @@ class Dumpstate { 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 db508b52bd..42beb2b6cf 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 android { 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 @@ TEST_F(DumpOptionsTest, InitializeNone) { 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 @@ TEST_F(DumpOptionsTest, InitializeAdbBugreport) { 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 @@ TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) { 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 @@ TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializeRemoteBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializeWearBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializeWifiBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializeLimitedOnlyBugreport) { 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 @@ TEST_F(DumpOptionsTest, InitializeDefaultBugReport) { 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 @@ TEST_F(DumpOptionsTest, InitializePartial1) { 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 @@ TEST_F(DumpOptionsTest, InitializePartial2) { 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/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 027c486f1e..94c4c8cda0 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -274,10 +274,10 @@ binder::Status checkArgumentPath(const std::optional<std::string>& path) { * 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> +template <class Key, class Mutex> struct LocalLockHolder { - using WeakPointer = std::weak_ptr<std::recursive_mutex>; - using StrongPointer = std::shared_ptr<std::recursive_mutex>; + using WeakPointer = std::weak_ptr<Mutex>; + using StrongPointer = std::shared_ptr<Mutex>; using Map = std::unordered_map<Key, WeakPointer>; using MapLock = std::recursive_mutex; @@ -290,11 +290,22 @@ struct LocalLockHolder { mRefLock = weakPtr.lock(); if (!mRefLock) { // Create a new lock. - mRefLock = std::make_shared<std::recursive_mutex>(); + 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(); @@ -311,6 +322,8 @@ struct LocalLockHolder { void lock() { mRefLock->lock(); } void unlock() { mRefLock->unlock(); } + void lock_shared() { mRefLock->lock_shared(); } + void unlock_shared() { mRefLock->unlock_shared(); } private: Key mKey; @@ -319,24 +332,33 @@ private: StrongPointer mRefLock; }; -#define LOCK_USER() \ - LocalLockHolder<userid_t> localUserLock(userId, mUserIdLock, mLock); \ - std::lock_guard userLock(localUserLock) +using UserLock = LocalLockHolder<userid_t, std::shared_mutex>; +using UserWriteLockGuard = std::unique_lock<UserLock>; +using UserReadLockGuard = std::shared_lock<UserLock>; -#define LOCK_PACKAGE() \ - LocalLockHolder<std::string> localPackageLock(packageName, mPackageNameLock, mLock); \ - std::lock_guard packageLock(localPackageLock) +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_PACKAGE(); \ - LOCK_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) @@ -619,14 +641,13 @@ static binder::Status createAppDataDirs(const std::string& path, 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); - LOCK_PACKAGE_USER(); const char* uuid_ = uuid ? uuid->c_str() : nullptr; const char* pkgname = packageName.c_str(); @@ -695,9 +716,22 @@ binder::Status InstalldNativeService::createAppData(const std::optional<std::str } 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); + // Locking is performed depeer in the callstack. int64_t ceDataInode = -1; auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId, @@ -712,6 +746,7 @@ binder::Status InstalldNativeService::createAppDataBatched( const std::vector<android::os::CreateAppDataArgs>& args, std::vector<android::os::CreateAppDataResult>* _aidl_return) { ENFORCE_UID(AID_SYSTEM); + // Locking is performed depeer in the callstack. std::vector<android::os::CreateAppDataResult> results; for (const auto &arg : args) { @@ -980,8 +1015,8 @@ binder::Status InstalldNativeService::fixupAppData(const std::optional<std::stri const char* uuid_ = uuid ? uuid->c_str() : nullptr; for (auto userId : get_known_users(uuid_)) { - ATRACE_BEGIN("fixup user"); LOCK_USER(); + ATRACE_BEGIN("fixup user"); FTS* fts; FTSENT* p; auto ce_path = create_data_user_ce_path(uuid_, userId); @@ -1416,13 +1451,12 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s continue; } - if (!createAppData(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId, - /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr) + 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, userId, package_name); auto to = create_data_user_de_path(to_uuid, userId); @@ -1444,8 +1478,8 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s } } - if (!restoreconAppData(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, - appId, seInfo) + if (!restoreconAppDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, + appId, seInfo) .isOk()) { res = error("Failed to restorecon"); goto fail; @@ -1541,6 +1575,9 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); +#ifndef GRANULAR_LOCKS + std::lock_guard lock(mLock); +#endif // !GRANULAR_LOCKS auto uuidString = uuid.value_or(""); const char* uuid_ = uuid ? uuid->c_str() : nullptr; @@ -1567,10 +1604,19 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> // 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 userId : get_known_users(uuid_)) { - LOCK_USER(); // ????????? - + 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_, userId); @@ -2760,6 +2806,15 @@ binder::Status InstalldNativeService::restoreconAppData(const std::optional<std: CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); 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(); diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index 78a47b36bd..09581bb544 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 @@ public: 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 @@ public: 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,8 +190,7 @@ public: private: std::recursive_mutex mLock; - - std::unordered_map<userid_t, std::weak_ptr<std::recursive_mutex>> mUserIdLock; + 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; diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp index 863cdfe55b..72f5f4b79c 100644 --- a/cmds/installd/tests/installd_cache_test.cpp +++ b/cmds/installd/tests/installd_cache_test.cpp @@ -122,6 +122,7 @@ protected: 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 36574974d9..b831515b94 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -138,6 +138,7 @@ protected: 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 4e44ac7323..4374abe2ef 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 @@ using ::android::internal::Stability; 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/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index d09ac83785..3d2eddf611 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -1027,16 +1027,20 @@ macro_rules! declare_binder_interface { #[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 1fd2eadc4e..40359b4749 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 BpTestSameDescriptor {} 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/services/gpuservice/gpumem/GpuMem.cpp b/services/gpuservice/gpumem/GpuMem.cpp index 3aa862f31f..dd3cc3bd86 100644 --- a/services/gpuservice/gpumem/GpuMem.cpp +++ b/services/gpuservice/gpumem/GpuMem.cpp @@ -22,7 +22,7 @@ #include <android-base/stringprintf.h> #include <libbpf.h> -#include <libbpf_android.h> +#include <bpf/WaitForProgsLoaded.h> #include <log/log.h> #include <unistd.h> #include <utils/Timers.h> diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp index 1be5a96f67..b596708a72 100644 --- a/services/sensorservice/Android.bp +++ b/services/sensorservice/Android.bp @@ -78,6 +78,11 @@ cc_library_shared { "libsensorprivacy", "libpermission", ], + + pgo: { + sampling: true, + profile_file: "sensorservice/libsensorservice.profdata", + }, } cc_binary { diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index d1cd397da4..fa3b2601a4 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -965,6 +965,13 @@ VkResult LayerChain::ValidateExtensions(VkPhysicalDevice physical_dev, 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 271558784e..8c54a0efe0 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -537,30 +537,6 @@ android_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace) { } } -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 @@ VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR( 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 @@ VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, 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 @@ VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, 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 @@ VkResult CreateSwapchainKHR(VkDevice device, } } - 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 |