/*
 * Copyright (C) 2011-2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "healthd_mode_charger.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>

#include <optional>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <android-base/strings.h>

#include <linux/netlink.h>
#include <sys/socket.h>

#include <cutils/android_get_control_file.h>
#include <cutils/klog.h>
#include <cutils/misc.h>
#include <cutils/properties.h>
#include <cutils/uevent.h>
#include <sys/reboot.h>

#include <suspend/autosuspend.h>

#include "AnimationParser.h"
#include "charger.sysprop.h"
#include "charger_utils.h"
#include "healthd_draw.h"

#include <android/hardware/health/2.0/IHealthInfoCallback.h>
#include <health/utils.h>
#include <health2impl/HalHealthLoop.h>
#include <health2impl/Health.h>
#include <healthd/healthd.h>

using std::string_literals::operator""s;
using namespace android;
using android::hardware::Return;
using android::hardware::health::GetHealthServiceOrDefault;
using android::hardware::health::HealthLoop;
using android::hardware::health::V1_0::BatteryStatus;
using android::hardware::health::V2_0::Result;
using android::hardware::health::V2_1::IHealth;
using IHealth_2_0 = android::hardware::health::V2_0::IHealth;
using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;

// main healthd loop
extern int healthd_main(void);

// minui globals
char* locale;

#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif

#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

#define MSEC_PER_SEC (1000LL)
#define NSEC_PER_MSEC (1000000LL)

#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC)
#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC)
#define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
#define UNPLUGGED_DISPLAY_TIME (3 * MSEC_PER_SEC)
#define MAX_BATT_LEVEL_WAIT_TIME (3 * MSEC_PER_SEC)
#define UNPLUGGED_SHUTDOWN_TIME_PROP "ro.product.charger.unplugged_shutdown_time"

#define LAST_KMSG_MAX_SZ (32 * 1024)

#define LOGE(x...) KLOG_ERROR("charger", x);
#define LOGW(x...) KLOG_WARNING("charger", x);
#define LOGV(x...) KLOG_DEBUG("charger", x);

namespace android {

// Legacy animation resources are loaded from this directory.
static constexpr const char* legacy_animation_root = "/res/images/";

// Built-in animation resources are loaded from this directory.
static constexpr const char* system_animation_root = "/system/etc/res/images/";

// Resources in /product/etc/res overrides resources in /res and /system/etc/res.
// If the device is using the Generic System Image (GSI), resources may exist in
// both paths.
static constexpr const char* product_animation_desc_path =
        "/product/etc/res/values/charger/animation.txt";
static constexpr const char* product_animation_root = "/product/etc/res/images/";
static constexpr const char* animation_desc_path = "/res/values/charger/animation.txt";

static const animation BASE_ANIMATION = {
    .text_clock =
        {
            .pos_x = 0,
            .pos_y = 0,

            .color_r = 255,
            .color_g = 255,
            .color_b = 255,
            .color_a = 255,

            .font = nullptr,
        },
    .text_percent =
        {
            .pos_x = 0,
            .pos_y = 0,

            .color_r = 255,
            .color_g = 255,
            .color_b = 255,
            .color_a = 255,
        },

    .run = false,

    .frames = nullptr,
    .cur_frame = 0,
    .num_frames = 0,
    .first_frame_repeats = 2,

    .cur_cycle = 0,
    .num_cycles = 3,

    .cur_level = 0,
    .cur_status = BATTERY_STATUS_UNKNOWN,
};

void Charger::InitDefaultAnimationFrames() {
    owned_frames_ = {
            {
                    .disp_time = 750,
                    .min_level = 0,
                    .max_level = 19,
                    .surface = NULL,
            },
            {
                    .disp_time = 750,
                    .min_level = 0,
                    .max_level = 39,
                    .surface = NULL,
            },
            {
                    .disp_time = 750,
                    .min_level = 0,
                    .max_level = 59,
                    .surface = NULL,
            },
            {
                    .disp_time = 750,
                    .min_level = 0,
                    .max_level = 79,
                    .surface = NULL,
            },
            {
                    .disp_time = 750,
                    .min_level = 80,
                    .max_level = 95,
                    .surface = NULL,
            },
            {
                    .disp_time = 750,
                    .min_level = 0,
                    .max_level = 100,
                    .surface = NULL,
            },
    };
}

Charger::Charger(const sp<IHealth>& service)
    : HalHealthLoop("charger", service), batt_anim_(BASE_ANIMATION) {}

Charger::~Charger() {}

/* current time in milliseconds */
static int64_t curr_time_ms() {
    timespec tm;
    clock_gettime(CLOCK_MONOTONIC, &tm);
    return tm.tv_sec * MSEC_PER_SEC + (tm.tv_nsec / NSEC_PER_MSEC);
}

#define MAX_KLOG_WRITE_BUF_SZ 256

static void dump_last_kmsg(void) {
    std::string buf;
    char* ptr;
    size_t len;

    LOGW("\n");
    LOGW("*************** LAST KMSG ***************\n");
    LOGW("\n");
    const char* kmsg[] = {
        // clang-format off
        "/sys/fs/pstore/console-ramoops-0",
        "/sys/fs/pstore/console-ramoops",
        "/proc/last_kmsg",
        // clang-format on
    };
    for (size_t i = 0; i < arraysize(kmsg) && buf.empty(); ++i) {
        auto fd = android_get_control_file(kmsg[i]);
        if (fd >= 0) {
            android::base::ReadFdToString(fd, &buf);
        } else {
            android::base::ReadFileToString(kmsg[i], &buf);
        }
    }

    if (buf.empty()) {
        LOGW("last_kmsg not found. Cold reset?\n");
        goto out;
    }

    len = min(buf.size(), LAST_KMSG_MAX_SZ);
    ptr = &buf[buf.size() - len];

    while (len > 0) {
        size_t cnt = min(len, MAX_KLOG_WRITE_BUF_SZ);
        char yoink;
        char* nl;

        nl = (char*)memrchr(ptr, '\n', cnt - 1);
        if (nl) cnt = nl - ptr + 1;

        yoink = ptr[cnt];
        ptr[cnt] = '\0';
        klog_write(6, "<4>%s", ptr);
        ptr[cnt] = yoink;

        len -= cnt;
        ptr += cnt;
    }

out:
    LOGW("\n");
    LOGW("************* END LAST KMSG *************\n");
    LOGW("\n");
}

static int request_suspend(bool enable) {
    if (!android::sysprop::ChargerProperties::enable_suspend().value_or(false)) {
        return 0;
    }

    if (enable)
        return autosuspend_enable();
    else
        return autosuspend_disable();
}

static void kick_animation(animation* anim) {
    anim->run = true;
}

static void reset_animation(animation* anim) {
    anim->cur_cycle = 0;
    anim->cur_frame = 0;
    anim->run = false;
}

void Charger::UpdateScreenState(int64_t now) {
    int disp_time;

    if (!batt_anim_.run || now < next_screen_transition_) return;

    // If battery level is not ready, keep checking in the defined time
    if (health_info_.batteryLevel == 0 && health_info_.batteryStatus == BatteryStatus::UNKNOWN) {
        if (wait_batt_level_timestamp_ == 0) {
            // Set max delay time and skip drawing screen
            wait_batt_level_timestamp_ = now + MAX_BATT_LEVEL_WAIT_TIME;
            LOGV("[%" PRId64 "] wait for battery capacity ready\n", now);
            return;
        } else if (now <= wait_batt_level_timestamp_) {
            // Do nothing, keep waiting
            return;
        }
        // If timeout and battery level is still not ready, draw unknown battery
    }

    if (healthd_draw_ == nullptr) {
        std::optional<bool> out_screen_on;
        service()->shouldKeepScreenOn([&](Result res, bool screen_on) {
            if (res == Result::SUCCESS) {
                *out_screen_on = screen_on;
            }
        });
        if (out_screen_on.has_value()) {
            if (!*out_screen_on) {
                LOGV("[%" PRId64 "] leave screen off\n", now);
                batt_anim_.run = false;
                next_screen_transition_ = -1;
                if (charger_online()) request_suspend(true);
                return;
            }
        }

        healthd_draw_.reset(new HealthdDraw(&batt_anim_));

        if (android::sysprop::ChargerProperties::disable_init_blank().value_or(false)) {
            healthd_draw_->blank_screen(true);
            screen_blanked_ = true;
        }
    }

    /* animation is over, blank screen and leave */
    if (batt_anim_.num_cycles > 0 && batt_anim_.cur_cycle == batt_anim_.num_cycles) {
        reset_animation(&batt_anim_);
        next_screen_transition_ = -1;
        healthd_draw_->blank_screen(true);
        screen_blanked_ = true;
        LOGV("[%" PRId64 "] animation done\n", now);
        if (charger_online()) request_suspend(true);
        return;
    }

    disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time;

    if (screen_blanked_) {
        healthd_draw_->blank_screen(false);
        screen_blanked_ = false;
    }

    /* animation starting, set up the animation */
    if (batt_anim_.cur_frame == 0) {
        LOGV("[%" PRId64 "] animation starting\n", now);
        batt_anim_.cur_level = health_info_.batteryLevel;
        batt_anim_.cur_status = (int)health_info_.batteryStatus;
        if (health_info_.batteryLevel >= 0 && batt_anim_.num_frames != 0) {
            /* find first frame given current battery level */
            for (int i = 0; i < batt_anim_.num_frames; i++) {
                if (batt_anim_.cur_level >= batt_anim_.frames[i].min_level &&
                    batt_anim_.cur_level <= batt_anim_.frames[i].max_level) {
                    batt_anim_.cur_frame = i;
                    break;
                }
            }

            if (charger_online()) {
                // repeat the first frame first_frame_repeats times
                disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time *
                            batt_anim_.first_frame_repeats;
            } else {
                disp_time = UNPLUGGED_DISPLAY_TIME / batt_anim_.num_cycles;
            }

            LOGV("cur_frame=%d disp_time=%d\n", batt_anim_.cur_frame, disp_time);
        }
    }

    /* draw the new frame (@ cur_frame) */
    healthd_draw_->redraw_screen(&batt_anim_, surf_unknown_);

    /* if we don't have anim frames, we only have one image, so just bump
     * the cycle counter and exit
     */
    if (batt_anim_.num_frames == 0 || batt_anim_.cur_level < 0) {
        LOGW("[%" PRId64 "] animation missing or unknown battery status\n", now);
        next_screen_transition_ = now + BATTERY_UNKNOWN_TIME;
        batt_anim_.cur_cycle++;
        return;
    }

    /* schedule next screen transition */
    next_screen_transition_ = curr_time_ms() + disp_time;

    /* advance frame cntr to the next valid frame only if we are charging
     * if necessary, advance cycle cntr, and reset frame cntr
     */
    if (charger_online()) {
        batt_anim_.cur_frame++;

        while (batt_anim_.cur_frame < batt_anim_.num_frames &&
               (batt_anim_.cur_level < batt_anim_.frames[batt_anim_.cur_frame].min_level ||
                batt_anim_.cur_level > batt_anim_.frames[batt_anim_.cur_frame].max_level)) {
            batt_anim_.cur_frame++;
        }
        if (batt_anim_.cur_frame >= batt_anim_.num_frames) {
            batt_anim_.cur_cycle++;
            batt_anim_.cur_frame = 0;

            /* don't reset the cycle counter, since we use that as a signal
             * in a test above to check if animation is over
             */
        }
    } else {
        /* Stop animating if we're not charging.
         * If we stop it immediately instead of going through this loop, then
         * the animation would stop somewhere in the middle.
         */
        batt_anim_.cur_frame = 0;
        batt_anim_.cur_cycle++;
    }
}

int Charger::SetKeyCallback(int code, int value) {
    int64_t now = curr_time_ms();
    int down = !!value;

    if (code > KEY_MAX) return -1;

    /* ignore events that don't modify our state */
    if (keys_[code].down == down) return 0;

    /* only record the down even timestamp, as the amount
     * of time the key spent not being pressed is not useful */
    if (down) keys_[code].timestamp = now;
    keys_[code].down = down;
    keys_[code].pending = true;
    if (down) {
        LOGV("[%" PRId64 "] key[%d] down\n", now, code);
    } else {
        int64_t duration = now - keys_[code].timestamp;
        int64_t secs = duration / 1000;
        int64_t msecs = duration - secs * 1000;
        LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", now, code,
             secs, msecs);
    }

    return 0;
}

void Charger::UpdateInputState(input_event* ev) {
    if (ev->type != EV_KEY) return;
    SetKeyCallback(ev->code, ev->value);
}

void Charger::SetNextKeyCheck(key_state* key, int64_t timeout) {
    int64_t then = key->timestamp + timeout;

    if (next_key_check_ == -1 || then < next_key_check_) next_key_check_ = then;
}

void Charger::ProcessKey(int code, int64_t now) {
    key_state* key = &keys_[code];

    if (code == KEY_POWER) {
        if (key->down) {
            int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME;
            if (now >= reboot_timeout) {
                /* We do not currently support booting from charger mode on
                   all devices. Check the property and continue booting or reboot
                   accordingly. */
                if (property_get_bool("ro.enable_boot_charger_mode", false)) {
                    LOGW("[%" PRId64 "] booting from charger mode\n", now);
                    property_set("sys.boot_from_charger_mode", "1");
                } else {
                    if (batt_anim_.cur_level >= boot_min_cap_) {
                        LOGW("[%" PRId64 "] rebooting\n", now);
                        reboot(RB_AUTOBOOT);
                    } else {
                        LOGV("[%" PRId64
                             "] ignore power-button press, battery level "
                             "less than minimum\n",
                             now);
                    }
                }
            } else {
                /* if the key is pressed but timeout hasn't expired,
                 * make sure we wake up at the right-ish time to check
                 */
                SetNextKeyCheck(key, POWER_ON_KEY_TIME);

                /* Turn on the display and kick animation on power-key press
                 * rather than on key release
                 */
                kick_animation(&batt_anim_);
                request_suspend(false);
            }
        } else {
            /* if the power key got released, force screen state cycle */
            if (key->pending) {
                kick_animation(&batt_anim_);
                request_suspend(false);
            }
        }
    }

    key->pending = false;
}

void Charger::HandleInputState(int64_t now) {
    ProcessKey(KEY_POWER, now);

    if (next_key_check_ != -1 && now > next_key_check_) next_key_check_ = -1;
}

void Charger::HandlePowerSupplyState(int64_t now) {
    int timer_shutdown = UNPLUGGED_SHUTDOWN_TIME;
    if (!have_battery_state_) return;

    if (!charger_online()) {
        request_suspend(false);
        if (next_pwr_check_ == -1) {
            /* Last cycle would have stopped at the extreme top of battery-icon
             * Need to show the correct level corresponding to capacity.
             *
             * Reset next_screen_transition_ to update screen immediately.
             * Reset & kick animation to show complete animation cycles
             * when charger disconnected.
             */
            timer_shutdown =
                    property_get_int32(UNPLUGGED_SHUTDOWN_TIME_PROP, UNPLUGGED_SHUTDOWN_TIME);
            next_screen_transition_ = now - 1;
            reset_animation(&batt_anim_);
            kick_animation(&batt_anim_);
            next_pwr_check_ = now + timer_shutdown;
            LOGW("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
                 now, (int64_t)timer_shutdown, next_pwr_check_);
        } else if (now >= next_pwr_check_) {
            LOGW("[%" PRId64 "] shutting down\n", now);
            reboot(RB_POWER_OFF);
        } else {
            /* otherwise we already have a shutdown timer scheduled */
        }
    } else {
        /* online supply present, reset shutdown timer if set */
        if (next_pwr_check_ != -1) {
            /* Reset next_screen_transition_ to update screen immediately.
             * Reset & kick animation to show complete animation cycles
             * when charger connected again.
             */
            request_suspend(false);
            next_screen_transition_ = now - 1;
            reset_animation(&batt_anim_);
            kick_animation(&batt_anim_);
            LOGW("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
        }
        next_pwr_check_ = -1;
    }
}

void Charger::Heartbeat() {
    // charger* charger = &charger_state;
    int64_t now = curr_time_ms();

    HandleInputState(now);
    HandlePowerSupplyState(now);

    /* do screen update last in case any of the above want to start
     * screen transitions (animations, etc)
     */
    UpdateScreenState(now);
}

void Charger::OnHealthInfoChanged(const HealthInfo_2_1& health_info) {
    set_charger_online(health_info);

    if (!have_battery_state_) {
        have_battery_state_ = true;
        next_screen_transition_ = curr_time_ms() - 1;
        request_suspend(false);
        reset_animation(&batt_anim_);
        kick_animation(&batt_anim_);
    }
    health_info_ = health_info.legacy.legacy;

    AdjustWakealarmPeriods(charger_online());
}

int Charger::PrepareToWait(void) {
    int64_t now = curr_time_ms();
    int64_t next_event = INT64_MAX;
    int64_t timeout;

    LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n",
         now, next_screen_transition_, next_key_check_, next_pwr_check_);

    if (next_screen_transition_ != -1) next_event = next_screen_transition_;
    if (next_key_check_ != -1 && next_key_check_ < next_event) next_event = next_key_check_;
    if (next_pwr_check_ != -1 && next_pwr_check_ < next_event) next_event = next_pwr_check_;

    if (next_event != -1 && next_event != INT64_MAX)
        timeout = max(0, next_event - now);
    else
        timeout = -1;

    return (int)timeout;
}

int Charger::InputCallback(int fd, unsigned int epevents) {
    input_event ev;
    int ret;

    ret = ev_get_input(fd, epevents, &ev);
    if (ret) return -1;
    UpdateInputState(&ev);
    return 0;
}

static void charger_event_handler(HealthLoop* /*charger_loop*/, uint32_t /*epevents*/) {
    int ret;

    ret = ev_wait(-1);
    if (!ret) ev_dispatch();
}

void Charger::InitAnimation() {
    bool parse_success;

    std::string content;
    if (base::ReadFileToString(product_animation_desc_path, &content)) {
        parse_success = parse_animation_desc(content, &batt_anim_);
        batt_anim_.set_resource_root(product_animation_root);
    } else if (base::ReadFileToString(animation_desc_path, &content)) {
        parse_success = parse_animation_desc(content, &batt_anim_);
        // Fallback resources always exist in system_animation_root. On legacy devices with an old
        // ramdisk image, resources may be overridden under root. For example,
        // /res/images/charger/battery_fail.png may not be the same as
        // system/core/healthd/images/battery_fail.png in the source tree, but is a device-specific
        // image. Hence, load from /res, and fall back to /system/etc/res.
        batt_anim_.set_resource_root(legacy_animation_root, system_animation_root);
    } else {
        LOGW("Could not open animation description at %s\n", animation_desc_path);
        parse_success = false;
    }

    if (!parse_success) {
        LOGW("Could not parse animation description. Using default animation.\n");
        batt_anim_ = BASE_ANIMATION;
        batt_anim_.animation_file.assign(system_animation_root + "charger/battery_scale.png"s);
        InitDefaultAnimationFrames();
        batt_anim_.frames = owned_frames_.data();
        batt_anim_.num_frames = owned_frames_.size();
    }
    if (batt_anim_.fail_file.empty()) {
        batt_anim_.fail_file.assign(system_animation_root + "charger/battery_fail.png"s);
    }

    LOGV("Animation Description:\n");
    LOGV("  animation: %d %d '%s' (%d)\n", batt_anim_.num_cycles, batt_anim_.first_frame_repeats,
         batt_anim_.animation_file.c_str(), batt_anim_.num_frames);
    LOGV("  fail_file: '%s'\n", batt_anim_.fail_file.c_str());
    LOGV("  clock: %d %d %d %d %d %d '%s'\n", batt_anim_.text_clock.pos_x,
         batt_anim_.text_clock.pos_y, batt_anim_.text_clock.color_r, batt_anim_.text_clock.color_g,
         batt_anim_.text_clock.color_b, batt_anim_.text_clock.color_a,
         batt_anim_.text_clock.font_file.c_str());
    LOGV("  percent: %d %d %d %d %d %d '%s'\n", batt_anim_.text_percent.pos_x,
         batt_anim_.text_percent.pos_y, batt_anim_.text_percent.color_r,
         batt_anim_.text_percent.color_g, batt_anim_.text_percent.color_b,
         batt_anim_.text_percent.color_a, batt_anim_.text_percent.font_file.c_str());
    for (int i = 0; i < batt_anim_.num_frames; i++) {
        LOGV("  frame %.2d: %d %d %d\n", i, batt_anim_.frames[i].disp_time,
             batt_anim_.frames[i].min_level, batt_anim_.frames[i].max_level);
    }
}

void Charger::Init(struct healthd_config* config) {
    int ret;
    int i;
    int epollfd;

    dump_last_kmsg();

    LOGW("--------------- STARTING CHARGER MODE ---------------\n");

    ret = ev_init(
            std::bind(&Charger::InputCallback, this, std::placeholders::_1, std::placeholders::_2));
    if (!ret) {
        epollfd = ev_get_epollfd();
        RegisterEvent(epollfd, &charger_event_handler, EVENT_WAKEUP_FD);
    }

    InitAnimation();

    ret = CreateDisplaySurface(batt_anim_.fail_file, &surf_unknown_);
    if (ret < 0) {
        LOGE("Cannot load custom battery_fail image. Reverting to built in: %d\n", ret);
        ret = CreateDisplaySurface((system_animation_root + "charger/battery_fail.png"s).c_str(),
                                   &surf_unknown_);
        if (ret < 0) {
            LOGE("Cannot load built in battery_fail image\n");
            surf_unknown_ = NULL;
        }
    }

    GRSurface** scale_frames;
    int scale_count;
    int scale_fps;  // Not in use (charger/battery_scale doesn't have FPS text
                    // chunk). We are using hard-coded frame.disp_time instead.
    ret = CreateMultiDisplaySurface(batt_anim_.animation_file, &scale_count, &scale_fps,
                                    &scale_frames);
    if (ret < 0) {
        LOGE("Cannot load battery_scale image\n");
        batt_anim_.num_frames = 0;
        batt_anim_.num_cycles = 1;
    } else if (scale_count != batt_anim_.num_frames) {
        LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", scale_count,
             batt_anim_.num_frames);
        batt_anim_.num_frames = 0;
        batt_anim_.num_cycles = 1;
    } else {
        for (i = 0; i < batt_anim_.num_frames; i++) {
            batt_anim_.frames[i].surface = scale_frames[i];
        }
    }
    ev_sync_key_state(std::bind(&Charger::SetKeyCallback, this, std::placeholders::_1,
                                std::placeholders::_2));

    next_screen_transition_ = -1;
    next_key_check_ = -1;
    next_pwr_check_ = -1;
    wait_batt_level_timestamp_ = 0;

    // Retrieve healthd_config from the existing health HAL.
    HalHealthLoop::Init(config);

    boot_min_cap_ = config->boot_min_cap;
}

int Charger::CreateDisplaySurface(const std::string& name, GRSurface** surface) {
    return res_create_display_surface(name.c_str(), surface);
}

int Charger::CreateMultiDisplaySurface(const std::string& name, int* frames, int* fps,
                                       GRSurface*** surface) {
    return res_create_multi_display_surface(name.c_str(), frames, fps, surface);
}

void set_resource_root_for(const std::string& root, const std::string& backup_root,
                           std::string* value) {
    if (value->empty()) {
        return;
    }

    std::string new_value = root + *value + ".png";
    // If |backup_root| is provided, additionally check whether the file under |root| is
    // accessible or not. If not accessible, fallback to file under |backup_root|.
    if (!backup_root.empty() && access(new_value.data(), F_OK) == -1) {
        new_value = backup_root + *value + ".png";
    }

    *value = new_value;
}

void animation::set_resource_root(const std::string& root, const std::string& backup_root) {
    CHECK(android::base::StartsWith(root, "/") && android::base::EndsWith(root, "/"))
            << "animation root " << root << " must start and end with /";
    CHECK(backup_root.empty() || (android::base::StartsWith(backup_root, "/") &&
                                  android::base::EndsWith(backup_root, "/")))
            << "animation backup root " << backup_root << " must start and end with /";
    set_resource_root_for(root, backup_root, &animation_file);
    set_resource_root_for(root, backup_root, &fail_file);
    set_resource_root_for(root, backup_root, &text_clock.font_file);
    set_resource_root_for(root, backup_root, &text_percent.font_file);
}

}  // namespace android

int healthd_charger_main(int argc, char** argv) {
    int ch;

    while ((ch = getopt(argc, argv, "cr")) != -1) {
        switch (ch) {
            case 'c':
                // -c is now a noop
                break;
            case 'r':
                // -r is now a noop
                break;
            case '?':
            default:
                LOGE("Unrecognized charger option: %c\n", optopt);
                exit(1);
        }
    }

    Charger charger(GetHealthServiceOrDefault());
    return charger.StartLoop();
}
