[kdbus] Fix problem with receiving async messages
[platform/upstream/glib.git] / gio / tests / gdbus-example-watch-proxy.c
index 7060b21..51132e3 100644 (file)
@@ -1,23 +1,10 @@
-/*
- * Copyright © 2010 Red Hat, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2 of the licence or (at
- * your option) any later version.
- *
- * See the included COPYING file for more information.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
 #include <gio/gio.h>
 
 static gchar *opt_name         = NULL;
 static gchar *opt_object_path  = NULL;
 static gchar *opt_interface    = NULL;
 static gboolean opt_system_bus = FALSE;
-static gboolean opt_auto_start = FALSE;
+static gboolean opt_no_auto_start = FALSE;
 static gboolean opt_no_properties = FALSE;
 
 static GOptionEntry opt_entries[] =
@@ -26,11 +13,13 @@ static GOptionEntry opt_entries[] =
   { "object-path", 'o', 0, G_OPTION_ARG_STRING, &opt_object_path, "Object path of the remote object", NULL },
   { "interface", 'i', 0, G_OPTION_ARG_STRING, &opt_interface, "D-Bus interface of remote object", NULL },
   { "system-bus", 's', 0, G_OPTION_ARG_NONE, &opt_system_bus, "Use the system-bus instead of the session-bus", NULL },
-  { "auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_auto_start, "Instruct the bus to launch an owner for the name", NULL},
+  { "no-auto-start", 'a', 0, G_OPTION_ARG_NONE, &opt_no_auto_start, "Don't instruct the bus to launch an owner for the name", NULL},
   { "no-properties", 'p', 0, G_OPTION_ARG_NONE, &opt_no_properties, "Do not load properties", NULL},
   { NULL}
 };
 
+static GMainLoop *loop = NULL;
+
 static void
 print_properties (GDBusProxy *proxy)
 {
@@ -39,13 +28,13 @@ print_properties (GDBusProxy *proxy)
 
   g_print ("    properties:\n");
 
-  property_names = g_dbus_proxy_get_cached_property_names (proxy, NULL);
+  property_names = g_dbus_proxy_get_cached_property_names (proxy);
   for (n = 0; property_names != NULL && property_names[n] != NULL; n++)
     {
       const gchar *key = property_names[n];
       GVariant *value;
       gchar *value_str;
-      value = g_dbus_proxy_get_cached_property (proxy, key, NULL);
+      value = g_dbus_proxy_get_cached_property (proxy, key);
       value_str = g_variant_print (value, TRUE);
       g_print ("      %s -> %s\n", key, value_str);
       g_variant_unref (value);
@@ -55,32 +44,44 @@ print_properties (GDBusProxy *proxy)
 }
 
 static void
-on_properties_changed (GDBusProxy *proxy,
-                       GVariant   *changed_properties,
-                       gpointer    user_data)
+on_properties_changed (GDBusProxy          *proxy,
+                       GVariant            *changed_properties,
+                       const gchar* const  *invalidated_properties,
+                       gpointer             user_data)
 {
-  GVariantIter *iter;
-  GVariant *item;
-
-  g_print (" *** Properties Changed:\n");
+  /* Note that we are guaranteed that changed_properties and
+   * invalidated_properties are never NULL
+   */
 
-  g_variant_get (changed_properties,
-                 "a{sv}",
-                 &iter);
-  while ((item = g_variant_iter_next_value (iter)))
+  if (g_variant_n_children (changed_properties) > 0)
     {
+      GVariantIter *iter;
       const gchar *key;
       GVariant *value;
-      gchar *value_str;
 
-      g_variant_get (item,
-                     "{sv}",
-                     &key,
-                     &value);
+      g_print (" *** Properties Changed:\n");
+      g_variant_get (changed_properties,
+                     "a{sv}",
+                     &iter);
+      while (g_variant_iter_loop (iter, "{&sv}", &key, &value))
+        {
+          gchar *value_str;
+          value_str = g_variant_print (value, TRUE);
+          g_print ("      %s -> %s\n", key, value_str);
+          g_free (value_str);
+        }
+      g_variant_iter_free (iter);
+    }
 
-      value_str = g_variant_print (value, TRUE);
-      g_print ("      %s -> %s\n", key, value_str);
-      g_free (value_str);
+  if (g_strv_length ((GStrv) invalidated_properties) > 0)
+    {
+      guint n;
+      g_print (" *** Properties Invalidated:\n");
+      for (n = 0; invalidated_properties[n] != NULL; n++)
+        {
+          const gchar *key = invalidated_properties[n];
+          g_print ("      %s\n", key);
+        }
     }
 }
 
@@ -101,63 +102,59 @@ on_signal (GDBusProxy *proxy,
 }
 
 static void
