ADD_SUBDIRECTORY(plugins/iot-headed/display)
ADD_SUBDIRECTORY(plugins/iot-headless/input)
ADD_SUBDIRECTORY(plugins/iot-headless/power)
+ADD_SUBDIRECTORY(plugins/iot-headless/battery)
IF(BATTERY_MODULE STREQUAL on)
ADD_SUBDIRECTORY(plugins/mobile/battery)
ADD_SUBDIRECTORY(plugins/wearable/battery)
RealOff=0
WarningMethod=warning
CriticalMethod=critical
+
+# hold wakelock if a charger has been connected, iot-headless only
+[CHARGER_WAKELOCK]
+ChargerWakeLockEnabled=yes
+
+# define event-action, iot-headless only
+# DeviceNotifier=
+# - define which event(device-notifiy) is filtered
+# Action=
+# - define action for the event
+[EVENT_ACTION]
+Name=CHARGER_CONNECTED
+Enum=2001
+DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED
+Action=sleep,sleep
+Action=normal,normal
+
+[EVENT_ACTION]
+Name=CHARGER_DISCONNECTED
+Enum=2002
+DeviceNotifier=DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED
+Action=sleep,sleep
+Action=normal,normal
mkdir -p %{_libdir}/deviced
mv %{_libdir}/iot-headless-input-handler.so %{_libdir}/deviced/input-handler.so
mv %{_libdir}/iot-headless-power.so %{_libdir}/deviced/power.so
+mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so
%files
%manifest %{name}.manifest
%config %{_sysconfdir}/deviced/iot-headless-input.conf
%{_libdir}/iot-headless-input-handler.so
%{_libdir}/iot-headless-power.so
+%{_libdir}/iot-headless-battery.so
%{_unitdir}/rndis.service
%{_bindir}/rndis.sh
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+PROJECT(iot-headless-battery C)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(REQUIRED_PKGS REQUIRED
+ glib-2.0
+ dlog
+ libsyscommon)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../power)
+
+FILE(GLOB SRCS "*.c")
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME iot-headless-battery)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
--- /dev/null
+#include <stdio.h>
+#include <glib.h>
+#include <libsyscommon/ini-parser.h>
+#include <libsyscommon/list.h>
+
+#include "shared/device-notifier.h"
+#include "shared/log.h"
+#include "battery/battery-ops.h"
+
+#include "power-state-manager.h"
+
+#define BATTERY_CONF_PATH "/etc/deviced/battery.conf"
+
+struct battery_event_handler {
+ char *name;
+ int id;
+
+ /* which action to do on receiving an event */
+ enum device_notifier_type action;
+ void *user_data;
+};
+
+static struct battery_event_handler *handler_connected;
+static struct battery_event_handler *handler_disconnected;
+
+static void parse_device_notifier(struct battery_event_handler *handler, const char *action)
+{
+ if (MATCH(action, "DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED")) {
+ handler_connected = handler;
+ } else if (MATCH(action, "DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED")) {
+ handler_disconnected = handler;
+ }
+}
+
+static enum psm_state convert_action_string_to_psm_state(char *str)
+{
+ if (MATCH(str, "sleep"))
+ return PSM_SLEEP;
+ else if (MATCH(str, "normal"))
+ return PSM_NORMAL;
+ else if (MATCH(str, "poweroff"))
+ return PSM_POWEROFF;
+
+ _W("Invalid psm_state=%s", str);
+
+ return PSM_MAX;
+}
+
+static void add_action_transition_info(struct battery_event_handler *handler, char *curr, char *next)
+{
+ struct trans_info *ti = NULL;
+ GList **action_list = (GList **) &(handler->user_data);
+
+ ti = calloc(1, sizeof(struct trans_info));
+ if (!ti)
+ return;
+
+ /* In configuration file, Enum= must be followed by Action=.
+ * Otherwise, handler->id won't be defined at this point.*/
+ ti->reason = handler->id;
+
+ ti->curr = convert_action_string_to_psm_state(curr);
+ ti->next = convert_action_string_to_psm_state(next);
+
+ SYS_G_LIST_APPEND(*action_list, ti);
+}
+
+static void parse_action(struct battery_event_handler *handler, const char *action)
+{
+ char curr[16] = { 0, };
+ char next[16] = { 0, };
+
+ if (sscanf(action, "%15[^,],%15s", curr, next) == 2) {
+ handler->action = DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE;
+ /* append transition info to handler->user_data */
+ add_action_transition_info(handler, curr, next);
+ } else {
+ _E("Invalid action=%s", action);
+ }
+}
+
+static void parse_event_action_property(gpointer data, gpointer user_data)
+{
+ struct section_property *prop = (struct section_property *) data;
+ struct battery_event_handler *handler = (struct battery_event_handler *) user_data;
+
+ if (!prop)
+ return;
+
+ _D("Key=%s, Value=%s", prop->key, prop->value);
+
+ if (MATCH(prop->key, "Name")) {
+ handler->name = strndup(prop->value, 32);
+ } else if (MATCH(prop->key, "Enum")) {
+ sscanf(prop->value, "%d", &handler->id);
+ } else if (MATCH(prop->key, "DeviceNotifier")) {
+ parse_device_notifier(handler, prop->value);
+ } else if (MATCH(prop->key, "Action")) {
+ parse_action(handler, prop->value);
+ }
+}
+
+static int parse_event_action(const struct parse_result *result, void *data)
+{
+ struct battery_event_handler *handler = NULL;
+
+ if (!result || !result->props)
+ return 0;
+
+ if (MATCH(result->section, "EVENT_ACTION")) {
+ handler = calloc(1, sizeof(struct battery_event_handler));
+ if (!handler)
+ return 0;
+
+ g_list_foreach(result->props, parse_event_action_property, handler);
+ }
+
+ return 0;
+}
+
+static int charger_connected_callback(void *data)
+{
+ _D("event=%s(%d), action=%d", handler_connected->name, handler_connected->id, handler_connected->action);
+ device_notify(handler_connected->action, handler_connected->user_data);
+
+ return 0;
+}
+
+static int charger_disconnected_callback(void *data)
+{
+ _D("event=%s(%d), action=%d", handler_disconnected->name, handler_disconnected->id, handler_disconnected->action);
+ device_notify(handler_disconnected->action, handler_disconnected->user_data);
+
+ return 0;
+}
+
+static void battery_plugin_init(void *data)
+{
+ libsys_config_parse_by_section(BATTERY_CONF_PATH, parse_event_action, NULL);
+
+ if (handler_connected)
+ register_notifier(DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED, charger_connected_callback);
+
+ if (handler_disconnected)
+ register_notifier(DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED, charger_disconnected_callback);
+}
+
+static const struct battery_ops battery_plugin_ops = {
+ .name = "battery-plugin",
+ .init = battery_plugin_init,
+};
+
+BATTERY_OPS_REGISTER(&battery_plugin_ops)
ieu->notifier = DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL;
ieu->user_data = (void *) ieu;
} else if (sscanf(action, "%15[^,],%15s", curr, next) == 2) {
- ieu->notifier = DEVICE_NOTIFIER_INPUT_TRANSITION_STATE;
+ ieu->notifier = DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE;
/* append transition info to ieu->user_data */
add_action_transition_info(ieu, curr, next);
} else {
#include <glib.h>
#include <stdint.h>
#include <linux/input.h>
+#include <libsyscommon/ini-parser.h>
#include "shared/bitmap.h"
#include "shared/device-notifier.h"
#include "shared/log.h"
#include "power-event-lock.h"
+#define BATTERY_CONF_FILE "/etc/deviced/battery.conf"
+
/* eventlock is another wakelock than mainlock.
*
* The eventlock works independently of mainlock, which is controlled by
* power state. The main purpose of eventlock is to prevent the subroutine
* of an event from going to sleep regardless of the power state. */
-#define EVENT_LOCK "eventlock"
-#define EVENT_LOCK_MARGIN_MS 1000
+#define EVENT_LOCK "eventlock"
enum eventlock_type {
EL_MIN,
EL_KEY,
EL_KEY_POWER = EL_KEY,
EL_KEY_BLUETOOTH,
+
+ EL_CHARGER,
/* add eventlock type here */
EL_MAX,
};
power_event_unlock_callback, (void *)(intptr_t) type, NULL, -1000);
}
+static int check_charger_wakelock(struct parse_result *result, void *user_data)
+{
+ if (MATCH(result->section, "CHARGER_WAKELOCK")
+ && MATCH(result->name, "ChargerWakeLockEnabled")
+ && MATCH(result->value, "yes"))
+ *(int *) user_data = 1;
+
+ return 0;
+}
+
void power_event_lock_init(void)
{
+ int charger_wakelock = 0;
+
eventlock = init_bitmap(EL_MAX);
if (!eventlock) {
_E("Failed to init event lock bitmap");
return;
}
+ config_parse(BATTERY_CONF_FILE, check_charger_wakelock, &charger_wakelock);
+
register_power_event_lock_controller(EL_KEY,
DEVICE_NOTIFIER_KEY_PRESS,
DEVICE_NOTIFIER_KEY_RELEASE);
+
+ if (charger_wakelock) {
+ register_power_event_lock_controller(EL_CHARGER,
+ DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED,
+ DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED);
+ }
}
device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL);
device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL);
- register_notifier(DEVICE_NOTIFIER_INPUT_TRANSITION_STATE, psm_transition_state_cb);
+ register_notifier(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE, psm_transition_state_cb);
power_plugin_dbus_init(NULL);
power_event_lock_init();
break;
case CHARGE_STATUS_FULL:
str = EVT_VAL_BATTERY_CHARGER_DISCHARGING;
- CRITICAL_LOG("Battery %s", str);
+ CRITICAL_LOG("Battery charger: %s", str);
break;
case CHARGE_STATUS_DISCHARGING:
str = EVT_VAL_BATTERY_CHARGER_DISCHARGING;
+ CRITICAL_LOG("Battery charger: %s", str);
break;
case CHARGE_STATUS_CONNECTED:
str = EVT_VAL_BATTERY_CHARGER_CONNECTED;
- CRITICAL_LOG("Battery %s", str);
+ CRITICAL_LOG("Battery charger: %s", str);
break;
case CHARGE_STATUS_DISCONNECTED:
str = EVT_VAL_BATTERY_CHARGER_DISCONNECTED;
- CRITICAL_LOG("Battery %s", str);
+ CRITICAL_LOG("Battery charger: %s", str);
break;
default:
_E("Invalid parameter: %d", state);
return;
}
- _D("System_event: %s", str);
-
event_system_send(SYS_EVENT_BATTERY_CHARGER_STATUS, EVT_KEY_BATTERY_CHARGER_STATUS, str);
}
extcon_update_count(EXTCON_TA, 1);
check_power_supply(online_status);
charger_state_send_system_event(CHARGE_STATUS_CONNECTED);
+ device_notify(DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED, NULL);
if (old_battery.charge_status != battery.charge_status)
charger_state_send_system_event(battery.charge_status);
broadcast = true;
if (old_battery.charge_status != battery.charge_status)
charger_state_send_system_event(battery.charge_status);
charger_state_send_system_event(CHARGE_STATUS_DISCONNECTED);
+ device_notify(DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED, NULL);
broadcast = true;
} else {
if (old_battery.charge_status != battery.charge_status)
DEVICE_NOTIFIER_BATTERY_PRESENT,
DEVICE_NOTIFIER_BATTERY_OVP,
DEVICE_NOTIFIER_BATTERY_CHARGING,
+ DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED,
+ DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED,
DEVICE_NOTIFIER_DISPLAY_AMBIENT_CONDITION,
DEVICE_NOTIFIER_DISPLAY_AMBIENT_STATE,
DEVICE_NOTIFIER_DISPLAY_LOCK,
/* action triggered by input event */
DEVICE_NOTIFIER_INPUT_TRIGGER_POWEROFF,
DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL,
- DEVICE_NOTIFIER_INPUT_TRANSITION_STATE,
-
/* Purpose of calling methods of different modules
* Use prefix DEVICE_NOTIFIER_REQUEST */
DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP,
DEVICE_NOTIFIER_REQUEST_WAKE_LOCK,
DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK,
+ DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE,
DEVICE_NOTIFIER_MAX,
};