Merge tag 'android-13.0.0_r3' into android-12.1
Android 13.0.0 Release 3 (TP1A.220624.021.A1)
diff --git a/Android.bp b/Android.bp
index 17b58f8..f20a551 100755
--- a/Android.bp
+++ b/Android.bp
@@ -87,12 +87,9 @@
],
srcs: [
"install/adb_install.cpp",
- "install/asn1_decoder.cpp",
"install/get_args.cpp",
"install/install.cpp",
- "install/package.cpp",
"install/spl_check.cpp",
- "install/verifier.cpp",
"install/wipe_data.cpp",
"install/set_metadata.cpp",
"install/ZipUtil.cpp"
diff --git a/Android.mk b/Android.mk
index 61cec06..210a1e3 100755
--- a/Android.mk
+++ b/Android.mk
@@ -18,17 +18,19 @@
ifneq ($(project-path-for),)
ifeq ($(LOCAL_PATH),$(call project-path-for,recovery))
PROJECT_PATH_AGREES := true
- BOARD_SEPOLICY_DIRS += $(call project-path-for,recovery)/sepolicy
+ BOARD_VENDOR_SEPOLICY_DIRS += $(call project-path-for,recovery)/sepolicy
endif
else
+ $(warning BOARD_VENDOR_SEPOLICY_DIRS: $(LOCAL_PATH))
ifeq ($(LOCAL_PATH),bootable/recovery)
PROJECT_PATH_AGREES := true
- BOARD_SEPOLICY_DIRS += bootable/recovery/sepolicy
+ BOARD_VENDOR_SEPOLICY_DIRS += bootable/recovery/sepolicy
+ $(warning BOARD_VENDOR_SEPOLICY_DIRS2: $(BOARD_VENDOR_SEPOLICY_DIRS))
else
ifeq ($(LOCAL_PATH),bootable/recovery-twrp)
ifeq ($(RECOVERY_VARIANT),twrp)
PROJECT_PATH_AGREES := true
- BOARD_SEPOLICY_DIRS += bootable/recovery-twrp/sepolicy
+ BOARD_VENDOR_SEPOLICY_DIRS += bootable/recovery-twrp/sepolicy
endif
endif
endif
@@ -314,14 +316,14 @@
TW_INCLUDE_CRYPTO_FBE := true
LOCAL_CFLAGS += -DTW_INCLUDE_FBE
LOCAL_SHARED_LIBRARIES += android.frameworks.stats@1.0 android.hardware.authsecret@1.0 \
- android.security.authorization-ndk_platform \
+ android.security.authorization-ndk \
android.hardware.oemlock@1.0 libf2fs_sparseblock libbinder libbinder_ndk \
libandroidicu.recovery \
android.hardware.gatekeeper@1.0 \
android.hardware.weaver@1.0 \
android.frameworks.stats@1.0 \
- android.security.maintenance-ndk_platform \
- android.system.keystore2-V1-ndk_platform \
+ android.security.maintenance-ndk \
+ android.system.keystore2-V1-ndk \
libkeyutils \
liblog \
libsqlite.recovery \
@@ -602,6 +604,16 @@
TWRP_REQUIRED_MODULES += file_contexts_text
+LOCAL_REQUIRED_MODULES += \
+ mkfs.erofs.recovery \
+ dump.erofs.recovery \
+ fsck.erofs.recovery
+
+# On A/B devices recovery-persist reads the recovery related file from the persist storage and
+# copies them into /data/misc/recovery. Then, for both A/B and non-A/B devices, recovery-persist
+# parses the last_install file and reports the embedded update metrics. Also, the last_install file
+# will be deteleted after the report.
+LOCAL_REQUIRED_MODULES += recovery-persist
ifeq ($(BOARD_CACHEIMAGE_PARTITION_SIZE),)
TWRP_REQUIRED_MODULES += recovery-persist recovery-refresh
endif
diff --git a/METADATA b/METADATA
index a1ce3c6..68bf6f8 100644
--- a/METADATA
+++ b/METADATA
@@ -2,8 +2,8 @@
# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
# DEPENDING ON IT IN YOUR PROJECT. ***
third_party {
- # would be NOTICE save for OFL in:
- # fonts/README
- # fonts/OFL.txt
+ license_note: "would be NOTICE save for OFL in:\n"
+ " fonts/README\n"
+ " fonts/OFL.txt\n"
license_type: BY_EXCEPTION_ONLY
}
diff --git a/OWNERS b/OWNERS
index 79dd9f7..45c72e3 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,4 @@
elsk@google.com
-enh@google.com
nhdo@google.com
xunchang@google.com
-zhaojiac@google.com
+zhangkelvin@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 28aa06f..023d48b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -6,5 +6,6 @@
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
[Hook Scripts]
+aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
--file_whitelist tools/ updater_sample/
diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp
index b70d54e..1ea56cd 100755
--- a/bootloader_message/bootloader_message.cpp
+++ b/bootloader_message/bootloader_message.cpp
@@ -304,6 +304,16 @@
offsetof(misc_system_space_layout, virtual_ab_message), err);
}
+bool ReadMiscMemtagMessage(misc_memtag_message* message, std::string* err) {
+ return ReadMiscPartitionSystemSpace(message, sizeof(*message),
+ offsetof(misc_system_space_layout, memtag_message), err);
+}
+
+bool WriteMiscMemtagMessage(const misc_memtag_message& message, std::string* err) {
+ return WriteMiscPartitionSystemSpace(&message, sizeof(message),
+ offsetof(misc_system_space_layout, memtag_message), err);
+}
+
extern "C" bool write_reboot_bootloader(void) {
std::string err;
return write_reboot_bootloader(&err);
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index e4cf09b..d58158d 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -93,18 +93,35 @@
uint8_t reserved[57];
} __attribute__((packed));
+struct misc_memtag_message {
+ uint8_t version;
+ uint32_t magic; // magic string for treble compat
+ uint32_t memtag_mode;
+ uint8_t reserved[55];
+} __attribute__((packed));
+
#define MISC_VIRTUAL_AB_MESSAGE_VERSION 2
#define MISC_VIRTUAL_AB_MAGIC_HEADER 0x56740AB0
+#define MISC_MEMTAG_MESSAGE_VERSION 1
+#define MISC_MEMTAG_MAGIC_HEADER 0x5afefe5a
+#define MISC_MEMTAG_MODE_MEMTAG 0x1
+#define MISC_MEMTAG_MODE_MEMTAG_ONCE 0x2
+#define MISC_MEMTAG_MODE_MEMTAG_KERNEL 0x4
+#define MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE 0x8
+
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
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_memtag_message has wrong size");
#endif
// This struct is not meant to be used directly, rather, it is to make
// computation of offsets easier. New fields must be added to the end.
struct misc_system_space_layout {
misc_virtual_ab_message virtual_ab_message;
+ misc_memtag_message memtag_message;
} __attribute__((packed));
#ifdef __cplusplus
@@ -172,6 +189,9 @@
bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err);
bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err);
+// Read or write the memtag message from system space in /misc.
+bool ReadMiscMemtagMessage(misc_memtag_message* message, std::string* err);
+bool WriteMiscMemtagMessage(const misc_memtag_message& message, std::string* err);
#else
#include <stdbool.h>
diff --git a/edify/parser.yy b/edify/parser.yy
index 37bcdd0..5e1e847 100644
--- a/edify/parser.yy
+++ b/edify/parser.yy
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/etc/init.rc b/etc/init.rc
index c6f750b..c7e8874 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -75,6 +75,7 @@
domainname localdomain
class_start default
+ class_start hal
on firmware_mounts_complete
rm /dev/.booting
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/gui/action.cpp b/gui/action.cpp
index d5b8c8f..61a3bed 100755
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -1973,7 +1973,6 @@
int GUIAction::installapp(std::string arg __unused)
{
- int op_status = 1;
operation_start("Install TWRP App");
if (!simulate)
{
@@ -1990,7 +1989,7 @@
LOGERR("chown %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
- if (setfilecon(install_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(install_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
@@ -2004,7 +2003,7 @@
LOGERR("chown %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
- if (setfilecon(install_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(install_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
@@ -2017,7 +2016,7 @@
LOGERR("chown %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
- if (setfilecon(install_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(install_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
@@ -2037,7 +2036,7 @@
install_path += "/twrpapp";
LOGINFO("Installing app to '%s'\n", install_path.c_str());
if (mkdir(install_path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0) {
- if (setfilecon(install_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(install_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
@@ -2046,7 +2045,7 @@
LOGERR("Error copying apk file\n");
goto exit;
}
- if (setfilecon(install_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(install_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", install_path.c_str(), strerror(errno));
goto exit;
}
@@ -2061,7 +2060,7 @@
LOGERR("chown %s error: %s\n", permission_path.c_str(), strerror(errno));
goto exit;
}
- if (setfilecon(permission_path.c_str(), (security_context_t)context.c_str()) < 0) {
+ if (setfilecon(permission_path.c_str(), (char *)context.c_str()) < 0) {
LOGERR("setfilecon %s error: %s\n", permission_path.c_str(), strerror(errno));
goto exit;
}
@@ -2069,7 +2068,6 @@
sync();
sync();
PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true);
- op_status = 0;
} else {
LOGERR("Error making app directory '%s': %s\n", strerror(errno));
}
diff --git a/install/Android.bp b/install/Android.bp
index 1d965cc..22d3fec 100644
--- a/install/Android.bp
+++ b/install/Android.bp
@@ -111,12 +111,9 @@
srcs: [
"adb_install.cpp",
- "asn1_decoder.cpp",
"fuse_install.cpp",
"install.cpp",
- "package.cpp",
"snapshot_utils.cpp",
- "verifier.cpp",
"wipe_data.cpp",
"wipe_device.cpp",
"spl_check.cpp",
diff --git a/install/adb_install.cpp b/install/adb_install.cpp
index feebaee..b9dac0f 100755
--- a/install/adb_install.cpp
+++ b/install/adb_install.cpp
@@ -95,6 +95,7 @@
// 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;
@@ -350,15 +351,8 @@
InstallResult install_result = INSTALL_ERROR;
std::map<MinadbdCommand, CommandFunction> command_map{
- { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, &install_result) },
- { MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid,
- &install_result, reboot_action) },
- { MinadbdCommand::kRebootBootloader,
- std::bind(&AdbRebootHandler, MinadbdCommand::kRebootBootloader, &install_result,
- reboot_action) },
- { MinadbdCommand::kRebootFastboot, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootFastboot,
- &install_result, reboot_action) },
- { MinadbdCommand::kRebootRecovery, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRecovery,
+ { MinadbdCommand::kInstall, std::bind(&AdbInstallPackageHandler, &install_result) },
+ { MinadbdCommand::kRebootAndroid, std::bind(&AdbRebootHandler, MinadbdCommand::kRebootAndroid,
&install_result, reboot_action) },
{ MinadbdCommand::kRebootRescue,
std::bind(&AdbRebootHandler, MinadbdCommand::kRebootRescue, &install_result, reboot_action) },
@@ -371,7 +365,7 @@
"to the device with \"adb sideload <filename>\"...\n");
} else {
command_map.emplace(MinadbdCommand::kWipeData, [&device]() {
- bool result = WipeData(device, false);
+ bool result = WipeData(device);
return std::make_pair(result, true);
});
command_map.emplace(MinadbdCommand::kNoOp, []() { return std::make_pair(true, true); });
diff --git a/install/fuse_install.cpp b/install/fuse_install.cpp
index 61e1d74..5ae5382 100755
--- a/install/fuse_install.cpp
+++ b/install/fuse_install.cpp
@@ -150,6 +150,7 @@
// 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);
@@ -225,7 +226,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 eb91974..b2d9ca9 100755
--- a/install/include/install/install.h
+++ b/install/include/install/install.h
@@ -24,7 +24,8 @@
#include <ziparchive/zip_archive.h>
-#include "package.h"
+#include "otautil/package.h"
+#include "recovery_ui/device.h"
#include "recovery_ui/ui.h"
enum InstallResult {
diff --git a/install/include/install/wipe_data.h b/install/include/install/wipe_data.h
index 76ebf05..0505fc9 100755
--- a/install/include/install/wipe_data.h
+++ b/install/include/install/wipe_data.h
@@ -27,4 +27,4 @@
bool WipeCache(const std::function<bool()>& confirm);
// Returns true on success.
-bool WipeData(Device* device, bool convert_fbe);
+bool WipeData();
diff --git a/install/include/install/wipe_device.h b/install/include/install/wipe_device.h
index c60b999..903ddfd 100755
--- a/install/include/install/wipe_device.h
+++ b/install/include/install/wipe_device.h
@@ -19,7 +19,7 @@
#include <string>
#include <vector>
-#include "install/package.h"
+#include "otautil/package.h"
#include "recovery_ui/device.h"
// Wipes the current A/B device, with a secure wipe of all the partitions in RECOVERY_WIPE.
diff --git a/install/install.cpp b/install/install.cpp
index c1f14cf..8c92817 100755
--- a/install/install.cpp
+++ b/install/install.cpp
@@ -46,13 +46,13 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include "install/package.h"
#include "install/spl_check.h"
-#include "install/verifier.h"
#include "install/wipe_data.h"
#include "otautil/error_code.h"
+#include "otautil/package.h"
#include "otautil/paths.h"
#include "otautil/sysutil.h"
+#include "otautil/verifier.h"
#include "private/setup_commands.h"
#include "recovery_ui/ui.h"
#include "recovery_utils/roots.h"
@@ -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,6 +343,15 @@
}
}
+static bool PerformPowerwashIfRequired(ZipArchiveHandle zip) {
+ 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();
+ }
+ 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,
@@ -530,6 +550,7 @@
} else {
LOG(FATAL) << "Invalid status code " << status;
}
+ PerformPowerwashIfRequired(zip);
return INSTALL_SUCCESS;
}
diff --git a/install/set_metadata.cpp b/install/set_metadata.cpp
index 6b762bf..9eb20bf 100644
--- a/install/set_metadata.cpp
+++ b/install/set_metadata.cpp
@@ -30,7 +30,7 @@
#include <unistd.h>
#include "selinux/selinux.h"
-static security_context_t selinux_context;
+static char* selinux_context;
struct stat s;
static int has_stat = 0;
diff --git a/install/wipe_data.cpp b/install/wipe_data.cpp
index 2ae4993..6b7cc25 100755
--- a/install/wipe_data.cpp
+++ b/install/wipe_data.cpp
@@ -16,9 +16,7 @@
#include "install/wipe_data.h"
-#include <stdio.h>
#include <string.h>
-#include <sys/stat.h>
#include <functional>
#include <vector>
@@ -34,12 +32,11 @@
#include "recovery_utils/roots.h"
constexpr const char* CACHE_ROOT = "/cache";
-constexpr const char* DATA_ROOT = "/data";
-constexpr const char* METADATA_ROOT = "/metadata";
+//constexpr const char* DATA_ROOT = "/data";
+//constexpr const char* METADATA_ROOT = "/metadata";
-static bool EraseVolume(const char* volume, bool convert_fbe) {
+static bool EraseVolume(const char* volume) {
bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
- bool is_data = (strcmp(volume, DATA_ROOT) == 0);
// ui->SetBackground(RecoveryUI::ERASING);
// ui->SetProgressType(RecoveryUI::INDETERMINATE);
@@ -55,28 +52,7 @@
ensure_path_unmounted(volume);
- int result;
- if (is_data && convert_fbe) {
- constexpr const char* CONVERT_FBE_DIR = "/tmp/convert_fbe";
- constexpr const char* CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
- // Create convert_fbe breadcrumb file to signal init to convert to file based encryption, not
- // full disk encryption.
- if (mkdir(CONVERT_FBE_DIR, 0700) != 0) {
- PLOG(ERROR) << "Failed to mkdir " << CONVERT_FBE_DIR;
- return false;
- }
- FILE* f = fopen(CONVERT_FBE_FILE, "wbe");
- if (!f) {
- PLOG(ERROR) << "Failed to convert to file encryption";
- return false;
- }
- fclose(f);
- result = format_volume(volume, CONVERT_FBE_DIR);
- remove(CONVERT_FBE_FILE);
- rmdir(CONVERT_FBE_DIR);
- } else {
- result = format_volume(volume);
- }
+ int result = format_volume(volume);
if (is_cache) {
RestoreLogFilesAfterFormat(log_files);
@@ -100,12 +76,12 @@
// ui->SetBackground(RecoveryUI::ERASING);
// ui->SetProgressType(RecoveryUI::INDETERMINATE);
- bool success = EraseVolume("/cache", false);
- // ui->Print("Cache wipe %s.\n", success ? "complete" : "failed");
+ bool success = EraseVolume("/cache");
+ //ui->Print("Cache wipe %s.\n", success ? "complete" : "failed");
return success;
}
-bool WipeData(Device* device, bool convert_fbe) {
+bool WipeData() {
// RecoveryUI* ui = device->GetUI();
// ui->Print("\n-- Wiping data...\n");
// ui->SetBackground(RecoveryUI::ERASING);
@@ -116,20 +92,21 @@
// return false;
// }
- bool success = device->PreWipeData();
- if (success) {
- success &= EraseVolume(DATA_ROOT, convert_fbe);
- bool has_cache = volume_for_mount_point("/cache") != nullptr;
- if (has_cache) {
- success &= EraseVolume(CACHE_ROOT, false);
- }
- if (volume_for_mount_point(METADATA_ROOT) != nullptr) {
- success &= EraseVolume(METADATA_ROOT, false);
- }
- }
- if (success) {
- success &= device->PostWipeData();
- }
+ //bool success = device->PreWipeData();
+ bool success = true;
+ //if (success) {
+ //success &= EraseVolume(DATA_ROOT);
+ //bool has_cache = volume_for_mount_point("/cache") != nullptr;
+ //if (has_cache) {
+ // success &= EraseVolume(CACHE_ROOT);
+ // }
+ //if (volume_for_mount_point(METADATA_ROOT) != nullptr) {
+ //success &= EraseVolume(METADATA_ROOT);
+ //}
+ //}
+ //if (success) {
+ //success &= device->PostWipeData();
+ //}
// ui->Print("Data wipe %s.\n", success ? "complete" : "failed");
return success;
}
diff --git a/install/wipe_device.cpp b/install/wipe_device.cpp
index 7944c1c..fe7e78e 100644
--- a/install/wipe_device.cpp
+++ b/install/wipe_device.cpp
@@ -35,7 +35,7 @@
#include "bootloader_message/bootloader_message.h"
#include "install/install.h"
-#include "install/package.h"
+#include "otautil/package.h"
#include "recovery_ui/device.h"
#include "recovery_ui/ui.h"
diff --git a/libtar/Android.mk b/libtar/Android.mk
index fac3772..80ded75 100755
--- a/libtar/Android.mk
+++ b/libtar/Android.mk
@@ -23,10 +23,11 @@
android.hardware.keymaster@4.0 \
android.hardware.keymaster@4.1 \
android.hardware.weaver@1.0 \
- android.security.apc-ndk_platform \
- android.system.keystore2-V1-ndk_platform \
- android.security.authorization-ndk_platform \
- android.security.maintenance-ndk_platform \
+ android.security.apc-ndk \
+ android.system.keystore2-V1-ndk \
+ android.security.authorization-ndk \
+ android.security.maintenance-ndk \
+ libkeystoreinfo \
libselinux \
libbinder_ndk \
libext4_utils \
@@ -36,7 +37,6 @@
libf2fs_sparseblock \
libkeymaster_messages \
libkeymint_support \
- libkeystoreinfo \
libkeystore-attestation-application-id \
libhardware \
libprotobuf-cpp-lite \
diff --git a/libtar/append.c b/libtar/append.c
index 6e75f0d..7557158 100755
--- a/libtar/append.c
+++ b/libtar/append.c
@@ -119,7 +119,7 @@
t->th_buf.selinux_context = NULL;
}
- security_context_t selinux_context = NULL;
+ char* selinux_context = NULL;
if (lgetfilecon(realname, &selinux_context) >= 0)
{
t->th_buf.selinux_context = strdup(selinux_context);
diff --git a/minadbd/Android.bp b/minadbd/Android.bp
index 9401405..ec56ef0 100644
--- a/minadbd/Android.bp
+++ b/minadbd/Android.bp
@@ -99,6 +99,7 @@
],
shared_libs: [
+ "android.hardware.health-V1-ndk", // from librecovery_utils
"libbase",
"libcrypto",
],
@@ -130,6 +131,7 @@
],
static_libs: [
+ "android.hardware.health-V1-ndk", // from librecovery_utils
"libminadbd_services",
"libfusesideload",
"librecovery_utils",
diff --git a/minadbd/minadbd.cpp b/minadbd/minadbd.cpp
index 732f3a5..83586a6 100755
--- a/minadbd/minadbd.cpp
+++ b/minadbd/minadbd.cpp
@@ -64,6 +64,7 @@
// We can't require authentication for sideloading. http://b/22025550.
auth_required = false;
+ socket_access_allowed = false;
init_transport_registration();
usb_init();
diff --git a/minui/Android.bp b/minui/Android.bp
old mode 100755
new mode 100644
index f68f6c8..02fb363
--- a/minui/Android.bp
+++ b/minui/Android.bp
@@ -24,6 +24,7 @@
cc_library {
name: "libminui",
recovery_available: true,
+ vendor_available: true,
defaults: [
"recovery_defaults",
@@ -51,4 +52,15 @@
"libpng",
"libz",
],
+
+ target: {
+ vendor: {
+ exclude_static_libs: [
+ "libsync",
+ ],
+ shared_libs: [
+ "libsync",
+ ],
+ },
+ },
}
diff --git a/minui/events.cpp b/minui/events.cpp
old mode 100755
new mode 100644
index cee4d73..b307a49
--- a/minui/events.cpp
+++ b/minui/events.cpp
@@ -29,7 +29,9 @@
#include <functional>
#include <memory>
+#include <string>
+#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include "minui/minui.h"
@@ -47,9 +49,6 @@
struct FdInfo {
android::base::unique_fd fd;
ev_callback cb;
-#ifdef TW_USE_MINUI_WITH_DATA
- void* data;
-#endif
};
static bool g_allow_touch_inputs = true;
@@ -68,7 +67,6 @@
return (array[bit / BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
}
-#ifdef TW_USE_MINUI_WITH_OPTIONAL_TOUCH_EVENTS
static bool should_add_input_device(int fd, bool allow_touch_inputs) {
// Use unsigned long to match ioctl's parameter type.
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
@@ -122,12 +120,12 @@
}
offset += sizeof(inotify_event) + pevent->len;
- pevent->name[pevent->len] = '\0';
- if (strncmp(pevent->name, "event", 5)) {
+ std::string event_name(pevent->name, pevent->len);
+ if (!android::base::StartsWith(event_name, "event")) {
continue;
}
- android::base::unique_fd dfd(openat(dirfd(dir.get()), pevent->name, O_RDONLY));
+ android::base::unique_fd dfd(openat(dirfd(dir.get()), event_name.c_str(), O_RDONLY));
if (dfd == -1) {
break;
}
@@ -144,14 +142,6 @@
}
int ev_init(ev_callback input_cb, bool allow_touch_inputs) {
-#else
-#ifdef TW_USE_MINUI_WITH_DATA
-int ev_init(ev_callback input_cb, void* data) {
-#else
-int ev_init(ev_callback input_cb) {
-#endif
- bool allow_touch_inputs = false;
-#endif
g_epoll_fd.reset();
android::base::unique_fd epoll_fd(epoll_create1(EPOLL_CLOEXEC));
@@ -180,11 +170,9 @@
android::base::unique_fd fd(openat(dirfd(dir.get()), de->d_name, O_RDONLY | O_CLOEXEC));
if (fd == -1) continue;
-#ifdef TW_USE_MINUI_WITH_OPTIONAL_TOUCH_EVENTS
if (!should_add_input_device(fd, allow_touch_inputs)) {
continue;
}
-#endif
epoll_event ev;
ev.events = EPOLLIN | EPOLLWAKEUP;
@@ -209,9 +197,7 @@
g_saved_input_cb = input_cb;
g_allow_touch_inputs = allow_touch_inputs;
-#ifdef TW_USE_MINUI_WITH_OPTIONAL_TOUCH_EVENTS
ev_add_fd(std::move(inotify_fd), inotify_cb);
-#endif
return 0;
}
@@ -281,11 +267,36 @@
return -1;
}
-#ifdef TW_USE_MINUI_WITH_DATA
-int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data) {
-#else
+int ev_sync_sw_state(const ev_set_sw_callback& set_sw_cb) {
+ // Use unsigned long to match ioctl's parameter type.
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
+ unsigned long sw_bits[BITS_TO_LONGS(SW_MAX)]; // NOLINT
+
+ for (size_t i = 0; i < g_ev_dev_count; ++i) {
+ memset(ev_bits, 0, sizeof(ev_bits));
+ memset(sw_bits, 0, sizeof(sw_bits));
+
+ if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+ continue;
+ }
+ if (!test_bit(EV_SW, ev_bits)) {
+ continue;
+ }
+ if (ioctl(ev_fdinfo[i].fd, EVIOCGSW(sizeof(sw_bits)), sw_bits) == -1) {
+ continue;
+ }
+
+ for (int code = 0; code <= SW_MAX; code++) {
+ if (test_bit(code, sw_bits)) {
+ set_sw_cb(code, 1);
+ }
+ }
+ }
+
+ return 0;
+}
+
int ev_sync_key_state(const ev_set_key_callback& set_key_cb) {
-#endif
// Use unsigned long to match ioctl's parameter type.
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
@@ -306,11 +317,7 @@
for (int code = 0; code <= KEY_MAX; code++) {
if (test_bit(code, key_bits)) {
-#ifdef TW_USE_MINUI_WITH_DATA
- set_key_cb(code, 1, data);
-#else
set_key_cb(code, 1);
-#endif
}
}
}
@@ -347,7 +354,6 @@
}
}
-#ifdef TW_USE_MINUI_WITH_OPTIONAL_TOUCH_EVENTS
void ev_iterate_touch_inputs(const std::function<void(int)>& action) {
for (size_t i = 0; i < g_ev_dev_count; ++i) {
// Use unsigned long to match ioctl's parameter type.
@@ -371,4 +377,3 @@
}
}
}
-#endif
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
old mode 100755
new mode 100644
index 38ba6ca..41a3661
--- a/minui/graphics.cpp
+++ b/minui/graphics.cpp
@@ -25,12 +25,6 @@
#include <android-base/properties.h>
-#ifdef BOARD_USE_CUSTOM_RECOVERY_FONT
-#include BOARD_USE_CUSTOM_RECOVERY_FONT
-#else
-#include "font_10x18.h"
-#endif
-
#include "graphics_drm.h"
#include "graphics_fbdev.h"
#include "minui/minui.h"
@@ -41,24 +35,15 @@
static int overscan_offset_x = 0;
static int overscan_offset_y = 0;
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-static unsigned char gr_current_r = 255;
-static unsigned char gr_current_g = 255;
-static unsigned char gr_current_b = 255;
-#endif
-static unsigned char gr_current_a = 255;
-static unsigned char rgb_555[2];
-static unsigned char gr_current_r5 = 31;
-static unsigned char gr_current_g5 = 63;
-static unsigned char gr_current_b5 = 31;
-
static uint32_t gr_current = ~0;
-static constexpr uint32_t alpha_mask = 0xff000000;
// gr_draw is owned by backends.
static GRSurface* gr_draw = nullptr;
static GRRotation rotation = GRRotation::NONE;
static PixelFormat pixel_format = PixelFormat::UNKNOWN;
+// The graphics backend list that provides fallback options for the default backend selection.
+// For example, it will fist try DRM, then try FBDEV if DRM is unavailable.
+constexpr auto default_backends = { GraphicsBackend::DRM, GraphicsBackend::FBDEV };
static bool outside(int x, int y) {
auto swapped = (rotation == GRRotation::LEFT || rotation == GRRotation::RIGHT);
@@ -66,18 +51,6 @@
y >= (swapped ? gr_draw->width : gr_draw->height);
}
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-int gr_measure(const char *s)
-{
- return gr_font->char_width * strlen(s);
-}
-
-void gr_font_size(int *x, int *y)
-{
- *x = gr_font->char_width;
- *y = gr_font->char_height;
-}
-#else // TW_USE_MINUI_CUSTOM_FONTS
const GRFont* gr_sys_font() {
return gr_font;
}
@@ -103,78 +76,9 @@
*y = font->char_height;
return 0;
}
-#endif // TW_NO_MINUI_CUSTOM_FONTS
-
-void blend_16bpp(unsigned char* px, unsigned r5, unsigned g5, unsigned b5, unsigned char a)
-{
- unsigned char orig[2];
- orig[0] = px[0];
- orig[1] = px[1];
-
- /* This code is a little easier to read
- unsigned oldred = (orig[1] >> 3);
- unsigned oldgreen = (((orig[0] >> 5) << 3) + (orig[1] & 0x7));
- unsigned oldblue = (orig[0] & 0x1F);
-
- unsigned newred = (oldred * (255-a) + r5 * a) / 255;
- unsigned newgreen = (oldgreen * (255-a) + g5 * a) / 255;
- unsigned newblue = (oldblue * (255-a) + b5 * a) / 255;
- */
-
- unsigned newred = ((orig[1] >> 3) * (255-a) + r5 * a) / 255;
- unsigned newgreen = ((((orig[0] >> 5) << 3) + (orig[1] & 0x7)) * (255-a) + g5 * a) / 255;
- unsigned newblue = ((orig[0] & 0x1F) * (255-a) + b5 * a) / 255;
-
- *px++ = (newgreen << 5) + (newblue);
- *px++ = (newred << 3) + (newgreen >> 3);
-}
-
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-static void text_blend_old(unsigned char* src_p, int src_row_bytes,
- unsigned char* dst_p, int dst_row_bytes,
- int width, int height)
-{
- for (int j = 0; j < height; ++j) {
- unsigned char* sx = src_p;
- unsigned char* px = dst_p;
- for (int i = 0; i < width; ++i) {
- unsigned char a = *sx++;
- if (gr_current_a < 255) a = ((int)a * gr_current_a) / 255;
- if (a == 255) {
- if (gr_draw->pixel_bytes == 2) {
- *px++ = rgb_555[0];
- *px++ = rgb_555[1];
- } else {
- *px++ = gr_current_r;
- *px++ = gr_current_g;
- *px++ = gr_current_b;
- px++;
- }
- } else if (a > 0) {
- if (gr_draw->pixel_bytes == 2) {
- blend_16bpp(px, gr_current_r5, gr_current_g5, gr_current_b5, a);
- px += gr_draw->pixel_bytes;
- } else {
- *px = (*px * (255-a) + gr_current_r * a) / 255;
- ++px;
- *px = (*px * (255-a) + gr_current_g * a) / 255;
- ++px;
- *px = (*px * (255-a) + gr_current_b * a) / 255;
- ++px;
- ++px;
- }
- } else {
- px += gr_draw->pixel_bytes;
- }
- }
- src_p += src_row_bytes;
- dst_p += dst_row_bytes;
- }
-}
-#endif // TW_NO_MINUI_CUSTOM_FONTS
// Blends gr_current onto pix value, assumes alpha as most significant byte.
-static inline uint32_t pixel_blend(uint8_t alpha, uint32_t pix) {
+static inline uint32_t pixel_blend_argb(uint8_t alpha, uint32_t pix) {
if (alpha == 255) return gr_current;
if (alpha == 0) return pix;
uint32_t pix_r = pix & 0xff;
@@ -191,6 +95,48 @@
return (out_r & 0xff) | (out_g & 0xff00) | (out_b & 0xff0000) | (gr_current & 0xff000000);
}
+static inline uint32_t pixel_blend_rgba(uint8_t alpha, uint32_t pix) {
+ if (alpha == 255) return gr_current;
+ if (alpha == 0) return pix;
+ uint32_t pix_r = pix & 0xff00;
+ uint32_t pix_g = pix & 0xff0000;
+ uint32_t pix_b = pix & 0xff000000;
+ uint32_t cur_r = gr_current & 0xff00;
+ uint32_t cur_g = gr_current & 0xff0000;
+ uint32_t cur_b = gr_current & 0xff000000;
+
+ uint32_t out_r = (pix_r * (255 - alpha) + cur_r * alpha) / 255;
+ uint32_t out_g = (pix_g * (255 - alpha) + cur_g * alpha) / 255;
+ uint32_t out_b = (pix_b * (255 - alpha) + cur_b * alpha) / 255;
+
+ return (gr_current & 0xff) | (out_r & 0xff00) | (out_g & 0xff0000) | (out_b & 0xff000000);
+}
+
+static inline uint32_t pixel_blend(uint8_t alpha, uint32_t pix) {
+ if (pixel_format == PixelFormat::RGBA) {
+ return pixel_blend_rgba(alpha, pix);
+ }
+ return pixel_blend_argb(alpha, pix);
+}
+
+static inline uint32_t get_alphamask() {
+ if (pixel_format == PixelFormat::RGBA) {
+ return 0x000000ff;
+ }
+ return 0xff000000;
+}
+
+static inline uint8_t get_alpha_shift() {
+ if (pixel_format == PixelFormat::RGBA) {
+ return 0;
+ }
+ return 24;
+}
+
+static inline uint8_t get_alpha(uint32_t pix) {
+ return static_cast<uint8_t>((pix & (gr_current & get_alphamask())) >> get_alpha_shift());
+}
+
// Increments pixel pointer right, with current rotation.
static void incr_x(uint32_t** p, int row_pixels) {
if (rotation == GRRotation::LEFT) {
@@ -238,7 +184,7 @@
static void TextBlend(const uint8_t* src_p, int src_row_bytes, uint32_t* dst_p, int dst_row_pixels,
int width, int height) {
- uint8_t alpha_current = static_cast<uint8_t>((alpha_mask & gr_current) >> 24);
+ uint8_t alpha_current = get_alpha(gr_current);
for (int j = 0; j < height; ++j) {
const uint8_t* sx = src_p;
uint32_t* px = dst_p;
@@ -252,41 +198,8 @@
}
}
-
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-void gr_text(int x, int y, const char *s, bool bold)
-{
- GRFont* font = gr_font;
-
- if (!font->texture || gr_current_a == 0) return;
-
- bold = bold && (font->texture->height != font->char_height);
-
- x += overscan_offset_x;
- y += overscan_offset_y;
-
- unsigned char ch;
- while ((ch = *s++)) {
- if (outside(x, y) || outside(x+font->char_width-1, y+font->char_height-1)) break;
-
- if (ch < ' ' || ch > '~') {
- ch = '?';
- }
-
- unsigned char* src_p = font->texture->data + ((ch - ' ') * font->char_width) +
- (bold ? font->char_height * font->texture->row_bytes : 0);
- unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
-
- text_blend_old(src_p, font->texture->row_bytes,
- dst_p, gr_draw->row_bytes,
- font->char_width, font->char_height);
-
- x += font->char_width;
- }
-}
-#else //TW_NO_MINUI_CUSTOM_FONTS
void gr_text(const GRFont* font, int x, int y, const char* s, bool bold) {
- if (!font || !font->texture || (gr_current & alpha_mask) == 0) return;
+ if (!font || !font->texture || (gr_current & get_alphamask()) == 0) return;
if (font->texture->pixel_bytes != 1) {
printf("gr_text: font has wrong format\n");
@@ -317,7 +230,6 @@
x += font->char_width;
}
}
-#endif //TW_NO_MINUI_CUSTOM_FONTS
void gr_texticon(int x, int y, const GRSurface* icon) {
if (icon == nullptr) return;
@@ -338,50 +250,18 @@
TextBlend(src_p, icon->row_bytes, dst_p, row_pixels, icon->width, icon->height);
}
-void gr_convert_rgb_555(unsigned char r, unsigned char g, unsigned char b)
-{
- gr_current_r5 = (((r & 0xFF) * 0x1F) + 0x7F) / 0xFF;
- gr_current_g5 = (((g & 0xFF) * 0x3F) + 0x7F) / 0xFF;
- gr_current_b5 = (((b & 0xFF) * 0x1F) + 0x7F) / 0xFF;
-
- rgb_555[0] = (gr_current_g5 << 5) + (gr_current_b5);
- rgb_555[1] = (gr_current_r5 << 3) + (gr_current_g5 >> 3);
-}
-
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
- gr_current_r = b;
- gr_current_g = g;
- gr_current_b = r;
-#else
- gr_current_r = r;
- gr_current_g = g;
- gr_current_b = b;
-#endif
-#endif
-
- if (gr_draw->pixel_bytes == 2) {
- gr_current_a = a;
- gr_convert_rgb_555(r, g, b);
- return;
- }
-
uint32_t r32 = r, g32 = g, b32 = b, a32 = a;
if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
gr_current = (a32 << 24) | (r32 << 16) | (g32 << 8) | b32;
+ } else if (pixel_format == PixelFormat::RGBA) {
+ gr_current = (b32 << 24) | (g32 << 16) | (r32 << 8) | a32;
} else {
gr_current = (a32 << 24) | (b32 << 16) | (g32 << 8) | r32;
}
}
void gr_clear() {
- if (gr_draw->pixel_bytes == 2) {
- gr_fill(0, 0, gr_fb_width(), gr_fb_height());
- return;
- }
-
- // This code only works on 32bpp devices
if ((gr_current & 0xff) == ((gr_current >> 8) & 0xff) &&
(gr_current & 0xff) == ((gr_current >> 16) & 0xff) &&
(gr_current & 0xff) == ((gr_current >> 24) & 0xff) &&
@@ -410,7 +290,7 @@
int row_pixels = gr_draw->row_bytes / gr_draw->pixel_bytes;
uint32_t* p = PixelAt(gr_draw, x1, y1, row_pixels);
- uint8_t alpha = static_cast<uint8_t>(((gr_current & alpha_mask) >> 24));
+ uint8_t alpha = get_alpha(gr_current);
if (alpha > 0) {
for (int y = y1; y < y2; ++y) {
uint32_t* px = p;
@@ -423,56 +303,12 @@
}
}
-void gr_blit_32to16(const GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
- dx += overscan_offset_x;
- dy += overscan_offset_y;
-
- if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
-
- unsigned char* src_p = (unsigned char*) source->data() + sy*source->row_bytes + sx*source->pixel_bytes;
- unsigned char* dst_p = gr_draw->data() + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
-
- int i, j;
- for (i = 0; i < h; ++i) {
- unsigned char* spx = src_p;
- unsigned char* dpx = dst_p;
-
- for (j = 0; j < w; ++j) {
- unsigned a = spx[3];
-
- if (a == 0) {
- spx += source->pixel_bytes;
- dpx += gr_draw->pixel_bytes;
- } else {
- unsigned r5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
- unsigned g5 = (((*spx++ & 0xFF) * 0x3F) + 0x7F) / 0xFF;
- unsigned b5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
- spx++;
- if (a == 255) {
- *dpx++ = (g5 << 5) + (b5);
- *dpx++ = (r5 << 3) + (g5 >> 3);
- } else {
- blend_16bpp(dpx, r5, g5, b5, a);
- spx += source->pixel_bytes;
- }
- }
- }
- src_p += source->row_bytes;
- dst_p += gr_draw->row_bytes;
- }
-}
-
void gr_blit(const GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
if (source == nullptr) return;
if (gr_draw->pixel_bytes != source->pixel_bytes) {
- if (gr_draw->pixel_bytes == 2 && source->pixel_bytes == 4) {
- gr_blit_32to16(source, sx, sy, w, h, dx, dy);
- return;
- } else {
- printf("gr_blit: source has wrong format\n");
- return;
- }
+ printf("gr_blit: source has wrong format\n");
+ return;
}
dx += overscan_offset_x;
@@ -523,49 +359,6 @@
return surface->height;
}
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-static void gr_init_font(void)
-{
- gr_font = reinterpret_cast<GRFont*>(calloc(sizeof(*gr_font), 1));
-
- int res = res_create_alpha_surface("font", &(gr_font->texture));
- if (res == 0) {
- // The font image should be a 96x2 array of character images. The
- // columns are the printable ASCII characters 0x20 - 0x7f. The
- // top row is regular text; the bottom row is bold.
- gr_font->char_width = gr_font->texture->width / 96;
- gr_font->char_height = gr_font->texture->height / 2;
- } else {
- printf("failed to read font: res=%d\n", res);
-
- // fall back to the compiled-in font.
- gr_font->texture = reinterpret_cast<GRSurface*>(malloc(sizeof(*gr_font->texture)));
- gr_font->texture->width = font.width;
- gr_font->texture->height = font.height;
- gr_font->texture->row_bytes = font.width;
- gr_font->texture->pixel_bytes = 1;
-
- unsigned char* bits = reinterpret_cast<unsigned char*>(malloc(font.width * font.height));
- gr_font->texture->data = reinterpret_cast<unsigned char*>(bits);
-
- unsigned char data;
- unsigned char* in = font.rundata;
- while((data = *in++)) {
- memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
- bits += (data & 0x7f);
- }
-
- gr_font->char_width = font.char_width;
- gr_font->char_height = font.char_height;
- }
-}
-
-void gr_set_font(__attribute__ ((unused))const char* name) {
- //this cm function is made to change font. Don't care, just init the font:
- gr_init_font();
- return;
-}
-#else // TW_NO_MINUI_CUSTOM_FONTS
int gr_init_font(const char* name, GRFont** dest) {
GRFont* font = static_cast<GRFont*>(calloc(1, sizeof(*gr_font)));
if (font == nullptr) {
@@ -588,13 +381,27 @@
return 0;
}
-#endif // TW_NO_MINUI_CUSTOM_FONTS
void gr_flip() {
gr_draw = gr_backend->Flip();
}
+std::unique_ptr<MinuiBackend> create_backend(GraphicsBackend backend) {
+ switch (backend) {
+ case GraphicsBackend::DRM:
+ return std::make_unique<MinuiBackendDrm>();
+ case GraphicsBackend::FBDEV:
+ return std::make_unique<MinuiBackendFbdev>();
+ default:
+ return nullptr;
+ }
+}
+
int gr_init() {
+ return gr_init(default_backends);
+}
+
+int gr_init(std::initializer_list<GraphicsBackend> backends) {
// pixel_format needs to be set before loading any resources or initializing backends.
std::string format = android::base::GetProperty("ro.minui.pixel_format", "");
if (format == "ABGR_8888") {
@@ -605,6 +412,8 @@
pixel_format = PixelFormat::ARGB;
} else if (format == "BGRA_8888") {
pixel_format = PixelFormat::BGRA;
+ } else if (format == "RGBA_8888") {
+ pixel_format = PixelFormat::RGBA;
} else {
pixel_format = PixelFormat::UNKNOWN;
}
@@ -615,34 +424,22 @@
ret);
}
- auto backend = std::unique_ptr<MinuiBackend>{ std::make_unique<MinuiBackendDrm>() };
- gr_draw = backend->Init();
-
-#ifdef MSM_BSP
- if (gr_draw) {
- printf("Using overlay graphics.\n");
+ std::unique_ptr<MinuiBackend> minui_backend;
+ for (GraphicsBackend backend : backends) {
+ minui_backend = create_backend(backend);
+ if (!minui_backend) {
+ printf("gr_init: minui_backend %d is a nullptr\n", backend);
+ continue;
}
-#endif
-
-
- if (!gr_draw) {
- backend = std::make_unique<MinuiBackendDrm>();
- gr_draw = backend->Init();
- if (gr_draw)
- printf("Using drm graphics.\n");
- }
-
- if (!gr_draw) {
- backend = std::make_unique<MinuiBackendFbdev>();
- gr_draw = backend->Init();
- if (gr_draw)
- printf("Using fbdev graphics.\n");
- }
+ gr_draw = minui_backend->Init();
+ if (gr_draw) break;
+ }
if (!gr_draw) {
return -1;
}
+ gr_backend = minui_backend.release();
int overscan_percent = android::base::GetIntProperty("ro.minui.overscan_percent", 0);
overscan_offset_x = gr_draw->width * overscan_percent / 100;
@@ -698,6 +495,14 @@
gr_backend->Blank(blank);
}
+void gr_fb_blank(bool blank, int index) {
+ gr_backend->Blank(blank, static_cast<MinuiBackend::DrmConnector>(index));
+}
+
void gr_rotate(GRRotation rot) {
rotation = rot;
}
+
+bool gr_has_multiple_connectors() {
+ return gr_backend->HasMultipleConnectors();
+}
diff --git a/minui/graphics.h b/minui/graphics.h
index 3c45a40..ff063ae 100644
--- a/minui/graphics.h
+++ b/minui/graphics.h
@@ -21,6 +21,12 @@
class MinuiBackend {
public:
+ enum DrmConnector {
+ DRM_MAIN = 0,
+ DRM_SEC,
+ DRM_MAX,
+ };
+
// Initializes the backend and returns a GRSurface* to draw into.
virtual GRSurface* Init() = 0;
@@ -28,11 +34,17 @@
// be displayed, and returns a new drawing surface.
virtual GRSurface* Flip() = 0;
- // Blank (or unblank) the screen.
+ // Blank (or unblank) the default screen.
virtual void Blank(bool) = 0;
+ // Blank (or unblank) the specific screen.
+ virtual void Blank(bool blank, DrmConnector index) = 0;
+
+ // Return true if the device supports multiple connectors.
+ virtual bool HasMultipleConnectors() = 0;
+
// Device cleanup when drawing is done.
- virtual ~MinuiBackend() {};
+ virtual ~MinuiBackend() = default;
};
#endif // _GRAPHICS_H_
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
old mode 100755
new mode 100644
index 95759e3..6c3a5bd
--- a/minui/graphics_drm.cpp
+++ b/minui/graphics_drm.cpp
@@ -105,6 +105,8 @@
perror("Failed to DRM_IOCTL_MODE_CREATE_DUMB");
return nullptr;
}
+ printf("Allocating buffer with resolution %d x %d pitch: %d bpp: %d, size: %llu\n", width, height,
+ create_dumb.pitch, create_dumb.bpp, create_dumb.size);
// Cannot use std::make_unique to access non-public ctor.
auto surface = std::unique_ptr<GRSurfaceDrm>(new GRSurfaceDrm(
@@ -128,13 +130,14 @@
return nullptr;
}
- auto mmapped = mmap(nullptr, surface->height * surface->row_bytes, PROT_READ | PROT_WRITE,
- MAP_SHARED, drm_fd, map_dumb.offset);
+ auto mmapped =
+ mmap(nullptr, create_dumb.size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, map_dumb.offset);
if (mmapped == MAP_FAILED) {
perror("Failed to mmap()");
return nullptr;
}
surface->mmapped_buffer_ = static_cast<uint8_t*>(mmapped);
+ printf("Framebuffer of size %llu allocated @ %p\n", create_dumb.size, surface->mmapped_buffer_);
return surface;
}
@@ -150,23 +153,55 @@
}
bool MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc,
- const std::unique_ptr<GRSurfaceDrm>& surface) {
+ const std::unique_ptr<GRSurfaceDrm>& surface,
+ uint32_t* connector_id) {
if (drmModeSetCrtc(drm_fd, crtc->crtc_id, surface->fb_id, 0, 0, // x,y
- &main_monitor_connector->connector_id,
- 1, // connector_count
- &main_monitor_crtc->mode) != 0) {
- perror("Failed to drmModeSetCrtc");
+ connector_id, 1, // connector_count
+ &crtc->mode) != 0) {
+ fprintf(stderr, "Failed to drmModeSetCrtc(%d)\n", *connector_id);
return false;
}
+
return true;
}
void MinuiBackendDrm::Blank(bool blank) {
- if (blank) {
- DrmDisableCrtc(drm_fd, main_monitor_crtc);
- } else {
- DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]);
+ Blank(blank, DRM_MAIN);
+}
+
+void MinuiBackendDrm::Blank(bool blank, DrmConnector index) {
+ const auto* drmInterface = &drm[DRM_MAIN];
+
+ switch (index) {
+ case DRM_MAIN:
+ drmInterface = &drm[DRM_MAIN];
+ break;
+ case DRM_SEC:
+ drmInterface = &drm[DRM_SEC];
+ break;
+ default:
+ fprintf(stderr, "Invalid index: %d\n", index);
+ return;
}
+
+ if (!drmInterface->monitor_connector) {
+ fprintf(stderr, "Unsupported. index = %d\n", index);
+ return;
+ }
+
+ if (blank) {
+ DrmDisableCrtc(drm_fd, drmInterface->monitor_crtc);
+ } else {
+ DrmEnableCrtc(drm_fd, drmInterface->monitor_crtc,
+ drmInterface->GRSurfaceDrms[drmInterface->current_buffer],
+ &drmInterface->monitor_connector->connector_id);
+
+ active_display = index;
+ }
+}
+
+bool MinuiBackendDrm::HasMultipleConnectors() {
+ return (drm[DRM_SEC].GRSurfaceDrms[0] && drm[DRM_SEC].GRSurfaceDrms[1]);
}
static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources,
@@ -207,18 +242,21 @@
return nullptr;
}
-static drmModeConnector* find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) {
+std::vector<drmModeConnector*> find_used_connector_by_type(int fd, drmModeRes* resources,
+ unsigned type) {
+ std::vector<drmModeConnector*> drmConnectors;
for (int i = 0; i < resources->count_connectors; i++) {
drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]);
if (connector) {
if ((connector->connector_type == type) && (connector->connection == DRM_MODE_CONNECTED) &&
(connector->count_modes > 0)) {
- return connector;
+ drmConnectors.push_back(connector);
+ } else {
+ drmModeFreeConnector(connector);
}
- drmModeFreeConnector(connector);
}
}
- return nullptr;
+ return drmConnectors;
}
static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* resources) {
@@ -236,8 +274,7 @@
return nullptr;
}
-drmModeConnector* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources,
- uint32_t* mode_index) {
+bool MinuiBackendDrm::FindAndSetMonitor(int fd, drmModeRes* resources) {
/* Look for LVDS/eDP/DSI connectors. Those are the main screens. */
static constexpr unsigned kConnectorPriority[] = {
DRM_MODE_CONNECTOR_LVDS,
@@ -245,30 +282,41 @@
DRM_MODE_CONNECTOR_DSI,
};
- drmModeConnector* main_monitor_connector = nullptr;
- unsigned i = 0;
- do {
- main_monitor_connector = find_used_connector_by_type(fd, resources, kConnectorPriority[i]);
- i++;
- } while (!main_monitor_connector && i < arraysize(kConnectorPriority));
-
- /* If we didn't find a connector, grab the first one that is connected. */
- if (!main_monitor_connector) {
- main_monitor_connector = find_first_connected_connector(fd, resources);
- }
-
- /* If we still didn't find a connector, give up and return. */
- if (!main_monitor_connector) return nullptr;
-
- *mode_index = 0;
- for (int modes = 0; modes < main_monitor_connector->count_modes; modes++) {
- if (main_monitor_connector->modes[modes].type & DRM_MODE_TYPE_PREFERRED) {
- *mode_index = modes;
- break;
+ std::vector<drmModeConnector*> drmConnectors;
+ for (int i = 0; i < arraysize(kConnectorPriority) && drmConnectors.size() < DRM_MAX; i++) {
+ auto connectors = find_used_connector_by_type(fd, resources, kConnectorPriority[i]);
+ for (auto connector : connectors) {
+ drmConnectors.push_back(connector);
+ if (drmConnectors.size() >= DRM_MAX) break;
}
}
- return main_monitor_connector;
+ /* If we didn't find a connector, grab the first one that is connected. */
+ if (drmConnectors.empty()) {
+ drmModeConnector* connector = find_first_connected_connector(fd, resources);
+ if (connector) {
+ drmConnectors.push_back(connector);
+ }
+ }
+
+ for (int drm_index = 0; drm_index < drmConnectors.size(); drm_index++) {
+ drm[drm_index].monitor_connector = drmConnectors[drm_index];
+
+ drm[drm_index].selected_mode = 0;
+ for (int modes = 0; modes < drmConnectors[drm_index]->count_modes; modes++) {
+ printf("Display Mode %d resolution: %d x %d @ %d FPS\n", modes,
+ drmConnectors[drm_index]->modes[modes].hdisplay,
+ drmConnectors[drm_index]->modes[modes].vdisplay,
+ drmConnectors[drm_index]->modes[modes].vrefresh);
+ if (drmConnectors[drm_index]->modes[modes].type & DRM_MODE_TYPE_PREFERRED) {
+ printf("Choosing display mode #%d\n", modes);
+ drm[drm_index].selected_mode = modes;
+ break;
+ }
+ }
+ }
+
+ return drmConnectors.size() > 0;
}
void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) {
@@ -319,46 +367,49 @@
return nullptr;
}
- uint32_t selected_mode;
- main_monitor_connector = FindMainMonitor(drm_fd, res, &selected_mode);
- if (!main_monitor_connector) {
- fprintf(stderr, "Failed to find main_monitor_connector\n");
+ if (!FindAndSetMonitor(drm_fd, res)) {
+ fprintf(stderr, "Failed to find main monitor_connector\n");
drmModeFreeResources(res);
- close(drm_fd);
return nullptr;
}
- main_monitor_crtc = find_crtc_for_connector(drm_fd, res, main_monitor_connector);
- if (!main_monitor_crtc) {
- fprintf(stderr, "Failed to find main_monitor_crtc\n");
- drmModeFreeResources(res);
- close(drm_fd);
- return nullptr;
+ for (int i = 0; i < DRM_MAX; i++) {
+ if (drm[i].monitor_connector) {
+ drm[i].monitor_crtc = find_crtc_for_connector(drm_fd, res, drm[i].monitor_connector);
+ if (!drm[i].monitor_crtc) {
+ fprintf(stderr, "Failed to find monitor_crtc, drm index=%d\n", i);
+ drmModeFreeResources(res);
+ return nullptr;
+ }
+
+ drm[i].monitor_crtc->mode = drm[i].monitor_connector->modes[drm[i].selected_mode];
+
+ int width = drm[i].monitor_crtc->mode.hdisplay;
+ int height = drm[i].monitor_crtc->mode.vdisplay;
+
+ drm[i].GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height);
+ drm[i].GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height);
+ if (!drm[i].GRSurfaceDrms[0] || !drm[i].GRSurfaceDrms[1]) {
+ fprintf(stderr, "Failed to create GRSurfaceDrm, drm index=%d\n", i);
+ drmModeFreeResources(res);
+ return nullptr;
+ }
+
+ drm[i].current_buffer = 0;
+ }
}
- DisableNonMainCrtcs(drm_fd, res, main_monitor_crtc);
-
- main_monitor_crtc->mode = main_monitor_connector->modes[selected_mode];
-
- int width = main_monitor_crtc->mode.hdisplay;
- int height = main_monitor_crtc->mode.vdisplay;
+ DisableNonMainCrtcs(drm_fd, res, drm[DRM_MAIN].monitor_crtc);
drmModeFreeResources(res);
- GRSurfaceDrms[0] = GRSurfaceDrm::Create(drm_fd, width, height);
- GRSurfaceDrms[1] = GRSurfaceDrm::Create(drm_fd, width, height);
- if (!GRSurfaceDrms[0] || !GRSurfaceDrms[1]) {
- return nullptr;
- }
-
- current_buffer = 0;
-
// We will likely encounter errors in the backend functions (i.e. Flip) if EnableCrtc fails.
- if (!DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1])) {
+ if (!DrmEnableCrtc(drm_fd, drm[DRM_MAIN].monitor_crtc, drm[DRM_MAIN].GRSurfaceDrms[1],
+ &drm[DRM_MAIN].monitor_connector->connector_id)) {
return nullptr;
}
- return GRSurfaceDrms[0].get();
+ return drm[DRM_MAIN].GRSurfaceDrms[0].get();
}
static void page_flip_complete(__unused int fd,
@@ -370,10 +421,19 @@
}
GRSurface* MinuiBackendDrm::Flip() {
+ GRSurface* surface = NULL;
+ DrmInterface* current_drm = &drm[active_display];
bool ongoing_flip = true;
- if (drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id, GRSurfaceDrms[current_buffer]->fb_id,
+
+ if (!current_drm->monitor_connector) {
+ fprintf(stderr, "Unsupported. active_display = %d\n", active_display);
+ return nullptr;
+ }
+
+ if (drmModePageFlip(drm_fd, current_drm->monitor_crtc->crtc_id,
+ current_drm->GRSurfaceDrms[current_drm->current_buffer]->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, &ongoing_flip) != 0) {
- perror("Failed to drmModePageFlip");
+ fprintf(stderr, "Failed to drmModePageFlip, active_display=%d", active_display);
return nullptr;
}
@@ -399,14 +459,19 @@
}
}
- current_buffer = 1 - current_buffer;
- return GRSurfaceDrms[current_buffer].get();
+ current_drm->current_buffer = 1 - current_drm->current_buffer;
+ surface = current_drm->GRSurfaceDrms[current_drm->current_buffer].get();
+ return surface;
}
MinuiBackendDrm::~MinuiBackendDrm() {
- DrmDisableCrtc(drm_fd, main_monitor_crtc);
- drmModeFreeCrtc(main_monitor_crtc);
- drmModeFreeConnector(main_monitor_connector);
+ for (int i = 0; i < DRM_MAX; i++) {
+ if (drm[i].monitor_connector) {
+ DrmDisableCrtc(drm_fd, drm[i].monitor_crtc);
+ drmModeFreeCrtc(drm[i].monitor_crtc);
+ drmModeFreeConnector(drm[i].monitor_connector);
+ }
+ }
close(drm_fd);
drm_fd = -1;
}
diff --git a/minui/graphics_drm.h b/minui/graphics_drm.h
index 57ba39b..a8c9886 100644
--- a/minui/graphics_drm.h
+++ b/minui/graphics_drm.h
@@ -59,16 +59,24 @@
GRSurface* Init() override;
GRSurface* Flip() override;
void Blank(bool) override;
+ void Blank(bool blank, DrmConnector index) override;
+ bool HasMultipleConnectors() override;
private:
void DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc);
- bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface);
+ bool DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, const std::unique_ptr<GRSurfaceDrm>& surface,
+ uint32_t* conntcors);
void DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc);
- drmModeConnector* FindMainMonitor(int fd, drmModeRes* resources, uint32_t* mode_index);
+ bool FindAndSetMonitor(int fd, drmModeRes* resources);
- std::unique_ptr<GRSurfaceDrm> GRSurfaceDrms[2];
- int current_buffer{ 0 };
- drmModeCrtc* main_monitor_crtc{ nullptr };
- drmModeConnector* main_monitor_connector{ nullptr };
+ struct DrmInterface {
+ std::unique_ptr<GRSurfaceDrm> GRSurfaceDrms[2];
+ int current_buffer{ 0 };
+ drmModeCrtc* monitor_crtc{ nullptr };
+ drmModeConnector* monitor_connector{ nullptr };
+ uint32_t selected_mode{ 0 };
+ } drm[DRM_MAX];
+
int drm_fd{ -1 };
+ DrmConnector active_display = DRM_MAIN;
};
diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp
index 353a070..4a7d325 100644
--- a/minui/graphics_fbdev.cpp
+++ b/minui/graphics_fbdev.cpp
@@ -39,25 +39,17 @@
}
void MinuiBackendFbdev::Blank(bool blank) {
-#if defined(TW_NO_SCREEN_BLANK) && defined(TW_BRIGHTNESS_PATH) && defined(TW_MAX_BRIGHTNESS)
- int fd;
- char brightness[4];
- snprintf(brightness, 4, "%03d", TW_MAX_BRIGHTNESS/2);
+ int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
+ if (ret < 0) perror("ioctl(): blank");
+}
- fd = open(TW_BRIGHTNESS_PATH, O_RDWR);
- if (fd < 0) {
- perror("cannot open LCD backlight");
- return;
- }
- write(fd, blank ? "000" : brightness, 3);
- close(fd);
-#else
- int ret;
+void MinuiBackendFbdev::Blank(bool blank, DrmConnector index) {
+ fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index);
+}
- ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
- if (ret < 0)
- perror("ioctl(): blank");
-#endif
+bool MinuiBackendFbdev::HasMultipleConnectors() {
+ fprintf(stderr, "Unsupported multiple connectors\n");
+ return false;
}
void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) {
@@ -148,8 +140,6 @@
SetDisplayedFramebuffer(0);
printf("framebuffer: %d (%zu x %zu)\n", fb_fd.get(), gr_draw->width, gr_draw->height);
-
- Blank(true);
Blank(false);
return gr_draw;
diff --git a/minui/graphics_fbdev.h b/minui/graphics_fbdev.h
index 596ba74..c772428 100644
--- a/minui/graphics_fbdev.h
+++ b/minui/graphics_fbdev.h
@@ -56,6 +56,8 @@
GRSurface* Init() override;
GRSurface* Flip() override;
void Blank(bool) override;
+ void Blank(bool blank, DrmConnector index) override;
+ bool HasMultipleConnectors() override;
private:
void SetDisplayedFramebuffer(size_t n);
diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h
old mode 100755
new mode 100644
index ecc0c9e..2353ed3
--- a/minui/include/minui/minui.h
+++ b/minui/include/minui/minui.h
@@ -15,10 +15,6 @@
*/
#pragma once
-#ifndef _MINUI_H_
-#define _MINUI_H_
-
-#ifndef TW_USE_MINUI_21
#include <stdint.h>
#include <stdlib.h>
@@ -106,12 +102,22 @@
RGBX = 2,
BGRA = 3,
ARGB = 4,
+ RGBA = 5, // LSB Alpha
};
-// Initializes the graphics backend and loads font file. Returns 0 on success, or -1 on error. Note
-// that the font initialization failure would be non-fatal, as caller may not need to draw any text
-// at all. Caller can check the font initialization result via gr_sys_font() as needed.
+enum class GraphicsBackend : int {
+ UNKNOWN = 0,
+ DRM = 1,
+ FBDEV = 2,
+};
+
+// Initializes the default graphics backend and loads font file. Returns 0 on success, or -1 on
+// error. Note that the font initialization failure would be non-fatal, as caller may not need to
+// draw any text at all. Caller can check the font initialization result via gr_sys_font() as
+// needed.
int gr_init();
+// Supports backend selection for minui client.
+int gr_init(std::initializer_list<GraphicsBackend> backends);
// Frees the allocated resources. The function is idempotent, and safe to be called if gr_init()
// didn't finish successfully.
@@ -122,19 +128,14 @@
void gr_flip();
void gr_fb_blank(bool blank);
+void gr_fb_blank(bool blank, int index);
+bool gr_has_multiple_connectors();
// Clears entire surface to current color.
void gr_clear();
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void gr_fill(int x1, int y1, int x2, int y2);
-void gr_texticon(int x, int y, GRSurface* icon);
-#ifdef TW_NO_MINUI_CUSTOM_FONTS
-void gr_text(int x, int y, const char *s, bool bold);
-int gr_measure(const char *s);
-void gr_font_size(int *x, int *y);
-void gr_set_font(__attribute__ ((unused))const char* name);
-#else
void gr_texticon(int x, int y, const GRSurface* icon);
const GRFont* gr_sys_font();
@@ -144,7 +145,7 @@
int gr_measure(const GRFont* font, const char* s);
// Returns -1 if font is nullptr.
int gr_font_size(const GRFont* font, int* x, int* y);
-#endif
+
void gr_blit(const GRSurface* source, int sx, int sy, int w, int h, int dx, int dy);
unsigned int gr_get_width(const GRSurface* surface);
unsigned int gr_get_height(const GRSurface* surface);
@@ -161,31 +162,17 @@
struct input_event;
-#ifdef TW_USE_MINUI_WITH_DATA
-typedef int (*ev_callback)(int fd, uint32_t epevents, void* data);
-typedef int (*ev_set_key_callback)(int code, int value, void* data);
-
-int ev_init(ev_callback input_cb, void* data);
-int ev_add_fd(int fd, ev_callback cb, void* data);
-int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data);
-#else
using ev_callback = std::function<int(int fd, uint32_t epevents)>;
using ev_set_key_callback = std::function<int(int code, int value)>;
+using ev_set_sw_callback = std::function<int(int code, int value)>;
-#ifdef TW_USE_MINUI_WITH_OPTIONAL_TOUCH_EVENTS
int ev_init(ev_callback input_cb, bool allow_touch_inputs = false);
void ev_exit();
int ev_add_fd(android::base::unique_fd&& fd, ev_callback cb);
void ev_iterate_available_keys(const std::function<void(int)>& f);
void ev_iterate_touch_inputs(const std::function<void(int)>& action);
-#else
-int ev_init(ev_callback input_cb);
-#endif
-int ev_add_fd(int fd, ev_callback cb);
int ev_sync_key_state(const ev_set_key_callback& set_key_cb);
-#endif
-void ev_exit();
-void ev_iterate_available_keys(const std::function<void(int)>& f);
+int ev_sync_sw_state(const ev_set_sw_callback& set_sw_cb);
// 'timeout' has the same semantics as poll(2).
// 0 : don't block
@@ -220,9 +207,7 @@
// should have a 'Frames' text chunk whose value is the number of
// frames this image represents. The pixel data itself is interlaced
// by row.
-int res_create_multi_display_surface(const char* name, int* frames,
- int* fps, GRSurface*** pSurface);
-int res_create_multi_display_surface(const char* name, int* frames,
+int res_create_multi_display_surface(const char* name, int* frames, int* fps,
GRSurface*** pSurface);
// Load a single alpha surface from a grayscale PNG image.
@@ -243,95 +228,3 @@
// Free a surface allocated by any of the res_create_*_surface()
// functions.
void res_free_surface(GRSurface* surface);
-#else //ifndef TW_USE_MINUI_21
-
-// This the old minui21/minui.h for compatibility with building TWRP
-// in pre 6.0 trees.
-
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void* gr_surface;
-typedef unsigned short gr_pixel;
-
-int gr_init(void);
-void gr_exit(void);
-
-int gr_fb_width(void);
-int gr_fb_height(void);
-gr_pixel *gr_fb_data(void);
-void gr_flip(void);
-void gr_fb_blank(bool blank);
-
-void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-void gr_fill(int x1, int y1, int x2, int y2);
-
-// system/core/charger uses different gr_print signatures in diferent
-// Android versions, either with or without int bold.
-int gr_text(int x, int y, const char *s, ...);
-int gr_text_impl(int x, int y, const char *s, int bold);
-
- void gr_texticon(int x, int y, gr_surface icon);
-int gr_measure(const char *s);
-void gr_font_size(int *x, int *y);
-void gr_get_memory_surface(gr_surface);
-
-void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy);
-unsigned int gr_get_width(gr_surface surface);
-unsigned int gr_get_height(gr_surface surface);
-
-// input event structure, include <linux/input.h> for the definition.
-// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
-struct input_event;
-
-typedef int (*ev_callback)(int fd, uint32_t epevents, void *data);
-typedef int (*ev_set_key_callback)(int code, int value, void *data);
-
-int ev_init(ev_callback input_cb, void *data);
-void ev_exit(void);
-int ev_add_fd(int fd, ev_callback cb, void *data);
-int ev_sync_key_state(ev_set_key_callback set_key_cb, void *data);
-
-/* timeout has the same semantics as for poll
- * 0 : don't block
- * < 0 : block forever
- * > 0 : block for 'timeout' milliseconds
- */
-int ev_wait(int timeout);
-
-int ev_get_input(int fd, uint32_t epevents, struct input_event *ev);
-void ev_dispatch(void);
-int ev_get_epollfd(void);
-
-// Resources
-
-// Returns 0 if no error, else negative.
-int res_create_surface(const char* name, gr_surface* pSurface);
-
-// Load an array of display surfaces from a single PNG image. The PNG
-// should have a 'Frames' text chunk whose value is the number of
-// frames this image represents. The pixel data itself is interlaced
-// by row.
-int res_create_multi_display_surface(const char* name,
- int* frames, gr_surface** pSurface);
-
-int res_create_localized_surface(const char* name, gr_surface* pSurface);
-void res_free_surface(gr_surface surface);
-static inline int res_create_display_surface(const char* name, gr_surface* pSurface) {
- return res_create_surface(name, pSurface);
-}
-
-// These are new graphics functions from 5.0 that were not available in
-// 4.4 that are required by charger and healthd
-void gr_clear();
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ifndef TW_USE_MINUI_21
-#endif // ifndef _MINUI_H_
diff --git a/minui/resources.cpp b/minui/resources.cpp
old mode 100755
new mode 100644
index fe47df1..1521c8f
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -153,32 +153,57 @@
int width) {
const uint8_t* ip = input_row;
uint8_t* op = output_row;
+ PixelFormat pixel_format = gr_pixel_format();
switch (channels) {
case 1:
// expand gray level to RGBX
for (int x = 0; x < width; ++x) {
- *op++ = *ip;
- *op++ = *ip;
- *op++ = *ip;
- *op++ = 0xff;
+ if (pixel_format == PixelFormat::RGBA) {
+ *op++ = 0xff;
+ *op++ = *ip;
+ *op++ = *ip;
+ *op++ = *ip;
+ } else {
+ *op++ = *ip;
+ *op++ = *ip;
+ *op++ = *ip;
+ *op++ = 0xff;
+ }
ip++;
}
break;
case 3:
- // expand RGBA to RGBX
for (int x = 0; x < width; ++x) {
- *op++ = *ip++;
- *op++ = *ip++;
- *op++ = *ip++;
- *op++ = 0xff;
+ // expand RGBA to RGBX
+ if (pixel_format == PixelFormat::RGBA) {
+ *op++ = 0xff;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ } else {
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = 0xff;
+ }
}
break;
case 4:
- // copy RGBA to RGBX
- memcpy(output_row, input_row, width * 4);
+ if (pixel_format == PixelFormat::RGBA) {
+ for (int x = 0; x < width; ++x) {
+ *op++ = *(ip + 3);
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ ip++;
+ }
+ } else {
+ // copy RGBA to RGBX
+ memcpy(output_row, input_row, width * 4);
+ }
break;
}
}
@@ -201,6 +226,8 @@
PixelFormat pixel_format = gr_pixel_format();
if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
png_set_bgr(png_ptr);
+ } else if (pixel_format == PixelFormat::RGBA) {
+ png_set_swap_alpha(png_ptr);
}
for (png_uint_32 y = 0; y < height; ++y) {
@@ -273,6 +300,8 @@
if (gr_pixel_format() == PixelFormat::ARGB || gr_pixel_format() == PixelFormat::BGRA) {
png_set_bgr(png_ptr);
+ } else if (gr_pixel_format() == PixelFormat::RGBA) {
+ png_set_swap_alpha(png_ptr);
}
for (png_uint_32 y = 0; y < height; ++y) {
@@ -297,12 +326,6 @@
return result;
}
-int res_create_multi_display_surface(const char* name, int* frames,
- GRSurface*** pSurface) {
- int fps = 0;
- return res_create_multi_display_surface(name, frames, &fps, pSurface);
-}
-
int res_create_alpha_surface(const char* name, GRSurface** pSurface) {
*pSurface = nullptr;
@@ -322,11 +345,6 @@
return -8;
}
- PixelFormat pixel_format = gr_pixel_format();
- if (pixel_format == PixelFormat::ARGB || pixel_format == PixelFormat::BGRA) {
- png_set_bgr(png_ptr);
- }
-
for (png_uint_32 y = 0; y < height; ++y) {
uint8_t* p_row = surface->data() + y * surface->row_bytes;
png_read_row(png_ptr, p_row, nullptr);
diff --git a/otautil/Android.bp b/otautil/Android.bp
index 557b8a3..4b043ad 100755
--- a/otautil/Android.bp
+++ b/otautil/Android.bp
@@ -34,16 +34,21 @@
// Minimal set of files to support host build.
srcs: [
+ "asn1_decoder.cpp",
"dirutil.cpp",
+ "package.cpp",
"paths.cpp",
"rangeset.cpp",
"sysutil.cpp",
+ "verifier.cpp",
],
shared_libs: [
"libbase",
+ "libcrypto",
"libcutils",
"libselinux",
+ "libziparchive",
],
export_include_dirs: [
diff --git a/install/asn1_decoder.cpp b/otautil/asn1_decoder.cpp
similarity index 100%
rename from install/asn1_decoder.cpp
rename to otautil/asn1_decoder.cpp
diff --git a/install/include/install/package.h b/otautil/include/otautil/package.h
similarity index 97%
rename from install/include/install/package.h
rename to otautil/include/otautil/package.h
index 3699752..c933e78 100755
--- a/install/include/install/package.h
+++ b/otautil/include/otautil/package.h
@@ -26,7 +26,7 @@
#include <ziparchive/zip_archive.h>
-#include "verifier.h"
+#include "otautil/verifier.h"
enum class PackageType {
kMemory,
diff --git a/install/include/install/verifier.h b/otautil/include/otautil/verifier.h
similarity index 100%
rename from install/include/install/verifier.h
rename to otautil/include/otautil/verifier.h
diff --git a/install/include/private/asn1_decoder.h b/otautil/include/private/asn1_decoder.h
similarity index 100%
rename from install/include/private/asn1_decoder.h
rename to otautil/include/private/asn1_decoder.h
diff --git a/install/package.cpp b/otautil/package.cpp
similarity index 99%
rename from install/package.cpp
rename to otautil/package.cpp
index d3470bc..a6febb3 100755
--- a/install/package.cpp
+++ b/otautil/package.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "install/package.h"
+#include "otautil/package.h"
#include <string.h>
#include <unistd.h>
diff --git a/install/verifier.cpp b/otautil/verifier.cpp
similarity index 98%
rename from install/verifier.cpp
rename to otautil/verifier.cpp
index 3f02601..8a65566 100644
--- a/install/verifier.cpp
+++ b/otautil/verifier.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "install/verifier.h"
+#include "otautil/verifier.h"
#include <errno.h>
#include <stdio.h>
@@ -257,8 +257,8 @@
// Check to make sure at least one of the keys matches the signature. Since any key can match,
// we need to try each before determining a verification failure has happened.
- size_t i = 0;
- for (const auto& key : keys) {
+ for (size_t i = 0; i < keys.size(); i++) {
+ const auto& key = keys[i];
const uint8_t* hash;
int hash_nid;
switch (key.hash_len) {
@@ -296,7 +296,6 @@
} else {
LOG(INFO) << "Unknown key type " << key.key_type;
}
- i++;
}
if (need_sha1) {
diff --git a/partition.cpp b/partition.cpp
index 3019708..0a87c4e 100755
--- a/partition.cpp
+++ b/partition.cpp
@@ -680,21 +680,22 @@
if (Is_Present) {
if (Key_Directory.empty()) {
set_partition_data(Use_Original_Path ? Original_Path.c_str() : Actual_Block_Device.c_str(), Crypto_Key_Location.c_str());
- if (cryptfs_check_footer() == 0) {
- Is_Encrypted = true;
- Is_Decrypted = false;
- Can_Be_Mounted = false;
- Current_File_System = "emmc";
- Setup_Image();
- DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type());
- DataManager::SetValue("tw_crypto_pwtype_0", cryptfs_get_password_type());
- DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
- DataManager::SetValue("tw_crypto_display", "");
- if (datamedia)
- Setup_Data_Media();
- } else {
- gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer.");
- }
+ //if (cryptfs_check_footer() == 0) {
+ // Is_Encrypted = true;
+ // Is_Decrypted = false;
+ // Can_Be_Mounted = false;
+ // Current_File_System = "emmc";
+ // Setup_Image();
+ // DataManager::SetValue(TW_CRYPTO_PWTYPE, cryptfs_get_password_type());
+ // DataManager::SetValue("tw_crypto_pwtype_0", cryptfs_get_password_type());
+ // DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
+ // DataManager::SetValue("tw_crypto_display", "");
+ // if (datamedia)
+ // Setup_Data_Media();
+ //}
+ // else {
+ // gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer.");
+ //}
} else {
Is_Encrypted = true;
Is_Decrypted = false;
@@ -1728,7 +1729,7 @@
}
bool TWPartition::Wipe(string New_File_System) {
- bool wiped = false, update_crypt = false, recreate_media = true;
+ bool wiped = false, update_crypt = false, recreate_media = false;
int check;
if (!Can_Be_Wiped) {
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index ebdada4..6f55065 100755
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -466,23 +466,6 @@
gui_err("unable_to_decrypt=Unable to decrypt with default password.");
}
}
- } else {
- LOGINFO("FBE setup failed. Trying FDE...");
- Set_Crypto_State();
- Set_Crypto_Type("block");
- int password_type = cryptfs_get_password_type();
- if (password_type == CRYPT_TYPE_DEFAULT) {
- LOGINFO("Device is encrypted with the default password, attempting to decrypt.\n");
- if (Decrypt_Device("default_password") == 0) {
- gui_msg("decrypt_success=Successfully decrypted with default password.");
- DataManager::SetValue(TW_IS_ENCRYPTED, 0);
- } else {
- gui_err("unable_to_decrypt=Unable to decrypt with default password.");
- }
- } else {
- DataManager::SetValue("TW_CRYPTO_TYPE", password_type);
- DataManager::SetValue("tw_crypto_pwtype_0", password_type);
- }
}
}
if (Decrypt_Data && (!Decrypt_Data->Is_Encrypted || Decrypt_Data->Is_Decrypted)) {
@@ -911,12 +894,11 @@
string Backup_Name, Backup_List, backup_path;
unsigned long long total_bytes = 0, free_space = 0;
TWPartition* storage = NULL;
- struct tm *t;
- time_t seconds, total_start, total_stop;
+ time_t total_start, total_stop;
+ //time_t seconds = time(0);
+ //struct tm *t = localtime(&seconds);
size_t start_pos = 0, end_pos = 0;
stop_backup.set_value(0);
- seconds = time(0);
- t = localtime(&seconds);
part_settings.img_bytes_remaining = 0;
part_settings.file_bytes_remaining = 0;
@@ -2024,8 +2006,8 @@
// Child process
char cPassword[255];
strcpy(cPassword, Password.c_str());
- int ret = cryptfs_check_passwd(cPassword);
- exit(ret);
+ //int ret = cryptfs_check_passwd(cPassword);
+ exit(0);
} else {
// Parent
int status;
diff --git a/pigz/Android.mk b/pigz/Android.mk
index 2875fd1..723367a 100755
--- a/pigz/Android.mk
+++ b/pigz/Android.mk
@@ -6,7 +6,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
-LOCAL_CFLAGS :=
+LOCAL_CFLAGS := -Wno-unused-but-set-variable
LOCAL_SRC_FILES = pigz.c yarn.c
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
external/zlib
diff --git a/recovery.cpp b/recovery.cpp
index 36924fb..4d39019 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -48,12 +48,12 @@
#include "install/adb_install.h"
#include "install/fuse_install.h"
#include "install/install.h"
-#include "install/package.h"
#include "install/snapshot_utils.h"
#include "install/wipe_data.h"
#include "install/wipe_device.h"
#include "otautil/boot_state.h"
#include "otautil/error_code.h"
+#include "otautil/package.h"
#include "otautil/paths.h"
#include "otautil/sysutil.h"
#include "recovery_ui/screen_ui.h"
@@ -207,8 +207,7 @@
if (ask_to_wipe_data(device)) {
CHECK(device->GetReason().has_value());
- bool convert_fbe = device->GetReason().value() == "convert_fbe";
- if (WipeData(device, convert_fbe)) {
+ if (WipeData(device)) {
return INSTALL_SUCCESS;
} else {
return INSTALL_ERROR;
@@ -437,10 +436,10 @@
save_current_log = true;
if (ui->IsTextVisible()) {
if (ask_to_wipe_data(device)) {
- WipeData(device, false);
+ WipeData(device);
}
} else {
- WipeData(device, false);
+ WipeData(device);
return Device::NO_ACTION;
}
break;
@@ -752,20 +751,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");
@@ -794,8 +793,7 @@
} else if (should_wipe_data) {
save_current_log = true;
CHECK(device->GetReason().has_value());
- bool convert_fbe = device->GetReason().value() == "convert_fbe";
- if (!WipeData(device, convert_fbe)) {
+ if (!WipeData(device)) {
status = INSTALL_ERROR;
}
} else if (should_prompt_and_wipe_data) {
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 80cba61..9a358ab 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -73,12 +73,12 @@
return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
}
-static void UiLogger(android::base::LogId /* id */, android::base::LogSeverity severity,
- const char* /* tag */, const char* /* file */, unsigned int /* line */,
- const char* message) {
- static constexpr char log_characters[] = "VDIWEF";
+static void UiLogger(android::base::LogId log_buffer_id, android::base::LogSeverity severity,
+ const char* tag, const char* file, unsigned int line, const char* message) {
+ android::base::KernelLogger(log_buffer_id, severity, tag, file, line, message);
+ static constexpr auto&& log_characters = "VDIWEF";
if (severity >= android::base::ERROR && ui != nullptr) {
- ui->Print("E:%s\n", message);
+ ui->Print("ERROR: %10s: %s\n", tag, message);
} else {
fprintf(stdout, "%c:%s\n", log_characters[severity], message);
}
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/recovery_utils/Android.bp b/recovery_utils/Android.bp
index d5f6e84..5297584 100644
--- a/recovery_utils/Android.bp
+++ b/recovery_utils/Android.bp
@@ -31,6 +31,7 @@
shared_libs: [
"android.hardware.health@2.0",
"libbase",
+ "libbinder_ndk",
"libext4_utils",
"libfs_mgr",
"libhidlbase",
@@ -42,8 +43,10 @@
"libotautil",
// External dependencies.
+ "android.hardware.health-translate-ndk",
"libfstab",
"libhealthhalutils",
+ "libhealthshim",
],
}
@@ -70,6 +73,15 @@
"libvold_headers",
],
+ shared_libs: [
+ // The following cannot be placed in librecovery_utils_defaults,
+ // because at the time of writing, android.hardware.health-V1-ndk.so
+ // is not installed to the system image yet. (It is installed
+ // to the recovery ramdisk.) Hence, minadbd_test must link to it
+ // statically.
+ "android.hardware.health-V1-ndk",
+ ],
+
export_include_dirs: [
"include",
],
diff --git a/recovery_utils/battery_utils.cpp b/recovery_utils/battery_utils.cpp
index 323f525..6b126bd 100644
--- a/recovery_utils/battery_utils.cpp
+++ b/recovery_utils/battery_utils.cpp
@@ -20,59 +20,74 @@
#include <unistd.h>
#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <health-shim/shim.h>
#include <healthhalutils/HealthHalUtils.h>
BatteryInfo GetBatteryInfo() {
- using android::hardware::health::V1_0::BatteryStatus;
using android::hardware::health::V2_0::get_health_service;
- using android::hardware::health::V2_0::IHealth;
- using android::hardware::health::V2_0::Result;
- using android::hardware::health::V2_0::toString;
+ using HidlHealth = android::hardware::health::V2_0::IHealth;
+ using aidl::android::hardware::health::BatteryStatus;
+ using aidl::android::hardware::health::HealthShim;
+ using aidl::android::hardware::health::IHealth;
+ using aidl::android::hardware::health::toString;
+ using std::string_literals::operator""s;
- android::sp<IHealth> health = get_health_service();
+ auto service_name = IHealth::descriptor + "/default"s;
+ std::shared_ptr<IHealth> health;
+ if (AServiceManager_isDeclared(service_name.c_str())) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(service_name.c_str()));
+ health = IHealth::fromBinder(binder);
+ }
+ if (health == nullptr) {
+ LOG(INFO) << "Unable to get AIDL health service, trying HIDL...";
+ android::sp<HidlHealth> hidl_health = get_health_service();
+ if (hidl_health != nullptr) {
+ health = ndk::SharedRefBase::make<HealthShim>(hidl_health);
+ }
+ }
+ if (health == nullptr) {
+ LOG(WARNING) << "No health implementation is found; assuming defaults";
+ }
int wait_second = 0;
while (true) {
auto charge_status = BatteryStatus::UNKNOWN;
-
- if (health == nullptr) {
- LOG(WARNING) << "No health implementation is found; assuming defaults";
- } else {
- health
- ->getChargeStatus([&charge_status](auto res, auto out_status) {
- if (res == Result::SUCCESS) {
- charge_status = out_status;
- }
- })
- .isOk(); // should not have transport error
+ if (health != nullptr) {
+ auto res = health->getChargeStatus(&charge_status);
+ if (!res.isOk()) {
+ LOG(WARNING) << "Unable to call getChargeStatus: " << res.getDescription();
+ charge_status = BatteryStatus::UNKNOWN;
+ }
}
- // Treat unknown status as on charger. See hardware/interfaces/health/1.0/types.hal for the
- // meaning of the return values.
+ // Treat unknown status as on charger. See hardware/interfaces/health/aidl/BatteryStatus.aidl
+ // for the meaning of the return values.
bool charging = (charge_status != BatteryStatus::DISCHARGING &&
charge_status != BatteryStatus::NOT_CHARGING);
- Result res = Result::UNKNOWN;
int32_t capacity = INT32_MIN;
if (health != nullptr) {
- health
- ->getCapacity([&res, &capacity](auto out_res, auto out_capacity) {
- res = out_res;
- capacity = out_capacity;
- })
- .isOk(); // should not have transport error
+ auto res = health->getCapacity(&capacity);
+ if (!res.isOk()) {
+ LOG(WARNING) << "Unable to call getCapacity: " << res.getDescription();
+ capacity = INT32_MIN;
+ }
}
LOG(INFO) << "charge_status " << toString(charge_status) << ", charging " << charging
- << ", status " << toString(res) << ", capacity " << capacity;
+ << ", capacity " << capacity;
constexpr int BATTERY_READ_TIMEOUT_IN_SEC = 10;
// At startup, the battery drivers in devices like N5X/N6P take some time to load
// the battery profile. Before the load finishes, it reports value 50 as a fake
// capacity. BATTERY_READ_TIMEOUT_IN_SEC is set that the battery drivers are expected
// to finish loading the battery profile earlier than 10 seconds after kernel startup.
- if (res == Result::SUCCESS && capacity == 50) {
+ if (capacity == 50) {
if (wait_second < BATTERY_READ_TIMEOUT_IN_SEC) {
+ LOG(INFO) << "Battery capacity == 50, waiting "
+ << (BATTERY_READ_TIMEOUT_IN_SEC - wait_second)
+ << " seconds to ensure this is not a fake value...";
sleep(1);
wait_second++;
continue;
@@ -80,10 +95,12 @@
}
// If we can't read battery percentage, it may be a device without battery. In this
// situation, use 100 as a fake battery percentage.
- if (res != Result::SUCCESS) {
+ if (capacity == INT32_MIN) {
+ LOG(WARNING) << "Using fake battery capacity 100.";
capacity = 100;
}
+ LOG(INFO) << "GetBatteryInfo() reporting charging " << charging << ", capacity " << capacity;
return BatteryInfo{ charging, capacity };
}
}
diff --git a/recovery_utils/roots.cpp b/recovery_utils/roots.cpp
index 1948447..5c95cba 100644
--- a/recovery_utils/roots.cpp
+++ b/recovery_utils/roots.cpp
@@ -33,7 +33,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
-#include <cryptfs.h>
+#include <ext4_utils/ext4_utils.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>
#include <fs_mgr/roots.h>
@@ -154,53 +154,56 @@
}
bool needs_casefold = false;
- bool needs_projid = false;
if (volume == "/data") {
needs_casefold = android::base::GetBoolProperty("external_storage.casefold.enabled", false);
- needs_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false);
- }
-
- // If there's a key_loc that looks like a path, it should be a block device for storing encryption
- // metadata. Wipe it too.
- if (!v->key_loc.empty() && v->key_loc[0] == '/') {
- LOG(INFO) << "Wiping " << v->key_loc;
- int fd = open(v->key_loc.c_str(), O_WRONLY | O_CREAT, 0644);
- if (fd == -1) {
- PLOG(ERROR) << "format_volume: Failed to open " << v->key_loc;
- return -1;
- }
- wipe_block_device(fd, get_file_size(fd));
- close(fd);
}
int64_t length = 0;
if (v->length > 0) {
length = v->length;
- } else if (v->length < 0 || v->key_loc == "footer") {
+ } else if (v->length < 0) {
android::base::unique_fd fd(open(v->blk_device.c_str(), O_RDONLY));
if (fd == -1) {
PLOG(ERROR) << "format_volume: failed to open " << v->blk_device;
return -1;
}
- length = get_file_size(fd.get(), v->length ? -v->length : CRYPT_FOOTER_OFFSET);
+ length = get_file_size(fd.get(), -v->length);
if (length <= 0) {
LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device;
return -1;
}
}
+ // If the raw disk will be used as a metadata encrypted device mapper target,
+ // next boot will do encrypt_in_place the raw disk which gives a subtle duration
+ // to get any failure in the process. In order to avoid it, let's simply wipe
+ // the raw disk if we don't reserve any space, which behaves exactly same as booting
+ // after "fastboot -w".
+ if (!v->metadata_key_dir.empty() && length == 0) {
+ android::base::unique_fd fd(open(v->blk_device.c_str(), O_RDWR));
+ if (fd == -1) {
+ PLOG(ERROR) << "format_volume: failed to open " << v->blk_device;
+ return -1;
+ }
+ int64_t device_size = get_file_size(fd.get(), 0);
+ if (device_size > 0 && !wipe_block_device(fd.get(), device_size)) {
+ LOG(INFO) << "format_volume: wipe metadata encrypted " << v->blk_device << " with size "
+ << device_size;
+ return 0;
+ }
+ }
+
if (v->fs_type == "ext4") {
static constexpr int kBlockSize = 4096;
std::vector<std::string> mke2fs_args = {
"/system/bin/mke2fs", "-F", "-t", "ext4", "-b", std::to_string(kBlockSize),
};
- // Project ID's require wider inodes. The Quotas themselves are enabled by tune2fs on boot.
- if (needs_projid) {
- mke2fs_args.push_back("-I");
- mke2fs_args.push_back("512");
- }
+ // Following is added for Project ID's quota as they require wider inodes.
+ // The Quotas themselves are enabled by tune2fs on boot.
+ mke2fs_args.push_back("-I");
+ mke2fs_args.push_back("512");
if (v->fs_mgr_flags.ext_meta_csum) {
mke2fs_args.push_back("-O");
@@ -249,10 +252,10 @@
"-g",
"android",
};
- if (needs_projid) {
- make_f2fs_cmd.push_back("-O");
- make_f2fs_cmd.push_back("project_quota,extra_attr");
- }
+
+ make_f2fs_cmd.push_back("-O");
+ make_f2fs_cmd.push_back("project_quota,extra_attr");
+
if (needs_casefold) {
make_f2fs_cmd.push_back("-O");
make_f2fs_cmd.push_back("casefold");
diff --git a/tests/Android.bp b/tests/Android.bp
index be4d476..fb403e5 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -134,11 +134,22 @@
test_suites: ["device-tests"],
+ tidy_timeout_srcs: [
+ "unit/commands_test.cpp",
+ ],
+
srcs: [
"unit/*.cpp",
],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+
static_libs: libapplypatch_static_libs + librecovery_static_libs + [
+ "android.hardware.health-translate-ndk",
+ "android.hardware.health-V1-ndk",
+ "libhealthshim",
"librecovery_ui",
"libfusesideload",
"libminui",
@@ -185,6 +196,10 @@
"libupdater_defaults",
],
+ tidy_timeout_srcs: [
+ "unit/host/imgdiff_test.cpp",
+ ],
+
srcs: [
"unit/host/*",
],
diff --git a/tests/fuzz/verify_package_fuzzer.cpp b/tests/fuzz/verify_package_fuzzer.cpp
index baa44e0..36c8534 100644
--- a/tests/fuzz/verify_package_fuzzer.cpp
+++ b/tests/fuzz/verify_package_fuzzer.cpp
@@ -17,7 +17,7 @@
#include "fuzzer/FuzzedDataProvider.h"
#include "install/install.h"
-#include "install/package.h"
+#include "otautil/package.h"
#include "recovery_ui/stub_ui.h"
std::unique_ptr<Package> CreatePackage(std::vector<uint8_t>& content) {
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";
diff --git a/tests/unit/package_test.cpp b/tests/unit/package_test.cpp
index 164a93d..66882bb 100644
--- a/tests/unit/package_test.cpp
+++ b/tests/unit/package_test.cpp
@@ -26,7 +26,7 @@
#include <ziparchive/zip_writer.h>
#include "common/test_constants.h"
-#include "install/package.h"
+#include "otautil/package.h"
class PackageTest : public ::testing::Test {
protected:
diff --git a/tests/unit/verifier_test.cpp b/tests/unit/verifier_test.cpp
index ded23c5..08a3ddf 100644
--- a/tests/unit/verifier_test.cpp
+++ b/tests/unit/verifier_test.cpp
@@ -35,8 +35,8 @@
#include <ziparchive/zip_writer.h>
#include "common/test_constants.h"
-#include "install/package.h"
-#include "install/verifier.h"
+#include "otautil/package.h"
+#include "otautil/verifier.h"
#include "otautil/sysutil.h"
using namespace std::string_literals;
diff --git a/tools/recovery_l10n/res/values-as/strings.xml b/tools/recovery_l10n/res/values-as/strings.xml
index 33a204d..d956b9a 100644
--- a/tools/recovery_l10n/res/values-as/strings.xml
+++ b/tools/recovery_l10n/res/values-as/strings.xml
@@ -6,9 +6,9 @@
<string name="recovery_no_command" msgid="4465476568623024327">"কোনো আদেশ নাই"</string>
<string name="recovery_error" msgid="5748178989622716736">"ত্ৰুটি!"</string>
<string name="recovery_installing_security" msgid="9184031299717114342">"সুৰক্ষা আপডেইট ইনষ্টল কৰি থকা হৈছে"</string>
- <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android ছিষ্টেম ল\'ড কৰিব নোৱাৰি। আপোনাৰ ডেটাত কিবা আসোঁৱাহ থকা যেন লাগিছে। আপুনি যদি এই বাৰ্তাটো পায়েই থাকে, আপুনি নিজৰ ডিভাইচটো ফেক্টৰী ডেটা ৰিছেট কৰি সেইটোত থকা ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব লগা হ\'ব পাৰে।"</string>
+ <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android ছিষ্টেম ল\'ড কৰিব নোৱাৰি। আপোনাৰ ডেটাত কিবা আসোঁৱাহ থকা যেন লাগিছে। আপুনি যদি এই বাৰ্তাটো পায়েই থাকে, আপুনি নিজৰ ডিভাইচটো ফেক্টৰী ডেটা ৰিছেট কৰি সেইটোত থকা ব্যৱহাৰকাৰীৰ আটাইবোৰ ডেটা মচিব লগা হ\'ব পাৰে।"</string>
<string name="recovery_try_again" msgid="7168248750158873496">"আকৌ চেষ্টা কৰক"</string>
<string name="recovery_factory_data_reset" msgid="7321351565602894783">"ফেক্টৰী ডেটা ৰিছেট"</string>
- <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিবনে?\n\n এইটো কৰাৰ পিছত আনডু কৰিব নোৱাৰি!"</string>
+ <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"ব্যৱহাৰকাৰীৰ আটাইবোৰ ডেটা মচিবনে?\n\n এইটো কৰাৰ পাছত আনডু কৰিব নোৱাৰি!"</string>
<string name="recovery_cancel_wipe_data" msgid="66987687653647384">"বাতিল কৰক"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ky/strings.xml b/tools/recovery_l10n/res/values-ky/strings.xml
index 45fcd15..67dca2a 100644
--- a/tools/recovery_l10n/res/values-ky/strings.xml
+++ b/tools/recovery_l10n/res/values-ky/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recovery_installing" msgid="2013591905463558223">"Тутум жаңырууда"</string>
+ <string name="recovery_installing" msgid="2013591905463558223">"Система жаңырууда"</string>
<string name="recovery_erasing" msgid="7334826894904037088">"Тазаланууда"</string>
<string name="recovery_no_command" msgid="4465476568623024327">"Буйрук берилген жок"</string>
<string name="recovery_error" msgid="5748178989622716736">"Ката!"</string>
diff --git a/tools/recovery_l10n/res/values-nb/strings.xml b/tools/recovery_l10n/res/values-nb/strings.xml
index e8cad13..61d1173 100644
--- a/tools/recovery_l10n/res/values-nb/strings.xml
+++ b/tools/recovery_l10n/res/values-nb/strings.xml
@@ -7,7 +7,7 @@
<string name="recovery_error" msgid="5748178989622716736">"Feil!"</string>
<string name="recovery_installing_security" msgid="9184031299717114342">"Installerer sikkerhetsoppdateringen"</string>
<string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Kan ikke laste inn Android-systemet. Dataene dine er muligens skadet. Hvis du fortsetter å se denne meldingen, må du muligens tilbakestille til fabrikkstandard og tømme alle brukerdataene som er lagret på denne enheten."</string>
- <string name="recovery_try_again" msgid="7168248750158873496">"Prøv igjen"</string>
+ <string name="recovery_try_again" msgid="7168248750158873496">"Prøv på nytt"</string>
<string name="recovery_factory_data_reset" msgid="7321351565602894783">"Tilbakestill til fabrikkstandard"</string>
<string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Vil du viske ut alle brukerdataene?\n\n DETTE KAN IKKE ANGRES!"</string>
<string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Avbryt"</string>
diff --git a/tools/recovery_l10n/res/values-te/strings.xml b/tools/recovery_l10n/res/values-te/strings.xml
index 32a9c64..5747075 100644
--- a/tools/recovery_l10n/res/values-te/strings.xml
+++ b/tools/recovery_l10n/res/values-te/strings.xml
@@ -4,11 +4,11 @@
<string name="recovery_installing" msgid="2013591905463558223">"సిస్టమ్ అప్డేట్ను ఇన్స్టాల్ చేస్తోంది"</string>
<string name="recovery_erasing" msgid="7334826894904037088">"డేటాను తొలగిస్తోంది"</string>
<string name="recovery_no_command" msgid="4465476568623024327">"ఆదేశం లేదు"</string>
- <string name="recovery_error" msgid="5748178989622716736">"ఎర్రర్ సంభవించింది!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"భద్రతా అప్డేట్ను ఇన్స్టాల్ చేస్తోంది"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"ఎర్రర్ ఏర్పడింది!"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"సెక్యూరిటీ అప్డేట్ను ఇన్స్టాల్ చేస్తోంది"</string>
<string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Android సిస్టమ్ని లోడ్ చేయడం సాధ్యం కాదు. మీ డేటా పాడై ఉండవచ్చు. మీకు ఈ మెసేజ్ వస్తూనే ఉంటే, మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసి, పరికరంలో నిల్వ అయిన వినియోగదారు డేటా మొత్తాన్ని తొలగించాల్సి రావచ్చు."</string>
<string name="recovery_try_again" msgid="7168248750158873496">"మళ్లీ ప్రయత్నించు"</string>
<string name="recovery_factory_data_reset" msgid="7321351565602894783">"ఫ్యాక్టరీ డేటా రీసెట్"</string>
<string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"వినియోగదారు డేటా మొత్తాన్ని తొలగించాలా?\n\n ఈ చర్యను రద్దు చేయలేరు!"</string>
- <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"రద్దు చేయి"</string>
+ <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"రద్దు చేయండి"</string>
</resources>
diff --git a/update_verifier/Android.bp b/update_verifier/Android.bp
index ff2eff9..220b007 100644
--- a/update_verifier/Android.bp
+++ b/update_verifier/Android.bp
@@ -33,6 +33,25 @@
],
}
+python_library_host {
+ name: "care_map_proto_py",
+ srcs: [
+ "care_map.proto",
+ ],
+ proto: {type: "lite", canonical_path_from_root: false},
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: true,
+ },
+ },
+ visibility: [
+ "//build/make/tools/releasetools:__subpackages__",
+ ],
+}
+
cc_library_static {
name: "libupdate_verifier",
diff --git a/update_verifier/care_map_generator.py b/update_verifier/care_map_generator.py
index c6f2dad..b1396a4 100644
--- a/update_verifier/care_map_generator.py
+++ b/update_verifier/care_map_generator.py
@@ -111,14 +111,14 @@
logging.basicConfig(level=logging.INFO if args.verbose else logging.WARNING,
format=logging_format)
- with open(args.input_care_map, 'r') as input_care_map:
+ with open(args.input_care_map, 'rb') as input_care_map:
content = input_care_map.read()
if args.parse_proto:
result = ParseProtoMessage(content, args.fingerprint_enabled).encode()
else:
care_map_proto = GenerateCareMapProtoFromLegacyFormat(
- content.rstrip().splitlines(), args.fingerprint_enabled)
+ content.decode().rstrip().splitlines(), args.fingerprint_enabled)
result = care_map_proto.SerializeToString()
with open(args.output_file, 'wb') as output: