Merge "health: Remove 2.0 HAL implementation." into main
This commit is contained in:
commit
7535e95430
14 changed files with 10 additions and 1078 deletions
|
@ -1,181 +1,7 @@
|
|||
# Implement the 2.1 HAL instead!
|
||||
# Deprecated.
|
||||
|
||||
It is strongly recommended that you implement the 2.1 HAL directly. See
|
||||
`hardware/interfaces/health/2.1/README.md` for more details.
|
||||
Health HIDL HAL 2.0 is deprecated and subject to removal. Please
|
||||
implement the Health AIDL HAL instead.
|
||||
|
||||
# Upgrading from Health 1.0 HAL
|
||||
|
||||
1. Remove `android.hardware.health@1.0*` from `PRODUCT_PACKAGES`
|
||||
in `device/<manufacturer>/<device>/device.mk`
|
||||
|
||||
1. If the device does not have a vendor-specific `libhealthd` AND does not
|
||||
implement storage-related APIs, just do the following:
|
||||
|
||||
```mk
|
||||
PRODUCT_PACKAGES += android.hardware.health@2.0-service
|
||||
```
|
||||
|
||||
Otherwise, continue to the next step.
|
||||
|
||||
1. Create directory
|
||||
`device/<manufacturer>/<device>/health`
|
||||
|
||||
1. Create `device/<manufacturer>/<device>/health/Android.bp`
|
||||
(or equivalent `device/<manufacturer>/<device>/health/Android.mk`)
|
||||
|
||||
```bp
|
||||
cc_binary {
|
||||
name: "android.hardware.health@2.0-service.<device>",
|
||||
init_rc: ["android.hardware.health@2.0-service.<device>.rc"],
|
||||
proprietary: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: [
|
||||
"HealthService.cpp",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"android.hardware.health@2.0-impl",
|
||||
"android.hardware.health@1.0-convert",
|
||||
"libhealthservice",
|
||||
"libbatterymonitor",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
"android.hardware.health@2.0",
|
||||
],
|
||||
|
||||
header_libs: ["libhealthd_headers"],
|
||||
|
||||
overrides: [
|
||||
"healthd",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
1. (recommended) To remove `healthd` from the build, keep "overrides" section.
|
||||
1. To keep `healthd` in the build, remove "overrides" section.
|
||||
|
||||
1. Create `device/<manufacturer>/<device>/health/android.hardware.health@2.0-service.<device>.rc`
|
||||
|
||||
```rc
|
||||
service vendor.health-hal-2-0 /vendor/bin/hw/android.hardware.health@2.0-service.<device>
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
capabilities WAKE_ALARM
|
||||
file /dev/kmsg w
|
||||
```
|
||||
|
||||
1. Create `device/<manufacturer>/<device>/health/HealthService.cpp`:
|
||||
|
||||
```c++
|
||||
#include <health2/service.h>
|
||||
int main() { return health_service_main(); }
|
||||
```
|
||||
|
||||
1. `libhealthd` dependency:
|
||||
|
||||
1. If the device has a vendor-specific `libhealthd.<soc>`, add it to static_libs.
|
||||
|
||||
1. If the device does not have a vendor-specific `libhealthd`, add the following
|
||||
lines to `HealthService.cpp`:
|
||||
|
||||
```c++
|
||||
#include <healthd/healthd.h>
|
||||
void healthd_board_init(struct healthd_config*) {}
|
||||
|
||||
int healthd_board_battery_update(struct android::BatteryProperties*) {
|
||||
// return 0 to log periodic polled battery status to kernel log
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
1. Storage related APIs:
|
||||
|
||||
1. If the device does not implement `IHealth.getDiskStats` and
|
||||
`IHealth.getStorageInfo`, add `libhealthstoragedefault` to `static_libs`.
|
||||
|
||||
1. If the device implements one of these two APIs, add and implement the
|
||||
following functions in `HealthService.cpp`:
|
||||
|
||||
```c++
|
||||
void get_storage_info(std::vector<struct StorageInfo>& info) {
|
||||
// ...
|
||||
}
|
||||
void get_disk_stats(std::vector<struct DiskStats>& stats) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
1. Update necessary SELinux permissions. For example,
|
||||
|
||||
```
|
||||
# device/<manufacturer>/<device>/sepolicy/vendor/file_contexts
|
||||
/vendor/bin/hw/android\.hardware\.health@2\.0-service\.<device> u:object_r:hal_health_default_exec:s0
|
||||
|
||||
# device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te
|
||||
# Add device specific permissions to hal_health_default domain, especially
|
||||
# if a device-specific libhealthd is used and/or device-specific storage related
|
||||
# APIs are implemented.
|
||||
```
|
||||
|
||||
1. Implementing health HAL in recovery. The health HAL is used for battery
|
||||
status checks during OTA for non-A/B devices. If the health HAL is not
|
||||
implemented in recovery, `is_battery_ok()` will always return `true`.
|
||||
|
||||
1. If the device does not have a vendor-specific `libhealthd`, nothing needs to
|
||||
be done. A "backup" implementation is provided in
|
||||
`android.hardware.health@2.0-impl-default`, which is always installed to recovery
|
||||
image by default.
|
||||
|
||||
1. If the device does have a vendor-specific `libhealthd`, implement the following
|
||||
module and include it in `PRODUCT_PACKAGES` (replace `<device>` with appropriate
|
||||
strings):
|
||||
|
||||
```bp
|
||||
// Android.bp
|
||||
cc_library_shared {
|
||||
name: "android.hardware.health@2.0-impl-<device>",
|
||||
recovery_available: true,
|
||||
relative_install_path: "hw",
|
||||
static_libs: [
|
||||
"android.hardware.health@2.0-impl",
|
||||
"libhealthd.<device>"
|
||||
// Include the following or implement device-specific storage APIs
|
||||
"libhealthstoragedefault",
|
||||
],
|
||||
srcs: [
|
||||
"HealthImpl.cpp",
|
||||
],
|
||||
overrides: [
|
||||
"android.hardware.health@2.0-impl-default",
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
```c++
|
||||
// HealthImpl.cpp
|
||||
#include <health2/Health.h>
|
||||
#include <healthd/healthd.h>
|
||||
using android::hardware::health::V2_0::IHealth;
|
||||
using android::hardware::health::V2_0::implementation::Health;
|
||||
extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) {
|
||||
const static std::string providedInstance{"default"};
|
||||
if (providedInstance != name) return nullptr;
|
||||
return Health::initInstance(&gHealthdConfig).get();
|
||||
}
|
||||
```
|
||||
|
||||
```mk
|
||||
# device.mk
|
||||
PRODUCT_PACKAGES += android.hardware.health@2.0-impl-<device>
|
||||
```
|
||||
See [`hardware/interfaces/health/aidl/README.md`](../aidl/README.md) for
|
||||
details.
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "android.hardware.health@2.0-impl_defaults",
|
||||
|
||||
recovery_available: true,
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libhidlbase",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libcutils",
|
||||
"android.hardware.health@2.0",
|
||||
],
|
||||
|
||||
static_libs: [
|
||||
"libbatterymonitor",
|
||||
"android.hardware.health@1.0-convert",
|
||||
],
|
||||
}
|
||||
|
||||
// Helper library for implementing health HAL. It is recommended that a health
|
||||
// service or passthrough HAL link to this library.
|
||||
cc_library_static {
|
||||
name: "android.hardware.health@2.0-impl",
|
||||
defaults: ["android.hardware.health@2.0-impl_defaults"],
|
||||
|
||||
vendor_available: true,
|
||||
srcs: [
|
||||
"Health.cpp",
|
||||
"healthd_common_adapter.cpp",
|
||||
],
|
||||
|
||||
whole_static_libs: [
|
||||
"libhealthloop",
|
||||
],
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
}
|
||||
|
||||
// Default passthrough implementation for recovery. Vendors can implement
|
||||
// android.hardware.health@2.0-impl-recovery-<device> to customize the behavior
|
||||
// of the HAL in recovery.
|
||||
// The implementation does NOT start the uevent loop for polling.
|
||||
cc_library_shared {
|
||||
name: "android.hardware.health@2.0-impl-default",
|
||||
defaults: ["android.hardware.health@2.0-impl_defaults"],
|
||||
|
||||
recovery_available: true,
|
||||
relative_install_path: "hw",
|
||||
|
||||
static_libs: [
|
||||
"android.hardware.health@2.0-impl",
|
||||
"libhealthstoragedefault",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"HealthImplDefault.cpp",
|
||||
],
|
||||
}
|
|
@ -1,306 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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 "android.hardware.health@2.0-impl"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android/hardware/health/2.0/types.h>
|
||||
#include <health2/Health.h>
|
||||
|
||||
#include <hal_conversion.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
|
||||
using android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
|
||||
|
||||
extern void healthd_battery_update_internal(bool);
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace health {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
sp<Health> 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<BatteryMonitor>();
|
||||
battery_monitor_->init(c);
|
||||
}
|
||||
|
||||
// Methods from IHealth follow.
|
||||
Return<Result> Health::registerCallback(const sp<IHealthInfoCallback>& callback) {
|
||||
if (callback == nullptr) {
|
||||
return Result::SUCCESS;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<decltype(callbacks_lock_)> 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 updateAndNotify(callback);
|
||||
}
|
||||
|
||||
bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
|
||||
if (callback == nullptr) return false;
|
||||
|
||||
bool removed = false;
|
||||
std::lock_guard<decltype(callbacks_lock_)> 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<Result> Health::unregisterCallback(const sp<IHealthInfoCallback>& callback) {
|
||||
return unregisterCallbackInternal(callback) ? Result::SUCCESS : Result::NOT_FOUND;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void getProperty(const std::unique_ptr<BatteryMonitor>& monitor, int id, T defaultValue,
|
||||
const std::function<void(Result, T)>& callback) {
|
||||
struct BatteryProperty prop;
|
||||
T ret = defaultValue;
|
||||
Result result = Result::SUCCESS;
|
||||
status_t err = monitor->getProperty(static_cast<int>(id), &prop);
|
||||
if (err != OK) {
|
||||
LOG(DEBUG) << "getProperty(" << id << ")"
|
||||
<< " fails: (" << err << ") " << strerror(-err);
|
||||
} else {
|
||||
ret = static_cast<T>(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<T>(ret));
|
||||
}
|
||||
|
||||
Return<void> Health::getChargeCounter(getChargeCounter_cb _hidl_cb) {
|
||||
getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CHARGE_COUNTER, 0, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getCurrentNow(getCurrentNow_cb _hidl_cb) {
|
||||
getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CURRENT_NOW, 0, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getCurrentAverage(getCurrentAverage_cb _hidl_cb) {
|
||||
getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CURRENT_AVG, 0, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getCapacity(getCapacity_cb _hidl_cb) {
|
||||
getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CAPACITY, 0, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getEnergyCounter(getEnergyCounter_cb _hidl_cb) {
|
||||
getProperty<int64_t>(battery_monitor_, BATTERY_PROP_ENERGY_COUNTER, 0, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getChargeStatus(getChargeStatus_cb _hidl_cb) {
|
||||
getProperty(battery_monitor_, BATTERY_PROP_BATTERY_STATUS, BatteryStatus::UNKNOWN, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> 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";
|
||||
return Result::UNKNOWN;
|
||||
}
|
||||
|
||||
// Retrieve all information and call healthd_mode_ops->battery_update, which calls
|
||||
// notifyListeners.
|
||||
battery_monitor_->updateValues();
|
||||
const HealthInfo_1_0& health_info = battery_monitor_->getHealthInfo_1_0();
|
||||
struct BatteryProperties props;
|
||||
convertFromHealthInfo(health_info, &props);
|
||||
bool log = (healthd_board_battery_update(&props) == 0);
|
||||
if (log) {
|
||||
battery_monitor_->logValues();
|
||||
}
|
||||
healthd_mode_ops->battery_update(&props);
|
||||
bool chargerOnline = battery_monitor_->isChargerOnline();
|
||||
|
||||
// adjust uevent / wakealarm periods
|
||||
healthd_battery_update_internal(chargerOnline);
|
||||
|
||||
return Result::SUCCESS;
|
||||
}
|
||||
|
||||
Return<Result> Health::updateAndNotify(const sp<IHealthInfoCallback>& callback) {
|
||||
std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
|
||||
std::vector<sp<IHealthInfoCallback>> storedCallbacks{std::move(callbacks_)};
|
||||
callbacks_.clear();
|
||||
if (callback != nullptr) {
|
||||
callbacks_.push_back(callback);
|
||||
}
|
||||
Return<Result> result = update();
|
||||
callbacks_ = std::move(storedCallbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Health::notifyListeners(HealthInfo* healthInfo) {
|
||||
std::vector<StorageInfo> info;
|
||||
get_storage_info(info);
|
||||
|
||||
std::vector<DiskStats> stats;
|
||||
get_disk_stats(stats);
|
||||
|
||||
int32_t currentAvg = 0;
|
||||
|
||||
struct BatteryProperty prop;
|
||||
status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
|
||||
if (ret == OK) {
|
||||
currentAvg = static_cast<int32_t>(prop.valueInt64);
|
||||
}
|
||||
|
||||
healthInfo->batteryCurrentAverage = currentAvg;
|
||||
healthInfo->diskStats = stats;
|
||||
healthInfo->storageInfos = info;
|
||||
|
||||
std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
|
||||
for (auto it = callbacks_.begin(); it != callbacks_.end();) {
|
||||
auto ret = (*it)->healthInfoChanged(*healthInfo);
|
||||
if (!ret.isOk() && ret.isDeadObject()) {
|
||||
it = callbacks_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Return<void> Health::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
|
||||
if (handle != nullptr && handle->numFds >= 1) {
|
||||
int fd = handle->data[0];
|
||||
battery_monitor_->dumpState(fd);
|
||||
|
||||
getHealthInfo([fd](auto res, const auto& info) {
|
||||
android::base::WriteStringToFd("\ngetHealthInfo -> ", fd);
|
||||
if (res == Result::SUCCESS) {
|
||||
android::base::WriteStringToFd(toString(info), fd);
|
||||
} else {
|
||||
android::base::WriteStringToFd(toString(res), fd);
|
||||
}
|
||||
android::base::WriteStringToFd("\n", fd);
|
||||
});
|
||||
|
||||
fsync(fd);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getStorageInfo(getStorageInfo_cb _hidl_cb) {
|
||||
std::vector<struct StorageInfo> info;
|
||||
get_storage_info(info);
|
||||
hidl_vec<struct StorageInfo> info_vec(info);
|
||||
if (!info.size()) {
|
||||
_hidl_cb(Result::NOT_SUPPORTED, info_vec);
|
||||
} else {
|
||||
_hidl_cb(Result::SUCCESS, info_vec);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getDiskStats(getDiskStats_cb _hidl_cb) {
|
||||
std::vector<struct DiskStats> stats;
|
||||
get_disk_stats(stats);
|
||||
hidl_vec<struct DiskStats> stats_vec(stats);
|
||||
if (!stats.size()) {
|
||||
_hidl_cb(Result::NOT_SUPPORTED, stats_vec);
|
||||
} else {
|
||||
_hidl_cb(Result::SUCCESS, stats_vec);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Health::getHealthInfo(getHealthInfo_cb _hidl_cb) {
|
||||
using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
|
||||
|
||||
updateAndNotify(nullptr);
|
||||
HealthInfo healthInfo = battery_monitor_->getHealthInfo_2_0();
|
||||
|
||||
std::vector<StorageInfo> info;
|
||||
get_storage_info(info);
|
||||
|
||||
std::vector<DiskStats> stats;
|
||||
get_disk_stats(stats);
|
||||
|
||||
int32_t currentAvg = 0;
|
||||
|
||||
struct BatteryProperty prop;
|
||||
status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
|
||||
if (ret == OK) {
|
||||
currentAvg = static_cast<int32_t>(prop.valueInt64);
|
||||
}
|
||||
|
||||
healthInfo.batteryCurrentAverage = currentAvg;
|
||||
healthInfo.diskStats = stats;
|
||||
healthInfo.storageInfos = info;
|
||||
|
||||
_hidl_cb(Result::SUCCESS, healthInfo);
|
||||
return Void();
|
||||
}
|
||||
|
||||
void Health::serviceDied(uint64_t /* cookie */, const wp<IBase>& who) {
|
||||
(void)unregisterCallbackInternal(who.promote());
|
||||
}
|
||||
|
||||
sp<IHealth> Health::initInstance(struct healthd_config* c) {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new Health(c);
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
sp<Health> Health::getImplementation() {
|
||||
CHECK(instance_ != nullptr);
|
||||
return instance_;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace health
|
||||
} // namespace hardware
|
||||
} // namespace android
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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 <health2/Health.h>
|
||||
#include <healthd/healthd.h>
|
||||
|
||||
using android::hardware::health::V2_0::IHealth;
|
||||
using android::hardware::health::V2_0::implementation::Health;
|
||||
|
||||
static struct healthd_config gHealthdConfig = {
|
||||
.energyCounter = nullptr,
|
||||
.boot_min_cap = 0,
|
||||
.screen_on = nullptr};
|
||||
|
||||
void healthd_board_init(struct healthd_config*) {
|
||||
// use defaults
|
||||
}
|
||||
|
||||
int healthd_board_battery_update(struct android::BatteryProperties*) {
|
||||
// return 0 to log periodic polled battery status to kernel log
|
||||
return 0;
|
||||
}
|
||||
|
||||
void healthd_mode_default_impl_init(struct healthd_config*) {
|
||||
// noop
|
||||
}
|
||||
|
||||
int healthd_mode_default_impl_preparetowait(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void healthd_mode_default_impl_heartbeat(void) {
|
||||
// noop
|
||||
}
|
||||
|
||||
void healthd_mode_default_impl_battery_update(struct android::BatteryProperties*) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static struct healthd_mode_ops healthd_mode_default_impl_ops = {
|
||||
.init = healthd_mode_default_impl_init,
|
||||
.preparetowait = healthd_mode_default_impl_preparetowait,
|
||||
.heartbeat = healthd_mode_default_impl_heartbeat,
|
||||
.battery_update = healthd_mode_default_impl_battery_update,
|
||||
};
|
||||
|
||||
extern "C" IHealth* HIDL_FETCH_IHealth(const char* name) {
|
||||
const static std::string providedInstance{"backup"};
|
||||
healthd_mode_ops = &healthd_mode_default_impl_ops;
|
||||
if (providedInstance == name) {
|
||||
// use defaults
|
||||
// Health class stores static instance
|
||||
return Health::initInstance(&gHealthdConfig).get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
// Support legacy functions in healthd/healthd.h using healthd_mode_ops.
|
||||
// New code should use HealthLoop directly instead.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <cutils/klog.h>
|
||||
#include <health/HealthLoop.h>
|
||||
#include <health2/Health.h>
|
||||
#include <healthd/healthd.h>
|
||||
|
||||
using android::hardware::health::HealthLoop;
|
||||
using android::hardware::health::V2_0::implementation::Health;
|
||||
|
||||
struct healthd_mode_ops* healthd_mode_ops = nullptr;
|
||||
|
||||
// Adapter of HealthLoop to use legacy healthd_mode_ops.
|
||||
class HealthLoopAdapter : public HealthLoop {
|
||||
public:
|
||||
// Expose internal functions, assuming clients calls them in the same thread
|
||||
// where StartLoop is called.
|
||||
int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
|
||||
return HealthLoop::RegisterEvent(fd, func, wakeup);
|
||||
}
|
||||
void AdjustWakealarmPeriods(bool charger_online) {
|
||||
return HealthLoop::AdjustWakealarmPeriods(charger_online);
|
||||
}
|
||||
protected:
|
||||
void Init(healthd_config* config) override { healthd_mode_ops->init(config); }
|
||||
void Heartbeat() override { healthd_mode_ops->heartbeat(); }
|
||||
int PrepareToWait() override { return healthd_mode_ops->preparetowait(); }
|
||||
void ScheduleBatteryUpdate() override { Health::getImplementation()->update(); }
|
||||
};
|
||||
static std::unique_ptr<HealthLoopAdapter> health_loop;
|
||||
|
||||
int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
|
||||
if (!health_loop) return -1;
|
||||
|
||||
auto wrapped_handler = [handler](auto*, uint32_t epevents) { handler(epevents); };
|
||||
return health_loop->RegisterEvent(fd, wrapped_handler, wakeup);
|
||||
}
|
||||
|
||||
void healthd_battery_update_internal(bool charger_online) {
|
||||
if (!health_loop) return;
|
||||
health_loop->AdjustWakealarmPeriods(charger_online);
|
||||
}
|
||||
|
||||
int healthd_main() {
|
||||
if (!healthd_mode_ops) {
|
||||
KLOG_ERROR("healthd ops not set, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
health_loop = std::make_unique<HealthLoopAdapter>();
|
||||
|
||||
int ret = health_loop->StartLoop();
|
||||
|
||||
// Should not reach here. The following will exit().
|
||||
health_loop.reset();
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
#ifndef ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
|
||||
#define ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <android/hardware/health/1.0/types.h>
|
||||
#include <android/hardware/health/2.0/IHealth.h>
|
||||
#include <healthd/BatteryMonitor.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
using android::hardware::health::V2_0::StorageInfo;
|
||||
using android::hardware::health::V2_0::DiskStats;
|
||||
|
||||
void get_storage_info(std::vector<struct StorageInfo>& info);
|
||||
void get_disk_stats(std::vector<struct DiskStats>& stats);
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace health {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using V1_0::BatteryStatus;
|
||||
|
||||
using ::android::hidl::base::V1_0::IBase;
|
||||
|
||||
struct Health : public IHealth, hidl_death_recipient {
|
||||
public:
|
||||
static sp<IHealth> 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.
|
||||
static sp<Health> getImplementation();
|
||||
|
||||
Health(struct healthd_config* c);
|
||||
|
||||
void notifyListeners(HealthInfo* info);
|
||||
|
||||
// Methods from IHealth follow.
|
||||
Return<Result> registerCallback(const sp<IHealthInfoCallback>& callback) override;
|
||||
Return<Result> unregisterCallback(const sp<IHealthInfoCallback>& callback) override;
|
||||
Return<Result> update() override;
|
||||
Return<void> getChargeCounter(getChargeCounter_cb _hidl_cb) override;
|
||||
Return<void> getCurrentNow(getCurrentNow_cb _hidl_cb) override;
|
||||
Return<void> getCurrentAverage(getCurrentAverage_cb _hidl_cb) override;
|
||||
Return<void> getCapacity(getCapacity_cb _hidl_cb) override;
|
||||
Return<void> getEnergyCounter(getEnergyCounter_cb _hidl_cb) override;
|
||||
Return<void> getChargeStatus(getChargeStatus_cb _hidl_cb) override;
|
||||
Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override;
|
||||
Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override;
|
||||
Return<void> getHealthInfo(getHealthInfo_cb _hidl_cb) override;
|
||||
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
|
||||
|
||||
void serviceDied(uint64_t cookie, const wp<IBase>& /* who */) override;
|
||||
|
||||
private:
|
||||
static sp<Health> instance_;
|
||||
|
||||
std::recursive_mutex callbacks_lock_;
|
||||
std::vector<sp<IHealthInfoCallback>> callbacks_;
|
||||
std::unique_ptr<BatteryMonitor> battery_monitor_;
|
||||
|
||||
bool unregisterCallbackInternal(const sp<IBase>& cb);
|
||||
|
||||
// update() and only notify the given callback, but none of the other callbacks.
|
||||
// If cb is null, do not notify any callback at all.
|
||||
Return<Result> updateAndNotify(const sp<IHealthInfoCallback>& cb);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace health
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H
|
|
@ -6,25 +6,3 @@ by healthd). C++ clients of health HAL should use this library instead of
|
|||
calling `IHealth::getService()` directly.
|
||||
|
||||
Its Java equivalent can be found in `BatteryService.HealthServiceWrapper`.
|
||||
|
||||
# libhealthservice
|
||||
|
||||
Common code for all (hwbinder) services of the health HAL, including healthd and
|
||||
vendor health service `android.hardware.health@2.0-service(.<vendor>)`. `main()` in
|
||||
those binaries calls `health_service_main()` directly.
|
||||
|
||||
# libhealthstoragedefault
|
||||
|
||||
Default implementation for storage related APIs for (hwbinder) services of the
|
||||
health HAL. If an implementation of the health HAL do not wish to provide any
|
||||
storage info, include this library. Otherwise, it should implement the following
|
||||
two functions:
|
||||
|
||||
```c++
|
||||
void get_storage_info(std::vector<struct StorageInfo>& info) {
|
||||
// ...
|
||||
}
|
||||
void get_disk_stats(std::vector<struct DiskStats>& stats) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
|
|
@ -24,34 +24,14 @@ namespace hardware {
|
|||
namespace health {
|
||||
namespace V2_0 {
|
||||
|
||||
// Deprecated. Kept to minimize migration cost.
|
||||
// The function can be removed once Health 2.1 is removed
|
||||
// (i.e. compatibility_matrix.7.xml is the lowest supported level).
|
||||
sp<IHealth> get_health_service() {
|
||||
// For the core and vendor variant, the "backup" instance points to healthd,
|
||||
// which is removed.
|
||||
// For the recovery variant, the "backup" instance has a different
|
||||
// meaning. It points to android.hardware.health@2.0-impl-default.recovery
|
||||
// which was assumed by OEMs to be always installed when a
|
||||
// vendor-specific libhealthd is not necessary. Hence, its behavior
|
||||
// is kept. See health/2.0/README.md.
|
||||
// android.hardware.health@2.0-impl-default.recovery, and subsequently the
|
||||
// special handling of recovery mode below, can be removed once health@2.1
|
||||
// is the minimum required version (i.e. compatibility matrix level 5 is the
|
||||
// minimum supported level). Health 2.1 requires OEMs to install the
|
||||
// Health 2.1 requires OEMs to install the
|
||||
// implementation to the recovery partition when it is necessary (i.e. on
|
||||
// non-A/B devices, where IsBatteryOk() is needed in recovery).
|
||||
for (auto&& instanceName :
|
||||
#ifdef __ANDROID_RECOVERY__
|
||||
{ "default", "backup" }
|
||||
#else
|
||||
{"default"}
|
||||
#endif
|
||||
) {
|
||||
auto ret = IHealth::getService(instanceName);
|
||||
if (ret != nullptr) {
|
||||
return ret;
|
||||
}
|
||||
LOG(INFO) << "health: cannot get " << instanceName << " service";
|
||||
}
|
||||
return nullptr;
|
||||
return IHealth::getService();
|
||||
}
|
||||
|
||||
} // namespace V2_0
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// Reasonable defaults for android.hardware.health@2.0-service.<device>.
|
||||
// Vendor service can customize by implementing functions defined in
|
||||
// libhealthd and libhealthstoragedefault.
|
||||
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libhealthservice",
|
||||
vendor_available: true,
|
||||
srcs: ["HealthServiceCommon.cpp"],
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.health@2.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.health@2.0-impl",
|
||||
"android.hardware.health@1.0-convert",
|
||||
],
|
||||
export_static_lib_headers: [
|
||||
"android.hardware.health@1.0-convert",
|
||||
],
|
||||
header_libs: ["libhealthd_headers"],
|
||||
export_header_lib_headers: ["libhealthd_headers"],
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "health@2.0/"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/health/1.0/types.h>
|
||||
#include <hal_conversion.h>
|
||||
#include <health2/Health.h>
|
||||
#include <health2/service.h>
|
||||
#include <healthd/healthd.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <hwbinder/IPCThreadState.h>
|
||||
|
||||
using android::hardware::IPCThreadState;
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::handleTransportPoll;
|
||||
using android::hardware::setupTransportPolling;
|
||||
using android::hardware::health::V2_0::HealthInfo;
|
||||
using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
|
||||
using android::hardware::health::V2_0::IHealth;
|
||||
using android::hardware::health::V2_0::implementation::Health;
|
||||
|
||||
extern int healthd_main(void);
|
||||
|
||||
static int gBinderFd = -1;
|
||||
static std::string gInstanceName;
|
||||
|
||||
static void binder_event(uint32_t /*epevents*/) {
|
||||
if (gBinderFd >= 0) handleTransportPoll(gBinderFd);
|
||||
}
|
||||
|
||||
void healthd_mode_service_2_0_init(struct healthd_config* config) {
|
||||
LOG(INFO) << LOG_TAG << gInstanceName << " Hal is starting up...";
|
||||
|
||||
gBinderFd = setupTransportPolling();
|
||||
|
||||
if (gBinderFd >= 0) {
|
||||
if (healthd_register_event(gBinderFd, binder_event))
|
||||
LOG(ERROR) << LOG_TAG << gInstanceName << ": Register for binder events failed";
|
||||
}
|
||||
|
||||
android::sp<IHealth> service = Health::initInstance(config);
|
||||
CHECK_EQ(service->registerAsService(gInstanceName), android::OK)
|
||||
<< LOG_TAG << gInstanceName << ": Failed to register HAL";
|
||||
|
||||
LOG(INFO) << LOG_TAG << gInstanceName << ": Hal init done";
|
||||
}
|
||||
|
||||
int healthd_mode_service_2_0_preparetowait(void) {
|
||||
IPCThreadState::self()->flushCommands();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void healthd_mode_service_2_0_heartbeat(void) {
|
||||
// noop
|
||||
}
|
||||
|
||||
void healthd_mode_service_2_0_battery_update(struct android::BatteryProperties* prop) {
|
||||
HealthInfo info;
|
||||
convertToHealthInfo(prop, info.legacy);
|
||||
Health::getImplementation()->notifyListeners(&info);
|
||||
}
|
||||
|
||||
static struct healthd_mode_ops healthd_mode_service_2_0_ops = {
|
||||
.init = healthd_mode_service_2_0_init,
|
||||
.preparetowait = healthd_mode_service_2_0_preparetowait,
|
||||
.heartbeat = healthd_mode_service_2_0_heartbeat,
|
||||
.battery_update = healthd_mode_service_2_0_battery_update,
|
||||
};
|
||||
|
||||
int health_service_main(const char* instance) {
|
||||
gInstanceName = instance;
|
||||
if (gInstanceName.empty()) {
|
||||
gInstanceName = "default";
|
||||
}
|
||||
healthd_mode_ops = &healthd_mode_service_2_0_ops;
|
||||
LOG(INFO) << LOG_TAG << gInstanceName << ": Hal starting main loop...";
|
||||
return healthd_main();
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright 2018 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
|
||||
#define ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
|
||||
|
||||
int health_service_main(const char* instance = "");
|
||||
|
||||
#endif // ANDROID_HARDWARE_HEALTH_V2_0_SERVICE_COMMON
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
// Default implementation for (passthrough) clients that statically links to
|
||||
// android.hardware.health@2.0-impl but do no query for storage related
|
||||
// information.
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
srcs: ["StorageHealthDefault.cpp"],
|
||||
name: "libhealthstoragedefault",
|
||||
vendor_available: true,
|
||||
recovery_available: true,
|
||||
cflags: ["-Werror"],
|
||||
shared_libs: [
|
||||
"android.hardware.health@2.0",
|
||||
],
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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 "include/StorageHealthDefault.h"
|
||||
|
||||
void get_storage_info(std::vector<struct StorageInfo>&) {
|
||||
// Use defaults.
|
||||
}
|
||||
|
||||
void get_disk_stats(std::vector<struct DiskStats>&) {
|
||||
// Use defaults
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
|
||||
#define ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
|
||||
|
||||
#include <android/hardware/health/2.0/types.h>
|
||||
|
||||
using android::hardware::health::V2_0::StorageInfo;
|
||||
using android::hardware::health::V2_0::DiskStats;
|
||||
|
||||
/*
|
||||
* Get storage information.
|
||||
*/
|
||||
void get_storage_info(std::vector<struct StorageInfo>& info);
|
||||
|
||||
/*
|
||||
* Get disk statistics.
|
||||
*/
|
||||
void get_disk_stats(std::vector<struct DiskStats>& stats);
|
||||
|
||||
#endif // ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
|
Loading…
Reference in a new issue