handle_user_call,
handle_user_get_property,
};
-static GDBusConnection *ck_connection = NULL;
static GDBusNodeInfo *ck_session_info;
typedef struct
{
typedef struct
{
+ gchar *id;
+ gchar *path;
+ gboolean can_graphical;
+ gboolean can_multi_session;
+ gchar *active_session;
+} Login1Seat;
+
+static GList *login1_seats = NULL;
+
+static Login1Seat *add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal);
+static Login1Seat *find_login1_seat (const gchar *id);
+static void remove_login1_seat (GDBusConnection *connection, const gchar *id);
+
+typedef struct
+{
+ gchar *id;
gchar *path;
guint pid;
gboolean locked;
static void ready (void);
static void quit (int status);
+static gboolean status_timeout_cb (gpointer data);
static void check_status (const gchar *status);
static AccountsUser *get_accounts_user_by_uid (guint uid);
static AccountsUser *get_accounts_user_by_name (const gchar *username);
static void accounts_user_set_hidden (AccountsUser *user, gboolean hidden, gboolean emit_signal);
+static Login1Session *find_login1_session (const gchar *id);
static gboolean
kill_timeout_cb (gpointer data)
return G_SOURCE_REMOVE;
}
+static void
+switch_to_greeter_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+ GVariant *r;
+ GError *error = NULL;
+
+ r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+ if (error)
+ g_warning ("Failed to switch to greeter: %s\n", error->message);
+ g_clear_error (&error);
+
+ if (r)
+ {
+ check_status ("RUNNER SWITCH-TO-GREETER");
+ g_variant_unref (r);
+ }
+ else
+ check_status ("RUNNER SWITCH-TO-GREETER FAILED");
+}
+
+static void
+switch_to_user_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+ GVariant *r;
+ GError *error = NULL;
+ gchar *username = data, *status_text;
+
+ r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+ if (error)
+ g_warning ("Failed to switch to user: %s\n", error->message);
+ g_clear_error (&error);
+
+ if (r)
+ {
+ status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
+ g_variant_unref (r);
+ }
+ else
+ status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s FAILED", username);
+ check_status (status_text);
+
+ g_free (status_text);
+ g_free (username);
+}
+
+static void
+switch_to_guest_done_cb (GObject *bus, GAsyncResult *result, gpointer data)
+{
+ GVariant *r;
+ GError *error = NULL;
+
+ r = g_dbus_connection_call_finish (G_DBUS_CONNECTION (bus), result, &error);
+ if (error)
+ g_warning ("Failed to switch to guest: %s\n", error->message);
+ g_clear_error (&error);
+
+ if (r)
+ {
+ check_status ("RUNNER SWITCH-TO-GUEST");
+ g_variant_unref (r);
+ }
+ else
+ check_status ("RUNNER SWITCH-TO-GUEST FAILED");
+}
+
static void
handle_command (const gchar *command)
{
}
else if (strcmp (name, "WAIT") == 0)
{
+ const gchar *v;
+ int duration;
+
+ /* Stop status timeout */
+ if (status_timeout)
+ g_source_remove (status_timeout);
+ status_timeout = 0;
+
/* Use a main loop so that our DBus functions are still responsive */
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
- g_timeout_add_seconds (1, stop_loop, loop);
+ v = g_hash_table_lookup (params, "DURATION");
+ duration = v ? atoi (v) : 1;
+ if (duration < 1)
+ duration = 1;
+ g_timeout_add_seconds (duration, stop_loop, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
+
+ /* Restart status timeout */
+ status_timeout = g_timeout_add (status_timeout_ms, status_timeout_cb, NULL);
+ }
+ else if (strcmp (name, "ADD-SEAT") == 0)
+ {
+ const gchar *id, *v;
+ Login1Seat *seat;
+
+ id = g_hash_table_lookup (params, "ID");
+ seat = add_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id, TRUE);
+ v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
+ if (v)
+ seat->can_graphical = strcmp (v, "TRUE") == 0;
+ v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
+ if (v)
+ seat->can_multi_session = strcmp (v, "TRUE") == 0;
+ }
+ else if (strcmp (name, "ADD-LOCAL-X-SEAT") == 0)
+ {
+ GVariant *result;
+ const gchar *v;
+
+ v = g_hash_table_lookup (params, "DISPLAY");
+ result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager",
+ "org.freedesktop.DisplayManager",
+ "AddLocalXSeat",
+ g_variant_new ("(i)", v ? atoi (v) : -1),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ NULL);
+ g_variant_unref (result);
+ }
+ else if (strcmp (name, "UPDATE-SEAT") == 0)
+ {
+ Login1Seat *seat;
+ const gchar *id;
+
+ id = g_hash_table_lookup (params, "ID");
+ seat = find_login1_seat (id);
+ if (seat)
+ {
+ const gchar *v;
+ GVariantBuilder invalidated_properties;
+ GError *error = NULL;
+
+ g_variant_builder_init (&invalidated_properties, G_VARIANT_TYPE_ARRAY);
+
+ v = g_hash_table_lookup (params, "CAN-GRAPHICAL");
+ if (v)
+ {
+ seat->can_graphical = strcmp (v, "TRUE") == 0;
+ g_variant_builder_add (&invalidated_properties, "s", "CanGraphical");
+ }
+ v = g_hash_table_lookup (params, "CAN-MULTI-SESSION");
+ if (v)
+ {
+ seat->can_multi_session = strcmp (v, "TRUE") == 0;
+ g_variant_builder_add (&invalidated_properties, "s", "CanMultiSession");
+ }
+ v = g_hash_table_lookup (params, "ACTIVE-SESSION");
+ if (v)
+ {
+ g_free (seat->active_session);
+ seat->active_session = g_strdup (v);
+ g_variant_builder_add (&invalidated_properties, "s", "ActiveSession");
+ }
+
+ g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ NULL,
+ seat->path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)", "org.freedesktop.login1.Seat", NULL, &invalidated_properties),
+ &error);
+ if (error)
+ g_warning ("Failed to emit PropertiesChanged: %s", error->message);
+ g_clear_error (&error);
+ }
+ }
+ else if (strcmp (name, "REMOVE-SEAT") == 0)
+ {
+ const gchar *id;
+ id = g_hash_table_lookup (params, "ID");
+ remove_login1_seat (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL), id);
}
else if (strcmp (name, "LIST-SEATS") == 0)
{
g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Seats"),
G_VARIANT_TYPE ("(v)"),
G_DBUS_CALL_FLAGS_NONE,
- 1000,
+ G_MAXINT,
NULL,
NULL);
g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"),
G_VARIANT_TYPE ("(v)"),
G_DBUS_CALL_FLAGS_NONE,
- 1000,
+ G_MAXINT,
NULL,
NULL);
check_status (status->str);
g_string_free (status, TRUE);
}
+ else if (strcmp (name, "SEAT-CAN-SWITCH") == 0)
+ {
+ GVariant *result, *value;
+ gchar *status;
+
+ result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager/Seat0",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "CanSwitch"),
+ G_VARIANT_TYPE ("(v)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ NULL);
+
+ g_variant_get (result, "(v)", &value);
+ status = g_strdup_printf ("RUNNER SEAT-CAN-SWITCH CAN-SWITCH=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
+ g_variant_unref (value);
+ g_variant_unref (result);
+ check_status (status);
+ g_free (status);
+ }
+ else if (strcmp (name, "SEAT-HAS-GUEST-ACCOUNT") == 0)
+ {
+ GVariant *result, *value;
+ gchar *status;
+
+ result = g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager/Seat0",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)", "org.freedesktop.DisplayManager.Seat", "HasGuestAccount"),
+ G_VARIANT_TYPE ("(v)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ NULL);
+
+ g_variant_get (result, "(v)", &value);
+ status = g_strdup_printf ("RUNNER SEAT-HAS-GUEST-ACCOUNT HAS-GUEST-ACCOUNT=%s", g_variant_get_boolean (value) ? "TRUE" : "FALSE");
+ g_variant_unref (value);
+ g_variant_unref (result);
+ check_status (status);
+ g_free (status);
+ }
else if (strcmp (name, "SWITCH-TO-GREETER") == 0)
{
- g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
- "org.freedesktop.DisplayManager",
- "/org/freedesktop/DisplayManager/Seat0",
- "org.freedesktop.DisplayManager.Seat",
- "SwitchToGreeter",
- g_variant_new ("()"),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- 1000,
- NULL,
- NULL);
- check_status ("RUNNER SWITCH-TO-GREETER");
+ g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager/Seat0",
+ "org.freedesktop.DisplayManager.Seat",
+ "SwitchToGreeter",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ switch_to_greeter_done_cb,
+ NULL);
}
else if (strcmp (name, "SWITCH-TO-USER") == 0)
{
- gchar *status_text, *username;
+ const gchar *username;
username = g_hash_table_lookup (params, "USERNAME");
- g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
- "org.freedesktop.DisplayManager",
- "/org/freedesktop/DisplayManager/Seat0",
- "org.freedesktop.DisplayManager.Seat",
- "SwitchToUser",
- g_variant_new ("(ss)", username, ""),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- 1000,
- NULL,
- NULL);
- status_text = g_strdup_printf ("RUNNER SWITCH-TO-USER USERNAME=%s", username);
- check_status (status_text);
- g_free (status_text);
+ g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager/Seat0",
+ "org.freedesktop.DisplayManager.Seat",
+ "SwitchToUser",
+ g_variant_new ("(ss)", username, ""),
+ G_VARIANT_TYPE ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ switch_to_user_done_cb,
+ g_strdup (username));
}
else if (strcmp (name, "SWITCH-TO-GUEST") == 0)
{
- g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
- "org.freedesktop.DisplayManager",
- "/org/freedesktop/DisplayManager/Seat0",
- "org.freedesktop.DisplayManager.Seat",
- "SwitchToGuest",
- g_variant_new ("(s)", ""),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- 1000,
- NULL,
- NULL);
- check_status ("RUNNER SWITCH-TO-GUEST");
+ g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL),
+ "org.freedesktop.DisplayManager",
+ "/org/freedesktop/DisplayManager/Seat0",
+ "org.freedesktop.DisplayManager.Seat",
+ "SwitchToGuest",
+ g_variant_new ("(s)", ""),
+ G_VARIANT_TYPE ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ switch_to_guest_done_cb,
+ NULL);
}
else if (strcmp (name, "STOP-DAEMON") == 0)
stop_process (lightdm_process);
user->xsession = g_strdup (g_hash_table_lookup (params, "SESSION"));
g_string_append_printf (status_text, " SESSION=%s", user->xsession);
}
+
+ g_dbus_connection_emit_signal (accounts_connection,
+ NULL,
+ user->path,
+ "org.freedesktop.Accounts.User",
+ "Changed",
+ g_variant_new ("()"),
+ &error);
}
else
g_warning ("Unknown user %s", username);
- g_dbus_connection_emit_signal (accounts_connection,
- NULL,
- user->path,
- "org.freedesktop.Accounts.User",
- "Changed",
- g_variant_new ("()"),
- &error);
if (error)
g_warning ("Failed to emit Changed: %s", error->message);
g_clear_error (&error);
check_status (status_text);
g_free (status_text);
}
+ else if (strcmp (name, "UNLOCK-SESSION") == 0)
+ {
+ gchar *status_text, *id;
+ Login1Session *session;
+
+ id = g_hash_table_lookup (params, "SESSION");
+ session = find_login1_session (id);
+ if (session)
+ {
+ if (!session->locked)
+ g_warning ("Session %s is not locked", id);
+ session->locked = FALSE;
+ }
+ else
+ g_warning ("Unknown session %s", id);
+
+ status_text = g_strdup_printf ("RUNNER UNLOCK-SESSION SESSION=%s", id);
+ check_status (status_text);
+ g_free (status_text);
+ }
/* Forward to external processes */
else if (g_str_has_prefix (name, "SESSION-") ||
g_str_has_prefix (name, "GREETER-") ||
g_str_has_prefix (name, "XSERVER-") ||
+ g_str_has_prefix (name, "XMIR-") ||
+ g_str_has_prefix (name, "XVNC-") ||
strcmp (name, "UNITY-SYSTEM-COMPOSITOR") == 0)
{
GList *link;
{
ScriptLine *line;
+ status_timeout = 0;
+
line = get_script_line (NULL);
fail ("(timeout)", line ? line->text : NULL);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
static void
if (n_read > 0)
n_read = g_socket_receive (socket, buffer, length, NULL, &error);
if (error)
- g_warning ("Error reading from socket: %s", error->message);
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ n_read = 0;
+ else
+ g_warning ("Error reading from socket: %s", error->message);
+ }
g_clear_error (&error);
if (n_read == 0)
{
}
static CKSession *
-open_ck_session (GVariant *params)
+open_ck_session (GDBusConnection *connection, GVariant *params)
{
CKSession *session;
GString *cookie;
session->cookie = cookie->str;
g_string_free (cookie, FALSE);
session->path = g_strdup_printf ("/org/freedesktop/ConsoleKit/Session%d", ck_session_index++);
- session->id = g_dbus_connection_register_object (ck_connection,
+ session->id = g_dbus_connection_register_object (connection,
session->path,
ck_session_info->interfaces[0],
&ck_session_vtable,
{
GVariantBuilder params;
g_variant_builder_init (¶ms, G_VARIANT_TYPE ("a(sv)"));
- CKSession *session = open_ck_session (g_variant_builder_end (¶ms));
+ CKSession *session = open_ck_session (connection, g_variant_builder_end (¶ms));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
}
else if (strcmp (method_name, "OpenSessionWithParameters") == 0)
{
- CKSession *session = open_ck_session (g_variant_get_child_value (parameters, 0));
+ CKSession *session = open_ck_session (connection, g_variant_get_child_value (parameters, 0));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", session->cookie));
}
else if (strcmp (method_name, "GetSessionForCookie") == 0)
{
CKSession *session = user_data;
- if (strcmp (method_name, "Lock") == 0)
- {
+ if (strcmp (method_name, "GetXDGRuntimeDir") == 0 && !g_key_file_get_boolean (config, "test-runner-config", "ck-no-xdg-runtime", NULL))
+ {
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "/run/console-kit"));
+ }
+ else if (strcmp (method_name, "Lock") == 0)
+ {
if (!session->locked)
check_status ("CONSOLE-KIT LOCK-SESSION");
session->locked = TRUE;
{
handle_ck_call,
};
+ const gchar *ck_session_interface_old =
+ "<node>"
+ " <interface name='org.freedesktop.ConsoleKit.Session'>"
+ " <method name='Lock'/>"
+ " <method name='Unlock'/>"
+ " <method name='Activate'/>"
+ " </interface>"
+ "</node>";
const gchar *ck_session_interface =
"<node>"
" <interface name='org.freedesktop.ConsoleKit.Session'>"
+ " <method name='GetXDGRuntimeDir'>"
+ " <arg name='dir' direction='out' type='s'/>"
+ " </method>"
" <method name='Lock'/>"
" <method name='Unlock'/>"
" <method name='Activate'/>"
GDBusNodeInfo *ck_info;
GError *error = NULL;
- ck_connection = connection;
-
ck_info = g_dbus_node_info_new_for_xml (ck_interface, &error);
if (error)
g_warning ("Failed to parse D-Bus interface: %s", error->message);
g_clear_error (&error);
if (!ck_info)
return;
- ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface, &error);
+ if (g_key_file_get_boolean (config, "test-runner-config", "ck-no-xdg-runtime", NULL))
+ ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface_old, &error);
+ else
+ ck_session_info = g_dbus_node_info_new_for_xml (ck_session_interface, &error);
if (error)
g_warning ("Failed to parse D-Bus interface: %s", error->message);
g_clear_error (&error);
NULL);
}
+static void
+handle_login1_seat_call (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
+}
+
+static GVariant *
+handle_login1_seat_get_property (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GError **error,
+ gpointer user_data)
+{
+ Login1Seat *seat = user_data;
+
+ if (strcmp (property_name, "CanGraphical") == 0)
+ return g_variant_new_boolean (seat->can_graphical);
+ else if (strcmp (property_name, "CanMultiSession") == 0)
+ return g_variant_new_boolean (seat->can_multi_session);
+ else if (strcmp (property_name, "Id") == 0)
+ return g_variant_new_string (seat->id);
+ else if (strcmp (property_name, "ActiveSession") == 0)
+ {
+ if (seat->active_session)
+ {
+ gchar *path;
+ GVariant *ret;
+
+ path = g_strdup_printf ("/org/freedesktop/login1/session/%s", seat->active_session);
+ ret = g_variant_new ("(so)", seat->active_session, path);
+ g_free (path);
+
+ return ret;
+ }
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+static Login1Seat *
+add_login1_seat (GDBusConnection *connection, const gchar *id, gboolean emit_signal)
+{
+ Login1Seat *seat;
+ GError *error = NULL;
+ GDBusNodeInfo *login1_seat_info;
+
+ const gchar *login1_seat_interface =
+ "<node>"
+ " <interface name='org.freedesktop.login1.Seat'>"
+ " <property name='CanGraphical' type='b' access='read'/>"
+ " <property name='CanMultiSession' type='b' access='read'/>"
+ " <property name='ActiveSession' type='(so)' access='read'/>"
+ " <property name='Id' type='s' access='read'/>"
+ " </interface>"
+ "</node>";
+ static const GDBusInterfaceVTable login1_seat_vtable =
+ {
+ handle_login1_seat_call,
+ handle_login1_seat_get_property,
+ };
+
+ seat = g_malloc0 (sizeof (Login1Seat));
+ login1_seats = g_list_append (login1_seats, seat);
+ seat->id = g_strdup (id);
+ seat->path = g_strdup_printf ("/org/freedesktop/login1/seat/%s", seat->id);
+ seat->can_graphical = TRUE;
+ seat->can_multi_session = TRUE;
+ seat->active_session = NULL;
+
+ login1_seat_info = g_dbus_node_info_new_for_xml (login1_seat_interface, &error);
+ if (error)
+ g_warning ("Failed to parse login1 seat D-Bus interface: %s", error->message);
+ g_clear_error (&error);
+ if (!login1_seat_info)
+ return NULL;
+
+ g_dbus_connection_register_object (connection,
+ seat->path,
+ login1_seat_info->interfaces[0],
+ &login1_seat_vtable,
+ seat,
+ NULL,
+ &error);
+ if (error)
+ g_warning ("Failed to register login1 seat: %s", error->message);
+ g_clear_error (&error);
+ g_dbus_node_info_unref (login1_seat_info);
+
+ if (emit_signal)
+ {
+ g_dbus_connection_emit_signal (connection,
+ NULL,
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SeatNew",
+ g_variant_new ("(so)", seat->id, seat->path),
+ &error);
+ if (error)
+ g_warning ("Failed to emit SeatNew: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ return seat;
+}
+
+static Login1Seat *
+find_login1_seat (const gchar *id)
+{
+ Login1Seat *seat;
+ GList *link;
+
+ for (link = login1_seats; link; link = link->next)
+ {
+ seat = link->data;
+ if (strcmp (seat->id, id) == 0)
+ return seat;
+ }
+
+ return NULL;
+}
+
+static void
+remove_login1_seat (GDBusConnection *connection, const gchar *id)
+{
+ Login1Seat *seat;
+ GError *error = NULL;
+
+ seat = find_login1_seat (id);
+ if (!seat)
+ return;
+
+ g_dbus_connection_emit_signal (connection,
+ NULL,
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SeatRemoved",
+ g_variant_new ("(so)", seat->id, seat->path),
+ &error);
+ if (error)
+ g_warning ("Failed to emit SeatNew: %s", error->message);
+ g_clear_error (&error);
+
+ login1_seats = g_list_remove (login1_seats, seat);
+ g_free (seat->id);
+ g_free (seat->path);
+ g_free (seat->active_session);
+ g_free (seat);
+}
+
static void
handle_login1_session_call (GDBusConnection *connection,
const gchar *sender,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
- Login1Session *session = user_data;
-
- if (strcmp (method_name, "Lock") == 0)
- {
- if (!session->locked)
- check_status ("LOGIN1 LOCK-SESSION");
- session->locked = TRUE;
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
- }
- else if (strcmp (method_name, "Unlock") == 0)
- {
- if (session->locked)
- check_status ("LOGIN1 UNLOCK-SESSION");
- session->locked = FALSE;
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
- }
- else if (strcmp (method_name, "Activate") == 0)
- {
- gchar *status = g_strdup_printf ("LOGIN1 ACTIVATE-SESSION SESSION=%s", strrchr (object_path, '/') + 1);
- check_status (status);
- g_free (status);
-
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
- }
- else
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
+ /*Login1Session *session = user_data;*/
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name);
}
static Login1Session *
-open_login1_session (GDBusConnection *connection,
- GVariant *params)
+create_login1_session (GDBusConnection *connection)
{
Login1Session *session;
GError *error = NULL;
const gchar *login1_session_interface =
"<node>"
" <interface name='org.freedesktop.login1.Session'>"
- " <method name='Lock'/>"
- " <method name='Unlock'/>"
- " <method name='Activate'/>"
" </interface>"
"</node>";
static const GDBusInterfaceVTable login1_session_vtable =
session = g_malloc0 (sizeof (Login1Session));
login1_sessions = g_list_append (login1_sessions, session);
- session->path = g_strdup_printf("/org/freedesktop/login1/Session/c%d",
- login1_session_index++);
-
-
+ session->id = g_strdup_printf ("c%d", login1_session_index++);
+ session->path = g_strdup_printf ("/org/freedesktop/login1/Session/%s", session->id);
- login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface,
- &error);
+ login1_session_info = g_dbus_node_info_new_for_xml (login1_session_interface, &error);
if (error)
- g_warning ("Failed to parse login1 session D-Bus interface: %s",
- error->message);
+ g_warning ("Failed to parse login1 session D-Bus interface: %s", error->message);
g_clear_error (&error);
if (!login1_session_info)
return NULL;
return session;
}
+static Login1Session *
+find_login1_session (const gchar *id)
+{
+ GList *link;
+
+ for (link = login1_sessions; link; link = link->next)
+ {
+ Login1Session *session = link->data;
+ if (strcmp (session->id, id) == 0)
+ return session;
+ }
+
+ return NULL;
+}
static void
handle_login1_call (GDBusConnection *connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
-
- if (strcmp (method_name, "GetSessionByPID") == 0)
+ if (strcmp (method_name, "ListSeats") == 0)
{
- /* Look for a session with our PID, and create one if we don't have one
- already. */
+ GVariantBuilder seats;
GList *link;
- guint pid;
- Login1Session *ret = NULL;
- g_variant_get (parameters, "(u)", &pid);
+ g_variant_builder_init (&seats, G_VARIANT_TYPE ("a(so)"));
+ for (link = login1_seats; link; link = link->next)
+ {
+ Login1Seat *seat = link->data;
+ g_variant_builder_add (&seats, "(so)", seat->id, seat->path);
+ }
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &seats));
+ }
+ else if (strcmp (method_name, "CreateSession") == 0)
+ {
+ /* Note: this is not the full CreateSession as used by logind, we just
+ need one so our fake PAM stack can communicate with this service */
+ Login1Session *session = create_login1_session (connection);
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(so)", session->id, session->path));
+
+ }
+ else if (strcmp (method_name, "LockSession") == 0)
+ {
+ const gchar *id;
+ Login1Session *session;
- for (link = login1_sessions; link; link = link->next)
+ g_variant_get (parameters, "(&s)", &id);
+ session = find_login1_session (id);
+ if (!session)
{
- Login1Session *session;
- session = link->data;
- if (session->pid == pid)
- {
- ret = session;
- break;
- }
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+ return;
+ }
+
+ if (!session->locked)
+ {
+ gchar *status = g_strdup_printf ("LOGIN1 LOCK-SESSION SESSION=%s", id);
+ check_status (status);
+ g_free (status);
}
- /* Not found */
- if (!ret)
- ret = open_login1_session (connection, parameters);
+ session->locked = TRUE;
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+ }
+ else if (strcmp (method_name, "UnlockSession") == 0)
+ {
+ const gchar *id;
+ Login1Session *session;
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new("(o)", ret->path));
+ g_variant_get (parameters, "(&s)", &id);
+ session = find_login1_session (id);
+ if (!session)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+ return;
+ }
+ if (session->locked)
+ {
+ gchar *status = g_strdup_printf ("LOGIN1 UNLOCK-SESSION SESSION=%s", id);
+ check_status (status);
+ g_free (status);
+ }
+ session->locked = FALSE;
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+ }
+ else if (strcmp (method_name, "ActivateSession") == 0)
+ {
+ const gchar *id;
+ Login1Session *session;
+
+ g_variant_get (parameters, "(&s)", &id);
+ session = find_login1_session (id);
+ if (!session)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such session: %s", id);
+ return;
+ }
+
+ gchar *status = g_strdup_printf ("LOGIN1 ACTIVATE-SESSION SESSION=%s", id);
+ check_status (status);
+ g_free (status);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
}
else if (strcmp (method_name, "CanReboot") == 0)
{
const gchar *login1_interface =
"<node>"
" <interface name='org.freedesktop.login1.Manager'>"
- " <method name='GetSessionByPID'>"
- " <arg name='pid' type='u' direction='in'/>"
- " <arg name='session' type='o' direction='out'/>"
+ " <method name='ListSeats'>"
+ " <arg name='seats' type='a(so)' direction='out'/>"
+ " </method>"
+ " <method name='CreateSession'>"
+ " <arg name='id' type='s' direction='out'/>"
+ " <arg name='path' type='o' direction='out'/>"
+ " </method>"
+ " <method name='LockSession'>"
+ " <arg name='id' type='s' direction='in'/>"
+ " </method>"
+ " <method name='UnlockSession'>"
+ " <arg name='id' type='s' direction='in'/>"
+ " </method>"
+ " <method name='ActivateSession'>"
+ " <arg name='id' type='s' direction='in'/>"
" </method>"
" <method name='CanReboot'>"
" <arg name='result' direction='out' type='s'/>"
" <method name='Hibernate'>"
" <arg name='interactive' direction='in' type='b'/>"
" </method>"
+ " <signal name='SeatNew'>"
+ " <arg name='seat' type='so'/>"
+ " </signal>"
+ " <signal name='SeatRemoved'>"
+ " <arg name='seat' type='so'/>"
+ " </signal>"
" </interface>"
"</node>";
static const GDBusInterfaceVTable login1_vtable =
handle_login1_call,
};
GDBusNodeInfo *login1_info;
+ Login1Seat *seat0;
GError *error = NULL;
login1_info = g_dbus_node_info_new_for_xml (login1_interface, &error);
g_clear_error (&error);
g_dbus_node_info_unref (login1_info);
+ /* We always have seat0 */
+ seat0 = add_login1_seat (connection, "seat0", FALSE);
+ if (g_key_file_has_key (config, "test-runner-config", "seat0-can-graphical", NULL))
+ seat0->can_graphical = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-graphical", NULL);
+ if (g_key_file_has_key (config, "test-runner-config", "seat0-can-multi-session", NULL))
+ seat0->can_multi_session = g_key_file_get_boolean (config, "test-runner-config", "seat0-can-multi-session", NULL);
+
service_count--;
if (service_count == 0)
ready ();
if (u->uid == uid)
return u;
}
-
+
return NULL;
}
status = g_string_new ("RUNNER DBUS-PROPERTIES-CHANGED");
g_string_append_printf (status, " PATH=%s", object_path);
g_string_append_printf (status, " INTERFACE=%s", interface);
- for (i = 0; g_variant_iter_loop (changed_properties, "(&sv)", &name, &value); i++)
+ for (i = 0; g_variant_iter_loop (changed_properties, "{&sv}", &name, &value); i++)
{
if (i == 0)
g_string_append (status, " CHANGED=");
else
g_string_append (status, ",");
g_string_append (status, name);
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao")))
+ {
+ GVariantIter iter;
+ const gchar *path;
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_loop (&iter, "&o", &path))
+ g_string_append_printf (status, ":%s", path);
+ }
}
for (i = 0; g_variant_iter_loop (invalidated_properties, "&s", &name); i++)
{
if (!g_file_test (temp_dir, G_FILE_TEST_EXISTS))
break;
i++;
- }
+ }
g_mkdir_with_parents (temp_dir, 0755);
g_setenv ("LIGHTDM_TEST_ROOT", temp_dir, TRUE);
/* Set up a skeleton file system */
g_mkdir_with_parents (g_strdup_printf ("%s/etc", temp_dir), 0755);
+ g_mkdir_with_parents (g_strdup_printf ("%s/run", temp_dir), 0755);
g_mkdir_with_parents (g_strdup_printf ("%s/usr/share", temp_dir), 0755);
g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/sessions", temp_dir), 0755);
g_mkdir_with_parents (g_strdup_printf ("%s/usr/share/lightdm/remote-sessions", temp_dir), 0755);
if (!g_key_file_has_key (config, "test-runner-config", "have-config", NULL) || g_key_file_get_boolean (config, "test-runner-config", "have-config", NULL))
if (system (g_strdup_printf ("cp %s %s/etc/lightdm/lightdm.conf", config_path, temp_dir)))
perror ("Failed to copy configuration");
+ if (system (g_strdup_printf ("cp %s/tests/data/keys.conf %s/etc/lightdm/", SRCDIR, temp_dir)))
+ perror ("Failed to copy key configuration");
additional_system_config = g_key_file_get_string (config, "test-runner-config", "additional-system-config", NULL);
if (additional_system_config)