#include <glib.h>
#include <gio/gio.h>
+#include "device-error.h"
+
/**
* @platform
* @brief Power off the device.
enum sleep_ready {
DEVICE_SLEEP_READY,
+ DEVICE_WAKEUP_READY = DEVICE_SLEEP_READY,
DEVICE_SLEEP_NOT_READY,
};
+enum device_siginfo {
+ DEVICE_SIG_SLEEP_SHORTKEY,
+ DEVICE_SIG_WAKEUP_SHORTKEY,
+ DEVICE_SIG_UNKNOWN,
+};
+
/* This callback is invoked when system is going to sleep.
- * Return DEVICE_SLEEP_READY to notify system that I am ready to sleep.
- * sleep_time_ms: realtime in milisecond when the sleep signal emitted */
-typedef int (*sleep_callback) (guint64 sleep_time_ms, void *user_data);
+ * There can be only one callbacks per process.
+ * Return DEVICE_SLEEP_READY to notify system that I am ready to sleep
+ * when siginfo == DEVICE_SIG_SLEEP_SHORTKEY. */
+typedef int (*sleep_callback) (guint64 sig_time_ms, enum device_siginfo siginfo, void *user_data);
/* return DEVICE_ERROR_NONE on success */
int device_power_add_sleep_callback(sleep_callback cb, void *user_data);
#include <stdlib.h>
+#include <string.h>
#include <gio/gio.h>
#include <libsyscommon/libgdbus.h>
#include "common.h"
#define SLEEP_DBUS_SIGNAME "sleep"
+#define WAKEUP_DBUS_SIGNAME "wakeup"
#define DBUS_METHOD_SYNC_CALL_TIMEOUT_MS 10000 /* 10 second */
struct userdata {
sleep_callback callback;
};
-static int signal_subscribe_id = -1;
+static int sleep_signal_subscribe_id = -1;
+static int wakeup_signal_subscribe_id = -1;
static void signal_unsubscribed_callback(void *data)
{
free(ud);
}
-static void signal_callback(GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
+static void handle_sleep_signal(GDBusConnection *connection, GVariant *parameters, void *user_data)
{
- guint64 sleep_time_ms;
- guint64 sleep_id;
struct userdata *ud = (struct userdata *) user_data;
+ guint64 sig_time_ms;
+ guint64 sleep_id;
int retval;
- g_variant_get(parameters, "(tt)", &sleep_time_ms, &sleep_id);
-
if (!ud || !ud->callback)
return;
- retval = ud->callback(sleep_time_ms, ud->data);
+ g_variant_get(parameters, "(tt)", &sig_time_ms, &sleep_id);
+
+ retval = ud->callback(sig_time_ms, DEVICE_SIG_SLEEP_SHORTKEY, ud->data);
if (retval == DEVICE_SLEEP_READY) {
g_dbus_connection_call_sync(connection,
DEVICED_BUS_NAME,
}
}
+static void handle_wakeup_signal(GVariant *parameters, void *user_data)
+{
+ struct userdata *ud = (struct userdata *) user_data;
+ guint64 sig_time_ms;
+ enum device_siginfo siginfo;
+
+ if (!ud || !ud->callback)
+ return;
+
+ g_variant_get(parameters, "(tt)", &sig_time_ms, &siginfo);
+ ud->callback(sig_time_ms, siginfo, ud->data);
+}
+
+static void signal_callback(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+
+ if (!strncmp(signal_name, SLEEP_DBUS_SIGNAME, sizeof(SLEEP_DBUS_SIGNAME)))
+ handle_sleep_signal(connection, parameters, user_data);
+ else if (!strncmp(signal_name, WAKEUP_DBUS_SIGNAME, sizeof(WAKEUP_DBUS_SIGNAME)))
+ handle_wakeup_signal(parameters, user_data);
+}
+
int device_power_add_sleep_callback(sleep_callback cb, void *data)
{
GDBusConnection *connection;
GError *err = NULL;
struct userdata *ud;
- if (signal_subscribe_id != -1)
+ if (sleep_signal_subscribe_id != -1)
return DEVICE_ERROR_ALREADY_IN_PROGRESS;
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
ud->data = data;
ud->callback = cb;
- signal_subscribe_id = g_dbus_connection_signal_subscribe(connection,
+ sleep_signal_subscribe_id = g_dbus_connection_signal_subscribe(connection,
DEVICED_BUS_NAME,
DEVICED_INTERFACE_POWER,
SLEEP_DBUS_SIGNAME,
ud,
signal_unsubscribed_callback);
+ wakeup_signal_subscribe_id = g_dbus_connection_signal_subscribe(connection,
+ DEVICED_BUS_NAME,
+ DEVICED_INTERFACE_POWER,
+ WAKEUP_DBUS_SIGNAME,
+ DEVICED_PATH_POWER,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ signal_callback,
+ ud,
+ NULL);
+
return DEVICE_ERROR_NONE;
}
GError *err = NULL;
GDBusConnection *connection;
- if (signal_subscribe_id == -1)
+ if (sleep_signal_subscribe_id == -1)
return;
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
return;
}
- g_dbus_connection_signal_unsubscribe(connection, signal_subscribe_id);
- signal_subscribe_id = -1;
+ g_dbus_connection_signal_unsubscribe(connection, sleep_signal_subscribe_id);
+ sleep_signal_subscribe_id = -1;
+ g_dbus_connection_signal_unsubscribe(connection, wakeup_signal_subscribe_id);
+ wakeup_signal_subscribe_id = -1;
g_dbus_connection_call_sync(connection,
DEVICED_BUS_NAME,