/* * gtkappchooseronlinepk.c: packagekit module for app-chooser * * Copyright (C) 2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Cosimo Cecchi */ #include "config.h" #include "gtkappchooseronlinepk.h" #include "gtkappchooseronline.h" #ifdef GDK_WINDOWING_X11 #include "x11/gdkx.h" #endif #include #define gtk_app_chooser_online_pk_get_type _gtk_app_chooser_online_pk_get_type static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface); static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (GtkAppChooserOnlinePk, gtk_app_chooser_online_pk, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, app_chooser_online_pk_async_initable_init) G_IMPLEMENT_INTERFACE (GTK_TYPE_APP_CHOOSER_ONLINE, app_chooser_online_iface_init) g_io_extension_point_implement ("gtkappchooser-online", g_define_type_id, "packagekit", 10)); struct _GtkAppChooserOnlinePkPrivate { GSimpleAsyncResult *init_result; guint watch_id; GDBusProxy *proxy; GSimpleAsyncResult *result; GtkWindow *parent; }; static void gtk_app_chooser_online_pk_dispose (GObject *obj) { GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj); g_clear_object (&self->priv->result); g_clear_object (&self->priv->proxy); G_OBJECT_CLASS (gtk_app_chooser_online_pk_parent_class)->dispose (obj); } static void gtk_app_chooser_online_pk_class_init (GtkAppChooserOnlinePkClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS (klass); oclass->dispose = gtk_app_chooser_online_pk_dispose; g_type_class_add_private (klass, sizeof (GtkAppChooserOnlinePkPrivate)); } static void gtk_app_chooser_online_pk_init (GtkAppChooserOnlinePk *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTK_TYPE_APP_CHOOSER_ONLINE_PK, GtkAppChooserOnlinePkPrivate); } static gboolean pk_search_mime_finish (GtkAppChooserOnline *obj, GAsyncResult *res, GError **error) { GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); return !g_simple_async_result_propagate_error (simple, error); } static void install_mime_types_ready_cb (GObject *source, GAsyncResult *res, gpointer user_data) { GtkAppChooserOnlinePk *self = user_data; GDBusProxy *proxy = G_DBUS_PROXY (source); GError *error = NULL; GVariant *variant; variant = g_dbus_proxy_call_finish (proxy, res, &error); if (variant == NULL) { /* don't show errors if the user cancelled the installation explicitely * or if PK wasn't able to find any apps */ if (g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.Cancelled") != 0 && g_strcmp0 (g_dbus_error_get_remote_error (error), "org.freedesktop.PackageKit.Modify.NoPackagesFound") != 0) g_simple_async_result_set_from_error (self->priv->result, error); g_error_free (error); } g_simple_async_result_complete (self->priv->result); g_clear_object (&self->priv->result); } static void pk_search_mime_async (GtkAppChooserOnline *obj, const gchar *content_type, GtkWindow *parent, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (obj); guint xid = 0; GdkWindow *window; const gchar *mime_types[2]; self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, _gtk_app_chooser_online_search_for_mimetype_async); #ifdef GDK_WINDOWING_X11 window = gtk_widget_get_window (GTK_WIDGET (parent)); xid = GDK_WINDOW_XID (window); #endif mime_types[0] = content_type; mime_types[1] = NULL; g_dbus_proxy_call (self->priv->proxy, "InstallMimeTypes", g_variant_new ("(u^ass)", xid, mime_types, "hide-confirm-search"), G_DBUS_CALL_FLAGS_NONE, G_MAXINT, /* no timeout */ cancellable, install_mime_types_ready_cb, self); } static void app_chooser_online_iface_init (GtkAppChooserOnlineInterface *iface) { iface->search_for_mimetype_async = pk_search_mime_async; iface->search_for_mimetype_finish = pk_search_mime_finish; } static void pk_proxy_created_cb (GObject *source, GAsyncResult *result, gpointer user_data) { GtkAppChooserOnlinePk *self = user_data; GDBusProxy *proxy; proxy = g_dbus_proxy_new_finish (result, NULL); if (proxy == NULL) { g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE); } else { g_simple_async_result_set_op_res_gboolean (self->priv->init_result, TRUE); self->priv->proxy = proxy; } g_simple_async_result_complete (self->priv->init_result); g_clear_object (&self->priv->init_result); } static void pk_appeared_cb (GDBusConnection *conn, const gchar *name, const gchar *owner, gpointer user_data) { GtkAppChooserOnlinePk *self = user_data; /* create the proxy */ g_dbus_proxy_new (conn, 0, NULL, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit.Modify", NULL, pk_proxy_created_cb, self); g_bus_unwatch_name (self->priv->watch_id); } static void pk_vanished_cb (GDBusConnection *conn, const gchar *name, gpointer user_data) { GtkAppChooserOnlinePk *self = user_data; /* just return */ g_simple_async_result_set_op_res_gboolean (self->priv->init_result, FALSE); g_simple_async_result_complete (self->priv->init_result); g_bus_unwatch_name (self->priv->watch_id); g_clear_object (&self->priv->init_result); } static gboolean app_chooser_online_pk_init_finish (GAsyncInitable *init, GAsyncResult *res, GError **error) { return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res)); } static void app_chooser_online_pk_init_async (GAsyncInitable *init, int io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GtkAppChooserOnlinePk *self = GTK_APP_CHOOSER_ONLINE_PK (init); self->priv->init_result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, _gtk_app_chooser_online_get_default_async); self->priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, "org.freedesktop.PackageKit", G_BUS_NAME_WATCHER_FLAGS_AUTO_START, pk_appeared_cb, pk_vanished_cb, self, NULL); } static void app_chooser_online_pk_async_initable_init (GAsyncInitableIface *iface) { iface->init_async = app_chooser_online_pk_init_async; iface->init_finish = app_chooser_online_pk_init_finish; }