diff options
110 files changed, 1726 insertions, 1893 deletions
diff --git a/apex/com.google.aosp_cf.rros/Android.bp b/apex/com.google.aosp_cf.rros/Android.bp deleted file mode 100644 index cc325cb82..000000000 --- a/apex/com.google.aosp_cf.rros/Android.bp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -apex { - name: "com.google.aosp_cf.rros", - manifest: "apex_manifest.json", - key: "com.google.cf.apex.key", - certificate: ":com.google.cf.apex.certificate", - file_contexts: "file_contexts", - updatable: false, - soc_specific: true, - - // RROs shared across CF-derived devices - rros: [ - "cuttlefish_overlay_connectivity", - "cuttlefish_overlay_frameworks_base_core", - "cuttlefish_overlay_nfc", - "cuttlefish_overlay_settings_provider", - ], -} diff --git a/apex/com.google.aosp_cf.rros/apex_manifest.json b/apex/com.google.aosp_cf.rros/apex_manifest.json deleted file mode 100644 index faf4eef25..000000000 --- a/apex/com.google.aosp_cf.rros/apex_manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "com.google.aosp_cf.rros", - "version": 1 -} diff --git a/apex/com.google.aosp_cf.rros/file_contexts b/apex/com.google.aosp_cf.rros/file_contexts deleted file mode 100644 index cb7fd8dc3..000000000 --- a/apex/com.google.aosp_cf.rros/file_contexts +++ /dev/null @@ -1,2 +0,0 @@ -(/.*)? u:object_r:vendor_file:s0 -/overlay(/.*)? u:object_r:vendor_overlay_file:s0 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/device_config/Android.bp b/common/libs/device_config/Android.bp deleted file mode 100644 index d8307bd37..000000000 --- a/common/libs/device_config/Android.bp +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -cc_library { - name: "libcuttlefish_device_config_proto", - proto: { - export_proto_headers: true, - type: "full", - }, - srcs: [ - "device_config.proto", - ], - defaults: ["cuttlefish_host"], - target: { - darwin: { - enabled: true, - }, - }, -} - -cc_library_shared { - name: "libcuttlefish_device_config", - srcs: [ - "device_config.cpp", - "device_config_shared.cpp", - ], - shared_libs: [ - "libbase", - "liblog", - "libcuttlefish_device_config_proto", - "libcuttlefish_fs", - "libcuttlefish_utils", - "libprotobuf-cpp-full", - ], - target: { - host: { - srcs: [ - "host_device_config.cpp", - ], - shared_libs: [ - "libjsoncpp", - ], - static_libs: [ - "libcuttlefish_host_config", - ], - }, - darwin: { - enabled: true, - }, - android: { - srcs: [ - "guest_device_config.cpp", - ], - shared_libs: [ - "libcutils", - ], - }, - }, - export_include_dirs: ["."], - defaults: ["cuttlefish_host"], -} diff --git a/common/libs/device_config/device_config.proto b/common/libs/device_config/device_config.proto deleted file mode 100644 index 4a5a17016..000000000 --- a/common/libs/device_config/device_config.proto +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto3"; - -package cuttlefish; - -message DeviceConfig { - - message RILConfig { - string ipaddr = 1; - string gateway = 2; - string dns = 3; - string broadcast = 4; - int32 prefixlen = 5; - }; - - RILConfig ril_config = 1; - - message DisplayConfig { - int32 width = 1; - int32 height = 2; - int32 dpi = 3; - int32 refresh_rate_hz = 4; - }; - - repeated DisplayConfig display_config = 2; -} diff --git a/common/libs/device_config/device_config_shared.cpp b/common/libs/device_config/device_config_shared.cpp deleted file mode 100644 index ac4f8b46f..000000000 --- a/common/libs/device_config/device_config_shared.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "device_config.h" - -namespace cuttlefish { - -DeviceConfig GetDeviceConfig() { - const auto device_config_helper = cuttlefish::DeviceConfigHelper::Get(); - return device_config_helper->GetDeviceConfig(); -} - -} // namespace cuttlefish
\ No newline at end of file diff --git a/common/libs/device_config/guest_device_config.cpp b/common/libs/device_config/guest_device_config.cpp deleted file mode 100644 index 29be97372..000000000 --- a/common/libs/device_config/guest_device_config.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "device_config.h" - -#include <chrono> -#include <thread> - -#include <android-base/logging.h> -#include <cutils/properties.h> - -#include "common/libs/fs/shared_fd_stream.h" - -namespace cuttlefish { - -namespace { - -static constexpr int kRetries = 5; -static constexpr int kRetryDelaySeconds = 5; - -bool GetRawFromServer(DeviceConfig* data) { - auto port_property = "ro.boot.cuttlefish_config_server_port"; - auto port = property_get_int64(port_property, -1); - if (port < 0) { - LOG(ERROR) << "Unable to get config server port from property: " << - port_property; - return false; - } - -#ifdef CUTTLEFISH_HOST - LOG(FATAL) << "it is supposed to run in the guest"; -#endif - auto config_server = - SharedFD::VsockClient(2 /*host cid*/, static_cast<unsigned int>(port), - SOCK_STREAM, false /* it's guest */); - if (!config_server->IsOpen()) { - LOG(ERROR) << "Unable to connect to config server: " - << config_server->StrError(); - return false; - } - - SharedFDIstream stream(config_server); - if (!data->ParseFromIstream(&stream)) { - LOG(ERROR) << "Error reading from config server: " - << config_server->StrError(); - } - return true; -} - -} // namespace - -std::unique_ptr<DeviceConfigHelper> DeviceConfigHelper::Get() { - DeviceConfig device_config; - - int attempts_remaining = 1 + kRetries; - while (attempts_remaining > 0) { - if (GetRawFromServer(&device_config)) { - return std::unique_ptr<DeviceConfigHelper>( - new DeviceConfigHelper(device_config)); - } - - std::this_thread::sleep_for(std::chrono::seconds(kRetryDelaySeconds)); - - --attempts_remaining; - } - return nullptr; -} - -} // namespace cuttlefish diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp index c1d671ec7..2442787b2 100644 --- a/common/libs/fs/shared_fd.cpp +++ b/common/libs/fs/shared_fd.cpp @@ -397,7 +397,11 @@ SharedFD SharedFD::Dup(int unmanaged_fd) { bool SharedFD::Pipe(SharedFD* fd0, SharedFD* fd1) { int fds[2]; +#ifdef __linux__ + int rval = pipe2(fds, O_CLOEXEC); +#else int rval = pipe(fds); +#endif if (rval != -1) { (*fd0) = std::shared_ptr<FileInstance>(new FileInstance(fds[0], errno)); (*fd1) = std::shared_ptr<FileInstance>(new FileInstance(fds[1], errno)); diff --git a/common/libs/utils/Android.bp b/common/libs/utils/Android.bp index ee5d565e1..6ac56bfc7 100644 --- a/common/libs/utils/Android.bp +++ b/common/libs/utils/Android.bp @@ -30,6 +30,7 @@ cc_library { "network.cpp", "proc_file_utils.cpp", "shared_fd_flag.cpp", + "signals.cpp", "subprocess.cpp", "tcp_socket.cpp", "tee_logging.cpp", diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp index 5fa1e6ecf..23b36dd09 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> @@ -129,8 +130,12 @@ Result<void> EnsureDirectoryExists(const std::string& directory_path, << strerror(errno)); } + CF_EXPECTF(chmod(directory_path.c_str(), mode) == 0, + "Failed to set permission on {}: {}", directory_path, + strerror(errno)); + if (group_name != "") { - ChangeGroup(directory_path, group_name); + CF_EXPECT(ChangeGroup(directory_path, group_name)); } return {}; @@ -663,6 +668,54 @@ 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 << "|"; + LOG(DEBUG) << "lsof stderr:|" << lsof_err << "|"; + + std::smatch socket_state_match; + if (std::regex_search(lsof_out, socket_state_match, socket_state_regex)) { + if (socket_state_match.size() == 2) { + 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/common/libs/utils/signals.cpp b/common/libs/utils/signals.cpp new file mode 100644 index 000000000..ab6fb9388 --- /dev/null +++ b/common/libs/utils/signals.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/libs/utils/signals.h" + +#include <errno.h> +#include <signal.h> +#include <string.h> + +#include <vector> + +#include <android-base/logging.h> + +namespace cuttlefish { + +SignalMasker::SignalMasker(sigset_t signals) { + auto res = sigprocmask(SIG_SETMASK, &signals, &old_mask_); + auto err = errno; + CHECK(res == 0) << "Failed to set thread's blocked signal mask: " + << strerror(err); +} + +SignalMasker::~SignalMasker() { + auto res = sigprocmask(SIG_SETMASK, &old_mask_, NULL); + auto err = errno; + CHECK(res == 0) << "Failed to reset thread's blocked signal mask: " + << strerror(err); +} + +void ChangeSignalHandlers(void (*handler)(int), std::vector<int> signals) { + struct sigaction act; + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + for (auto signal: signals) { + sigaddset(&act.sa_mask, signal); + } + act.sa_flags = 0; + + for (auto signal : signals) { + sigaction(signal, &act, NULL); + } +} + +} // namespace cuttlefish + diff --git a/common/libs/device_config/device_config.h b/common/libs/utils/signals.h index 7655e49e1..4eb68437d 100644 --- a/common/libs/device_config/device_config.h +++ b/common/libs/utils/signals.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,31 +16,33 @@ #pragma once -#include <memory> -#include <string> -#include <vector> - -#include "common/libs/fs/shared_fd.h" -#include "device/google/cuttlefish/common/libs/device_config/device_config.pb.h" +#include <signal.h> -#ifdef CUTTLEFISH_HOST -#include "host/libs/config/cuttlefish_config.h" -#endif +#include <vector> namespace cuttlefish { -class DeviceConfigHelper { +/** + * Blocks signals for the current thread for the lifetime of the object. + * + * Provides a RAII interface to sigprocmask. + */ +class SignalMasker { public: - static std::unique_ptr<DeviceConfigHelper> Get(); - - const DeviceConfig& GetDeviceConfig() const { return device_config_; } - - bool SendDeviceConfig(SharedFD fd); + /** + * Blocks the given signals until the object is destroyed. + */ + SignalMasker(sigset_t signals); + SignalMasker(const SignalMasker&) = delete; + SignalMasker(SignalMasker&&) = delete; + SignalMasker operator=(const SignalMasker&) = delete; + SignalMasker operator=(SignalMasker&&) = delete; + ~SignalMasker(); private: - explicit DeviceConfigHelper(const DeviceConfig& device_config); - - DeviceConfig device_config_; + sigset_t old_mask_; }; +void ChangeSignalHandlers(void(*handler)(int), std::vector<int> signals); + } // namespace cuttlefish diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp index 40b13c3cf..2ef5957d3 100644 --- a/common/libs/utils/subprocess.cpp +++ b/common/libs/utils/subprocess.cpp @@ -230,7 +230,7 @@ int Subprocess::Wait(siginfo_t* infop, int options) { return -1; } *infop = {}; - auto retval = waitid(P_PID, pid_, infop, options); + auto retval = TEMP_FAILURE_RETRY(waitid(P_PID, pid_, infop, options)); // We don't want to wait twice for the same process bool exited = infop->si_code == CLD_EXITED || infop->si_code == CLD_DUMPED; bool reaped = !(options & WNOWAIT); diff --git a/guest/hals/ril/reference-ril/reference-ril.c b/guest/hals/ril/reference-ril/reference-ril.c index b7915e109..c946db0f4 100644 --- a/guest/hals/ril/reference-ril/reference-ril.c +++ b/guest/hals/ril/reference-ril/reference-ril.c @@ -918,6 +918,10 @@ static void requestOrSendDataCallList(int cid, RIL_Token *t) continue; i = ncid - 1; + + if (i >= n || i < 0) + goto error; + // Assume no error responses[i].status = 0; @@ -1054,14 +1058,21 @@ static void requestOrSendDataCallList(int cid, RIL_Token *t) &input, (responses) ? &responses[i].dnses : &sskip); // dns_prim_addr if (err < 0) goto error; + size_t response_size = 0; + RIL_Data_Call_Response_v11 *presponse = NULL; + if (responses) { + if (i >= n || i < 0) + goto error; + presponse = &responses[i]; + response_size = sizeof(*presponse); + } + if (t != NULL) RIL_onRequestComplete(*t, RIL_E_SUCCESS, - (responses != NULL) ? (responses + i) : responses, - sizeof(RIL_Data_Call_Response_v11)); + presponse, response_size); else RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, - responses, - n * sizeof(RIL_Data_Call_Response_v11)); + responses, n * response_size); at_response_free(p_response); return; diff --git a/host/commands/assemble_cvd/Android.bp b/host/commands/assemble_cvd/Android.bp index 9f07eab3b..b90a8be0b 100644 --- a/host/commands/assemble_cvd/Android.bp +++ b/host/commands/assemble_cvd/Android.bp @@ -40,6 +40,7 @@ cc_binary_host { "graphics_flags.cc", "kernel_module_parser.cc", "misc_info.cc", + "network_flags.cpp", "super_image_mixer.cc", "touchpad.cpp", "vendor_dlkm_utils.cc", @@ -51,8 +52,6 @@ cc_binary_host { "libbase", "libcuttlefish_allocd_utils", "libcuttlefish_command_util", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", "libcuttlefish_fs", "libcuttlefish_utils", "libext2_blkid", diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc index 37d931af0..0f73d4d42 100644 --- a/host/commands/assemble_cvd/assemble_cvd.cc +++ b/host/commands/assemble_cvd/assemble_cvd.cc @@ -304,6 +304,32 @@ Result<const CuttlefishConfig*> InitFilesystemAndCreateConfig( const std::string snapshot_path = FLAGS_snapshot_path; if (!snapshot_path.empty()) { CF_EXPECT(RestoreHostFiles(config.root_dir(), snapshot_path)); + + // Add a delimiter to each log file so that we can clearly tell what + // happened before vs after the restore. + const std::string snapshot_delimiter = + "\n\n\n" + "============ SNAPSHOT RESTORE POINT ============\n" + "Lines above are pre-snapshot.\n" + "Lines below are post-restore.\n" + "================================================\n" + "\n\n\n"; + for (const auto& instance : config.Instances()) { + const auto log_files = + CF_EXPECT(DirectoryContents(instance.PerInstanceLogPath(""))); + for (const auto& filename : log_files) { + if (filename == "." || filename == "..") { + continue; + } + const std::string path = instance.PerInstanceLogPath(filename); + auto fd = SharedFD::Open(path, O_WRONLY | O_APPEND); + CF_EXPECT(fd->IsOpen(), + "failed to open " << path << ": " << fd->StrError()); + const ssize_t n = WriteAll(fd, snapshot_delimiter); + CF_EXPECT(n == snapshot_delimiter.size(), + "failed to write to " << path << ": " << fd->StrError()); + } + } } // take the max value of modem_simulator_instance_number in each instance diff --git a/host/commands/assemble_cvd/bootconfig_args.cpp b/host/commands/assemble_cvd/bootconfig_args.cpp index 2792ee19a..baa1d9030 100644 --- a/host/commands/assemble_cvd/bootconfig_args.cpp +++ b/host/commands/assemble_cvd/bootconfig_args.cpp @@ -111,16 +111,10 @@ Result<std::unordered_map<std::string, std::string>> BootconfigArgsFromConfig( std::to_string(instance.tombstone_receiver_port()); } - const auto enable_confui = - (config.vm_manager() == QemuManager::name() ? 0 : 1); + const auto enable_confui = (config.vm_manager() == VmmMode::kQemu ? 0 : 1); bootconfig_args["androidboot.enable_confirmationui"] = std::to_string(enable_confui); - if (instance.config_server_port()) { - bootconfig_args["androidboot.cuttlefish_config_server_port"] = - std::to_string(instance.config_server_port()); - } - if (instance.audiocontrol_server_port()) { bootconfig_args["androidboot.vendor.audiocontrol.server.cid"] = std::to_string(instance.vsock_guest_cid()); @@ -178,7 +172,7 @@ Result<std::unordered_map<std::string, std::string>> BootconfigArgsFromConfig( if (instance.target_arch() == Arch::X86 || instance.target_arch() == Arch::X86_64) { bootconfig_args["androidboot.hypervisor.version"] = - "cf-" + config.vm_manager(); + "cf-" + ToString(config.vm_manager()); bootconfig_args["androidboot.hypervisor.vm.supported"] = "1"; } else { bootconfig_args["androidboot.hypervisor.vm.supported"] = "0"; diff --git a/host/commands/assemble_cvd/disk/gem5_image_unpacker.cpp b/host/commands/assemble_cvd/disk/gem5_image_unpacker.cpp index f4d91f876..b60bd39ba 100644 --- a/host/commands/assemble_cvd/disk/gem5_image_unpacker.cpp +++ b/host/commands/assemble_cvd/disk/gem5_image_unpacker.cpp @@ -26,7 +26,7 @@ namespace cuttlefish { Result<void> Gem5ImageUnpacker(const CuttlefishConfig& config, KernelRamdiskRepacker& /* dependency */) { - if (config.vm_manager() != vm_manager::Gem5Manager::name()) { + if (config.vm_manager() != VmmMode::kGem5) { return {}; } // TODO: b/281130788 - This should accept InstanceSpecific as an argument diff --git a/host/commands/assemble_cvd/disk/generate_persistent_bootconfig.cpp b/host/commands/assemble_cvd/disk/generate_persistent_bootconfig.cpp index 7960b631b..04ebafa87 100644 --- a/host/commands/assemble_cvd/disk/generate_persistent_bootconfig.cpp +++ b/host/commands/assemble_cvd/disk/generate_persistent_bootconfig.cpp @@ -78,7 +78,7 @@ Result<void> GeneratePersistentBootconfig( << bootconfig_path << "` failed:" << bootconfig_fd->StrError()); - if (config.vm_manager() == vm_manager::Gem5Manager::name()) { + if (config.vm_manager() == VmmMode::kGem5) { const off_t bootconfig_size_bytes_gem5 = AlignToPowerOf2(bytesWritten, PARTITION_SIZE_SHIFT); CF_EXPECT(bootconfig_fd->Truncate(bootconfig_size_bytes_gem5) == 0); diff --git a/host/commands/assemble_cvd/disk/initialize_instance_composite_disk.cc b/host/commands/assemble_cvd/disk/initialize_instance_composite_disk.cc index 6658a2bd8..ed6d36aa7 100644 --- a/host/commands/assemble_cvd/disk/initialize_instance_composite_disk.cc +++ b/host/commands/assemble_cvd/disk/initialize_instance_composite_disk.cc @@ -84,7 +84,7 @@ std::vector<ImagePartition> PersistentAPCompositeDiskConfig( } // namespace bool IsVmManagerQemu(const CuttlefishConfig& config) { - return config.vm_manager() == vm_manager::QemuManager::name(); + return config.vm_manager() == VmmMode::kQemu; } Result<void> InitializeInstanceCompositeDisk( const CuttlefishConfig& config, diff --git a/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp b/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp index 46d49a549..6268d8604 100644 --- a/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp +++ b/host/commands/assemble_cvd/disk/kernel_ramdisk_repacker.cpp @@ -136,7 +136,8 @@ class KernelRamdiskRepackerImpl : public KernelRamdiskRepacker { // large to be repacked. Skip repack of boot.img on Gem5, as we need to be // able to extract the ramdisk.img in a later stage and so this step must // not fail (..and the repacked kernel wouldn't be used anyway). - if (instance_.kernel_path().size() && config_.vm_manager() != Gem5Manager::name()) { + if (instance_.kernel_path().size() && + config_.vm_manager() != VmmMode::kGem5) { CF_EXPECT(RepackBootImage(avb_, instance_.kernel_path(), instance_.boot_image(), instance_.new_boot_image(), instance_.instance_dir()), "Failed to regenerate the boot image with the new kernel"); diff --git a/host/commands/assemble_cvd/disk_builder.cpp b/host/commands/assemble_cvd/disk_builder.cpp index b7f6b4198..d6ee26ba4 100644 --- a/host/commands/assemble_cvd/disk_builder.cpp +++ b/host/commands/assemble_cvd/disk_builder.cpp @@ -91,11 +91,11 @@ DiskBuilder DiskBuilder::CrosvmPath(std::string crosvm_path) && { return *this; } -DiskBuilder& DiskBuilder::VmManager(std::string vm_manager) & { +DiskBuilder& DiskBuilder::VmManager(VmmMode vm_manager) & { vm_manager_ = std::move(vm_manager); return *this; } -DiskBuilder DiskBuilder::VmManager(std::string vm_manager) && { +DiskBuilder DiskBuilder::VmManager(VmmMode vm_manager) && { vm_manager_ = std::move(vm_manager); return *this; } @@ -139,7 +139,7 @@ DiskBuilder DiskBuilder::ResumeIfPossible(bool resume_if_possible) && { Result<std::string> DiskBuilder::TextConfig() { std::ostringstream disk_conf; - CF_EXPECT(!vm_manager_.empty(), "Missing vm_manager"); + CF_EXPECT(vm_manager_ != VmmMode::kUnknown, "Missing vm_manager"); disk_conf << vm_manager_ << "\n"; CF_EXPECT(!partitions_.empty() ^ !entire_disk_.empty(), @@ -195,8 +195,8 @@ Result<bool> DiskBuilder::BuildCompositeDiskIfNecessary() { return false; } - CF_EXPECT(!vm_manager_.empty()); - if (vm_manager_ == vm_manager::CrosvmManager::name()) { + CF_EXPECT(vm_manager_ != VmmMode::kUnknown); + if (vm_manager_ == VmmMode::kCrosvm) { CF_EXPECT(!header_path_.empty(), "No header path"); CF_EXPECT(!footer_path_.empty(), "No footer path"); CreateCompositeDisk(partitions_, AbsolutePath(header_path_), diff --git a/host/commands/assemble_cvd/disk_builder.h b/host/commands/assemble_cvd/disk_builder.h index 424a5ad63..6b3be7bd0 100644 --- a/host/commands/assemble_cvd/disk_builder.h +++ b/host/commands/assemble_cvd/disk_builder.h @@ -42,8 +42,8 @@ class DiskBuilder { DiskBuilder& CrosvmPath(std::string crosvm_path) &; DiskBuilder CrosvmPath(std::string crosvm_path) &&; - DiskBuilder& VmManager(std::string vm_manager) &; - DiskBuilder VmManager(std::string vm_manager) &&; + DiskBuilder& VmManager(VmmMode vm_manager) &; + DiskBuilder VmManager(VmmMode vm_manager) &&; DiskBuilder& ConfigPath(std::string config_path) &; DiskBuilder ConfigPath(std::string config_path) &&; @@ -70,7 +70,7 @@ class DiskBuilder { std::string entire_disk_; std::string header_path_; std::string footer_path_; - std::string vm_manager_; + VmmMode vm_manager_ = VmmMode::kUnknown; std::string crosvm_path_; std::string config_path_; std::string composite_disk_path_; diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc index 6f23e0323..d7fac9688 100644 --- a/host/commands/assemble_cvd/disk_flags.cc +++ b/host/commands/assemble_cvd/disk_flags.cc @@ -625,7 +625,7 @@ Result<void> InitializeSdCard( CF_EXPECT(CreateBlankImage(instance.sdcard_path(), instance.blank_sdcard_image_mb(), "sdcard"), "Failed to create \"" << instance.sdcard_path() << "\""); - if (config.vm_manager() == "qemu_cli") { + if (config.vm_manager() == VmmMode::kQemu) { const std::string crosvm_path = instance.crosvm_binary(); CreateQcowOverlay(crosvm_path, instance.sdcard_path(), instance.sdcard_overlay_path()); @@ -927,8 +927,7 @@ Result<void> DiskImageFlagsVectorization(CuttlefishConfig& config, const Fetcher // Repacking a boot.img changes boot_image and vendor_boot_image paths const CuttlefishConfig& const_config = const_cast<const CuttlefishConfig&>(config); const CuttlefishConfig::InstanceSpecific const_instance = const_config.ForInstance(num); - if (cur_kernel_path.size() && - config.vm_manager() != Gem5Manager::name()) { + if (cur_kernel_path.size() && config.vm_manager() != VmmMode::kGem5) { const std::string new_boot_image_path = const_instance.PerInstancePath("boot_repacked.img"); // change the new flag value to corresponding instance @@ -1078,7 +1077,7 @@ Result<void> CreateDynamicDiskFiles(const FetcherConfig& fetcher_config, } // Gem5 Simulate per-instance what the bootloader would usually do // Since on other devices this runs every time, just do it here every time - if (config.vm_manager() == Gem5Manager::name()) { + if (config.vm_manager() == VmmMode::kGem5) { RepackGem5BootImage(instance.PerInstancePath("initrd.img"), instance.persistent_bootconfig_path(), config.assembly_dir(), instance.initramfs_path()); diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc index 6b86737f8..ca295fedb 100644 --- a/host/commands/assemble_cvd/flags.cc +++ b/host/commands/assemble_cvd/flags.cc @@ -52,6 +52,7 @@ #include "host/commands/assemble_cvd/flags_defaults.h" #include "host/commands/assemble_cvd/graphics_flags.h" #include "host/commands/assemble_cvd/misc_info.h" +#include "host/commands/assemble_cvd/network_flags.h" #include "host/commands/assemble_cvd/touchpad.h" #include "host/libs/config/config_flag.h" #include "host/libs/config/cuttlefish_config.h" @@ -543,7 +544,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]; } @@ -972,14 +973,27 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( // TODO(weihsu), b/250988697: moved bootconfig_supported and hctr2_supported // into each instance, but target_arch is still in todo // target_arch should be in instance later - auto vmm = GetVmManager(vm_manager_vec[0], guest_configs[0].target_arch); + auto vmm_mode = CF_EXPECT(ParseVmm(vm_manager_vec[0])); + auto vmm = GetVmManager(vmm_mode, guest_configs[0].target_arch); if (!vmm) { LOG(FATAL) << "Invalid vm_manager: " << vm_manager_vec[0]; } - tmp_config_obj.set_vm_manager(vm_manager_vec[0]); + tmp_config_obj.set_vm_manager(vmm_mode); tmp_config_obj.set_ap_vm_manager(vm_manager_vec[0] + "_openwrt"); - auto secure_hals_strs = android::base::Split(FLAGS_secure_hals, ","); + // TODO: schuffelen - fix behavior on riscv64 + if (guest_configs[0].target_arch == Arch::RiscV64) { + static constexpr char kRiscv64Secure[] = "keymint,gatekeeper,oemlock"; + SetCommandLineOptionWithMode("secure_hals", kRiscv64Secure, + google::FlagSettingMode::SET_FLAGS_DEFAULT); + } else { + static constexpr char kDefaultSecure[] = + "oemlock,guest_keymint_insecure,guest_gatekeeper_insecure"; + SetCommandLineOptionWithMode("secure_hals", kDefaultSecure, + google::FlagSettingMode::SET_FLAGS_DEFAULT); + } + auto secure_hals_strs = + android::base::Tokenize(FLAGS_secure_hals, ",:;|/\\+"); tmp_config_obj.set_secure_hals( std::set<std::string>(secure_hals_strs.begin(), secure_hals_strs.end())); auto secure_hals = tmp_config_obj.secure_hals(); @@ -1226,8 +1240,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); @@ -1362,7 +1376,6 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( instance.set_qemu_binary_dir(qemu_binary_dir_vec[instance_index]); // wifi, bluetooth, connectivity setup - instance.set_ril_dns(ril_dns_vec[instance_index]); instance.set_vhost_net(vhost_net_vec[instance_index]); @@ -1372,7 +1385,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( std::set<Arch> default_on_arch = {Arch::Arm64}; if (guest_configs[instance_index].vhost_user_vsock) { instance.set_vhost_user_vsock(true); - } else if (tmp_config_obj.vm_manager() == CrosvmManager::name() && + } else if (tmp_config_obj.vm_manager() == VmmMode::kCrosvm && default_on_arch.find( guest_configs[instance_index].target_arch) != default_on_arch.end()) { @@ -1382,7 +1395,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( } } else if (vhost_user_vsock_vec[instance_index] == kVhostUserVsockModeTrue) { - CHECK(tmp_config_obj.vm_manager() == CrosvmManager::name()) + CHECK(tmp_config_obj.vm_manager() == VmmMode::kCrosvm) << "For now, only crosvm supports vhost_user_vsock"; instance.set_vhost_user_vsock(true); } else if (vhost_user_vsock_vec[instance_index] == @@ -1503,6 +1516,9 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( instance.set_ethernet_bridge_name("cvd-ebr"); instance.set_mobile_tap_name(iface_config.mobile_tap.name); + CF_EXPECT(ConfigureNetworkSettings(ril_dns_vec[instance_index], + const_instance, instance)); + if (NetworkInterfaceExists(iface_config.non_bridged_wireless_tap.name) && tmp_config_obj.virtio_mac80211_hwsim()) { instance.set_use_bridged_wifi_tap(false); @@ -1540,15 +1556,15 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( instance.set_ethernet_ipv6(Ipv6ToString(ethernet_ipv6)); instance.set_tombstone_receiver_port(calc_vsock_port(6600)); - instance.set_audiocontrol_server_port(9410); /* OK to use the same port number across instances */ - instance.set_config_server_port(calc_vsock_port(6800)); + instance.set_audiocontrol_server_port( + 9410); /* OK to use the same port number across instances */ instance.set_lights_server_port(calc_vsock_port(6900)); // gpu related settings 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], - gpu_context_types_vec[instance_index], vm_manager_vec[instance_index], + gpu_context_types_vec[instance_index], vmm_mode, guest_configs[instance_index], instance)); calculated_gpu_mode_vec[instance_index] = gpu_mode_vec[instance_index]; @@ -1629,7 +1645,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( bool os_overlay = true; os_overlay &= !protected_vm_vec[instance_index]; // Gem5 already uses CoW wrappers around disk images - os_overlay &= vm_manager_vec[0] != Gem5Manager::name(); + os_overlay &= vmm_mode != VmmMode::kGem5; os_overlay &= FLAGS_use_overlay; if (os_overlay) { auto path = const_instance.PerInstancePath("overlay.img"); @@ -1640,13 +1656,14 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( bool persistent_disk = true; persistent_disk &= !protected_vm_vec[instance_index]; - persistent_disk &= vm_manager_vec[0] != Gem5Manager::name(); + persistent_disk &= vmm_mode != VmmMode::kGem5; if (persistent_disk) { #ifdef __APPLE__ const std::string persistent_composite_img_base = "persistent_composite.img"; #else - const bool is_vm_qemu_cli = (tmp_config_obj.vm_manager() == "qemu_cli"); + const bool is_vm_qemu_cli = + (tmp_config_obj.vm_manager() == VmmMode::kQemu); const std::string persistent_composite_img_base = is_vm_qemu_cli ? "persistent_composite_overlay.img" : "persistent_composite.img"; @@ -1662,7 +1679,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( sdcard &= use_sdcard_vec[instance_index]; sdcard &= !protected_vm_vec[instance_index]; if (sdcard) { - if (tmp_config_obj.vm_manager() == "qemu_cli") { + if (tmp_config_obj.vm_manager() == VmmMode::kQemu) { virtual_disk_paths.push_back(const_instance.sdcard_overlay_path()); } else { virtual_disk_paths.push_back(const_instance.sdcard_path()); @@ -1761,7 +1778,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( auto external_network_mode = CF_EXPECT( ParseExternalNetworkMode(device_external_network_vec[instance_index])); CF_EXPECT(external_network_mode == ExternalNetworkMode::kTap || - vm_manager_vec[instance_index] == QemuManager::name(), + vmm_mode == VmmMode::kQemu, "TODO(b/286284441): slirp only works on QEMU"); instance.set_external_network_mode(external_network_mode); @@ -1820,7 +1837,7 @@ Result<CuttlefishConfig> InitializeCuttlefishConfiguration( .ForEnvironment(environment_name); CF_EXPECT(CheckSnapshotCompatible( FLAGS_snapshot_compatible && - (tmp_config_obj.vm_manager() == CrosvmManager::name()) && + (tmp_config_obj.vm_manager() == VmmMode::kCrosvm) && instance_nums.size() == 1, calculated_gpu_mode_vec), "The set of flags is incompatible with snapshot"); @@ -2053,23 +2070,27 @@ Result<std::vector<GuestConfig>> GetGuestConfigAndSetDefaults() { } if (FLAGS_vm_manager == "") { if (IsHostCompatible(guest_configs[0].target_arch)) { - FLAGS_vm_manager = CrosvmManager::name(); + FLAGS_vm_manager = ToString(VmmMode::kCrosvm); } else { - FLAGS_vm_manager = QemuManager::name(); + FLAGS_vm_manager = ToString(VmmMode::kQemu); } } - // TODO(weihsu), b/250988697: - // Currently, all instances should use same vmm + std::vector<std::string> vm_manager_vec = android::base::Split(FLAGS_vm_manager, ","); + + // TODO(weihsu), b/250988697: + // Currently, all instances should use same vmm + auto vmm = CF_EXPECT(ParseVmm(vm_manager_vec[0])); + // get flag default values and store into map auto name_to_default_value = CurrentFlagsToDefaultValue(); - if (vm_manager_vec[0] == QemuManager::name()) { + if (vmm == VmmMode::kQemu) { CF_EXPECT(SetDefaultFlagsForQemu(guest_configs[0].target_arch, name_to_default_value)); - } else if (vm_manager_vec[0] == CrosvmManager::name()) { + } else if (vmm == VmmMode::kCrosvm) { CF_EXPECT(SetDefaultFlagsForCrosvm(guest_configs, name_to_default_value)); - } else if (vm_manager_vec[0] == Gem5Manager::name()) { + } else if (vmm == VmmMode::kGem5) { // TODO: Get the other architectures working if (guest_configs[0].target_arch != Arch::Arm64) { return CF_ERR("Gem5 only supports ARM64"); @@ -2078,7 +2099,7 @@ Result<std::vector<GuestConfig>> GetGuestConfigAndSetDefaults() { } else { return CF_ERR("Unknown Virtual Machine Manager: " << FLAGS_vm_manager); } - if (vm_manager_vec[0] != Gem5Manager::name()) { + if (vmm != VmmMode::kGem5) { // After SetCommandLineOptionWithMode in SetDefaultFlagsForCrosvm/Qemu, // default flag values changed, need recalculate name_to_default_value name_to_default_value = CurrentFlagsToDefaultValue(); diff --git a/host/commands/assemble_cvd/flags_defaults.h b/host/commands/assemble_cvd/flags_defaults.h index 34d69b38b..d787179b0 100644 --- a/host/commands/assemble_cvd/flags_defaults.h +++ b/host/commands/assemble_cvd/flags_defaults.h @@ -90,7 +90,7 @@ #define CF_DEFAULTS_USE_RANDOM_SERIAL false #define CF_DEFAULTS_SERIAL_NUMBER \ cuttlefish::ForCurrentInstance("CUTTLEFISHCVD") -#define CF_DEFAULTS_SECURE_HALS "keymint,gatekeeper,oemlock" +#define CF_DEFAULTS_SECURE_HALS CF_DEFAULTS_DYNAMIC_STRING #define CF_DEFAULTS_PROTECTED_VM false #define CF_DEFAULTS_MTE false diff --git a/host/commands/assemble_cvd/graphics_flags.cc b/host/commands/assemble_cvd/graphics_flags.cc index bd43ff097..d843f5118 100644 --- a/host/commands/assemble_cvd/graphics_flags.cc +++ b/host/commands/assemble_cvd/graphics_flags.cc @@ -24,9 +24,8 @@ #include <google/protobuf/text_format.h> #include "common/libs/utils/contains.h" +#include "common/libs/utils/subprocess.h" #include "host/libs/config/cuttlefish_config.h" -#include "host/libs/vm_manager/crosvm_manager.h" -#include "host/libs/vm_manager/qemu_manager.h" #ifdef __APPLE__ #define CF_UNUSED_ON_MACOS [[maybe_unused]] @@ -232,7 +231,7 @@ GetNeededVhostUserGpuHostRendererFeatures( #ifndef __APPLE__ Result<std::string> SelectGpuMode( - const std::string& gpu_mode_arg, const std::string& vm_manager, + const std::string& gpu_mode_arg, VmmMode vmm, const GuestConfig& guest_config, const gfxstream::proto::GraphicsAvailability& graphics_availability) { if (gpu_mode_arg != kGpuModeAuto && gpu_mode_arg != kGpuModeDrmVirgl && @@ -260,8 +259,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 (vmm == VmmMode::kQemu && !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, " @@ -290,8 +289,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 (vmm == VmmMode::kQemu && !UseQemuPrebuilt()) { + LOG(INFO) << "Not using QEMU prebuilt (QEMU 8+): selecting guest swiftshader"; return kGpuModeGuestSwiftshader; } } @@ -301,7 +300,7 @@ Result<std::string> SelectGpuMode( Result<bool> SelectGpuVhostUserMode(const std::string& gpu_mode, const std::string& gpu_vhost_user_mode_arg, - const std::string& vm_manager) { + VmmMode vmm) { CF_EXPECT(gpu_vhost_user_mode_arg == kGpuVhostUserModeAuto || gpu_vhost_user_mode_arg == kGpuVhostUserModeOn || gpu_vhost_user_mode_arg == kGpuVhostUserModeOff); @@ -313,9 +312,9 @@ Result<bool> SelectGpuVhostUserMode(const std::string& gpu_mode, return false; } - if (vm_manager != vm_manager::CrosvmManager::name()) { - LOG(INFO) << "GPU vhost user auto mode: not yet supported with " - << vm_manager << ". Not enabling vhost user gpu."; + if (vmm != VmmMode::kCrosvm) { + LOG(INFO) << "GPU vhost user auto mode: not yet supported with " << vmm + << ". Not enabling vhost user gpu."; return false; } @@ -490,12 +489,12 @@ static std::unordered_set<std::string> kSupportedGpuContexts{ 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, - std::string& gpu_context_types_arg, const std::string& vm_manager, + std::string& gpu_context_types_arg, VmmMode vmm, const GuestConfig& guest_config, CuttlefishConfig::MutableInstanceSpecific& instance) { #ifdef __APPLE__ (void)gpu_vhost_user_mode_arg; - (void)vm_manager; + (void)vmm; (void)guest_config; CF_EXPECT(gpu_mode_arg == kGpuModeAuto || gpu_mode_arg == kGpuModeGuestSwiftshader || @@ -521,10 +520,10 @@ Result<std::string> ConfigureGpuSettings( << graphics_availability.DebugString(); } - const std::string gpu_mode = CF_EXPECT(SelectGpuMode( - gpu_mode_arg, vm_manager, guest_config, graphics_availability)); - const bool enable_gpu_vhost_user = CF_EXPECT( - SelectGpuVhostUserMode(gpu_mode, gpu_vhost_user_mode_arg, vm_manager)); + const std::string gpu_mode = CF_EXPECT( + SelectGpuMode(gpu_mode_arg, vmm, guest_config, graphics_availability)); + const bool enable_gpu_vhost_user = + CF_EXPECT(SelectGpuVhostUserMode(gpu_mode, gpu_vhost_user_mode_arg, vmm)); if (gpu_mode == kGpuModeGfxstream || gpu_mode == kGpuModeGfxstreamGuestAngle || diff --git a/host/commands/assemble_cvd/graphics_flags.h b/host/commands/assemble_cvd/graphics_flags.h index 63a4df13e..83297243f 100644 --- a/host/commands/assemble_cvd/graphics_flags.h +++ b/host/commands/assemble_cvd/graphics_flags.h @@ -27,7 +27,7 @@ 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, - std::string& gpu_context_types_arg, const std::string& vm_manager, + std::string& gpu_context_types_arg, VmmMode vmm, 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/common/libs/device_config/host_device_config.cpp b/host/commands/assemble_cvd/network_flags.cpp index 3e977c177..055bd94b5 100644 --- a/common/libs/device_config/host_device_config.cpp +++ b/host/commands/assemble_cvd/network_flags.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,17 +14,14 @@ * limitations under the License. */ +#include "host/commands/assemble_cvd/network_flags.h" + #include <arpa/inet.h> -#include <android-base/logging.h> #include <ifaddrs.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include "device_config.h" +#include <android-base/logging.h> namespace cuttlefish { - namespace { uint8_t number_of_ones(unsigned long val) { @@ -128,64 +125,36 @@ class NetConfig { } }; -bool InitializeNetworkConfiguration(const CuttlefishConfig& cuttlefish_config, - DeviceConfig* device_config) { - auto instance = cuttlefish_config.ForDefaultInstance(); +} // namespace + +Result<void> ConfigureNetworkSettings( + const std::string& ril_dns_arg, + const CuttlefishConfig::InstanceSpecific& const_instance, + CuttlefishConfig::MutableInstanceSpecific& instance) { NetConfig netconfig; // Check the mobile bridge first; this was the traditional way we configured // the mobile interface. If that fails, it probably means we are using a // newer version of cuttlefish-common, and we can use the tap device // directly instead. - if (!netconfig.ObtainConfig(instance.mobile_bridge_name(), - instance.ril_dns())) { - if (!netconfig.ObtainConfig(instance.mobile_tap_name(), - instance.ril_dns())) { - LOG(ERROR) << "Unable to obtain the network configuration"; - return false; + if (!netconfig.ObtainConfig(const_instance.mobile_bridge_name(), + ril_dns_arg)) { + if (!netconfig.ObtainConfig(const_instance.mobile_tap_name(), + ril_dns_arg)) { + LOG(ERROR) << "Unable to get the network config. Assuming defaults."; + instance.set_ril_dns("8.8.8.8"); + instance.set_ril_gateway("10.0.2.2"); + instance.set_ril_ipaddr("10.0.2.15"); + instance.set_ril_prefixlen(24); } } - DeviceConfig::RILConfig* ril_config = device_config->mutable_ril_config(); - ril_config->set_ipaddr(netconfig.ril_ipaddr); - ril_config->set_gateway(netconfig.ril_gateway); - ril_config->set_dns(netconfig.ril_dns); - ril_config->set_broadcast(netconfig.ril_broadcast); - ril_config->set_prefixlen(netconfig.ril_prefixlen); - - return true; -} - -void InitializeScreenConfiguration(const CuttlefishConfig& cuttlefish_config, - DeviceConfig* device_config) { - auto instance = cuttlefish_config.ForDefaultInstance(); - for (const auto& cuttlefish_display_config : instance.display_configs()) { - DeviceConfig::DisplayConfig* device_display_config = - device_config->add_display_config(); - - device_display_config->set_width(cuttlefish_display_config.width); - device_display_config->set_height(cuttlefish_display_config.height); - device_display_config->set_dpi(cuttlefish_display_config.dpi); - device_display_config->set_refresh_rate_hz( - cuttlefish_display_config.refresh_rate_hz); - } -} - -} // namespace - -std::unique_ptr<DeviceConfigHelper> DeviceConfigHelper::Get() { - auto cuttlefish_config = CuttlefishConfig::Get(); - if (!cuttlefish_config) { - return nullptr; - } - - DeviceConfig device_config; - if (!InitializeNetworkConfiguration(*cuttlefish_config, &device_config)) { - return nullptr; - } - InitializeScreenConfiguration(*cuttlefish_config, &device_config); + instance.set_ril_broadcast(netconfig.ril_broadcast); + instance.set_ril_dns(netconfig.ril_dns); + instance.set_ril_gateway(netconfig.ril_gateway); + instance.set_ril_ipaddr(netconfig.ril_ipaddr); + instance.set_ril_prefixlen(netconfig.ril_prefixlen); - return std::unique_ptr<DeviceConfigHelper>( - new DeviceConfigHelper(device_config)); + return {}; } -} // namespace cuttlefish +} // namespace cuttlefish
\ No newline at end of file diff --git a/common/libs/device_config/device_config_shared.h b/host/commands/assemble_cvd/network_flags.h index 3176917df..1de720e47 100644 --- a/common/libs/device_config/device_config_shared.h +++ b/host/commands/assemble_cvd/network_flags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #pragma once -#include "device/google/cuttlefish/common/libs/device_config/device_config.pb.h" +#include "common/libs/utils/result.h" +#include "host/libs/config/cuttlefish_config.h" namespace cuttlefish { -// Minimal version to share with Goldfish which doesn't include additional -// Cuttlefish headers. -// -// TODO(natsu): switch ranchu hwcomposer to drm for display discovery. -DeviceConfig GetDeviceConfig(); +Result<void> ConfigureNetworkSettings( + const std::string& ril_dns_arg, + const CuttlefishConfig::InstanceSpecific& const_instance, + CuttlefishConfig::MutableInstanceSpecific& instance); } // namespace cuttlefish
\ No newline at end of file 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/config_server/Android.bp b/host/commands/config_server/Android.bp deleted file mode 100644 index b567bd902..000000000 --- a/host/commands/config_server/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -cc_binary { - name: "config_server", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "libjsoncpp", - "liblog", - "libcuttlefish_utils", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", - "libprotobuf-cpp-full" - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - ], - defaults: ["cuttlefish_host"], -} diff --git a/host/commands/cvd_env/Android.bp b/host/commands/cvd_env/Android.bp index 5ab3f898f..58c485208 100644 --- a/host/commands/cvd_env/Android.bp +++ b/host/commands/cvd_env/Android.bp @@ -24,7 +24,6 @@ cc_binary_host { ], shared_libs: [ "libbase", - "libcuttlefish_device_config", "libcuttlefish_utils", "libgrpc++", "libjsoncpp", diff --git a/host/commands/health/Android.bp b/host/commands/health/Android.bp index c580152b1..afeddca96 100644 --- a/host/commands/health/Android.bp +++ b/host/commands/health/Android.bp @@ -25,8 +25,6 @@ cc_binary { shared_libs: [ "libbase", "libcuttlefish_command_util", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", "libcuttlefish_fs", "libcuttlefish_utils", "libfruit", diff --git a/host/commands/host_bugreport/Android.bp b/host/commands/host_bugreport/Android.bp index 6880fba0b..24c9b68ff 100644 --- a/host/commands/host_bugreport/Android.bp +++ b/host/commands/host_bugreport/Android.bp @@ -25,9 +25,7 @@ cc_binary { ], shared_libs: [ "libbase", - "libcuttlefish_command_util", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", + "libcuttlefish_command_util", "libcuttlefish_fs", "libcuttlefish_utils", "libfruit", diff --git a/host/commands/log_tee/Android.bp b/host/commands/log_tee/Android.bp index 7c1267b2b..c17d71e14 100644 --- a/host/commands/log_tee/Android.bp +++ b/host/commands/log_tee/Android.bp @@ -24,9 +24,7 @@ cc_binary { ], shared_libs: [ "libbase", - "libcuttlefish_command_util", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", + "libcuttlefish_command_util", "libcuttlefish_fs", "libcuttlefish_utils", "libfruit", 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/metrics/events.cc b/host/commands/metrics/events.cc index 3d3a7c14a..ec0147e9a 100644 --- a/host/commands/metrics/events.cc +++ b/host/commands/metrics/events.cc @@ -94,10 +94,10 @@ cuttlefish::MetricsEvent::VmmType GetVmmManager() { auto config = cuttlefish::CuttlefishConfig::Get(); CHECK(config) << "Could not open cuttlefish config"; auto vmm = config->vm_manager(); - if (vmm == cuttlefish::vm_manager::CrosvmManager::name()) { + if (vmm == cuttlefish::VmmMode::kCrosvm) { return cuttlefish::MetricsEvent::CUTTLEFISH_VMM_TYPE_CROSVM; } - if (vmm == cuttlefish::vm_manager::QemuManager::name()) { + if (vmm == cuttlefish::VmmMode::kQemu) { return cuttlefish::MetricsEvent::CUTTLEFISH_VMM_TYPE_QEMU; } return cuttlefish::MetricsEvent::CUTTLEFISH_VMM_TYPE_UNSPECIFIED; diff --git a/host/commands/modem_simulator/Android.bp b/host/commands/modem_simulator/Android.bp index c0d03718e..0f684e825 100644 --- a/host/commands/modem_simulator/Android.bp +++ b/host/commands/modem_simulator/Android.bp @@ -43,8 +43,6 @@ cc_defaults { "libbase", "libjsoncpp", "libnl", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", ], static_libs: [ "libcuttlefish_host_config", diff --git a/host/commands/modem_simulator/cf_device_config.cpp b/host/commands/modem_simulator/cf_device_config.cpp index 1201db51a..58a740a23 100644 --- a/host/commands/modem_simulator/cf_device_config.cpp +++ b/host/commands/modem_simulator/cf_device_config.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "common/libs/device_config/device_config.h" #include "host/commands/modem_simulator/device_config.h" #include "host/libs/config/cuttlefish_config.h" @@ -45,30 +44,21 @@ std::string DeviceConfig::DefaultHostArtifactsPath(const std::string& file) { } std::string DeviceConfig::ril_address_and_prefix() { - auto device_config_helper = cuttlefish::DeviceConfigHelper::Get(); - if (!device_config_helper) { - return "10.0.2.15/24"; - } - const auto& ril_config = device_config_helper->GetDeviceConfig().ril_config(); - return ril_config.ipaddr() + "/" + std::to_string(ril_config.prefixlen()); + auto config = cuttlefish::CuttlefishConfig::Get(); + auto instance = config->ForDefaultInstance(); + return instance.ril_ipaddr() + "/" + std::to_string(instance.ril_prefixlen()); }; std::string DeviceConfig::ril_gateway() { - auto device_config_helper = cuttlefish::DeviceConfigHelper::Get(); - if (!device_config_helper) { - return "10.0.2.2"; - } - const auto& ril_config = device_config_helper->GetDeviceConfig().ril_config(); - return ril_config.gateway(); + auto config = cuttlefish::CuttlefishConfig::Get(); + auto instance = config->ForDefaultInstance(); + return instance.ril_gateway(); } std::string DeviceConfig::ril_dns() { - auto device_config_helper = cuttlefish::DeviceConfigHelper::Get(); - if (!device_config_helper) { - return "8.8.8.8"; - } - const auto& ril_config = device_config_helper->GetDeviceConfig().ril_config(); - return ril_config.dns(); + auto config = cuttlefish::CuttlefishConfig::Get(); + auto instance = config->ForDefaultInstance(); + return instance.ril_dns(); } std::ifstream DeviceConfig::open_ifstream_crossplat(const char* filename) { diff --git a/host/commands/modem_simulator/main.cpp b/host/commands/modem_simulator/main.cpp index a979c3662..c22d11d77 100644 --- a/host/commands/modem_simulator/main.cpp +++ b/host/commands/modem_simulator/main.cpp @@ -92,7 +92,7 @@ int ModemSimulatorMain(int argc, char** argv) { } auto nvram_config = NvramConfig::Get(); - auto nvram_config_file = nvram_config->ConfigFileLocation(); + const auto nvram_config_file = nvram_config->ConfigFileLocation(); // Start channel monitor, wait for RIL to connect int32_t modem_id = 0; diff --git a/host/commands/modem_simulator/network_service.cpp b/host/commands/modem_simulator/network_service.cpp index 25a2f97d4..03d0a59a9 100644 --- a/host/commands/modem_simulator/network_service.cpp +++ b/host/commands/modem_simulator/network_service.cpp @@ -160,18 +160,15 @@ void NetworkService::InitializeNetworkOperator() { current_operator_numeric_ = operator_list_.begin()->numeric; operator_list_.begin()->operator_state = NetworkOperator::OPER_STATE_CURRENT; } else if (oper_selection_mode_ == OperatorSelectionMode::OPER_SELECTION_MANUAL_AUTOMATIC) { - auto iter = operator_list_.begin(); - for (; iter != operator_list_.end(); ++iter) { - if (iter->numeric == current_operator_numeric_) { - break; + for (auto& iter : operator_list_) { + if (iter.numeric == current_operator_numeric_) { + iter.operator_state = NetworkOperator::OPER_STATE_CURRENT; + return; } } - if (iter == operator_list_.end()) { - current_operator_numeric_ = operator_list_.begin()->numeric; - operator_list_.begin()->operator_state = NetworkOperator::OPER_STATE_CURRENT; - } else { - iter->operator_state = NetworkOperator::OPER_STATE_CURRENT; - } + current_operator_numeric_ = operator_list_.begin()->numeric; + operator_list_.begin()->operator_state = + NetworkOperator::OPER_STATE_CURRENT; } } diff --git a/host/commands/modem_simulator/nvram_config.cpp b/host/commands/modem_simulator/nvram_config.cpp index 22b337329..021ba7391 100644 --- a/host/commands/modem_simulator/nvram_config.cpp +++ b/host/commands/modem_simulator/nvram_config.cpp @@ -45,11 +45,9 @@ static constexpr bool kDefaultEmergencyMode = false; * Returns nullptr if there was an error loading from file */ NvramConfig* NvramConfig::BuildConfigImpl(size_t num_instances, int sim_type) { - auto nvram_config_path = - cuttlefish::modem::DeviceConfig::PerInstancePath("modem_nvram.json"); - auto ret = new NvramConfig(num_instances, sim_type); if (ret) { + const auto nvram_config_path = ConfigFileLocation(); if (!cuttlefish::FileExists(nvram_config_path) || !cuttlefish::FileHasContent(nvram_config_path.c_str())) { ret->InitDefaultNvramConfig(); @@ -82,7 +80,7 @@ void NvramConfig::InitNvramConfigService(size_t num_instances, int sim_type) { void NvramConfig::SaveToFile() { auto nvram_config = Get(); - auto nvram_config_file = nvram_config->ConfigFileLocation(); + const auto nvram_config_file = ConfigFileLocation(); nvram_config->SaveToFile(nvram_config_file); } @@ -101,7 +99,7 @@ NvramConfig::InstanceSpecific NvramConfig::ForInstance(int num) const { return InstanceSpecific(this, std::to_string(num)); } -std::string NvramConfig::ConfigFileLocation() const { +/* static */ std::string NvramConfig::ConfigFileLocation() { return cuttlefish::AbsolutePath( cuttlefish::modem::DeviceConfig::PerInstancePath("modem_nvram.json")); } diff --git a/host/commands/modem_simulator/nvram_config.h b/host/commands/modem_simulator/nvram_config.h index fc51c80fb..bf4370a0a 100644 --- a/host/commands/modem_simulator/nvram_config.h +++ b/host/commands/modem_simulator/nvram_config.h @@ -32,7 +32,7 @@ class NvramConfig { ~NvramConfig(); NvramConfig& operator=(NvramConfig&&); - std::string ConfigFileLocation() const; + static std::string ConfigFileLocation(); // Saves the configuration object in a file bool SaveToFile(const std::string& file) const; diff --git a/host/commands/run_cvd/Android.bp b/host/commands/run_cvd/Android.bp index 0f7217d6c..faacebb10 100644 --- a/host/commands/run_cvd/Android.bp +++ b/host/commands/run_cvd/Android.bp @@ -41,7 +41,7 @@ cc_binary_host { "launch/pica.cpp", "launch/screen_recording_server.cpp", "launch/secure_env.cpp", - "launch/secure_env_files.cpp", + "launch/snapshot_control_files.cpp", "launch/webrtc_recorder.cpp", "launch/streamer.cpp", "launch/netsim_server.cpp", @@ -55,8 +55,6 @@ cc_binary_host { ], shared_libs: [ "libbase", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", "libcuttlefish_fs", "libcuttlefish_kernel_log_monitor_utils", "libcuttlefish_run_cvd_proto", @@ -97,7 +95,6 @@ cc_binary_host { "gnss_grpc_proxy", ], srcs: [ - "launch/config_server.cpp", "launch/mcu.cpp", "launch/modem.cpp", "launch/open_wrt.cpp", diff --git a/host/commands/run_cvd/boot_state_machine.cc b/host/commands/run_cvd/boot_state_machine.cc index 67060e07a..fd858a40e 100644 --- a/host/commands/run_cvd/boot_state_machine.cc +++ b/host/commands/run_cvd/boot_state_machine.cc @@ -21,6 +21,7 @@ #include <memory> #include <thread> +#include <android-base/file.h> #include <android-base/logging.h> #include <gflags/gflags.h> @@ -43,72 +44,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 +121,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 +155,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 +176,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 +207,72 @@ 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."; + + auto SubtoolPath = [](const std::string& subtool_name) { + auto my_own_dir = android::base::GetExecutableDirectory(); + std::stringstream subtool_path_stream; + subtool_path_stream << my_own_dir << "/" << subtool_name; + auto subtool_path = subtool_path_stream.str(); + if (my_own_dir.empty() || !FileExists(subtool_path)) { + return HostBinaryPath(subtool_name); + } + return subtool_path; + }; + const auto adb_bin_path = SubtoolPath("adb"); + CHECK(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), + "wait-for-device"}, + SubprocessOptions(), WEXITED) + .ok()) + << "Failed to suspend bluetooth manager."; + CHECK(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), + "shell", "cmd", "bluetooth_manager", "enable"}, + SubprocessOptions(), WEXITED) + .ok()); + CHECK(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), + "shell", "cmd", "uwb", "enable-uwb"}, + SubprocessOptions(), WEXITED) + .ok()); + // 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 +280,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 +307,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 +396,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 +418,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/launch/config_server.cpp b/host/commands/run_cvd/launch/config_server.cpp deleted file mode 100644 index 3973de391..000000000 --- a/host/commands/run_cvd/launch/config_server.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "host/commands/run_cvd/launch/launch.h" - -#include "common/libs/utils/result.h" -#include "host/libs/config/command_source.h" -#include "host/libs/config/known_paths.h" - -namespace cuttlefish { - -Result<MonitorCommand> ConfigServer( - const CuttlefishConfig::InstanceSpecific& instance) { - auto port = instance.config_server_port(); - auto socket = - SharedFD::VsockServer(port, SOCK_STREAM, - instance.vhost_user_vsock() - ? std::make_optional(instance.vsock_guest_cid()) - : std::nullopt); - CF_EXPECTF(socket->IsOpen(), "Can't configuration server socket: '{}'", - socket->StrError()); - return Command(ConfigServerBinary()).AddParameter("-server_fd=", socket); -} - -} // namespace cuttlefish diff --git a/host/commands/run_cvd/launch/launch.h b/host/commands/run_cvd/launch/launch.h index 55a2326be..4d939844a 100644 --- a/host/commands/run_cvd/launch/launch.h +++ b/host/commands/run_cvd/launch/launch.h @@ -26,7 +26,7 @@ #include "host/commands/run_cvd/launch/auto_cmd.h" #include "host/commands/run_cvd/launch/grpc_socket_creator.h" #include "host/commands/run_cvd/launch/log_tee_creator.h" -#include "host/commands/run_cvd/launch/secure_env_files.h" +#include "host/commands/run_cvd/launch/snapshot_control_files.h" #include "host/commands/run_cvd/launch/webrtc_recorder.h" #include "host/commands/run_cvd/launch/wmediumd_server.h" #include "host/libs/config/command_source.h" @@ -65,8 +65,6 @@ Result<std::optional<MonitorCommand>> CasimirControlServer( const CuttlefishConfig&, const CuttlefishConfig::InstanceSpecific&, GrpcSocketCreator&); -Result<MonitorCommand> ConfigServer(const CuttlefishConfig::InstanceSpecific&); - Result<std::optional<MonitorCommand>> ConsoleForwarder( const CuttlefishConfig::InstanceSpecific&); std::string ConsoleInfo(const CuttlefishConfig::InstanceSpecific&); @@ -113,7 +111,7 @@ Result<std::optional<MonitorCommand>> ScreenRecordingServer(GrpcSocketCreator&); Result<MonitorCommand> SecureEnv(const CuttlefishConfig&, const CuttlefishConfig::InstanceSpecific&, - AutoSecureEnvFiles::Type&, + AutoSnapshotControlFiles::Type&, KernelLogPipeProvider&); Result<MonitorCommand> TombstoneReceiver( diff --git a/host/commands/run_cvd/launch/open_wrt.cpp b/host/commands/run_cvd/launch/open_wrt.cpp index 0ca4a9cc6..289d63f7a 100644 --- a/host/commands/run_cvd/launch/open_wrt.cpp +++ b/host/commands/run_cvd/launch/open_wrt.cpp @@ -86,11 +86,12 @@ class OpenWrt : public CommandSource { wifi_tap = ap_cmd.AddTap(instance_.wifi_tap_name()); } - if (IsRestoring(config_)) { - const std::string snapshot_dir = config_.snapshot_path(); - CF_EXPECT(ap_cmd.SetToRestoreFromSnapshot(snapshot_dir, instance_.id(), - "_openwrt")); - } + // TODO(khei): Enable restore once open_wrt instance restoring is fixed + // if (IsRestoring(config_)) { + // const std::string snapshot_dir = config_.snapshot_path(); + // CF_EXPECT(ap_cmd.SetToRestoreFromSnapshot(snapshot_dir, instance_.id(), + // "_openwrt")); + //} /* TODO(kwstephenkim): delete this code when Minidroid completely disables * the AP VM itself @@ -123,7 +124,7 @@ class OpenWrt : public CommandSource { auto openwrt_args = OpenwrtArgsFromConfig(instance_); switch (instance_.ap_boot_flow()) { case APBootFlow::Grub: - if (config_.vm_manager() == "qemu_cli") { + if (config_.vm_manager() == VmmMode::kQemu) { ap_cmd.AddReadWriteDisk( instance_.persistent_ap_composite_overlay_path()); } else { @@ -156,7 +157,7 @@ class OpenWrt : public CommandSource { std::string Name() const override { return "OpenWrt"; } bool Enabled() const override { return instance_.ap_boot_flow() != APBootFlow::None && - config_.vm_manager() == vm_manager::CrosvmManager::name(); + config_.vm_manager() == VmmMode::kCrosvm; } private: diff --git a/host/commands/run_cvd/launch/secure_env.cpp b/host/commands/run_cvd/launch/secure_env.cpp index 23a5b040d..5f499fad7 100644 --- a/host/commands/run_cvd/launch/secure_env.cpp +++ b/host/commands/run_cvd/launch/secure_env.cpp @@ -24,7 +24,7 @@ #include <fruit/fruit.h> #include "common/libs/utils/result.h" -#include "host/commands/run_cvd/launch/secure_env_files.h" +#include "host/commands/run_cvd/launch/snapshot_control_files.h" #include "host/libs/config/command_source.h" #include "host/libs/config/known_paths.h" @@ -33,13 +33,13 @@ namespace cuttlefish { Result<MonitorCommand> SecureEnv( const CuttlefishConfig& config, const CuttlefishConfig::InstanceSpecific& instance, - AutoSecureEnvFiles::Type& secure_env_files, + AutoSnapshotControlFiles::Type& snapshot_control_files, KernelLogPipeProvider& kernel_log_pipe_provider) { Command command(SecureEnvBinary()); command.AddParameter("-confui_server_fd=", - secure_env_files->confui_server_fd); + snapshot_control_files->confui_server_fd); command.AddParameter("-snapshot_control_fd=", - secure_env_files->snapshot_control_fd); + snapshot_control_files->secure_env_snapshot_control_fd); std::vector<std::string> fifo_paths = { instance.PerInstanceInternalPath("keymaster_fifo_vm.in"), diff --git a/host/commands/run_cvd/launch/secure_env_files.cpp b/host/commands/run_cvd/launch/snapshot_control_files.cpp index 2a88d4b71..d9fc80b35 100644 --- a/host/commands/run_cvd/launch/secure_env_files.cpp +++ b/host/commands/run_cvd/launch/snapshot_control_files.cpp @@ -13,13 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "host/commands/run_cvd/launch/secure_env_files.h" +#include "host/commands/run_cvd/launch/snapshot_control_files.h" #include <unistd.h> namespace cuttlefish { -Result<SecureEnvFiles> SecureEnvFiles::Create( +Result<SnapshotControlFiles> SnapshotControlFiles::Create( const CuttlefishConfig::InstanceSpecific& instance) { auto confui_socket_path = instance.PerInstanceInternalUdsPath("confui_sign.sock"); @@ -34,7 +34,7 @@ Result<SecureEnvFiles> SecureEnvFiles::Create( CF_EXPECT(SharedFD::SocketPair(AF_UNIX, SOCK_STREAM, 0, &snapshot_control_fd, &run_cvd_to_secure_env_fd)); - return SecureEnvFiles{ + return SnapshotControlFiles{ confui_server_fd, snapshot_control_fd, run_cvd_to_secure_env_fd, diff --git a/host/commands/run_cvd/launch/secure_env_files.h b/host/commands/run_cvd/launch/snapshot_control_files.h index ed70ced66..dc0b391b0 100644 --- a/host/commands/run_cvd/launch/secure_env_files.h +++ b/host/commands/run_cvd/launch/snapshot_control_files.h @@ -24,15 +24,15 @@ namespace cuttlefish { -struct SecureEnvFiles { +struct SnapshotControlFiles { SharedFD confui_server_fd; - SharedFD snapshot_control_fd; + SharedFD secure_env_snapshot_control_fd; SharedFD run_cvd_to_secure_env_fd; - static Result<SecureEnvFiles> Create( + static Result<SnapshotControlFiles> Create( const CuttlefishConfig::InstanceSpecific&); }; -using AutoSecureEnvFiles = AutoSetup<SecureEnvFiles::Create>; +using AutoSnapshotControlFiles = AutoSetup<SnapshotControlFiles::Create>; } // namespace cuttlefish diff --git a/host/commands/run_cvd/launch/streamer.cpp b/host/commands/run_cvd/launch/streamer.cpp index 3334efdf1..b27fb7bd8 100644 --- a/host/commands/run_cvd/launch/streamer.cpp +++ b/host/commands/run_cvd/launch/streamer.cpp @@ -94,7 +94,7 @@ class StreamerSockets : public virtual SetupFeature { : config_(config), instance_(instance) {} void AppendCommandArguments(Command& cmd) { - if (config_.vm_manager() == vm_manager::QemuManager::name()) { + if (config_.vm_manager() == VmmMode::kQemu) { cmd.AddParameter("-write_virtio_input"); } if (!touch_servers_.empty()) { @@ -126,7 +126,7 @@ class StreamerSockets : public virtual SetupFeature { // SetupFeature std::string Name() const override { return "StreamerSockets"; } bool Enabled() const override { - bool is_qemu = config_.vm_manager() == vm_manager::QemuManager::name(); + bool is_qemu = config_.vm_manager() == VmmMode::kQemu; bool is_accelerated = instance_.gpu_mode() != kGpuModeGuestSwiftshader; return !(is_qemu && is_accelerated); } @@ -261,7 +261,7 @@ class WebRtcServer : public virtual CommandSource, webrtc.UnsetFromEnvironment("http_proxy"); sockets_.AppendCommandArguments(webrtc); - if (config_.vm_manager() == vm_manager::CrosvmManager::name()) { + if (config_.vm_manager() == VmmMode::kCrosvm) { webrtc.AddParameter("-switches_fd=", switches_server_); } // Currently there is no way to ensure the signaling server will already @@ -300,7 +300,7 @@ class WebRtcServer : public virtual CommandSource, } Result<void> ResultSetup() override { - if (config_.vm_manager() == vm_manager::CrosvmManager::name()) { + if (config_.vm_manager() == VmmMode::kCrosvm) { switches_server_ = CreateUnixInputServer(instance_.switches_socket_path()); CF_EXPECT(switches_server_->IsOpen(), switches_server_->StrError()); diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc index cf5e5754d..05bd8d2ac 100644 --- a/host/commands/run_cvd/main.cc +++ b/host/commands/run_cvd/main.cc @@ -127,7 +127,6 @@ fruit::Component<> runCvdComponent( .bindInstance(*environment) #ifdef __linux__ .install(AutoCmd<AutomotiveProxyService>::Component) - .install(AutoCmd<ConfigServer>::Component) .install(AutoCmd<ModemSimulator>::Component) .install(AutoCmd<TombstoneReceiver>::Component) .install(McuComponent) @@ -164,7 +163,7 @@ fruit::Component<> runCvdComponent( .install(RootCanalComponent) .install(AutoCmd<Casimir>::Component) .install(NetsimServerComponent) - .install(AutoSecureEnvFiles::Component) + .install(AutoSnapshotControlFiles::Component) .install(AutoCmd<SecureEnv>::Component) .install(serverLoopComponent) .install(WebRtcRecorderComponent) diff --git a/host/commands/run_cvd/server_loop.cpp b/host/commands/run_cvd/server_loop.cpp index abe4e65e8..81fd0ee6f 100644 --- a/host/commands/run_cvd/server_loop.cpp +++ b/host/commands/run_cvd/server_loop.cpp @@ -18,7 +18,6 @@ #include <fruit/fruit.h> -#include "host/commands/run_cvd/launch/secure_env_files.h" #include "host/commands/run_cvd/launch/webrtc_recorder.h" #include "host/commands/run_cvd/server_loop_impl.h" #include "host/libs/config/cuttlefish_config.h" @@ -29,11 +28,11 @@ namespace cuttlefish { ServerLoop::~ServerLoop() = default; -fruit::Component<fruit::Required<const CuttlefishConfig, - const CuttlefishConfig::InstanceSpecific, - AutoSecureEnvFiles::Type, - WebRtcRecorder>, - ServerLoop> +fruit::Component< + fruit::Required<const CuttlefishConfig, + const CuttlefishConfig::InstanceSpecific, + AutoSnapshotControlFiles::Type, WebRtcRecorder>, + ServerLoop> serverLoopComponent() { using run_cvd_impl::ServerLoopImpl; return fruit::createComponent() diff --git a/host/commands/run_cvd/server_loop.h b/host/commands/run_cvd/server_loop.h index 9c28dfe2f..0ceeee0cb 100644 --- a/host/commands/run_cvd/server_loop.h +++ b/host/commands/run_cvd/server_loop.h @@ -18,7 +18,7 @@ #include <fruit/fruit.h> -#include "host/commands/run_cvd/launch/secure_env_files.h" +#include "host/commands/run_cvd/launch/snapshot_control_files.h" #include "host/commands/run_cvd/launch/webrtc_recorder.h" #include "host/libs/config/cuttlefish_config.h" @@ -30,10 +30,10 @@ class ServerLoop { virtual Result<void> Run() = 0; }; -fruit::Component<fruit::Required<const CuttlefishConfig, - const CuttlefishConfig::InstanceSpecific, - AutoSecureEnvFiles::Type, - WebRtcRecorder>, - ServerLoop> +fruit::Component< + fruit::Required<const CuttlefishConfig, + const CuttlefishConfig::InstanceSpecific, + AutoSnapshotControlFiles::Type, WebRtcRecorder>, + ServerLoop> serverLoopComponent(); } diff --git a/host/commands/run_cvd/server_loop_impl.cpp b/host/commands/run_cvd/server_loop_impl.cpp index 8506245cf..f5caa7c2d 100644 --- a/host/commands/run_cvd/server_loop_impl.cpp +++ b/host/commands/run_cvd/server_loop_impl.cpp @@ -63,11 +63,11 @@ bool ServerLoopImpl::CreateQcowOverlay(const std::string& crosvm_path, ServerLoopImpl::ServerLoopImpl( const CuttlefishConfig& config, const CuttlefishConfig::InstanceSpecific& instance, - AutoSecureEnvFiles::Type& secure_env_files, + AutoSnapshotControlFiles::Type& snapshot_control_files, WebRtcRecorder& webrtc_recorder) : config_(config), instance_(instance), - secure_env_files_(secure_env_files), + snapshot_control_files_(snapshot_control_files), webrtc_recorder_(webrtc_recorder), vm_name_to_control_sock_{InitializeVmToControlSockPath(instance)}, device_status_{DeviceStatus::kUnknown} {} @@ -93,7 +93,7 @@ Result<void> ServerLoopImpl::Run() { } } const auto& channel_to_secure_env = - secure_env_files_->run_cvd_to_secure_env_fd; + snapshot_control_files_->run_cvd_to_secure_env_fd; ProcessMonitor process_monitor(std::move(process_monitor_properties), channel_to_secure_env); @@ -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"), @@ -415,7 +414,7 @@ void ServerLoopImpl::RestartRunCvd(int notification_fd) { } Result<std::string> ServerLoopImpl::VmControlSocket() const { - CF_EXPECT_EQ(config_.vm_manager(), "crosvm", + CF_EXPECT_EQ(config_.vm_manager(), VmmMode::kCrosvm, "Other VMs but crosvm is not yet supported."); return instance_.CrosvmSocketPath(); } diff --git a/host/commands/run_cvd/server_loop_impl.h b/host/commands/run_cvd/server_loop_impl.h index 1577f283e..dde74b05f 100644 --- a/host/commands/run_cvd/server_loop_impl.h +++ b/host/commands/run_cvd/server_loop_impl.h @@ -46,7 +46,7 @@ class ServerLoopImpl : public ServerLoop, public: INJECT(ServerLoopImpl(const CuttlefishConfig& config, const CuttlefishConfig::InstanceSpecific& instance, - AutoSecureEnvFiles::Type& secure_env_files, + AutoSnapshotControlFiles::Type& snapshot_control_files, WebRtcRecorder& webrtc_recorder)); Result<void> LateInject(fruit::Injector<>& injector) override; @@ -66,7 +66,7 @@ class ServerLoopImpl : public ServerLoop, private: bool Enabled() const override { return true; } std::unordered_set<SetupFeature*> Dependencies() const override { - return {&secure_env_files_}; + return {&snapshot_control_files_}; } Result<void> ResultSetup() override; Result<void> HandleExtended(const LauncherActionInfo& action_info, @@ -93,7 +93,7 @@ class ServerLoopImpl : public ServerLoop, static std::unordered_map<std::string, std::string> InitializeVmToControlSockPath(const CuttlefishConfig::InstanceSpecific&); Result<std::string> VmControlSocket() const; - Result<void> TakeGuestSnapshot(const std::string&, const std::string&); + Result<void> TakeGuestSnapshot(VmmMode, const std::string&); Result<void> TakeCrosvmGuestSnapshot(const Json::Value&); const CuttlefishConfig& config_; @@ -104,7 +104,7 @@ class ServerLoopImpl : public ServerLoop, * secure_env. The socket pairs are used to send suspend/resume to * secure_env, and get the responses. */ - AutoSecureEnvFiles::Type& secure_env_files_; + AutoSnapshotControlFiles::Type& snapshot_control_files_; WebRtcRecorder& webrtc_recorder_; std::vector<CommandSource*> command_sources_; SharedFD server_; diff --git a/host/commands/run_cvd/server_loop_impl_snapshot.cpp b/host/commands/run_cvd/server_loop_impl_snapshot.cpp index c846e3726..c90c4aca6 100644 --- a/host/commands/run_cvd/server_loop_impl_snapshot.cpp +++ b/host/commands/run_cvd/server_loop_impl_snapshot.cpp @@ -43,9 +43,9 @@ ServerLoopImpl::InitializeVmToControlSockPath( const CuttlefishConfig::InstanceSpecific& instance) { return std::unordered_map<std::string, std::string>{ // TODO(kwstephenkim): add the following two lines to support QEMU - // {QemuManager::name(), + // {ToString(VmmMode::kQemu), // instance.PerInstanceInternalUdsPath("qemu_monitor.sock")}, - {vm_manager::CrosvmManager::name(), instance.CrosvmSocketPath()}, + {ToString(VmmMode::kCrosvm), instance.CrosvmSocketPath()}, {cuttlefish::kApName, instance.OpenwrtCrosvmSocketPath()}, }; } @@ -105,15 +105,16 @@ Result<void> ServerLoopImpl::SuspendGuest() { CF_EXPECT(SuspendCrosvm(openwrt_sock), "failed to suspend openwrt crosvm instance."); } - const auto vm_name = config_.vm_manager(); - if (vm_name == vm_manager::CrosvmManager::name()) { - const auto& vm_sock = GetSocketPath(vm_name, vm_name_to_control_sock_); + const auto main_vmm = config_.vm_manager(); + if (main_vmm == VmmMode::kCrosvm) { + const auto& vm_sock = + GetSocketPath(ToString(main_vmm), vm_name_to_control_sock_); if (vm_sock == "") { - return CF_ERR("The vm_manager " + vm_name + " is not supported yet"); + return CF_ERR("The vm_manager " << main_vmm << " is not supported yet"); } return SuspendCrosvm(vm_sock); } else { - return CF_ERR("The vm_manager " + vm_name + " is not supported yet"); + return CF_ERR("The vm_manager " << main_vmm << " is not supported yet"); } } @@ -130,21 +131,33 @@ Result<void> ServerLoopImpl::ResumeGuest() { CF_EXPECT(ResumeCrosvm(openwrt_sock), "failed to resume openwrt crosvm instance."); } - const auto vm_name = config_.vm_manager(); - if (vm_name == vm_manager::CrosvmManager::name()) { - const auto& vm_sock = GetSocketPath(vm_name, vm_name_to_control_sock_); + const auto main_vmm = config_.vm_manager(); + if (main_vmm == VmmMode::kCrosvm) { + const auto& vm_sock = + GetSocketPath(ToString(main_vmm), vm_name_to_control_sock_); if (vm_sock == "") { - return CF_ERR("The vm_manager " + vm_name + " is not supported yet"); + return CF_ERR("The vm_manager " << main_vmm << " is not supported yet"); } return ResumeCrosvm(vm_sock); } else { - return CF_ERR("The vm_manager " + vm_name + " is not supported yet"); + return CF_ERR("The vm_manager " << main_vmm << " is not supported yet"); } } Result<void> ServerLoopImpl::HandleSuspend(ProcessMonitor& process_monitor) { // right order: guest -> host LOG(DEBUG) << "Suspending the guest.."; + const auto adb_bin_path = SubtoolPath("adb"); + CF_EXPECT(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), "shell", + "cmd", "bluetooth_manager", "disable"}, + SubprocessOptions(), WEXITED)); + CF_EXPECT(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), "shell", + "cmd", "bluetooth_manager", "wait-for-state:STATE_OFF"}, + SubprocessOptions(), WEXITED)); + CF_EXPECT(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), "shell", + "cmd", "uwb", "disable-uwb"}, + SubprocessOptions(), WEXITED)); + // right order: guest -> host CF_EXPECT(SuspendGuest()); LOG(DEBUG) << "The guest is suspended."; CF_EXPECT(process_monitor.SuspendMonitoredProcesses(), @@ -160,6 +173,14 @@ Result<void> ServerLoopImpl::HandleResume(ProcessMonitor& process_monitor) { LOG(DEBUG) << "The host processes are resumed."; LOG(DEBUG) << "Resuming the guest.."; CF_EXPECT(ResumeGuest()); + // Resume services after guest has resumed. + const auto adb_bin_path = SubtoolPath("adb"); + CF_EXPECT(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), "shell", + "cmd", "bluetooth_manager", "enable"}, + SubprocessOptions(), WEXITED)); + CF_EXPECT(Execute({adb_bin_path, "-s", instance_.adb_ip_and_port(), "shell", + "cmd", "uwb", "enable-uwb"}, + SubprocessOptions(), WEXITED)); LOG(DEBUG) << "The guest resumed."; return {}; } @@ -215,7 +236,7 @@ Result<void> ServerLoopImpl::TakeCrosvmGuestSnapshot( /* * Parse json file at json_path, and take guest snapshot */ -Result<void> ServerLoopImpl::TakeGuestSnapshot(const std::string& vm_manager, +Result<void> ServerLoopImpl::TakeGuestSnapshot(VmmMode vm_manager, const std::string& json_path) { // common code across vm_manager CF_EXPECTF(FileExists(json_path), "{} must exist but does not.", json_path); @@ -226,7 +247,7 @@ Result<void> ServerLoopImpl::TakeGuestSnapshot(const std::string& vm_manager, std::string("Failed to read from ") + json_path); Json::Value meta_json = CF_EXPECTF( ParseJson(json_contents), "Failed to parse json: \n{}", json_contents); - CF_EXPECTF(vm_manager == "crosvm", + CF_EXPECTF(vm_manager == VmmMode::kCrosvm, "{}, which is not crosvm, is not yet supported.", vm_manager); CF_EXPECT(TakeCrosvmGuestSnapshot(meta_json), "TakeCrosvmGuestSnapshot() failed."); diff --git a/host/frontend/webrtc/connection_observer.cpp b/host/frontend/webrtc/connection_observer.cpp index 246a4e109..aaa903cff 100644 --- a/host/frontend/webrtc/connection_observer.cpp +++ b/host/frontend/webrtc/connection_observer.cpp @@ -78,33 +78,40 @@ class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver { SendLastFrameAsync(/*all displays*/ std::nullopt); } - void OnTouchEvent(const std::string &device_label, int x, int y, - bool down) override { - input_events_sink_->SendTouchEvent(device_label, x, y, down); + Result<void> OnTouchEvent(const std::string &device_label, int x, int y, + bool down) override { + CF_EXPECT(input_events_sink_->SendTouchEvent(device_label, x, y, down)); + return {}; } - void OnMultiTouchEvent(const std::string &device_label, Json::Value id, - Json::Value slot, Json::Value x, Json::Value y, - bool down, int size) { + Result<void> OnMultiTouchEvent(const std::string &device_label, + Json::Value id, Json::Value slot, + Json::Value x, Json::Value y, bool down, + int size) { std::vector<MultitouchSlot> slots(size); for (int i = 0; i < size; i++) { slots[i].id = id[i].asInt(); slots[i].x = x[i].asInt(); slots[i].y = y[i].asInt(); } - input_events_sink_->SendMultiTouchEvent(device_label, slots, down); + CF_EXPECT( + input_events_sink_->SendMultiTouchEvent(device_label, slots, down)); + return {}; } - void OnKeyboardEvent(uint16_t code, bool down) override { - input_events_sink_->SendKeyboardEvent(code, down); + Result<void> OnKeyboardEvent(uint16_t code, bool down) override { + CF_EXPECT(input_events_sink_->SendKeyboardEvent(code, down)); + return {}; } - void OnWheelEvent(int pixels) { - input_events_sink_->SendRotaryEvent(pixels); + Result<void> OnWheelEvent(int pixels) { + CF_EXPECT(input_events_sink_->SendRotaryEvent(pixels)); + return {}; } - void OnSwitchEvent(uint16_t code, bool state) { - input_events_sink_->SendSwitchesEvent(code, state); + Result<void> OnSwitchEvent(uint16_t code, bool state) { + CF_EXPECT(input_events_sink_->SendSwitchesEvent(code, state)); + return {}; } void OnAdbChannelOpen(std::function<bool(const uint8_t *, size_t)> @@ -127,32 +134,39 @@ class ConnectionObserverImpl : public webrtc_streaming::ConnectionObserver { kernel_log_events_handler_->AddSubscriber(control_message_sender); } - void OnLidStateChange(bool lid_open) override { + Result<void> OnLidStateChange(bool lid_open) override { // InputManagerService treats a value of 0 as open and 1 as closed, so // invert the lid_switch_open value that is sent to the input device. - OnSwitchEvent(SW_LID, !lid_open); + CF_EXPECT(OnSwitchEvent(SW_LID, !lid_open)); + return {}; } void OnHingeAngleChange(int /*hinge_angle*/) override { // TODO(b/181157794) Propagate hinge angle sensor data using a custom // Sensor HAL. } - void OnPowerButton(bool button_down) override { - OnKeyboardEvent(KEY_POWER, button_down); + Result<void> OnPowerButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_POWER, button_down)); + return {}; } - void OnBackButton(bool button_down) override { - OnKeyboardEvent(KEY_BACK, button_down); + Result<void> OnBackButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_BACK, button_down)); + return {}; } - void OnHomeButton(bool button_down) override { - OnKeyboardEvent(KEY_HOMEPAGE, button_down); + Result<void> OnHomeButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_HOMEPAGE, button_down)); + return {}; } - void OnMenuButton(bool button_down) override { - OnKeyboardEvent(KEY_MENU, button_down); + Result<void> OnMenuButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_MENU, button_down)); + return {}; } - void OnVolumeDownButton(bool button_down) override { - OnKeyboardEvent(KEY_VOLUMEDOWN, button_down); + Result<void> OnVolumeDownButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_VOLUMEDOWN, button_down)); + return {}; } - void OnVolumeUpButton(bool button_down) override { - OnKeyboardEvent(KEY_VOLUMEUP, button_down); + Result<void> OnVolumeUpButton(bool button_down) override { + CF_EXPECT(OnKeyboardEvent(KEY_VOLUMEUP, button_down)); + return {}; } void OnCustomActionButton(const std::string &command, const std::string &button_state) override { diff --git a/host/frontend/webrtc/libcommon/connection_controller.cpp b/host/frontend/webrtc/libcommon/connection_controller.cpp index cc22e862a..fff37ff5b 100644 --- a/host/frontend/webrtc/libcommon/connection_controller.cpp +++ b/host/frontend/webrtc/libcommon/connection_controller.cpp @@ -41,7 +41,10 @@ class CreateSessionDescriptionObserverIntermediate : controller_(controller) {} void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { - controller_.OnCreateSDPSuccess(desc); + auto res = controller_.OnCreateSDPSuccess(desc); + if (!res.ok()) { + LOG(ERROR) << res.error().FormatForEnv(); + } } void OnFailure(webrtc::RTCError error) override { controller_.OnCreateSDPFailure(error); @@ -114,7 +117,10 @@ void ConnectionController::FailConnection(const std::string& message) { Json::Value reply; reply["type"] = "error"; reply["error"] = message; - sig_handler_.SendMessage(reply); + auto res = sig_handler_.SendMessage(reply); + if (!res.ok()) { + LOG(ERROR) << res.error().FormatForEnv(); + } observer_.OnConnectionStateChange(CF_ERR(message)); } @@ -181,7 +187,7 @@ Result<void> ConnectionController::OnErrorMsg(const std::string& msg) { return {}; } -void ConnectionController::OnCreateSDPSuccess( +Result<void> ConnectionController::OnCreateSDPSuccess( webrtc::SessionDescriptionInterface* desc) { std::string offer_str; desc->ToString(&offer_str); @@ -195,7 +201,8 @@ void ConnectionController::OnCreateSDPSuccess( reply["type"] = sdp_type; reply["sdp"] = offer_str; - sig_handler_.SendMessage(reply); + CF_EXPECT(sig_handler_.SendMessage(reply)); + return {}; } void ConnectionController::OnCreateSDPFailure(const webrtc::RTCError& error) { @@ -395,7 +402,10 @@ void ConnectionController::OnIceCandidate( reply["mLineIndex"] = static_cast<Json::UInt64>(line_index); reply["candidate"] = candidate_sdp; - sig_handler_.SendMessage(reply); + auto res = sig_handler_.SendMessage(reply); + if (!res.ok()) { + LOG(ERROR) << res.error().FormatForEnv(); + } } // Gathering of an ICE candidate failed. diff --git a/host/frontend/webrtc/libcommon/connection_controller.h b/host/frontend/webrtc/libcommon/connection_controller.h index b03476480..d1700e619 100644 --- a/host/frontend/webrtc/libcommon/connection_controller.h +++ b/host/frontend/webrtc/libcommon/connection_controller.h @@ -155,7 +155,7 @@ class ConnectionController : public webrtc::PeerConnectionObserver { rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> ThisAsSetRemoteSDPObserver(); - void OnCreateSDPSuccess(webrtc::SessionDescriptionInterface* desc); + Result<void> OnCreateSDPSuccess(webrtc::SessionDescriptionInterface* desc); void OnCreateSDPFailure(const webrtc::RTCError& error); void OnSetLocalDescriptionSuccess(); void OnSetLocalDescriptionFailure(const webrtc::RTCError& error); diff --git a/host/frontend/webrtc/libdevice/connection_observer.h b/host/frontend/webrtc/libdevice/connection_observer.h index a55f4b3ec..7dfe072bb 100644 --- a/host/frontend/webrtc/libdevice/connection_observer.h +++ b/host/frontend/webrtc/libdevice/connection_observer.h @@ -20,6 +20,8 @@ #include <json/json.h> +#include "common/libs/utils/result.h" + namespace cuttlefish { namespace webrtc_streaming { @@ -42,15 +44,16 @@ class ConnectionObserver { virtual void OnConnected() = 0; - virtual void OnTouchEvent(const std::string& device_label, int x, int y, - bool down) = 0; - virtual void OnMultiTouchEvent(const std::string& label, Json::Value id, - Json::Value slot, Json::Value x, Json::Value y, - bool down, int size) = 0; + virtual Result<void> OnTouchEvent(const std::string& device_label, int x, + int y, bool down) = 0; + virtual Result<void> OnMultiTouchEvent(const std::string& label, + Json::Value id, Json::Value slot, + Json::Value x, Json::Value y, + bool down, int size) = 0; - virtual void OnKeyboardEvent(uint16_t keycode, bool down) = 0; + virtual Result<void> OnKeyboardEvent(uint16_t keycode, bool down) = 0; - virtual void OnWheelEvent(int pixels) = 0; + virtual Result<void> OnWheelEvent(int pixels) = 0; virtual void OnAdbChannelOpen( std::function<bool(const uint8_t*, size_t)> adb_message_sender) = 0; @@ -58,14 +61,14 @@ class ConnectionObserver { virtual void OnControlChannelOpen( std::function<bool(const Json::Value)> control_message_sender) = 0; - virtual void OnLidStateChange(bool lid_open) = 0; + virtual Result<void> OnLidStateChange(bool lid_open) = 0; virtual void OnHingeAngleChange(int hinge_angle) = 0; - virtual void OnPowerButton(bool button_down) = 0; - virtual void OnBackButton(bool button_down) = 0; - virtual void OnHomeButton(bool button_down) = 0; - virtual void OnMenuButton(bool button_down) = 0; - virtual void OnVolumeDownButton(bool button_down) = 0; - virtual void OnVolumeUpButton(bool button_down) = 0; + virtual Result<void> OnPowerButton(bool button_down) = 0; + virtual Result<void> OnBackButton(bool button_down) = 0; + virtual Result<void> OnHomeButton(bool button_down) = 0; + virtual Result<void> OnMenuButton(bool button_down) = 0; + virtual Result<void> OnVolumeDownButton(bool button_down) = 0; + virtual Result<void> OnVolumeUpButton(bool button_down) = 0; virtual void OnCustomActionButton(const std::string& command, const std::string& button_state) = 0; diff --git a/host/frontend/webrtc/libdevice/data_channels.cpp b/host/frontend/webrtc/libdevice/data_channels.cpp index 113013c39..9c459a542 100644 --- a/host/frontend/webrtc/libdevice/data_channels.cpp +++ b/host/frontend/webrtc/libdevice/data_channels.cpp @@ -41,7 +41,7 @@ class DataChannelHandler : public webrtc::DataChannelObserver { virtual std::shared_ptr<ConnectionObserver> observer() = 0; // Subclasses must override this to process messages. - virtual void OnMessageInner(const webrtc::DataBuffer &msg) = 0; + virtual Result<void> OnMessageInner(const webrtc::DataBuffer &msg) = 0; // Some subclasses may override this to defer some work until the channel is // actually used. virtual void OnFirstMessage() {} @@ -77,60 +77,47 @@ static constexpr auto kCameraDataEof = "EOF"; class InputChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { - if (msg.binary) { - // TODO (jemoreira) consider binary protocol to avoid JSON parsing - // overhead - LOG(ERROR) << "Received invalid (binary) data on input channel"; - return; - } + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { + // TODO: jemoreira - consider binary protocol to avoid JSON parsing + // overhead + CF_EXPECT(!msg.binary, "Received invalid (binary) data on input channel"); auto size = msg.size(); Json::Value evt; Json::CharReaderBuilder builder; std::unique_ptr<Json::CharReader> json_reader(builder.newCharReader()); - std::string errorMessage; + std::string error_message; auto str = msg.data.cdata<char>(); - if (!json_reader->parse(str, str + size, &evt, &errorMessage)) { - LOG(ERROR) << "Received invalid JSON object over input channel: " - << errorMessage; - return; - } - if (!evt.isMember("type") || !evt["type"].isString()) { - LOG(ERROR) << "Input event doesn't have a valid 'type' field: " - << evt.toStyledString(); - return; - } + CF_EXPECTF(json_reader->parse(str, str + size, &evt, &error_message), + "Received invalid JSON object over control channel: '{}'", + error_message); + + CF_EXPECTF(evt.isMember("type") && evt["type"].isString(), + "Input event doesn't have a valid 'type' field: ", + evt.toStyledString()); auto event_type = evt["type"].asString(); + if (event_type == "mouse") { - auto result = - ValidateJsonObject(evt, "mouse", - {{"down", Json::ValueType::intValue}, - {"x", Json::ValueType::intValue}, - {"y", Json::ValueType::intValue}, - {"display_label", Json::ValueType::stringValue}}); - if (!result.ok()) { - LOG(ERROR) << result.error().FormatForEnv(); - return; - } + CF_EXPECT(ValidateJsonObject( + evt, "mouse", + {{"down", Json::ValueType::intValue}, + {"x", Json::ValueType::intValue}, + {"y", Json::ValueType::intValue}, + {"display_label", Json::ValueType::stringValue}})); auto label = evt["device_label"].asString(); int32_t down = evt["down"].asInt(); int32_t x = evt["x"].asInt(); int32_t y = evt["y"].asInt(); - observer()->OnTouchEvent(label, x, y, down); + CF_EXPECT(observer()->OnTouchEvent(label, x, y, down)); } else if (event_type == "multi-touch") { - auto result = + CF_EXPECT( ValidateJsonObject(evt, "multi-touch", {{"id", Json::ValueType::arrayValue}, {"down", Json::ValueType::intValue}, {"x", Json::ValueType::arrayValue}, {"y", Json::ValueType::arrayValue}, - {"device_label", Json::ValueType::stringValue}}); - if (!result.ok()) { - LOG(ERROR) << result.error().FormatForEnv(); - return; - } + {"device_label", Json::ValueType::stringValue}})); auto label = evt["device_label"].asString(); auto idArr = evt["id"]; @@ -140,34 +127,25 @@ class InputChannelHandler : public DataChannelHandler { auto slotArr = evt["slot"]; int size = evt["id"].size(); - observer()->OnMultiTouchEvent(label, idArr, slotArr, xArr, yArr, down, - size); + CF_EXPECT(observer()->OnMultiTouchEvent(label, idArr, slotArr, xArr, yArr, + down, size)); } else if (event_type == "keyboard") { - auto result = + CF_EXPECT( ValidateJsonObject(evt, "keyboard", {{"event_type", Json::ValueType::stringValue}, - {"keycode", Json::ValueType::stringValue}}); - if (!result.ok()) { - LOG(ERROR) << result.error().FormatForEnv(); - return; - } + {"keycode", Json::ValueType::stringValue}})); auto down = evt["event_type"].asString() == std::string("keydown"); auto code = DomKeyCodeToLinux(evt["keycode"].asString()); - observer()->OnKeyboardEvent(code, down); + CF_EXPECT(observer()->OnKeyboardEvent(code, down)); } else if (event_type == "wheel") { - auto result = - ValidateJsonObject(evt, "wheel", - {{"pixels", Json::ValueType::intValue}}); - if (!result.ok()) { - LOG(ERROR) << result.error().FormatForEnv(); - return; - } - auto pixels = evt["pixels"].asInt(); - observer()->OnWheelEvent(pixels); + CF_EXPECT(ValidateJsonObject(evt, "wheel", + {{"pixels", Json::ValueType::intValue}})); + auto pixels = evt["pixels"].asInt(); + CF_EXPECT(observer()->OnWheelEvent(pixels)); } else { - LOG(ERROR) << "Unrecognized event type: " << event_type; - return; + return CF_ERRF("Unrecognized event type: '{}'", event_type); } + return {}; } }; @@ -179,20 +157,19 @@ class ControlChannelHandler : public DataChannelHandler { observer()->OnControlChannelOpen(GetJSONSender()); } } - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { auto msg_str = msg.data.cdata<char>(); auto size = msg.size(); Json::Value evt; Json::CharReaderBuilder builder; std::unique_ptr<Json::CharReader> json_reader(builder.newCharReader()); - std::string errorMessage; - if (!json_reader->parse(msg_str, msg_str + size, &evt, &errorMessage)) { - LOG(ERROR) << "Received invalid JSON object over control channel: " - << errorMessage; - return; - } + std::string error_message; + CF_EXPECTF( + json_reader->parse(msg_str, msg_str + size, &evt, &error_message), + "Received invalid JSON object over control channel: '{}'", + error_message); - auto result = ValidateJsonObject( + CF_EXPECT(ValidateJsonObject( evt, "command", /*required_fields=*/{{"command", Json::ValueType::stringValue}}, /*optional_fields=*/ @@ -200,54 +177,53 @@ class ControlChannelHandler : public DataChannelHandler { {"button_state", Json::ValueType::stringValue}, {"lid_switch_open", Json::ValueType::booleanValue}, {"hinge_angle_value", Json::ValueType::intValue}, - }); - if (!result.ok()) { - LOG(ERROR) << result.error().FormatForEnv(); - return; - } + })); auto command = evt["command"].asString(); if (command == "device_state") { if (evt.isMember("lid_switch_open")) { - observer()->OnLidStateChange(evt["lid_switch_open"].asBool()); + CF_EXPECT( + observer()->OnLidStateChange(evt["lid_switch_open"].asBool())); } if (evt.isMember("hinge_angle_value")) { observer()->OnHingeAngleChange(evt["hinge_angle_value"].asInt()); } - return; + return {}; } else if (command.rfind("camera_", 0) == 0) { observer()->OnCameraControlMsg(evt); - return; + return {}; } else if (command == "display") { observer()->OnDisplayControlMsg(evt); - return; + return {}; } auto button_state = evt["button_state"].asString(); LOG(VERBOSE) << "Control command: " << command << " (" << button_state << ")"; if (command == "power") { - observer()->OnPowerButton(button_state == "down"); + CF_EXPECT(observer()->OnPowerButton(button_state == "down")); } else if (command == "back") { - observer()->OnBackButton(button_state == "down"); + CF_EXPECT(observer()->OnBackButton(button_state == "down")); } else if (command == "home") { - observer()->OnHomeButton(button_state == "down"); + CF_EXPECT(observer()->OnHomeButton(button_state == "down")); } else if (command == "menu") { - observer()->OnMenuButton(button_state == "down"); + CF_EXPECT(observer()->OnMenuButton(button_state == "down")); } else if (command == "volumedown") { - observer()->OnVolumeDownButton(button_state == "down"); + CF_EXPECT(observer()->OnVolumeDownButton(button_state == "down")); } else if (command == "volumeup") { - observer()->OnVolumeUpButton(button_state == "down"); + CF_EXPECT(observer()->OnVolumeUpButton(button_state == "down")); } else { observer()->OnCustomActionButton(command, button_state); } + return {}; } }; class AdbChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { observer()->OnAdbMessage(msg.data.cdata(), msg.size()); + return {}; } void OnFirstMessage() override { // Report the adb channel as open on the first message received instead of @@ -259,8 +235,9 @@ class AdbChannelHandler : public DataChannelHandler { class BluetoothChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { observer()->OnBluetoothMessage(msg.data.cdata(), msg.size()); + return {}; } void OnFirstMessage() override { // Notify bluetooth channel opening when actually using the channel, @@ -272,18 +249,19 @@ class BluetoothChannelHandler : public DataChannelHandler { class CameraChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { auto msg_data = msg.data.cdata<char>(); if (msg.size() == strlen(kCameraDataEof) && !strncmp(msg_data, kCameraDataEof, msg.size())) { // Send complete buffer to observer on EOF marker observer()->OnCameraData(receive_buffer_); receive_buffer_.clear(); - return; + return {}; } // Otherwise buffer up data receive_buffer_.insert(receive_buffer_.end(), msg_data, msg_data + msg.size()); + return {}; } private: @@ -294,12 +272,13 @@ class CameraChannelHandler : public DataChannelHandler { class SensorsChannelHandler : public DataChannelHandler { public: void OnFirstMessage() override { observer()->OnSensorsChannelOpen(GetBinarySender()); } - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { if (!first_msg_received_) { first_msg_received_ = true; - return; + return {}; } observer()->OnSensorsMessage(msg.data.cdata(), msg.size()); + return {}; } void OnStateChangeInner(webrtc::DataChannelInterface::DataState state) override { @@ -315,7 +294,9 @@ class SensorsChannelHandler : public DataChannelHandler { class LightsChannelHandler : public DataChannelHandler { public: // We do not expect any messages from the frontend. - void OnMessageInner(const webrtc::DataBuffer &msg) override {} + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { + return {}; + } void OnStateChangeInner( webrtc::DataChannelInterface::DataState state) override { @@ -329,8 +310,9 @@ class LightsChannelHandler : public DataChannelHandler { class LocationChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { observer()->OnLocationMessage(msg.data.cdata(), msg.size()); + return {}; } void OnFirstMessage() override { // Notify location channel opening when actually using the channel, @@ -342,8 +324,9 @@ class LocationChannelHandler : public DataChannelHandler { class KmlLocationChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { observer()->OnKmlLocationsMessage(msg.data.cdata(), msg.size()); + return {}; } void OnFirstMessage() override { // Notify location channel opening when actually using the channel, @@ -355,8 +338,9 @@ class KmlLocationChannelHandler : public DataChannelHandler { class GpxLocationChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &msg) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &msg) override { observer()->OnGpxLocationsMessage(msg.data.cdata(), msg.size()); + return {}; } void OnFirstMessage() override { // Notify location channel opening when actually using the channel, @@ -368,9 +352,10 @@ class GpxLocationChannelHandler : public DataChannelHandler { class UnknownChannelHandler : public DataChannelHandler { public: - void OnMessageInner(const webrtc::DataBuffer &) override { + Result<void> OnMessageInner(const webrtc::DataBuffer &) override { LOG(WARNING) << "Message received on unknown channel: " << channel()->label(); + return {}; } }; @@ -427,7 +412,10 @@ void DataChannelHandler::OnMessage(const webrtc::DataBuffer &msg) { first_msg_received_ = true; OnFirstMessage(); } - OnMessageInner(msg); + auto res = OnMessageInner(msg); + if (!res.ok()) { + LOG(ERROR) << res.error().FormatForEnv(); + } } DataChannelHandlers::DataChannelHandlers( 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 6de482552..091b59160 100644 --- a/host/libs/config/cuttlefish_config.cpp +++ b/host/libs/config/cuttlefish_config.cpp @@ -111,11 +111,12 @@ void CuttlefishConfig::set_root_dir(const std::string& root_dir) { } static constexpr char kVmManager[] = "vm_manager"; -std::string CuttlefishConfig::vm_manager() const { - return (*dictionary_)[kVmManager].asString(); +VmmMode CuttlefishConfig::vm_manager() const { + auto str = (*dictionary_)[kVmManager].asString(); + return ParseVmm(str).value_or(VmmMode::kUnknown); } -void CuttlefishConfig::set_vm_manager(const std::string& name) { - (*dictionary_)[kVmManager] = name; +void CuttlefishConfig::set_vm_manager(VmmMode vmm) { + (*dictionary_)[kVmManager] = fmt::format("{}", vmm); } static constexpr char kApVmManager[] = "ap_vm_manager"; @@ -173,7 +174,9 @@ void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) { (*dictionary_)[kCrosvmBinary] = crosvm_binary; } -bool CuttlefishConfig::IsCrosvm() const { return vm_manager() == "crosvm"; } +bool CuttlefishConfig::IsCrosvm() const { + return vm_manager() == VmmMode::kCrosvm; +} static constexpr char kGem5DebugFlags[] = "gem5_debug_flags"; std::string CuttlefishConfig::gem5_debug_flags() const { diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h index 8de591aa8..ecc93ea03 100644 --- a/host/libs/config/cuttlefish_config.h +++ b/host/libs/config/cuttlefish_config.h @@ -52,6 +52,17 @@ enum class SecureHal { HostOemlockSecure, }; +enum class VmmMode { + kUnknown, + kCrosvm, + kGem5, + kQemu, +}; + +std::ostream& operator<<(std::ostream&, VmmMode); +std::string ToString(VmmMode mode); +Result<VmmMode> ParseVmm(std::string_view); + enum class ExternalNetworkMode { kUnknown, kTap, @@ -100,8 +111,8 @@ class CuttlefishConfig { std::string environments_uds_dir() const; std::string EnvironmentsUdsPath(const std::string&) const; - std::string vm_manager() const; - void set_vm_manager(const std::string& name); + VmmMode vm_manager() const; + void set_vm_manager(VmmMode vmm); std::string ap_vm_manager() const; void set_ap_vm_manager(const std::string& name); @@ -398,7 +409,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; @@ -573,8 +583,12 @@ class CuttlefishConfig { bool vhost_net() const; bool vhost_user_vsock() const; - // The dns address of mobile network (RIL) + // Mobile network info (RIL) std::string ril_dns() const; + std::string ril_ipaddr() const; + std::string ril_gateway() const; + std::string ril_broadcast() const; + uint8_t ril_prefixlen() const; bool enable_webrtc() const; std::string webrtc_assets_dir() const; @@ -798,8 +812,12 @@ class CuttlefishConfig { void set_vhost_net(bool vhost_net); void set_vhost_user_vsock(bool vhost_user_vsock); - // The dns address of mobile network (RIL) + // Mobile network (RIL) void set_ril_dns(const std::string& ril_dns); + void set_ril_ipaddr(const std::string& ril_ipaddr); + void set_ril_gateway(const std::string& ril_gateway); + void set_ril_broadcast(const std::string& ril_broadcast); + void set_ril_prefixlen(uint8_t ril_prefixlen); // Configuration flags for a minimal device void set_enable_minimal_mode(bool enable_minimal_mode); @@ -1003,4 +1021,6 @@ extern const char* const kHwComposerNone; #if FMT_VERSION >= 90000 template <> struct fmt::formatter<cuttlefish::ExternalNetworkMode> : ostream_formatter {}; +template <> +struct fmt::formatter<cuttlefish::VmmMode> : ostream_formatter {}; #endif diff --git a/host/libs/config/cuttlefish_config_instance.cpp b/host/libs/config/cuttlefish_config_instance.cpp index 41c319e5b..24b246417 100644 --- a/host/libs/config/cuttlefish_config_instance.cpp +++ b/host/libs/config/cuttlefish_config_instance.cpp @@ -62,6 +62,37 @@ Result<ExternalNetworkMode> ParseExternalNetworkMode(std::string_view str) { } } +std::string ToString(VmmMode mode) { + std::stringstream ss; + ss << mode; + return ss.str(); +} + +std::ostream& operator<<(std::ostream& out, VmmMode vmm) { + switch (vmm) { + case VmmMode::kUnknown: + return out << "unknown"; + case VmmMode::kCrosvm: + return out << "crosvm"; + case VmmMode::kGem5: + return out << "gem5"; + case VmmMode::kQemu: + return out << "qemu_cli"; + } +} + +Result<VmmMode> ParseVmm(std::string_view str) { + if (android::base::EqualsIgnoreCase(str, "crosvm")) { + return VmmMode::kCrosvm; + } else if (android::base::EqualsIgnoreCase(str, "gem5")) { + return VmmMode::kGem5; + } else if (android::base::EqualsIgnoreCase(str, "qemu_cli")) { + return VmmMode::kQemu; + } else { + return CF_ERRF("\"{}\" is not a valid Vmm.", str); + } +} + static constexpr char kInstanceDir[] = "instance_dir"; CuttlefishConfig::MutableInstanceSpecific::MutableInstanceSpecific( CuttlefishConfig* config, const std::string& id) @@ -1054,6 +1085,42 @@ std::string CuttlefishConfig::InstanceSpecific::ril_dns() const { return (*Dictionary())[kRilDns].asString(); } +static constexpr char kRilIpaddr[] = "ril_ipaddr"; +void CuttlefishConfig::MutableInstanceSpecific::set_ril_ipaddr( + const std::string& ril_ipaddr) { + (*Dictionary())[kRilIpaddr] = ril_ipaddr; +} +std::string CuttlefishConfig::InstanceSpecific::ril_ipaddr() const { + return (*Dictionary())[kRilIpaddr].asString(); +} + +static constexpr char kRilGateway[] = "ril_gateway"; +void CuttlefishConfig::MutableInstanceSpecific::set_ril_gateway( + const std::string& ril_gateway) { + (*Dictionary())[kRilGateway] = ril_gateway; +} +std::string CuttlefishConfig::InstanceSpecific::ril_gateway() const { + return (*Dictionary())[kRilGateway].asString(); +} + +static constexpr char kRilBroadcast[] = "ril_broadcast"; +void CuttlefishConfig::MutableInstanceSpecific::set_ril_broadcast( + const std::string& ril_broadcast) { + (*Dictionary())[kRilBroadcast] = ril_broadcast; +} +std::string CuttlefishConfig::InstanceSpecific::ril_broadcast() const { + return (*Dictionary())[kRilBroadcast].asString(); +} + +static constexpr char kRilPrefixlen[] = "ril_prefixlen"; +void CuttlefishConfig::MutableInstanceSpecific::set_ril_prefixlen( + uint8_t ril_prefixlen) { + (*Dictionary())[kRilPrefixlen] = static_cast<Json::UInt>(ril_prefixlen); +} +uint8_t CuttlefishConfig::InstanceSpecific::ril_prefixlen() const { + return static_cast<uint8_t>((*Dictionary())[kRilPrefixlen].asUInt()); +} + static constexpr char kDisplayConfigs[] = "display_configs"; static constexpr char kXRes[] = "x_res"; static constexpr char kYRes[] = "y_res"; @@ -1163,8 +1230,7 @@ bool CuttlefishConfig::InstanceSpecific::console() const { std::string CuttlefishConfig::InstanceSpecific::console_dev() const { auto can_use_virtio_console = !kgdb() && !use_bootloader(); std::string console_dev; - if (can_use_virtio_console || - config_->vm_manager() == vm_manager::Gem5Manager::name()) { + if (can_use_virtio_console || config_->vm_manager() == VmmMode::kGem5) { // If kgdb and the bootloader are disabled, the Android serial console // spawns on a virtio-console port. If the bootloader is enabled, virtio // console can't be used since uboot doesn't support it. @@ -1174,7 +1240,7 @@ std::string CuttlefishConfig::InstanceSpecific::console_dev() const { // architectures emulate ns16550a/uart8250 instead. Arch target = target_arch(); if ((target == Arch::Arm64 || target == Arch::Arm) && - config_->vm_manager() != vm_manager::CrosvmManager::name()) { + config_->vm_manager() != VmmMode::kCrosvm) { console_dev = "ttyAMA0"; } else { console_dev = "ttyS0"; @@ -1187,10 +1253,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")); } diff --git a/host/libs/config/data_image.cpp b/host/libs/config/data_image.cpp index 0849fd088..915728efc 100644 --- a/host/libs/config/data_image.cpp +++ b/host/libs/config/data_image.cpp @@ -271,7 +271,7 @@ class InitializeEspImageImpl : public InitializeEspImage { LOG(DEBUG) << "creating esp_image: " << instance_.ap_esp_image_path(); CF_EXPECT(BuildAPImage()); } - const auto is_not_gem5 = config_.vm_manager() != vm_manager::Gem5Manager::name(); + const auto is_not_gem5 = config_.vm_manager() != VmmMode::kGem5; const auto esp_required_for_boot_flow = EspRequiredForBootFlow(); if (is_not_gem5 && esp_required_for_boot_flow) { LOG(DEBUG) << "creating esp_image: " << instance_.esp_image_path(); diff --git a/host/libs/config/kernel_args.cpp b/host/libs/config/kernel_args.cpp index 91e0bbd0e..f5bdf7dc0 100644 --- a/host/libs/config/kernel_args.cpp +++ b/host/libs/config/kernel_args.cpp @@ -42,7 +42,7 @@ std::vector<std::string> VmManagerKernelCmdline( const CuttlefishConfig& config, const CuttlefishConfig::InstanceSpecific& instance) { std::vector<std::string> vm_manager_cmdline; - if (config.vm_manager() == QemuManager::name()) { + if (config.vm_manager() == VmmMode::kQemu) { Arch target_arch = instance.target_arch(); if (target_arch == Arch::Arm64 || target_arch == Arch::Arm) { if (instance.enable_kernel_log()) { diff --git a/host/libs/config/known_paths.cpp b/host/libs/config/known_paths.cpp index 9303fa805..a5bfb0c9a 100644 --- a/host/libs/config/known_paths.cpp +++ b/host/libs/config/known_paths.cpp @@ -30,10 +30,6 @@ std::string CasimirControlServerBinary() { return HostBinaryPath("casimir_control_server"); } -std::string ConfigServerBinary() { - return HostBinaryPath("config_server"); -} - std::string ConsoleForwarderBinary() { return HostBinaryPath("console_forwarder"); } diff --git a/host/libs/config/known_paths.h b/host/libs/config/known_paths.h index 0670b644d..355d255d7 100644 --- a/host/libs/config/known_paths.h +++ b/host/libs/config/known_paths.h @@ -22,7 +22,6 @@ namespace cuttlefish { std::string AdbConnectorBinary(); std::string AvbToolBinary(); std::string CasimirControlServerBinary(); -std::string ConfigServerBinary(); std::string ConsoleForwarderBinary(); std::string ControlEnvProxyServerBinary(); std::string EchoServerBinary(); diff --git a/host/libs/vm_manager/Android.bp b/host/libs/vm_manager/Android.bp index 3325e6544..1bc3ee0be 100644 --- a/host/libs/vm_manager/Android.bp +++ b/host/libs/vm_manager/Android.bp @@ -24,6 +24,7 @@ cc_library { "crosvm_manager.cpp", "gem5_manager.cpp", "host_configuration.cpp", + "pci.cpp", "qemu_manager.cpp", "vm_manager.cpp", ], @@ -33,8 +34,6 @@ cc_library { shared_libs: [ "libbase", "libcuttlefish_command_util", - "libcuttlefish_device_config", - "libcuttlefish_device_config_proto", "libcuttlefish_fs", "libcuttlefish_utils", "libfruit", diff --git a/host/libs/vm_manager/crosvm_builder.cpp b/host/libs/vm_manager/crosvm_builder.cpp index cb863db32..4f51e331c 100644 --- a/host/libs/vm_manager/crosvm_builder.cpp +++ b/host/libs/vm_manager/crosvm_builder.cpp @@ -28,6 +28,17 @@ #include "host/libs/config/known_paths.h" namespace cuttlefish { +namespace { + +std::string MacCrosvmArgument(std::optional<std::string_view> mac) { + return mac.has_value() ? fmt::format(",mac={}", mac.value()) : ""; +} + +std::string PciCrosvmArgument(std::optional<pci::Address> pci) { + return pci.has_value() ? fmt::format(",pci-address={}", pci.value().Id()) : ""; +} + +} CrosvmBuilder::CrosvmBuilder() : command_("crosvm") {} @@ -104,10 +115,12 @@ void CrosvmBuilder::AddSerial(const std::string& output, } #ifdef __linux__ -SharedFD CrosvmBuilder::AddTap(const std::string& tap_name) { +SharedFD CrosvmBuilder::AddTap(const std::string& tap_name, + std::optional<std::string_view> mac, + const std::optional<pci::Address>& pci) { auto tap_fd = OpenTapInterface(tap_name); if (tap_fd->IsOpen()) { - command_.AddParameter("--net=tap-fd=", tap_fd); + command_.AddParameter("--net=tap-fd=", tap_fd, MacCrosvmArgument(mac), PciCrosvmArgument(pci)); } else { LOG(ERROR) << "Unable to connect to \"" << tap_name << "\": " << tap_fd->StrError(); @@ -115,16 +128,6 @@ SharedFD CrosvmBuilder::AddTap(const std::string& tap_name) { return tap_fd; } -SharedFD CrosvmBuilder::AddTap(const std::string& tap_name, const std::string& mac) { - auto tap_fd = OpenTapInterface(tap_name); - if (tap_fd->IsOpen()) { - command_.AddParameter("--net=tap-fd=", tap_fd, ",mac=\"", mac, "\""); - } else { - LOG(ERROR) << "Unable to connect to \"" << tap_name - << "\": " << tap_fd->StrError(); - } - return tap_fd; -} #endif int CrosvmBuilder::HvcNum() { return hvc_num_; } diff --git a/host/libs/vm_manager/crosvm_builder.h b/host/libs/vm_manager/crosvm_builder.h index e2f722e03..123d01a6a 100644 --- a/host/libs/vm_manager/crosvm_builder.h +++ b/host/libs/vm_manager/crosvm_builder.h @@ -15,12 +15,14 @@ #pragma once +#include <optional> #include <string> #include <utility> #include "common/libs/fs/shared_fd.h" #include "common/libs/utils/result.h" #include "common/libs/utils/subprocess.h" +#include "host/libs/vm_manager/pci.h" namespace cuttlefish { @@ -48,8 +50,9 @@ class CrosvmBuilder { void AddSerial(const std::string& output, const std::string& input); #ifdef __linux__ - SharedFD AddTap(const std::string& tap_name); - SharedFD AddTap(const std::string& tap_name, const std::string& mac); + SharedFD AddTap(const std::string& tap_name, + std::optional<std::string_view> mac = std::nullopt, + const std::optional<pci::Address>& pci = std::nullopt); #endif int HvcNum(); diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp index fb8f4605c..fe25ab896 100644 --- a/host/libs/vm_manager/crosvm_manager.cpp +++ b/host/libs/vm_manager/crosvm_manager.cpp @@ -212,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)); @@ -318,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); @@ -579,10 +582,16 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands( // having to pass arguments to crosvm via a wrapper script. #ifdef __linux__ if (!gpu_capture_enabled) { - // The ordering of tap devices is important. Make sure any change here - // is reflected in ethprime u-boot variable - crosvm_cmd.AddTap(instance.mobile_tap_name(), instance.mobile_mac()); - crosvm_cmd.AddTap(instance.ethernet_tap_name(), instance.ethernet_mac()); + // The PCI ordering of tap devices is important. Make sure any change here + // is reflected in ethprime u-boot variable. + // TODO(b/218364216, b/322862402): Crosvm occupies 32 PCI devices first and only then uses PCI + // functions which may break order. The final solution is going to be a PCI allocation strategy + // that will guarantee the ordering. For now, hardcode PCI network devices to unoccupied + // functions. + const pci::Address mobile_pci = pci::Address(0, VmManager::kNetPciDeviceNum, 1); + const pci::Address ethernet_pci = pci::Address(0, VmManager::kNetPciDeviceNum, 2); + crosvm_cmd.AddTap(instance.mobile_tap_name(), instance.mobile_mac(), mobile_pci); + crosvm_cmd.AddTap(instance.ethernet_tap_name(), instance.ethernet_mac(), ethernet_pci); if (!config.virtio_mac80211_hwsim() && environment.enable_wifi()) { wifi_tap = crosvm_cmd.AddTap(instance.wifi_tap_name()); @@ -810,9 +819,18 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands( // This needs to be the last parameter crosvm_cmd.Cmd().AddParameter("--bios=", instance.bootloader()); + std::vector<MonitorCommand> commands; + + if (vhost_user_gpu) { + // The vhost user gpu crosvm command should be added before the main + // crosvm command so that the main crosvm command can use a prerequisite + // to wait for the communication socket to be ready. + commands.emplace_back(std::move(vhost_user_gpu->device_cmd)); + commands.emplace_back(std::move(vhost_user_gpu->device_logs_cmd)); + } + // log_tee must be added before crosvm_cmd to ensure all of crosvm's logs are // captured during shutdown. Processes are stopped in reverse order. - std::vector<MonitorCommand> commands; commands.emplace_back(std::move(crosvm_log_tee_cmd)); if (gpu_capture_enabled) { @@ -869,13 +887,35 @@ Result<std::vector<MonitorCommand>> CrosvmManager::StartCommands( commands.emplace_back(std::move(crosvm_cmd.Cmd()), true); } - if (vhost_user_gpu) { - commands.emplace_back(std::move(vhost_user_gpu->device_cmd)); - commands.emplace_back(std::move(vhost_user_gpu->device_logs_cmd)); - } - 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/pci.cpp b/host/libs/vm_manager/pci.cpp new file mode 100644 index 000000000..9b57fcfd1 --- /dev/null +++ b/host/libs/vm_manager/pci.cpp @@ -0,0 +1,37 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "host/libs/vm_manager/pci.h" + +#include <android-base/logging.h> + +namespace cuttlefish { +namespace pci { +namespace { +constexpr unsigned int kMaxBus = 255; +constexpr unsigned int kMaxDevice = 31; +constexpr unsigned int kMaxFunction = 7; +} // namespace + +Address::Address(unsigned int bus, unsigned int device, unsigned int function) + : bus_(bus), device_(device), function_(function) { + if (bus_ > kMaxBus || device_ > kMaxDevice || function_ > kMaxFunction) { + LOG(FATAL) << "Failed to create PCI address instance with bus: " << bus_ + << " device: " << device_ << " function: " << function_; + } +} + +} // namespace pci +} // namespace cuttlefish
\ No newline at end of file diff --git a/common/libs/device_config/device_config.cpp b/host/libs/vm_manager/pci.h index 0bbe903e3..47ca0769a 100644 --- a/common/libs/device_config/device_config.cpp +++ b/host/libs/vm_manager/pci.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,24 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#pragma once -#include "device_config.h" - -#include <sstream> -#include <type_traits> - -#include <android-base/logging.h> - -#include "common/libs/fs/shared_fd_stream.h" +#include <fmt/core.h> namespace cuttlefish { - -bool DeviceConfigHelper::SendDeviceConfig(SharedFD fd) { - SharedFDOstream stream(fd); - return device_config_.SerializeToOstream(&stream); -} - -DeviceConfigHelper::DeviceConfigHelper(const DeviceConfig& device_config) - : device_config_(device_config) {} - +namespace pci { + +class Address { + public: + Address(unsigned int bus, unsigned int device, unsigned int function); + + unsigned int Bus() const { return bus_; }; + unsigned int Device() const { return device_; } + unsigned int Function() const { return function_; } + std::string Id() const { + return fmt::format("{:02x}:{:02x}.{:01x}", bus_, device_, function_); + } + + private: + unsigned int bus_; + unsigned int device_; + unsigned int function_; +}; + +} // namespace pci } // namespace cuttlefish diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp index 26ff43628..332023d77 100644 --- a/host/libs/vm_manager/qemu_manager.cpp +++ b/host/libs/vm_manager/qemu_manager.cpp @@ -35,7 +35,6 @@ #include <android-base/logging.h> #include <vulkan/vulkan.h> -#include "common/libs/device_config/device_config.h" #include "common/libs/utils/files.h" #include "common/libs/utils/result.h" #include "common/libs/utils/subprocess.h" @@ -729,18 +728,9 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands( } break; case cuttlefish::ExternalNetworkMode::kSlirp: { - // TODO(schuffelen): Deduplicate with modem_simulator/cf_device_config.cpp - // The configuration here needs to match the ip address reported by the - // modem simulator, which the guest uses to statically assign an IP - // address to its virtio-net ethernet device. - std::string net = "10.0.2.15/24"; - std::string host = "10.0.2.2"; - auto device_config_helper = DeviceConfigHelper::Get(); - if (device_config_helper) { - const auto& cfg = device_config_helper->GetDeviceConfig().ril_config(); - net = fmt::format("{}/{}", cfg.ipaddr(), cfg.prefixlen()); - host = cfg.gateway(); - } + const std::string net = + fmt::format("{}/{}", instance.ril_ipaddr(), instance.ril_prefixlen()); + const std::string& host = instance.ril_gateway(); qemu_cmd.AddParameter("-netdev"); // TODO(schuffelen): `dns` needs to match the first `nameserver` in // `/etc/resolv.conf`. Implement something that generalizes beyond gLinux. @@ -807,6 +797,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.cpp b/host/libs/vm_manager/vm_manager.cpp index c916b13e8..7860d3cb2 100644 --- a/host/libs/vm_manager/vm_manager.cpp +++ b/host/libs/vm_manager/vm_manager.cpp @@ -37,21 +37,22 @@ namespace cuttlefish { namespace vm_manager { -std::unique_ptr<VmManager> GetVmManager(const std::string& name, Arch arch) { +std::unique_ptr<VmManager> GetVmManager(VmmMode vmm_mode, Arch arch) { std::unique_ptr<VmManager> vmm; - if (name == QemuManager::name()) { + if (vmm_mode == VmmMode::kQemu) { vmm.reset(new QemuManager(arch)); - } else if (name == Gem5Manager::name()) { + } else if (vmm_mode == VmmMode::kGem5) { vmm.reset(new Gem5Manager(arch)); - } else if (name == CrosvmManager::name()) { + } else if (vmm_mode == VmmMode::kCrosvm) { vmm.reset(new CrosvmManager()); } if (!vmm) { - LOG(ERROR) << "Invalid VM manager: " << name; + LOG(ERROR) << "Invalid VM manager: " << vmm_mode; return {}; } if (!vmm->IsSupported()) { - LOG(ERROR) << "VM manager " << name << " is not supported on this machine."; + LOG(ERROR) << "VM manager " << vmm_mode + << " is not supported on this machine."; return {}; } return vmm; diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h index b3fa4be6c..9b704771c 100644 --- a/host/libs/vm_manager/vm_manager.h +++ b/host/libs/vm_manager/vm_manager.h @@ -80,6 +80,8 @@ class VmManager { // the persistent disk static const int kDefaultNumBootDevices = 2; + static constexpr const int kNetPciDeviceNum = 1; + // LINT.IfChange(virtio_gpu_pci_address) static constexpr const int kGpuPciSlotNum = 2; // LINT.ThenChange(../../../shared/sepolicy/vendor/genfs_contexts:virtio_gpu_pci_address) @@ -101,6 +103,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, @@ -108,7 +118,7 @@ fruit::Component<fruit::Required<const CuttlefishConfig, VmManager> VmManagerComponent(); -std::unique_ptr<VmManager> GetVmManager(const std::string&, Arch arch); +std::unique_ptr<VmManager> GetVmManager(VmmMode vmm, Arch arch); Result<std::unordered_map<std::string, std::string>> ConfigureMultipleBootDevices(const std::string& pci_path, int pci_offset, diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk index 01941bb4c..a6f46bfff 100644 --- a/shared/BoardConfig.mk +++ b/shared/BoardConfig.mk @@ -64,7 +64,7 @@ BOARD_VENDOR_RAMDISK_KERNEL_MODULES += \ $(wildcard $(KERNEL_MODULES_PATH)/vsock.ko) -# TODO(b/176860479) once virt_wifi is deprecated we can stop loading mac80211 in +# TODO(b/294888357) once virt_wifi is deprecated we can stop loading mac80211 in # first stage init. To minimize scope of modules options to first stage init, # mac80211_hwsim.radios=0 has to be specified in the modules options file (which we # only read in first stage) and mac80211_hwsim has to be loaded in first stage consequently.. diff --git a/shared/auto/audio_policy_configuration.xml b/shared/auto/audio_policy_configuration.xml index 7834e8e63..02a860a3f 100644 --- a/shared/auto/audio_policy_configuration.xml +++ b/shared/auto/audio_policy_configuration.xml @@ -37,7 +37,7 @@ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> - <mixPort name="primary input" role="sink"> + <mixPort name="primary input" role="sink" maxActiveCount="1" maxOpenCount="1"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </mixPort> 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/shared/config/init.vendor.rc b/shared/config/init.vendor.rc index 43a769d47..4925c5d39 100644 --- a/shared/config/init.vendor.rc +++ b/shared/config/init.vendor.rc @@ -63,7 +63,7 @@ on late-fs write /dev/kmsg "GUEST_BUILD_FINGERPRINT: ${ro.build.fingerprint}" -on post-fs-data && property:ro.vendor.wifi_impl=mac8011_hwsim_virtio +on post-fs-data && property:ro.vendor.wifi_impl=mac80211_hwsim_virtio mkdir /data/vendor/wifi 0770 wifi wifi mkdir /data/vendor/wifi/hostapd 0770 wifi wifi mkdir /data/vendor/wifi/hostapd/sockets 0770 wifi wifi diff --git a/shared/device.mk b/shared/device.mk index cb69217b1..985334f07 100644 --- a/shared/device.mk +++ b/shared/device.mk @@ -40,7 +40,7 @@ PRODUCT_SOONG_NAMESPACES += device/generic/goldfish # for audio, wifi and sensor PRODUCT_USE_DYNAMIC_PARTITIONS := true DISABLE_RILD_OEM_HOOK := true -# TODO(b/205788876) remove this condition when openwrt has an image for arm. +# TODO(b/294888357) Remove this condition when OpenWRT is supported for RISC-V. ifndef PRODUCT_ENFORCE_MAC80211_HWSIM PRODUCT_ENFORCE_MAC80211_HWSIM := true endif @@ -82,6 +82,16 @@ ifeq ($(TARGET_BUILD_VARIANT),user) PRODUCT_PRODUCT_PROPERTIES += \ ro.adb.secure=0 \ ro.debuggable=1 + +PRODUCT_PACKAGES += \ + logpersist.start + +PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \ + $(TARGET_COPY_OUT_SYSTEM)/bin/logcatd \ + $(TARGET_COPY_OUT_SYSTEM)/bin/logpersist.cat \ + $(TARGET_COPY_OUT_SYSTEM)/bin/logpersist.start \ + $(TARGET_COPY_OUT_SYSTEM)/bin/logpersist.stop \ + $(TARGET_COPY_OUT_SYSTEM)/etc/init/logcatd.rc endif # Use AIDL for media.c2 HAL @@ -181,7 +191,12 @@ PRODUCT_PACKAGES += \ aidl_lazy_cb_test_server \ # Runtime Resource Overlays -PRODUCT_PACKAGES += com.google.aosp_cf.rros +PRODUCT_PACKAGES += \ + cuttlefish_overlay_connectivity \ + cuttlefish_overlay_frameworks_base_core \ + cuttlefish_overlay_nfc \ + cuttlefish_overlay_settings_provider \ + cuttlefish_overlay_uwb \ # # Satellite vendor service for CF @@ -529,7 +544,7 @@ PRODUCT_PACKAGES += \ CuttlefishWifiOverlay ifeq ($(PRODUCT_ENFORCE_MAC80211_HWSIM),true) -PRODUCT_VENDOR_PROPERTIES += ro.vendor.wifi_impl=mac8011_hwsim_virtio +PRODUCT_VENDOR_PROPERTIES += ro.vendor.wifi_impl=mac80211_hwsim_virtio $(call soong_config_append,cvdhost,enforce_mac80211_hwsim,true) else PRODUCT_VENDOR_PROPERTIES += ro.vendor.wifi_impl=virt_wifi diff --git a/shared/graphics/sepolicy/hal_graphics_composer.te b/shared/graphics/sepolicy/hal_graphics_composer.te index aa851ecf7..de1900f5f 100644 --- a/shared/graphics/sepolicy/hal_graphics_composer.te +++ b/shared/graphics/sepolicy/hal_graphics_composer.te @@ -1,7 +1,6 @@ allow hal_graphics_composer_server hal_graphics_allocator_default_tmpfs:file read; allow hal_graphics_composer_server self:{ socket vsock_socket } create_socket_perms_no_ioctl; -get_prop(hal_graphics_composer_server, vendor_cuttlefish_config_server_port_prop) get_prop(hal_graphics_composer_server, vendor_hwcomposer_prop) # Persistent memory for some hwcomposer configuration. diff --git a/shared/overlays/uwb/Android.bp b/shared/overlays/uwb/Android.bp new file mode 100644 index 000000000..aa7847753 --- /dev/null +++ b/shared/overlays/uwb/Android.bp @@ -0,0 +1,9 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +runtime_resource_overlay { + name: "cuttlefish_overlay_uwb", + sdk_version: "current", + product_specific: true, +} diff --git a/shared/overlays/uwb/AndroidManifest.xml b/shared/overlays/uwb/AndroidManifest.xml new file mode 100644 index 000000000..1d50faf56 --- /dev/null +++ b/shared/overlays/uwb/AndroidManifest.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- Cuttlefish specific uwb overlays --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.uwb.resources.cuttlefish.overlay" + android:versionCode="1" + android:versionName="1.0"> + <application android:hasCode="false" /> + <overlay + android:targetPackage="com.android.uwb.resources" + android:targetName="UwbCustomization" + android:isStatic="true" + android:priority="0"/> +</manifest> diff --git a/shared/overlays/uwb/OWNERS b/shared/overlays/uwb/OWNERS new file mode 100644 index 000000000..c4ad4164e --- /dev/null +++ b/shared/overlays/uwb/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 1042770 +include platform/packages/modules/Uwb:/OWNERS diff --git a/shared/overlays/uwb/res/values/config.xml b/shared/overlays/uwb/res/values/config.xml new file mode 100644 index 000000000..9bd3d621e --- /dev/null +++ b/shared/overlays/uwb/res/values/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <bool name="is_multicast_list_update_ntf_v2_supported">true</bool> +</resources> diff --git a/shared/sepolicy/system_ext/private/system_app.te b/shared/sepolicy/system_ext/private/system_app.te index 326d9fd43..3a45a332f 100644 --- a/shared/sepolicy/system_ext/private/system_app.te +++ b/shared/sepolicy/system_ext/private/system_app.te @@ -1 +1,2 @@ get_prop(system_app, vendor_aware_available_prop) +set_prop(system_app, logpersistd_logging_prop) diff --git a/shared/sepolicy/vendor/bug_map b/shared/sepolicy/vendor/bug_map index 8a616df25..33a4601aa 100644 --- a/shared/sepolicy/vendor/bug_map +++ b/shared/sepolicy/vendor/bug_map @@ -5,3 +5,5 @@ rs privapp_data_file file b/291029681 rs priv_app unix_stream_socket b/291029681 rs priv_app udp_socket b/291029681 mediashell_app rootfs dir b/293075059 +init debugfs_bootreceiver_tracing dir b/340399580 +init debugfs_wifi_tracing dir b/340399580 diff --git a/shared/sepolicy/vendor/property.te b/shared/sepolicy/vendor/property.te index 6f3dca158..63339fb49 100644 --- a/shared/sepolicy/vendor/property.te +++ b/shared/sepolicy/vendor/property.te @@ -1,4 +1,3 @@ -vendor_restricted_prop(vendor_cuttlefish_config_server_port_prop) vendor_internal_prop(vendor_modem_simulator_ports_prop) vendor_internal_prop(vendor_boot_security_patch_level_prop) vendor_internal_prop(vendor_hwcomposer_prop) diff --git a/shared/sepolicy/vendor/property_contexts b/shared/sepolicy/vendor/property_contexts index 9acb48309..4c4552b5d 100644 --- a/shared/sepolicy/vendor/property_contexts +++ b/shared/sepolicy/vendor/property_contexts @@ -1,5 +1,4 @@ ro.boot.cpuvulkan.version u:object_r:vendor_graphics_config_prop:s0 exact int -ro.boot.cuttlefish_config_server_port u:object_r:vendor_cuttlefish_config_server_port_prop:s0 ro.boot.hardware.egl u:object_r:vendor_graphics_config_prop:s0 exact string ro.boot.hardware.gralloc u:object_r:vendor_graphics_config_prop:s0 exact string ro.boot.hardware.hwcomposer u:object_r:vendor_graphics_config_prop:s0 exact string diff --git a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te index 2b578590b..6e2958e7b 100644 --- a/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te +++ b/shared/sepolicy/vendor/telephony/libcuttlefish_rild.te @@ -8,7 +8,6 @@ hal_server_domain(libcuttlefish_rild, hal_telephony) # Failing to create these sockets appears to be non-fatal net_domain(libcuttlefish_rild) -get_prop(libcuttlefish_rild, vendor_cuttlefish_config_server_port_prop) get_prop(libcuttlefish_rild, vendor_modem_simulator_ports_prop) allow libcuttlefish_rild self:{ socket vsock_socket } { create_socket_perms_no_ioctl getattr }; diff --git a/shared/tv/device_vendor.mk b/shared/tv/device_vendor.mk index 77e6a493a..f6e10ab4a 100644 --- a/shared/tv/device_vendor.mk +++ b/shared/tv/device_vendor.mk @@ -25,7 +25,7 @@ $(call inherit-product, device/google/cuttlefish/shared/graphics/device_vendor.m $(call inherit-product, device/google/cuttlefish/shared/swiftshader/device_vendor.mk) $(call inherit-product, device/google/cuttlefish/shared/virgl/device_vendor.mk) $(call inherit-product, device/google/cuttlefish/shared/device.mk) -$(call inherit-product, vendor/google/tv/gcbs/projects/reference-v4/dtvstack.mk) +$(call inherit-product-if-exists, vendor/google/tv/gcbs/projects/reference-v4/dtvstack.mk) # Loads the camera HAL and which set of cameras is required. $(call inherit-product, device/google/cuttlefish/shared/camera/device_vendor.mk) diff --git a/system_image/Android.bp b/system_image/Android.bp index db91323f3..8252664a9 100644 --- a/system_image/Android.bp +++ b/system_image/Android.bp @@ -56,434 +56,17 @@ android_symlinks = [ target: "/system_dlkm/lib/modules", name: "system/lib/modules", }, - { - target: "/apex/com.android.tethering/bin/ethtool", - name: "system/bin/ethtool", - }, ] -android_system_image { - name: "aosp_cf_system_x86_64", - use_avb: true, - avb_private_key: ":microdroid_sign_key", - avb_algorithm: "SHA256_RSA4096", - avb_hash_algorithm: "sha256", - partition_name: "system", - deps: [ - "abb", - "abx", - "abx2xml", - "aconfigd", - "adb_debug.prop", - "adevice_fingerprint", - "aflags", - "aidl_lazy_cb_test_server", - "aidl_lazy_test_server", - "am", - "android_build_prop", - "android_vintf_manifest", - "android.hardware.audio.common-util", - "android.hardware.audio.common-V3-ndk", - "android.hardware.audio.common@5.0-util", - "android.hardware.audio.common@5.0", - "android.hardware.audio.common@6.0-util", - "android.hardware.audio.common@6.0", - "android.hardware.audio.core-V2-ndk", - "android.hardware.audio.core.sounddose-V2-ndk", - "android.hardware.audio.effect-V2-ndk", - "android.hardware.audio.effect.service-aidl.example", - "android.hardware.audio.effect@5.0-util", - "android.hardware.audio.effect@5.0", - "android.hardware.audio.effect@6.0-util", - "android.hardware.audio.effect@6.0", - "android.hardware.audio.effect@7.0-impl", - "android.hardware.audio.service-aidl.example", - "android.hardware.audio@5.0-util", - "android.hardware.audio@5.0", - "android.hardware.audio@6.0-util", - "android.hardware.audio@6.0", - "android.hardware.biometrics.fingerprint@2.1", - "android.hardware.bluetooth.audio-impl", - "android.hardware.boot-service.default_recovery", - "android.hardware.common.fmq-V1-ndk", - "android.hardware.fastboot@1.1-impl-mock", - "android.hardware.graphics.allocator-service.minigbm", - "android.hardware.graphics.mapper@4.0-impl.minigbm", - "android.hardware.health-service.cuttlefish_recovery", - "android.hardware.health-V2-ndk", - "android.hardware.health-V3-ndk", - "android.hardware.power.stats-V1-cpp", - "android.hardware.radio.config@1.0", - "android.hardware.radio.deprecated@1.0", - "android.hardware.radio@1.0", - "android.hardware.radio@1.1", - "android.hardware.radio@1.2", - "android.hardware.radio@1.3", - "android.hardware.radio@1.4", - "android.hardware.secure_element@1.0", - "android.hardware.security.secretkeeper-service.nonsecure", - "android.hidl.allocator@1.0-service", - "android.hidl.memory.token@1.0", - "android.hidl.memory@1.0", - "android.hidl.safe_union@1.0", - "android.media.audio.common.types-V3-ndk", - "android.system.suspend-service", +phony { + name: "fonts", + required: [ "AndroidClock.ttf", - "apexd", - "app_process", - "appops", - "appwidget", - "arping", - "atrace", - "audio.primary.default", - "audioserver", - "auditctl", - "av-audio-types-aidl-V1-ndk", - "avbctl", - "awk", - "bc", - "bcc", - "blank_screen", - "blkid", - "bmgr", - "bootanimation", - "bootctl", - "bootstat", - "boringssl_self_test", - "bpfloader", - "bu", - "bugreport_procdump", - "bugreport", - "bugreportz", - "bzip2", - "cacerts", - "cameraserver", "CarroisGothicSC-Regular.ttf", - "cgroups.json", - "cgroups.recovery.json", - "checkpoint_gc", - "cmd", "ComingSoon.ttf", - "content", - "cppreopts.sh", - "credstore", "CutiveMono.ttf", - "cuttlefish_sensor_injection", "DancingScript-Regular.ttf", - "debuggerd", - "device_config", - "dirty-image-objects", - "dlkm_loader", - "dmabuf_dump", - "dmctl", - "dmesgd", - "dmuserd", - "dnsmasq", - "dpm", "DroidSansMono.ttf", - "dump.erofs", - "dumpstate", - "dumpsys_vendor", - "dumpsys", - "e2freefrag", - "e2fsck", - "e2fsdroid", - "etc_hosts", - "evemu-record", - "extra_free_kbytes", - "fastbootd", - "flags_health_check", - "font_fallback.xml", - "fonts.xml", - "framework-sysconfig.xml", - "fsck_msdos", - "fsck.erofs", - "fsck.exfat", - "fsck.f2fs", - "fstab.cf.ext4.cts", - "fstab.cf.ext4.hctr2", - "fstab.cf.f2fs.cts", - "fstab.cf.f2fs.hctr2", - "fstab.postinstall", - "fsverity_init", - "fsverity-release-cert-der", - "gatekeeperd", - "gpu_counter_producer", - "gpuservice", - "group_odm", - "group_product", - "group_system_ext", - "group_system", - "group_vendor", - "gsi_tool", - "gsid", - "heapprofd_client", - "heapprofd", - "hid", - "hiddenapi-package-whitelist.xml", - "hidl_lazy_cb_test_server", - "hidl_lazy_test_server", - "hwservicemanager", - "idlcli", - "idmap2", - "idmap2d", - "ime", - "incident_helper", - "incident-helper-cmd", - "incident", - "incidentd", - "init-debug.rc", - "init_first_stage", - "init.boringssl.zygote64_32.rc", - "init.boringssl.zygote64.rc", - "init.rc", - "init.usb.configfs.rc", - "init.usb.rc", - "init.zygote32.rc", - "init.zygote64_32.rc", - "init.zygote64.rc", - "initial-package-stopped-states-aosp.xml", - "initial-package-stopped-states.xml", - "input", - "installd", - "iotop", - "ip", - "iperf3", - "iptables", - "iw", - "kcmdlinectrl", - "keystore_cli_v2", - "keystore2", - "layertracegenerator", - "ld.config.recovery.txt", - "ld.mc", - "ldd", - "lib_renderControl_enc", - "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", - "libaudio_aidl_conversion_common_ndk", - "libaudio_aidl_conversion_common_ndk", - "libaudio_aidl_conversion_core_ndk", - "libaudio_aidl_conversion_effect_ndk", - "libaudio-resampler", - "libaudioaidlcommon", - "libaudioaidlcommon", - "libaudioeffect_jni", - "libaudiohal_deathhandler", - "libaudiohal", - "libaudiohal@5.0", - "libaudiohal@6.0", - "libaudiohal@7.0", - "libaudiohal@7.1", - "libaudiohal@aidl", - "libaudiopolicyengineconfigurable", - "libaudiopreprocessing", - "libaudioutils", - "libaudioutils", - "libbinder_ndk", - "libbinder_rpc_unstable", - "libbinder", - "libblas", - "libbootloader_message", - "libbundlewrapper", - "libcamera2ndk", - "libclang_rt.asan", - "libclcore_debug_g.bc", - "libclcore_debug.bc", - "libclcore_g.bc", - "libclcore.bc", - "libclearkeycasplugin", - "libcompiler_rt", - "libcrypto_utils", - "libcups", - "libcutils", - "libdmabufheap", - "libdmabufheap", - "libdownmix", - "libdrm", - "libdrm", - "libdrm", - "libdrmclearkeyplugin", - "libdrmframework_jni", - "libdrmframework", - "libdynproc", - "libeffectproxy", - "libeffects", - "libeffectsconfig", - "libeffectsconfig", - "libEGL_angle", - "libEGL_emulation", - "libEGL", - "libepoxy", - "libETC1", - "libext4_utils", - "libfdtrack", - "libfec", - "libFFTEm", - "libfilterfw", - "libfilterpack_imageproc", - "libfmq", - "libfs_mgr", - "libfwdlockengine", - "libgatekeeper", - "libgbm", - "libGLESv1_CM_angle", - "libGLESv1_CM_emulation", - "libGLESv1_CM", - "libGLESv1_enc", - "libGLESv2_angle", - "libGLESv2_emulation", - "libGLESv2_enc", - "libGLESv2", - "libGLESv3", - "libgralloctypes", - "libgsi", - "libgui", - "libhapticgenerator", - "libhardware_legacy", - "libhardware", - "libhidcommand_jni", - "libhidlmemory", - "libhidlmemory", - "libhidltransport", - "libhwbinder", - "libincident", - "libinput", - "libinputflinger", - "libiprouteutil", - "libjni_deviceAsWebcam", - "libjnigraphics", - "libjpeg", - "libldnhncr", - "liblockagent", - "liblog", - "liblogwrap", - "liblp", - "liblz4", - "libmedia_helper", - "libmedia_helper", - "libmedia_jni", - "libmedia", - "libmediandk", - "libmediaplayerservice", - "libmediautils_delayed", - "libminui", - "libmtp", - "libnativewindow", - "libnetd_client", - "libnetlink", - "libnetutils", - "libneuralnetworks_packageinfo", - "libnfc_nci_jni", - "libnl", - "libOpenglCodecCommon", - "libOpenglSystemCommon", - "libOpenMAXAL", - "libOpenSLES", - "libpdfium", - "libperfetto_android_internal", - "libpolicy-subsystem", - "libpower", - "libpowermanager", - "libprintspooler_jni", - "libprocessgroup_setup", - "libprotobuf-cpp-full", - "libradio_metadata", - "librank", - "libresourcemanagerservice", - "libreverbwrapper", - "libRS_internal", - "librs_jni", - "libRSCacheDir", - "libRSCpuRef", - "libRSDriver", - "librtp_jni", - "libsensorservice", - "libsfplugin_ccodec", - "libskia", - "libsonic", - "libsonivox", - "libsoundpool", - "libspeexresampler", - "libspeexresampler", - "libspeexresampler", - "libsqlite", - "libsquashfs_utils", - "libssl", - "libstagefright_foundation", - "libstagefright_foundation", - "libstagefright_foundation", - "libstagefright_httplive", - "libstagefright_omx", - "libstagefright", - "libstdc++", - "libsync", - "libsysutils", - "libtinyxml2", - "libtombstoned_client", - "libtracingproxy", - "libui", - "libuinputcommand_jni", - "libukey2_jni_shared", - "libusbhost", - "libutils", - "libvendorsupport", - "libvintf_jni", - "libvirglrenderer", - "libvisualizer", - "libvulkan", - "libwebviewchromium_loader", - "libwebviewchromium_plat_support", - "libwfds", - "libwilhelm", - "libxml2", - "libxml2", - "linker", - "llkd", - "lmkd", - "local_time.default", - "lockagent_crasher", - "locksettings", - "logcat", - "logcatd", - "logd", - "logpersist.start", - "logtagd.rc", - "logwrapper", - "lpdump", - "lpdumpd", - "lshal", - "make_f2fs", - "mapper.minigbm", - "mdnsd", - "mediacodec.policy", - "mediaextractor", - "mediametrics", - "migrate_legacy_obb_data", - "mini-keyctl", - "misctrl", - "mke2fs", - "mkfs.erofs", - "mkfs.exfat", - "mm_events", - "monkey", - "mtectrl", - "ndc", - "netd", - "netutils-wrapper-1.0", - "newfs_msdos", "NotoColorEmoji.ttf", "NotoColorEmojiFlags.ttf", "NotoColorEmojiLegacy.ttf", @@ -506,13 +89,13 @@ android_system_image { "NotoSansBrahmi-Regular.ttf", "NotoSansBuginese-Regular.ttf", "NotoSansBuhid-Regular.ttf", + "NotoSansCJK-Regular.ttc", "NotoSansCanadianAboriginal-Regular.ttf", "NotoSansCarian-Regular.ttf", "NotoSansChakma-Regular.otf", "NotoSansCham-Bold.ttf", "NotoSansCham-Regular.ttf", "NotoSansCherokee-Regular.ttf", - "NotoSansCJK-Regular.ttc", "NotoSansCoptic-Regular.ttf", "NotoSansCuneiform-Regular.ttf", "NotoSansCypriot-Regular.ttf", @@ -582,10 +165,10 @@ android_system_image { "NotoSansMyanmarUI-Bold.otf", "NotoSansMyanmarUI-Medium.otf", "NotoSansMyanmarUI-Regular.otf", + "NotoSansNKo-Regular.ttf", "NotoSansNabataean-Regular.otf", - "NotoSansNewa-Regular.otf", "NotoSansNewTaiLue-Regular.ttf", - "NotoSansNKo-Regular.ttf", + "NotoSansNewa-Regular.otf", "NotoSansOgham-Regular.ttf", "NotoSansOlChiki-Regular.ttf", "NotoSansOldItalic-Regular.ttf", @@ -675,340 +258,431 @@ android_system_image { "NotoSerifThai-Regular.ttf", "NotoSerifTibetan-VF.ttf", "NotoSerifYezidi-VF.ttf", - "odsign", - "ot-cli-ftd", - "ot-ctl", - "otapreopt_chroot", - "otapreopt_script", - "otapreopt_slot", - "otapreopt", - "passwd_odm", - "passwd_product", - "passwd_system_ext", - "passwd_system", - "passwd_vendor", - "perfetto", - "ping", - "ping6", - "pintool", - "platform.xml", - "pm", - "power.default", - "preinstalled-packages-asl-files.xml", - "preinstalled-packages-platform-aosp-product.xml", - "preinstalled-packages-platform-generic-system.xml", - "preinstalled-packages-platform-handheld-product.xml", - "preinstalled-packages-platform-handheld-system.xml", - "preinstalled-packages-platform-telephony-product.xml", - "preinstalled-packages-platform.xml", - "preinstalled-packages-strict-signature.xml", - "preloads_copy.sh", - "preloads_copy.sh", - "preopt2cachename", - "preopt2cachename", - "printflags", - "privapp-permissions-platform.xml", - "prng_seeder", - "procrank", - "profcollectctl", - "profcollectd", - "reboot", - "record_binder", - "recovery-persist", - "recovery-refresh", - "recovery", - "remount", - "requestsync", - "resize2fs", "Roboto-Regular.ttf", "RobotoFlex-Regular.ttf", "RobotoStatic-Regular.ttf", - "rss_hwm_reset", - "run-as", - "sample_camera_extensions.xml", - "sanitizer-status", - "schedtest", - "screencap", - "screenrecord", - "sdcard", - "secdiscard", - "sensorservice", - "server_configurable_flags", - "service", - "servicedispatcher", - "servicemanager.recovery", - "servicemanager", - "settaskprofile", - "settings", - "sfdo", - "sgdisk", - "sh", - "showmap", - "simpleperf_app_runner", - "simpleperf", - "sload_f2fs", - "sm", - "snapshotctl", - "snapuserd_ramdisk", - "snapuserd", - "socket_vsock_proxy", "SourceSansPro-Bold.ttf", "SourceSansPro-BoldItalic.ttf", "SourceSansPro-Italic.ttf", "SourceSansPro-Regular.ttf", "SourceSansPro-SemiBold.ttf", "SourceSansPro-SemiBoldItalic.ttf", - "sqlite3", - "ss", - "start_with_lockagent", - "storaged", - "strace", - "surfaceflinger", - "suspend_blocker", - "svc", - "task_profiles.json", - "tc", - "tcpdump", - "telecom", - "tinycap", - "tinyhostless", - "tinymix", - "tinypcminfo", - "tinyplay", - "tombstone_producer", - "tombstone_transmit", - "tombstoned", - "toolbox", - "toybox", - "toybox", - "traced_perf", - "traced_probes", - "traced", - "tracepath", - "tracepath6", - "traceroute6", - "trigger_perfetto", - "tune2fs", - "ueventd.rc", - "uiautomator", - "uinput", - "uncrypt", - "unwind_info", - "unwind_reg_info", - "unwind_symbols", - "update_engine_client", - "update_engine_sideload", - "update_engine", - "update_verifier", - "usbd", - "vdc", - "vibrator.default", - "virtual_camera", - "vold_prepare_subdirs", - "vold", - "vr", - "watchdogd", - "wifi.rc", - "wificond", - "wm", - "xml2abx", - "xtables.lock", - "ziptool", + "font_fallback.xml", + "fonts.xml", + ], +} + +android_system_image { + name: "aosp_cf_system_x86_64", + + partition_name: "system", + base_dir: "system", + dirs: android_rootdirs, + symlinks: android_symlinks, + file_contexts: ":plat_file_contexts", + linker_config_src: "linker.config.json", + fsverity: { + inputs: [ + "etc/boot-image.prof", + "etc/dirty-image-objects", + "etc/preloaded-classes", + "etc/classpaths/*.pb", + "framework/*", + "framework/*/*", // framework/{arch} + "framework/oat/*/*", // framework/oat/{arch} + ], + libs: [":framework-res{.export-package.apk}"], + }, + build_logtags: true, + gen_aconfig_flags_pb: true, + + use_avb: true, + avb_private_key: ":microdroid_sign_key", + avb_algorithm: "SHA256_RSA4096", + avb_hash_algorithm: "sha256", + + deps: [ + "android.hardware.biometrics.fingerprint@2.1", // generic_system + "android.hardware.radio@1.0", // generic_system + "android.hardware.radio@1.1", // generic_system + "android.hardware.radio@1.2", // generic_system + "android.hardware.radio@1.3", // generic_system + "android.hardware.radio@1.4", // generic_system + "android.hardware.radio.config@1.0", // generic_system + "android.hardware.radio.deprecated@1.0", // generic_system + "android.hardware.secure_element@1.0", // generic_system + "abx", + "aconfigd", + "aflags", + "am", + "android_build_prop", + "android_vintf_manifest", + "android.system.suspend-service", + "apexd", + "app_process", + "appops", + "appwidget", + "atrace", + "audioserver", + "bcc", + "blank_screen", + "blkid", + "bmgr", + "bootanimation", + "bootstat", + "boringssl_self_test", + "bpfloader", + "bu", + "bugreport", + "bugreportz", + "cameraserver", + "cgroups.json", + "cmd", + "content", + "cppreopts.sh", // generic_system + "credstore", + "debuggerd", + "device_config", + "dirty-image-objects", + "dmctl", + "dmesgd", + "dnsmasq", + "dpm", + "dump.erofs", + "dumpstate", + "dumpsys", + "e2fsck", + "etc_hosts", + "flags_health_check", + "framework-audio_effects.xml", // for handheld // handheld_system + "framework-sysconfig.xml", + "fsck_msdos", + "fsck.erofs", + "fsck.f2fs", // for media_system + "fsverity-release-cert-der", + "fs_config_files_system", + "fs_config_dirs_system", + "gatekeeperd", + "gpu_counter_producer", + "gpuservice", + "group_system", + "gsi_tool", + "gsid", + "heapprofd_client", + "heapprofd", + "hid", + "hiddenapi-package-whitelist.xml", // from runtime_libart + "idc_data", + "idmap2", + "idmap2d", + "ime", + "incident_helper", + "incident-helper-cmd", + "incident", + "incidentd", + "init_first_stage", // for boot partition + // "init.environ.rc", // TODO: move to soong + "init.usb.configfs.rc", + "init.usb.rc", + "init.zygote32.rc", + "init.zygote64_32.rc", + "init.zygote64.rc", + "initial-package-stopped-states.xml", + "input", + "installd", + "ip", // base_system + "iptables", + "kcmdlinectrl", + "keychars_data", + "keylayout_data", + "keystore2", + "ld.mc", + "libaaudio", + "libalarm_jni", + "libamidi", + "libandroid_runtime", + "libandroid_servers", + "libandroid", + "libandroidfw", + "libartpalette-system", + "libaudio-resampler", // generic-system + "libaudioeffect_jni", + "libaudiohal", // generic-system + "libaudiopolicyengineconfigurable", // generic-system + "libbinder_ndk", + "libbinder_rpc_unstable", + "libbinder", + "libcamera2ndk", + "libclang_rt.asan", + "libcompiler_rt", + "libcutils", // used by many libs + "libdmabufheap", // used by many libs + "libdrm", // used by many libs // generic_system + "libdrmframework_jni", // base_system + "libdrmframework", // base_system + "libEGL_angle", // base_system + "libEGL", // base_system + "libETC1", // base_system + "libfdtrack", // base_system + "libFFTEm", // base_system + "libfilterfw", // base_system + "libfilterpack_imageproc", // media_system + "libfwdlockengine", // generic_system + "libgatekeeper", // base_system + "libGLESv1_CM_angle", // base_system + "libGLESv1_CM", // base_system + "libGLESv2_angle", // base_system + "libGLESv2", // base_system + "libGLESv3", // base_system + "libgui", // base_system + "libhardware_legacy", // base_system + "libhardware", // base_system + "libhidltransport", // generic_system + "libhwbinder", // generic_system + "libinput", // base_system + "libinputflinger", // base_system + "libiprouteutil", // base_system + "libjnigraphics", // base_system + "libjpeg", // base_system + "liblog", // base_system + "liblogwrap", // generic_system + "liblz4", // generic_system + "libmedia_jni", // base_system + "libmedia", // base_system + "libmediandk", // base_system + "libminui", // generic_system + "libmtp", // base_system + "libnetd_client", // base_system + "libnetlink", // base_system + "libnetutils", // base_system + "libneuralnetworks_packageinfo", // base_system + "libnl", // generic_system + "libOpenMAXAL", // base_system + "libOpenSLES", // base_system + "libpdfium", // base_system + "libpolicy-subsystem", // generic_system + "libpower", // base_system + "libpowermanager", // base_system + "libprotobuf-cpp-full", // generic_system + "libradio_metadata", // base_system + "librs_jni", // handheld_system + "librtp_jni", // base_system + "libsensorservice", // base_system + "libsfplugin_ccodec", // base_system + "libskia", // base_system + "libsonic", // base_system + "libsonivox", // base_system + "libsoundpool", // base_system + "libspeexresampler", // base_system + "libsqlite", // base_system + "libstagefright_foundation", // base_system + "libstagefright_omx", // base_system + "libstagefright", // base_system + "libstdc++", // base_system + "libsysutils", // base_system + "libui", // base_system + "libusbhost", // base_system + "libutils", // base_system + "libvintf_jni", // base_system + "libvulkan", // base_system + "libwebviewchromium_loader", // media_system + "libwebviewchromium_plat_support", // media_system + "libwilhelm", // base_system + "linker", // ok + "llkd", // base_system + "lmkd", // base_system + "local_time.default", // handheld_vendo + "locksettings", // base_system + "logcat", // base_system + "logd", // base_system + "lpdump", // base_system + "lshal", // base_system + "make_f2fs", // media_system + "mdnsd", // base_system + "media_profiles_V1_0.dtd", // base_system + "mediacodec.policy", // base_system + "mediaextractor", // base_system + "mediametrics", // base_system + "misctrl", // from base_system + "mke2fs", // base_system + "mkfs.erofs", // base_system + "monkey", // base_system + "mtectrl", // base_system + "ndc", // base_system + "netd", // base_system + "netutils-wrapper-1.0", // full_base + "odsign", // base_system + "otapreopt_script", // generic_system + "passwd_system", // base_system + "perfetto", // base_system + "ping", // base_system + "ping6", // base_system + "pintool", // base_system + "platform.xml", // base_system + "pm", // base_system + "preinstalled-packages-asl-files.xml", // base_system + "preinstalled-packages-platform-generic-system.xml", // generic_system + "preinstalled-packages-platform-handheld-system.xml", // handheld_system + "preinstalled-packages-platform.xml", // base_system + "preinstalled-packages-strict-signature.xml", // base_system + "preloaded-classes", // ok + "printflags", // base_system + "privapp-permissions-platform.xml", // base_system + "prng_seeder", // base_system + "recovery-persist", // base_system + "recovery-refresh", // generic_system + "requestsync", // media_system + "resize2fs", // base_system + "rss_hwm_reset", // base_system + "run-as", // base_system + "schedtest", // base_system + "screencap", // base_system + "screenrecord", // handheld_system + "sdcard", // base_system + "secdiscard", // base_system + "sensorservice", // base_system + "service", // base_system + "servicemanager", // base_system + "settings", // base_system + "sfdo", // base_system + "sgdisk", // base_system + "sm", // base_system + "snapshotctl", // base_system + "snapuserd_ramdisk", // ramdisk + "snapuserd", // base_system + "storaged", // base_system + "surfaceflinger", // base_system + "svc", // base_system + "task_profiles.json", // base_system + "tc", // base_system + "telecom", // base_system + "tombstoned", // base_system + "traced_probes", // base_system + "traced", // base_system + "tune2fs", // base_system + "uiautomator", // base_system + "uinput", // base_system + "uncrypt", // base_system + "update_engine_sideload", // recovery + "update_engine", // generic_system + "update_verifier", // generic_system + "usbd", // base_system + "vdc", // base_system + "virtual_camera", // handheld_system // release_package_virtual_camera + "vold", // base_system + "vr", // handheld_system + "watchdogd", // base_system + "wifi.rc", // base_system + "wificond", // base_system + "wm", // base_system ], multilib: { common: { deps: [ - "AccessibilityMenu", - "adbd_system_api", - "android.hardware.drm@latest-service.clearkey", - "android.hidl.base-V1.0-java", - "android.hidl.manager-V1.0-java", - "android.test.base", - "android.test.mock", - "android.test.runner", - "androidx.camera.extensions.impl", - "androidx.window.extensions", - "androidx.window.sidecar", - "aosp_mainline_modules", - "BackupRestoreConfirmation", - "BasicDreams", - "BlockedNumberProvider", - "BluetoothMidiService", - "BookmarkProvider", - "bpfMemEvents.o", - "bpfMemEventsTest.o", - "bpfRingbufProg.o", - "Browser2", - "BuiltInPrintService", - "Calendar", - "CalendarProvider", - "CallLogBackup", - "Camera2", - "CameraExtensionsProxy", - "CaptivePortalLogin", - "CarrierConfig", - "CarrierDefaultApp", - "CellBroadcastLegacyApp", - "CertInstaller", - "CFSatelliteService", - "charger_res_images", - "com.android.apex.cts.shim.v1_prebuilt", - "com.android.cellbroadcast", - "com.android.compos", - "com.android.future.usb.accessory", - "com.android.hardware.authsecret", - "com.android.hardware.biometrics.face.virtual", - "com.android.hardware.biometrics.fingerprint.virtual", - "com.android.hardware.boot", - "com.android.hardware.cas", - "com.android.hardware.contexthub", - "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", - "com.android.hardware.power", - "com.android.hardware.rebootescrow", - "com.android.hardware.secure_element", - "com.android.hardware.security.authgraph", - "com.android.hardware.sensors", - "com.android.hardware.tetheroffload", - "com.android.hardware.thermal", - "com.android.hardware.threadnetwork", - "com.android.hardware.usb", - "com.android.hardware.uwb", - "com.android.hardware.vibrator", - "com.android.hardware.wifi", - "com.android.i18n", - "com.android.ipsec", - "com.android.hardware.gatekeeper.cf_remote", - "com.android.hardware.gatekeeper.nonsecure", - "com.android.hardware.keymint.rust_cf_remote", - "com.android.hardware.keymint.rust_nonsecure", - "com.android.location.provider", - "com.android.media.remotedisplay.xml", - "com.android.media.remotedisplay", - "com.android.mediadrm.signer", - "com.android.nfc_extras", - "com.android.runtime", - "com.google.cf.bt", - "com.google.cf.confirmationui", - "com.google.cf.health.storage", - "com.google.cf.health", - "com.google.cf.identity", - "com.google.cf.input.config", - "com.google.cf.ir", - "com.google.cf.light", - "com.google.cf.nfc", - "com.google.cf.oemlock", - "com.google.cf.rild", - "com.google.cf.vulkan", - "com.google.cf.wifi", - "CompanionDeviceManager", - "Contacts", - "ContactsProvider", - "CredentialManager", - "CuttlefishService", - "CuttlefishTetheringOverlay", - "CuttlefishWifiOverlay", - "DeskClock", - "DeviceAsWebcam", - "DocumentsUI", - "DownloadProvider", - "DownloadProviderUi", - "DynamicSystemInstallationService", - "EasterEgg", - "EmergencyInfo", - "ext", - "ExternalStorageProvider", - "ExtShared", - "framework-graphics", - "framework-location", - "framework-minus-apex-install-dependencies", - "framework-nfc", - "framework-res", - "FusedLocation", - "fuseMedia.o", - "Gallery2", - "gpuMem.o", - "gpuWork.o", - "HTMLViewer", - "hwservicemanager_compat_symlink_module", - "ims-common", - "ImsServiceEntitlement", - "init_system", - "InputDevices", - "IntentResolver", - "javax.obex", - "KeyChain", - "LatinIME", - "Launcher3QuickStep", - "LiveWallpapersPicker", - "llndk.libraries.txt", - "LocalTransport", - "lockagent", - "ManagedProvisioning", - "MediaProviderLegacy", - "messaging", - "MmsService", - "ModuleMetadata", - "MtpService", - "Music", - "MusicFX", - "NetworkStack", - "NfcNci", - "ONS", - "org.apache.http.legacy", - "PackageInstaller", - "PacProcessor", - "PartnerBookmarksProvider", - "PhotoTable", - "PrintRecommendationService", - "PrintSpooler", - "Provision", - "ProxyHandler", - "QualifiedNetworksService", - "QuickSearchBox", - "SecureElement", - "selinux_policy_system_soong", - "services", - "Settings", - "SettingsIntelligence", - "SettingsProvider", - "SharedStorageBackup", - "shell_and_utilities_recovery", - "shell_and_utilities_system", - "shell_and_utilities_vendor", - "Shell", - "SimAppDialog", - "SoundPicker", - "StatementService", - "Stk", - "StorageManager", - "SystemUI", - "Tag", - "Telecom", - "telephony-common", - "TelephonyProvider", - "TeleService", - "timeInState.o", - "Traceur", - "UserDictionaryProvider", - "voip-common", - "VpnDialogs", - "WallpaperBackup", - "WallpaperCropper", - "webview", + "adbd_system_api", // base_system + "android.hidl.base-V1.0-java", // base_system + "android.hidl.manager-V1.0-java", // base_system + "android.test.base", // from runtime_libart + "android.test.mock", // base_system + "android.test.runner", // base_system + "aosp_mainline_modules", // ok + "BackupRestoreConfirmation", // base_system + "BasicDreams", // handheld_system + "BlockedNumberProvider", // handheld_system + "BluetoothMidiService", // handheld_system + "BookmarkProvider", // handheld_system + "BuiltInPrintService", // handheld_system + "CalendarProvider", // handheld_system + "CallLogBackup", // telephony_system + "CameraExtensionsProxy", // handheld_system + "CaptivePortalLogin", // handheld_system + "CarrierDefaultApp", // telephony_system + "CellBroadcastLegacyApp", // telephony_system + "CertInstaller", // handheld_system + "charger_res_images", // generic_system + "com.android.apex.cts.shim.v1_prebuilt", // ok + "com.android.cellbroadcast", // telephony_system + "com.android.future.usb.accessory", // media_system + "com.android.location.provider", // base_system + "com.android.media.remotedisplay.xml", // media_system + "com.android.media.remotedisplay", // media_system + "com.android.mediadrm.signer", // media_system + "com.android.nfc_extras", // ok + "com.android.runtime", // ok + "CompanionDeviceManager", // media_system + "ContactsProvider", // base_system + "CredentialManager", // handheld_system + "DeviceAsWebcam", // handheld_system + "DocumentsUI", // handheld_system + "DownloadProvider", // base_system + "DownloadProviderUi", // handheld_system + "DynamicSystemInstallationService", // base_system + "EasterEgg", // handheld_system + "ext", // from runtime_libart + "ExternalStorageProvider", // handheld_system + "ExtShared", // base_system + "fonts", // ok + "framework-graphics", // base_system + "framework-location", // base_system + "framework-minus-apex-install-dependencies", // base_system + "framework-nfc", // base_system + "FusedLocation", // handheld_system + "HTMLViewer", // media_system + "hwservicemanager_compat_symlink_module", // base_system + "ims-common", // base_system + "init_system", // base_system + "InputDevices", // handheld_system + "IntentResolver", // base_system + "javax.obex", // base_system + "KeyChain", // handheld_system + "LiveWallpapersPicker", // generic_system, full_base + "llndk.libraries.txt", //ok + "LocalTransport", // base_system + "ManagedProvisioning", // handheld_system + "MediaProviderLegacy", // base_system + "MmsService", // handheld_system + "MtpService", // handheld_system + "MusicFX", // handheld_system + "NetworkStack", // base_system + "NfcNci", // base_system + "ONS", // telephony_system + "org.apache.http.legacy", // base_system + "perfetto-extras", // system + "PackageInstaller", // base_system + "PacProcessor", // handheld_system + "PartnerBookmarksProvider", // generic_system + "PhotoTable", // full_base + "PrintRecommendationService", // handheld_system + "PrintSpooler", // handheld_system + "ProxyHandler", // handheld_system + "SecureElement", // handheld_system + "selinux_policy_system_soong", // ok + "services", // base_system + "SettingsProvider", // base_system + "SharedStorageBackup", // handheld_system + "shell_and_utilities_system", // ok + "Shell", // base_system + "SimAppDialog", // handheld_system + "SoundPicker", // not installed by anyone + "StatementService", // media_system + "Stk", // generic_system + "Tag", // generic_system + "Telecom", // handheld_system + "telephony-common", // libs from TeleService + "TelephonyProvider", // handheld_system + "TeleService", // handheld_system + "Traceur", // handheld_system + "UserDictionaryProvider", // handheld_system + "voip-common", // base_system + "VpnDialogs", // handheld_system + "WallpaperBackup", // base_system ], }, lib32: { deps: [ "android.hardware.audio.service", - "drmserver", - "mediaserver", + "drmserver", // media_system + "mediaserver", // base_system ], }, lib64: { @@ -1019,46 +693,52 @@ android_system_image { ], }, }, - base_dir: "system", - dirs: android_rootdirs, - symlinks: android_symlinks, - file_contexts: ":plat_file_contexts", - linker_config_src: "linker.config.json", - arch: { - x86: { - multilib: { - common: { - deps: [ - "com.android.wifi", - ], - }, - }, - }, - x86_64: { + product_variables: { + debuggable: { deps: [ - "libgfxstream_backend", + "adevice_fingerprint", + "arping", + "avbctl", + "bootctl", + "dmuserd", + "evemu-record", + "idlcli", + "init-debug.rc", + "iotop", + "iperf3", + "iw", + "layertracegenerator", + "logpersist.start", + "logtagd.rc", + "ot-cli-ftd", + "ot-ctl", + "procrank", + "profcollectctl", + "profcollectd", + "record_binder", + "sanitizer-status", + "servicedispatcher", + "showmap", + "sqlite3", + "ss", + "start_with_lockagent", + "strace", + "su", + "tinycap", + "tinyhostless", + "tinymix", + "tinypcminfo", + "tinyplay", // host + "tracepath", + "tracepath6", + "traceroute6", + "unwind_info", + "unwind_reg_info", + "unwind_symbols", + "update_engine_client", ], - multilib: { - common: { - deps: [ - "com.android.wifi", - ], - }, - }, }, }, - fsverity: { - inputs: [ - "etc/boot-image.prof", - "etc/dirty-image-objects", - "etc/preloaded-classes", - "etc/classpaths/*.pb", - "framework/*", - "framework/*/*", // framework/{arch} - "framework/oat/*/*", // framework/oat/{arch} - ], - libs: [":framework-res{.export-package.apk}"], - }, } prebuilt_etc { diff --git a/vsoc_arm64/phone/aosp_cf.mk b/vsoc_arm64/phone/aosp_cf.mk index 3d74e3b38..99e4fc848 100644 --- a/vsoc_arm64/phone/aosp_cf.mk +++ b/vsoc_arm64/phone/aosp_cf.mk @@ -50,7 +50,7 @@ PRODUCT_NAME := aosp_cf_arm64_phone PRODUCT_DEVICE := vsoc_arm64 PRODUCT_MANUFACTURER := Google PRODUCT_MODEL := Cuttlefish arm64 phone -PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 65536 +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 PRODUCT_VENDOR_PROPERTIES += \ ro.soc.manufacturer=$(PRODUCT_MANUFACTURER) \ diff --git a/vsoc_arm64_only/phone/aosp_cf.mk b/vsoc_arm64_only/phone/aosp_cf.mk index 623e79c8e..64d6a6686 100644 --- a/vsoc_arm64_only/phone/aosp_cf.mk +++ b/vsoc_arm64_only/phone/aosp_cf.mk @@ -54,7 +54,7 @@ PRODUCT_NAME := aosp_cf_arm64_only_phone PRODUCT_DEVICE := vsoc_arm64_only PRODUCT_MANUFACTURER := Google PRODUCT_MODEL := Cuttlefish arm64 phone 64-bit only -PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 65536 +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 PRODUCT_VENDOR_PROPERTIES += \ ro.soc.manufacturer=$(PRODUCT_MANUFACTURER) \ diff --git a/vsoc_arm64_pgagnostic/BoardConfig.mk b/vsoc_arm64_pgagnostic/BoardConfig.mk index 240ef74b9..ec1e47934 100644 --- a/vsoc_arm64_pgagnostic/BoardConfig.mk +++ b/vsoc_arm64_pgagnostic/BoardConfig.mk @@ -53,6 +53,8 @@ HOST_CROSS_2ND_ARCH := -include device/google/cuttlefish/shared/telephony/BoardConfig.mk -include device/google/cuttlefish/shared/virgl/BoardConfig.mk +BOARD_16K_OTA_MOVE_VENDOR := true + BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := erofs BOARD_SYSTEMIMAGE_EROFS_BLOCKSIZE := 16384 BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := erofs diff --git a/vsoc_arm64_pgagnostic/phone/aosp_cf.mk b/vsoc_arm64_pgagnostic/phone/aosp_cf.mk index b042b7ebf..e9fcaf605 100644 --- a/vsoc_arm64_pgagnostic/phone/aosp_cf.mk +++ b/vsoc_arm64_pgagnostic/phone/aosp_cf.mk @@ -58,7 +58,7 @@ PRODUCT_NAME := aosp_cf_arm64_phone_pgagnostic PRODUCT_DEVICE := vsoc_arm64_pgagnostic PRODUCT_MANUFACTURER := Google PRODUCT_MODEL := Cuttlefish arm64 phone 64-bit only pgagnostic -PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 65536 +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true PRODUCT_VENDOR_PROPERTIES += \ diff --git a/vsoc_x86_64_pgagnostic/phone/aosp_cf.mk b/vsoc_x86_64_pgagnostic/phone/aosp_cf.mk index a02619b41..2c8d842fc 100644 --- a/vsoc_x86_64_pgagnostic/phone/aosp_cf.mk +++ b/vsoc_x86_64_pgagnostic/phone/aosp_cf.mk @@ -58,7 +58,7 @@ PRODUCT_NAME := aosp_cf_x86_64_phone_pgagnostic PRODUCT_DEVICE := vsoc_x86_64_pgagnostic PRODUCT_MANUFACTURER := Google PRODUCT_MODEL := Cuttlefish x86_64 phone 64-bit only pgagnostic -PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 65536 +PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true # Window Extensions |