]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Give the property values when emitting the PropertiesChanged signal
authorRobert Ancell <robert.ancell@canonical.com>
Thu, 17 Apr 2014 04:03:45 +0000 (16:03 +1200)
committerRobert Ancell <robert.ancell@canonical.com>
Thu, 17 Apr 2014 04:03:45 +0000 (16:03 +1200)
src/lightdm.c
tests/scripts/dbus.conf
tests/src/test-runner.c

index 97326d34d031907bd3dfe6c8fbbbc7540037917e..74599fce4554dcd83cd425854442d162196233c2 100644 (file)
@@ -56,11 +56,14 @@ static gint exit_code = EXIT_SUCCESS;
 typedef struct
 {
     gchar *path;
-    gchar *parent_path;
-    gchar *property_name;
-    gchar *removed_signal;
     guint bus_id;
-} BusEntry;
+} SeatBusEntry;
+typedef struct
+{
+    gchar *path;
+    gchar *seat_path;
+    guint bus_id;
+} SessionBusEntry;
 
 #define LIGHTDM_BUS_NAME "org.freedesktop.DisplayManager"
 
@@ -245,6 +248,44 @@ display_manager_seat_removed_cb (DisplayManager *display_manager, Seat *seat)
     g_string_free (next_types, TRUE);
 }
 
