static gboolean gdm_display_real_set_slave_bus_name (GdmDisplay *display, const char *name, GError **error) { g_free (display->priv->slave_bus_name); display->priv->slave_bus_name = g_strdup (name); if (display->priv->slave_name_id > 0) { g_bus_unwatch_name (display->priv->slave_name_id); } display->priv->slave_name_id = g_bus_watch_name_on_connection (display->priv->connection, name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, /* name appeared */ on_name_vanished, g_object_ref (display), NULL); g_clear_object (&display->priv->slave_bus_proxy); display->priv->slave_bus_proxy = GDM_DBUS_SLAVE (gdm_dbus_slave_proxy_new_sync (display->priv->connection, G_DBUS_PROXY_FLAGS_NONE, name, GDM_SLAVE_PATH, NULL, NULL)); g_object_bind_property (G_OBJECT (display->priv->slave_bus_proxy), "session-id", G_OBJECT (display), "session-id", G_BINDING_DEFAULT); return TRUE; }
static GVariant * g_menu_exporter_subscribe (GMenuExporter *exporter, const gchar *sender, GVariant *group_ids) { GMenuExporterRemote *remote; GVariantBuilder builder; GVariantIter iter; guint32 id; remote = g_hash_table_lookup (exporter->remotes, sender); if (remote == NULL) { guint watch_id; watch_id = g_bus_watch_name_on_connection (exporter->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, g_menu_exporter_name_vanished, exporter, NULL); remote = g_menu_exporter_remote_new (exporter, watch_id); g_hash_table_insert (exporter->remotes, g_strdup (sender), remote); } g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a(uuaa{sv}))")); g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(uuaa{sv})")); g_variant_iter_init (&iter, group_ids); while (g_variant_iter_next (&iter, "u", &id)) g_menu_exporter_remote_subscribe (remote, id, &builder); g_variant_builder_close (&builder); return g_variant_builder_end (&builder); }
static void handle_method_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) { SensorData *data = user_data; DriverType driver_type; GHashTable *ht; guint watch_id; if (g_strcmp0 (method_name, "ClaimAccelerometer") == 0 || g_strcmp0 (method_name, "ReleaseAccelerometer") == 0) driver_type = DRIVER_TYPE_ACCEL; else if (g_strcmp0 (method_name, "ClaimLight") == 0 || g_strcmp0 (method_name, "ClaimAccelerometer") == 0) driver_type = DRIVER_TYPE_LIGHT; else { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method '%s' does not exist", method_name); return; } ht = data->clients[driver_type]; if (g_str_has_prefix (method_name, "Claim")) { watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id > 0) { g_dbus_method_invocation_return_value (invocation, NULL); return; } /* No other clients for this sensor? Start it */ if (driver_type_exists (data, driver_type) && g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), TRUE); watch_id = g_bus_watch_name_on_connection (data->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, client_vanished_cb, data, NULL); g_hash_table_insert (ht, g_strdup (sender), GUINT_TO_POINTER (watch_id)); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_str_has_prefix (method_name, "Release")) { client_release (data, sender, driver_type); g_dbus_method_invocation_return_value (invocation, NULL); } }
static void watch_name (TcmmdDbus *self, const gchar *name) { if (self->priv->watch_id != 0) g_bus_unwatch_name (self->priv->watch_id); self->priv->watch_id = g_bus_watch_name_on_connection (self->priv->connection, name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, name_vanished_cb, self, NULL); }
/** * g_bus_watch_name_on_connection_with_closures: (rename-to g_bus_watch_name_on_connection) * @connection: A #GDBusConnection. * @name: The name (well-known or unique) to watch. * @flags: Flags from the #GBusNameWatcherFlags enumeration. * @name_appeared_closure: (nullable): #GClosure to invoke when @name is known * to exist or %NULL. * @name_vanished_closure: (nullable): #GClosure to invoke when @name is known * to not exist or %NULL. * * Version of g_bus_watch_name_on_connection() using closures instead of callbacks for * easier binding in other languages. * * Returns: An identifier (never 0) that an be used with * g_bus_unwatch_name() to stop watching the name. * * Since: 2.26 */ guint g_bus_watch_name_on_connection_with_closures ( GDBusConnection *connection, const gchar *name, GBusNameWatcherFlags flags, GClosure *name_appeared_closure, GClosure *name_vanished_closure) { return g_bus_watch_name_on_connection (connection, name, flags, name_appeared_closure != NULL ? watch_with_closures_on_name_appeared : NULL, name_vanished_closure != NULL ? watch_with_closures_on_name_vanished : NULL, watch_name_data_new (name_appeared_closure, name_vanished_closure), bus_watch_name_free_func); }
static void handle_generic_method_call (SensorData *data, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, DriverType driver_type) { GHashTable *ht; guint watch_id; g_debug ("Handling driver refcounting method '%s' for %s device", method_name, driver_type_to_str (driver_type)); ht = data->clients[driver_type]; if (g_str_has_prefix (method_name, "Claim")) { watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id > 0) { g_dbus_method_invocation_return_value (invocation, NULL); return; } /* No other clients for this sensor? Start it */ if (driver_type_exists (data, driver_type) && g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), TRUE); watch_id = g_bus_watch_name_on_connection (data->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, client_vanished_cb, data, NULL); g_hash_table_insert (ht, g_strdup (sender), GUINT_TO_POINTER (watch_id)); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_str_has_prefix (method_name, "Release")) { client_release (data, sender, driver_type); g_dbus_method_invocation_return_value (invocation, NULL); } }
GDBusProxy* WebKitTestBus::createProxy(const char* serviceName, const char* objectPath, const char* interfaceName, GMainLoop* mainLoop) { unsigned watcherID = g_bus_watch_name_on_connection(getOrCreateConnection(), serviceName, G_BUS_NAME_WATCHER_FLAGS_NONE, onNameAppeared, 0, mainLoop, 0); g_main_loop_run(mainLoop); g_bus_unwatch_name(watcherID); GDBusProxy* proxy = g_dbus_proxy_new_sync( connection(), G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, 0, // GDBusInterfaceInfo serviceName, objectPath, interfaceName, 0, // GCancellable 0); g_assert(proxy); return proxy; }
static DBusWatch * make_dbus_watch (MetaDBusIdleMonitor *skeleton, GDBusMethodInvocation *invocation, MetaIdleMonitor *monitor) { DBusWatch *watch; watch = g_slice_new (DBusWatch); watch->dbus_monitor = g_object_ref (skeleton); watch->monitor = g_object_ref (monitor); watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), watch->dbus_name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, /* appeared */ name_vanished_callback, watch, NULL); return watch; }
static void on_get_pid_ready (GObject *source_object, GAsyncResult *res, gpointer user_data) { GTask *task = G_TASK (user_data); gpointer *info = g_task_get_source_object (task); GClueClientInfoPrivate *priv = GCLUE_CLIENT_INFO (info)->priv; guint32 pid; GError *error = NULL; GVariant *results = NULL; results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (results == NULL) { g_task_return_error (task, error); g_object_unref (task); return; } g_assert (g_variant_n_children (results) > 0); g_variant_get_child (results, 0, "u", &pid); g_variant_unref (results); priv->xdg_id = get_xdg_id (pid); priv->watch_id = g_bus_watch_name_on_connection (priv->connection, priv->bus_name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, on_name_vanished, info, NULL); g_task_return_boolean (task, TRUE); g_object_unref (task); }
/** * secret_prompt_perform: * @self: a prompt * @window_id: XWindow id for parent window to be transient for * @return_type: the variant type of the prompt result * @cancellable: optional cancellation object * @callback: called when the operation completes * @user_data: data to be passed to the callback * * Runs a prompt and performs the prompting. Returns %TRUE if the prompt * was completed and not dismissed. * * If @window_id is non-zero then it is used as an XWindow id. The Secret * Service can make its prompt transient for the window with this id. In some * Secret Service implementations this is not possible, so the behavior * depending on this should degrade gracefully. * * This method will return immediately and complete asynchronously. */ void secret_prompt_perform (SecretPrompt *self, gulong window_id, const GVariantType *return_type, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *res; PerformClosure *closure; const gchar *owner_name; const gchar *object_path; gboolean prompted; GDBusProxy *proxy; gchar *window; g_return_if_fail (SECRET_IS_PROMPT (self)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); prompted = g_atomic_int_get (&self->pv->prompted); if (prompted) { g_warning ("The prompt object has already had its prompt called."); return; } proxy = G_DBUS_PROXY (self); res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, secret_prompt_perform); closure = g_slice_new0 (PerformClosure); closure->connection = g_object_ref (g_dbus_proxy_get_connection (proxy)); closure->call_cancellable = g_cancellable_new (); closure->async_cancellable = cancellable ? g_object_ref (cancellable) : NULL; closure->return_type = return_type ? g_variant_type_copy (return_type) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, perform_closure_free); if (window_id == 0) window = g_strdup (""); else window = g_strdup_printf ("%lu", window_id); owner_name = g_dbus_proxy_get_name_owner (proxy); object_path = g_dbus_proxy_get_object_path (proxy); closure->signal = g_dbus_connection_signal_subscribe (closure->connection, owner_name, SECRET_PROMPT_INTERFACE, SECRET_PROMPT_SIGNAL_COMPLETED, object_path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, on_prompt_completed, g_object_ref (res), g_object_unref); closure->watch = g_bus_watch_name_on_connection (closure->connection, owner_name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, on_prompt_vanished, g_object_ref (res), g_object_unref); if (closure->async_cancellable) { closure->cancelled_sig = g_cancellable_connect (closure->async_cancellable, G_CALLBACK (on_prompt_cancelled), res, NULL); } g_dbus_proxy_call (proxy, "Prompt", g_variant_new ("(s)", window), G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, closure->call_cancellable, on_prompt_prompted, g_object_ref (res)); g_free (window); g_object_unref (res); }
static void invocation_client_create (GDBusConnection *connection, const gchar *bus_name) { InvocationClient *client; g_mutex_lock (&inv.mutex); client = g_hash_table_lookup (inv.clients, bus_name); g_mutex_unlock (&inv.mutex); if (client != NULL) return; /* * Each time we see an incoming function call, keep the service alive for * that client, and each invocation of the client * * We would also like to get client credentials here and not pass client * messages into the rest of the machinery until that has completed. * Unfortunately the necessary patch in gio has not yet been merged. * * So we do an async call and if it hasn't completed by the time we need * the caller credentials, then we block and wait for it. Since it's the * system bus responding, it should respond pretty quickly. * * See invocation_client_lookup() for the waiting side of things. */ client = g_new0 (InvocationClient, 1); client->bus_name = g_strdup (bus_name); client->subject = polkit_system_bus_name_new (bus_name); client->refs = 1; client->uid_peer = ~0; client->uid_state = UID_LOADING; client->watch = g_bus_watch_name_on_connection (connection, bus_name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, on_client_vanished, NULL, NULL); g_debug ("GetConnectionUnixUser('%s') ...", bus_name); /* * This async call in the GDBusWorker thread main context will not * be blocked by the daemon main context blocking. */ g_dbus_connection_call (connection, "org.freedesktop.DBus", /* bus name */ "/org/freedesktop/DBus", /* object path */ "org.freedesktop.DBus", /* interface */ "GetConnectionUnixUser", /* method */ g_variant_new ("(s)", bus_name), G_VARIANT_TYPE ("(u)"), G_DBUS_CALL_FLAGS_NONE, -1, /* timeout_msec */ NULL, on_get_connection_unix_user, g_strdup (bus_name)); g_mutex_lock (&inv.mutex); if (!g_hash_table_lookup (inv.clients, bus_name)) { g_hash_table_replace (inv.clients, client->bus_name, client); client = NULL; } g_mutex_unlock (&inv.mutex); if (client) { invocation_client_unref (client); } else { g_main_context_invoke_full (NULL, G_PRIORITY_DEFAULT, on_invoke_client_appeared, g_strdup (bus_name), g_free); } }
static void method_call_cb (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { if (g_strcmp0 (interface_name, EV_DBUS_DAEMON_INTERFACE_NAME) != 0) return; if (g_strcmp0 (method_name, "RegisterDocument") == 0) { EvDoc *doc; const gchar *uri; g_variant_get (parameters, "(&s)", &uri); doc = ev_daemon_find_doc (uri); if (doc != NULL) { LOG ("RegisterDocument found owner '%s' for URI '%s'\n", doc->dbus_name, uri); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", doc->dbus_name)); return; } ev_daemon_stop_killtimer (); doc = g_new (EvDoc, 1); doc->dbus_name = g_strdup (sender); doc->uri = g_strdup (uri); doc->loaded_id = g_dbus_connection_signal_subscribe (connection, doc->dbus_name, EV_DBUS_WINDOW_INTERFACE_NAME, "DocumentLoaded", NULL, NULL, 0, (GDBusSignalCallback) document_loaded_cb, doc, NULL); doc->watch_id = g_bus_watch_name_on_connection (connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_cb, name_vanished_cb, user_data, NULL); LOG ("RegisterDocument registered owner '%s' for URI '%s'\n", doc->dbus_name, uri); ev_daemon_docs = g_list_prepend (ev_daemon_docs, doc); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "")); } else if (g_strcmp0 (method_name, "UnregisterDocument") == 0) { EvDoc *doc; const gchar *uri; g_variant_get (parameters, "(&s)", &uri); LOG ("UnregisterDocument URI '%s'\n", uri); doc = ev_daemon_find_doc (uri); if (doc == NULL) { LOG ("UnregisterDocument URI was not registered!\n"); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "URI not registered"); return; } if (strcmp (doc->dbus_name, sender) != 0) { LOG ("UnregisterDocument called by non-owner (owner '%s' sender '%s')\n", doc->dbus_name, sender); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_BAD_ADDRESS, "Only owner can call this method"); return; } ev_daemon_docs = g_list_remove (ev_daemon_docs, doc); ev_doc_free (doc); ev_daemon_maybe_start_killtimer (user_data); g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); } else if (g_strcmp0 (method_name, "FindDocument") == 0) { EvDoc *doc; const gchar *uri; gboolean spawn; g_variant_get (parameters, "(&sb)", &uri, &spawn); LOG ("FindDocument URI '%s' \n", uri); doc = ev_daemon_find_doc (uri); if (doc != NULL) { g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", doc->dbus_name)); return; } if (spawn) { GList *uri_invocations; gboolean ret_val = TRUE; uri_invocations = g_hash_table_lookup (pending_invocations, uri); if (uri_invocations == NULL) { /* Only spawn once. */ ret_val = spawn_atril (uri); } if (ret_val) { /* Only defer DBUS answer if atril was succesfully spawned */ uri_invocations = g_list_prepend (uri_invocations, invocation); g_hash_table_insert (pending_invocations, g_strdup (uri), uri_invocations); return; } } LOG ("FindDocument URI '%s' was not registered!\n", uri); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)","")); } }