From: Youngjae Cho Date: Tue, 14 Dec 2021 06:38:45 +0000 (+0900) Subject: power: apply wait callback mechanism to all state transitions X-Git-Tag: accepted/tizen/unified/20220117.135039~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=92c421f3c06b5825d3c3513c792705bf7b35a009;p=platform%2Fcore%2Fapi%2Fdevice.git power: apply wait callback mechanism to all state transitions Change-Id: I09f2d72e3b0d49f775ed9087641cfe71f0ba424d Signed-off-by: Youngjae Cho --- diff --git a/include/power-internal.h b/include/power-internal.h index 3f32717..acc96e4 100644 --- a/include/power-internal.h +++ b/include/power-internal.h @@ -21,6 +21,7 @@ extern "C" { #endif +#include #include #include @@ -43,22 +44,35 @@ extern "C" { int device_power_poweroff(void); enum { - DEVICE_SLEEP_READY, - DEVICE_WAKEUP_READY = DEVICE_SLEEP_READY, - DEVICE_NOT_READY, + POWER_STATE_MIN_INDEX = 4, + POWER_STATE_NORMAL_INDEX = POWER_STATE_MIN_INDEX, + POWER_STATE_SLEEP_INDEX, + POWER_STATE_POWEROFF_INDEX, + POWER_STATE_REBOOT_INDEX, + POWER_STATE_MAX_INDEX, }; -struct device_event_info { - int event; /* 0: sleep, 1: wakeup */ +#define POWER_STATE_NORMAL (1ULL << POWER_STATE_NORMAL_INDEX) +#define POWER_STATE_SLEEP (1ULL << POWER_STATE_SLEEP_INDEX) +#define POWER_STATE_POWEROFF (1ULL << POWER_STATE_POWEROFF_INDEX) +#define POWER_STATE_REBOOT (1ULL << POWER_STATE_REBOOT_INDEX) +#define POWER_STATE_ALL ((1ULL << POWER_STATE_MAX_INDEX) - (1ULL << POWER_STATE_MIN_INDEX)) + +#define SIGNAME_CHANGE_STATE_TO_NORMAL "ChangeStateToNormal" +#define SIGNAME_CHANGE_STATE_TO_SLEEP "ChangeStateToSleep" +#define SIGNAME_CHANGE_STATE_TO_POWEROFF "ChangeStateToPowerOff" +#define SIGNAME_CHANGE_STATE_TO_REBOOT "ChangeStateToReboot" + +struct device_change_state_info { + uint64_t prev_state; + uint64_t next_state; int reason; }; -/* return DEVICE_SLEEP_READY or DEVICE_WAKEUP_READY on finishing todo list */ -typedef int (*sleep_callback) (const struct device_event_info *info, void *user_data); +typedef int (*change_state_callback) (const struct device_change_state_info *info, void *user_data); -/* return DEVICE_ERROR_NONE on success */ -int device_power_add_sleep_wait_callback(sleep_callback cb, void *user_data); -void device_power_remove_sleep_wait_callback(void); +int device_power_add_change_state_wait_callback(uint64_t state_bits, change_state_callback cb, void *user_data); +void device_power_remove_change_state_wait_callback(uint64_t state_bits); #ifdef __cplusplus } diff --git a/src/power-internal.c b/src/power-internal.c index a14b186..c89c565 100644 --- a/src/power-internal.c +++ b/src/power-internal.c @@ -6,18 +6,20 @@ #include "power-internal.h" #include "common.h" -#define CHANGE_STATE_DBUS_SIGNAME "ChangeState" #define DBUS_METHOD_SYNC_CALL_TIMEOUT_MS 10000 /* 10 second */ -#define EVENT_TYPE_SLEEP 0 -#define EVENT_TYPE_WAKEUP 1 - struct userdata { + change_state_callback callback; void *data; - sleep_callback callback; }; -static int change_state_signal_id = -1; +static int change_state_signal_id[POWER_STATE_MAX_INDEX]; +static const char *signame[POWER_STATE_MAX_INDEX] = { + [POWER_STATE_NORMAL_INDEX] = SIGNAME_CHANGE_STATE_TO_NORMAL, + [POWER_STATE_SLEEP_INDEX] = SIGNAME_CHANGE_STATE_TO_SLEEP, + [POWER_STATE_POWEROFF_INDEX] = SIGNAME_CHANGE_STATE_TO_POWEROFF, + [POWER_STATE_REBOOT_INDEX] = SIGNAME_CHANGE_STATE_TO_REBOOT, +}; static void signal_unsubscribed_callback(void *data) { @@ -34,9 +36,9 @@ static void signal_callback(GDBusConnection *connection, GVariant *parameters, gpointer user_data) { - struct device_event_info info; + struct device_change_state_info info; struct userdata *ud; - guint64 event_id; + uint64_t event_id; int retval; ud = (struct userdata *) user_data; @@ -44,16 +46,16 @@ static void signal_callback(GDBusConnection *connection, if (!ud || !ud->callback) return; - g_variant_get(parameters, "(iti)", &info.event, &event_id, &info.reason); + g_variant_get(parameters, "(ttti)", &info.prev_state, &info.next_state, &event_id, &info.reason); retval = ud->callback(&info, ud->data); - if (info.event == EVENT_TYPE_SLEEP && retval == DEVICE_SLEEP_READY) { + if (retval == 0) { g_dbus_connection_call_sync(connection, DEVICED_BUS_NAME, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, - "ConfirmSleepWait", - g_variant_new("(i)", event_id), + "ConfirmChangeStateWait", + g_variant_new("(t)", event_id), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_METHOD_SYNC_CALL_TIMEOUT_MS, @@ -62,53 +64,27 @@ static void signal_callback(GDBusConnection *connection, } } -int device_power_add_sleep_wait_callback(sleep_callback cb, void *data) +static int __device_power_add_change_state_wait_callback(GDBusConnection *connection, + int index, change_state_callback cb, void *data) { - GDBusConnection *connection; - GVariant *retval; - GError *err = NULL; struct userdata *ud; - if (change_state_signal_id != -1) + if (change_state_signal_id[index] > 0) return DEVICE_ERROR_ALREADY_IN_PROGRESS; - connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); - if (!connection) { - _E("Failed to get dbus connection, %s", err->message); - g_clear_error(&err); - return DEVICE_ERROR_OPERATION_FAILED; - } - - retval = g_dbus_connection_call_sync(connection, - DEVICED_BUS_NAME, - DEVICED_PATH_POWER, - DEVICED_INTERFACE_POWER, - "AddSleepWait", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_METHOD_SYNC_CALL_TIMEOUT_MS, - NULL, - &err); - if (!retval || err) { - _E("Failed to request AddSleepWait, %s", err->message); - g_error_free(err); - return DEVICE_ERROR_OPERATION_FAILED; - } - ud = malloc(sizeof(struct userdata)); if (!ud) { _E("Failed to alloc user data"); return DEVICE_ERROR_OPERATION_FAILED; } - ud->data = data; ud->callback = cb; + ud->data = data; - change_state_signal_id = g_dbus_connection_signal_subscribe(connection, + change_state_signal_id[index] = g_dbus_connection_signal_subscribe(connection, DEVICED_BUS_NAME, DEVICED_INTERFACE_POWER, - CHANGE_STATE_DBUS_SIGNAME, + signame[index], DEVICED_PATH_POWER, NULL, G_DBUS_SIGNAL_FLAGS_NONE, @@ -119,12 +95,63 @@ int device_power_add_sleep_wait_callback(sleep_callback cb, void *data) return DEVICE_ERROR_NONE; } -void device_power_remove_sleep_wait_callback(void) +int device_power_add_change_state_wait_callback(uint64_t state_bits, change_state_callback cb, void *data) +{ + GDBusConnection *connection; + GVariant *retgv = NULL; + GError *err = NULL; + + if (state_bits == 0) + return DEVICE_ERROR_NONE; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!connection) { + _E("Failed to get dbus connection, %s", err->message); + g_clear_error(&err); + return DEVICE_ERROR_OPERATION_FAILED; + } + + // subscribe signal + for (int index = 0; index < POWER_STATE_MAX_INDEX; ++index) + if((state_bits & (1ULL << index)) && (change_state_signal_id[index] == 0)) + __device_power_add_change_state_wait_callback(connection, index, cb, data); + + // add change state wait + retgv = g_dbus_connection_call_sync(connection, + DEVICED_BUS_NAME, + DEVICED_PATH_POWER, + DEVICED_INTERFACE_POWER, + "AddChangeStateWait", + g_variant_new("(t)", state_bits), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_METHOD_SYNC_CALL_TIMEOUT_MS, + NULL, + &err); + if (!retgv || err) { + _E("Failed to request AddChangeStateWait, %s", err->message); + g_error_free(err); + return DEVICE_ERROR_OPERATION_FAILED; + } + + return DEVICE_ERROR_NONE; +} + +static void __device_power_remove_change_state_wait_callback(GDBusConnection *connection, int index) +{ + if (change_state_signal_id[index] == 0) + return; + + g_dbus_connection_signal_unsubscribe(connection, change_state_signal_id[index]); + change_state_signal_id[index] = 0; +} + +void device_power_remove_change_state_wait_callback(uint64_t state_bits) { GError *err = NULL; GDBusConnection *connection; - if (change_state_signal_id == -1) + if (state_bits == 0) return; connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); @@ -134,15 +161,18 @@ void device_power_remove_sleep_wait_callback(void) return; } - g_dbus_connection_signal_unsubscribe(connection, change_state_signal_id); - change_state_signal_id = -1; + // unsubscribe signal + for (int index = 0; index < POWER_STATE_MAX_INDEX; ++index) + if((state_bits & (1ULL << index)) && (change_state_signal_id[index] > 0)) + __device_power_remove_change_state_wait_callback(connection, index); + //remove change state wait g_dbus_connection_call_sync(connection, DEVICED_BUS_NAME, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, - "RemoveSleepWait", - NULL, + "RemoveChangeStateWait", + g_variant_new("(t)", state_bits), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_METHOD_SYNC_CALL_TIMEOUT_MS,