Merge "Snap for 8253222 from 13907aef6b89af5ff396e8e4459ea52d450bdf27 to sdk-release" into sdk-release
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index 0d99273..d58158d 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -114,7 +114,7 @@
static_assert(sizeof(struct misc_virtual_ab_message) == 64,
"struct misc_virtual_ab_message has wrong size");
static_assert(sizeof(struct misc_memtag_message) == 64,
- "struct misc_virtual_ab_message has wrong size");
+ "struct misc_memtag_message has wrong size");
#endif
// This struct is not meant to be used directly, rather, it is to make
diff --git a/fuse_sideload/fuse_provider.cpp b/fuse_sideload/fuse_provider.cpp
index 8fa1b5c..2183d08 100644
--- a/fuse_sideload/fuse_provider.cpp
+++ b/fuse_sideload/fuse_provider.cpp
@@ -118,11 +118,16 @@
}
if (uint64_t tailing_bytes = fetch_size % source_block_size_; tailing_bytes != 0) {
- // Calculate the offset to last partial block.
+ // Calculate the offset to last partial block. Two possibilities as below:
+ // 1: fetch_size < source_block_size_, the read_ranges is a blank range_set.
+ // Get the last block num through GetBlockNumber() of the offset block.
+ // 2: fetch_size >= source_block_size_, the last block num is already stored
+ // in read-ranges by GetSubRanges() above.
uint64_t tailing_offset =
read_ranges.value()
? static_cast<uint64_t>((read_ranges->cend() - 1)->second) * source_block_size_
- : static_cast<uint64_t>(start_block) * source_block_size_;
+ : static_cast<uint64_t>(ranges_.GetBlockNumber(offset / source_block_size_)) *
+ source_block_size_;
if (!android::base::ReadFullyAtOffset(fd_, next_out, tailing_bytes, tailing_offset)) {
PLOG(ERROR) << "Failed to read tailing " << tailing_bytes << " bytes at offset "
<< tailing_offset;
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index ee79a32..5cba7b6 100644
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -90,11 +90,12 @@
// Installs the package from FUSE. Returns the installation result and whether it should continue
// waiting for new commands.
-static auto AdbInstallPackageHandler(RecoveryUI* ui, InstallResult* result) {
+static auto AdbInstallPackageHandler(Device* device, InstallResult* result) {
// How long (in seconds) we wait for the package path to be ready. It doesn't need to be too long
// because the minadbd service has already issued an install command. FUSE_SIDELOAD_HOST_PATHNAME
// will start to exist once the host connects and starts serving a package. Poll for its
// appearance. (Note that inotify doesn't work with FUSE.)
+ auto ui = device->GetUI();
constexpr int ADB_INSTALL_TIMEOUT = 15;
bool should_continue = true;
*result = INSTALL_ERROR;
@@ -114,7 +115,7 @@
auto package =
Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME,
std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
- *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, ui);
+ *result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0, device);
break;
}
@@ -348,7 +349,7 @@
InstallResult install_result = INSTALL_ERROR;
std::map<MinadbdCommand, CommandFunction> command_map{
- { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, ui, &install_result) },
+ { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, device, &install_result) },
{ MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid,
&install_result, reboot_action) },
{ MinadbdCommand::kRebootBootloader,
diff --git a/install/fuse_install.cpp b/install/fuse_install.cpp
index 143b5d3..197e1de 100644
--- a/install/fuse_install.cpp
+++ b/install/fuse_install.cpp
@@ -146,10 +146,11 @@
return run_fuse_sideload(std::move(fuse_data_provider)) == 0;
}
-InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui) {
+InstallResult InstallWithFuseFromPath(std::string_view path, Device* device) {
// We used to use fuse in a thread as opposed to a process. Since accessing
// through fuse involves going from kernel to userspace to kernel, it leads
// to deadlock when a page fault occurs. (Bug: 26313124)
+ auto ui = device->GetUI();
pid_t child;
if ((child = fork()) == 0) {
bool status = StartInstallPackageFuse(path);
@@ -183,8 +184,8 @@
auto package =
Package::CreateFilePackage(FUSE_SIDELOAD_HOST_PATHNAME,
std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
- result =
- InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */, ui);
+ result = InstallPackage(package.get(), FUSE_SIDELOAD_HOST_PATHNAME, false, 0 /* retry_count */,
+ device);
break;
}
@@ -226,7 +227,7 @@
ui->Print("\n-- Install %s ...\n", path.c_str());
SetSdcardUpdateBootloaderMessage();
- auto result = InstallWithFuseFromPath(path, ui);
+ auto result = InstallWithFuseFromPath(path, device);
ensure_path_unmounted(SDCARD_ROOT);
return result;
}
diff --git a/install/include/install/fuse_install.h b/install/include/install/fuse_install.h
index 63b116a..29c283f 100644
--- a/install/include/install/fuse_install.h
+++ b/install/include/install/fuse_install.h
@@ -25,6 +25,6 @@
// Starts FUSE with the package from |path| as the data source. And installs the package from
// |FUSE_SIDELOAD_HOST_PATHNAME|. The |path| can point to the location of a package zip file or a
// block map file with the prefix '@'; e.g. /sdcard/package.zip, @/cache/recovery/block.map.
-InstallResult InstallWithFuseFromPath(std::string_view path, RecoveryUI* ui);
+InstallResult InstallWithFuseFromPath(std::string_view path, Device* device);
InstallResult ApplyFromSdcard(Device* device);
diff --git a/install/include/install/install.h b/install/include/install/install.h
index 704841f..0f5102f 100644
--- a/install/include/install/install.h
+++ b/install/include/install/install.h
@@ -25,6 +25,7 @@
#include <ziparchive/zip_archive.h>
#include "otautil/package.h"
+#include "recovery_ui/device.h"
#include "recovery_ui/ui.h"
enum InstallResult {
@@ -49,7 +50,8 @@
// cache partition after a successful installation if |should_wipe_cache| is true or an updater
// command asks to wipe the cache.
InstallResult InstallPackage(Package* package, const std::string_view package_id,
- bool should_wipe_cache, int retry_count, RecoveryUI* ui);
+ bool should_wipe_cache, int retry_count,
+ Device* ui);
// Verifies the package by ota keys. Returns true if the package is verified successfully,
// otherwise returns false.
diff --git a/install/install.cpp b/install/install.cpp
index bb8c3b8..811bcb0 100644
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -235,30 +235,41 @@
return true;
}
-bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd,
- std::vector<std::string>* cmd) {
- CHECK(cmd != nullptr);
-
+static std::string ExtractPayloadProperties(ZipArchiveHandle zip) {
// For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
// in the zip file.
static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
ZipEntry64 properties_entry;
if (FindEntry(zip, AB_OTA_PAYLOAD_PROPERTIES, &properties_entry) != 0) {
LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
- return false;
+ return {};
}
auto properties_entry_length = properties_entry.uncompressed_length;
if (properties_entry_length > std::numeric_limits<size_t>::max()) {
LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES
<< " because's uncompressed size exceeds size of address space. "
<< properties_entry_length;
- return false;
+ return {};
}
- std::vector<uint8_t> payload_properties(properties_entry_length);
+ std::string payload_properties(properties_entry_length, '\0');
int32_t err =
- ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
+ ExtractToMemory(zip, &properties_entry, reinterpret_cast<uint8_t*>(payload_properties.data()),
+ properties_entry_length);
if (err != 0) {
LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
+ return {};
+ }
+ return payload_properties;
+}
+
+bool SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int status_fd,
+ std::vector<std::string>* cmd) {
+ CHECK(cmd != nullptr);
+
+ // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
+ // in the zip file.
+ const auto payload_properties = ExtractPayloadProperties(zip);
+ if (payload_properties.empty()) {
return false;
}
@@ -332,10 +343,20 @@
}
}
+static bool PerformPowerwashIfRequired(ZipArchiveHandle zip, Device *device) {
+ const auto payload_properties = ExtractPayloadProperties(zip);
+ if (payload_properties.find("POWERWASH=1") != std::string::npos) {
+ LOG(INFO) << "Payload properties has POWERWASH=1, wiping userdata...";
+ return WipeData(device, true);
+ }
+ return true;
+}
+
// If the package contains an update binary, extract it and run it.
static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
std::vector<std::string>* log_buffer, int retry_count,
- int* max_temperature, RecoveryUI* ui) {
+ int* max_temperature, Device* device) {
+ auto ui = device->GetUI();
std::map<std::string, std::string> metadata;
auto zip = package->GetZipArchiveHandle();
if (!ReadMetadataFromPackage(zip, &metadata)) {
@@ -530,13 +551,15 @@
} else {
LOG(FATAL) << "Invalid status code " << status;
}
+ PerformPowerwashIfRequired(zip, device);
return INSTALL_SUCCESS;
}
static InstallResult VerifyAndInstallPackage(Package* package, bool* wipe_cache,
std::vector<std::string>* log_buffer, int retry_count,
- int* max_temperature, RecoveryUI* ui) {
+ int* max_temperature, Device* device) {
+ auto ui = device->GetUI();
ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
// Give verification half the progress bar...
ui->SetProgressType(RecoveryUI::DETERMINATE);
@@ -554,7 +577,8 @@
ui->Print("Retry attempt: %d\n", retry_count);
}
ui->SetEnableReboot(false);
- auto result = TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, ui);
+ auto result =
+ TryUpdateBinary(package, wipe_cache, log_buffer, retry_count, max_temperature, device);
ui->SetEnableReboot(true);
ui->Print("\n");
@@ -562,7 +586,8 @@
}
InstallResult InstallPackage(Package* package, const std::string_view package_id,
- bool should_wipe_cache, int retry_count, RecoveryUI* ui) {
+ bool should_wipe_cache, int retry_count, Device* device) {
+ auto ui = device->GetUI();
auto start = std::chrono::system_clock::now();
int start_temperature = GetMaxValueFromThermalZone();
@@ -584,7 +609,7 @@
} else {
bool updater_wipe_cache = false;
result = VerifyAndInstallPackage(package, &updater_wipe_cache, &log_buffer, retry_count,
- &max_temperature, ui);
+ &max_temperature, device);
should_wipe_cache = should_wipe_cache || updater_wipe_cache;
}
diff --git a/recovery.cpp b/recovery.cpp
index 641fe47..0c977c3 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -752,20 +752,20 @@
status = INSTALL_ERROR;
} else if (install_with_fuse || should_use_fuse) {
LOG(INFO) << "Installing package " << update_package << " with fuse";
- status = InstallWithFuseFromPath(update_package, ui);
+ status = InstallWithFuseFromPath(update_package, device);
} else if (auto memory_package = Package::CreateMemoryPackage(
update_package,
std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
memory_package != nullptr) {
status = InstallPackage(memory_package.get(), update_package, should_wipe_cache,
- retry_count, ui);
+ retry_count, device);
} else {
// We may fail to memory map the package on 32 bit builds for packages with 2GiB+ size.
// In such cases, we will try to install the package with fuse. This is not the default
// installation method because it introduces a layer of indirection from the kernel space.
LOG(WARNING) << "Failed to memory map package " << update_package
<< "; falling back to install with fuse";
- status = InstallWithFuseFromPath(update_package, ui);
+ status = InstallWithFuseFromPath(update_package, device);
}
if (status != INSTALL_SUCCESS) {
ui->Print("Installation aborted.\n");
diff --git a/recovery_ui/ethernet_device.cpp b/recovery_ui/ethernet_device.cpp
index d79f41d..0318db8 100644
--- a/recovery_ui/ethernet_device.cpp
+++ b/recovery_ui/ethernet_device.cpp
@@ -30,10 +30,12 @@
#include "recovery_ui/ethernet_device.h"
#include "recovery_ui/ethernet_ui.h"
-const std::string EthernetDevice::interface = "eth0";
+// Android TV defaults to eth0 for it's interface
+EthernetDevice::EthernetDevice(EthernetRecoveryUI* ui) : EthernetDevice(ui, "eth0") {}
-EthernetDevice::EthernetDevice(EthernetRecoveryUI* ui)
- : Device(ui), ctl_sock_(socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) {
+// Allow future users to define the interface as they prefer
+EthernetDevice::EthernetDevice(EthernetRecoveryUI* ui, std::string interface)
+ : Device(ui), ctl_sock_(socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)), interface_(interface) {
if (ctl_sock_ < 0) {
PLOG(ERROR) << "Failed to open socket";
}
@@ -63,7 +65,7 @@
}
memset(&ifr, 0, sizeof(struct ifreq));
- strncpy(ifr.ifr_name, interface.c_str(), IFNAMSIZ);
+ strncpy(ifr.ifr_name, interface_.c_str(), IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(ctl_sock_, SIOCGIFFLAGS, &ifr) < 0) {
@@ -96,7 +98,7 @@
std::unique_ptr<struct ifaddrs, decltype(&freeifaddrs)> guard{ ifaddr, freeifaddrs };
for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr->sa_family != AF_INET6 || interface != ifa->ifa_name) {
+ if (ifa->ifa_addr->sa_family != AF_INET6 || interface_ != ifa->ifa_name) {
continue;
}
diff --git a/recovery_ui/include/recovery_ui/ethernet_device.h b/recovery_ui/include/recovery_ui/ethernet_device.h
index ea710ab..3aadea2 100644
--- a/recovery_ui/include/recovery_ui/ethernet_device.h
+++ b/recovery_ui/include/recovery_ui/ethernet_device.h
@@ -27,6 +27,7 @@
class EthernetDevice : public Device {
public:
explicit EthernetDevice(EthernetRecoveryUI* ui);
+ explicit EthernetDevice(EthernetRecoveryUI* ui, std::string interface);
void PreRecovery() override;
void PreFastboot() override;
@@ -36,7 +37,7 @@
void SetTitleIPv6LinkLocalAddress(const bool interface_up);
android::base::unique_fd ctl_sock_;
- static const std::string interface;
+ std::string interface_;
};
#endif // _ETHERNET_RECOVERY_DEVICE_H
diff --git a/tests/Android.bp b/tests/Android.bp
index 7f00adc..9ad3d3b 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -134,6 +134,10 @@
test_suites: ["device-tests"],
+ tidy_timeout_srcs: [
+ "unit/commands_test.cpp",
+ ],
+
srcs: [
"unit/*.cpp",
],
@@ -192,6 +196,10 @@
"libupdater_defaults",
],
+ tidy_timeout_srcs: [
+ "unit/host/imgdiff_test.cpp",
+ ],
+
srcs: [
"unit/host/*",
],
diff --git a/tests/unit/host/update_simulator_test.cpp b/tests/unit/host/update_simulator_test.cpp
index fb12178..1603982 100644
--- a/tests/unit/host/update_simulator_test.cpp
+++ b/tests/unit/host/update_simulator_test.cpp
@@ -101,7 +101,7 @@
// TODO(xunchang) check the recovery&system has the expected contents.
}
-class UpdateSimulatorTest : public ::testing::Test {
+class DISABLED_UpdateSimulatorTest : public ::testing::Test {
protected:
void SetUp() override {
std::vector<string> props = {
@@ -147,7 +147,7 @@
string sparse_system_string_;
};
-TEST_F(UpdateSimulatorTest, TargetFile_ExtractImage) {
+TEST_F(DISABLED_UpdateSimulatorTest, TargetFile_ExtractImage) {
TemporaryFile zip_file;
AddZipEntries(zip_file.release(), { { "META/misc_info.txt", "extfs_sparse_flag=-s" },
{ "IMAGES/system.img", sparse_system_string_ } });
@@ -166,7 +166,7 @@
ASSERT_EQ(expected_content, content);
}
-TEST_F(UpdateSimulatorTest, TargetFile_ParseFstabInfo) {
+TEST_F(DISABLED_UpdateSimulatorTest, TargetFile_ParseFstabInfo) {
TemporaryFile zip_file;
AddZipEntries(zip_file.release(),
{ { "META/misc_info.txt", "" },
@@ -195,7 +195,7 @@
EXPECT_EQ(expected, transformed);
}
-TEST_F(UpdateSimulatorTest, BuildInfo_ParseTargetFile) {
+TEST_F(DISABLED_UpdateSimulatorTest, BuildInfo_ParseTargetFile) {
std::map<string, string> entries = {
{ "META/misc_info.txt", "" },
{ "SYSTEM/build.prop", build_prop_string_ },
@@ -240,7 +240,7 @@
}
}
-TEST_F(UpdateSimulatorTest, RunUpdateSmoke) {
+TEST_F(DISABLED_UpdateSimulatorTest, RunUpdateSmoke) {
string recovery_img_string = "recovery.img";
string boot_img_string = "boot.img";
@@ -326,7 +326,7 @@
RunSimulation(src_tf.path, ota_package.path, true);
}
-TEST_F(UpdateSimulatorTest, RunUpdateUnrecognizedFunction) {
+TEST_F(DISABLED_UpdateSimulatorTest, RunUpdateUnrecognizedFunction) {
std::map<string, string> src_entries{
{ "META/misc_info.txt", "extfs_sparse_flag=-s" },
{ "IMAGES/system.img", sparse_system_string_ },
@@ -350,7 +350,7 @@
RunSimulation(src_tf.path, ota_package.path, false);
}
-TEST_F(UpdateSimulatorTest, RunUpdateApplyPatchFailed) {
+TEST_F(DISABLED_UpdateSimulatorTest, RunUpdateApplyPatchFailed) {
string recovery_img_string = "recovery.img";
string boot_img_string = "boot.img";