diff options
| author | Julian Veit <Claymore1298@gmail.com> | 2024-06-13 08:17:58 +0200 |
|---|---|---|
| committer | Julian Veit <Claymore1298@gmail.com> | 2024-06-13 08:17:58 +0200 |
| commit | 090e278f122777078f470fe87e11ad1212db90ef (patch) | |
| tree | 5473ec2fd9a90bdf60757ffcb5ade48b088cb4ed | |
| parent | 6d486b1f5660f2a9fc3f4559c03d9d4989af2c99 (diff) | |
| parent | 8904d2a254c5263caded20af8fde209f8b37f22d (diff) | |
Merge branch 'lineage-20.0' of https://github.com/LineageOS/android_bootable_recovery into HEADHEADt13.0
Change-Id: Ic0aae25ab32e81f4ebf802693f8c9a2fdc283beb
| -rw-r--r-- | install/install.cpp | 21 | ||||
| -rw-r--r-- | minui/graphics.cpp | 21 | ||||
| -rw-r--r-- | minui/include/minui/minui.h | 4 | ||||
| -rw-r--r-- | recovery.cpp | 8 | ||||
| -rw-r--r-- | recovery_ui/Android.bp | 6 | ||||
| -rw-r--r-- | recovery_ui/include/recovery_ui/screen_ui.h | 8 | ||||
| -rw-r--r-- | recovery_ui/include/recovery_ui/ui.h | 10 | ||||
| -rw-r--r-- | recovery_ui/screen_ui.cpp | 149 | ||||
| -rw-r--r-- | recovery_ui/ui.cpp | 1 | ||||
| -rw-r--r-- | tools/recovery_l10n/res/values-te/strings.xml | 2 | ||||
| -rw-r--r-- | update_verifier/Android.bp | 4 | ||||
| -rw-r--r-- | update_verifier/include/update_verifier/update_verifier.h | 5 | ||||
| -rw-r--r-- | update_verifier/update_verifier.cpp | 22 |
13 files changed, 259 insertions, 2 deletions
diff --git a/install/install.cpp b/install/install.cpp index dab919b2..ed5200be 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -46,6 +46,7 @@ #include <android-base/strings.h> #include <android-base/unique_fd.h> +#include "bootloader_message/bootloader_message.h" #include "install/snapshot_utils.h" #include "install/spl_check.h" #include "install/wipe_data.h" @@ -62,6 +63,7 @@ using namespace std::chrono_literals; +bool ask_to_ab_reboot(Device* device); bool ask_to_continue_unverified(Device* device); bool ask_to_continue_downgrade(Device* device); @@ -382,6 +384,21 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, LOG(WARNING) << "This is SPL downgrade"; } + const auto reboot_to_recovery = [] { + if (std::string err; !clear_bootloader_message(&err)) { + LOG(ERROR) << "Failed to clear BCB message: " << err; + } + Reboot("recovery"); + }; + + static bool ab_package_installed = false; + if (ab_package_installed) { + if (ask_to_ab_reboot(device)) { + reboot_to_recovery(); + } + return INSTALL_ERROR; + } + if (package_is_ab) { CHECK(package->GetType() == PackageType::kFile); } @@ -567,7 +584,11 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, LOG(FATAL) << "Invalid status code " << status; } if (package_is_ab) { + ab_package_installed = true; PerformPowerwashIfRequired(zip, device); + if (!ui->IsSideloadAutoReboot() && ask_to_ab_reboot(device)) { + reboot_to_recovery(); + } } return INSTALL_SUCCESS; diff --git a/minui/graphics.cpp b/minui/graphics.cpp index cd01768a..67de5cc0 100644 --- a/minui/graphics.cpp +++ b/minui/graphics.cpp @@ -41,6 +41,7 @@ static uint32_t gr_current = ~0; // gr_draw is owned by backends. static GRSurface* gr_draw = nullptr; static GRRotation rotation = GRRotation::NONE; +static GRRotation touch_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. @@ -474,6 +475,18 @@ int gr_init(std::initializer_list<GraphicsBackend> backends) { gr_rotate(GRRotation::NONE); } + std::string touch_rotation_str = + android::base::GetProperty("ro.minui.default_touch_rotation", "ROTATION_NONE"); + if (touch_rotation_str == "ROTATION_RIGHT") { + gr_rotate_touch(GRRotation::RIGHT); + } else if (touch_rotation_str == "ROTATION_DOWN") { + gr_rotate_touch(GRRotation::DOWN); + } else if (touch_rotation_str == "ROTATION_LEFT") { + gr_rotate_touch(GRRotation::LEFT); + } else { // "ROTATION_NONE" or unknown string + gr_rotate_touch(GRRotation::NONE); + } + if (gr_draw->pixel_bytes != 4) { printf("gr_init: Only 4-byte pixel formats supported\n"); } @@ -519,6 +532,10 @@ int gr_overscan_offset_y() { return overscan_offset_y; } +GRRotation gr_touch_rotation() { + return touch_rotation; +} + void gr_fb_blank(bool blank) { gr_backend->Blank(blank); } @@ -531,6 +548,10 @@ void gr_rotate(GRRotation rot) { rotation = rot; } +void gr_rotate_touch(GRRotation rot) { + touch_rotation = rot; +} + bool gr_has_multiple_connectors() { return gr_backend->HasMultipleConnectors(); } diff --git a/minui/include/minui/minui.h b/minui/include/minui/minui.h index 76d6cd78..19022bbd 100644 --- a/minui/include/minui/minui.h +++ b/minui/include/minui/minui.h @@ -129,6 +129,7 @@ int gr_fb_width_real(); int gr_fb_height_real(); int gr_overscan_offset_x(); int gr_overscan_offset_y(); +GRRotation gr_touch_rotation(); void gr_flip(); void gr_fb_blank(bool blank); @@ -158,6 +159,9 @@ unsigned int gr_get_height(const GRSurface* surface); // Sets rotation, flips gr_fb_width/height if 90 degree rotation difference void gr_rotate(GRRotation rotation); +// Sets touch rotation +void gr_rotate_touch(GRRotation rotation); + // Returns the current PixelFormat being used. PixelFormat gr_pixel_format(); diff --git a/recovery.cpp b/recovery.cpp index 85688f9b..2b6edfd0 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -180,6 +180,12 @@ static bool yes_no(Device* device, const char* question1, const char* question2) return (chosen_item == 1); } +bool ask_to_ab_reboot(Device* device) { + device->GetUI()->SetProgressType(RecoveryUI::EMPTY); + return yes_no(device, "To install additional packages, you need to reboot recovery first", + "Do you want to reboot to recovery now?"); +} + bool ask_to_continue_unverified(Device* device) { if (get_build_type() == "user") { return false; @@ -864,6 +870,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri std::vector<std::string> title_lines = { "AICP Version " + android::base::GetProperty("ro.romstats.version", "(unknown)"), }; + title_lines.push_back("Product name - " + android::base::GetProperty("ro.product.device", "")); if (android::base::GetBoolProperty("ro.build.ab_update", false)) { std::string slot = android::base::GetProperty("ro.boot.slot_suffix", ""); if (android::base::StartsWith(slot, "_")) slot.erase(0, 1); @@ -990,6 +997,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri if (!sideload_auto_reboot) { ui->ShowText(true); } + ui->SetSideloadAutoReboot(sideload_auto_reboot); status = ApplyFromAdb(device, false /* rescue_mode */, &next_action); ui->Print("\nInstall from ADB complete (status: %d).\n", status); if (sideload_auto_reboot) { diff --git a/recovery_ui/Android.bp b/recovery_ui/Android.bp index 454947b0..8fef5b22 100644 --- a/recovery_ui/Android.bp +++ b/recovery_ui/Android.bp @@ -43,13 +43,19 @@ cc_library { export_include_dirs: ["include"], static_libs: [ + "libbatterymonitor", + "libhealthloop", "libminui", "libotautil", ], shared_libs: [ + "android.hardware.health-V1-ndk", "libbase", + "libcutils", + "libhidlbase", "libpng", + "libutils", "libz", "libvolume_manager", ], diff --git a/recovery_ui/include/recovery_ui/screen_ui.h b/recovery_ui/include/recovery_ui/screen_ui.h index 0e7420f6..1a48179a 100644 --- a/recovery_ui/include/recovery_ui/screen_ui.h +++ b/recovery_ui/include/recovery_ui/screen_ui.h @@ -32,6 +32,7 @@ class GRSurface; enum class UIElement { + BATTERY_LOW, HEADER, MENU, MENU_SEL_BG, @@ -392,6 +393,7 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface { virtual std::vector<std::string> GetMenuHelpMessage() const; virtual void draw_background_locked(); + virtual void draw_battery_capacity_locked(); virtual void draw_foreground_locked(); virtual void draw_screen_locked(); virtual void draw_menu_and_text_buffer_locked(const std::vector<std::string>& help_message); @@ -401,6 +403,7 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface { const GRSurface* GetCurrentFrame() const; const GRSurface* GetCurrentText() const; + void BattMonitorThreadLoop(); void ProgressThreadLoop(); virtual void ShowFile(FILE*); @@ -523,6 +526,11 @@ class ScreenRecoveryUI : public RecoveryUI, public DrawInterface { std::mutex updateMutex; + std::thread batt_monitor_thread_; + std::atomic<bool> batt_monitor_thread_stopped_{ false }; + int32_t batt_capacity_; + bool charging_; + // Switch the display to active one after graphics is ready bool is_graphics_available; diff --git a/recovery_ui/include/recovery_ui/ui.h b/recovery_ui/include/recovery_ui/ui.h index 4703065f..d263cf71 100644 --- a/recovery_ui/include/recovery_ui/ui.h +++ b/recovery_ui/include/recovery_ui/ui.h @@ -297,6 +297,14 @@ class RecoveryUI { EnqueueKey(KEY_REFRESH); } + bool IsSideloadAutoReboot() const { + return sideload_auto_reboot_; + } + + void SetSideloadAutoReboot(bool sar) { + sideload_auto_reboot_ = sar; + } + protected: void EnqueueKey(int key_code); void EnqueueTouch(const Point& pos); @@ -314,6 +322,8 @@ class RecoveryUI { bool fastbootd_logo_enabled_; + bool sideload_auto_reboot_; + private: enum class ScreensaverState { DISABLED, diff --git a/recovery_ui/screen_ui.cpp b/recovery_ui/screen_ui.cpp index f7a6ee1f..5d713d6f 100644 --- a/recovery_ui/screen_ui.cpp +++ b/recovery_ui/screen_ui.cpp @@ -37,12 +37,17 @@ #include <unordered_map> #include <vector> +#include <aidl/android/hardware/health/BatteryStatus.h> + #include <android-base/chrono_utils.h> #include <android-base/logging.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <health/utils.h> +#include <healthd/BatteryMonitor.h> + #include "minui/minui.h" #include "otautil/paths.h" #include "recovery_ui/device.h" @@ -406,9 +411,16 @@ ScreenRecoveryUI::ScreenRecoveryUI() max_stage(-1), locale_(""), rtl_locale_(false), + batt_capacity_(0), + charging_(false), is_graphics_available(false) {} ScreenRecoveryUI::~ScreenRecoveryUI() { + batt_monitor_thread_stopped_ = true; + if (batt_monitor_thread_.joinable()) { + batt_monitor_thread_.join(); + } + progress_thread_stopped_ = true; if (progress_thread_.joinable()) { progress_thread_.join(); @@ -570,6 +582,12 @@ void ScreenRecoveryUI::draw_foreground_locked() { fastboot light: #FDD835 */ void ScreenRecoveryUI::SetColor(UIElement e) const { switch (e) { + case UIElement::BATTERY_LOW: + if (fastbootd_logo_enabled_) + gr_color(0xfd, 0x35, 0x35, 255); + else + gr_color(0xc7, 0x15, 0x85, 255); + break; case UIElement::INFO: if (fastbootd_logo_enabled_) gr_color(0xfd, 0xd8, 0x35, 255); @@ -807,6 +825,7 @@ void ScreenRecoveryUI::draw_screen_locked() { gr_clear(); draw_menu_and_text_buffer_locked(GetMenuHelpMessage()); + draw_battery_capacity_locked(); } // Draws the menu and text buffer on the screen. Should only be called with updateMutex locked. @@ -860,6 +879,60 @@ void ScreenRecoveryUI::draw_menu_and_text_buffer_locked( } } +// Draws the battery capacity on the screen. Should only be called with updateMutex locked. +void ScreenRecoveryUI::draw_battery_capacity_locked() { + int x; + int y = margin_height_ + gr_get_height(lineage_logo_.get()); + int icon_x, icon_y, icon_h, icon_w; + + // Battery status + std::string batt_capacity = std::to_string(batt_capacity_) + '%'; + + if (charging_) + batt_capacity.push_back('+'); + else if (batt_capacity.back() == '+') + batt_capacity.pop_back(); + + if (menu_) { + // Battery icon + x = (ScreenWidth() - margin_width_ * 2 - kMenuIndent) - char_width_; + + SetColor(UIElement::INFO); + + // Top + icon_x = x + char_width_ / 3; + icon_y = y; + icon_w = char_width_ / 3; + icon_h = char_height_ / 12; + gr_fill(icon_x, icon_y, icon_x + icon_w, icon_y + icon_h); + + // Main rect + icon_x = x; + icon_y = y + icon_h; + icon_w = char_width_; + icon_h = char_height_ - (char_height_ / 12); + gr_fill(icon_x, icon_y, icon_x + icon_w, icon_y + icon_h); + + // Capacity + if (batt_capacity_ <= 15) SetColor(UIElement::BATTERY_LOW); + icon_x = x + char_width_ / 6; + icon_y = y + char_height_ / 12; + icon_w = char_width_ - (2 * char_width_ / 6); + icon_h = char_height_ - (3 * char_height_ / 12); + int cap_h = icon_h * batt_capacity_ / 100; + gr_fill(icon_x, icon_y + icon_h - cap_h, icon_x + icon_w, icon_y + icon_h); + gr_color(0, 0, 0, 255); + gr_fill(icon_x, icon_y, icon_x + icon_w, icon_y + icon_h - cap_h); + + x -= char_width_; // Separator + + // Battery text + SetColor(UIElement::INFO); + x -= batt_capacity.size() * char_width_; + DrawTextLine(x, icon_y, batt_capacity.c_str(), false); + } +} + // Redraw everything on the screen and flip the screen (make it visible). // Should only be called with updateMutex locked. void ScreenRecoveryUI::update_screen_locked() { @@ -879,6 +952,51 @@ void ScreenRecoveryUI::update_progress_locked() { gr_flip(); } +void ScreenRecoveryUI::BattMonitorThreadLoop() { + using aidl::android::hardware::health::BatteryStatus; + using android::hardware::health::InitHealthdConfig; + + auto config = std::make_unique<healthd_config>(); + InitHealthdConfig(config.get()); + + auto batt_monitor = std::make_unique<android::BatteryMonitor>(); + batt_monitor->init(config.get()); + + while (!batt_monitor_thread_stopped_) { + bool redraw = false; + { + std::lock_guard<std::mutex> lg(updateMutex); + + auto charge_status = static_cast<BatteryStatus>(batt_monitor->getChargeStatus()); + // Treat unknown status as on charger. + bool charging = (charge_status != BatteryStatus::DISCHARGING && + charge_status != BatteryStatus::NOT_CHARGING && + charge_status != BatteryStatus::FULL); + if (charging_ != charging) { + charging_ = charging; + redraw = true; + } + + android::BatteryProperty prop; + android::status_t status = batt_monitor->getProperty(android::BATTERY_PROP_CAPACITY, &prop); + // 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 (status != android::OK) { + prop.valueInt64 = 100; + } + + int32_t batt_capacity = static_cast<int32_t>(prop.valueInt64); + if (batt_capacity_ != batt_capacity) { + batt_capacity_ = batt_capacity; + redraw = true; + } + + if (redraw) update_screen_locked(); + } + std::this_thread::sleep_for(5s); + } +} + void ScreenRecoveryUI::ProgressThreadLoop() { double interval = 1.0 / animation_fps_; while (!progress_thread_stopped_) { @@ -1070,6 +1188,9 @@ bool ScreenRecoveryUI::Init(const std::string& locale) { LoadAnimation(); + // Keep the battery capacity updated. + batt_monitor_thread_ = std::thread(&ScreenRecoveryUI::BattMonitorThreadLoop, this); + // Keep the progress bar updated, even when the process is otherwise busy. progress_thread_ = std::thread(&ScreenRecoveryUI::ProgressThreadLoop, this); @@ -1353,8 +1474,34 @@ int ScreenRecoveryUI::SelectMenu(int sel) { } int ScreenRecoveryUI::SelectMenu(const Point& p) { + Point point; + + const auto scaleX = static_cast<double>(p.x()) / ScreenWidth(); + const auto scaleY = static_cast<double>(p.y()) / ScreenHeight(); + + // Correct position for touch rotation + switch (gr_touch_rotation()) { + case GRRotation::NONE: + point.x(ScreenWidth() * scaleX); + point.y(ScreenHeight() * scaleY); + break; + case GRRotation::RIGHT: + point.x(ScreenWidth() * scaleY); + point.y(ScreenHeight() - (ScreenHeight() * scaleX)); + break; + case GRRotation::DOWN: + point.x(ScreenWidth() - (ScreenWidth() * scaleX)); + point.y(ScreenHeight() - (ScreenHeight() * scaleY)); + break; + case GRRotation::LEFT: + point.x(ScreenWidth() - (ScreenWidth() * scaleY)); + point.y(ScreenHeight() * scaleX); + break; + } + // Correct position for overscan - const Point point(p.x() - gr_overscan_offset_x(), p.y() - gr_overscan_offset_y()); + point.x(point.x() - gr_overscan_offset_x()); + point.y(point.y() - gr_overscan_offset_y()); int new_sel = Device::kNoAction; std::lock_guard<std::mutex> lg(updateMutex); diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp index 8561120c..60df9019 100644 --- a/recovery_ui/ui.cpp +++ b/recovery_ui/ui.cpp @@ -64,6 +64,7 @@ RecoveryUI::RecoveryUI() max_brightness_file_(MAX_BRIGHTNESS_FILE), touch_screen_allowed_(true), fastbootd_logo_enabled_(false), + sideload_auto_reboot_(false), touch_low_threshold_(android::base::GetIntProperty("ro.recovery.ui.touch_low_threshold", kDefaultTouchLowThreshold)), touch_high_threshold_(android::base::GetIntProperty("ro.recovery.ui.touch_high_threshold", diff --git a/tools/recovery_l10n/res/values-te/strings.xml b/tools/recovery_l10n/res/values-te/strings.xml index 57470752..513ae9d5 100644 --- a/tools/recovery_l10n/res/values-te/strings.xml +++ b/tools/recovery_l10n/res/values-te/strings.xml @@ -6,7 +6,7 @@ <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> diff --git a/update_verifier/Android.bp b/update_verifier/Android.bp index 220b007f..cb97bd1f 100644 --- a/update_verifier/Android.bp +++ b/update_verifier/Android.bp @@ -73,6 +73,10 @@ cc_library_static { "libvold_binder", ], + whole_static_libs: [ + "libsnapshot_snapuserd", + ], + shared_libs: [ "android.hardware.boot@1.0", "libbase", diff --git a/update_verifier/include/update_verifier/update_verifier.h b/update_verifier/include/update_verifier/update_verifier.h index 4c64b1ea..0cccc907 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 a042f900..88fcfa50 100644 --- a/update_verifier/update_verifier.cpp +++ b/update_verifier/update_verifier.cpp @@ -52,6 +52,7 @@ #include <future> #include <thread> +#include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> @@ -188,7 +189,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."; |
