Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16d0a185 authored by Yabin Cui's avatar Yabin Cui Committed by Gerrit Code Review
Browse files

Merge "recovery: check battery level before installing package."

parents fa9af7da 53e7a062
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -64,6 +64,7 @@ LOCAL_C_INCLUDES += \
    system/core/adb \
    system/core/adb \


LOCAL_STATIC_LIBRARIES := \
LOCAL_STATIC_LIBRARIES := \
    libbatterymonitor \
    libext4_utils_static \
    libext4_utils_static \
    libsparse_static \
    libsparse_static \
    libminzip \
    libminzip \
@@ -77,11 +78,14 @@ LOCAL_STATIC_LIBRARIES := \
    libfs_mgr \
    libfs_mgr \
    libbase \
    libbase \
    libcutils \
    libcutils \
    libutils \
    liblog \
    liblog \
    libselinux \
    libselinux \
    libm \
    libm \
    libc
    libc


LOCAL_HAL_STATIC_LIBRARIES := libhealthd

ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
    LOCAL_CFLAGS += -DUSE_EXT4
    LOCAL_CFLAGS += -DUSE_EXT4
    LOCAL_C_INCLUDES += system/extras/ext4_utils
    LOCAL_C_INCLUDES += system/extras/ext4_utils
+1 −1
Original line number Original line Diff line number Diff line
@@ -23,7 +23,7 @@
extern "C" {
extern "C" {
#endif
#endif


enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_NONE };
enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT, INSTALL_NONE, INSTALL_SKIPPED };
// Install the package specified by root_path.  If INSTALL_SUCCESS is
// Install the package specified by root_path.  If INSTALL_SUCCESS is
// returned and *wipe_cache is true on exit, caller should wipe the
// returned and *wipe_cache is true on exit, caller should wipe the
// cache partition.
// cache partition.
+84 −15
Original line number Original line Diff line number Diff line
@@ -40,6 +40,8 @@
#include <cutils/android_reboot.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
#include <cutils/properties.h>


#include <healthd/BatteryMonitor.h>

#include "adb_install.h"
#include "adb_install.h"
#include "bootloader.h"
#include "bootloader.h"
#include "common.h"
#include "common.h"
@@ -84,6 +86,12 @@ static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install";
static const char *LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
static const char *LAST_KMSG_FILE = "/cache/recovery/last_kmsg";
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const int KEEP_LOG_COUNT = 10;
static const int KEEP_LOG_COUNT = 10;
static const int BATTERY_READ_TIMEOUT_IN_SEC = 10;
// GmsCore enters recovery mode to install package when having enough battery
// percentage. Normally, the threshold is 40% without charger and 20% with charger.
// So we should check battery with a slightly lower limitation.
static const int BATTERY_OK_PERCENTAGE = 20;
static const int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15;


RecoveryUI* ui = NULL;
RecoveryUI* ui = NULL;
char* locale = NULL;
char* locale = NULL;
@@ -1058,8 +1066,61 @@ ui_print(const char* format, ...) {
    }
    }
}
}


