power: apply wait callback mechanism to all state transitions 84/267984/8
authorYoungjae Cho <y0.cho@samsung.com>
Tue, 14 Dec 2021 06:38:45 +0000 (15:38 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Wed, 15 Dec 2021 08:33:57 +0000 (17:33 +0900)
Change-Id: I09f2d72e3b0d49f775ed9087641cfe71f0ba424d
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
include/power-internal.h
src/power-internal.c

index 3f32717..acc96e4 100644 (file)
@@ -21,6 +21,7 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
 #include <glib.h>
 #include <gio/gio.h>
 
@@ -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
 }
index a14b186..c89c565 100644 (file)
@@ -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,