diff --git a/healthd/Android.bp b/healthd/Android.bp index ea5946984..3a71d03e8 100644 --- a/healthd/Android.bp +++ b/healthd/Android.bp @@ -20,38 +20,6 @@ cc_library_static { export_header_lib_headers: ["libhealthd_headers"], } -cc_library_static { - name: "android.hardware.health@2.0-impl", - vendor_available: true, - srcs: [ - "Health.cpp", - "healthd_common.cpp", - ], - - cflags: [ - "-Wall", - "-Werror", - ], - - export_include_dirs: ["include"], - - shared_libs: [ - "libbase", - "libhidlbase", - "libhidltransport", - "libhwbinder", - "liblog", - "libutils", - "libcutils", - "android.hardware.health@2.0", - ], - - static_libs: [ - "libbatterymonitor", - "android.hardware.health@1.0-convert", - ], -} - cc_binary { name: "android.hardware.health@2.0-service", init_rc: ["android.hardware.health@2.0-service.rc"], diff --git a/healthd/Android.mk b/healthd/Android.mk index 63c9d276c..7e58785d6 100644 --- a/healthd/Android.mk +++ b/healthd/Android.mk @@ -48,6 +48,7 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \ LOCAL_STATIC_LIBRARIES := \ android.hardware.health@2.0 \ + android.hardware.health@2.0-impl \ android.hardware.health@1.0 \ libminui \ libpng \ diff --git a/healthd/Health.cpp b/healthd/Health.cpp deleted file mode 100644 index 822f6641a..000000000 --- a/healthd/Health.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#define LOG_TAG "Health" -#include - -#include - -#include - -extern void healthd_battery_update_internal(bool); - -namespace android { -namespace hardware { -namespace health { -namespace V2_0 { -namespace implementation { - -sp Health::instance_; - -Health::Health(struct healthd_config* c) { - // TODO(b/69268160): remove when libhealthd is removed. - healthd_board_init(c); - battery_monitor_ = std::make_unique(); - battery_monitor_->init(c); -} - -// Methods from IHealth follow. -Return Health::registerCallback(const sp& callback) { - if (callback == nullptr) { - return Result::SUCCESS; - } - - { - std::lock_guard _lock(callbacks_lock_); - callbacks_.push_back(callback); - // unlock - } - - auto linkRet = callback->linkToDeath(this, 0u /* cookie */); - if (!linkRet.withDefault(false)) { - LOG(WARNING) << __func__ << "Cannot link to death: " - << (linkRet.isOk() ? "linkToDeath returns false" : linkRet.description()); - // ignore the error - } - - return update(); -} - -bool Health::unregisterCallbackInternal(const sp& callback) { - if (callback == nullptr) return false; - - bool removed = false; - std::lock_guard _lock(callbacks_lock_); - for (auto it = callbacks_.begin(); it != callbacks_.end();) { - if (interfacesEqual(*it, callback)) { - it = callbacks_.erase(it); - removed = true; - } else { - ++it; - } - } - (void)callback->unlinkToDeath(this).isOk(); // ignore errors - return removed; -} - -Return Health::unregisterCallback(const sp& callback) { - return unregisterCallbackInternal(callback) ? Result::SUCCESS : Result::NOT_FOUND; -} - -template -void getProperty(const std::unique_ptr& monitor, int id, T defaultValue, - const std::function& callback) { - struct BatteryProperty prop; - T ret = defaultValue; - Result result = Result::SUCCESS; - status_t err = monitor->getProperty(static_cast(id), &prop); - if (err != OK) { - LOG(DEBUG) << "getProperty(" << id << ")" << " fails: (" << err << ") " << strerror(-err); - } else { - ret = static_cast(prop.valueInt64); - } - switch (err) { - case OK: result = Result::SUCCESS; break; - case NAME_NOT_FOUND: result = Result::NOT_SUPPORTED; break; - default: result = Result::UNKNOWN; break; - } - callback(result, static_cast(ret)); -} - -Return Health::getChargeCounter(getChargeCounter_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_CHARGE_COUNTER, INT32_MIN, _hidl_cb); - return Void(); -} - -Return Health::getCurrentNow(getCurrentNow_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_CURRENT_NOW, INT32_MIN, _hidl_cb); - return Void(); -} - -Return Health::getCurrentAverage(getCurrentAverage_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_CURRENT_AVG, INT32_MIN, _hidl_cb); - return Void(); -} - -Return Health::getCapacity(getCapacity_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_CAPACITY, INT32_MIN, _hidl_cb); - return Void(); -} - -Return Health::getEnergyCounter(getEnergyCounter_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_ENERGY_COUNTER, INT64_MIN, _hidl_cb); - return Void(); -} - -Return Health::getChargeStatus(getChargeStatus_cb _hidl_cb) { - getProperty(battery_monitor_, BATTERY_PROP_BATTERY_STATUS, BatteryStatus::UNKNOWN, _hidl_cb); - return Void(); -} - - -Return Health::update() { - if (!healthd_mode_ops || !healthd_mode_ops->battery_update) { - LOG(WARNING) << "health@2.0: update: not initialized. " - << "update() should not be called in charger / recovery."; - return Result::UNKNOWN; - } - - // Retrieve all information and call healthd_mode_ops->battery_update, which calls - // notifyListeners. - bool chargerOnline = battery_monitor_->update(); - - // adjust uevent / wakealarm periods - healthd_battery_update_internal(chargerOnline); - - return Result::SUCCESS; -} - -void Health::notifyListeners(const HealthInfo& info) { - std::lock_guard _lock(callbacks_lock_); - for (auto it = callbacks_.begin(); it != callbacks_.end();) { - auto ret = (*it)->healthInfoChanged(info); - if (!ret.isOk() && ret.isDeadObject()) { - it = callbacks_.erase(it); - } else { - ++it; - } - } -} - -Return Health::debug(const hidl_handle& handle, const hidl_vec&) { - if (handle != nullptr && handle->numFds >= 1) { - int fd = handle->data[0]; - battery_monitor_->dumpState(fd); - fsync(fd); - } - return Void(); -} - -void Health::serviceDied(uint64_t /* cookie */, const wp& who) { - (void)unregisterCallbackInternal(who.promote()); -} - -sp Health::initInstance(struct healthd_config* c) { - if (instance_ == nullptr) { - instance_ = new Health(c); - } - return instance_; -} - -sp Health::getImplementation() { - CHECK(instance_ != nullptr); - return instance_; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace health -} // namespace hardware -} // namespace android diff --git a/healthd/healthd_common.cpp b/healthd/healthd_common.cpp deleted file mode 100644 index 300664461..000000000 --- a/healthd/healthd_common.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#define LOG_TAG "healthd-common" -#define KLOG_LEVEL 6 - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace android; - -// Periodic chores fast interval in seconds -#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1) -// Periodic chores fast interval in seconds -#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10) - -static struct healthd_config healthd_config = { - .periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST, - .periodic_chores_interval_slow = DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW, - .batteryStatusPath = String8(String8::kEmptyString), - .batteryHealthPath = String8(String8::kEmptyString), - .batteryPresentPath = String8(String8::kEmptyString), - .batteryCapacityPath = String8(String8::kEmptyString), - .batteryVoltagePath = String8(String8::kEmptyString), - .batteryTemperaturePath = String8(String8::kEmptyString), - .batteryTechnologyPath = String8(String8::kEmptyString), - .batteryCurrentNowPath = String8(String8::kEmptyString), - .batteryCurrentAvgPath = String8(String8::kEmptyString), - .batteryChargeCounterPath = String8(String8::kEmptyString), - .batteryFullChargePath = String8(String8::kEmptyString), - .batteryCycleCountPath = String8(String8::kEmptyString), - .energyCounter = NULL, - .boot_min_cap = 0, - .screen_on = NULL, -}; - -static int eventct; -static int epollfd; - -#define POWER_SUPPLY_SUBSYSTEM "power_supply" - -// epoll_create() parameter is actually unused -#define MAX_EPOLL_EVENTS 40 -static int uevent_fd; -static int wakealarm_fd; - -// -1 for no epoll timeout -static int awake_poll_interval = -1; - -static int wakealarm_wake_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST; - -using ::android::hardware::health::V2_0::implementation::Health; - -struct healthd_mode_ops *healthd_mode_ops = nullptr; - -int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) { - struct epoll_event ev; - - ev.events = EPOLLIN; - - if (wakeup == EVENT_WAKEUP_FD) - ev.events |= EPOLLWAKEUP; - - ev.data.ptr = (void *)handler; - if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - KLOG_ERROR(LOG_TAG, - "epoll_ctl failed; errno=%d\n", errno); - return -1; - } - - eventct++; - return 0; -} - -static void wakealarm_set_interval(int interval) { - struct itimerspec itval; - - if (wakealarm_fd == -1) - return; - - wakealarm_wake_interval = interval; - - if (interval == -1) - interval = 0; - - itval.it_interval.tv_sec = interval; - itval.it_interval.tv_nsec = 0; - itval.it_value.tv_sec = interval; - itval.it_value.tv_nsec = 0; - - if (timerfd_settime(wakealarm_fd, 0, &itval, NULL) == -1) - KLOG_ERROR(LOG_TAG, "wakealarm_set_interval: timerfd_settime failed\n"); -} - -void healthd_battery_update_internal(bool charger_online) { - // Fast wake interval when on charger (watch for overheat); - // slow wake interval when on battery (watch for drained battery). - - int new_wake_interval = charger_online ? healthd_config.periodic_chores_interval_fast - : healthd_config.periodic_chores_interval_slow; - - if (new_wake_interval != wakealarm_wake_interval) - wakealarm_set_interval(new_wake_interval); - - // During awake periods poll at fast rate. If wake alarm is set at fast - // rate then just use the alarm; if wake alarm is set at slow rate then - // poll at fast rate while awake and let alarm wake up at slow rate when - // asleep. - - if (healthd_config.periodic_chores_interval_fast == -1) - awake_poll_interval = -1; - else - awake_poll_interval = - new_wake_interval == healthd_config.periodic_chores_interval_fast ? - -1 : healthd_config.periodic_chores_interval_fast * 1000; -} - -static void healthd_battery_update(void) { - Health::getImplementation()->update(); -} - -static void periodic_chores() { - healthd_battery_update(); -} - -#define UEVENT_MSG_LEN 2048 -static void uevent_event(uint32_t /*epevents*/) { - char msg[UEVENT_MSG_LEN+2]; - char *cp; - int n; - - n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN); - if (n <= 0) - return; - if (n >= UEVENT_MSG_LEN) /* overflow -- discard */ - return; - - msg[n] = '\0'; - msg[n+1] = '\0'; - cp = msg; - - while (*cp) { - if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) { - healthd_battery_update(); - break; - } - - /* advance to after the next \0 */ - while (*cp++) - ; - } -} - -static void uevent_init(void) { - uevent_fd = uevent_open_socket(64*1024, true); - - if (uevent_fd < 0) { - KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n"); - return; - } - - fcntl(uevent_fd, F_SETFL, O_NONBLOCK); - if (healthd_register_event(uevent_fd, uevent_event, EVENT_WAKEUP_FD)) - KLOG_ERROR(LOG_TAG, - "register for uevent events failed\n"); -} - -static void wakealarm_event(uint32_t /*epevents*/) { - unsigned long long wakeups; - - if (read(wakealarm_fd, &wakeups, sizeof(wakeups)) == -1) { - KLOG_ERROR(LOG_TAG, "wakealarm_event: read wakealarm fd failed\n"); - return; - } - - periodic_chores(); -} - -static void wakealarm_init(void) { - wakealarm_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK); - if (wakealarm_fd == -1) { - KLOG_ERROR(LOG_TAG, "wakealarm_init: timerfd_create failed\n"); - return; - } - - if (healthd_register_event(wakealarm_fd, wakealarm_event, EVENT_WAKEUP_FD)) - KLOG_ERROR(LOG_TAG, - "Registration of wakealarm event failed\n"); - - wakealarm_set_interval(healthd_config.periodic_chores_interval_fast); -} - -static void healthd_mainloop(void) { - int nevents = 0; - while (1) { - struct epoll_event events[eventct]; - int timeout = awake_poll_interval; - int mode_timeout; - - /* Don't wait for first timer timeout to run periodic chores */ - if (!nevents) - periodic_chores(); - - healthd_mode_ops->heartbeat(); - - mode_timeout = healthd_mode_ops->preparetowait(); - if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout)) - timeout = mode_timeout; - nevents = epoll_wait(epollfd, events, eventct, timeout); - if (nevents == -1) { - if (errno == EINTR) - continue; - KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n"); - break; - } - - for (int n = 0; n < nevents; ++n) { - if (events[n].data.ptr) - (*(void (*)(int))events[n].data.ptr)(events[n].events); - } - } - - return; -} - -static int healthd_init() { - epollfd = epoll_create(MAX_EPOLL_EVENTS); - if (epollfd == -1) { - KLOG_ERROR(LOG_TAG, - "epoll_create failed; errno=%d\n", - errno); - return -1; - } - - healthd_mode_ops->init(&healthd_config); - wakealarm_init(); - uevent_init(); - - return 0; -} - -int healthd_main() { - int ret; - - klog_set_level(KLOG_LEVEL); - - if (!healthd_mode_ops) { - KLOG_ERROR("healthd ops not set, exiting\n"); - exit(1); - } - - ret = healthd_init(); - if (ret) { - KLOG_ERROR("Initialization failed, exiting\n"); - exit(2); - } - - healthd_mainloop(); - KLOG_ERROR("Main loop terminated, exiting\n"); - return 3; -} diff --git a/healthd/include/health2/Health.h b/healthd/include/health2/Health.h deleted file mode 100644 index 012b95bf4..000000000 --- a/healthd/include/health2/Health.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H -#define ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H - -#include -#include - -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace health { -namespace V2_0 { -namespace implementation { - -using V1_0::BatteryStatus; -using V1_0::HealthInfo; - -using ::android::hidl::base::V1_0::IBase; - -struct Health : public IHealth, hidl_death_recipient { - public: - static sp initInstance(struct healthd_config* c); - // Should only be called by implementation itself (-impl, -service). - // Clients should not call this function. Instead, initInstance() initializes and returns the - // global instance that has fewer functions. - // TODO(b/62229583): clean up and hide these functions after update() logic is simplified. - static sp getImplementation(); - - Health(struct healthd_config* c); - - // TODO(b/62229583): clean up and hide these functions after update() logic is simplified. - void notifyListeners(const HealthInfo& info); - - // Methods from IHealth follow. - Return registerCallback(const sp& callback) override; - Return unregisterCallback(const sp& callback) override; - Return update() override; - Return getChargeCounter(getChargeCounter_cb _hidl_cb) override; - Return getCurrentNow(getCurrentNow_cb _hidl_cb) override; - Return getCurrentAverage(getCurrentAverage_cb _hidl_cb) override; - Return getCapacity(getCapacity_cb _hidl_cb) override; - Return getEnergyCounter(getEnergyCounter_cb _hidl_cb) override; - Return getChargeStatus(getChargeStatus_cb _hidl_cb) override; - - // Methods from ::android::hidl::base::V1_0::IBase follow. - Return debug(const hidl_handle& fd, const hidl_vec& args) override; - - void serviceDied(uint64_t cookie, const wp& /* who */) override; - - private: - static sp instance_; - - std::mutex callbacks_lock_; - std::vector> callbacks_; - std::unique_ptr battery_monitor_; - - bool unregisterCallbackInternal(const sp& cb); - -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace health -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H