aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChippa-a <bagirovvusal99@gmail.com>2023-10-19 00:06:41 +0300
committerChippa-a <bagirovvusal99@gmail.com>2023-12-14 22:12:03 +0300
commita6aa35048cf1f96a0d4608a7dedf230e125b2ce8 (patch)
treec46efe72b33f638faff96fbd133b10de4b35620d
parente5c3f128ca728ae53c1f9606e79f85df817bdeee (diff)
recovery_ui: Add support for battery capacity status
This is a reworked version from the older GUI implementation (I89c963e75bbc40f4bb7204211773fbfb28a5206b). - Update for the current recovery/fastbootd UI - Use loop to update battery capacity in background - Reflect charging status by appending "+" Change-Id: If7a6c080da273dfedddffcbea5e0ce12e677bf2f Signed-off-by: Chippa-a <bagirovvusal99@gmail.com>
-rw-r--r--recovery_ui/Android.bp6
-rw-r--r--recovery_ui/include/recovery_ui/screen_ui.h8
-rw-r--r--recovery_ui/screen_ui.cpp122
3 files changed, 136 insertions, 0 deletions
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/screen_ui.cpp b/recovery_ui/screen_ui.cpp
index 17ece4c0..75797cee 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 = 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,52 @@ 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) {
+ LOG(WARNING) << "Using fake battery capacity 100.";
+ 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 +1189,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);