diff options
27 files changed, 606 insertions, 343 deletions
diff --git a/build/Android.bp b/build/Android.bp index 33563de5a..1e69ce018 100644 --- a/build/Android.bp +++ b/build/Android.bp @@ -45,6 +45,33 @@ soong_config_module_type { ], } +// Start of generated qemu_aarch64_linux_gnu_binary +// Generated by gen_android_bp.py +qemu_aarch64_linux_gnu_binary = [ + "aarch64_linux_gnu_libc++.so.1_binary_for_qemu", + "aarch64_linux_gnu_libc++abi.so.1_binary_for_qemu", + "aarch64_linux_gnu_libepoxy.so.0_binary_for_qemu", + "aarch64_linux_gnu_libgbm.so.1_binary_for_qemu", + "aarch64_linux_gnu_libgfxstream_backend.so.0_binary_for_qemu", + "aarch64_linux_gnu_librutabaga_gfx_ffi.so.0_binary_for_qemu", + "aarch64_linux_gnu_libunwind.so.1_binary_for_qemu", + "aarch64_linux_gnu_libvirglrenderer.so.1_binary_for_qemu", + "aarch64_linux_gnu_libz.so.1_binary_for_qemu", + "aarch64_linux_gnu_qemu-system-aarch64_binary_for_qemu", + "aarch64_linux_gnu_qemu-system-riscv64_binary_for_qemu", + "aarch64_linux_gnu_qemu-system-x86_64_binary_for_qemu", +] +// End of generated qemu_aarch64_linux_gnu_binary + +// Start of generated qemu_aarch64_linux_gnu_resource +// Generated by gen_android_bp.py +qemu_aarch64_linux_gnu_resource = [ + "aarch64_efi-virtio.rom_resource_for_qemu", + "aarch64_en-us_resource_for_qemu", + "aarch64_opensbi-riscv64-generic-fw_dynamic.bin_resource_for_qemu", +] +// End of generated qemu_aarch64_linux_gnu_resource + // Start of generated qemu_x86_64_linux_gnu_binary // Generated by gen_android_bp.py qemu_x86_64_linux_gnu_binary = [ @@ -247,7 +274,7 @@ cvd_host_aarch64_crosvm = [ "aarch64_linux_gnu_libwayland_client.so.0_for_crosvm", ] -cvd_host_aarch64 = cvd_host_aarch64_crosvm + cvd_host_aarch64_graphics_detector +cvd_host_aarch64 = cvd_host_aarch64_crosvm + cvd_host_aarch64_graphics_detector + qemu_aarch64_linux_gnu_binary cvd_host_seccomp_policy_x86_64 = [ "9p_device.policy_x86_64", @@ -428,7 +455,7 @@ cvd_host_package_customization { deps: cvd_host_aarch64, multilib: { common: { - deps: cvd_host_seccomp_policy_aarch64, + deps: cvd_host_seccomp_policy_aarch64 + qemu_aarch64_linux_gnu_resource, }, }, }, diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp index 5fa1e6ecf..0f9f93ec1 100644 --- a/common/libs/utils/files.cpp +++ b/common/libs/utils/files.cpp @@ -52,6 +52,7 @@ #include <numeric> #include <ostream> #include <ratio> +#include <regex> #include <string> #include <vector> @@ -663,6 +664,57 @@ Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec) { return CF_ERR("This shouldn't be executed"); } + +Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path, + int timeoutSec) { + const auto targetTime = + std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec); + + CF_EXPECT(WaitForFile(path, timeoutSec), + "Waiting for socket path creation failed"); + CF_EXPECT(FileIsSocket(path), "Specified path is not a socket"); + + std::regex socket_state_regex("TST=(.*)"); + + while (true) { + const auto currentTime = std::chrono::system_clock::now(); + + if (currentTime >= targetTime) { + return CF_ERR("Timed out"); + } + + Command lsof("lsof"); + lsof.AddParameter(/*"format"*/ "-F", /*"connection state"*/ "TST"); + lsof.AddParameter(path); + std::string lsof_out; + std::string lsof_err; + int rval = + RunWithManagedStdio(std::move(lsof), nullptr, &lsof_out, &lsof_err); + if (rval != 0) { + return CF_ERR("Failed to run `lsof`, stderr: " << lsof_err); + } + + LOG(DEBUG) << "lsof stdout:" << lsof_out; + + std::smatch socket_state_match; + if (!std::regex_search(lsof_out, socket_state_match, socket_state_regex)) { + return CF_ERR("Failed to find state in `lsof` stdout: " << lsof_out); + } + if (socket_state_match.size() != 2) { + return CF_ERR( + "Unexpected number of matches in `lsof` stdout: " << lsof_out); + } + + const std::string& socket_state = socket_state_match[1]; + if (socket_state == "LISTEN") { + return {}; + } + + sched_yield(); + } + + return CF_ERR("This shouldn't be executed"); +} #endif namespace { diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h index cf13dea72..6e423cda4 100644 --- a/common/libs/utils/files.h +++ b/common/libs/utils/files.h @@ -84,6 +84,8 @@ Result<void> WalkDirectory( #ifdef __linux__ Result<void> WaitForFile(const std::string& path, int timeoutSec); Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec); +Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path, + int timeoutSec); #endif // parameter to EmulateAbsolutePath diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc index c1e8b8767..a65f47fbf 100644 --- a/host/commands/assemble_cvd/flags.cc +++ b/host/commands/assemble_cvd/flags.cc @@ -134,7 +134,7 @@ DEFINE_vec(use_random_serial, fmt::format("{}", CF_DEFAULTS_USE_RANDOM_SERIAL), DEFINE_vec(vm_manager, CF_DEFAULTS_VM_MANAGER, "What virtual machine manager to use, one of {qemu_cli, crosvm}"); DEFINE_vec(gpu_mode, CF_DEFAULTS_GPU_MODE, - "What gpu configuration to use, one of {auto, drm_virgl, " + "What gpu configuration to use, one of {auto, custom, drm_virgl, " "gfxstream, gfxstream_guest_angle, " "gfxstream_guest_angle_host_swiftshader, guest_swiftshader}"); DEFINE_vec(gpu_vhost_user_mode, @@ -155,6 +155,22 @@ DEFINE_vec( "be a semicolon separated list of \"<feature name>:[enabled|disabled]\"" "pairs."); +DEFINE_vec(gpu_context_types, CF_DEFAULTS_GPU_CONTEXT_TYPES, + "A colon separated list of virtio-gpu context types. Only valid " + "with --gpu_mode=custom." + " For example \"--gpu_context_types=cross_domain:gfxstream\""); + +DEFINE_vec( + guest_vulkan_driver, CF_DEFAULTS_GUEST_VULKAN_DRIVER, + "Vulkan driver to use with Cuttlefish. Android VMs require specifying " + "this at boot time. Only valid with --gpu_mode=custom. " + "For example \"--guest_vulkan_driver=ranchu\""); + +DEFINE_vec( + frames_socket_path, CF_DEFAULTS_FRAME_SOCKET_PATH, + "Frame socket path to use when launching a VM " + "For example, \"--frames_socket_path=${XDG_RUNTIME_DIR}/wayland-0\""); + DEFINE_vec(use_allocd, CF_DEFAULTS_USE_ALLOCD?"true":"false", "Acquire static resources from the resource allocator daemon."); DEFINE_vec( @@ -435,6 +451,9 @@ DEFINE_vec(mte, fmt::format("{}", CF_DEFAULTS_MTE), "Enable MTE"); DEFINE_vec(enable_audio, fmt::format("{}", CF_DEFAULTS_ENABLE_AUDIO), "Whether to play or capture audio"); +DEFINE_vec(enable_usb, fmt::format("{}", CF_DEFAULTS_ENABLE_USB), + "Whether to allow USB passthrough on the device"); + DEFINE_vec(camera_server_port, std::to_string(CF_DEFAULTS_CAMERA_SERVER_PORT), "camera vsock port"); @@ -524,7 +543,7 @@ Result<std::string> GetAndroidInfoConfig( CF_EXPECT(FileExists(android_info_file_path)); std::string android_info_contents = ReadFile(android_info_file_path); - auto android_info_map = ParseMiscInfo(android_info_contents); + auto android_info_map = CF_EXPECT(ParseMiscInfo(android_info_contents)); CF_EXPECT(android_info_map.find(key) != android_info_map.end()); return android_info_map[key]; } @@ -885,6 +904,14 @@ Result<void> CheckSnapshotCompatible( "--enable_virtiofs=false"); /* + * TODO(khei@): delete this block once usb is supported + */ + CF_EXPECTF(gflags::GetCommandLineFlagInfoOrDie("enable_usb").current_value == + "false", + "--enable_usb should be false for snapshot, consider \"{}\"", + "--enable_usb=false"); + + /* * TODO(kwstephenkim@): delete this block once 3D gpu mode snapshots are * supported */ @@ -1076,6 +1103,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( modem_simulator_sim_type)); std::vector<bool> console_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(console)); std::vector<bool> enable_audio_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(enable_audio)); + std::vector<bool> enable_usb_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE(enable_usb)); std::vector<bool> start_gnss_proxy_vec = CF_EXPECT(GET_FLAG_BOOL_VALUE( start_gnss_proxy)); std::vector<bool> enable_bootanimation_vec = @@ -1124,6 +1152,12 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( CF_EXPECT(GET_FLAG_STR_VALUE(gpu_vhost_user_mode)); std::vector<std::string> gpu_renderer_features_vec = CF_EXPECT(GET_FLAG_STR_VALUE(gpu_renderer_features)); + std::vector<std::string> gpu_context_types_vec = + CF_EXPECT(GET_FLAG_STR_VALUE(gpu_context_types)); + std::vector<std::string> guest_vulkan_driver_vec = + CF_EXPECT(GET_FLAG_STR_VALUE(guest_vulkan_driver)); + std::vector<std::string> frames_socket_path_vec = + CF_EXPECT(GET_FLAG_STR_VALUE(frames_socket_path)); std::vector<std::string> gpu_capture_binary_vec = CF_EXPECT(GET_FLAG_STR_VALUE(gpu_capture_binary)); @@ -1192,8 +1226,8 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( if (FLAGS_casimir_instance_num > 0) { casimir_instance_num = FLAGS_casimir_instance_num - 1; } - tmp_config_obj.set_casimir_nci_port(7100 + casimir_instance_num); - tmp_config_obj.set_casimir_rf_port(8100 + casimir_instance_num); + tmp_config_obj.set_casimir_nci_port(7800 + casimir_instance_num); + tmp_config_obj.set_casimir_rf_port(7900 + casimir_instance_num); LOG(DEBUG) << "casimir_instance_num: " << casimir_instance_num; LOG(DEBUG) << "launch casimir: " << (FLAGS_casimir_instance_num <= 0); @@ -1301,6 +1335,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( guest_configs[instance_index].hctr2_supported ? "hctr2" : "cts"); instance.set_use_allocd(use_allocd_vec[instance_index]); instance.set_enable_audio(enable_audio_vec[instance_index]); + instance.set_enable_usb(enable_usb_vec[instance_index]); instance.set_enable_gnss_grpc_proxy(start_gnss_proxy_vec[instance_index]); instance.set_enable_bootanimation(enable_bootanimation_vec[instance_index]); @@ -1513,8 +1548,8 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( const std::string gpu_mode = CF_EXPECT(ConfigureGpuSettings( gpu_mode_vec[instance_index], gpu_vhost_user_mode_vec[instance_index], gpu_renderer_features_vec[instance_index], - vm_manager_vec[instance_index], guest_configs[instance_index], - instance)); + gpu_context_types_vec[instance_index], vm_manager_vec[instance_index], + guest_configs[instance_index], instance)); calculated_gpu_mode_vec[instance_index] = gpu_mode_vec[instance_index]; instance.set_restart_subprocesses(restart_subprocesses_vec[instance_index]); @@ -1550,6 +1585,16 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( instance.set_enable_gpu_udmabuf(enable_gpu_udmabuf_vec[instance_index]); + instance.set_gpu_context_types(gpu_context_types_vec[instance_index]); + instance.set_guest_vulkan_driver(guest_vulkan_driver_vec[instance_index]); + + if (!frames_socket_path_vec[instance_index].empty()) { + instance.set_frames_socket_path(frames_socket_path_vec[instance_index]); + } else { + instance.set_frames_socket_path( + const_instance.PerInstanceInternalUdsPath("frames.sock")); + } + // 1. Keep original code order SetCommandLineOptionWithMode("enable_sandbox") // then set_enable_sandbox later. // 2. SetCommandLineOptionWithMode condition: if gpu_mode or console, @@ -1775,7 +1820,8 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( .ForEnvironment(environment_name); CF_EXPECT(CheckSnapshotCompatible( FLAGS_snapshot_compatible && - (tmp_config_obj.vm_manager() == CrosvmManager::name()), + (tmp_config_obj.vm_manager() == CrosvmManager::name()) && + instance_nums.size() == 1, calculated_gpu_mode_vec), "The set of flags is incompatible with snapshot"); diff --git a/host/commands/assemble_cvd/flags_defaults.h b/host/commands/assemble_cvd/flags_defaults.h index 1fd1b168a..34d69b38b 100644 --- a/host/commands/assemble_cvd/flags_defaults.h +++ b/host/commands/assemble_cvd/flags_defaults.h @@ -141,6 +141,10 @@ #define CF_DEFAULTS_RECORD_SCREEN false #define CF_DEFAULTS_GPU_CAPTURE_BINARY CF_DEFAULTS_DYNAMIC_STRING #define CF_DEFAULTS_GPU_RENDERER_FEATURES "" +#define CF_DEFAULTS_GPU_CONTEXT_TYPES \ + "gfxstream-vulkan:cross-domain:gfxstream-composer" +#define CF_DEFAULTS_GUEST_VULKAN_DRIVER "ranchu" +#define CF_DEFAULTS_FRAME_SOCKET_PATH "" #define CF_DEFAULTS_ENABLE_GPU_UDMABUF false #define CF_DEFAULTS_ENABLE_GPU_VHOST_USER false #define CF_DEFAULTS_DISPLAY0 CF_DEFAULTS_DYNAMIC_STRING @@ -196,6 +200,9 @@ // Audio default parameters #define CF_DEFAULTS_ENABLE_AUDIO true +// USB Passhtrough default parameters +#define CF_DEFAULTS_ENABLE_USB false + // Streaming default parameters #define CF_DEFAULTS_START_WEBRTC false #define CF_DEFAULTS_START_WEBRTC_SIG_SERVER true diff --git a/host/commands/assemble_cvd/graphics_flags.cc b/host/commands/assemble_cvd/graphics_flags.cc index 72a4c8eb4..e5e7e4424 100644 --- a/host/commands/assemble_cvd/graphics_flags.cc +++ b/host/commands/assemble_cvd/graphics_flags.cc @@ -39,6 +39,7 @@ namespace { enum class RenderingMode { kNone, + kCustom, kGuestSwiftShader, kGfxstream, kGfxstreamGuestAngle, @@ -63,6 +64,9 @@ Result<RenderingMode> GetRenderingMode(const std::string& mode) { if (mode == std::string(kGpuModeGuestSwiftshader)) { return RenderingMode::kGuestSwiftShader; } + if (mode == std::string(kGpuModeCustom)) { + return RenderingMode::kCustom; + } if (mode == std::string(kGpuModeNone)) { return RenderingMode::kNone; } @@ -232,7 +236,7 @@ Result<std::string> SelectGpuMode( const GuestConfig& guest_config, const gfxstream::proto::GraphicsAvailability& graphics_availability) { if (gpu_mode_arg != kGpuModeAuto && gpu_mode_arg != kGpuModeDrmVirgl && - gpu_mode_arg != kGpuModeGfxstream && + gpu_mode_arg != kGpuModeCustom && gpu_mode_arg != kGpuModeGfxstream && gpu_mode_arg != kGpuModeGfxstreamGuestAngle && gpu_mode_arg != kGpuModeGfxstreamGuestAngleHostSwiftShader && gpu_mode_arg != kGpuModeGuestSwiftshader && @@ -256,8 +260,8 @@ Result<std::string> SelectGpuMode( LOG(INFO) << "GPU auto mode: detected prerequisites for accelerated " << "rendering support."; - if (vm_manager == vm_manager::QemuManager::name() && !UseQemu8()) { - LOG(INFO) << "Not using QEMU8: selecting guest swiftshader"; + if (vm_manager == vm_manager::QemuManager::name() && !UseQemuPrebuilt()) { + LOG(INFO) << "Not using QEMU prebuilt (QEMU 8+): selecting guest swiftshader"; return kGpuModeGuestSwiftshader; } else if (!guest_config.gfxstream_supported) { LOG(INFO) << "GPU auto mode: guest does not support gfxstream, " @@ -286,8 +290,8 @@ Result<std::string> SelectGpuMode( "--gpu_mode=auto or --gpu_mode=guest_swiftshader."; } - if (vm_manager == vm_manager::QemuManager::name() && !UseQemu8()) { - LOG(INFO) << "Not using QEMU8: selecting guest swiftshader"; + if (vm_manager == vm_manager::QemuManager::name() && !UseQemuPrebuilt()) { + LOG(INFO) << "Not using QEMU prebuilt (QEMU 8+): selecting guest swiftshader"; return kGpuModeGuestSwiftshader; } } @@ -480,9 +484,13 @@ Result<void> SetGfxstreamFlags( } // namespace +static std::unordered_set<std::string> kSupportedGpuContexts{ + "gfxstream-vulkan", "gfxstream-composer", "cross-domain", "magma"}; + Result<std::string> ConfigureGpuSettings( const std::string& gpu_mode_arg, const std::string& gpu_vhost_user_mode_arg, - const std::string& gpu_renderer_features_arg, const std::string& vm_manager, + const std::string& gpu_renderer_features_arg, + std::string& gpu_context_types_arg, const std::string& vm_manager, const GuestConfig& guest_config, CuttlefishConfig::MutableInstanceSpecific& instance) { #ifdef __APPLE__ @@ -525,6 +533,14 @@ Result<std::string> ConfigureGpuSettings( guest_config, graphics_availability, instance)); } + if (gpu_mode == kGpuModeCustom) { + auto requested_types = android::base::Split(gpu_context_types_arg, ":"); + for (const std::string& requested : requested_types) { + CF_EXPECT(kSupportedGpuContexts.count(requested) == 1, + "unsupported context type: " + requested); + } + } + const auto angle_features = CF_EXPECT(GetNeededAngleFeatures( CF_EXPECT(GetRenderingMode(gpu_mode)), graphics_availability)); instance.set_gpu_angle_feature_overrides_enabled( diff --git a/host/commands/assemble_cvd/graphics_flags.h b/host/commands/assemble_cvd/graphics_flags.h index 04923e974..63a4df13e 100644 --- a/host/commands/assemble_cvd/graphics_flags.h +++ b/host/commands/assemble_cvd/graphics_flags.h @@ -26,7 +26,8 @@ namespace cuttlefish { Result<std::string> ConfigureGpuSettings( const std::string& gpu_mode_arg, const std::string& gpu_vhost_user_mode_arg, - const std::string& gpu_renderer_features_arg, const std::string& vm_manager, + const std::string& gpu_renderer_features_arg, + std::string& gpu_context_types_arg, const std::string& vm_manager, const GuestConfig& guest_config, CuttlefishConfig::MutableInstanceSpecific& instance); diff --git a/host/commands/assemble_cvd/misc_info.cc b/host/commands/assemble_cvd/misc_info.cc index e96099c4d..292258b96 100644 --- a/host/commands/assemble_cvd/misc_info.cc +++ b/host/commands/assemble_cvd/misc_info.cc @@ -16,14 +16,26 @@ #include "misc_info.h" #include <algorithm> +#include <string> +#include <vector> #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include "common/libs/utils/contains.h" +#include "common/libs/utils/result.h" + namespace cuttlefish { +namespace { + +constexpr char kDynamicPartitions[] = "dynamic_partition_list"; +constexpr char kGoogleDynamicPartitions[] = "google_dynamic_partitions"; +constexpr char kSuperPartitionGroups[] = "super_partition_groups"; + +} // namespace -MiscInfo ParseMiscInfo(const std::string& misc_info_contents) { +Result<MiscInfo> ParseMiscInfo(const std::string& misc_info_contents) { auto lines = android::base::Split(misc_info_contents, "\n"); MiscInfo misc_info; for (auto& line : lines) { @@ -37,13 +49,13 @@ MiscInfo ParseMiscInfo(const std::string& misc_info_contents) { continue; } // Not using android::base::Split here to only capture the first = - auto key = android::base::Trim(line.substr(0, eq_pos)); - auto value = android::base::Trim(line.substr(eq_pos + 1)); - if (misc_info.find(key) != misc_info.end() && misc_info[key] != value) { - LOG(ERROR) << "Duplicate key: \"" << key << "\". First value: \"" - << misc_info[key] << "\", Second value: \"" << value << "\""; - return {}; - } + const auto key = android::base::Trim(line.substr(0, eq_pos)); + const auto value = android::base::Trim(line.substr(eq_pos + 1)); + const bool duplicate = Contains(misc_info, key) && misc_info[key] != value; + CF_EXPECTF(!duplicate, + "Duplicate key with different value. key:\"{}\", previous " + "value:\"{}\", this value:\"{}\"", + key, misc_info[key], value); misc_info[key] = value; } return misc_info; @@ -57,8 +69,6 @@ std::string WriteMiscInfo(const MiscInfo& misc_info) { return out.str(); } -static const std::string kDynamicPartitions = "dynamic_partition_list"; - std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) { auto value_it = info.find(kDynamicPartitions); if (value_it == info.end()) { @@ -73,10 +83,6 @@ std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) { return components; } -static constexpr const char* kGoogleDynamicPartitions = - "google_dynamic_partitions"; -static constexpr const char* kSuperPartitionGroups = "super_partition_groups"; - bool SetSuperPartitionComponents(const std::vector<std::string>& components, MiscInfo* misc_info) { auto super_partition_groups = misc_info->find(kSuperPartitionGroups); diff --git a/host/commands/assemble_cvd/misc_info.h b/host/commands/assemble_cvd/misc_info.h index aa130bcc9..f832a4c5f 100644 --- a/host/commands/assemble_cvd/misc_info.h +++ b/host/commands/assemble_cvd/misc_info.h @@ -19,11 +19,13 @@ #include <string> #include <vector> +#include "common/libs/utils/result.h" + namespace cuttlefish { using MiscInfo = std::map<std::string, std::string>; -MiscInfo ParseMiscInfo(const std::string& file_contents); +Result<MiscInfo> ParseMiscInfo(const std::string& file_contents); std::string WriteMiscInfo(const MiscInfo& info); std::vector<std::string> SuperPartitionComponents(const MiscInfo&); diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc index 8f445310a..b59d163fb 100644 --- a/host/commands/assemble_cvd/super_image_mixer.cc +++ b/host/commands/assemble_cvd/super_image_mixer.cc @@ -30,6 +30,7 @@ #include "common/libs/utils/archive.h" #include "common/libs/utils/contains.h" #include "common/libs/utils/files.h" +#include "common/libs/utils/result.h" #include "common/libs/utils/subprocess.h" #include "host/commands/assemble_cvd/misc_info.h" #include "host/libs/config/config_utils.h" @@ -37,59 +38,8 @@ #include "host/libs/config/fetcher_config.h" namespace cuttlefish { - -Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config, - const std::string& default_target_zip, - const std::string& system_target_zip) { - bool has_default_target_zip = false; - bool has_system_target_zip = false; - if (default_target_zip != "" && - default_target_zip != "unset") { - has_default_target_zip = true; - } - if (system_target_zip != "" && - system_target_zip != "unset") { - has_system_target_zip = true; - } - CF_EXPECT(has_default_target_zip == has_system_target_zip, - "default_target_zip and system_target_zip " - "flags must be specified together"); - // at this time, both should be the same, either true or false - // therefore, I only check one variable - if (has_default_target_zip) { - return true; - } - - bool has_default_build = false; - bool has_system_build = false; - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - if (file_iter.second.source == FileSource::DEFAULT_BUILD) { - has_default_build = true; - } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) { - has_system_build = true; - } - } - return has_default_build && has_system_build; -} - namespace { -std::string TargetFilesZip(const FetcherConfig& fetcher_config, - FileSource source) { - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - const auto& file_path = file_iter.first; - const auto& file_info = file_iter.second; - if (file_info.source != source) { - continue; - } - std::string expected_filename = "target_files-" + file_iter.second.build_id; - if (file_path.find(expected_filename) != std::string::npos) { - return file_path; - } - } - return ""; -} - constexpr char kMiscInfoPath[] = "META/misc_info.txt"; constexpr std::array kVendorTargetImages = { "IMAGES/boot.img", @@ -115,6 +65,13 @@ constexpr std::array kVendorTargetBuildProps = { "VENDOR/etc/build.prop", }; +struct TargetFiles { + Archive vendor_zip; + Archive system_zip; + std::vector<std::string> vendor_contents; + std::vector<std::string> system_contents; +}; + void FindImports(Archive* archive, const std::string& build_prop_file) { auto contents = archive->ExtractToMemory(build_prop_file); auto lines = android::base::Split(contents, "\n"); @@ -126,119 +83,126 @@ void FindImports(Archive* archive, const std::string& build_prop_file) { } } -Result<void> CombineTargetZipFiles(const std::string& default_target_zip, - const std::string& system_target_zip, - const std::string& output_path) { - Archive default_target_archive(default_target_zip); - auto default_target_contents = default_target_archive.Contents(); - CF_EXPECT(default_target_contents.size() != 0, - "Could not open " << default_target_zip); - - Archive system_target_archive(system_target_zip); - auto system_target_contents = system_target_archive.Contents(); - CF_EXPECT(system_target_contents.size() != 0, - "Could not open " << system_target_zip); - - CF_EXPECT( - mkdir(output_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0, - "Could not create directory " << output_path); - - std::string output_meta = output_path + "/META"; - CF_EXPECT( - mkdir(output_meta.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0, - "Could not create directory " << output_meta); - - CF_EXPECT( - std::find(default_target_contents.begin(), default_target_contents.end(), - kMiscInfoPath) != default_target_contents.end(), - "Default target files zip does not have " << kMiscInfoPath); - - CF_EXPECT( - std::find(system_target_contents.begin(), system_target_contents.end(), - kMiscInfoPath) != system_target_contents.end(), - "System target files zip does not have " << kMiscInfoPath); - - const auto default_misc = - ParseMiscInfo(default_target_archive.ExtractToMemory(kMiscInfoPath)); - CF_EXPECT(default_misc.size() != 0, - "Could not read the default misc_info.txt file."); - - const auto system_misc = - ParseMiscInfo(system_target_archive.ExtractToMemory(kMiscInfoPath)); - CF_EXPECT(system_misc.size() != 0, - "Could not read the system misc_info.txt file."); +bool IsTargetFilesImage(const std::string& filename) { + return android::base::StartsWith(filename, "IMAGES/") && + android::base::EndsWith(filename, ".img"); +} + +bool IsTargetFilesBuildProp(const std::string& filename) { + return android::base::EndsWith(filename, "build.prop"); +} + +Result<TargetFiles> GetTargetFiles(const std::string& vendor_zip_path, + const std::string& system_zip_path) { + auto result = TargetFiles{ + .vendor_zip = Archive(vendor_zip_path), + .system_zip = Archive(system_zip_path), + }; + result.vendor_contents = result.vendor_zip.Contents(); + result.system_contents = result.system_zip.Contents(); + CF_EXPECTF(!result.vendor_contents.empty(), "Could not open {}", + vendor_zip_path); + CF_EXPECTF(!result.system_contents.empty(), "Could not open {}", + system_zip_path); + return result; +} + +Result<void> CombineMiscInfo(TargetFiles& target_files, + const std::string& misc_output_path) { + CF_EXPECTF(Contains(target_files.vendor_contents, kMiscInfoPath), + "Default target files zip does not contain {}", kMiscInfoPath); + CF_EXPECTF(Contains(target_files.system_contents, kMiscInfoPath), + "System target files zip does not contain {}", kMiscInfoPath); + + const MiscInfo default_misc = CF_EXPECT( + ParseMiscInfo(target_files.vendor_zip.ExtractToMemory(kMiscInfoPath))); + const MiscInfo system_misc = CF_EXPECT( + ParseMiscInfo(target_files.system_zip.ExtractToMemory(kMiscInfoPath))); auto output_misc = default_misc; auto system_super_partitions = SuperPartitionComponents(system_misc); // Ensure specific skipped partitions end up in the misc_info.txt for (auto partition : {"odm", "odm_dlkm", "vendor", "vendor_dlkm", "system_dlkm"}) { - if (std::find(system_super_partitions.begin(), system_super_partitions.end(), - partition) == system_super_partitions.end()) { + if (!Contains(system_super_partitions, partition)) { system_super_partitions.push_back(partition); } } CF_EXPECT(SetSuperPartitionComponents(system_super_partitions, &output_misc), "Failed to update super partitions components for misc_info"); - auto misc_output_path = output_path + "/" + kMiscInfoPath; - SharedFD misc_output_file = - SharedFD::Creat(misc_output_path.c_str(), 0644); + SharedFD misc_output_file = SharedFD::Creat(misc_output_path.c_str(), 0644); CF_EXPECT(misc_output_file->IsOpen(), "Failed to open output misc file: " << misc_output_file->StrError()); CF_EXPECT(WriteAll(misc_output_file, WriteMiscInfo(output_misc)) >= 0, "Failed to write output misc file contents: " << misc_output_file->StrError()); + return {}; +} - for (const auto& name : default_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { +Result<void> ExtractTargetFiles(TargetFiles& target_files, + const std::string& combined_output_path) { + for (const auto& name : target_files.vendor_contents) { + if (!IsTargetFilesImage(name)) { continue; } else if (!Contains(kVendorTargetImages, name)) { continue; } - LOG(INFO) << "Writing " << name; - CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + LOG(INFO) << "Writing " << name << " from vendor target"; + CF_EXPECT( + target_files.vendor_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the vendor target zip"); } - for (const auto& name : default_target_contents) { - if (!android::base::EndsWith(name, "build.prop")) { + for (const auto& name : target_files.vendor_contents) { + if (!IsTargetFilesBuildProp(name)) { continue; } else if (!Contains(kVendorTargetBuildProps, name)) { continue; } - FindImports(&default_target_archive, name); - LOG(INFO) << "Writing " << name; - CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + FindImports(&target_files.vendor_zip, name); + LOG(INFO) << "Writing " << name << " from vendor target"; + CF_EXPECT( + target_files.vendor_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the vendor target zip"); } - for (const auto& name : system_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { + for (const auto& name : target_files.system_contents) { + if (!IsTargetFilesImage(name)) { continue; } else if (Contains(kVendorTargetImages, name)) { continue; } - LOG(INFO) << "Writing " << name; - CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the system target zip"); + LOG(INFO) << "Writing " << name << " from system target"; + CF_EXPECT( + target_files.system_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the system target zip"); } - for (const auto& name : system_target_contents) { - if (!android::base::EndsWith(name, "build.prop")) { + for (const auto& name : target_files.system_contents) { + if (!IsTargetFilesBuildProp(name)) { continue; } else if (Contains(kVendorTargetBuildProps, name)) { continue; } - FindImports(&system_target_archive, name); - LOG(INFO) << "Writing " << name; - CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + FindImports(&target_files.system_zip, name); + LOG(INFO) << "Writing " << name << " from system target"; + CF_EXPECT( + target_files.system_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the system target zip"); } + return {}; +} +Result<void> CombineTargetZipFiles(const std::string& vendor_zip_path, + const std::string& system_zip_path, + const std::string& output_path) { + CF_EXPECT(EnsureDirectoryExists(output_path)); + CF_EXPECT(EnsureDirectoryExists(output_path + "/META")); + auto target_files = + CF_EXPECT(GetTargetFiles(vendor_zip_path, system_zip_path)); + CF_EXPECT(ExtractTargetFiles(target_files, output_path)); + const auto misc_output_path = output_path + "/" + kMiscInfoPath; + CF_EXPECT(CombineMiscInfo(target_files, misc_output_path)); return {}; } @@ -258,6 +222,22 @@ bool BuildSuperImage(const std::string& combined_target_zip, }) == 0; } +std::string TargetFilesZip(const FetcherConfig& fetcher_config, + FileSource source) { + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + const auto& file_path = file_iter.first; + const auto& file_info = file_iter.second; + if (file_info.source != source) { + continue; + } + std::string expected_filename = "target_files-" + file_iter.second.build_id; + if (file_path.find(expected_filename) != std::string::npos) { + return file_path; + } + } + return ""; +} + Result<void> RebuildSuperImage(const FetcherConfig& fetcher_config, const CuttlefishConfig& config, const std::string& output_path) { @@ -319,6 +299,38 @@ class SuperImageRebuilderImpl : public SuperImageRebuilder { } // namespace +Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config, + const std::string& default_target_zip, + const std::string& system_target_zip) { + bool has_default_target_zip = false; + bool has_system_target_zip = false; + if (default_target_zip != "" && default_target_zip != "unset") { + has_default_target_zip = true; + } + if (system_target_zip != "" && system_target_zip != "unset") { + has_system_target_zip = true; + } + CF_EXPECT(has_default_target_zip == has_system_target_zip, + "default_target_zip and system_target_zip " + "flags must be specified together"); + // at this time, both should be the same, either true or false + // therefore, I only check one variable + if (has_default_target_zip) { + return true; + } + + bool has_default_build = false; + bool has_system_build = false; + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + if (file_iter.second.source == FileSource::DEFAULT_BUILD) { + has_default_build = true; + } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) { + has_system_build = true; + } + } + return has_default_build && has_system_build; +} + fruit::Component<fruit::Required<const FetcherConfig, const CuttlefishConfig, const CuttlefishConfig::InstanceSpecific>, SuperImageRebuilder> @@ -328,4 +340,4 @@ SuperImageRebuilderComponent() { .addMultibinding<SetupFeature, SuperImageRebuilder>(); } -} // namespace cuttlefish +} // namespace cuttlefish diff --git a/host/commands/logcat_receiver/main.cpp b/host/commands/logcat_receiver/main.cpp index d7c9dbc94..3e08f750a 100644 --- a/host/commands/logcat_receiver/main.cpp +++ b/host/commands/logcat_receiver/main.cpp @@ -64,7 +64,6 @@ int main(int argc, char** argv) { auto logcat_file = cuttlefish::SharedFD::Open(path.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0666); - bool first_iter = true; // Server loop while (true) { char buff[1024]; @@ -74,35 +73,9 @@ int main(int argc, char** argv) { break; } auto written = cuttlefish::WriteAll(logcat_file, buff, read); - CHECK(written == read) - << "Error writing to log file: " << logcat_file->StrError() - << ". This is unrecoverable."; - if (first_iter) { - first_iter = false; - if (cuttlefish::IsRestoring(*config)) { - cuttlefish::SharedFD restore_pipe = cuttlefish::SharedFD::Open( - instance.restore_pipe_name().c_str(), O_WRONLY); - if (!restore_pipe->IsOpen()) { - LOG(ERROR) << "Error opening restore pipe: " - << restore_pipe->StrError(); - return 2; - } - cuttlefish::SharedFD restore_adbd_pipe = cuttlefish::SharedFD::Open( - instance.restore_adbd_pipe_name().c_str(), O_WRONLY); - if (!restore_adbd_pipe->IsOpen()) { - LOG(ERROR) << "Error opening restore pipe: " - << restore_adbd_pipe->StrError(); - return 2; - } - - CHECK(cuttlefish::WriteAll(restore_pipe, "1") == 1) - << "Error writing to restore pipe: " << restore_pipe->StrError() - << ". This is unrecoverable."; - CHECK(cuttlefish::WriteAll(restore_adbd_pipe, "2") == 1) - << "Error writing to adbd restore pipe: " - << restore_adbd_pipe->StrError() << ". This is unrecoverable."; - } - } + CHECK(written == read) << "Error writing to log file: " + << logcat_file->StrError() + << ". This is unrecoverable."; } logcat_file->Close(); diff --git a/host/commands/run_cvd/boot_state_machine.cc b/host/commands/run_cvd/boot_state_machine.cc index 67060e07a..242c0a5e3 100644 --- a/host/commands/run_cvd/boot_state_machine.cc +++ b/host/commands/run_cvd/boot_state_machine.cc @@ -43,72 +43,47 @@ namespace { // Forks run_cvd into a daemonized child process. The current process continues // only until the child has signalled that the boot is finished. // -// How the child signals when the boot is finished depends on whether we are -// restoring from a snapshot. -// -// * When booting normally, `DaemonizeLauncher` returns the write end of a -// pipe. The child is expected to write a `RunnerExitCodes` into the pipe -// when the boot finishes. -// * When restoring from a snapshot, `DaemonizeLauncher` returns an invalid -// `SharedFD`. The child is expected to write an arbitrary byte to the -// instance's "restore_pipe" and then the parent assumes the restore was -// successful. -// -// We should consider unifying these two types of pipes. +// `DaemonizeLauncher` returns the write end of a pipe. The child is expected +// to write a `RunnerExitCodes` into the pipe when the boot finishes. Result<SharedFD> DaemonizeLauncher(const CuttlefishConfig& config) { auto instance = config.ForDefaultInstance(); - SharedFD read_end, write_end, restore_pipe_read; - if (IsRestoring(config)) { - restore_pipe_read = - CF_EXPECT(SharedFD::Fifo(instance.restore_pipe_name(), 0600), - "Unable to create restore fifo"); - } else { - CF_EXPECT(SharedFD::Pipe(&read_end, &write_end), "Unable to create pipe"); - } + SharedFD read_end, write_end; + CF_EXPECT(SharedFD::Pipe(&read_end, &write_end), "Unable to create pipe"); auto pid = fork(); if (pid) { // Explicitly close here, otherwise we may end up reading forever if the // child process dies. write_end->Close(); RunnerExitCodes exit_code; - if (IsRestoring(config)) { - if (!restore_pipe_read->IsOpen()) { - LOG(ERROR) << "Error opening restore pipe: " - << restore_pipe_read->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - // Try to read from restore pipe. IF successfully reads, that means logcat - // has started, and the VM has resumed. Exit the thread. - char buff[1]; - auto read = restore_pipe_read->Read(buff, 1); - if (read <= 0) { - LOG(ERROR) << "Could not read restore pipe: " - << restore_pipe_read->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - exit_code = RunnerExitCodes::kSuccess; - LOG(INFO) << "Virtual device restored successfully"; - std::exit(exit_code); - } auto bytes_read = read_end->Read(&exit_code, sizeof(exit_code)); if (bytes_read != sizeof(exit_code)) { LOG(ERROR) << "Failed to read a complete exit code, read " << bytes_read << " bytes only instead of the expected " << sizeof(exit_code); exit_code = RunnerExitCodes::kPipeIOError; } else if (exit_code == RunnerExitCodes::kSuccess) { - LOG(INFO) << "Virtual device booted successfully"; + if (IsRestoring(config)) { + LOG(INFO) << "Virtual device restored successfully"; + } else { + LOG(INFO) << "Virtual device booted successfully"; + } } else if (exit_code == RunnerExitCodes::kVirtualDeviceBootFailed) { - LOG(ERROR) << "Virtual device failed to boot"; + if (IsRestoring(config)) { + LOG(ERROR) << "Virtual device failed to restore"; + } else { + LOG(ERROR) << "Virtual device failed to boot"; + } if (!instance.fail_fast()) { LOG(ERROR) << "Device has been left running for debug"; } } else { LOG(ERROR) << "Unexpected exit code: " << exit_code; } - if (exit_code == RunnerExitCodes::kSuccess) { - LOG(INFO) << kBootCompletedMessage; - } else { - LOG(INFO) << kBootFailedMessage; + if (!IsRestoring(config)) { + if (exit_code == RunnerExitCodes::kSuccess) { + LOG(INFO) << kBootCompletedMessage; + } else { + LOG(INFO) << kBootFailedMessage; + } } std::exit(exit_code); } else { @@ -145,12 +120,8 @@ Result<SharedFD> DaemonizeLauncher(const CuttlefishConfig& config) { std::exit(RunnerExitCodes::kDaemonizationError); } - if (IsRestoring(config)) { - return {}; - } else { - read_end->Close(); - return write_end; - } + read_end->Close(); + return write_end; } } @@ -183,11 +154,15 @@ Result<SharedFD> ProcessLeader( class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { public: INJECT( - CvdBootStateMachine(AutoSetup<ProcessLeader>::Type& process_leader, + CvdBootStateMachine(const CuttlefishConfig& config, + AutoSetup<ProcessLeader>::Type& process_leader, KernelLogPipeProvider& kernel_log_pipe_provider, + const vm_manager::VmManager& vm_manager, const CuttlefishConfig::InstanceSpecific& instance)) - : process_leader_(process_leader), + : config_(config), + process_leader_(process_leader), kernel_log_pipe_provider_(kernel_log_pipe_provider), + vm_manager_(vm_manager), instance_(instance), state_(kBootStarted) {} @@ -200,6 +175,9 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { if (boot_event_handler_.joinable()) { boot_event_handler_.join(); } + if (restore_complete_handler_.joinable()) { + restore_complete_handler_.join(); + } } // SetupFeature @@ -228,12 +206,48 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { SharedFD boot_events_pipe = kernel_log_pipe_provider_.KernelLogPipe(); CF_EXPECTF(boot_events_pipe->IsOpen(), "Could not get boot events pipe: {}", boot_events_pipe->StrError()); - boot_event_handler_ = std::thread( - [this, boot_events_pipe]() { ThreadLoop(boot_events_pipe); }); + + SharedFD restore_complete_pipe, restore_complete_pipe_write; + if (IsRestoring(config_)) { + CF_EXPECT( + SharedFD::Pipe(&restore_complete_pipe, &restore_complete_pipe_write), + "unable to create pipe"); + + // Unlike `boot_event_handler_`, this doesn't support graceful shutdown, + // it blocks until it finishes its work. + restore_complete_handler_ = + std::thread([this, restore_complete_pipe_write]() { + const auto result = vm_manager_.WaitForRestoreComplete(); + CHECK(result.ok()) << "Failed to wait for restore complete: " + << result.error().FormatForEnv(); + + cuttlefish::SharedFD restore_adbd_pipe = cuttlefish::SharedFD::Open( + config_.ForDefaultInstance().restore_adbd_pipe_name().c_str(), + O_WRONLY); + CHECK(restore_adbd_pipe->IsOpen()) + << "Error opening adbd restore pipe: " + << restore_adbd_pipe->StrError(); + CHECK(cuttlefish::WriteAll(restore_adbd_pipe, "2") == 1) + << "Error writing to adbd restore pipe: " + << restore_adbd_pipe->StrError() << ". This is unrecoverable."; + + // Done last so that adb is more likely to be ready. + CHECK(cuttlefish::WriteAll(restore_complete_pipe_write, "1") == 1) + << "Error writing to restore complete pipe: " + << restore_complete_pipe_write->StrError() + << ". This is unrecoverable."; + }); + } + + boot_event_handler_ = + std::thread([this, boot_events_pipe, restore_complete_pipe]() { + ThreadLoop(boot_events_pipe, restore_complete_pipe); + }); + return {}; } - void ThreadLoop(SharedFD boot_events_pipe) { + void ThreadLoop(SharedFD boot_events_pipe, SharedFD restore_complete_pipe) { while (true) { std::vector<PollSharedFd> poll_shared_fd = { { @@ -241,17 +255,26 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { .events = POLLIN | POLLHUP, }, { + .fd = restore_complete_pipe, + .events = restore_complete_pipe->IsOpen() + ? (short)(POLLIN | POLLHUP) + : (short)0, + }, + { .fd = interrupt_fd_read_, .events = POLLIN | POLLHUP, - }}; + }, + }; int result = SharedFD::Poll(poll_shared_fd, -1); - if (poll_shared_fd[1].revents & POLLIN) { + // interrupt_fd_read_ + if (poll_shared_fd[2].revents & POLLIN) { return; } if (result < 0) { PLOG(FATAL) << "Failed to call Select"; return; } + // boot_events_pipe if (poll_shared_fd[0].revents & POLLHUP) { LOG(ERROR) << "Failed to read a complete kernel log boot event."; state_ |= kGuestBootFailed; @@ -259,23 +282,46 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { break; } } - if (!(poll_shared_fd[0].revents & POLLIN)) { - continue; + if (poll_shared_fd[0].revents & POLLIN) { + auto sent_code = OnBootEvtReceived(boot_events_pipe); + if (sent_code) { + if (!BootCompleted()) { + if (!instance_.fail_fast()) { + LOG(ERROR) << "Device running, likely in a bad state"; + break; + } + auto monitor_res = GetLauncherMonitorFromInstance(instance_, 5); + CHECK(monitor_res.ok()) << monitor_res.error().FormatForEnv(); + auto fail_res = RunLauncherAction( + *monitor_res, LauncherAction::kFail, std::optional<int>()); + CHECK(fail_res.ok()) << fail_res.error().FormatForEnv(); + } + break; + } } - auto sent_code = OnBootEvtReceived(boot_events_pipe); - if (sent_code) { - if (!BootCompleted()) { - if (!instance_.fail_fast()) { - LOG(ERROR) << "Device running, likely in a bad state"; + // restore_complete_pipe + if (poll_shared_fd[1].revents & POLLIN) { + char buff[1]; + auto read = restore_complete_pipe->Read(buff, 1); + if (read <= 0) { + LOG(ERROR) << "Could not read restore pipe: " + << restore_complete_pipe->StrError(); + state_ |= kGuestBootFailed; + if (MaybeWriteNotification()) { break; } - auto monitor_res = GetLauncherMonitorFromInstance(instance_, 5); - CHECK(monitor_res.ok()) << monitor_res.error().FormatForEnv(); - auto fail_res = RunLauncherAction(*monitor_res, LauncherAction::kFail, - std::optional<int>()); - CHECK(fail_res.ok()) << fail_res.error().FormatForEnv(); } - break; + state_ |= kGuestBootCompleted; + if (MaybeWriteNotification()) { + break; + } + } + if (poll_shared_fd[1].revents & POLLHUP) { + LOG(ERROR) << "restore_complete_pipe closed unexpectedly"; + state_ |= kGuestBootFailed; + if (MaybeWriteNotification()) { + break; + } } } } @@ -325,11 +371,14 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { return BootCompleted() || (state_ & kGuestBootFailed); } + const CuttlefishConfig& config_; AutoSetup<ProcessLeader>::Type& process_leader_; KernelLogPipeProvider& kernel_log_pipe_provider_; + const vm_manager::VmManager& vm_manager_; const CuttlefishConfig::InstanceSpecific& instance_; std::thread boot_event_handler_; + std::thread restore_complete_handler_; SharedFD fg_launcher_pipe_; SharedFD reboot_notification_; SharedFD interrupt_fd_read_; @@ -344,6 +393,7 @@ class CvdBootStateMachine : public SetupFeature, public KernelLogPipeConsumer { fruit::Component<fruit::Required<const CuttlefishConfig, KernelLogPipeProvider, const CuttlefishConfig::InstanceSpecific, + const vm_manager::VmManager, AutoSetup<ValidateTapDevices>::Type>> bootStateMachineComponent() { return fruit::createComponent() diff --git a/host/commands/run_cvd/boot_state_machine.h b/host/commands/run_cvd/boot_state_machine.h index 04de24801..4b742ac4a 100644 --- a/host/commands/run_cvd/boot_state_machine.h +++ b/host/commands/run_cvd/boot_state_machine.h @@ -24,6 +24,7 @@ namespace cuttlefish { fruit::Component<fruit::Required<const CuttlefishConfig, KernelLogPipeProvider, const CuttlefishConfig::InstanceSpecific, + const vm_manager::VmManager, AutoSetup<ValidateTapDevices>::Type>> bootStateMachineComponent(); diff --git a/host/commands/run_cvd/server_loop_impl.cpp b/host/commands/run_cvd/server_loop_impl.cpp index 8506245cf..61f1fa6bb 100644 --- a/host/commands/run_cvd/server_loop_impl.cpp +++ b/host/commands/run_cvd/server_loop_impl.cpp @@ -297,7 +297,6 @@ void ServerLoopImpl::DeleteFifos() { instance_.console_in_pipe_name(), instance_.console_out_pipe_name(), instance_.logcat_pipe_name(), - instance_.restore_pipe_name(), instance_.PerInstanceInternalPath("keymaster_fifo_vm.in"), instance_.PerInstanceInternalPath("keymaster_fifo_vm.out"), instance_.PerInstanceInternalPath("keymint_fifo_vm.in"), diff --git a/host/commands/start/main.cc b/host/commands/start/main.cc index 1f5ca8d07..e0c035f9c 100644 --- a/host/commands/start/main.cc +++ b/host/commands/start/main.cc @@ -250,6 +250,7 @@ std::unordered_set<std::string> kBoolFlags = { "console", "enable_sandbox", "enable_virtiofs", + "enable_usb", "restart_subprocesses", "enable_gpu_udmabuf", "enable_gpu_vhost_user", diff --git a/host/libs/config/config_utils.cpp b/host/libs/config/config_utils.cpp index 9197877dc..c4fea49cc 100644 --- a/host/libs/config/config_utils.cpp +++ b/host/libs/config/config_utils.cpp @@ -24,8 +24,10 @@ #include <android-base/logging.h> #include <android-base/strings.h> +#include "common/libs/utils/contains.h" #include "common/libs/utils/environment.h" #include "host/libs/config/config_constants.h" +#include "host/libs/config/cuttlefish_config.h" namespace cuttlefish { @@ -111,19 +113,17 @@ std::string HostBinaryDir() { return DefaultHostArtifactsPath("bin"); } -bool UseQemu8() { +bool UseQemuPrebuilt() { const std::string target_prod_str = StringFromEnv("TARGET_PRODUCT", ""); - if (HostArch() == Arch::X86_64 && - target_prod_str.find("arm") == std::string::npos) { + if (!Contains(target_prod_str, "arm")) { return true; } - return false; } std::string DefaultQemuBinaryDir() { - if (UseQemu8()) { - return HostBinaryDir(); + if (UseQemuPrebuilt()) { + return HostBinaryDir() + "/" + HostArchStr() + "-linux-gnu/qemu"; } return "/usr/bin"; } @@ -140,6 +140,14 @@ std::string HostUsrSharePath(const std::string& binary_name) { return DefaultHostArtifactsPath("usr/share/" + binary_name); } +std::string HostQemuBiosPath() { + if (UseQemuPrebuilt()) { + return DefaultHostArtifactsPath( + "usr/share/qemu/" + HostArchStr() + "-linux-gnu"); + } + return "/usr/share/qemu"; +} + std::string DefaultGuestImagePath(const std::string& file_name) { return (StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", "."))) + file_name; diff --git a/host/libs/config/config_utils.h b/host/libs/config/config_utils.h index 8107f5e9b..b5058bb18 100644 --- a/host/libs/config/config_utils.h +++ b/host/libs/config/config_utils.h @@ -51,6 +51,7 @@ std::string DefaultHostArtifactsPath(const std::string& file); std::string DefaultQemuBinaryDir(); std::string HostBinaryPath(const std::string& file); std::string HostUsrSharePath(const std::string& file); +std::string HostQemuBiosPath(); std::string DefaultGuestImagePath(const std::string& file); std::string DefaultEnvironmentPath(const char* environment_key, const char* default_value, @@ -59,6 +60,6 @@ std::string DefaultEnvironmentPath(const char* environment_key, // Whether the host supports qemu bool HostSupportsQemuCli(); -// Whether to use QEMU8 -bool UseQemu8(); +// Whether to use our local QEMU prebuilt +bool UseQemuPrebuilt(); } diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp index ad65c9cbe..6de482552 100644 --- a/host/libs/config/cuttlefish_config.cpp +++ b/host/libs/config/cuttlefish_config.cpp @@ -50,6 +50,7 @@ const char* const kVhostUserVsockModeTrue = "true"; const char* const kVhostUserVsockModeFalse = "false"; const char* const kGpuModeAuto = "auto"; +const char* const kGpuModeCustom = "custom"; const char* const kGpuModeDrmVirgl = "drm_virgl"; const char* const kGpuModeGfxstream = "gfxstream"; const char* const kGpuModeGfxstreamGuestAngle = "gfxstream_guest_angle"; diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h index 5881b2c91..71448ea97 100644 --- a/host/libs/config/cuttlefish_config.h +++ b/host/libs/config/cuttlefish_config.h @@ -376,7 +376,6 @@ class CuttlefishConfig { std::string rotary_socket_path() const; std::string keyboard_socket_path() const; std::string switches_socket_path() const; - std::string frames_socket_path() const; std::string access_kregistry_path() const; @@ -399,7 +398,6 @@ class CuttlefishConfig { std::string gnss_out_pipe_name() const; std::string logcat_pipe_name() const; - std::string restore_pipe_name() const; std::string restore_adbd_pipe_name() const; std::string launcher_log_path() const; @@ -560,6 +558,7 @@ class CuttlefishConfig { bool enable_audio() const; bool enable_gnss_grpc_proxy() const; bool enable_bootanimation() const; + bool enable_usb() const; std::vector<std::string> extra_bootconfig_args() const; bool record_screen() const; std::string gem5_debug_file() const; @@ -602,6 +601,9 @@ class CuttlefishConfig { std::string gpu_capture_binary() const; std::string gpu_gfxstream_transport() const; std::string gpu_renderer_features() const; + std::string gpu_context_types() const; + std::string guest_vulkan_driver() const; + std::string frames_socket_path() const; std::string gpu_vhost_user_mode() const; @@ -763,6 +765,7 @@ class CuttlefishConfig { void set_pause_in_bootloader(bool pause_in_bootloader); void set_run_as_daemon(bool run_as_daemon); void set_enable_audio(bool enable); + void set_enable_usb(bool enable); void set_enable_gnss_grpc_proxy(const bool enable_gnss_grpc_proxy); void set_enable_bootanimation(const bool enable_bootanimation); void set_extra_bootconfig_args(const std::string& extra_bootconfig_args); @@ -809,6 +812,10 @@ class CuttlefishConfig { void set_gpu_capture_binary(const std::string&); void set_gpu_gfxstream_transport(const std::string& transport); void set_gpu_renderer_features(const std::string& features); + void set_gpu_context_types(const std::string& context_types); + void set_guest_vulkan_driver(const std::string& driver); + void set_frames_socket_path(const std::string& driver); + void set_enable_gpu_udmabuf(const bool enable_gpu_udmabuf); void set_enable_gpu_vhost_user(const bool enable_gpu_vhost_user); void set_enable_gpu_external_blob(const bool enable_gpu_external_blob); @@ -972,6 +979,7 @@ extern const char* const kVhostUserVsockModeFalse; // GPU modes extern const char* const kGpuModeAuto; +extern const char* const kGpuModeCustom; extern const char* const kGpuModeDrmVirgl; extern const char* const kGpuModeGfxstream; extern const char* const kGpuModeGfxstreamGuestAngle; diff --git a/host/libs/config/cuttlefish_config_instance.cpp b/host/libs/config/cuttlefish_config_instance.cpp index 1cc3c1f00..455f53af5 100644 --- a/host/libs/config/cuttlefish_config_instance.cpp +++ b/host/libs/config/cuttlefish_config_instance.cpp @@ -748,6 +748,24 @@ void CuttlefishConfig::MutableInstanceSpecific::set_gpu_renderer_features( (*Dictionary())[kGpuRendererFeatures] = transport; } +static constexpr char kGpuContextTypes[] = "gpu_context_types"; +std::string CuttlefishConfig::InstanceSpecific::gpu_context_types() const { + return (*Dictionary())[kGpuContextTypes].asString(); +} +void CuttlefishConfig::MutableInstanceSpecific::set_gpu_context_types( + const std::string& context_types) { + (*Dictionary())[kGpuContextTypes] = context_types; +} + +static constexpr char kVulkanDriver[] = "guest_vulkan_driver"; +std::string CuttlefishConfig::InstanceSpecific::guest_vulkan_driver() const { + return (*Dictionary())[kVulkanDriver].asString(); +} +void CuttlefishConfig::MutableInstanceSpecific::set_guest_vulkan_driver( + const std::string& driver) { + (*Dictionary())[kVulkanDriver] = driver; +} + static constexpr char kRestartSubprocesses[] = "restart_subprocesses"; bool CuttlefishConfig::InstanceSpecific::restart_subprocesses() const { return (*Dictionary())[kRestartSubprocesses].asBool(); @@ -824,6 +842,14 @@ void CuttlefishConfig::MutableInstanceSpecific::set_enable_bootanimation( (*Dictionary())[kEnableBootAnimation] = enable_bootanimation; } +static constexpr char kEnableUsb[] = "enable_usb"; +void CuttlefishConfig::MutableInstanceSpecific::set_enable_usb(bool enable) { + (*Dictionary())[kEnableUsb] = enable; +} +bool CuttlefishConfig::InstanceSpecific::enable_usb() const { + return (*Dictionary())[kEnableUsb].asBool(); +} + static constexpr char kExtraBootconfigArgsInstanced[] = "extra_bootconfig_args"; std::vector<std::string> CuttlefishConfig::InstanceSpecific::extra_bootconfig_args() const { @@ -1161,10 +1187,6 @@ std::string CuttlefishConfig::InstanceSpecific::logcat_pipe_name() const { return AbsolutePath(PerInstanceInternalPath("logcat-pipe")); } -std::string CuttlefishConfig::InstanceSpecific::restore_pipe_name() const { - return AbsolutePath(PerInstanceInternalPath("restore-pipe")); -} - std::string CuttlefishConfig::InstanceSpecific::restore_adbd_pipe_name() const { return AbsolutePath(PerInstanceInternalPath("restore-pipe-adbd")); } @@ -1721,8 +1743,14 @@ std::string CuttlefishConfig::InstanceSpecific::switches_socket_path() const { return PerInstanceInternalUdsPath("switches.sock"); } +static constexpr char kFrameSockPath[] = "frame_sock_path"; +void CuttlefishConfig::MutableInstanceSpecific::set_frames_socket_path( + const std::string& frame_socket_path) { + (*Dictionary())[kFrameSockPath] = frame_socket_path; +} + std::string CuttlefishConfig::InstanceSpecific::frames_socket_path() const { - return PerInstanceInternalUdsPath("frames.sock"); + return (*Dictionary())[kFrameSockPath].asString(); } static constexpr char kWifiMacPrefix[] = "wifi_mac_prefix"; diff --git a/host/libs/screen_connector/screen_connector.h b/host/libs/screen_connector/screen_connector.h index 634c7adf9..bc56cedf6 100644 --- a/host/libs/screen_connector/screen_connector.h +++ b/host/libs/screen_connector/screen_connector.h @@ -68,7 +68,9 @@ class ScreenConnector : public ScreenConnectorInfo, } auto instance = config->ForDefaultInstance(); std::unordered_set<std::string_view> valid_gpu_modes{ - cuttlefish::kGpuModeDrmVirgl, cuttlefish::kGpuModeGfxstream, + cuttlefish::kGpuModeCustom, + cuttlefish::kGpuModeDrmVirgl, + cuttlefish::kGpuModeGfxstream, cuttlefish::kGpuModeGfxstreamGuestAngle, cuttlefish::kGpuModeGfxstreamGuestAngleHostSwiftShader, cuttlefish::kGpuModeGuestSwiftshader}; diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp index e190ffe87..899e39653 100644 --- a/host/libs/vm_manager/crosvm_manager.cpp +++ b/host/libs/vm_manager/crosvm_manager.cpp @@ -1,4 +1,4 @@ -/* +/*crosvm * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -114,6 +114,17 @@ CrosvmManager::ConfigureGraphics( {"androidboot.hardware.gltransport", gfxstream_transport}, {"androidboot.opengles.version", "196609"}, // OpenGL ES 3.1 }; + } else if (instance.gpu_mode() == kGpuModeCustom) { + bootconfig_args = { + {"androidboot.cpuvulkan.version", "0"}, + {"androidboot.hardware.gralloc", "minigbm"}, + {"androidboot.hardware.hwcomposer", instance.hwcomposer()}, + {"androidboot.hardware.hwcomposer.display_finder_mode", "drm"}, + {"androidboot.hardware.egl", "angle"}, + {"androidboot.hardware.vulkan", instance.guest_vulkan_driver()}, + {"androidboot.hardware.gltransport", "virtio-gpu-asg"}, + {"androidboot.opengles.version", "196609"}, // OpenGL ES 3.1 + }; } else if (instance.gpu_mode() == kGpuModeNone) { return {}; } else { @@ -201,12 +212,6 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu( auto gpu_device_socket_path = instance.PerInstanceInternalUdsPath("vhost-user-gpu-socket"); - auto gpu_device_socket = SharedFD::SocketLocalServer( - gpu_device_socket_path.c_str(), false, SOCK_STREAM, 0777); - CF_EXPECT(gpu_device_socket->IsOpen(), - "Failed to create socket for crosvm vhost user gpu's control" - << gpu_device_socket->StrError()); - auto gpu_device_logs_path = instance.PerInstanceInternalPath("crosvm_vhost_user_gpu.fifo"); auto gpu_device_logs = CF_EXPECT(SharedFD::Fifo(gpu_device_logs_path, 0666)); @@ -307,6 +312,15 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu( // Connect device to main crosvm: gpu_device_cmd.Cmd().AddParameter("--socket=", gpu_device_socket_path); + + main_crosvm_cmd->AddPrerequisite([gpu_device_socket_path]() -> Result<void> { +#ifdef __linux__ + return WaitForUnixSocketListeningWithoutConnect(gpu_device_socket_path, + /*timeoutSec=*/30); +#else + return CF_ERR("Unhandled check if vhost user gpu ready."); +#endif + }); main_crosvm_cmd->AddParameter( "--vhost-user=gpu,pci-address=", gpu_pci_address, ",socket=", gpu_device_socket_path); @@ -374,6 +388,10 @@ Result<void> ConfigureGpu(const CuttlefishConfig& config, Command* crosvm_cmd) { crosvm_cmd->AddParameter( "--gpu=context-types=gfxstream-vulkan:gfxstream-composer", gpu_common_3d_string); + } else if (gpu_mode == kGpuModeCustom) { + const std::string gpu_context_types = + "--gpu=context-types=" + instance.gpu_context_types(); + crosvm_cmd->AddParameter(gpu_context_types, gpu_common_string); } MaybeConfigureVulkanIcd(config, crosvm_cmd); @@ -451,7 +469,9 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands( // Disable USB passthrough. It isn't needed for any key use cases and it is // not compatible with crosvm suspend-resume support yet (b/266622743). // TODO: Allow it to be turned back on using a flag. - crosvm_cmd.Cmd().AddParameter("--no-usb"); + if (!instance.enable_usb()) { + crosvm_cmd.Cmd().AddParameter("--no-usb"); + } crosvm_cmd.Cmd().AddParameter("--core-scheduling=false"); @@ -860,5 +880,32 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands( return commands; } +Result<void> CrosvmManager::WaitForRestoreComplete() const { + auto instance = CF_EXPECT(CuttlefishConfig::Get())->ForDefaultInstance(); + + // Wait for the control socket to exist. It is created early in crosvm's + // startup sequence, but the process may not even have been exec'd by CF at + // this point. + while (!FileExists(instance.CrosvmSocketPath())) { + usleep(50000); // 50 ms, arbitrarily chosen + } + + // Ask crosvm to resume the VM. crosvm promises to not complete this command + // until the vCPUs are started (even if it was never suspended to begin + // with). + auto infop = CF_EXPECT(Execute( + std::vector<std::string>{ + instance.crosvm_binary(), + "resume", + instance.CrosvmSocketPath(), + "--full", + }, + SubprocessOptions(), WEXITED)); + CF_EXPECT_EQ(infop.si_code, CLD_EXITED); + CF_EXPECTF(infop.si_status == 0, "crosvm resume returns non zero code {}", + infop.si_status); + return {}; +} + } // namespace vm_manager } // namespace cuttlefish diff --git a/host/libs/vm_manager/crosvm_manager.h b/host/libs/vm_manager/crosvm_manager.h index a1433d2a2..cb119fefb 100644 --- a/host/libs/vm_manager/crosvm_manager.h +++ b/host/libs/vm_manager/crosvm_manager.h @@ -46,6 +46,8 @@ class CrosvmManager : public VmManager { const CuttlefishConfig& config, std::vector<VmmDependencyCommand*>& dependencyCommands) override; + Result<void> WaitForRestoreComplete() const override; + private: static constexpr int kCrosvmVmResetExitCode = 32; }; diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp index 26ff43628..0f300d41d 100644 --- a/host/libs/vm_manager/qemu_manager.cpp +++ b/host/libs/vm_manager/qemu_manager.cpp @@ -807,6 +807,9 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands( qemu_cmd.AddParameter("-device"); qemu_cmd.AddParameter("qemu-xhci,id=xhci"); + qemu_cmd.AddParameter("-L"); + qemu_cmd.AddParameter(HostQemuBiosPath()); + if (is_riscv64) { qemu_cmd.AddParameter("-kernel"); } else { diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h index b3fa4be6c..29fb68a8e 100644 --- a/host/libs/vm_manager/vm_manager.h +++ b/host/libs/vm_manager/vm_manager.h @@ -101,6 +101,14 @@ class VmManager { virtual Result<std::vector<MonitorCommand>> StartCommands( const CuttlefishConfig& config, std::vector<VmmDependencyCommand*>& dependencyCommands) = 0; + + // Block until the restore work is finished and the guest is running. Only + // called if a snapshot is being restored. + // + // Must be thread safe. + virtual Result<void> WaitForRestoreComplete() const { + return CF_ERR("not implemented"); + } }; fruit::Component<fruit::Required<const CuttlefishConfig, diff --git a/shared/auto/sepolicy/evs/hal_evs_default.te b/shared/auto/sepolicy/evs/hal_evs_default.te index e60e2a3f2..16950040e 100644 --- a/shared/auto/sepolicy/evs/hal_evs_default.te +++ b/shared/auto/sepolicy/evs/hal_evs_default.te @@ -45,3 +45,7 @@ binder_call(hal_evs_default, mediaserver) # Allow to use OMX service. hal_client_domain(hal_evs_default, hal_omx) hal_client_domain(hal_evs_default, hal_codec2) + +# Allow to interact with mediametrics +allow hal_evs_default mediametrics_service:service_manager find; +binder_call(hal_evs_default, mediametrics) diff --git a/system_image/Android.bp b/system_image/Android.bp index c04f00e3e..8df510752 100644 --- a/system_image/Android.bp +++ b/system_image/Android.bp @@ -149,6 +149,7 @@ android_system_image { "bootanimation", "bootctl", "bootstat", + "boringssl_self_test", "bpfloader", "bu", "bugreport_procdump", @@ -262,12 +263,14 @@ android_system_image { "libaaudio", "libadbd_auth", "libadbd_fs", + "libalarm_jni", "libamidi", "libandroid_runtime", "libandroid_servers", "libandroid", "libandroidemu", "libandroidfw", + "libartpalette-system", "libasyncio", "libasyncio", "libaudio_aidl_conversion_common_ndk_cpp", @@ -291,6 +294,7 @@ android_system_image { "libaudioutils", "libaudioutils", "libbinder_ndk", + "libbinder_rpc_unstable", "libbinder", "libblas", "libbootloader_message", @@ -354,6 +358,8 @@ android_system_image { "libhidcommand_jni", "libhidlmemory", "libhidlmemory", + "libhidltransport", + "libhwbinder", "libincident", "libinput", "libinputflinger", @@ -380,6 +386,7 @@ android_system_image { "libnetd_client", "libnetlink", "libnetutils", + "libneuralnetworks_packageinfo", "libnfc_nci_jni", "libnl", "libOpenglCodecCommon", @@ -426,6 +433,7 @@ android_system_image { "libsync", "libsysutils", "libtinyxml2", + "libtombstoned_client", "libtracingproxy", "libui", "libuinputcommand_jni", @@ -461,6 +469,7 @@ android_system_image { "make_f2fs", "mapper.minigbm", "mdnsd", + "media_profiles_V1_0.dtd", "mediacodec.policy", "mediaextractor", "mediametrics", @@ -734,6 +743,7 @@ android_system_image { "settaskprofile", "settings", "sfdo", + "sgdisk", "sh", "showmap", "simpleperf_app_runner", @@ -806,38 +816,6 @@ android_system_image { "xml2abx", "xtables.lock", "ziptool", - // TODO(b/321000103): uncomment when visibility option for partitions is introduced - // "boringssl_self_test_vendor", - // "boringssl_self_test", - // "init_second_stage", - // "libaecsw", - // "libagc1sw", - // "libagc2sw", - // "libalarm_jni", - // "libartpalette-system", - // "libbassboostsw", - // "libbinder_rpc_unstable", - // "libbundleaidl", - // "libdownmixaidl", - // "libdynamicsprocessingaidl", - // "libenvreverbsw", - // "libequalizersw", - // "libextensioneffect", - // "libhapticgeneratoraidl", - // "libhidltransport", - // "libhwbinder", - // "libloudnessenhanceraidl", - // "libmdnssd", - // "libmediametrics", - // "libneuralnetworks_packageinfo", - // "libnssw", - // "libpreprocessingaidl", - // "libpresetreverbsw", - // "libreverbaidl", - // "libvirtualizersw", - // "libvisualizeraidl", - // "libvolumesw", - // "sgdisk", ], multilib: { common: { @@ -853,6 +831,7 @@ android_system_image { "androidx.camera.extensions.impl", "androidx.window.extensions", "androidx.window.sidecar", + "aosp_mainline_modules", "BackupRestoreConfirmation", "BasicDreams", "BlockedNumberProvider", @@ -875,15 +854,9 @@ android_system_image { "CertInstaller", "CFSatelliteService", "charger_res_images", - "com.android.adbd", - "com.android.adservices", "com.android.apex.cts.shim.v1_prebuilt", - "com.android.appsearch", "com.android.cellbroadcast", "com.android.compos", - "com.android.configinfrastructure", - "com.android.devicelock", - "com.android.extservices", "com.android.future.usb.accessory", "com.android.hardware.authsecret", "com.android.hardware.biometrics.face.virtual", @@ -894,6 +867,8 @@ android_system_image { "com.android.hardware.dumpstate", "com.android.hardware.gnss", "com.android.hardware.input.processor", + "com.android.hardware.keymint.rust_cf_remote", + "com.android.hardware.keymint.rust_nonsecure", "com.android.hardware.memtrack", "com.android.hardware.net.nlinterceptor", "com.android.hardware.neuralnetworks", @@ -918,20 +893,9 @@ android_system_image { "com.android.location.provider", "com.android.media.remotedisplay.xml", "com.android.media.remotedisplay", - "com.android.media.swcodec", - "com.android.media", "com.android.mediadrm.signer", - "com.android.mediaprovider", - "com.android.neuralnetworks", "com.android.nfc_extras", - "com.android.os.statsd", - "com.android.resolv", - "com.android.rkpd", "com.android.runtime", - "com.android.scheduling", - "com.android.tethering", - "com.android.tzdata", - "com.android.virt", "com.google.cf.bt", "com.google.cf.confirmationui", "com.google.cf.health.storage", @@ -964,7 +928,9 @@ android_system_image { "ExternalStorageProvider", "ExtShared", "framework-graphics", + "framework-location", "framework-minus-apex-install-dependencies", + "framework-nfc", "framework-res", "FusedLocation", "fuseMedia.o", @@ -985,6 +951,7 @@ android_system_image { "LiveWallpapersPicker", "llndk.libraries.txt", "LocalTransport", + "lockagent", "ManagedProvisioning", "MediaProviderLegacy", "messaging", @@ -1037,29 +1004,18 @@ android_system_image { "WallpaperBackup", "WallpaperCropper", "webview", - // TODO(b/321000103): uncomment when visibility option for partitions is introduced - // "com.android.art", - // "com.android.btservices", - // "com.android.conscrypt", - // "com.android.healthfitness", - // "com.android.ondevicepersonalization", - // "com.android.permission", - // "com.android.sdkext", - // "com.android.uwb", - // "framework-minus-apex", ], }, lib32: { deps: [ "android.hardware.audio.service", - "mediaserver", "drmserver", + "mediaserver", ], }, lib64: { deps: [ - // TODO(b/321000103): uncomment when visibility option for partitions is introduced - // "boringssl_self_test", + "boringssl_self_test", "libgsi", "servicemanager", ], |