int
static bool is_battery_ok() {
main(int argc, char **argv) {
    struct healthd_config healthd_config = {
            .batteryStatusPath = android::String8(android::String8::kEmptyString),
            .batteryHealthPath = android::String8(android::String8::kEmptyString),
            .batteryPresentPath = android::String8(android::String8::kEmptyString),
            .batteryCapacityPath = android::String8(android::String8::kEmptyString),
            .batteryVoltagePath = android::String8(android::String8::kEmptyString),
            .batteryTemperaturePath = android::String8(android::String8::kEmptyString),
            .batteryTechnologyPath = android::String8(android::String8::kEmptyString),
            .batteryCurrentNowPath = android::String8(android::String8::kEmptyString),
            .batteryCurrentAvgPath = android::String8(android::String8::kEmptyString),
            .batteryChargeCounterPath = android::String8(android::String8::kEmptyString),
            .batteryFullChargePath = android::String8(android::String8::kEmptyString),
            .batteryCycleCountPath = android::String8(android::String8::kEmptyString),
            .energyCounter = NULL,
            .boot_min_cap = 0,
            .screen_on = NULL
    };
    healthd_board_init(&healthd_config);

    android::BatteryMonitor monitor;
    monitor.init(&healthd_config);

    int wait_second = 0;
    while (true) {
        int charge_status = monitor.getChargeStatus();
        // Treat unknown status as charged.
        bool charged = (charge_status != android::BATTERY_STATUS_DISCHARGING &&
                        charge_status != android::BATTERY_STATUS_NOT_CHARGING);
        android::BatteryProperty capacity;
        android::status_t status = monitor.getProperty(android::BATTERY_PROP_CAPACITY, &capacity);
        ui_print("charge_status %d, charged %d, status %d, capacity %lld\n", charge_status,
                 charged, status, capacity.valueInt64);
        // 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 (status == 0 && capacity.valueInt64 == 50) {
            if (wait_second < BATTERY_READ_TIMEOUT_IN_SEC) {
                sleep(1);
                wait_second++;
                continue;
            }
        }
        // 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 != 0) {
            capacity.valueInt64 = 100;
        }
        return (charged && capacity.valueInt64 >= BATTERY_WITH_CHARGER_OK_PERCENTAGE) ||
                (!charged && capacity.valueInt64 >= BATTERY_OK_PERCENTAGE);
    }
}

int main(int argc, char **argv) {
    // If this binary is started with the single argument "--adbd",
    // If this binary is started with the single argument "--adbd",
    // instead of being the normal recovery binary, it turns into kind
    // instead of being the normal recovery binary, it turns into kind
    // of a stripped-down version of adbd that only supports the
    // of a stripped-down version of adbd that only supports the
@@ -1189,7 +1250,13 @@ main(int argc, char **argv) {
    int status = INSTALL_SUCCESS;
    int status = INSTALL_SUCCESS;


    if (update_package != NULL) {
    if (update_package != NULL) {
        status = install_package(update_package, &should_wipe_cache, TEMPORARY_INSTALL_FILE, true);
        if (!is_battery_ok()) {
            ui->Print("battery capacity is not enough for installing package, needed is %d%%\n",
                      BATTERY_OK_PERCENTAGE);
            status = INSTALL_SKIPPED;
        } else {
            status = install_package(update_package, &should_wipe_cache,
                                     TEMPORARY_INSTALL_FILE, true);
            if (status == INSTALL_SUCCESS && should_wipe_cache) {
            if (status == INSTALL_SUCCESS && should_wipe_cache) {
                wipe_cache(false, device);
                wipe_cache(false, device);
            }
            }
@@ -1203,6 +1270,7 @@ main(int argc, char **argv) {
                    ui->ShowText(true);
                    ui->ShowText(true);
                }
                }
            }
            }
        }
    } else if (should_wipe_data) {
    } else if (should_wipe_data) {
        if (!wipe_data(false, device)) {
        if (!wipe_data(false, device)) {
            status = INSTALL_ERROR;
            status = INSTALL_ERROR;
@@ -1249,7 +1317,8 @@ main(int argc, char **argv) {
    }
    }


    Device::BuiltinAction after = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
    Device::BuiltinAction after = shutdown_after ? Device::SHUTDOWN : Device::REBOOT;
    if ((status != INSTALL_SUCCESS && !sideload_auto_reboot) || ui->IsTextVisible()) {
    if ((status != INSTALL_SUCCESS && status != INSTALL_SKIPPED && !sideload_auto_reboot) ||
            ui->IsTextVisible()) {
        Device::BuiltinAction temp = prompt_and_wait(device, status);
        Device::BuiltinAction temp = prompt_and_wait(device, status);
        if (temp != Device::NO_ACTION) {
        if (temp != Device::NO_ACTION) {
            after = temp;
            after = temp;