diff options
28 files changed, 228 insertions, 95 deletions
diff --git a/Android.bp b/Android.bp index bd9570500..4cdeba0f4 100644 --- a/Android.bp +++ b/Android.bp @@ -94,6 +94,8 @@ cc_defaults { shared_libs: [ "android.hardware.boot@1.0", "android.hardware.boot@1.1", + "android.hardware.boot-V1-ndk", + "libboot_control_client", "libbase", "libbootloader_message", "libcrypto", @@ -113,6 +115,8 @@ cc_defaults { "librecovery_utils", "libotautil", "libsnapshot_nobinder", + "libsnapshot_cow", + "liblz4", "update_metadata-protos", ], } @@ -158,6 +162,7 @@ cc_binary { shared_libs: [ "android.hardware.health-V1-ndk", // from librecovery_utils + "android.hardware.boot-V1-ndk", "librecovery_ui", ], diff --git a/bootloader_message/Android.bp b/bootloader_message/Android.bp index 778fdb93e..76226773e 100644 --- a/bootloader_message/Android.bp +++ b/bootloader_message/Android.bp @@ -45,6 +45,7 @@ cc_library { "libbootloader_message_defaults", ], recovery_available: true, + vendor_available: true, host_supported: true, target: { diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp index 1ea56cd4e..0a713eed5 100644 --- a/bootloader_message/bootloader_message.cpp +++ b/bootloader_message/bootloader_message.cpp @@ -209,7 +209,11 @@ bool update_bootloader_message_in_struct(bootloader_message* boot, memset(boot->command, 0, sizeof(boot->command)); memset(boot->recovery, 0, sizeof(boot->recovery)); - strlcpy(boot->command, "boot-recovery", sizeof(boot->command)); + if (android::base::GetBoolProperty("ro.boot.quiescent", false)) { + strlcpy(boot->command, "boot-recovery,quiescent", sizeof(boot->command)); + } else { + strlcpy(boot->command, "boot-recovery", sizeof(boot->command)); + } std::string recovery = "recovery\n"; for (const auto& s : options) { diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h index d58158dd6..8fba101a0 100644 --- a/bootloader_message/include/bootloader_message/bootloader_message.h +++ b/bootloader_message/include/bootloader_message/bootloader_message.h @@ -109,6 +109,7 @@ struct misc_memtag_message { #define MISC_MEMTAG_MODE_MEMTAG_ONCE 0x2 #define MISC_MEMTAG_MODE_MEMTAG_KERNEL 0x4 #define MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE 0x8 +#define MISC_MEMTAG_MODE_MEMTAG_OFF 0x10 #if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) static_assert(sizeof(struct misc_virtual_ab_message) == 64, diff --git a/etc/init.rc b/etc/init.rc index e4afecff6..03df27b01 100644 --- a/etc/init.rc +++ b/etc/init.rc @@ -102,7 +102,7 @@ on property:service.adb.root=1 on fs && property:sys.usb.configfs=1 mount configfs none /config mkdir /config/usb_gadget/g1 0770 shell shell - write /config/usb_gadget/g1/idVendor 0x18D1 + write /config/usb_gadget/g1/idVendor 0x${ro.recovery.usb.vid} mkdir /config/usb_gadget/g1/strings/0x409 0770 write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno} write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer} @@ -114,7 +114,7 @@ on fs && property:sys.usb.configfs=1 on fs && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/f_ffs/aliases adb,fastboot - write /sys/class/android_usb/android0/idVendor 18D1 + write /sys/class/android_usb/android0/idVendor ${ro.recovery.usb.vid} write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer} write /sys/class/android_usb/android0/iProduct ${ro.product.model} write /sys/class/android_usb/android0/iSerial ${ro.serialno} @@ -139,19 +139,19 @@ on property:sys.usb.config=none && property:sys.usb.configfs=0 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=adb && property:sys.usb.configfs=0 - write /sys/class/android_usb/android0/idProduct D001 + write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.adb.pid} write /sys/class/android_usb/android0/functions adb write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=sideload && property:sys.usb.configfs=0 - write /sys/class/android_usb/android0/idProduct D001 + write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.adb.pid} write /sys/class/android_usb/android0/functions adb write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=fastboot && property:sys.usb.configfs=0 - write /sys/class/android_usb/android0/idProduct 4EE0 + write /sys/class/android_usb/android0/idProduct ${ro.recovery.usb.fastboot.pid} write /sys/class/android_usb/android0/functions fastboot write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} @@ -166,21 +166,21 @@ on property:sys.usb.config=none && property:sys.usb.configfs=1 setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=sideload && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0xD001 + write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.adb.pid} write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb" symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1 write /config/usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=adb && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0xD001 + write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.adb.pid} write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb" symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1 write /config/usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config} on property:sys.usb.config=fastboot && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1 - write /config/usb_gadget/g1/idProduct 0x4EE0 + write /config/usb_gadget/g1/idProduct 0x${ro.recovery.usb.fastboot.pid} write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "fastboot" symlink /config/usb_gadget/g1/functions/ffs.fastboot /config/usb_gadget/g1/configs/b.1/f1 write /config/usb_gadget/g1/UDC ${sys.usb.controller} diff --git a/install/install.cpp b/install/install.cpp index 83f3cad6b..044856b6b 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -551,7 +551,9 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, } else { LOG(FATAL) << "Invalid status code " << status; } - PerformPowerwashIfRequired(zip, device); + if (package_is_ab) { + PerformPowerwashIfRequired(zip, device); + } return INSTALL_SUCCESS; } diff --git a/install/wipe_data.cpp b/install/wipe_data.cpp index 024c1e1d5..c65e6f488 100644 --- a/install/wipe_data.cpp +++ b/install/wipe_data.cpp @@ -25,6 +25,7 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> +#include "bootloader_message/bootloader_message.h" #include "install/snapshot_utils.h" #include "otautil/dirutil.h" #include "recovery_ui/ui.h" @@ -100,6 +101,12 @@ bool WipeData(Device* device) { success &= EraseVolume(METADATA_ROOT, ui); } } + ui->Print("Resetting memtag message...\n"); + std::string err; + if (!WriteMiscMemtagMessage({}, &err)) { + ui->Print("Failed to reset memtag message: %s\n", err.c_str()); + success = false; + } if (success) { success &= device->PostWipeData(); } diff --git a/minadbd/OWNERS b/minadbd/OWNERS new file mode 100644 index 000000000..8ee79dd4f --- /dev/null +++ b/minadbd/OWNERS @@ -0,0 +1,2 @@ +enh@google.com +shaju@google.com diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp index 0abe8675b..16bcb5edb 100644 --- a/minadbd/minadbd_services.cpp +++ b/minadbd/minadbd_services.cpp @@ -305,7 +305,7 @@ static void WipeDeviceService(unique_fd fd, const std::string& args) { } } -asocket* daemon_service_to_socket(std::string_view) { +asocket* daemon_service_to_socket(std::string_view, atransport*) { return nullptr; } diff --git a/minui/graphics.cpp b/minui/graphics.cpp index b24c2b114..41a366112 100644 --- a/minui/graphics.cpp +++ b/minui/graphics.cpp @@ -502,3 +502,7 @@ void gr_fb_blank(bool blank, int 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 5408c93e9..ff063ae23 100644 --- a/minui/graphics.h +++ b/minui/graphics.h @@ -40,8 +40,11 @@ class MinuiBackend { // 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 index c55702276..6c3a5bdee 100644 --- a/minui/graphics_drm.cpp +++ b/minui/graphics_drm.cpp @@ -200,6 +200,10 @@ void MinuiBackendDrm::Blank(bool blank, DrmConnector 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, drmModeConnector* connector) { // Find the encoder. If we already have one, just use it. diff --git a/minui/graphics_drm.h b/minui/graphics_drm.h index fe3beaff9..a8c9886e5 100644 --- a/minui/graphics_drm.h +++ b/minui/graphics_drm.h @@ -60,6 +60,7 @@ class MinuiBackendDrm : public MinuiBackend { 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); diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp index 1cb0c0ab8..2711af74c 100644 --- a/minui/graphics_fbdev.cpp +++ b/minui/graphics_fbdev.cpp @@ -44,7 +44,16 @@ void MinuiBackendFbdev::Blank(bool blank) { } void MinuiBackendFbdev::Blank(bool blank, DrmConnector index) { - fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index); + if (index == DRM_MAIN) { + MinuiBackendFbdev::Blank(blank); + } else { + fprintf(stderr, "Unsupported multiple connectors, blank = %d, index = %d\n", blank, index); + } +} + +bool MinuiBackendFbdev::HasMultipleConnectors() { + fprintf(stderr, "Unsupported multiple connectors\n"); + return false; } void MinuiBackendFbdev::SetDisplayedFramebuffer(size_t n) { diff --git a/minui/graphics_fbdev.h b/minui/graphics_fbdev.h index 7e193c4ff..c772428dc 100644 --- a/minui/graphics_fbdev.h +++ b/minui/graphics_fbdev.h @@ -57,6 +57,7 @@ class MinuiBackendFbdev : public MinuiBackend { 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 index f9be82f52..2353ed3b9 100644 --- a/minui/include/minui/minui.h +++ b/minui/include/minui/minui.h @@ -129,6 +129,7 @@ int gr_fb_height(); 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(); diff --git a/otautil/verifier.cpp b/otautil/verifier.cpp index 8a65566ec..83ad7082b 100644 --- a/otautil/verifier.cpp +++ b/otautil/verifier.cpp @@ -309,13 +309,15 @@ int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys } static std::vector<Certificate> IterateZipEntriesAndSearchForKeys(const ZipArchiveHandle& handle) { - void* cookie; + void* cookie{}; + int32_t iter_status = StartIteration(handle, &cookie, "", "x509.pem"); if (iter_status != 0) { LOG(ERROR) << "Failed to iterate over entries in the certificate zipfile: " << ErrorCodeString(iter_status); return {}; } + std::unique_ptr<void, decltype(&EndIteration)> cookie_guard(cookie, &EndIteration); std::vector<Certificate> result; diff --git a/recovery-persist.cpp b/recovery-persist.cpp index ad101ede2..55699b24e 100644 --- a/recovery-persist.cpp +++ b/recovery-persist.cpp @@ -77,6 +77,10 @@ static void copy_file(const char* source, const char* destination) { } } +static bool file_exists(const char* filename) { + return access(filename, R_OK) == 0; +} + static bool rotated = false; ssize_t logsave( @@ -141,7 +145,7 @@ int main(int argc, char **argv) { if (has_cache) { // Collects and reports the non-a/b update metrics from last_install; and removes the file // to avoid duplicate report. - if (access(LAST_INSTALL_FILE_IN_CACHE, F_OK) && unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) { + if (file_exists(LAST_INSTALL_FILE_IN_CACHE) && unlink(LAST_INSTALL_FILE_IN_CACHE) == -1) { PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE_IN_CACHE; } @@ -152,9 +156,9 @@ int main(int argc, char **argv) { } } - /* Is there something in pmsg? */ - if (access(LAST_PMSG_FILE, R_OK)) { - return 0; + /* Is there something in pmsg? If not, no need to proceed. */ + if (!file_exists(LAST_PMSG_FILE)) { + return 0; } // Take last pmsg file contents and send it off to the logsave @@ -164,18 +168,18 @@ int main(int argc, char **argv) { // For those device without /cache, the last_install file has been copied to // /data/misc/recovery from pmsg. Looks for the sideload history only. if (!has_cache) { - if (access(LAST_INSTALL_FILE, F_OK) && unlink(LAST_INSTALL_FILE) == -1) { + if (file_exists(LAST_INSTALL_FILE) && unlink(LAST_INSTALL_FILE) == -1) { PLOG(ERROR) << "Failed to unlink " << LAST_INSTALL_FILE; } } /* Is there a last console log too? */ if (rotated) { - if (!access(LAST_CONSOLE_FILE, R_OK)) { - copy_file(LAST_CONSOLE_FILE, LAST_KMSG_FILE); - } else if (!access(ALT_LAST_CONSOLE_FILE, R_OK)) { - copy_file(ALT_LAST_CONSOLE_FILE, LAST_KMSG_FILE); - } + if (file_exists(LAST_CONSOLE_FILE)) { + copy_file(LAST_CONSOLE_FILE, LAST_KMSG_FILE); + } else if (file_exists(ALT_LAST_CONSOLE_FILE)) { + copy_file(ALT_LAST_CONSOLE_FILE, LAST_KMSG_FILE); + } } return 0; diff --git a/recovery_ui/include/recovery_ui/screen_ui.h b/recovery_ui/include/recovery_ui/screen_ui.h index 92b3c2546..99ad53420 100644 --- a/recovery_ui/include/recovery_ui/screen_ui.h +++ b/recovery_ui/include/recovery_ui/screen_ui.h @@ -245,6 +245,9 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface { const std::vector<std::string>& backup_headers, const std::vector<std::string>& backup_items, const std::function<int(int, bool)>& key_handler) override; + // For Lid switch handle + int SetSwCallback(int code, int value) override; + protected: static constexpr int kMenuIndent = 4; @@ -404,6 +407,9 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface { std::mutex updateMutex; + // Switch the display to active one after graphics is ready + bool is_graphics_available; + private: void SetLocale(const std::string&); diff --git a/recovery_ui/include/recovery_ui/stub_ui.h b/recovery_ui/include/recovery_ui/stub_ui.h index 511b1314a..49689ba36 100644 --- a/recovery_ui/include/recovery_ui/stub_ui.h +++ b/recovery_ui/include/recovery_ui/stub_ui.h @@ -80,6 +80,10 @@ class StubRecoveryUI : public RecoveryUI { } void SetTitle(const std::vector<std::string>& /* lines */) override {} + + int SetSwCallback(int /* code */, int /* value */) override { + return 0; + } }; #endif // RECOVERY_STUB_UI_H diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h index 512732f90..c3e3ee26c 100644 --- a/recovery_ui/include/recovery_ui/ui.h +++ b/recovery_ui/include/recovery_ui/ui.h @@ -231,6 +231,8 @@ class RecoveryUI { bool InitScreensaver(); void SetScreensaverState(ScreensaverState state); + virtual int SetSwCallback(int code, int value) = 0; + // Key event input queue std::mutex key_queue_mutex; std::condition_variable key_queue_cond; diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp index b2c828f34..ee3cbb134 100644 --- a/recovery_ui/screen_ui.cpp +++ b/recovery_ui/screen_ui.cpp @@ -48,6 +48,11 @@ #include "recovery_ui/device.h" #include "recovery_ui/ui.h" +enum DirectRenderManager { + DRM_INNER, + DRM_OUTER, +}; + // Return the current time as a double (including fractions of a second). static double now() { struct timeval tv; @@ -334,7 +339,8 @@ ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu) stage(-1), max_stage(-1), locale_(""), - rtl_locale_(false) {} + rtl_locale_(false), + is_graphics_available(false) {} ScreenRecoveryUI::~ScreenRecoveryUI() { progress_thread_stopped_ = true; @@ -906,6 +912,7 @@ bool ScreenRecoveryUI::Init(const std::string& locale) { if (!InitGraphics()) { return false; } + is_graphics_available = true; if (!InitTextParams()) { return false; @@ -950,6 +957,9 @@ bool ScreenRecoveryUI::Init(const std::string& locale) { // Keep the progress bar updated, even when the process is otherwise busy. progress_thread_ = std::thread(&ScreenRecoveryUI::ProgressThreadLoop, this); + // set the callback for hall sensor event + (void)ev_sync_sw_state([this](auto&& a, auto&& b) { return this->SetSwCallback(a, b);}); + return true; } @@ -1367,3 +1377,45 @@ void ScreenRecoveryUI::SetLocale(const std::string& new_locale) { } } } + +int ScreenRecoveryUI::SetSwCallback(int code, int value) { + if (!is_graphics_available) { return -1; } + if (code > SW_MAX) { return -1; } + if (code != SW_LID) { return 0; } + + /* detect dual display */ + if (!gr_has_multiple_connectors()) { return -1; } + + /* turn off all screen */ + gr_fb_blank(true, DirectRenderManager::DRM_INNER); + gr_fb_blank(true, DirectRenderManager::DRM_OUTER); + gr_color(0, 0, 0, 255); + gr_clear(); + + /* turn on the screen */ + gr_fb_blank(false, value); + gr_flip(); + + /* set the retation */ + std::string rotation_str; + if (value == DirectRenderManager::DRM_OUTER) { + rotation_str = + android::base::GetProperty("ro.minui.second_rotation", "ROTATION_NONE"); + } else { + rotation_str = + android::base::GetProperty("ro.minui.default_rotation", "ROTATION_NONE"); + } + + if (rotation_str == "ROTATION_RIGHT") { + gr_rotate(GRRotation::RIGHT); + } else if (rotation_str == "ROTATION_DOWN") { + gr_rotate(GRRotation::DOWN); + } else if (rotation_str == "ROTATION_LEFT") { + gr_rotate(GRRotation::LEFT); + } else { // "ROTATION_NONE" or unknown string + gr_rotate(GRRotation::NONE); + } + Redraw(); + + return 0; +} diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp index 6e67b1d4e..eb87f5261 100644 --- a/recovery_ui/ui.cpp +++ b/recovery_ui/ui.cpp @@ -341,6 +341,11 @@ int RecoveryUI::OnInputEvent(int fd, uint32_t epevents) { ProcessKey(ev.code, ev.value); } + // For Lid switch handle + if (ev.type == EV_SW) { + SetSwCallback(ev.code, ev.value); + } + return 0; } diff --git a/tools/image_generator/ImageGenerator.java b/tools/image_generator/ImageGenerator.java index 6c5ea4b5f..00264b1d8 100644 --- a/tools/image_generator/ImageGenerator.java +++ b/tools/image_generator/ImageGenerator.java @@ -16,6 +16,8 @@ package com.android.recovery.tools; +import static java.util.Map.entry; + import com.ibm.icu.text.BreakIterator; import org.apache.commons.cli.CommandLine; @@ -111,49 +113,43 @@ public class ImageGenerator { // https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry private static final String DEFAULT_FONT_NAME = "Roboto-Regular"; private static final Map<String, String> LANGUAGE_TO_FONT_MAP = - new TreeMap<String, String>() { - { - put("am", "NotoSansEthiopic-VF"); - put("ar", "NotoNaskhArabicUI-Regular"); - put("as", "NotoSansBengaliUI-VF"); - put("bn", "NotoSansBengaliUI-VF"); - put("fa", "NotoNaskhArabicUI-Regular"); - put("gu", "NotoSansGujaratiUI-Regular"); - put("hi", "NotoSansDevanagariUI-VF"); - put("hy", "NotoSansArmenian-VF"); - put("iw", "NotoSansHebrew-Regular"); - put("ja", "NotoSansCJK-Regular"); - put("ka", "NotoSansGeorgian-VF"); - put("ko", "NotoSansCJK-Regular"); - put("km", "NotoSansKhmerUI-Regular"); - put("kn", "NotoSansKannadaUI-VF"); - put("lo", "NotoSansLaoUI-Regular"); - put("ml", "NotoSansMalayalamUI-VF"); - put("mr", "NotoSansDevanagariUI-VF"); - put("my", "NotoSansMyanmarUI-Regular"); - put("ne", "NotoSansDevanagariUI-VF"); - put("or", "NotoSansOriya-Regular"); - put("pa", "NotoSansGurmukhiUI-VF"); - put("si", "NotoSansSinhalaUI-VF"); - put("ta", "NotoSansTamilUI-VF"); - put("te", "NotoSansTeluguUI-VF"); - put("th", "NotoSansThaiUI-Regular"); - put("ur", "NotoNaskhArabicUI-Regular"); - put("zh", "NotoSansCJK-Regular"); - } - }; + Map.ofEntries( + entry("am", "NotoSansEthiopic-VF"), + entry("ar", "NotoNaskhArabicUI-Regular"), + entry("as", "NotoSansBengaliUI-VF"), + entry("bn", "NotoSansBengaliUI-VF"), + entry("fa", "NotoNaskhArabicUI-Regular"), + entry("gu", "NotoSansGujaratiUI-Regular"), + entry("hi", "NotoSansDevanagariUI-VF"), + entry("hy", "NotoSansArmenian-VF"), + entry("iw", "NotoSansHebrew-Regular"), + entry("ja", "NotoSansCJK-Regular"), + entry("ka", "NotoSansGeorgian-VF"), + entry("ko", "NotoSansCJK-Regular"), + entry("km", "NotoSansKhmerUI-Regular"), + entry("kn", "NotoSansKannadaUI-VF"), + entry("lo", "NotoSansLaoUI-Regular"), + entry("ml", "NotoSansMalayalamUI-VF"), + entry("mr", "NotoSansDevanagariUI-VF"), + entry("my", "NotoSansMyanmarUI-Regular"), + entry("ne", "NotoSansDevanagariUI-VF"), + entry("or", "NotoSansOriya-Regular"), + entry("pa", "NotoSansGurmukhiUI-VF"), + entry("si", "NotoSansSinhalaUI-VF"), + entry("ta", "NotoSansTamilUI-VF"), + entry("te", "NotoSansTeluguUI-VF"), + entry("th", "NotoSansThaiUI-Regular"), + entry("ur", "NotoNaskhArabicUI-Regular"), + entry("zh", "NotoSansCJK-Regular")); // Languages that write from right to left. private static final Set<String> RTL_LANGUAGE = - new HashSet<String>() { - { - add("ar"); // Arabic - add("fa"); // Persian - add("he"); // Hebrew - add("iw"); // Hebrew - add("ur"); // Urdu - } - }; + Set.of( + "ar", // Arabic + "fa", // Persian + "he", // Hebrew + "iw", // Hebrew + "ur"); // Urdu /** Exception to indicate the failure to find the translated text strings. */ public static class LocalizedStringNotFoundException extends Exception { diff --git a/tools/recovery_l10n/res/values-en-rCA/strings.xml b/tools/recovery_l10n/res/values-en-rCA/strings.xml index 69be4bb04..6451e5b6c 100644 --- a/tools/recovery_l10n/res/values-en-rCA/strings.xml +++ b/tools/recovery_l10n/res/values-en-rCA/strings.xml @@ -9,6 +9,6 @@ <string name="recovery_wipe_data_menu_header" msgid="550255032058254478">"Cannot load Android system. Your data may be corrupt. If you continue to get this message, you may need to perform a factory data reset and erase all user data stored on this device."</string> <string name="recovery_try_again" msgid="7168248750158873496">"Try again"</string> <string name="recovery_factory_data_reset" msgid="7321351565602894783">"Factory data reset"</string> - <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Wipe all user data?\n\n THIS CAN NOT BE UNDONE!"</string> + <string name="recovery_wipe_data_confirmation" msgid="5439823343348043954">"Wipe all user data?\n\n THIS CANNOT BE UNDONE!"</string> <string name="recovery_cancel_wipe_data" msgid="66987687653647384">"Cancel"</string> </resources> diff --git a/update_verifier/Android.bp b/update_verifier/Android.bp index 220b007f5..26ff5305c 100644 --- a/update_verifier/Android.bp +++ b/update_verifier/Android.bp @@ -39,14 +39,6 @@ python_library_host { "care_map.proto", ], proto: {type: "lite", canonical_path_from_root: false}, - version: { - py2: { - enabled: true, - }, - py3: { - enabled: true, - }, - }, visibility: [ "//build/make/tools/releasetools:__subpackages__", ], @@ -73,8 +65,13 @@ cc_library_static { "libvold_binder", ], + whole_static_libs: [ + "libsnapshot_snapuserd", + ], + shared_libs: [ "android.hardware.boot@1.0", + "libboot_control_client", "libbase", "libcutils", "libbinder", @@ -114,6 +111,7 @@ cc_binary { "libprotobuf-cpp-lite", "libbinder", "libutils", + "libboot_control_client", ], init_rc: [ @@ -139,12 +137,7 @@ python_binary_host { }, version: { - py2: { - enabled: false, - embedded_launcher: false, - }, py3: { - enabled: true, embedded_launcher: true, }, }, diff --git a/update_verifier/include/update_verifier/update_verifier.h b/update_verifier/include/update_verifier/update_verifier.h index 4c64b1ea1..0cccc9075 100644 --- a/update_verifier/include/update_verifier/update_verifier.h +++ b/update_verifier/include/update_verifier/update_verifier.h @@ -21,6 +21,7 @@ #include <string> #include <vector> +#include <snapuserd/snapuserd_client.h> #include "otautil/rangeset.h" // The update verifier performs verification upon the first boot to a new slot on A/B devices. @@ -68,4 +69,8 @@ class UpdateVerifier { // The function to read the device property; default value: android::base::GetProperty() std::function<std::string(const std::string&)> property_reader_; + + // Check if snapuserd daemon has already completed the update verification + // Applicable only for VABC with userspace snapshots + bool CheckVerificationStatus(); }; diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp index a042f9008..ea47a65ca 100644 --- a/update_verifier/update_verifier.cpp +++ b/update_verifier/update_verifier.cpp @@ -52,13 +52,14 @@ #include <future> #include <thread> +#include <BootControlClient.h> +#include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/properties.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> -#include <android/hardware/boot/1.0/IBootControl.h> #include <android/os/IVold.h> #include <binder/BinderService.h> #include <binder/Status.h> @@ -66,11 +67,6 @@ #include "care_map.pb.h" -using android::sp; -using android::hardware::boot::V1_0::IBootControl; -using android::hardware::boot::V1_0::BoolResult; -using android::hardware::boot::V1_0::CommandResult; - // TODO(xunchang) remove the prefix and use a default path instead. constexpr const char* kDefaultCareMapPrefix = "/data/ota_package/care_map"; @@ -91,7 +87,7 @@ UpdateVerifier::UpdateVerifier() // partition's integrity. std::map<std::string, std::string> UpdateVerifier::FindDmPartitions() { static constexpr auto DM_PATH_PREFIX = "/sys/block/"; - dirent** namelist; + dirent** namelist = nullptr; int n = scandir(DM_PATH_PREFIX, &namelist, dm_name_filter, alphasort); if (n == -1) { PLOG(ERROR) << "Failed to scan dir " << DM_PATH_PREFIX; @@ -188,7 +184,28 @@ bool UpdateVerifier::ReadBlocks(const std::string partition_name, return ret; } +bool UpdateVerifier::CheckVerificationStatus() { + auto client = + android::snapshot::SnapuserdClient::Connect(android::snapshot::kSnapuserdSocket, 5s); + if (!client) { + LOG(ERROR) << "Unable to connect to snapuserd"; + return false; + } + + return client->QueryUpdateVerification(); +} + bool UpdateVerifier::VerifyPartitions() { + const bool userspace_snapshots = + android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false); + + if (userspace_snapshots && CheckVerificationStatus()) { + LOG(INFO) << "Partitions verified by snapuserd daemon"; + return true; + } + + LOG(INFO) << "Partitions not verified by snapuserd daemon"; + auto dm_block_devices = FindDmPartitions(); if (dm_block_devices.empty()) { LOG(ERROR) << "No dm-enabled block device is found."; @@ -307,18 +324,21 @@ int update_verifier(int argc, char** argv) { LOG(INFO) << "Started with arg " << i << ": " << argv[i]; } - sp<IBootControl> module = IBootControl::getService(); + const auto module = android::hal::BootControlClient::WaitForService(); if (module == nullptr) { LOG(ERROR) << "Error getting bootctrl module."; return reboot_device(); } - uint32_t current_slot = module->getCurrentSlot(); - BoolResult is_successful = module->isSlotMarkedSuccessful(current_slot); - LOG(INFO) << "Booting slot " << current_slot << ": isSlotMarkedSuccessful=" - << static_cast<int32_t>(is_successful); - - if (is_successful == BoolResult::FALSE) { + uint32_t current_slot = module->GetCurrentSlot(); + const auto is_successful = module->IsSlotMarkedSuccessful(current_slot); + if (!is_successful.has_value()) { + LOG(INFO) << "Booting slot " << current_slot << " failed"; + } else { + LOG(INFO) << "Booting slot " << current_slot + << ": isSlotMarkedSuccessful=" << is_successful.value(); + } + if (is_successful.has_value() && !is_successful.value()) { // The current slot has not booted successfully. bool skip_verification = false; @@ -364,8 +384,7 @@ int update_verifier(int argc, char** argv) { } if (!supports_checkpoint) { - CommandResult cr; - module->markBootSuccessful([&cr](CommandResult result) { cr = result; }); + const auto cr = module->MarkBootSuccessful(); if (!cr.success) { LOG(ERROR) << "Error marking booted successfully: " << cr.errMsg; return reboot_device(); |