Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
	}
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
/**
 * 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);
	}
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
/**
 * 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);
}
Esempio n. 11
0
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);
    }
}
Esempio n. 12
0
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)",""));
	}
}