From 3a66fa178fdeb6cf1c958d6b76537cf75f8d3e7a Mon Sep 17 00:00:00 2001 From: Jorge Ruesga Date: Sun, 28 Jun 2015 00:55:25 +0200 Subject: [PATCH] healthd: dock battery Change-Id: I2ad09e5e87d55c47af4d1efc14cc585cc08e2dce Require: topic:dock_battery Signed-off-by: Jorge Ruesga --- healthd/BatteryMonitor.cpp | 416 ++++++++++++++++++----- healthd/BatteryPropertiesRegistrar.cpp | 5 + healthd/BatteryPropertiesRegistrar.h | 2 + healthd/healthd.cpp | 17 + healthd/healthd_mode_charger.cpp | 1 + healthd/include/healthd/BatteryMonitor.h | 7 +- healthd/include/healthd/healthd.h | 34 ++ 7 files changed, 395 insertions(+), 87 deletions(-) diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp index 3641a6ba25d..6b6676a6892 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,6 +75,9 @@ static void initBatteryProperties(BatteryProperties* props) { props->batteryCycleCount = 0; props->batteryFullCharge = 0; props->batteryChargeCounter = 0; + props->chargerDockAcOnline = false; + props->dockBatteryStatus = BATTERY_STATUS_UNKNOWN; + props->dockBatteryHealth = BATTERY_HEALTH_UNKNOWN; props->batteryTechnology.clear(); } @@ -163,13 +167,14 @@ BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC }, { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC }, { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC }, + { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC }, + { "USB_HVDCP_3", ANDROID_POWER_SUPPLY_TYPE_AC }, { "USB_C", ANDROID_POWER_SUPPLY_TYPE_AC }, { "USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC }, { "USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB }, - { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC }, - { "USB_HVDCP_3", ANDROID_POWER_SUPPLY_TYPE_AC }, { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, - { "Wipower", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, + { "DockBattery", ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY }, + { "DockAC", ANDROID_POWER_SUPPLY_TYPE_DOCK_AC }, { "DASH", ANDROID_POWER_SUPPLY_TYPE_AC }, { NULL, 0 }, }; @@ -178,8 +183,10 @@ BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap); - if (ret < 0) + if (ret < 0) { + KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf); ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; + } return ret; } @@ -262,99 +269,99 @@ bool BatteryMonitor::update(void) { if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0) props.batteryTechnology = String8(buf); + props.dockBatterySupported = mHealthdConfig->dockBatterySupported; + if (props.dockBatterySupported) { + if (!mHealthdConfig->dockBatteryPresentPath.isEmpty()) + props.dockBatteryPresent = getBooleanField(mHealthdConfig->dockBatteryPresentPath); + else + props.dockBatteryPresent = mDockBatteryDevicePresent; + + props.dockBatteryLevel = mBatteryFixedCapacity ? + mBatteryFixedCapacity : + getIntField(mHealthdConfig->dockBatteryCapacityPath); + props.dockBatteryVoltage = getIntField(mHealthdConfig->dockBatteryVoltagePath) / 1000; + + props.dockBatteryTemperature = mBatteryFixedTemperature ? + mBatteryFixedTemperature : + getIntField(mHealthdConfig->dockBatteryTemperaturePath); + + if (readFromFile(mHealthdConfig->dockBatteryStatusPath, buf, SIZE) > 0) + props.dockBatteryStatus = getBatteryStatus(buf); + + if (readFromFile(mHealthdConfig->dockBatteryHealthPath, buf, SIZE) > 0) + props.dockBatteryHealth = getBatteryHealth(buf); + + if (readFromFile(mHealthdConfig->dockBatteryTechnologyPath, buf, SIZE) > 0) + props.dockBatteryTechnology = String8(buf); + } + unsigned int i; double MaxPower = 0; - // reinitialize the mChargerNames vector everytime there is an update - String8 path; - DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH); - if (dir == NULL) { - KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH); - } else { - struct dirent* entry; - // reconstruct the charger strings - mChargerNames.clear(); - while ((entry = readdir(dir))) { - const char* name = entry->d_name; + for (i = 0; i < mChargerNames.size(); i++) { + String8 path; + path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, + mChargerNames[i].string()); - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; - - // Look for "type" file in each subdirectory - path.clear(); - path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name); - switch(readPowerSupplyType(path)) { - case ANDROID_POWER_SUPPLY_TYPE_AC: - case ANDROID_POWER_SUPPLY_TYPE_USB: - case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: - // Check if any of them is online + if (readFromFile(path, buf, SIZE) > 0) { + if (buf[0] != '0') { path.clear(); - path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); - if (access(path.string(), R_OK) == 0) { - mChargerNames.add(String8(name)); - if (readFromFile(path, buf, SIZE) > 0) { - if (buf[0] != '0') { - path.clear(); - path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, - name); - switch(readPowerSupplyType(path)) { - case ANDROID_POWER_SUPPLY_TYPE_AC: - props.chargerAcOnline = true; - break; - case ANDROID_POWER_SUPPLY_TYPE_USB: - props.chargerUsbOnline = true; - break; - case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: - props.chargerWirelessOnline = true; - break; - default: - KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", - name); - } - - //If its online, read the voltage and current for power - path.clear(); - path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, - name); - int ChargingCurrent = - (access(path.string(), R_OK) == 0) ? getIntField(path) : 0; - - path.clear(); - path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH, - name); - - int ChargingVoltage = - (access(path.string(), R_OK) == 0) ? getIntField(path) : - DEFAULT_VBUS_VOLTAGE; - - double power = ((double)ChargingCurrent / MILLION) * - ((double)ChargingVoltage / MILLION); - if (MaxPower < power) { - props.maxChargingCurrent = ChargingCurrent; - props.maxChargingVoltage = ChargingVoltage; - MaxPower = power; - } - } + path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, + mChargerNames[i].string()); + switch(readPowerSupplyType(path)) { + case ANDROID_POWER_SUPPLY_TYPE_AC: + props.chargerAcOnline = true; + break; + case ANDROID_POWER_SUPPLY_TYPE_USB: + props.chargerUsbOnline = true; + break; + case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: + props.chargerWirelessOnline = true; + break; + case ANDROID_POWER_SUPPLY_TYPE_DOCK_AC: + if (mHealthdConfig->dockBatterySupported) { + props.chargerDockAcOnline = true; } + break; + default: + KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", + mChargerNames[i].string()); } - break; - case ANDROID_POWER_SUPPLY_TYPE_BATTERY: - break; - default: - break; - } //switch - } //while - closedir(dir); - }//else + path.clear(); + path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, + mChargerNames[i].string()); + int ChargingCurrent = + (access(path.string(), R_OK) == 0) ? getIntField(path) : 0; + + path.clear(); + path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH, + mChargerNames[i].string()); + + int ChargingVoltage = + (access(path.string(), R_OK) == 0) ? getIntField(path) : + DEFAULT_VBUS_VOLTAGE; + + double power = ((double)ChargingCurrent / MILLION) * + ((double)ChargingVoltage / MILLION); + if (MaxPower < power) { + props.maxChargingCurrent = ChargingCurrent; + props.maxChargingVoltage = ChargingVoltage; + MaxPower = power; + } + } + } + } logthis = !healthd_board_battery_update(&props); if (logthis) { char dmesgline[256]; + char dmesglinedock[256]; size_t len; + if (props.batteryPresent) { snprintf(dmesgline, sizeof(dmesgline), - "battery l=%d v=%d t=%s%d.%d h=%d st=%d", + "battery [l=%d v=%d t=%s%d.%d h=%d st=%d]", props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "", abs(props.batteryTemperature / 10), @@ -388,11 +395,38 @@ bool BatteryMonitor::update(void) { props.chargerWirelessOnline ? "w" : ""); KLOG_WARNING(LOG_TAG, "%s\n", dmesgline); + + if (props.dockBatteryPresent) { + snprintf(dmesglinedock, sizeof(dmesglinedock), + "dock-battery [l=%d v=%d t=%s%d.%d h=%d st=%d]", + props.dockBatteryLevel, props.dockBatteryVoltage, + props.dockBatteryTemperature < 0 ? "-" : "", + abs(props.dockBatteryTemperature / 10), + abs(props.dockBatteryTemperature % 10), props.dockBatteryHealth, + props.dockBatteryStatus); + + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + int c = getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + char b[20]; + + snprintf(b, sizeof(b), " c=%d", c / 1000); + strlcat(dmesglinedock, b, sizeof(dmesglinedock)); + } + } else { + snprintf(dmesglinedock, sizeof(dmesglinedock), + "dock-battery none"); + } + + KLOG_WARNING(LOG_TAG, "%s %s chg=%s%s%s%s\n", dmesgline, dmesglinedock, + props.chargerAcOnline ? "a" : "", + props.chargerUsbOnline ? "u" : "", + props.chargerWirelessOnline ? "w" : "", + props.chargerDockAcOnline ? "d" : ""); } healthd_mode_ops->battery_update(&props); return props.chargerAcOnline | props.chargerUsbOnline | - props.chargerWirelessOnline; + props.chargerWirelessOnline | props.chargerDockAcOnline; } int BatteryMonitor::getChargeStatus() { @@ -467,14 +501,78 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { return ret; } +status_t BatteryMonitor::getDockProperty(int id, struct BatteryProperty *val) { + status_t ret = BAD_VALUE; + if (!mHealthdConfig->dockBatterySupported) { + return ret; + } + + val->valueInt64 = LONG_MIN; + + switch(id) { + case BATTERY_PROP_CHARGE_COUNTER: + if (!mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryChargeCounterPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CURRENT_NOW: + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CURRENT_AVG: + if (!mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCurrentAvgPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CAPACITY: + if (!mHealthdConfig->dockBatteryCapacityPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCapacityPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_ENERGY_COUNTER: + if (mHealthdConfig->dockEnergyCounter) { + ret = mHealthdConfig->dockEnergyCounter(&val->valueInt64); + } else { + ret = NAME_NOT_FOUND; + } + break; + + default: + break; + } + + return ret; +} + void BatteryMonitor::dumpState(int fd) { int v; char vs[128]; - snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d voltage_max: %d\n", + snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d voltage_max: %d dock-ac: %d\n", props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline, props.maxChargingCurrent, - props.maxChargingVoltage); + props.maxChargingVoltage, props.chargerDockAcOnline); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); @@ -516,6 +614,34 @@ void BatteryMonitor::dumpState(int fd) { snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullCharge); write(fd, vs, strlen(vs)); } + + if (mHealthdConfig->dockBatterySupported) { + snprintf(vs, sizeof(vs), "dock-status: %d dock-health: %d dock-present: %d\n", + props.dockBatteryStatus, props.dockBatteryHealth, props.dockBatteryPresent); + write(fd, vs, strlen(vs)); + snprintf(vs, sizeof(vs), "dock-level: %d dock-voltage: %d dock-temp: %d\n", + props.dockBatteryLevel, props.dockBatteryVoltage, + props.dockBatteryTemperature); + write(fd, vs, strlen(vs)); + + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + snprintf(vs, sizeof(vs), "dock-current now: %d\n", v); + write(fd, vs, strlen(vs)); + } + + if (!mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryCurrentAvgPath); + snprintf(vs, sizeof(vs), "dock-current avg: %d\n", v); + write(fd, vs, strlen(vs)); + } + + if (!mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryChargeCounterPath); + snprintf(vs, sizeof(vs), "dock-charge counter: %d\n", v); + write(fd, vs, strlen(vs)); + } + } } void BatteryMonitor::init(struct healthd_config *hc) { @@ -542,6 +668,7 @@ void BatteryMonitor::init(struct healthd_config *hc) { case ANDROID_POWER_SUPPLY_TYPE_AC: case ANDROID_POWER_SUPPLY_TYPE_USB: case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: + case ANDROID_POWER_SUPPLY_TYPE_DOCK_AC: path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); if (access(path.string(), R_OK) == 0) @@ -663,6 +790,107 @@ void BatteryMonitor::init(struct healthd_config *hc) { break; + case ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY: + if (mHealthdConfig->dockBatterySupported) { + mDockBatteryDevicePresent = true; + + if (mHealthdConfig->dockBatteryStatusPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryStatusPath = path; + } + + if (mHealthdConfig->dockBatteryHealthPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryHealthPath = path; + } + + if (mHealthdConfig->dockBatteryPresentPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryPresentPath = path; + } + + if (mHealthdConfig->dockBatteryCapacityPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCapacityPath = path; + } + + if (mHealthdConfig->dockBatteryVoltagePath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/voltage_now", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) { + mHealthdConfig->dockBatteryVoltagePath = path; + } else { + path.clear(); + path.appendFormat("%s/%s/batt_vol", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryVoltagePath = path; + } + } + + if (mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/current_now", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCurrentNowPath = path; + } + + if (mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/current_avg", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCurrentAvgPath = path; + } + + if (mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/charge_counter", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryChargeCounterPath = path; + } + + if (mHealthdConfig->dockBatteryTemperaturePath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) { + mHealthdConfig->dockBatteryTemperaturePath = path; + } else { + path.clear(); + path.appendFormat("%s/%s/batt_temp", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryTemperaturePath = path; + } + } + + if (mHealthdConfig->dockBatteryTechnologyPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/technology", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryTechnologyPath = path; + } + } + + break; + case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN: break; } @@ -672,7 +900,7 @@ void BatteryMonitor::init(struct healthd_config *hc) { // Typically the case for devices which do not have a battery and // and are always plugged into AC mains. - if (!mBatteryDevicePresent) { + if (!mBatteryDevicePresent && !mDockBatteryDevicePresent) { KLOG_WARNING(LOG_TAG, "No battery devices found\n"); hc->periodic_chores_interval_fast = -1; hc->periodic_chores_interval_slow = -1; @@ -700,6 +928,22 @@ void BatteryMonitor::init(struct healthd_config *hc) { KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n"); if (mHealthdConfig->batteryCycleCountPath.isEmpty()) KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n"); + if (mHealthdConfig->dockBatterySupported) { + if (mHealthdConfig->dockBatteryStatusPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryStatusPath not found\n"); + if (mHealthdConfig->dockBatteryHealthPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryHealthPath not found\n"); + if (mHealthdConfig->dockBatteryPresentPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryPresentPath not found\n"); + if (mHealthdConfig->dockBatteryCapacityPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryCapacityPath not found\n"); + if (mHealthdConfig->dockBatteryVoltagePath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryVoltagePath not found\n"); + if (mHealthdConfig->dockBatteryTemperaturePath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryTemperaturePath not found\n"); + if (mHealthdConfig->dockBatteryTechnologyPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryTechnologyPath not found\n"); + } } if (property_get("ro.boot.fake_battery", pval, NULL) > 0 diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp index 5d1fa52b143..8d5c301b207 100644 --- a/healthd/BatteryPropertiesRegistrar.cpp +++ b/healthd/BatteryPropertiesRegistrar.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,6 +78,10 @@ status_t BatteryPropertiesRegistrar::getProperty(int id, struct BatteryProperty return healthd_get_property(id, val); } +status_t BatteryPropertiesRegistrar::getDockProperty(int id, struct BatteryProperty *val) { + return healthd_get_dock_property(id, val); +} + status_t BatteryPropertiesRegistrar::dump(int fd, const Vector& /*args*/) { IPCThreadState* self = IPCThreadState::self(); const int pid = self->getCallingPid(); diff --git a/healthd/BatteryPropertiesRegistrar.h b/healthd/BatteryPropertiesRegistrar.h index d17e4a32743..cbff5094d60 100644 --- a/healthd/BatteryPropertiesRegistrar.h +++ b/healthd/BatteryPropertiesRegistrar.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +41,7 @@ class BatteryPropertiesRegistrar : public BnBatteryPropertiesRegistrar, void registerListener(const sp& listener); void unregisterListener(const sp& listener); status_t getProperty(int id, struct BatteryProperty *val); + status_t getDockProperty(int id, struct BatteryProperty *val); status_t dump(int fd, const Vector& args); void binderDied(const wp& who); }; diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp index 4218eb8df19..9117abec6d1 100644 --- a/healthd/healthd.cpp +++ b/healthd/healthd.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,6 +65,18 @@ static struct healthd_config healthd_config = { .energyCounter = NULL, .boot_min_cap = 0, .screen_on = NULL, + .dockBatterySupported = false, + .dockBatteryStatusPath = String8(String8::kEmptyString), + .dockBatteryHealthPath = String8(String8::kEmptyString), + .dockBatteryPresentPath = String8(String8::kEmptyString), + .dockBatteryCapacityPath = String8(String8::kEmptyString), + .dockBatteryVoltagePath = String8(String8::kEmptyString), + .dockBatteryTemperaturePath = String8(String8::kEmptyString), + .dockBatteryTechnologyPath = String8(String8::kEmptyString), + .dockBatteryCurrentNowPath = String8(String8::kEmptyString), + .dockBatteryCurrentAvgPath = String8(String8::kEmptyString), + .dockBatteryChargeCounterPath = String8(String8::kEmptyString), + .dockEnergyCounter = NULL, }; static int eventct; @@ -182,6 +195,10 @@ status_t healthd_get_property(int id, struct BatteryProperty *val) { return gBatteryMonitor->getProperty(id, val); } +status_t healthd_get_dock_property(int id, struct BatteryProperty *val) { + return gBatteryMonitor->getDockProperty(id, val); +} + void healthd_battery_update(void) { // Fast wake interval when on charger (watch for overheat); // slow wake interval when on battery (watch for drained battery). diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp index 7af4e9634d7..38e1b549c9e 100644 --- a/healthd/healthd_mode_charger.cpp +++ b/healthd/healthd_mode_charger.cpp @@ -640,6 +640,7 @@ static void process_key(struct charger *charger, int code, int64_t now) if (property_get_bool("ro.enable_boot_charger_mode", false)) { LOGW("[%" PRId64 "] booting from charger mode\n", now); healthd_board_mode_charger_set_backlight(false); + gr_fb_blank(true); property_set("sys.boot_from_charger_mode", "1"); } else { if (charger->batt_anim->capacity >= charger->boot_min_cap) { diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h index 440f2e44cce..53ccb17f926 100644 --- a/healthd/include/healthd/BatteryMonitor.h +++ b/healthd/include/healthd/BatteryMonitor.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +35,9 @@ class BatteryMonitor { ANDROID_POWER_SUPPLY_TYPE_AC, ANDROID_POWER_SUPPLY_TYPE_USB, ANDROID_POWER_SUPPLY_TYPE_WIRELESS, - ANDROID_POWER_SUPPLY_TYPE_BATTERY + ANDROID_POWER_SUPPLY_TYPE_BATTERY, + ANDROID_POWER_SUPPLY_TYPE_DOCK_AC, + ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY }; BatteryMonitor(); @@ -42,12 +45,14 @@ class BatteryMonitor { bool update(void); int getChargeStatus(); status_t getProperty(int id, struct BatteryProperty *val); + status_t getDockProperty(int id, struct BatteryProperty *val); void dumpState(int fd); private: struct healthd_config *mHealthdConfig; Vector mChargerNames; bool mBatteryDevicePresent; + bool mDockBatteryDevicePresent; bool mAlwaysPluggedDevice; int mBatteryFixedCapacity; int mBatteryFixedTemperature; diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h index 19b9c6251c4..022c1c428c7 100644 --- a/healthd/include/healthd/healthd.h +++ b/healthd/include/healthd/healthd.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +49,25 @@ // batteryTemperaturePath: battery temperature (POWER_SUPPLY_PROP_TEMP) // batteryTechnologyPath: battery technology (POWER_SUPPLY_PROP_TECHNOLOGY) // batteryCurrentNowPath: battery current (POWER_SUPPLY_PROP_CURRENT_NOW) +// batteryCurrentAvgPath: battery average (POWER_SUPPLY_PROP_CURRENT_AVG) // batteryChargeCounterPath: battery accumulated charge // (POWER_SUPPLY_PROP_CHARGE_COUNTER) +// +// dockBatteryStatusPath: dock charging status (POWER_SUPPLY_PROP_STATUS) +// dockBatteryHealthPath: dock battery health (POWER_SUPPLY_PROP_HEALTH) +// dockBatteryPresentPath: dock battery present (POWER_SUPPLY_PROP_PRESENT) +// dockBatteryCapacityPath: remaining dock capacity (POWER_SUPPLY_PROP_CAPACITY) +// dockBatteryVoltagePath: dock battery voltage (POWER_SUPPLY_PROP_VOLTAGE_NOW) +// dockBatteryTemperaturePath: dock battery temperature (POWER_SUPPLY_PROP_TEMP) +// dockBatteryTechnologyPath: dock battery technology (POWER_SUPPLY_PROP_TECHNOLOGY) +// dockBatteryCurrentNowPath: dock battery current (POWER_SUPPLY_PROP_CURRENT_NOW) +// dockBatteryCurrentAvgPath: dock battery average (POWER_SUPPLY_PROP_CURRENT_AVG) +// dockBatteryChargeCounterPath: dock battery accumulated charge +// (POWER_SUPPLY_PROP_CHARGE_COUNTER) +// +// The dockBatterySupported property indicates whether a dock battery is supported +// by the device, and whether this module should fetch dock battery values. +// Defaults is to false. struct healthd_config { int periodic_chores_interval_fast; @@ -71,6 +89,20 @@ struct healthd_config { int (*energyCounter)(int64_t *); int boot_min_cap; bool (*screen_on)(android::BatteryProperties *props); + + bool dockBatterySupported; + android::String8 dockBatteryStatusPath; + android::String8 dockBatteryHealthPath; + android::String8 dockBatteryPresentPath; + android::String8 dockBatteryCapacityPath; + android::String8 dockBatteryVoltagePath; + android::String8 dockBatteryTemperaturePath; + android::String8 dockBatteryTechnologyPath; + android::String8 dockBatteryCurrentNowPath; + android::String8 dockBatteryCurrentAvgPath; + android::String8 dockBatteryChargeCounterPath; + + int (*dockEnergyCounter)(int64_t *); }; // Global helper functions @@ -79,6 +111,8 @@ int healthd_register_event(int fd, void (*handler)(uint32_t)); void healthd_battery_update(); android::status_t healthd_get_property(int id, struct android::BatteryProperty *val); +android::status_t healthd_get_dock_property(int id, + struct android::BatteryProperty *val); void healthd_dump_battery_state(int fd); struct healthd_mode_ops {