From 7bbc7b78952622f9c2d2b5e085d4a180475f031e Mon Sep 17 00:00:00 2001 From: Taeyoung Kim Date: Mon, 16 May 2016 18:40:37 +0900 Subject: [PATCH] battery: add battery info apis - int device_battery_get_health(device_battery_health_e *health); - int device_battery_get_power_source(device_battery_power_source_e *source); - int device_battery_get_property(device_battery_property_e propertyi, int *val); - int device_battery_get_status(device_battery_status_e *status); Change-Id: I0995f070039286b8e0c3be3c711c06ef238c5bf8 Signed-off-by: taeyoung --- include/battery.h | 109 ++++++++++++++++++++++++++++++++ src/battery.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dbus.c | 68 ++++++++++++++++++++ src/dbus.h | 4 ++ 4 files changed, 362 insertions(+) diff --git a/include/battery.h b/include/battery.h index 1173df4..9b4cda2 100755 --- a/include/battery.h +++ b/include/battery.h @@ -44,6 +44,50 @@ typedef enum { } device_battery_level_e; /** + * @brief Enumeration for battery health information. + * @since_tizen 3.0 + */ +typedef enum { + DEVICE_BATTERY_HEALTH_GOOD, /**< The battery health is good */ + DEVICE_BATTERY_HEALTH_COLD, /**< The temperature of the battery is cold */ + DEVICE_BATTERY_HEALTH_DEAD, /**< The battery is dead */ + DEVICE_BATTERY_HEALTH_OVER_HEAT, /**< The temperature of the battery is high */ + DEVICE_BATTERY_HEALTH_OVER_VOLTAGE,/**< The battery is in over voltage state */ +} device_battery_health_e; + +/** + * @brief Enumeration for power source information. + * @since_tizen 3.0 + */ +typedef enum { + DEVICE_BATTERY_POWER_SOURCE_NONE, /**< There is no power source */ + DEVICE_BATTERY_POWER_SOURCE_AC, /**< AC power cable is connected */ + DEVICE_BATTERY_POWER_SOURCE_USB, /**< USB power cable is connected */ + DEVICE_BATTERY_POWER_SOURCE_WIRELESS,/**< Power is provided by a wireless source */ +} device_battery_power_source_e; + +/** + * @brief Enumeration for battery property information. + * @since_tizen 3.0 + */ +typedef enum { + DEVICE_BATTERY_PROPERTY_CAPACITY, /**< The battery capacity (0 ~ 100 %) */ + DEVICE_BATTERY_PROPERTY_CURRENT_NOW, /**< The battery current (uA) */ + DEVICE_BATTERY_PROPERTY_CURRENT_AVERAGE,/**< The average battery current (uA) */ +} device_battery_property_e; + +/** + * @brief Enumeration for battery status information. + * @since_tizen 3.0 + */ +typedef enum { + DEVICE_BATTERY_STATUS_CHARGING, /**< Battery is charging */ + DEVICE_BATTERY_STATUS_DISCHARGING, /**< Battery is discharging */ + DEVICE_BATTERY_STATUS_FULL, /**< Battery is fully charged */ + DEVICE_BATTERY_STATUS_NOT_CHARGING, /**< Battery is not charging */ +} device_battery_status_e; + +/** * @brief Gets the battery charge percentage. * @details It returns an integer value from @c 0 to @c 100 that indicates remaining battery charge * as a percentage of the maximum level. @@ -106,6 +150,71 @@ int device_battery_is_charging(bool *charging); int device_battery_get_level_status(device_battery_level_e *status); /** + * @brief Gets the battery health information. + * + * @since_tizen 3.0 + * + * @param[out] health The battery health information + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_battery_get_health(device_battery_health_e *health); + +/** + * @brief Gets the battery power source information. + * + * @since_tizen 3.0 + * + * @param[out] source The battery power source information + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_battery_get_power_source(device_battery_power_source_e *source); + +/** + * @brief Gets the battery properties. + * + * @since_tizen 3.0 + * + * @param[in] property The property type + * @param[out] value The battery information for the property given + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_battery_get_property(device_battery_property_e property, int *value); + +/** + * @brief Gets the battery status information. + * + * @since_tizen 3.0 + * + * @param[out] status The battery status information + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_battery_get_status(device_battery_status_e *status); + +/** * @} */ diff --git a/src/battery.c b/src/battery.c index fb0855e..d65ed3d 100644 --- a/src/battery.c +++ b/src/battery.c @@ -26,6 +26,20 @@ #include "dbus.h" #define METHOD_GET_PERCENT "GetPercent" +#define METHOD_GET_INFO "GetBatteryInfo" + +#define INFO_MAX 32 + +struct battery_info { + char status[INFO_MAX]; + char health[INFO_MAX]; + char power_source[INFO_MAX]; + int online; + int present; + int capacity; + int current_now; + int current_average; +}; int device_battery_get_percent(int *percent) { @@ -94,3 +108,170 @@ int device_battery_get_level_status(device_battery_level_e *status) return DEVICE_ERROR_NONE; } + +static int device_battery_get_info(struct battery_info *info) +{ + int ret; + GVariant *output = NULL; + char *status = NULL; + char *health = NULL; + char *power_source; + int online; + int present; + int capacity; + int current_now; + int current_average; + + if (!info) + return DEVICE_ERROR_INVALID_PARAMETER; + + ret = dbus_method_sync_with_reply(DEVICED_BUS_NAME, + DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY, + METHOD_GET_INFO, NULL, NULL, &output); + /* regard not suppoted as disconnected */ + if (ret == -ENOTSUP) + ret = 0; + else if (ret < 0) + return errno_to_device_error(ret); + + g_variant_get(output, "(isssiiiii)", &ret, + &status, &health, &power_source, + &online, &present, &capacity, + ¤t_now, ¤t_average); + + if (ret < 0) { + ret = errno_to_device_error(ret); + goto out; + } + + snprintf(info->status, sizeof(info->status), "%s", status); + snprintf(info->health, sizeof(info->health), "%s", health); + snprintf(info->power_source, sizeof(info->power_source), "%s", power_source); + info->online = online; + info->present = present; + info->capacity = capacity; + info->current_now = current_now; + info->current_average = current_average; + + ret = DEVICE_ERROR_NONE; + +out: + free(status); + free(health); + free(power_source); + g_variant_unref(output); + + return ret; +} + +int device_battery_get_health(device_battery_health_e *health) +{ + struct battery_info info; + int ret; + size_t len; + + ret = device_battery_get_info(&info); + if (ret != DEVICE_ERROR_NONE) { + _E("Failed to get battery info (%d)", ret); + return ret; + } + + len = strlen(info.status); + if (!strncmp(info.health, "Good", len)) + *health = DEVICE_BATTERY_HEALTH_GOOD; + else if (!strncmp(info.health, "Cold", len)) + *health = DEVICE_BATTERY_HEALTH_COLD; + else if (!strncmp(info.health, "Dead", len)) + *health = DEVICE_BATTERY_HEALTH_DEAD; + else if (!strncmp(info.health, "Overheat", len)) + *health = DEVICE_BATTERY_HEALTH_OVER_HEAT; + else if (!strncmp(info.health, "Over voltage", len)) + *health = DEVICE_BATTERY_HEALTH_OVER_VOLTAGE; + else + return DEVICE_ERROR_OPERATION_FAILED; + + return DEVICE_ERROR_NONE; +} + +int device_battery_get_power_source(device_battery_power_source_e *source) +{ + struct battery_info info; + int ret; + size_t len; + + ret = device_battery_get_info(&info); + if (ret != DEVICE_ERROR_NONE) { + _E("Failed to get battery info (%d)", ret); + return ret; + } + + len = strlen(info.status); + if (!strncmp(info.power_source, "ac", len)) + *source = DEVICE_BATTERY_POWER_SOURCE_AC; + else if (!strncmp(info.power_source, "usb", len)) + *source = DEVICE_BATTERY_POWER_SOURCE_USB; + else if (!strncmp(info.power_source, "wireless", len)) + *source = DEVICE_BATTERY_POWER_SOURCE_WIRELESS; + else + *source = DEVICE_BATTERY_POWER_SOURCE_NONE; + + return DEVICE_ERROR_NONE; +} + +int device_battery_get_property(device_battery_property_e property, int *val) +{ + struct battery_info info; + int ret; + + if (!val) + return DEVICE_ERROR_INVALID_PARAMETER; + + ret = device_battery_get_info(&info); + if (ret != DEVICE_ERROR_NONE) { + _E("Failed to get battery info (%d)", ret); + return ret; + } + + switch (property) { + case DEVICE_BATTERY_PROPERTY_CAPACITY: + *val = info.capacity; + break; + case DEVICE_BATTERY_PROPERTY_CURRENT_NOW: + *val = info.current_now; + break; + case DEVICE_BATTERY_PROPERTY_CURRENT_AVERAGE: + *val = info.current_average; + break; + default: + return DEVICE_ERROR_INVALID_PARAMETER; + } + + return DEVICE_ERROR_NONE; +} + +int device_battery_get_status(device_battery_status_e *status) +{ + struct battery_info info; + int ret; + size_t len; + + ret = device_battery_get_info(&info); + if (ret != DEVICE_ERROR_NONE) { + _E("Failed to get battery info (%d)", ret); + return ret; + } + + len = strlen(info.status); + if (!strncmp(info.status, "Charging", len)) + *status = DEVICE_BATTERY_STATUS_CHARGING; + else if (!strncmp(info.status, "Discharging", len)) + *status = DEVICE_BATTERY_STATUS_DISCHARGING; + else if (!strncmp(info.status, "Full", len)) + *status = DEVICE_BATTERY_STATUS_FULL; + else if (!strncmp(info.status, "Not charging", len)) + *status = DEVICE_BATTERY_STATUS_NOT_CHARGING; + else + return DEVICE_ERROR_OPERATION_FAILED; + + return DEVICE_ERROR_NONE; +} diff --git a/src/dbus.c b/src/dbus.c index 08d5a98..e109293 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -169,6 +169,74 @@ int dbus_method_sync(const char *dest, const char *path, return result; } +int dbus_method_sync_with_reply(const char *dest, + const char *path, const char *interface, + const char *method, const char *sig, + char *param[], GVariant **info) +{ + GDBusConnection *conn; + GDBusProxy *proxy; + GError *err = NULL; + GVariant *output; + int result; + +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + _E("g_bus_get_sync error : %s-%s (%d-%s)", + interface, method, err->code, err->message); + result = g_dbus_error_to_errno(err->code); + g_clear_error(&err); + return result; + } + + proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusinterfaceinfo */ + dest, /* bus name */ + path, /* object path */ + interface, /* interface name */ + NULL, /* GCancellable */ + &err); + if (!proxy) { + _E("g_dbus_proxy_new_sync error : %s-%s (%d-%s)", + interface, method, err->code, err->message); + result = g_dbus_error_to_errno(err->code); + g_clear_error(&err); + return result; + } + + output = g_dbus_proxy_call_sync(proxy, + method, /* method name */ + append_g_variant(sig, param), /* parameters */ + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, /* timeout */ + NULL, /* GCancellable */ + &err); + if (!output) { + if (!err) { + _E("g_dbus_proxy_call_sync error : %s-%s", + interface, method); + g_object_unref(proxy); + return -EPERM; + } + _E("g_dbus_proxy_call_sync error : %s-%s (%d-%s)", + interface, method, err->code, err->message); + result = g_dbus_error_to_errno(err->code); + g_clear_error(&err); + g_object_unref(proxy); + return result; + } + + g_object_unref(proxy); + + *info = output; + return DEVICE_ERROR_NONE; +} + static void cb_pending(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data) diff --git a/src/dbus.h b/src/dbus.h index 0f32297..b912d8c 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -58,6 +58,10 @@ struct dbus_int { int dbus_method_sync(const char *dest, const char *path, const char *interface, const char *method, const char *sig, char *param[]); +int dbus_method_sync_with_reply(const char *dest, + const char *path, const char *interface, + const char *method, const char *sig, + char *param[], GVariant **info); /** * If result is NULL, err is set. -- 2.7.4