+/*
+ * battery-plugin
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdio.h>
+#include <errno.h>
+
+#include <hw/common.h>
+#include <hw/battery.h>
+
+#include "battery-plugin.h"
+
+#define BATTERY_INFO_MAX 32
+
+struct device_battery_info {
+ char status[BATTERY_INFO_MAX];
+ char health[BATTERY_INFO_MAX];
+ char power_source[BATTERY_INFO_MAX];
+ int online;
+ int present;
+ int capacity;
+ int current_now;
+ int current_average;
+ int voltage_now;
+ int voltage_average;
+ int temperature;
+};
+
+static struct hw_info *hw = NULL;
+static struct battery_device *battery_dev = NULL;
+
+static int load_battery_dev()
+{
+ int ret = 0;
+
+ if (!hw) {
+ ret = hw_get_info(BATTERY_HARDWARE_DEVICE_ID, (const struct hw_info **)&hw);
+ if (ret < 0) {
+ return -ENODEV;
+ }
+ }
+
+ if (!hw->open) {
+ _E("Failed to open battery device: open(NULL)");
+ return -ENODEV;
+ }
+
+ ret = hw->open(hw, NULL, (struct hw_common**)&battery_dev);
+ if (ret < 0) {
+ _E("Failed to get battery device structure: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void battery_get_info(struct battery_info *info, void *data)
+{
+ struct device_battery_info *bat = data;
+
+ if (!info || !bat)
+ return;
+
+ snprintf(bat->status, sizeof(bat->status), "%s", info->status);
+ snprintf(bat->health, sizeof(bat->health), "%s", info->health);
+ snprintf(bat->power_source, sizeof(bat->power_source), "%s", info->power_source);
+ bat->online = info->online;
+ bat->present = info->present;
+ bat->capacity = info->capacity;
+ bat->current_now = info->current_now;
+ bat->current_average = info->current_average;
+ bat->temperature = info->temperature;
+ bat->voltage_now = info->voltage_now;
+ bat->voltage_average = info->voltage_average;
+}
+
+int __attribute__((visibility("default"))) battery_get_info_direct(void *battery_info)
+{
+ struct device_battery_info *info = battery_info;
+ int ret = 0;
+
+ if (!info)
+ return -EINVAL;
+
+ if (!battery_dev) {
+ ret = load_battery_dev();
+ if (ret < 0)
+ return ret;
+
+ if (!battery_dev)
+ return -ENODEV;
+ }
+
+ if (!battery_dev->get_current_state) {
+ _E("get_current_state() is not supported by the Battery HAL.");
+ return -ENODEV;
+ }
+
+ ret = battery_dev->get_current_state(battery_get_info, info);
+ if (ret < 0) {
+ _E("Failed to get battery info: %d", ret);
+ return -EPERM;
+ }
+
+ return 0;
+}