+static GVariant *
+get_seat_list (void)
+{
+    GVariantBuilder builder;
+    GHashTableIter iter;
+    gpointer value;
+
+    g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
+    g_hash_table_iter_init (&iter, seat_bus_entries);
+    while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+        SeatBusEntry *entry = value;
+        g_variant_builder_add_value (&builder, g_variant_new_object_path (entry->path));
+    }
+
+    return g_variant_builder_end (&builder);
+}
+
+static GVariant *
+get_session_list (const gchar *seat_path)
+{
+    GVariantBuilder builder;
+    GHashTableIter iter;
+    gpointer value;
+
+    g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
+
+    g_hash_table_iter_init (&iter, session_bus_entries);
+    while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+        SessionBusEntry *entry = value;
+        if (seat_path == NULL || strcmp (entry->seat_path, seat_path) == 0)
+            g_variant_builder_add_value (&builder, g_variant_new_object_path (entry->path));
+    }
+
+    return g_variant_builder_end (&builder);
+}
+
 static GVariant *
 handle_display_manager_get_property (GDBusConnection       *connection,
                                      const gchar           *sender,
@@ -254,42 +295,12 @@ handle_display_manager_get_property (GDBusConnection       *connection,
                                      GError               **error,
                                      gpointer               user_data)
 {
-    GVariant *result = NULL;
-
     if (g_strcmp0 (property_name, "Seats") == 0)
-    {
-        GVariantBuilder *builder;
-        GHashTableIter iter;
-        gpointer value;
-
-        builder = g_variant_builder_new (G_VARIANT_TYPE ("ao"));
-        g_hash_table_iter_init (&iter, seat_bus_entries);
-        while (g_hash_table_iter_next (&iter, NULL, &value))
-        {
-            BusEntry *entry = value;
-            g_variant_builder_add_value (builder, g_variant_new_object_path (entry->path));
-        }
-        result = g_variant_builder_end (builder);
-        g_variant_builder_unref (builder);
-    }
+        return get_seat_list ();
     else if (g_strcmp0 (property_name, "Sessions") == 0)
-    {
-        GVariantBuilder *builder;
-        GHashTableIter iter;
-        gpointer value;
-
-        builder = g_variant_builder_new (G_VARIANT_TYPE ("ao"));
-        g_hash_table_iter_init (&iter, session_bus_entries);
-        while (g_hash_table_iter_next (&iter, NULL, &value))
-        {
-            BusEntry *entry = value;
-            g_variant_builder_add_value (builder, g_variant_new_object_path (entry->path));
-        }
-        result = g_variant_builder_end (builder);
-        g_variant_builder_unref (builder);
-    }
+        return get_session_list (NULL);
 
-    return result;
+    return NULL;
 }
 
 static void
@@ -334,7 +345,7 @@ handle_display_manager_call (GDBusConnection       *connection,
 
         if (display_manager_add_seat (display_manager, seat))
         {
-            BusEntry *entry;
+            SeatBusEntry *entry;
 
             entry = g_hash_table_lookup (seat_bus_entries, seat);
             g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", entry->path));
@@ -375,7 +386,7 @@ handle_display_manager_call (GDBusConnection       *connection,
 
         if (display_manager_add_seat (display_manager, seat))
         {
-            BusEntry *entry;
+            SeatBusEntry *entry;
 
             entry = g_hash_table_lookup (seat_bus_entries, seat);
             g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", entry->path));
@@ -396,31 +407,20 @@ handle_seat_get_property (GDBusConnection       *connection,
                           gpointer               user_data)
 {
     Seat *seat = user_data;
-    GVariant *result = NULL;
 
     if (g_strcmp0 (property_name, "CanSwitch") == 0)
-        result = g_variant_new_boolean (seat_get_can_switch (seat));
+        return g_variant_new_boolean (seat_get_can_switch (seat));
     if (g_strcmp0 (property_name, "HasGuestAccount") == 0)
-        result = g_variant_new_boolean (seat_get_allow_guest (seat));
+        return g_variant_new_boolean (seat_get_allow_guest (seat));
     else if (g_strcmp0 (property_name, "Sessions") == 0)
     {
-        GVariantBuilder *builder;
-        GList *link;
+        SeatBusEntry *entry;
 
-        builder = g_variant_builder_new (G_VARIANT_TYPE ("ao"));
-        for (link = seat_get_sessions (seat); link; link = link->next)
-        {
-            Session *session = link->data;
-            BusEntry *entry;
-            entry = g_hash_table_lookup (session_bus_entries, session);
-            if (entry)
-                g_variant_builder_add_value (builder, g_variant_new_object_path (entry->path));
-        }
-        result = g_variant_builder_end (builder);
-        g_variant_builder_unref (builder);
+        entry = g_hash_table_lookup (seat_bus_entries, seat);
+        return get_session_list (entry->path);
     }
 
-    return result;
+    return NULL;
 }
 
 static void
@@ -511,11 +511,11 @@ handle_session_get_property (GDBusConnection       *connection,
                              gpointer               user_data)
 {
     Session *session = user_data;
-    BusEntry *entry;
+    SessionBusEntry *entry;
 
     entry = g_hash_table_lookup (session_bus_entries, session);
     if (g_strcmp0 (property_name, "Seat") == 0)
-        return g_variant_new_object_path (entry ? entry->parent_path : "");
+        return g_variant_new_object_path (entry ? entry->seat_path : "");
     else if (g_strcmp0 (property_name, "UserName") == 0)
         return g_variant_new_string (session_get_username (session));
 
@@ -545,34 +545,45 @@ handle_session_call (GDBusConnection       *connection,
     }
 }
 
-static BusEntry *
-bus_entry_new (const gchar *path, const gchar *parent_path, const gchar *property_name, const gchar *removed_signal)
+static SeatBusEntry *
+seat_bus_entry_new (const gchar *path)
 {
-    BusEntry *entry;
+    SeatBusEntry *entry;
 
-    entry = g_malloc0 (sizeof (BusEntry));
+    entry = g_malloc0 (sizeof (SeatBusEntry));
     entry->path = g_strdup (path);
-    entry->parent_path = g_strdup (parent_path);
-    entry->property_name = g_strdup (property_name);
-    entry->removed_signal = g_strdup (removed_signal);
+
+    return entry;
+}
+
+static SessionBusEntry *
+session_bus_entry_new (const gchar *path, const gchar *seat_path)
+{
+    SessionBusEntry *entry;
+
+    entry = g_malloc0 (sizeof (SessionBusEntry));
+    entry->path = g_strdup (path);
+    entry->seat_path = g_strdup (seat_path);
 
     return entry;
 }
 
 static void
-emit_property_changed (GDBusConnection *bus, const gchar *path, const gchar *property_name)
+emit_object_value_changed (GDBusConnection *bus, const gchar *path, const gchar *interface_name, const gchar *property_name, GVariant *property_value)
 {
     GVariantBuilder builder;
     GError *error = NULL;
 
-    g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
-    g_variant_builder_add (&builder, "s", property_name);
+    g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+    g_variant_builder_add (&builder, "{sv}", property_name, property_value);
+
+    GVariant *v = g_variant_new ("(sa{sv}as)", interface_name, &builder, NULL);
     if (!g_dbus_connection_emit_signal (bus,
                                         NULL,
                                         path,
                                         "org.freedesktop.DBus.Properties",
                                         "PropertiesChanged",
-                                        g_variant_new ("(sa{sv}as)", "org.freedesktop.DisplayManager", NULL, &builder),
+                                        v,//g_variant_new ("(sa{sv}as)", interface_name, &builder, NULL),
                                         &error))
         g_warning ("Failed to emit PropertiesChanged signal: %s", error->message);
     g_clear_error (&error); 
@@ -595,25 +606,34 @@ emit_object_signal (GDBusConnection *bus, const gchar *path, const gchar *signal
 }
 
 static void
-bus_entry_free (gpointer data)
+seat_bus_entry_free (gpointer data)
 {
-    BusEntry *entry = data;
+    SeatBusEntry *entry = data;
 
     g_dbus_connection_unregister_object (bus, entry->bus_id);
 
-    emit_property_changed (bus, "/org/freedesktop/DisplayManager", entry->property_name);
-    emit_object_signal (bus, "/org/freedesktop/DisplayManager", entry->removed_signal, entry->path);
+    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Seats", get_seat_list ());
+    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SeatRemoved", entry->path);
 
-    if (entry->parent_path)
-    {
-        emit_property_changed (bus, entry->parent_path, entry->property_name);
-        emit_object_signal (bus, entry->parent_path, entry->removed_signal, entry->path);
-    }
+    g_free (entry->path);
+    g_free (entry);
+}
+
+static void
+session_bus_entry_free (gpointer data)
+{
+    SessionBusEntry *entry = data;
+
+    g_dbus_connection_unregister_object (bus, entry->bus_id);
+
+    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Sessions", get_session_list (NULL));
+    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SessionRemoved", entry->path);
+
+    emit_object_value_changed (bus, entry->seat_path, "org.freedesktop.DisplayManager.Seat", "Sessions", get_session_list (entry->seat_path));
+    emit_object_signal (bus, entry->seat_path, "SessionRemoved", entry->path);
 
     g_free (entry->path);
-    g_free (entry->parent_path);
-    g_free (entry->property_name);
-    g_free (entry->removed_signal);
+    g_free (entry->seat_path);
     g_free (entry);
 }
 
@@ -625,7 +645,8 @@ running_user_session_cb (Seat *seat, Session *session)
         handle_session_call,
         handle_session_get_property
     };
-    BusEntry *seat_entry, *entry;
+    SeatBusEntry *seat_entry;
+    SessionBusEntry *session_entry;
     gchar *path;
     GError *error = NULL;
 
@@ -638,26 +659,26 @@ running_user_session_cb (Seat *seat, Session *session)
     g_object_set_data_full (G_OBJECT (session), "XDG_SESSION_PATH", path, g_free);
 
     seat_entry = g_hash_table_lookup (seat_bus_entries, seat);
-    entry = bus_entry_new (g_object_get_data (G_OBJECT (session), "XDG_SESSION_PATH"), seat_entry ? seat_entry->path : NULL, "Sessions", "SessionRemoved");
-    g_hash_table_insert (session_bus_entries, g_object_ref (session), entry);
-
-    g_debug ("Registering session with bus path %s", entry->path);
-
-    entry->bus_id = g_dbus_connection_register_object (bus,
-                                                       entry->path,
-                                                       session_info->interfaces[0],
-                                                       &session_vtable,
-                                                       g_object_ref (session), g_object_unref,
-                                                       &error);
-    if (entry->bus_id == 0)
+    session_entry = session_bus_entry_new (g_object_get_data (G_OBJECT (session), "XDG_SESSION_PATH"), seat_entry ? seat_entry->path : NULL);
+    g_hash_table_insert (session_bus_entries, g_object_ref (session), session_entry);
+
+    g_debug ("Registering session with bus path %s", session_entry->path);
+
+    session_entry->bus_id = g_dbus_connection_register_object (bus,
+                                                               session_entry->path,
+                                                               session_info->interfaces[0],
+                                                               &session_vtable,
+                                                               g_object_ref (session), g_object_unref,
+                                                               &error);
+    if (session_entry->bus_id == 0)
         g_warning ("Failed to register user session: %s", error->message);
     g_clear_error (&error);
 
-    emit_property_changed (bus, "/org/freedesktop/DisplayManager", "Sessions");
-    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SessionAdded", entry->path);
+    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Sessions", get_session_list (NULL));
+    emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SessionAdded", session_entry->path);
 
-    emit_property_changed (bus, seat_entry->path, "Sessions");
-    emit_object_signal (bus, seat_entry->path, "SessionAdded", entry->path);
+    emit_object_value_changed (bus, seat_entry->path, "org.freedesktop.DisplayManager.Seat", "Sessions", get_session_list (session_entry->seat_path));
+    emit_object_signal (bus, seat_entry->path, "SessionAdded", session_entry->path);
 }
 
 static void
@@ -676,13 +697,13 @@ seat_added_cb (DisplayManager *display_manager, Seat *seat)
         handle_seat_get_property
     };
     gchar *path;
-    BusEntry *entry;
+    SeatBusEntry *entry;
     GError *error = NULL;
 
     path = g_strdup_printf ("/org/freedesktop/DisplayManager/Seat%d", seat_index);
     seat_index++;
 
-    entry = bus_entry_new (path, NULL, "Seats", "SeatRemoved");
+    entry = seat_bus_entry_new (path);
     g_free (path);
     g_hash_table_insert (seat_bus_entries, g_object_ref (seat), entry);
 
@@ -698,7 +719,7 @@ seat_added_cb (DisplayManager *display_manager, Seat *seat)
         g_warning ("Failed to register seat: %s", error->message);
     g_clear_error (&error);
 
-    emit_property_changed (bus, "/org/freedesktop/DisplayManager", "Seats");
+    emit_object_value_changed (bus, "/org/freedesktop/DisplayManager", "org.freedesktop.DisplayManager", "Seats", get_seat_list ());
     emit_object_signal (bus, "/org/freedesktop/DisplayManager", "SeatAdded", entry->path);
 
     g_signal_connect (seat, "running-user-session", G_CALLBACK (running_user_session_cb), NULL);
@@ -744,12 +765,8 @@ bus_acquired_cb (GDBusConnection *connection,
     const gchar *display_manager_interface =
         "<node>"
         "  <interface name='org.freedesktop.DisplayManager'>"
-        "    <property name='Seats' type='ao' access='read'>"
-        "      <annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='invalidates'/>"
-        "    </property>"
-        "    <property name='Sessions' type='ao' access='read'>"
-        "      <annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='invalidates'/>"
-        "    </property>"
+        "    <property name='Seats' type='ao' access='read'/>"
+        "    <property name='Sessions' type='ao' access='read'/>"
         "    <method name='AddSeat'>"
         "      <arg name='type' direction='in' type='s'/>"
         "      <arg name='properties' direction='in' type='a(ss)'/>"
@@ -783,9 +800,7 @@ bus_acquired_cb (GDBusConnection *connection,
         "  <interface name='org.freedesktop.DisplayManager.Seat'>"
         "    <property name='CanSwitch' type='b' access='read'/>"
         "    <property name='HasGuestAccount' type='b' access='read'/>"
-        "    <property name='Sessions' type='ao' access='read'>"
-        "      <annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='invalidates'/>"
-        "    </property>"
+        "    <property name='Sessions' type='ao' access='read'/>"
         "    <method name='SwitchToGreeter'/>"
         "    <method name='SwitchToUser'>"
         "      <arg name='username' direction='in' type='s'/>"
@@ -837,8 +852,8 @@ bus_acquired_cb (GDBusConnection *connection,
     g_clear_error (&error);
     g_dbus_node_info_unref (display_manager_info);
 
-    seat_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, bus_entry_free);
-    session_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, bus_entry_free);
+    seat_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, seat_bus_entry_free);
+    session_bus_entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, session_bus_entry_free);
 
     g_signal_connect (display_manager, "seat-added", G_CALLBACK (seat_added_cb), NULL);
     g_signal_connect (display_manager, "seat-removed", G_CALLBACK (seat_removed_cb), NULL);
index 78516fa18dba187104a1bb1f49c84596f19c5e3c..5f2ce05b62ef85d0dc8f0b5e44a549335dd0f810 100644 (file)
@@ -47,9 +47,9 @@ user-session=default
 #?SESSION-X-0 CONNECT-XSERVER
 
 # Session is reported via D-Bus
-#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager INVALIDATED=Sessions
+#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager CHANGED=Sessions:/org/freedesktop/DisplayManager/Session0
 #?RUNNER DBUS-SIGNAL PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager NAME=SessionAdded
-#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager INVALIDATED=Sessions
+#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager.Seat CHANGED=Sessions:/org/freedesktop/DisplayManager/Session0
 #?RUNNER DBUS-SIGNAL PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager NAME=SessionAdded
 
 #?*LIST-SEATS
@@ -64,9 +64,9 @@ user-session=default
 #?XSERVER-0 TERMINATE SIGNAL=15
 
 # Removal is reported via D-Bus
-#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager INVALIDATED=Sessions
+#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager CHANGED=Sessions
 #?RUNNER DBUS-SIGNAL PATH=/org/freedesktop/DisplayManager INTERFACE=org.freedesktop.DisplayManager NAME=SessionRemoved
-#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager INVALIDATED=Sessions
+#?RUNNER DBUS-PROPERTIES-CHANGED PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager.Seat CHANGED=Sessions
 #?RUNNER DBUS-SIGNAL PATH=/org/freedesktop/DisplayManager/Seat0 INTERFACE=org.freedesktop.DisplayManager NAME=SessionRemoved
 
 # X server starts
index f2b7289d5da82db42f2dfa239305d271e33b3212..f5dfcf0b9b9ad477586e5a09de04d2f4ca275c0c 100644 (file)
@@ -1968,13 +1968,22 @@ properties_changed_cb (GDBusConnection *connection,
     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++)
     {