summaryrefslogtreecommitdiff
path: root/healthd
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2021-10-20 17:15:32 -0700
committerYifan Hong <elsk@google.com>2021-11-01 12:38:56 -0700
commitb5d7033dcc11f2551c64b5033bf59d4a581762f4 (patch)
tree5707b5de426ff529b0ea721873214c4d8d3cd906 /healthd
parent132f2341f9627d21e418801e6378e820afd3c157 (diff)
downloadcore-b5d7033dcc11f2551c64b5033bf59d4a581762f4.tar.gz
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
Diffstat (limited to 'healthd')
-rw-r--r--healthd/Android.bp53
-rw-r--r--healthd/charger.cpp4
-rw-r--r--healthd/charger_test.cpp4
-rw-r--r--healthd/healthd_mode_charger.cpp91
-rw-r--r--healthd/healthd_mode_charger_hidl.cpp76
-rw-r--r--healthd/healthd_mode_charger_hidl.h54
-rw-r--r--healthd/healthd_mode_charger_test.cpp9
-rw-r--r--healthd/include_charger/charger/healthd_mode_charger.h (renamed from healthd/healthd_mode_charger.h)58
8 files changed, 253 insertions, 96 deletions
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 <android-base/logging.h>
+#include <charger.sysprop.h>
-#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 <health/utils.h>
#include <health2impl/Health.h>
-#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<IHealth> 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 <charger/healthd_mode_charger.h>
#include <dirent.h>
#include <errno.h>
@@ -51,26 +51,16 @@
#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 <aidl/android/hardware/health/BatteryStatus.h>
+#include <health/HealthLoop.h>
#include <healthd/healthd.h>
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<IHealth>& 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<bool> out_screen_on;
- service()->shouldKeepScreenOn([&](Result res, bool screen_on) {
- if (res == Result::SUCCESS) {
- *out_screen_on = screen_on;
- }
- });
+ std::optional<bool> 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 <android/hardware/health/2.0/types.h>
+#include <cutils/klog.h>
+
+#include "charger_utils.h"
+
+using android::hardware::health::GetHealthServiceOrDefault;
+using android::hardware::health::V2_0::Result;
+
+namespace android {
+
+ChargerHidl::ChargerHidl(const sp<android::hardware::health::V2_1::IHealth>& service)
+ : HalHealthLoop("charger", service), charger_(std::make_unique<Charger>(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<bool> ChargerHidl::ChargerShouldKeepScreenOn() {
+ std::optional<bool> 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 <health2impl/HalHealthLoop.h>
+
+#include <charger/healthd_mode_charger.h>
+
+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<android::hardware::health::V2_1::IHealth>& service);
+ std::optional<bool> 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<android::hardware::health::V2_1::IHealth> service_;
+ std::unique_ptr<Charger> 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 <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
+#include <android/hardware/health/2.1/IHealth.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <health/utils.h>
-#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<void>, 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
index 6f9ae8c0e..a555b0a10 100644
--- a/healthd/healthd_mode_charger.h
+++ b/healthd/include_charger/charger/healthd_mode_charger.h
@@ -19,11 +19,12 @@
#include <linux/input.h>
#include <memory>
+#include <optional>
#include <vector>
-#include <android/hardware/health/2.0/IHealthInfoCallback.h>
-#include <android/hardware/health/2.1/IHealth.h>
-#include <health2impl/HalHealthLoop.h>
+#include <aidl/android/hardware/health/BatteryStatus.h>
+#include <health/HealthLoop.h>
+#include <healthd/healthd.h>
#include "animation.h"
@@ -37,22 +38,43 @@ struct key_state {
int64_t timestamp;
};
-class Charger : public ::android::hardware::health::V2_1::implementation::HalHealthLoop {
+// Health info that interests charger
+struct ChargerHealthInfo {
+ int32_t battery_level;
+ aidl::android::hardware::health::BatteryStatus battery_status;
+};
+
+// 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<bool> ChargerShouldKeepScreenOn() = 0;
+ virtual bool ChargerIsOnline() = 0;
+ virtual void ChargerInitConfig(healthd_config* config) = 0;
+ using BoundFunction =
+ std::function<void(android::hardware::health::HealthLoop*, uint32_t /* epevents */)>;
+ virtual int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) = 0;
+
+ // Other configuration values
+};
+
+// charger UI
+class Charger {
public:
- using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
- using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
+ explicit Charger(ChargerConfigurationInterface* configuration);
+ virtual ~Charger();
- Charger(const sp<android::hardware::health::V2_1::IHealth>& service);
- ~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<HealthdDraw> healthd_draw_;
std::vector<animation::frame> owned_frames_;
+
+ ChargerConfigurationInterface* configuration_;
};
} // namespace android
-
-int healthd_charger_main(int argc, char** argv);