diff --git a/base/cvd/adb/patches/0001-drop-fastdeploy.patch b/base/cvd/adb/patches/0001-drop-fastdeploy.patch new file mode 100644 index 00000000000..2ba023374ce --- /dev/null +++ b/base/cvd/adb/patches/0001-drop-fastdeploy.patch @@ -0,0 +1,205 @@ +--- b/base/cvd/adb/client/adb_install.cpp ++++ a/base/cvd/adb/client/adb_install.cpp +@@ -37,14 +37,11 @@ + #include "adb_utils.h" + #include "client/file_sync_client.h" + #include "commandline.h" +-#include "fastdeploy.h" + #include "incremental.h" + #include "sysdeps.h" + + using namespace std::literals; + +-static constexpr int kFastDeployMinApi = 24; +- + namespace { + + enum InstallMode { +@@ -158,7 +155,7 @@ static unique_fd send_command(const std::vector& cmd_args, std::str + } + } + +-static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy) { ++static int install_app_streamed(int argc, const char** argv) { + printf("Performing Streamed Install\n"); + + // The last argument must be the APK file +@@ -176,21 +173,6 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy + error_exit(".apex is not supported on the target device"); + } + +- if (is_apex && use_fastdeploy) { +- error_exit("--fastdeploy doesn't support .apex files"); +- } +- +- if (use_fastdeploy) { +- auto metadata = extract_metadata(file); +- if (metadata.has_value()) { +- // pass all but 1st (command) and last (apk path) parameters through to pm for +- // session creation +- std::vector pm_args{argv + 1, argv + argc - 1}; +- auto patchFd = install_patch(pm_args.size(), pm_args.data()); +- return stream_patch(file, std::move(metadata.value()), std::move(patchFd)); +- } +- } +- + struct stat sb; + if (stat(file, &sb) == -1) { + perror_exit("failed to stat %s", file); +@@ -247,7 +229,7 @@ static int install_app_streamed(int argc, const char** argv, bool use_fastdeploy + return 0; + } + +-static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy) { ++static int install_app_legacy(int argc, const char** argv) { + printf("Performing Push Install\n"); + + // Find last APK argument. +@@ -270,19 +252,6 @@ static int install_app_legacy(int argc, const char** argv, bool use_fastdeploy) + std::string apk_dest = "/data/local/tmp/" + android::base::Basename(argv[last_apk]); + argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ + +- if (use_fastdeploy) { +- auto metadata = extract_metadata(apk_file[0]); +- if (metadata.has_value()) { +- auto patchFd = apply_patch_on_device(apk_dest.c_str()); +- int status = stream_patch(apk_file[0], std::move(metadata.value()), std::move(patchFd)); +- +- result = pm_command(argc, argv); +- delete_device_file(apk_dest); +- +- return status; +- } +- } +- + if (do_sync_push(apk_file, apk_dest.c_str(), false, CompressionType::Any, false, false)) { + result = pm_command(argc, argv); + delete_device_file(apk_dest); +@@ -352,14 +321,7 @@ static int install_app_incremental(int argc, const char** argv, bool wait, bool + } + + static std::pair> calculate_install_mode( +- InstallMode modeFromArgs, bool fastdeploy, CmdlineOption incremental_request) { +- if (incremental_request == CmdlineOption::Enable) { +- if (fastdeploy) { +- error_exit( +- "--incremental and --fast-deploy options are incompatible. " +- "Please choose one"); +- } +- } ++ InstallMode modeFromArgs, CmdlineOption incremental_request) { + + if (modeFromArgs != INSTALL_DEFAULT) { + if (incremental_request == CmdlineOption::Enable) { +@@ -446,61 +408,23 @@ static std::vector parse_install_mode(std::vector argv + return passthrough; + } + +-static std::vector parse_fast_deploy_mode( +- std::vector argv, bool* use_fastdeploy, +- FastDeploy_AgentUpdateStrategy* agent_update_strategy) { +- *use_fastdeploy = false; +- *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; +- +- std::vector passthrough; +- for (auto&& arg : argv) { +- if (arg == "--fastdeploy"sv) { +- *use_fastdeploy = true; +- } else if (arg == "--no-fastdeploy"sv) { +- *use_fastdeploy = false; +- } else if (arg == "--force-agent"sv) { +- *agent_update_strategy = FastDeploy_AgentUpdateAlways; +- } else if (arg == "--date-check-agent"sv) { +- *agent_update_strategy = FastDeploy_AgentUpdateNewerTimeStamp; +- } else if (arg == "--version-check-agent"sv) { +- *agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; +- } else { +- passthrough.push_back(arg); +- } +- } +- return passthrough; +-} +- + int install_app(int argc, const char** argv) { + InstallMode install_mode = INSTALL_DEFAULT; + auto incremental_request = CmdlineOption::None; + bool incremental_wait = false; + +- bool use_fastdeploy = false; +- FastDeploy_AgentUpdateStrategy agent_update_strategy = FastDeploy_AgentUpdateDifferentVersion; +- + auto unused_argv = parse_install_mode({argv, argv + argc}, &install_mode, &incremental_request, + &incremental_wait); +- auto passthrough_argv = +- parse_fast_deploy_mode(std::move(unused_argv), &use_fastdeploy, &agent_update_strategy); ++ auto passthrough_argv = std::move(unused_argv); + + auto [primary_mode, fallback_mode] = +- calculate_install_mode(install_mode, use_fastdeploy, incremental_request); ++ calculate_install_mode(install_mode, incremental_request); + if ((primary_mode == INSTALL_STREAM || + fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) && + best_install_mode() == INSTALL_PUSH) { + error_exit("Attempting to use streaming install on unsupported device"); + } + +- if (use_fastdeploy && get_device_api_level() < kFastDeployMinApi) { +- fprintf(stderr, +- "Fast Deploy is only compatible with devices of API version %d or higher, " +- "ignoring.\n", +- kFastDeployMinApi); +- use_fastdeploy = false; +- } +- fastdeploy_set_agent_update_strategy(agent_update_strategy); +- + if (passthrough_argv.size() < 2) { + error_exit("install requires an apk argument"); + } +@@ -508,11 +432,9 @@ int install_app(int argc, const char** argv) { + auto run_install_mode = [&](InstallMode install_mode, bool silent) { + switch (install_mode) { + case INSTALL_PUSH: +- return install_app_legacy(passthrough_argv.size(), passthrough_argv.data(), +- use_fastdeploy); ++ return install_app_legacy(passthrough_argv.size(), passthrough_argv.data()); + case INSTALL_STREAM: +- return install_app_streamed(passthrough_argv.size(), passthrough_argv.data(), +- use_fastdeploy); ++ return install_app_streamed(passthrough_argv.size(), passthrough_argv.data()); + case INSTALL_INCREMENTAL: + return install_app_incremental(passthrough_argv.size(), passthrough_argv.data(), + incremental_wait, silent); +@@ -681,13 +603,12 @@ int install_multiple_app(int argc, const char** argv) { + InstallMode install_mode = INSTALL_DEFAULT; + auto incremental_request = CmdlineOption::None; + bool incremental_wait = false; +- bool use_fastdeploy = false; + + auto passthrough_argv = parse_install_mode({argv + 1, argv + argc}, &install_mode, + &incremental_request, &incremental_wait); + + auto [primary_mode, fallback_mode] = +- calculate_install_mode(install_mode, use_fastdeploy, incremental_request); ++ calculate_install_mode(install_mode, incremental_request); + if ((primary_mode == INSTALL_STREAM || + fallback_mode.value_or(INSTALL_PUSH) == INSTALL_STREAM) && + best_install_mode() == INSTALL_PUSH) { +--- b/base/cvd/adb/client/commandline.cpp ++++ a/base/cvd/adb/client/commandline.cpp +@@ -66,7 +66,6 @@ using namespace std::string_literals; + #include "bugreport.h" + #include "client/file_sync_client.h" + #include "commandline.h" +-#include "fastdeploy.h" + #include "incremental_server.h" + #include "services.h" + #include "shell_protocol.h" +@@ -189,8 +188,6 @@ static void help() { + " --instant: cause the app to be installed as an ephemeral install app\n" + " --no-streaming: always push APK to device and invoke Package Manager as separate steps\n" + " --streaming: force streaming APK directly into Package Manager\n" +- " --fastdeploy: use fast deploy\n" +- " --no-fastdeploy: prevent use of fast deploy\n" + " --force-agent: force update of deployment agent when using fast deploy\n" + " --date-check-agent: update deployment agent when local version is newer and using fast deploy\n" + " --version-check-agent: update deployment agent when local version has different version code and using fast deploy\n" diff --git a/base/cvd/adb/patches/0002-drop-incremental-update.patch b/base/cvd/adb/patches/0002-drop-incremental-update.patch new file mode 100644 index 00000000000..5a92961d3d1 --- /dev/null +++ b/base/cvd/adb/patches/0002-drop-incremental-update.patch @@ -0,0 +1,274 @@ +--- a/base/cvd/adb/client/incremental_utils.cpp ++++ b/base/cvd/adb/client/incremental_utils.cpp +@@ -21,8 +21,6 @@ + #include + #include + #include +-#include +-#include + + #include + #include +@@ -38,10 +36,6 @@ using namespace std::literals; + + namespace incremental { + +-static constexpr inline int32_t offsetToBlockIndex(int64_t offset) { +- return (offset & ~(kBlockSize - 1)) >> 12; +-} +- + Size verity_tree_blocks_for_file(Size fileSize) { + if (fileSize == 0) { + return 0; +@@ -144,16 +138,6 @@ static T valueAt(borrowed_fd fd, off64_t offset) { + return t; + } + +-static void appendBlocks(int32_t start, int count, std::vector* blocks) { +- if (count == 1) { +- blocks->push_back(start); +- } else { +- auto oldSize = blocks->size(); +- blocks->resize(oldSize + count); +- std::iota(blocks->begin() + oldSize, blocks->end(), start); +- } +-} +- + template + static void unduplicate(std::vector& v) { + std::unordered_set uniques(v.size()); +@@ -162,231 +146,9 @@ static void unduplicate(std::vector& v) { + v.end()); + } + +-static off64_t CentralDirOffset(borrowed_fd fd, Size fileSize) { +- static constexpr int kZipEocdRecMinSize = 22; +- static constexpr int32_t kZipEocdRecSig = 0x06054b50; +- static constexpr int kZipEocdCentralDirSizeFieldOffset = 12; +- static constexpr int kZipEocdCommentLengthFieldOffset = 20; +- +- int32_t sigBuf = 0; +- off64_t eocdOffset = -1; +- off64_t maxEocdOffset = fileSize - kZipEocdRecMinSize; +- int16_t commentLenBuf = 0; +- +- // Search from the end of zip, backward to find beginning of EOCD +- for (int16_t commentLen = 0; commentLen < fileSize; ++commentLen) { +- sigBuf = valueAt(fd, maxEocdOffset - commentLen); +- if (sigBuf == kZipEocdRecSig) { +- commentLenBuf = valueAt( +- fd, maxEocdOffset - commentLen + kZipEocdCommentLengthFieldOffset); +- if (commentLenBuf == commentLen) { +- eocdOffset = maxEocdOffset - commentLen; +- break; +- } +- } +- } +- +- if (eocdOffset < 0) { +- return -1; +- } +- +- off64_t cdLen = static_cast( +- valueAt(fd, eocdOffset + kZipEocdCentralDirSizeFieldOffset)); +- +- return eocdOffset - cdLen; +-} +- +-// Does not support APKs larger than 4GB +-static off64_t SignerBlockOffset(borrowed_fd fd, Size fileSize) { +- static constexpr int kApkSigBlockMinSize = 32; +- static constexpr int kApkSigBlockFooterSize = 24; +- static constexpr int64_t APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42l; +- static constexpr int64_t APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041l; +- +- off64_t cdOffset = CentralDirOffset(fd, fileSize); +- if (cdOffset < 0) { +- return -1; +- } +- // CD offset is where original signer block ends. Search backwards for magic and footer. +- if (cdOffset < kApkSigBlockMinSize || +- valueAt(fd, cdOffset - 2 * sizeof(int64_t)) != APK_SIG_BLOCK_MAGIC_LO || +- valueAt(fd, cdOffset - sizeof(int64_t)) != APK_SIG_BLOCK_MAGIC_HI) { +- return -1; +- } +- int32_t signerSizeInFooter = valueAt(fd, cdOffset - kApkSigBlockFooterSize); +- off64_t signerBlockOffset = cdOffset - signerSizeInFooter - sizeof(int64_t); +- if (signerBlockOffset < 0) { +- return -1; +- } +- int32_t signerSizeInHeader = valueAt(fd, signerBlockOffset); +- if (signerSizeInFooter != signerSizeInHeader) { +- return -1; +- } +- +- return signerBlockOffset; +-} +- +-static std::vector ZipPriorityBlocks(off64_t signerBlockOffset, Size fileSize) { +- int32_t signerBlockIndex = offsetToBlockIndex(signerBlockOffset); +- int32_t lastBlockIndex = offsetToBlockIndex(fileSize); +- const auto numPriorityBlocks = lastBlockIndex - signerBlockIndex + 1; +- +- std::vector zipPriorityBlocks; +- +- // Some magic here: most of zip libraries perform a scan for EOCD record starting at the offset +- // of a maximum comment size from the end of the file. This means the last 65-ish KBs will be +- // accessed first, followed by the rest of the central directory blocks. Make sure we +- // send the data in the proper order, as central directory can be quite big by itself. +- static constexpr auto kMaxZipCommentSize = 64 * 1024; +- static constexpr auto kNumBlocksInEocdSearch = kMaxZipCommentSize / kBlockSize + 1; +- if (numPriorityBlocks > kNumBlocksInEocdSearch) { +- appendBlocks(lastBlockIndex - kNumBlocksInEocdSearch + 1, kNumBlocksInEocdSearch, +- &zipPriorityBlocks); +- appendBlocks(signerBlockIndex, numPriorityBlocks - kNumBlocksInEocdSearch, +- &zipPriorityBlocks); +- } else { +- appendBlocks(signerBlockIndex, numPriorityBlocks, &zipPriorityBlocks); +- } +- +- // Somehow someone keeps accessing the start of the archive, even if there's nothing really +- // interesting there... +- appendBlocks(0, 1, &zipPriorityBlocks); +- return zipPriorityBlocks; +-} +- +-[[maybe_unused]] static ZipArchiveHandle openZipArchiveFd(borrowed_fd fd) { +- bool transferFdOwnership = false; +-#ifdef _WIN32 +- // +- // Need to create a special CRT FD here as the current one is not compatible with +- // normal read()/write() calls that libziparchive uses. +- // To make this work we have to create a copy of the file handle, as CRT doesn't care +- // and closes it together with the new descriptor. +- // +- // Note: don't move this into a helper function, it's better to be hard to reuse because +- // the code is ugly and won't work unless it's a last resort. +- // +- auto handle = adb_get_os_handle(fd); +- HANDLE dupedHandle; +- if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), &dupedHandle, 0, +- false, DUPLICATE_SAME_ACCESS)) { +- D("%s failed at DuplicateHandle: %d", __func__, (int)::GetLastError()); +- return {}; +- } +- int osfd = _open_osfhandle((intptr_t)dupedHandle, _O_RDONLY | _O_BINARY); +- if (osfd < 0) { +- D("%s failed at _open_osfhandle: %d", __func__, errno); +- ::CloseHandle(handle); +- return {}; +- } +- transferFdOwnership = true; +-#else +- int osfd = fd.get(); +-#endif +- ZipArchiveHandle zip; +- if (OpenArchiveFd(osfd, "apk_fd", &zip, transferFdOwnership) != 0) { +- D("%s failed at OpenArchiveFd: %d", __func__, errno); +-#ifdef _WIN32 +- // "_close()" is a secret WinCRT name for the regular close() function. +- _close(osfd); +-#endif +- return {}; +- } +- return zip; +-} +- +-static std::pair> openZipArchive( +- borrowed_fd fd, Size fileSize) { +-#ifndef __LP64__ +- if (fileSize >= INT_MAX) { +- return {openZipArchiveFd(fd), nullptr}; +- } +-#endif +- auto mapping = +- android::base::MappedFile::FromOsHandle(adb_get_os_handle(fd), 0, fileSize, PROT_READ); +- if (!mapping) { +- D("%s failed at FromOsHandle: %d", __func__, errno); +- return {}; +- } +- ZipArchiveHandle zip; +- if (OpenArchiveFromMemory(mapping->data(), mapping->size(), "apk_mapping", &zip) != 0) { +- D("%s failed at OpenArchiveFromMemory: %d", __func__, errno); +- return {}; +- } +- return {zip, std::move(mapping)}; +-} +- +-static std::vector InstallationPriorityBlocks(borrowed_fd fd, Size fileSize) { +- static constexpr std::array additional_matches = { +- "resources.arsc"sv, "AndroidManifest.xml"sv, "classes.dex"sv}; +- auto [zip, _] = openZipArchive(fd, fileSize); +- if (!zip) { +- return {}; +- } +- +- auto matcher = [](std::string_view entry_name) { +- if (entry_name.starts_with("lib/"sv) && entry_name.ends_with(".so"sv)) { +- return true; +- } +- return std::any_of(additional_matches.begin(), additional_matches.end(), +- [entry_name](std::string_view i) { return i == entry_name; }); +- }; +- +- void* cookie = nullptr; +- if (StartIteration(zip, &cookie, std::move(matcher)) != 0) { +- D("%s failed at StartIteration: %d", __func__, errno); +- return {}; +- } +- +- std::vector installationPriorityBlocks; +- ZipEntry64 entry; +- std::string_view entryName; +- while (Next(cookie, &entry, &entryName) == 0) { +- if (entryName == "classes.dex"sv) { +- // Only the head is needed for installation +- int32_t startBlockIndex = offsetToBlockIndex(entry.offset); +- appendBlocks(startBlockIndex, 2, &installationPriorityBlocks); +- D("\tadding to priority blocks: '%.*s' (%d)", (int)entryName.size(), entryName.data(), +- 2); +- } else { +- // Full entries are needed for installation +- off64_t entryStartOffset = entry.offset; +- off64_t entryEndOffset = +- entryStartOffset + +- (entry.method == kCompressStored ? entry.uncompressed_length +- : entry.compressed_length) + +- (entry.has_data_descriptor ? 16 /* sizeof(DataDescriptor) */ : 0); +- int32_t startBlockIndex = offsetToBlockIndex(entryStartOffset); +- int32_t endBlockIndex = offsetToBlockIndex(entryEndOffset); +- int32_t numNewBlocks = endBlockIndex - startBlockIndex + 1; +- appendBlocks(startBlockIndex, numNewBlocks, &installationPriorityBlocks); +- D("\tadding to priority blocks: '%.*s' (%d)", (int)entryName.size(), entryName.data(), +- numNewBlocks); +- } +- } +- +- EndIteration(cookie); +- CloseArchive(zip); +- return installationPriorityBlocks; +-} +- +-std::vector PriorityBlocksForFile(const std::string& filepath, borrowed_fd fd, +- Size fileSize) { +- if (!android::base::EndsWithIgnoreCase(filepath, ".apk"sv)) { +- return {}; +- } +- off64_t signerOffset = SignerBlockOffset(fd, fileSize); +- if (signerOffset < 0) { +- // No signer block? not a valid APK +- return {}; +- } +- std::vector priorityBlocks = ZipPriorityBlocks(signerOffset, fileSize); +- std::vector installationPriorityBlocks = InstallationPriorityBlocks(fd, fileSize); +- +- priorityBlocks.insert(priorityBlocks.end(), installationPriorityBlocks.begin(), +- installationPriorityBlocks.end()); +- unduplicate(priorityBlocks); +- return priorityBlocks; ++std::vector PriorityBlocksForFile(const std::string&, borrowed_fd, ++ Size) { ++ return {}; + } + + } // namespace incremental diff --git a/base/cvd/fastboot/patches/0001-restore-license-banner.patch b/base/cvd/fastboot/patches/0001-restore-license-banner.patch new file mode 100644 index 00000000000..005661f8910 --- /dev/null +++ b/base/cvd/fastboot/patches/0001-restore-license-banner.patch @@ -0,0 +1,72 @@ +diff --git b/base/cvd/fastboot/fs.cpp a/base/cvd/fastboot/fs.cpp +index c8d1b59c9..3e47171b4 100644 +--- b/base/cvd/fastboot/fs.cpp ++++ a/base/cvd/fastboot/fs.cpp +@@ -1,3 +1,19 @@ ++/* ++ * Copyright (C) 2014 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 "fs.h" + + +diff --git b/base/cvd/fastboot/fs.h a/base/cvd/fastboot/fs.h +index 5ae473be5..efee6878f 100644 +--- b/base/cvd/fastboot/fs.h ++++ a/base/cvd/fastboot/fs.h +@@ -1,3 +1,19 @@ ++/* ++ * Copyright (C) 2014 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. ++ */ ++ + #pragma once + + #include +diff --git b/base/cvd/fastboot/util.h a/base/cvd/fastboot/util.h +index fdbc1d699..e737726dd 100644 +--- b/base/cvd/fastboot/util.h ++++ a/base/cvd/fastboot/util.h +@@ -1,3 +1,19 @@ ++/* ++ * Copyright (C) 2018 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ + #pragma once + + #include diff --git a/base/cvd/fastboot/patches/0002-drop-libziparchive-dependency.patch b/base/cvd/fastboot/patches/0002-drop-libziparchive-dependency.patch new file mode 100644 index 00000000000..e113e2d4220 --- /dev/null +++ b/base/cvd/fastboot/patches/0002-drop-libziparchive-dependency.patch @@ -0,0 +1,182 @@ +diff --git b/base/cvd/fastboot/fastboot.cpp a/base/cvd/fastboot/fastboot.cpp +index 1c52da238..41472c286 100644 +--- b/base/cvd/fastboot/fastboot.cpp ++++ a/base/cvd/fastboot/fastboot.cpp +@@ -67,7 +67,7 @@ + #include + #include + #include +-#include ++#include + + #include "bootimg_utils.h" + #include "constants.h" +@@ -713,25 +713,40 @@ static std::vector LoadBootableImage(const std::string& kernel, const std: + return out; + } + +-static bool UnzipToMemory(ZipArchiveHandle zip, const std::string& entry_name, ++static zip_int64_t ExtractToBuffer(zip_file_t *zip_file, std::vector& out) { ++ zip_int64_t bytes_read; ++ zip_uint64_t pos = 0; ++ while ((bytes_read = zip_fread(zip_file, &out[pos], out.size() - pos)) > 0) { ++ pos += bytes_read; ++ } ++ return bytes_read; ++} ++ ++static bool UnzipToMemory(unique_zip_t& zip, const char *entry_name, + std::vector* out) { +- ZipEntry64 zip_entry; +- if (FindEntry(zip, entry_name, &zip_entry) != 0) { +- fprintf(stderr, "archive does not contain '%s'\n", entry_name.c_str()); ++ auto zip_file = zip_fopen(zip.get(), entry_name, 0); ++ if (!zip_file) { ++ fprintf(stderr, "archive does not contain '%s'\n", entry_name); + return false; + } + +- if (zip_entry.uncompressed_length > std::numeric_limits::max()) { +- die("entry '%s' is too large: %" PRIu64, entry_name.c_str(), zip_entry.uncompressed_length); ++ zip_stat_t zstat; ++ zip_stat_init(&zstat); ++ if (zip_stat(zip.get(), entry_name, 0, &zstat) < 0 || !(zstat.valid & ZIP_STAT_SIZE)) { ++ die("size of entry '%s' could not be determined\n", entry_name); + } +- out->resize(zip_entry.uncompressed_length); ++ if (zstat.size > std::numeric_limits::max()) { ++ die("entry '%s' is too large: %" PRIu64, entry_name, zstat.size); ++ } ++ out->resize(zstat.size); + +- fprintf(stderr, "extracting %s (%zu MB) to RAM...\n", entry_name.c_str(), ++ fprintf(stderr, "extracting %s (%zu MB) to RAM...\n", entry_name, + out->size() / 1024 / 1024); + +- int error = +- ExtractToMemory(zip, &zip_entry, reinterpret_cast(out->data()), out->size()); +- if (error != 0) die("failed to extract '%s': %s", entry_name.c_str(), ErrorCodeString(error)); ++ if (ExtractToBuffer(zip_file, *out) < 0) { ++ auto error = zip_file_get_error(zip_file); ++ die("failed to extract '%s': %s", entry_name, zip_error_strerror(error)); ++ } + + return true; + } +@@ -787,22 +802,47 @@ static int make_temporary_fd(const char* what) { + + #endif + +-static unique_fd UnzipToFile(ZipArchiveHandle zip, const char* entry_name) { ++static unique_fd UnzipToFile(unique_zip_t& zip, const char* entry_name) { + unique_fd fd(make_temporary_fd(entry_name)); + +- ZipEntry64 zip_entry; +- if (FindEntry(zip, entry_name, &zip_entry) != 0) { ++ auto zip_file = zip_fopen(zip.get(), entry_name, 0); ++ if (!zip_file) { + fprintf(stderr, "archive does not contain '%s'\n", entry_name); + errno = ENOENT; + return unique_fd(); + } + ++ zip_stat_t zstat; ++ zip_stat_init(&zstat); ++ if (zip_stat(zip.get(), entry_name, 0, &zstat) < 0 || !(zstat.valid & ZIP_STAT_SIZE)) { ++ die("size of entry '%s' could not be determined\n", entry_name); ++ } ++ + fprintf(stderr, "extracting %s (%" PRIu64 " MB) to disk...", entry_name, +- zip_entry.uncompressed_length / 1024 / 1024); ++ zstat.size / 1024 / 1024); ++ + double start = now(); +- int error = ExtractEntryToFile(zip, &zip_entry, fd.get()); +- if (error != 0) { +- die("\nfailed to extract '%s': %s", entry_name, ErrorCodeString(error)); ++ while (true) { ++ // Emulate libziparchive, which uses a 32kB read/write buffer ++ const size_t kBufSize = 32768; ++ std::vector out(kBufSize); ++ auto bytes_read = ExtractToBuffer(zip_file, out); ++ if (bytes_read < 0) { ++ auto error = zip_file_get_error(zip_file); ++ die("\nfailed to extract '%s': %s", entry_name, zip_error_strerror(error)); ++ } ++ if (bytes_read == 0) { ++ break; ++ } ++ ++ ssize_t bytes_written; ++ size_t pos = 0; ++ while ((bytes_written = write(fd.get(), &out[pos], out.size() - pos)) > 0) { ++ pos += bytes_written; ++ } ++ if (bytes_written != 0) { ++ die("\nfailed to write '%s': %s", entry_name, strerror(errno)); ++ } + } + + if (lseek(fd.get(), 0, SEEK_SET) != 0) { +@@ -1954,7 +1994,7 @@ void FlashAllTool::AddFlashTasks(const std::vector* out) const { +- return UnzipToMemory(zip_, name, out); ++ return UnzipToMemory(zip_, name.c_str(), out); + } + + unique_fd ZipImageSource::OpenFile(const std::string& name) const { +@@ -1962,16 +2002,16 @@ unique_fd ZipImageSource::OpenFile(const std::string& name) const { + } + + static void do_update(const char* filename, FlashingPlan* fp) { +- ZipArchiveHandle zip; +- int error = OpenArchive(filename, &zip); +- if (error != 0) { +- die("failed to open zip file '%s': %s", filename, ErrorCodeString(error)); ++ int err; ++ unique_zip_t zip(zip_open(filename, ZIP_RDONLY, &err), zip_close); ++ if (err != 0) { ++ zip_error_t error; ++ zip_error_init_with_code(&error, err); ++ die("failed to open zip file '%s': %s", filename, zip_error_strerror(&error)); + } + fp->source.reset(new ZipImageSource(zip)); + FlashAllTool tool(fp); + tool.Flash(); +- +- CloseArchive(zip); + } + + bool LocalImageSource::ReadFile(const std::string& name, std::vector* out) const { +diff --git b/base/cvd/fastboot/fastboot.h a/base/cvd/fastboot/fastboot.h +index 6a4997049..f68f70100 100644 +--- b/base/cvd/fastboot/fastboot.h ++++ a/base/cvd/fastboot/fastboot.h +@@ -40,7 +40,9 @@ + #include "result.h" + #include "socket.h" + #include "util.h" +-#include "ziparchive/zip_archive.h" ++#include ++ ++using unique_zip_t = std::unique_ptr; + + class FastBootTool { + public: +@@ -135,12 +137,12 @@ class FlashAllTool { + + class ZipImageSource final : public ImageSource { + public: +- explicit ZipImageSource(ZipArchiveHandle zip) : zip_(zip) {} ++ explicit ZipImageSource(unique_zip_t& zip) : zip_(zip) {} + bool ReadFile(const std::string& name, std::vector* out) const override; + unique_fd OpenFile(const std::string& name) const override; + + private: +- ZipArchiveHandle zip_; ++ unique_zip_t& zip_; + }; + + class LocalImageSource final : public ImageSource { diff --git a/base/cvd/mkbootfs/patches/0001-restore-license-banner.patch b/base/cvd/mkbootfs/patches/0001-restore-license-banner.patch new file mode 100644 index 00000000000..4f3a622ebc4 --- /dev/null +++ b/base/cvd/mkbootfs/patches/0001-restore-license-banner.patch @@ -0,0 +1,21 @@ +--- b/base/cvd/mkbootfs/mkbootfs.cpp ++++ a/base/cvd/mkbootfs/mkbootfs.cpp +@@ -1,3 +1,18 @@ ++/* ++ * Copyright (C) 2008 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 + #include diff --git a/base/cvd/teeui/libteeui/patches/0001-fix-Wctad-maybe-unsupported.patch b/base/cvd/teeui/libteeui/patches/0001-fix-Wctad-maybe-unsupported.patch new file mode 100644 index 00000000000..7c3187b201e --- /dev/null +++ b/base/cvd/teeui/libteeui/patches/0001-fix-Wctad-maybe-unsupported.patch @@ -0,0 +1,12 @@ +--- a/base/cvd/teeui/libteeui/include/teeui/font_rendering.h ++++ b/base/cvd/teeui/libteeui/include/teeui/font_rendering.h +@@ -67,6 +67,9 @@ template > class Handle { + T handle_; + }; + ++template ++Handle(T handle) -> Handle>; ++ + #define MAP_HANDLE_DELETER(type, deleter) \ + template <> struct HandleDelete { \ + void operator()(type h) { deleter(h); } \ diff --git a/base/cvd/teeui/libteeui/patches/0002-remove-use-of-literal-operators.patch b/base/cvd/teeui/libteeui/patches/0002-remove-use-of-literal-operators.patch new file mode 100644 index 00000000000..cefd6f3af03 --- /dev/null +++ b/base/cvd/teeui/libteeui/patches/0002-remove-use-of-literal-operators.patch @@ -0,0 +1,115 @@ +commit d22ec7296cbd69e90603d7645b6d75bea6ce4c6d +Author: Jason Macnak +Date: Tue Apr 1 11:03:42 2025 -0700 + + Remove use of literal operators + + ... to make internal build happy + +diff --git a/base/cvd/teeui/libteeui/include/teeui/label.h b/base/cvd/teeui/libteeui/include/teeui/label.h +index 6c7b3d042..e307f9a47 100644 +--- a/base/cvd/teeui/libteeui/include/teeui/label.h ++++ b/base/cvd/teeui/libteeui/include/teeui/label.h +@@ -66,7 +66,7 @@ class LabelImpl { + }; + + LabelImpl() +- : fontSize_(10_px), lineHeight_(12_px), text_{}, horizontalTextAlignment_(Alignment::LEFT), ++ : fontSize_(pxs(10)), lineHeight_(pxs(12)), text_{}, horizontalTextAlignment_(Alignment::LEFT), + verticalTextAlignment_(Alignment::TOP), textColor_(0), font_{}, textId_(0) {} + LabelImpl(pxs fontSize, pxs lineHeight, text_t text, Alignment horizontal, + Alignment verticalJustified, Color textColor, FontBuffer font, uint64_t textId) +diff --git a/base/cvd/teeui/libteeui/include/teeui/utils.h b/base/cvd/teeui/libteeui/include/teeui/utils.h +index 6c2d46bf4..2f64f10ef 100644 +--- a/base/cvd/teeui/libteeui/include/teeui/utils.h ++++ b/base/cvd/teeui/libteeui/include/teeui/utils.h +@@ -528,25 +528,6 @@ using dps = Coordinate; + using mms = Coordinate; + using pxs = Coordinate; + +-constexpr dps operator""_dp(long double dp) { +- return dps(dp); +-} +-constexpr mms operator""_mm(long double mm) { +- return mms(mm); +-} +-constexpr pxs operator""_px(long double px) { +- return pxs(px); +-} +-constexpr dps operator""_dp(unsigned long long dp) { +- return dps(dp); +-} +-constexpr mms operator""_mm(unsigned long long mm) { +- return mms(mm); +-} +-constexpr pxs operator""_px(unsigned long long px) { +- return pxs(px); +-} +- + template class Vec2d { + Coord x_, y_; + +diff --git a/base/cvd/teeui/libteeui/src/label.cpp b/base/cvd/teeui/libteeui/src/label.cpp +index 6dfd8f79a..188a9d645 100644 +--- a/base/cvd/teeui/libteeui/src/label.cpp ++++ b/base/cvd/teeui/libteeui/src/label.cpp +@@ -63,7 +63,7 @@ Error LabelImpl::draw(const PixelDrawer& drawPixel, const Box& bounds, Line + drawBox(bounds, 0xff); + #endif + +- Point pen = {0_px, 0_px}; ++ Point pen = {pxs(0), pxs(0)}; + auto textBegin = text_.begin(); + optional> boundingBox; + +@@ -95,7 +95,7 @@ Error LabelImpl::draw(const PixelDrawer& drawPixel, const Box& bounds, Line + case Alignment::BOTTOM: + break; + case Alignment::CENTER: +- pen += {(bounds.w() - bBox.w()) / 2.0_px, 0}; ++ pen += {(bounds.w() - bBox.w()) / pxs(2.0), 0}; + break; + case Alignment::RIGHT: + pen += {bounds.w() - bBox.w(), 0}; +@@ -116,7 +116,7 @@ Error LabelImpl::draw(const PixelDrawer& drawPixel, const Box& bounds, Line + textBegin++; + } + +- pen += {0_px, lineHeight_}; ++ pen += {pxs(0), lineHeight_}; + ++curLine; + } + +@@ -128,7 +128,7 @@ Error LabelImpl::draw(const PixelDrawer& drawPixel, const Box& bounds, Line + TEEUI_LOG << "Offset: " << offset << ENDL; + + if (verticalTextAlignment_ == Alignment::CENTER) +- offset += {0, (bounds.h() - boundingBox->h()) / 2.0_px}; ++ offset += {0, (bounds.h() - boundingBox->h()) / pxs(2.0)}; + else if (verticalTextAlignment_ == Alignment::BOTTOM) + offset += {0, (bounds.h() - boundingBox->h())}; + +diff --git a/base/cvd/teeui/libteeui/src/utils.cpp b/base/cvd/teeui/libteeui/src/utils.cpp +index 8e8c2eed8..246f31b42 100644 +--- a/base/cvd/teeui/libteeui/src/utils.cpp ++++ b/base/cvd/teeui/libteeui/src/utils.cpp +@@ -93,8 +93,8 @@ Color drawLinePoint(Point a, Point b, Point px_origin, Color c, p + auto len = line.length(); + auto l = line / len; + auto seg = l * (px_origin - b); +- auto dist = 0_px; +- if (seg < 0_px) { ++ auto dist = pxs(0); ++ if (seg < pxs(0)) { + // line = px_origin - b; + // dist = line.length(); + // line /= dist; +@@ -108,7 +108,7 @@ Color drawLinePoint(Point a, Point b, Point px_origin, Color c, p + return 0; + } else { + line = Point(-line.y(), line.x()) / len; +- dist = (line * (px_origin - a)).abs() - width + .5_px; ++ dist = (line * (px_origin - a)).abs() - width + pxs(.5); + } + + return pixelLineIntersect(line, dist, c); diff --git a/base/cvd/teeui/libteeui/prebuilt/localization/Android.bp b/base/cvd/teeui/libteeui/prebuilt/localization/Android.bp deleted file mode 100644 index 0e27bc42b73..00000000000 --- a/base/cvd/teeui/libteeui/prebuilt/localization/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -package { - default_team: "trendy_team_pixel_system_sw_security", - default_applicable_licenses: ["Android-Apache-2.0"], -} - -cc_library_static { - name: "libteeui_localization", - defaults: ["keystore_defaults"], - export_include_dirs: ["include"], - srcs: [ - "ConfirmationUITranslations.cpp", - ], - host_supported: true, - vendor_available: true, -} - -cc_test { - name: "ConfirmationUITranslations_test", - srcs: [ - "ConfirmationUITranslations-test.cpp", - ], - static_libs: [ - "libteeui_localization", - ], - gtest: false, - host_supported: true, - cflags: [ - "-ffunction-sections", - ], -} diff --git a/base/cvd/update_aosp_sources.sh b/base/cvd/update_aosp_sources.sh new file mode 100755 index 00000000000..b5540fbf869 --- /dev/null +++ b/base/cvd/update_aosp_sources.sh @@ -0,0 +1,250 @@ +#!/bin/bash + +set -e + +usage() { + echo "usage: $0 [/path/to/android/source/tree]" + exit +} +[ -z "$1" ] && usage + +# $1 = array name to update with checked path +# $2 = suffix applied to variable name set to checked path +# $3 = check this path is an existing directory +check_dir() { + local -n array="${1}" + if [ ! -d "${3}" ]; then + echo "${3} does not exist!" + exit + fi + eval ${3##*/}${2}="${3}" + array+=("${3}") +} + +script_dir="$(dirname $(readlink -f "$0"))" +cd ${script_dir} + +source_dirs=() +add_source_dir() { + check_dir source_dirs "_source" "${1}" +} +add_source_dir "$1/packages/modules/adb" +add_source_dir "$1/system/core/diagnose_usb" +add_source_dir "$1/system/core/fastboot" +add_source_dir "$1/system/core/fs_mgr/libstorage_literals" +add_source_dir "$1/system/core/libcrypto_utils" +add_source_dir "$1/system/core/mkbootfs" +add_source_dir "$1/system/extras/ext4_utils" +add_source_dir "$1/system/extras/libfec" +add_source_dir "$1/system/extras/verity" +add_source_dir "$1/system/teeui/libteeui" +# Can now access with e.g. $adb_source or $source_dirs[x] + +dest_dirs=() +add_dest_dir() { + check_dir dest_dirs "" "${1}" +} +add_dest_dir "adb" +add_dest_dir "fastboot" +add_dest_dir "fec" +add_dest_dir "libext4_utils" +add_dest_dir "mkbootfs" +add_dest_dir "teeui/libteeui" +# Can now access with e.g. $adb or $dest_dirs[x] + +echo "WARNING: This script MUST be run against an AOSP / publicly released Android tree." +echo "WARNING: Do not run it against an internal Android tree under any circumstance!" +echo +while true; do + read -p "Do you understand the above instructions? " yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac +done +echo + +# $1 = prefix for excluded paths +# $2 = array of paths to exclude from cleaning +excluded_files=() +clean_dest_excluded() { + local -n array="${2}" + find -type f \( \ + -not -name BUILD.bazel \ + -and -not -name "*.patch" \ + $(for file in ${array[@]}; do echo -and -not -path ./${file}; done) \ + \) -exec rm -f '{}' ';' + excluded_files+=("${array[@]/#/$1/}") +} +clean_dest() { + local empty=() + clean_dest_excluded "" empty +} + +adb() { + # version.h and platform_tools_version.h are generated files in AOSP + local adb_excluded_files=("version/build/version.h" + "version/platform_tools_version.h") + clean_dest_excluded adb adb_excluded_files + + cp -a "${adb_source}"/* . + cp -a "${diagnose_usb_source}"/* diagnose_usb/ + cp -a "${libcrypto_utils_source}"/* libcrypto_utils/ + + # Remove Android build system and metadata + find \( -name Android.bp -or -name OWNERS \) -exec rm -f '{}' ';' + rm -f adbd_flags.aconfig METADATA MODULE_LICENSE_* NOTICE PREUPLOAD.cfg TEST_MAPPING + rm -rf apex + + # Remove coverage instrumentation + rm -rf coverage + + # Remove documentation + rm -rf docs/ README.md sockets.dia + + # Remove tools + rm -rf adb.bash tools/ + + # Remove symbol map text files, as the modules using them are not built + find -name '*.map.txt' -exec rm -f '{}' ';' + + # Remove osx and windows support + find \( -name '*_osx*' -or -name 'fdevent_poll*' -or -name '*_windows*' -or -name '*win32*' \) -exec rm -rf '{}' ';' 2>/dev/null || true + + # Remove all tests, as they are not built and have additional dependencies + find \( -name '*_test.*' -or -name tests -or -name 'test_*' \) -exec rm -rf '{}' ';' 2>/dev/null || true + rm -f adb_integration_test_* run-device-tests.sh + + # Remove all benchmarks, as they are not built and have additional dependencies + find \( -name '*_benchmark.*' -or -name 'benchmark_*' -or -name trace.sh \) -exec rm -rf '{}' ';' + + # Remove fastdeploy + rm -rf client/fastdeploy.* fastdeploy/ proto/jarjar-rules.txt + + # Remove adb device-side daemon sources + rm -rf daemon/ libs/ security_log_tags.h transfer_id.h + find pairing_connection \( -name 'pairing_server*' -or -name internal \) -exec rm -rf '{}' ';' 2>/dev/null || true +} + +fastboot() { + # version.h and platform_tools_version.h are generated files in AOSP + local fastboot_excluded_files=("version/build/version.h" + "version/platform_tools_version.h") + clean_dest_excluded fastboot fastboot_excluded_files + + cp -a "${fastboot_source}"/* . + cp -a "${diagnose_usb_source}"/* diagnose_usb/ + cp -a "${libstorage_literals_source}"/* libstorage_literals/ + + # Remove fuzzers + rm -rf fuzzer fuzzy_fastboot + + # Remove osx and windows support + find \( -name '*_osx*' -or -name '*_windows*' \) -exec rm -rf '{}' ';' 2>/dev/null || true + + # Remove Android build system and metadata + find \( -name Android.bp -or -name OWNERS \) -exec rm -f '{}' ';' + rm -f LICENSE README.md TEST_MAPPING + + # Remove device-side implementation + rm -rf device + + # Remove tools + rm -rf fastboot.bash + + # Remove all tests, as they are not built and have additional dependencies + find \( \ + -name '*_test.*' -or -name 'test_*' -or -name tests -or \ + -name '*_mock.*' -or -name 'mock_*' \ + \) -exec rm -rf '{}' ';' 2>/dev/null || true + rm -rf testdata +} + +fec() { + # Compat.h is stubbed as it is not used + # squashfs_utils.h is stubbed to avoid a libsquashfs_utils dependency + local fec_excluded_files=("libutils/include/utils/Compat.h" + "squashfs_utils/squashfs_utils.h") + clean_dest_excluded fec fec_excluded_files + + cp -a "${libcrypto_utils_source}"/include/* libcrypto_utils/include/ + cp -a "${libfec_source}"/* libfec/ + cp -a "${verity_source}"/fec/* verity/fec/ + + # Remove Android build system and metadata + find \( -name Android.bp -or -name OWNERS -or -name NOTICE \) -exec rm -f '{}' ';' + + # Remove all tests, as they are not built and have additional dependencies + find \( -name test -or -name tests \) -exec rm -rf '{}' ';' 2>/dev/null || true +} + +libext4_utils() { + clean_dest + + cp -a "${ext4_utils_source}"/* . + chmod a+x mkuserimg_mke2fs.py + + # Remove Android build system and metadata + rm -f Android.bp MODULE_LICENSE_* NOTICE OWNERS + + # Remove unused blk_allow_to_base_fs and "wipe" APIs + rm -f blk_alloc_to_base_fs.cpp include/ext4_utils/wipe.h wipe.cpp + + # Remove all tests, as they are not built and have additional dependencies + find -name 'test_*' -exec rm -f '{}' ';' 2>/dev/null +} + +libteeui() { + clean_dest + + cp -a "${libteeui_source}"/* . + + # Remove Android build system + find -name Android.bp -exec rm -f '{}' ';' + + # Remove generic operation/messages support + rm -f \ + include/teeui/cbor.h \ + include/teeui/generic_messages.h \ + include/teeui/generic_operation.h \ + src/cbor.cpp \ + src/generic_messages.cpp \ + src/msg_formatting.cpp + + # Remove input device support + rm -rf include/secure_input/ src/evdev.cpp src/weak_secure_input_device.cpp + + # Remove example code + rm -rf example/ include/teeui/example/ include/teeui/incfont.h +} + +mkbootfs() { + clean_dest + + cp -a "${mkbootfs_source}"/* . + + # Remove Android build system + rm -f Android.bp +} + +# Copy, prune and optionally patch the upstream sources +for dir in ${dest_dirs[@]}; do + pushd "${dir}" >/dev/null + ${dir##*/} + if [ -d patches ]; then + for patch in patches/*; do + echo Applying patch "$dir/$patch"... + level=$((4 + $(echo $dir | tr -cd / | wc -c))) + patch --no-backup-if-mismatch -Np${level} -i $patch || true + echo + done + fi + popd >/dev/null +done + +echo "WARNING: If necessary, please update:" +echo +for file in ${excluded_files[@]}; do echo "$file"; done +echo +echo "Done!"