3 #include <linux/input.h>
4 #include <libsyscommon/libgdbus.h>
5 #include <libsyscommon/list.h>
6 #include <device/power-internal.h>
8 #include "shared/devices.h"
9 #include "shared/device-notifier.h"
10 #include "shared/log.h"
11 #include "power-state-manager.h"
12 #include "power-dbus.h"
13 #include "power-state-wait.h"
15 /* Temporal wakelock of powerkey input */
16 #define KEY_PRESSED_TEMPORAL_LOCK "templock"
17 #define TEMPORAL_LOCK_WAKE_MARGIN 1000 /* milisecond */
19 #define EVENT_TYPE_SLEEP 0
20 #define EVENT_TYPE_WAKEUP 1
22 static guint keypress_temporal_timer_id;
24 char *psm_name[PSM_MAX] = {
25 [PSM_NORMAL] = "PSM_NORMAL",
26 [PSM_SLEEP] = "PSM_SLEEP",
27 [PSM_POWEROFF] = "PSM_POWEROFF",
28 [PSM_REBOOT] = "PSM_REBOOT",
31 static guint64 state_transition_counter = 0;
32 static enum psm_state current;
34 static gboolean temporal_lock_expired_cb(void *data)
36 sys_set_str("/sys/power/wake_unlock", KEY_PRESSED_TEMPORAL_LOCK);
37 keypress_temporal_timer_id = 0;
39 return G_SOURCE_REMOVE;
42 static int acquire_temporal_lock(void *data)
44 int keycode = (int)(intptr_t) data;
46 if (keycode != KEY_POWER)
49 if (keypress_temporal_timer_id) {
50 g_source_remove(keypress_temporal_timer_id);
51 keypress_temporal_timer_id = 0;
54 sys_set_str("/sys/power/wake_lock", KEY_PRESSED_TEMPORAL_LOCK);
59 static int release_temporal_lock(void * data)
61 int keycode = (int)(intptr_t) data;
63 if (keycode != KEY_POWER)
66 if (keypress_temporal_timer_id) {
67 g_source_remove(keypress_temporal_timer_id);
68 keypress_temporal_timer_id = 0;
72 keypress_temporal_timer_id = g_timeout_add(TEMPORAL_LOCK_WAKE_MARGIN,
73 temporal_lock_expired_cb, NULL);
78 static void psm_wake_unlock(void)
80 /* for PSM_NORMAL, PSM_POWEROFF, do not wake unlock */
81 if (current != PSM_SLEEP) {
82 _E("Ignore sleep wait done, current=%s", psm_name[current]);
86 device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, NULL);
89 static void psm_trigger_poweroff(void)
91 const struct device_ops *power_device;
93 power_device = find_device("power");
94 if (check_default(power_device))
97 if (power_device->execute) {
98 device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL);
99 power_device->execute("poweroff");
103 static void broadcast_transition_info(const struct trans_info *ti)
105 // mapping deviced state to capi signame
106 static const char *capi_signame[PSM_MAX] = {
107 [PSM_NORMAL] = SIGNAME_CHANGE_STATE_TO_NORMAL,
108 [PSM_SLEEP] = SIGNAME_CHANGE_STATE_TO_SLEEP,
109 [PSM_POWEROFF] = SIGNAME_CHANGE_STATE_TO_POWEROFF,
110 [PSM_REBOOT] = SIGNAME_CHANGE_STATE_TO_REBOOT,
113 // mapping deviced state to capi state
114 static const guint64 capi_state[PSM_MAX] = {
115 [PSM_NORMAL] = POWER_STATE_NORMAL,
116 [PSM_SLEEP] = POWER_STATE_SLEEP,
117 [PSM_POWEROFF] = POWER_STATE_POWEROFF,
118 [PSM_REBOOT] = POWER_STATE_REBOOT,
121 gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, capi_signame[ti->next],
122 g_variant_new("(ttti)", capi_state[ti->curr], capi_state[ti->next], state_transition_counter, ti->reason));
125 static void psm_transition_normal_to_normal(const struct trans_info *ti)
127 broadcast_transition_info(ti);
128 update_change_state_wait(state_transition_counter, ti, NULL);
131 static void psm_transition_normal_to_sleep(const struct trans_info *ti)
137 broadcast_transition_info(ti);
138 waiting = update_change_state_wait(state_transition_counter, ti, psm_wake_unlock);
140 _D("Defer wake unlock");
147 static void psm_transition_sleep_to_normal(const struct trans_info *ti)
149 current = PSM_NORMAL;
151 broadcast_transition_info(ti);
152 device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL);
153 update_change_state_wait(state_transition_counter, ti, NULL);
156 static void psm_transition_sleep_to_sleep(const struct trans_info *ti)
160 broadcast_transition_info(ti);
161 device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL);
162 waiting = update_change_state_wait(state_transition_counter, ti, psm_wake_unlock);
164 _D("Defer wake unlock");
171 static void psm_transition_normal_to_poweroff(const struct trans_info *ti)
175 current = PSM_POWEROFF;
177 broadcast_transition_info(ti);
178 waiting = update_change_state_wait(state_transition_counter, ti, psm_trigger_poweroff);
180 _D("Defer poweroff");
184 psm_trigger_poweroff();
187 static int psm_transition_state_cb(void *data)
189 GList *action_list, *elem;
190 const struct trans_info *ti = NULL;
196 action_list = (GList *) data;
198 /* look for transition defined on the current state */
199 SYS_G_LIST_FOREACH(action_list, elem, ti) {
200 if (ti->curr == current)
209 _D("Transition power state: %s -> %s, reason=%d",
210 psm_name[current], psm_name[next], ti->reason);
213 ++state_transition_counter;
214 if (current == PSM_NORMAL) {
215 if (next == PSM_NORMAL)
216 psm_transition_normal_to_normal(ti);
217 else if (next == PSM_SLEEP)
218 psm_transition_normal_to_sleep(ti);
219 else if (next == PSM_POWEROFF)
220 psm_transition_normal_to_poweroff(ti);
221 } else if (current == PSM_SLEEP) {
222 if (next == PSM_NORMAL)
223 psm_transition_sleep_to_normal(ti);
224 else if (next == PSM_SLEEP)
225 psm_transition_sleep_to_sleep(ti);
231 void power_state_manager_init(void *data)
233 /* initialize state */
234 current = PSM_NORMAL;
235 device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL);
236 device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL);
238 register_notifier(DEVICE_NOTIFIER_KEY_PRESS, acquire_temporal_lock);
239 register_notifier(DEVICE_NOTIFIER_KEY_RELEASE, release_temporal_lock);
240 register_notifier(DEVICE_NOTIFIER_INPUT_TRANSITION_STATE, psm_transition_state_cb);
242 power_plugin_dbus_init(NULL);
245 static const struct device_ops power_state_manager_device_ops = {
246 DECLARE_NAME_LEN("power-control-plugin"),
247 .init = power_state_manager_init,
248 .disable_auto_init = true, /* initialized by core power module */
251 DEVICE_OPS_REGISTER(&power_state_manager_device_ops)