#define UNIT_CONTROL_INTERFACE "org.tizen.Activationd"
#define UNIT_CONTROL_OBJ_PATH "/org/tizen/activationd"
+#define SYSTEMD_SERVICE "org.freedesktop.systemd1"
+#define SYSTEMD_INTERFACE "org.freedesktop.systemd1.Manager"
+#define SYSTEMD_OBJ_PATH "/org/freedesktop/systemd1"
+
+struct generic_user_data {
+ actd_unit_cb cb;
+ void *user_data;
+};
+
+static void generic_callback(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ struct generic_user_data *data = user_data;
+ GVariant *var;
+ GError *err = NULL;
+
+ var = g_dbus_connection_call_finish(source_object, res, &err);
+
+ data->cb(var, data->user_data, err);
+
+ if (err)
+ g_error_free(err);
+
+ free(data);
+}
+
+const char *translate_to_systemd(const char *method)
+{
+ if (strcmp(method, "Start") == 0)
+ return "StartUnit";
+ if (strcmp(method, "Stop") == 0)
+ return "StopUnit";
+ if (strcmp(method, "Restart") == 0)
+ return "RestartUnit";
+
+ return NULL;
+}
+
static int call_uc(GBusType bus_type, const char *method, const char *unit)
{
int ret;
if (!bus)
return -1;
- msg = g_dbus_connection_call_sync(bus,
- UNIT_CONTROL_NAME,
- UNIT_CONTROL_OBJ_PATH,
- UNIT_CONTROL_INTERFACE,
- method,
- g_variant_new("(s)", unit),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL);
- if (!msg)
- return -EBADMSG;
-
- g_variant_get(msg, "(s)", &result);
- if (g_strcmp0(result, "ok") == 0)
+ if (bus_type == G_BUS_TYPE_SESSION) {
+ msg = g_dbus_connection_call_sync(bus,
+ SYSTEMD_SERVICE,
+ SYSTEMD_OBJ_PATH,
+ SYSTEMD_INTERFACE,
+ translate_to_systemd(method),
+ g_variant_new("(ss)", unit, "replace"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (!msg)
+ return -EBADMSG;
+
ret = 0;
- else
- ret = -1;
+ } else {
+ /* we assume that activationd runs on system bus and can be used as a proxy */
+ msg = g_dbus_connection_call_sync(bus,
+ UNIT_CONTROL_NAME,
+ UNIT_CONTROL_OBJ_PATH,
+ UNIT_CONTROL_INTERFACE,
+ method,
+ g_variant_new("(s)", unit),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (!msg)
+ return -EBADMSG;
+
+ g_variant_get(msg, "(s)", &result);
+ if (g_strcmp0(result, "ok") == 0)
+ ret = 0;
+ else
+ ret = -1;
+
+ g_free(result);
+ }
- g_free(result);
return ret;
}
static int call_uc_async(GBusType bus_type, const char *method, const char *unit, actd_unit_cb cb, void *user_data)
{
GDBusConnection *bus;
+ struct generic_user_data *data = user_data;
bus = g_bus_get_sync(bus_type, NULL, NULL);
if (!bus)
return -1;
- g_dbus_connection_call(bus,
- UNIT_CONTROL_NAME,
- UNIT_CONTROL_OBJ_PATH,
- UNIT_CONTROL_INTERFACE,
- method,
- g_variant_new("(s)", unit),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- (GAsyncReadyCallback) cb,
- NULL);
+ data = malloc(sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->user_data = user_data;
+ data->cb = cb;
+
+ if (bus_type == G_BUS_TYPE_SESSION) {
+ g_dbus_connection_call(bus,
+ SYSTEMD_SERVICE,
+ SYSTEMD_OBJ_PATH,
+ SYSTEMD_INTERFACE,
+ translate_to_systemd(method),
+ g_variant_new("(ss)", unit, "replace"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) generic_callback,
+ data);
+ } else {
+ g_dbus_connection_call(bus,
+ UNIT_CONTROL_NAME,
+ UNIT_CONTROL_OBJ_PATH,
+ UNIT_CONTROL_INTERFACE,
+ method,
+ g_variant_new("(s)", unit),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) generic_callback,
+ data);
+ }
return 0;
}