-on_proxy_appeared (GDBusConnection *connection,
-                   const gchar     *name,
-                   const gchar     *name_owner,
-                   GDBusProxy      *proxy,
-                   gpointer         user_data)
+print_proxy (GDBusProxy *proxy)
 {
-  g_print ("+++ Acquired proxy object for remote object owned by %s\n"
-           "    bus:          %s\n"
-           "    name:         %s\n"
-           "    object path:  %s\n"
-           "    interface:    %s\n",
-           name_owner,
-           opt_system_bus ? "System Bus" : "Session Bus",
-           opt_name,
-           opt_object_path,
-           opt_interface);
-
-  print_properties (proxy);
+  gchar *name_owner;
 
-  g_signal_connect (proxy,
-                    "g-properties-changed",
-                    G_CALLBACK (on_properties_changed),
-                    NULL);
-
-  g_signal_connect (proxy,
-                    "g-signal",
-                    G_CALLBACK (on_signal),
-                    NULL);
+  name_owner = g_dbus_proxy_get_name_owner (proxy);
+  if (name_owner != NULL)
+    {
+      g_print ("+++ Proxy object points to remote object owned by %s\n"
+               "    bus:          %s\n"
+               "    name:         %s\n"
+               "    object path:  %s\n"
+               "    interface:    %s\n",
+               name_owner,
+               opt_system_bus ? "System Bus" : "Session Bus",
+               opt_name,
+               opt_object_path,
+               opt_interface);
+      print_properties (proxy);
+    }
+  else
+    {
+      g_print ("--- Proxy object is inert - there is no name owner for the name\n"
+               "    bus:          %s\n"
+               "    name:         %s\n"
+               "    object path:  %s\n"
+               "    interface:    %s\n",
+               opt_system_bus ? "System Bus" : "Session Bus",
+               opt_name,
+               opt_object_path,
+               opt_interface);
+    }
+  g_free (name_owner);
 }
 
 static void
-on_proxy_vanished (GDBusConnection *connection,
-                   const gchar     *name,
-                   gpointer         user_data)
+on_name_owner_notify (GObject    *object,
+                      GParamSpec *pspec,
+                      gpointer    user_data)
 {
-  g_print ("--- Cannot create proxy object for\n"
-           "    bus:          %s\n"
-           "    name:         %s\n"
-           "    object path:  %s\n"
-           "    interface:    %s\n",
-           opt_system_bus ? "System Bus" : "Session Bus",
-           opt_name,
-           opt_object_path,
-           opt_interface);
+  GDBusProxy *proxy = G_DBUS_PROXY (object);
+  print_proxy (proxy);
 }
 
 int
 main (int argc, char *argv[])
 {
-  guint watcher_id;
-  GMainLoop *loop;
   GOptionContext *opt_context;
   GError *error;
-  GBusNameWatcherFlags flags;
-  GDBusProxyFlags proxy_flags;
+  GDBusProxyFlags flags;
+  GDBusProxy *proxy;
 
-  g_type_init ();
+  loop = NULL;
+  proxy = NULL;
 
   opt_context = g_option_context_new ("g_bus_watch_proxy() example");
   g_option_context_set_summary (opt_context,
@@ -170,7 +167,7 @@ main (int argc, char *argv[])
   error = NULL;
   if (!g_option_context_parse (opt_context, &argc, &argv, &error))
     {
-      g_printerr ("Error parsing options: %s", error->message);
+      g_printerr ("Error parsing options: %s\n", error->message);
       goto out;
     }
   if (opt_name == NULL || opt_object_path == NULL || opt_interface == NULL)
@@ -179,32 +176,51 @@ main (int argc, char *argv[])
       goto out;
     }
 
-  flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
-  if (opt_auto_start)
-    flags |= G_BUS_NAME_WATCHER_FLAGS_AUTO_START;
-
-  proxy_flags = G_DBUS_PROXY_FLAGS_NONE;
+  flags = G_DBUS_PROXY_FLAGS_NONE;
   if (opt_no_properties)
-    proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
-
-  watcher_id = g_bus_watch_proxy (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION,
-                                  opt_name,
-                                  flags,
-                                  opt_object_path,
-                                  opt_interface,
-                                  G_TYPE_DBUS_PROXY,
-                                  proxy_flags,
-                                  on_proxy_appeared,
-                                  on_proxy_vanished,
-                                  NULL,
-                                  NULL);
+    flags |= G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+  if (opt_no_auto_start)
+    flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
 
   loop = g_main_loop_new (NULL, FALSE);
-  g_main_loop_run (loop);
 
-  g_bus_unwatch_proxy (watcher_id);
+  error = NULL;
+  proxy = g_dbus_proxy_new_for_bus_sync (opt_system_bus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION,
+                                         flags,
+                                         NULL, /* GDBusInterfaceInfo */
+                                         opt_name,
+                                         opt_object_path,
+                                         opt_interface,
+                                         NULL, /* GCancellable */
+                                         &error);
+  if (proxy == NULL)
+    {
+      g_printerr ("Error creating proxy: %s\n", error->message);
+      g_error_free (error);
+      goto out;
+    }
+
+  g_signal_connect (proxy,
+                    "g-properties-changed",
+                    G_CALLBACK (on_properties_changed),
+                    NULL);
+  g_signal_connect (proxy,
+                    "g-signal",
+                    G_CALLBACK (on_signal),
+                    NULL);
+  g_signal_connect (proxy,
+                    "notify::g-name-owner",
+                    G_CALLBACK (on_name_owner_notify),
+                    NULL);
+  print_proxy (proxy);
+
+  g_main_loop_run (loop);
 
  out:
+  if (proxy != NULL)
+    g_object_unref (proxy);
+  if (loop != NULL)
+    g_main_loop_unref (loop);
   g_option_context_free (opt_context);
   g_free (opt_name);
   g_free (opt_object_path);