From b5d7033dcc11f2551c64b5033bf59d4a581762f4 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Wed, 20 Oct 2021 17:15:32 -0700 Subject: [PATCH] charger: separate UI and HAL access. Abstract all the HIDL-ness from charger so an AIDL HAL can later replace the HIDL HAL. Created libhealthd_charger_ui that is responsible for UI stuff in charger. Then libhealthd_charger is now the charger library backed by HIDL HAL. Bug: 170338625 Bug: 203246116 Test: charger_test Change-Id: I193bb76afa18b3367f24796ac53b1760650e8683 --- healthd/Android.bp | 53 +++++++++-- healthd/charger.cpp | 4 +- healthd/charger_test.cpp | 4 +- healthd/healthd_mode_charger.cpp | 91 ++++++------------- healthd/healthd_mode_charger_hidl.cpp | 76 ++++++++++++++++ healthd/healthd_mode_charger_hidl.h | 54 +++++++++++ healthd/healthd_mode_charger_test.cpp | 9 +- .../charger}/healthd_mode_charger.h | 60 ++++++++---- 8 files changed, 254 insertions(+), 97 deletions(-) create mode 100644 healthd/healthd_mode_charger_hidl.cpp create mode 100644 healthd/healthd_mode_charger_hidl.h rename healthd/{ => include_charger/charger}/healthd_mode_charger.h (57%) diff --git a/healthd/Android.bp b/healthd/Android.bp index ec47f68b3..020a74487 100644 --- a/healthd/Android.bp +++ b/healthd/Android.bp @@ -120,21 +120,22 @@ cc_library_static { } cc_library_static { - name: "libhealthd_charger", - local_include_dirs: ["include"], - export_include_dirs: [".", "include"], + name: "libhealthd_charger_ui", + export_include_dirs: [ + "include", + "include_charger", + ], static_libs: [ - "android.hardware.health@1.0-convert", + "android.hardware.health-V1-ndk", + "android.hardware.health-translate-ndk", "libcharger_sysprop", "libhealthd_draw", "libhealthloop", - "libhealth2impl", "libminui", ], shared_libs: [ - "android.hardware.health@2.1", "libbase", "libcutils", "liblog", @@ -143,14 +144,51 @@ cc_library_static { "libutils", ], + header_libs: [ + "libhealthd_headers", + ], + + export_static_lib_headers: [ + "android.hardware.health-V1-ndk", + ], + srcs: [ "healthd_mode_charger.cpp", "AnimationParser.cpp", ], } +cc_library_static { + name: "libhealthd_charger", + export_include_dirs: [ + "include", + "include_charger", + ], + + static_libs: [ + "android.hardware.health@1.0-convert", + "libhealth2impl", + "libhealthd_charger_ui", + ], + + shared_libs: [ + "android.hardware.health@2.1", + "libbase", + "libcutils", + "liblog", + "libutils", + ], + + srcs: [ + "healthd_mode_charger_hidl.cpp", + ], +} + cc_defaults { name: "charger_defaults", + local_include_dirs: [ + "include_charger", + ], cflags: [ "-Wall", @@ -174,6 +212,7 @@ cc_defaults { static_libs: [ // common "android.hardware.health@1.0-convert", + "android.hardware.health-V1-ndk", "libbatterymonitor", "libcharger_sysprop", "libhealthd_charger_nops", @@ -183,6 +222,7 @@ cc_defaults { // system charger only "libhealthd_draw", "libhealthd_charger", + "libhealthd_charger_ui", "libminui", "libsuspend", ], @@ -209,6 +249,7 @@ cc_binary { exclude_static_libs: [ "libhealthd_draw", "libhealthd_charger", + "libhealthd_charger_ui", "libminui", "libsuspend", ], diff --git a/healthd/charger.cpp b/healthd/charger.cpp index d03978d4f..73e04fe78 100644 --- a/healthd/charger.cpp +++ b/healthd/charger.cpp @@ -15,9 +15,9 @@ */ #include +#include -#include "charger.sysprop.h" -#include "healthd_mode_charger.h" +#include "healthd_mode_charger_hidl.h" #include "healthd_mode_charger_nops.h" #ifndef CHARGER_FORCE_NO_UI diff --git a/healthd/charger_test.cpp b/healthd/charger_test.cpp index e0bde681b..dc5c459d7 100644 --- a/healthd/charger_test.cpp +++ b/healthd/charger_test.cpp @@ -31,7 +31,7 @@ #include #include -#include "healthd_mode_charger.h" +#include "healthd_mode_charger_hidl.h" using android::hardware::health::InitHealthdConfig; using android::hardware::health::V2_1::HealthInfo; @@ -153,7 +153,7 @@ int main(int /*argc*/, char** /*argv*/) { sp passthrough = new TestHealth(std::move(config)); std::thread bgThread([=] { - android::Charger charger(passthrough); + android::ChargerHidl charger(passthrough); charger.StartLoop(); }); diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp index 3ea90b04e..645ac412d 100644 --- a/healthd/healthd_mode_charger.cpp +++ b/healthd/healthd_mode_charger.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "healthd_mode_charger.h" +#include #include #include @@ -51,26 +51,16 @@ #include "AnimationParser.h" #include "charger.sysprop.h" -#include "charger_utils.h" #include "healthd_draw.h" -#include -#include -#include -#include +#include +#include #include using std::string_literals::operator""s; using namespace android; -using android::hardware::Return; -using android::hardware::health::GetHealthServiceOrDefault; +using aidl::android::hardware::health::BatteryStatus; 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); @@ -199,8 +189,8 @@ void Charger::InitDefaultAnimationFrames() { }; } -Charger::Charger(const sp& service) - : HalHealthLoop("charger", service), batt_anim_(BASE_ANIMATION) {} +Charger::Charger(ChargerConfigurationInterface* configuration) + : batt_anim_(BASE_ANIMATION), configuration_(configuration) {} Charger::~Charger() {} @@ -291,7 +281,7 @@ void Charger::UpdateScreenState(int64_t now) { 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 (health_info_.battery_level == 0 && health_info_.battery_status == 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; @@ -305,18 +295,15 @@ void Charger::UpdateScreenState(int64_t now) { } if (healthd_draw_ == nullptr) { - std::optional out_screen_on; - service()->shouldKeepScreenOn([&](Result res, bool screen_on) { - if (res == Result::SUCCESS) { - *out_screen_on = screen_on; - } - }); + std::optional out_screen_on = configuration_->ChargerShouldKeepScreenOn(); 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); + if (configuration_->ChargerIsOnline()) { + request_suspend(true); + } return; } } @@ -337,7 +324,9 @@ void Charger::UpdateScreenState(int64_t now) { healthd_draw_->blank_screen(true); screen_blanked_ = true; LOGV("[%" PRId64 "] animation done\n", now); - if (charger_online()) request_suspend(true); + if (configuration_->ChargerIsOnline()) { + request_suspend(true); + } return; } @@ -351,9 +340,9 @@ void Charger::UpdateScreenState(int64_t now) { /* 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) { + batt_anim_.cur_level = health_info_.battery_level; + batt_anim_.cur_status = (int)health_info_.battery_status; + if (health_info_.battery_level >= 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 && @@ -363,7 +352,7 @@ void Charger::UpdateScreenState(int64_t now) { } } - if (charger_online()) { + if (configuration_->ChargerIsOnline()) { // repeat the first frame first_frame_repeats times disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time * batt_anim_.first_frame_repeats; @@ -394,7 +383,7 @@ void Charger::UpdateScreenState(int64_t now) { /* 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()) { + if (configuration_->ChargerIsOnline()) { batt_anim_.cur_frame++; while (batt_anim_.cur_frame < batt_anim_.num_frames && @@ -516,7 +505,7 @@ void Charger::HandlePowerSupplyState(int64_t now) { int timer_shutdown = UNPLUGGED_SHUTDOWN_TIME; if (!have_battery_state_) return; - if (!charger_online()) { + if (!configuration_->ChargerIsOnline()) { request_suspend(false); if (next_pwr_check_ == -1) { /* Last cycle would have stopped at the extreme top of battery-icon @@ -557,7 +546,7 @@ void Charger::HandlePowerSupplyState(int64_t now) { } } -void Charger::Heartbeat() { +void Charger::OnHeartbeat() { // charger* charger = &charger_state; int64_t now = curr_time_ms(); @@ -570,9 +559,7 @@ void Charger::Heartbeat() { UpdateScreenState(now); } -void Charger::OnHealthInfoChanged(const HealthInfo_2_1& health_info) { - set_charger_online(health_info); - +void Charger::OnHealthInfoChanged(const ChargerHealthInfo& health_info) { if (!have_battery_state_) { have_battery_state_ = true; next_screen_transition_ = curr_time_ms() - 1; @@ -580,12 +567,10 @@ void Charger::OnHealthInfoChanged(const HealthInfo_2_1& health_info) { reset_animation(&batt_anim_); kick_animation(&batt_anim_); } - health_info_ = health_info.legacy.legacy; - - AdjustWakealarmPeriods(charger_online()); + health_info_ = health_info; } -int Charger::PrepareToWait(void) { +int Charger::OnPrepareToWait(void) { int64_t now = curr_time_ms(); int64_t next_event = INT64_MAX; int64_t timeout; @@ -672,7 +657,7 @@ void Charger::InitAnimation() { } } -void Charger::Init(struct healthd_config* config) { +void Charger::OnInit(struct healthd_config* config) { int ret; int i; int epollfd; @@ -685,7 +670,7 @@ void Charger::Init(struct healthd_config* config) { 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); + configuration_->ChargerRegisterEvent(epollfd, &charger_event_handler, EVENT_WAKEUP_FD); } InitAnimation(); @@ -730,7 +715,7 @@ void Charger::Init(struct healthd_config* config) { wait_batt_level_timestamp_ = 0; // Retrieve healthd_config from the existing health HAL. - HalHealthLoop::Init(config); + configuration_->ChargerInitConfig(config); boot_min_cap_ = config->boot_min_cap; } @@ -773,25 +758,3 @@ void animation::set_resource_root(const std::string& root, const std::string& ba } } // 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(); -} diff --git a/healthd/healthd_mode_charger_hidl.cpp b/healthd/healthd_mode_charger_hidl.cpp new file mode 100644 index 000000000..ae46b23e2 --- /dev/null +++ b/healthd/healthd_mode_charger_hidl.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 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_hidl.h" + +#include +#include + +#include "charger_utils.h" + +using android::hardware::health::GetHealthServiceOrDefault; +using android::hardware::health::V2_0::Result; + +namespace android { + +ChargerHidl::ChargerHidl(const sp& service) + : HalHealthLoop("charger", service), charger_(std::make_unique(this)) {} + +void ChargerHidl::OnHealthInfoChanged(const HealthInfo_2_1& health_info) { + set_charger_online(health_info); + + charger_->OnHealthInfoChanged(ChargerHealthInfo{ + .battery_level = health_info.legacy.legacy.batteryLevel, + .battery_status = static_cast<::aidl::android::hardware::health::BatteryStatus>( + health_info.legacy.legacy.batteryStatus), + }); + + AdjustWakealarmPeriods(charger_online()); +} + +std::optional ChargerHidl::ChargerShouldKeepScreenOn() { + std::optional out_screen_on; + service()->shouldKeepScreenOn([&](Result res, bool screen_on) { + if (res == Result::SUCCESS) { + *out_screen_on = screen_on; + } + }); + return out_screen_on; +} + +} // 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: + KLOG_ERROR("charger", "Unrecognized charger option: %c\n", optopt); + exit(1); + } + } + + android::ChargerHidl charger(GetHealthServiceOrDefault()); + return charger.StartLoop(); +} diff --git a/healthd/healthd_mode_charger_hidl.h b/healthd/healthd_mode_charger_hidl.h new file mode 100644 index 000000000..9e70c5a92 --- /dev/null +++ b/healthd/healthd_mode_charger_hidl.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 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. + */ + +#pragma once + +#include + +#include + +namespace android { + +// An implementation of Charger backed by HIDL implementation. Uses HIDL health +// HAL's HalHealthLoop. +class ChargerHidl : public ::android::ChargerConfigurationInterface, + public ::android::hardware::health::V2_1::implementation::HalHealthLoop { + using HalHealthLoop = ::android::hardware::health::V2_1::implementation::HalHealthLoop; + using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo; + + public: + explicit ChargerHidl(const sp& service); + std::optional ChargerShouldKeepScreenOn() override; + bool ChargerIsOnline() override { return HalHealthLoop::charger_online(); } + void ChargerInitConfig(healthd_config* config) override { return HalHealthLoop::Init(config); } + int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) override { + return HalHealthLoop::RegisterEvent(fd, func, wakeup); + } + // HealthLoop overrides + void Heartbeat() override { charger_->OnHeartbeat(); } + int PrepareToWait() override { return charger_->OnPrepareToWait(); } + void Init(struct healthd_config* config) override { charger_->OnInit(config); } + // HalHealthLoop overrides + void OnHealthInfoChanged(const HealthInfo_2_1& health_info) override; + + private: + sp service_; + std::unique_ptr charger_; +}; + +} // namespace android + +int healthd_charger_main(int argc, char** argv); diff --git a/healthd/healthd_mode_charger_test.cpp b/healthd/healthd_mode_charger_test.cpp index f444f66ad..b7aace302 100644 --- a/healthd/healthd_mode_charger_test.cpp +++ b/healthd/healthd_mode_charger_test.cpp @@ -23,11 +23,12 @@ #include #include #include +#include #include #include #include -#include "healthd_mode_charger.h" +#include "healthd_mode_charger_hidl.h" using android::hardware::Return; using android::hardware::health::InitHealthdConfig; @@ -102,12 +103,12 @@ class MockHealth : public android::hardware::health::V2_1::IHealth { MOCK_METHOD(Return, shouldKeepScreenOn, (shouldKeepScreenOn_cb _hidl_cb)); }; -class TestCharger : public Charger { +class TestCharger : public ChargerHidl { public: // Inherit constructor. - using Charger::Charger; + using ChargerHidl::ChargerHidl; // Expose protected functions to be used in tests. - void Init(struct healthd_config* config) override { Charger::Init(config); } + void Init(struct healthd_config* config) override { ChargerHidl::Init(config); } MOCK_METHOD(int, CreateDisplaySurface, (const std::string& name, GRSurface** surface)); MOCK_METHOD(int, CreateMultiDisplaySurface, (const std::string& name, int* frames, int* fps, GRSurface*** surface)); diff --git a/healthd/healthd_mode_charger.h b/healthd/include_charger/charger/healthd_mode_charger.h similarity index 57% rename from healthd/healthd_mode_charger.h rename to healthd/include_charger/charger/healthd_mode_charger.h index 6f9ae8c0e..a555b0a10 100644 --- a/healthd/healthd_mode_charger.h +++ b/healthd/include_charger/charger/healthd_mode_charger.h @@ -19,11 +19,12 @@ #include #include +#include #include -#include -#include -#include +#include +#include +#include #include "animation.h" @@ -37,22 +38,43 @@ struct key_state { int64_t timestamp; }; -class Charger : public ::android::hardware::health::V2_1::implementation::HalHealthLoop { - public: - using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo; - using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo; +// Health info that interests charger +struct ChargerHealthInfo { + int32_t battery_level; + aidl::android::hardware::health::BatteryStatus battery_status; +}; - Charger(const sp& service); - ~Charger(); +// Configuration interface for charger. This includes: +// - HalHealthLoop APIs that interests charger. +// - configuration values that used to be provided by sysprops +class ChargerConfigurationInterface { + public: + virtual ~ChargerConfigurationInterface() = default; + // HalHealthLoop related APIs + virtual std::optional ChargerShouldKeepScreenOn() = 0; + virtual bool ChargerIsOnline() = 0; + virtual void ChargerInitConfig(healthd_config* config) = 0; + using BoundFunction = + std::function; + virtual int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) = 0; + + // Other configuration values +}; + +// charger UI +class Charger { + public: + explicit Charger(ChargerConfigurationInterface* configuration); + virtual ~Charger(); + + // Hooks for ChargerConfigurationInterface + void OnHeartbeat(); + int OnPrepareToWait(); + // |cookie| is passed to ChargerConfigurationInterface::ChargerInitConfig + void OnInit(struct healthd_config* config); + void OnHealthInfoChanged(const ChargerHealthInfo& health_info); protected: - // HealthLoop overrides. - void Heartbeat() override; - int PrepareToWait() override; - void Init(struct healthd_config* config) override; - // HalHealthLoop overrides - void OnHealthInfoChanged(const HealthInfo_2_1& health_info) override; - // Allowed to be mocked for testing. virtual int CreateDisplaySurface(const std::string& name, GRSurface** surface); virtual int CreateMultiDisplaySurface(const std::string& name, int* frames, int* fps, @@ -83,10 +105,10 @@ class Charger : public ::android::hardware::health::V2_1::implementation::HalHea GRSurface* surf_unknown_ = nullptr; int boot_min_cap_ = 0; - HealthInfo_1_0 health_info_ = {}; + ChargerHealthInfo health_info_ = {}; std::unique_ptr healthd_draw_; std::vector owned_frames_; + + ChargerConfigurationInterface* configuration_; }; } // namespace android - -int healthd_charger_main(int argc, char** argv);