[gnome-packagekit] Split up the DBus interface part of gpk-update-icon into an session-activated gpk-dbus-service binar



commit 9ed69a9113fd5dd9976c0f13057031faec8b27d4
Author: Richard Hughes <richard hughsie com>
Date:   Thu Dec 17 10:27:33 2009 +0000

    Split up the DBus interface part of gpk-update-icon into an session-activated gpk-dbus-service binary

 contrib/gnome-packagekit.spec.in           |    2 +
 data/org.freedesktop.PackageKit.service.in |    2 +-
 po/POTFILES.in                             |    1 +
 src/.gitignore                             |    1 +
 src/Makefile.am                            |   12 ++-
 src/gpk-dbus-service.c                     |  203 ++++++++++++++++++++++++++++
 src/gpk-dbus-task.c                        |   93 +++++++++++--
 src/gpk-dbus-task.h                        |   44 +++++--
 src/gpk-dbus.c                             |   65 +++++++--
 src/gpk-dbus.h                             |    2 +
 src/gpk-update-icon.c                      |   92 +-------------
 11 files changed, 386 insertions(+), 131 deletions(-)
---
diff --git a/contrib/gnome-packagekit.spec.in b/contrib/gnome-packagekit.spec.in
index 086b6c8..c76fabd 100644
--- a/contrib/gnome-packagekit.spec.in
+++ b/contrib/gnome-packagekit.spec.in
@@ -161,6 +161,7 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %{_bindir}/gpk-repo
 %{_bindir}/gpk-update-icon
 %{_bindir}/gpk-update-viewer
+%{_bindir}/gpk-dbus-service
 %dir %{_datadir}/gnome-packagekit
 %{_datadir}/gnome-packagekit/gpk-application.ui
 %{_datadir}/gnome-packagekit/gpk-client.ui
@@ -192,6 +193,7 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %{_datadir}/applications/gpk-log.desktop
 %{_datadir}/applications/gpk-repo.desktop
 %{_datadir}/applications/gpk-update-viewer.desktop
+%{_datadir}/dbus-1/services/org.freedesktop.PackageKit.service
 
 %files extra
 %defattr(-,root,root,-)
diff --git a/data/org.freedesktop.PackageKit.service.in b/data/org.freedesktop.PackageKit.service.in
index fdc13ce..be3e225 100644
--- a/data/org.freedesktop.PackageKit.service.in
+++ b/data/org.freedesktop.PackageKit.service.in
@@ -1,4 +1,4 @@
 [D-BUS Service]
 Name=org.freedesktop.PackageKit
-Exec= servicedir@/gpk-update-icon
+Exec= servicedir@/gpk-dbus-service
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b8e4475..1a03f4a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -52,6 +52,7 @@ src/gpk-service-pack.c
 src/gpk-update-icon.c
 src/gpk-update-viewer.c
 src/gpk-update-viewer-main.c
+src/gpk-dbus-service.c
 src/gpk-watch.c
 src/egg-debug.c
 
diff --git a/src/.gitignore b/src/.gitignore
index 5da2fcc..7c4d308 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -29,5 +29,6 @@ gpk-backend-status
 gpk-self-test
 gpk-service-pack
 gpk-log
+gpk-dbus-service
 .svn
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 7956fbf..1fa58fa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,6 +43,7 @@ bin_PROGRAMS =						\
 	gpk-update-viewer				\
 	gpk-log						\
 	gpk-backend-status				\
+	gpk-dbus-service					\
 	$(NULL)
 
 noinst_LIBRARIES = libgpkshared.a
@@ -165,13 +166,22 @@ gpk_update_icon_SOURCES =				\
 	gpk-hardware.h					\
 	gpk-inhibit.c					\
 	gpk-inhibit.h					\
+	$(NULL)
+
+gpk_update_icon_LDADD =					\
+	libgpkshared.a					\
+	$(shared_LIBS)					\
+	$(NULL)
+
+gpk_dbus_service_SOURCES =				\
+	gpk-dbus-service.c				\
 	gpk-dbus.c					\
 	gpk-dbus.h					\
 	gpk-dbus-task.c					\
 	gpk-dbus-task.h					\
 	$(NULL)
 
-gpk_update_icon_LDADD =					\
+gpk_dbus_service_LDADD =				\
 	libgpkshared.a					\
 	$(shared_LIBS)					\
 	$(NULL)
diff --git a/src/gpk-dbus-service.c b/src/gpk-dbus-service.c
new file mode 100644
index 0000000..0a7c1cf
--- /dev/null
+++ b/src/gpk-dbus-service.c
@@ -0,0 +1,203 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <gtk/gtk.h>
+#include <locale.h>
+#include <libnotify/notify.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-monitor.h"
+
+#include "gpk-dbus.h"
+#include "org.freedesktop.PackageKit.h"
+
+static GMainLoop *loop = NULL;
+
+#define GPK_SESSION_IDLE_EXIT	60 /* seconds */
+
+/**
+ * gpk_dbus_service_object_register:
+ * @connection: What we want to register to
+ * @object: The GObject we want to register
+ *
+ * Return value: success
+ **/
+static gboolean
+gpk_dbus_service_object_register (DBusGConnection *connection, GObject *object)
+{
+	DBusGProxy *bus_proxy = NULL;
+	GError *error = NULL;
+	guint request_name_result;
+	gboolean ret;
+
+	/* connect to the bus */
+	bus_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
+					       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+	/* get our name */
+	ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
+				 G_TYPE_STRING, PK_DBUS_SERVICE,
+				 G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
+					      DBUS_NAME_FLAG_REPLACE_EXISTING |
+					      DBUS_NAME_FLAG_DO_NOT_QUEUE,
+				 G_TYPE_INVALID,
+				 G_TYPE_UINT, &request_name_result,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		/* abort as the DBUS method failed */
+		egg_warning ("RequestName failed: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	/* free the bus_proxy */
+	g_object_unref (G_OBJECT (bus_proxy));
+
+	/* already running */
+	if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+		return FALSE;
+
+	dbus_g_object_type_install_info (GPK_TYPE_DBUS, &dbus_glib_gpk_dbus_object_info);
+	dbus_g_error_domain_register (GPK_DBUS_ERROR, NULL, GPK_DBUS_TYPE_ERROR);
+	dbus_g_connection_register_g_object (connection, PK_DBUS_PATH, object);
+
+	return TRUE;
+}
+
+/**
+ * gpk_dbus_service_check_idle_cb:
+ **/
+static gboolean
+gpk_dbus_service_check_idle_cb (GpkDbus *dbus)
+{
+	guint idle;
+
+	/* get the idle time */
+	idle = gpk_dbus_get_idle_time (dbus);
+	if (idle > GPK_SESSION_IDLE_EXIT) {
+		egg_debug ("exiting loop as idle");
+		g_main_loop_quit (loop);
+		return FALSE;
+	}
+	/* continue to poll */
+	return TRUE;
+}
+
+/**
+ * gpk_dbus_service_connection_replaced_cb:
+ **/
+static void
+gpk_dbus_service_connection_replaced_cb (EggDbusMonitor *monitor, gpointer data)
+{
+	egg_warning ("exiting as we have been replaced");
+	g_main_loop_quit (loop);
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+	gboolean no_timed_exit = FALSE;
+	GpkDbus *dbus = NULL;
+	GOptionContext *context;
+	GError *error = NULL;
+	gboolean ret;
+	guint retval = 0;
+	DBusGConnection *connection;
+	EggDbusMonitor *monitor;
+
+	const GOptionEntry options[] = {
+		{ "no-timed-exit", '\0', 0, G_OPTION_ARG_NONE, &no_timed_exit,
+		  _("Do not exit after the request has been processed"), NULL },
+		{ NULL}
+	};
+
+	setlocale (LC_ALL, "");
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	if (! g_thread_supported ())
+		g_thread_init (NULL);
+	dbus_g_thread_init ();
+	g_type_init ();
+	notify_init ("gpk-dbus-service");
+
+	/* TRANSLATORS: program name, a session wide daemon to watch for updates and changing system state */
+	g_set_application_name (_("Session DBus service for PackageKit"));
+	context = g_option_context_new (NULL);
+	g_option_context_set_summary (context, _("Session DBus service for PackageKit"));
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_add_group (context, egg_debug_get_option_group ());
+	g_option_context_add_group (context, gtk_get_option_group (TRUE));
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
+	gtk_init (&argc, &argv);
+
+	/* create new objects */
+	dbus = gpk_dbus_new ();
+	loop = g_main_loop_new (NULL, FALSE);
+
+	/* find out when we are replaced */
+	monitor = egg_dbus_monitor_new ();
+	egg_dbus_monitor_assign (monitor, EGG_DBUS_MONITOR_SESSION, PK_DBUS_SERVICE);
+	g_signal_connect (monitor, "connection-replaced",
+			  G_CALLBACK (gpk_dbus_service_connection_replaced_cb), NULL);
+
+	/* get the bus */
+	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (error) {
+		egg_warning ("%s", error->message);
+		g_error_free (error);
+		retval = 1;
+		goto out;
+	}
+
+	/* try to register */
+	ret = gpk_dbus_service_object_register (connection, G_OBJECT (dbus));
+	if (!ret) {
+		egg_warning ("failed to replace running instance.");
+		retval = 1;
+		goto out;
+	}
+
+	/* only timeout if we have specified iton the command line */
+	if (!no_timed_exit)
+		g_timeout_add_seconds (5, (GSourceFunc) gpk_dbus_service_check_idle_cb, dbus);
+
+	/* wait */
+	g_main_loop_run (loop);
+out:
+	g_object_unref (monitor);
+	g_main_loop_unref (loop);
+	g_object_unref (dbus);
+	return retval;
+}
+
diff --git a/src/gpk-dbus-task.c b/src/gpk-dbus-task.c
index 2f40d1e..4031730 100644
--- a/src/gpk-dbus-task.c
+++ b/src/gpk-dbus-task.c
@@ -95,6 +95,8 @@ struct _GpkDbusTaskPrivate
 	gchar			**files;
 	GCancellable		*cancellable;
 	PkCatalog		*catalog;
+	GpkDbusTaskFinishedCb	 finished_cb;
+	gpointer		 finished_userdata;
 };
 
 G_DEFINE_TYPE (GpkDbusTask, gpk_dbus_task, G_TYPE_OBJECT)
@@ -183,9 +185,15 @@ gpk_dbus_task_dbus_return_error (GpkDbusTask *dtask, const GError *error)
 	egg_debug ("sending async return error in response to %p: %s", dtask->priv->context, error->message);
 	dbus_g_method_return_error (dtask->priv->context, error);
 
-out:
 	/* set context NULL just in case we try to repeat */
 	dtask->priv->context = NULL;
+
+	/* do the finish callback */
+	if (dtask->priv->finished_cb)
+		dtask->priv->finished_cb (dtask, dtask->priv->finished_userdata);
+out:
+	/* we can't touch dtask now, as it might have been unreffed in the finished callback */
+	return;
 }
 
 /**
@@ -203,9 +211,16 @@ gpk_dbus_task_dbus_return_value (GpkDbusTask *dtask, gboolean ret)
 	/* send error */
 	egg_debug ("sending async return in response to %p: %i", dtask->priv->context, ret);
 	dbus_g_method_return (dtask->priv->context, ret);
-out:
+
 	/* set context NULL just in case we try to repeat */
 	dtask->priv->context = NULL;
+
+	/* do the finish callback */
+	if (dtask->priv->finished_cb)
+		dtask->priv->finished_cb (dtask, dtask->priv->finished_userdata);
+out:
+	/* we can't touch dtask now, as it might have been unreffed in the finished callback */
+	return;
 }
 
 /**
@@ -766,10 +781,17 @@ out:
  * gpk_dbus_task_is_installed:
  **/
 void
-gpk_dbus_task_is_installed (GpkDbusTask *dtask, const gchar *package_name)
+gpk_dbus_task_is_installed (GpkDbusTask *dtask, const gchar *package_name, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gchar **package_names = NULL;
 
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+	g_return_if_fail (package_name != NULL);
+
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* get the package list for the installed packages */
 	package_names = g_strsplit (package_name, "|", 1);
 	pk_client_resolve_async (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_names, NULL,
@@ -854,10 +876,17 @@ out:
  * gpk_dbus_task_search_file:
  **/
 void
-gpk_dbus_task_search_file (GpkDbusTask *dtask, const gchar *search_file)
+gpk_dbus_task_search_file (GpkDbusTask *dtask, const gchar *search_file, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gchar **values = NULL;
 
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+	g_return_if_fail (search_file != NULL);
+
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* get the package list for the installed packages */
 	egg_debug ("package_name=%s", search_file);
 	values = g_strsplit (search_file, "&", -1);
@@ -879,7 +908,7 @@ gpk_dbus_task_search_file (GpkDbusTask *dtask, const gchar *search_file)
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_package_files (GpkDbusTask *dtask, gchar **files_rel)
+gpk_dbus_task_install_package_files (GpkDbusTask *dtask, gchar **files_rel, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	GError *error = NULL;
 	GError *error_dbus = NULL;
@@ -890,6 +919,10 @@ gpk_dbus_task_install_package_files (GpkDbusTask *dtask, gchar **files_rel)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (files_rel != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	array = pk_strv_to_ptr_array (files_rel);
 
 	/* check the user wanted to call this method */
@@ -928,7 +961,7 @@ out:
  * gpk_dbus_task_install_package_names_resolve_cb:
  **/
 static void
-gpk_dbus_task_install_package_names_resolve_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
+gpk_dbus_task_install_package_names_resolve_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	GError *error = NULL;
 	GError *error_dbus = NULL;
@@ -1072,7 +1105,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_package_names (GpkDbusTask *dtask, gchar **packages)
+gpk_dbus_task_install_package_names (GpkDbusTask *dtask, gchar **packages, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret;
 	GError *error_dbus = NULL;
@@ -1085,6 +1118,10 @@ gpk_dbus_task_install_package_names (GpkDbusTask *dtask, gchar **packages)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (packages != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* optional */
 	if (!dtask->priv->show_confirm_install) {
 		egg_debug ("skip confirm as not allowed to interact with user");
@@ -1288,7 +1325,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_provide_files (GpkDbusTask *dtask, gchar **full_paths)
+gpk_dbus_task_install_provide_files (GpkDbusTask *dtask, gchar **full_paths, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret;
 	GError *error_dbus = NULL;
@@ -1301,6 +1338,10 @@ gpk_dbus_task_install_provide_files (GpkDbusTask *dtask, gchar **full_paths)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (full_paths != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* optional */
 	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
@@ -1578,7 +1619,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask, gchar **codec_names)
+gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask, gchar **codec_names, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret = TRUE;
 	GError *error_dbus = NULL;
@@ -1591,6 +1632,13 @@ gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask, gchar **codec_nam
 	gchar *title_str = NULL;
 	guint i;
 
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+	g_return_if_fail (codec_names != NULL);
+
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* check it's not session wide banned in gconf */
 	ret = gconf_client_get_bool (dtask->priv->gconf_client, GPK_CONF_ENABLE_CODEC_HELPER, NULL);
 	if (!ret) {
@@ -1749,7 +1797,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_mime_types (GpkDbusTask *dtask, gchar **mime_types)
+gpk_dbus_task_install_mime_types (GpkDbusTask *dtask, gchar **mime_types, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret;
 	GError *error_dbus = NULL;
@@ -1760,6 +1808,10 @@ gpk_dbus_task_install_mime_types (GpkDbusTask *dtask, gchar **mime_types)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (mime_types != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* check it's not session wide banned in gconf */
 	ret = gconf_client_get_bool (dtask->priv->gconf_client, GPK_CONF_ENABLE_MIME_TYPE_HELPER, NULL);
 	if (!ret) {
@@ -2060,7 +2112,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask, gchar **fonts)
+gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask, gchar **fonts, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret;
 	GPtrArray *array = NULL;
@@ -2079,6 +2131,10 @@ gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask, gchar **fonts)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (fonts != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* if this program banned? */
 	ret = gpk_dbus_task_install_check_exec_ignored (dtask);
 	if (!ret) {
@@ -2418,7 +2474,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_remove_package_by_file (GpkDbusTask *dtask, gchar **full_paths)
+gpk_dbus_task_remove_package_by_file (GpkDbusTask *dtask, gchar **full_paths, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	gboolean ret;
 	GError *error_dbus = NULL;
@@ -2431,6 +2487,10 @@ gpk_dbus_task_remove_package_by_file (GpkDbusTask *dtask, gchar **full_paths)
 	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (full_paths != NULL);
 
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	/* optional */
 	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
@@ -2497,7 +2557,7 @@ out:
  * gpk_dbus_task_install_catalogs:
  **/
 void
-gpk_dbus_task_install_catalogs (GpkDbusTask *dtask, gchar **filenames)
+gpk_dbus_task_install_catalogs (GpkDbusTask *dtask, gchar **filenames, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
 {
 	GError *error_dbus = NULL;
 	GtkResponseType button;
@@ -2505,6 +2565,13 @@ gpk_dbus_task_install_catalogs (GpkDbusTask *dtask, gchar **filenames)
 	const gchar *title;
 	guint len;
 
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+	g_return_if_fail (filenames != NULL);
+
+	/* save callback information */
+	dtask->priv->finished_cb = finished_cb;
+	dtask->priv->finished_userdata = userdata;
+
 	len = g_strv_length (filenames);
 
 	/* optional */
diff --git a/src/gpk-dbus-task.h b/src/gpk-dbus-task.h
index b9e1ecf..d493662 100644
--- a/src/gpk-dbus-task.h
+++ b/src/gpk-dbus-task.h
@@ -85,27 +85,51 @@ GType		 gpk_dbus_task_get_type			(void);
 GType		 gpk_dbus_task_error_get_type		(void);
 GpkDbusTask	*gpk_dbus_task_new			(void);
 
+/* callback when done */
+typedef void	(*GpkDbusTaskFinishedCb)		(GpkDbusTask	*dtask,
+							 gpointer	 userdata);
+
 /* methods that expect a DBusGMethodInvocation return */
 void		 gpk_dbus_task_is_installed		(GpkDbusTask	*dtask,
-							 const gchar	*package_name);
+							 const gchar	*package_name,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_search_file		(GpkDbusTask	*dtask,
-							 const gchar	*search_file);
+							 const gchar	*search_file,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_package_files	(GpkDbusTask	*dtask,
-							 gchar		**files_rel);
+							 gchar		**files_rel,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_provide_files	(GpkDbusTask	*dtask,
-							 gchar		**full_paths);
+							 gchar		**full_paths,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_mime_types	(GpkDbusTask	*dtask,
-							 gchar		**mime_types);
+							 gchar		**mime_types,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_gstreamer_resources (GpkDbusTask	*dtask,
-							 gchar		**codec_names);
+							 gchar		**codec_names,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask,
-							 gchar		**fonts);
+							 gchar		**fonts,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_package_names	(GpkDbusTask	*dtask,
-							 gchar		**packages);
+							 gchar		**packages,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_install_catalogs		(GpkDbusTask	*dtask,
-							 gchar		**filenames);
+							 gchar		**filenames,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 void		 gpk_dbus_task_remove_package_by_file	(GpkDbusTask	*dtask,
-							 gchar		**full_paths);
+							 gchar		**full_paths,
+							 GpkDbusTaskFinishedCb finished_cb,
+							 gpointer	 userdata);
 
 /* set state */
 gboolean	 gpk_dbus_task_set_interaction		(GpkDbusTask	*dtask,
diff --git a/src/gpk-dbus.c b/src/gpk-dbus.c
index e8c0389..0836c7e 100644
--- a/src/gpk-dbus.c
+++ b/src/gpk-dbus.c
@@ -57,8 +57,9 @@ struct GpkDbusPrivate
 {
 	GConfClient		*gconf_client;
 	gint			 timeout_tmp;
+	GTimer			*timer;
+	guint			 refcount;
 	GpkX11			*x11;
-	GPtrArray		*array;
 	DBusGProxy		*proxy_session_pid;
 	DBusGProxy		*proxy_system_pid;
 };
@@ -103,6 +104,24 @@ gpk_dbus_error_get_type (void)
 }
 
 /**
+ * gpk_dbus_get_idle_time:
+ **/
+guint
+gpk_dbus_get_idle_time (GpkDbus	*dbus)
+{
+	guint idle = 0;
+
+	/* we need to return 0 if there is a task in progress */
+	if (dbus->priv->refcount > 0)
+		goto out;
+
+	idle = (guint) g_timer_elapsed (dbus->priv->timer, NULL);
+	egg_debug ("we've been idle for %is", idle);
+out:
+	return idle;
+}
+
+/**
  * gpk_dbus_get_pid_session:
  **/
 static guint
@@ -363,14 +382,30 @@ gpk_dbus_create_task (GpkDbus *dbus, guint32 xid, const gchar *interaction, DBus
 	/* unref on delete */
 	//g_signal_connect...
 
-	/* add to array */
-	g_ptr_array_add (dbus->priv->array, task);
+	/* reset time */
+	g_timer_reset (dbus->priv->timer);
+	dbus->priv->refcount++;
 
 	g_free (sender);
 	g_free (exec);
 	return task;
 }
 
+/**
+ * gpk_dbus_task_finished_cb:
+ **/
+static void
+gpk_dbus_task_finished_cb (GpkDbusTask *task, GpkDbus *dbus)
+{
+	/* one context has returned */
+	if (dbus->priv->refcount > 0)
+		dbus->priv->refcount--;
+
+	/* reset time */
+	g_timer_reset (dbus->priv->timer);
+
+	g_object_unref (task);
+}
 
 /**
  * gpk_dbus_is_installed:
@@ -380,7 +415,7 @@ gpk_dbus_is_installed (GpkDbus *dbus, const gchar *package_name, const gchar *in
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, 0, interaction, context);
-	gpk_dbus_task_is_installed (task, package_name);
+	gpk_dbus_task_is_installed (task, package_name, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -391,7 +426,7 @@ gpk_dbus_search_file (GpkDbus *dbus, const gchar *file_name, const gchar *intera
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, 0, interaction, context);
-	gpk_dbus_task_search_file (task, file_name);
+	gpk_dbus_task_search_file (task, file_name, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -402,7 +437,7 @@ gpk_dbus_install_package_files (GpkDbus *dbus, guint32 xid, gchar **files, const
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_package_files (task, files);
+	gpk_dbus_task_install_package_files (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -413,7 +448,7 @@ gpk_dbus_install_provide_files (GpkDbus *dbus, guint32 xid, gchar **files, const
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_provide_files (task, files);
+	gpk_dbus_task_install_provide_files (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -424,7 +459,7 @@ gpk_dbus_remove_package_by_file (GpkDbus *dbus, guint32 xid, gchar **files, cons
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_remove_package_by_file (task, files);
+	gpk_dbus_task_remove_package_by_file (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -435,7 +470,7 @@ gpk_dbus_install_catalogs (GpkDbus *dbus, guint32 xid, gchar **files, const gcha
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_catalogs (task, files);
+	gpk_dbus_task_install_catalogs (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -446,7 +481,7 @@ gpk_dbus_install_package_names (GpkDbus *dbus, guint32 xid, gchar **packages, co
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_package_names (task, packages);
+	gpk_dbus_task_install_package_names (task, packages, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -457,7 +492,7 @@ gpk_dbus_install_mime_types (GpkDbus *dbus, guint32 xid, gchar **mime_types, con
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_mime_types (task, mime_types);
+	gpk_dbus_task_install_mime_types (task, mime_types, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -468,7 +503,7 @@ gpk_dbus_install_fontconfig_resources (GpkDbus *dbus, guint32 xid, gchar **resou
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_fontconfig_resources (task, resources);
+	gpk_dbus_task_install_fontconfig_resources (task, resources, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -479,7 +514,7 @@ gpk_dbus_install_gstreamer_resources (GpkDbus *dbus, guint32 xid, gchar **resour
 {
 	GpkDbusTask *task;
 	task = gpk_dbus_create_task (dbus, xid, interaction, context);
-	gpk_dbus_task_install_gstreamer_resources (task, resources);
+	gpk_dbus_task_install_gstreamer_resources (task, resources, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
 }
 
 /**
@@ -506,8 +541,8 @@ gpk_dbus_init (GpkDbus *dbus)
 	dbus->priv = GPK_DBUS_GET_PRIVATE (dbus);
 	dbus->priv->timeout_tmp = -1;
 	dbus->priv->gconf_client = gconf_client_get_default ();
-	dbus->priv->array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 	dbus->priv->x11 = gpk_x11_new ();
+	dbus->priv->timer = g_timer_new ();
 
 	/* find out PIDs on the session bus */
 	connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
@@ -535,7 +570,7 @@ gpk_dbus_finalize (GObject *object)
 
 	dbus = GPK_DBUS (object);
 	g_return_if_fail (dbus->priv != NULL);
-	g_ptr_array_unref (dbus->priv->array);
+	g_timer_destroy (dbus->priv->timer);
 	g_object_unref (dbus->priv->gconf_client);
 	g_object_unref (dbus->priv->x11);
 	g_object_unref (dbus->priv->proxy_session_pid);
diff --git a/src/gpk-dbus.h b/src/gpk-dbus.h
index c9b8301..c531b28 100644
--- a/src/gpk-dbus.h
+++ b/src/gpk-dbus.h
@@ -64,6 +64,8 @@ GType		 gpk_dbus_error_get_type		(void);
 GType		 gpk_dbus_get_type			(void);
 GpkDbus		*gpk_dbus_new				(void);
 
+guint		 gpk_dbus_get_idle_time			(GpkDbus	*dbus);
+
 /* org.freedesktop.PackageKit.Query */
 void		 gpk_dbus_is_installed			(GpkDbus	*dbus,
 							 const gchar	*package_name,
diff --git a/src/gpk-update-icon.c b/src/gpk-update-icon.c
index 65af229..b17d5fb 100644
--- a/src/gpk-update-icon.c
+++ b/src/gpk-update-icon.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007-2008 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2009 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -40,70 +40,9 @@
 #include "gpk-watch.h"
 #include "gpk-firmware.h"
 #include "gpk-hardware.h"
-#include "gpk-dbus.h"
-#include "org.freedesktop.PackageKit.h"
 #include "gpk-common.h"
 
 /**
- * gpk_object_register:
- * @connection: What we want to register to
- * @object: The GObject we want to register
- *
- * Return value: success
- **/
-static gboolean
-gpk_object_register (DBusGConnection *connection, GObject *object)
-{
-	DBusGProxy *bus_proxy = NULL;
-	GError *error = NULL;
-	guint request_name_result;
-	gboolean ret;
-
-	/* connect to the bus */
-	bus_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
-					       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
-
-	/* get our name */
-	ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
-				 G_TYPE_STRING, PK_DBUS_SERVICE,
-				 G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
-					      DBUS_NAME_FLAG_REPLACE_EXISTING |
-					      DBUS_NAME_FLAG_DO_NOT_QUEUE,
-				 G_TYPE_INVALID,
-				 G_TYPE_UINT, &request_name_result,
-				 G_TYPE_INVALID);
-	if (ret == FALSE) {
-		/* abort as the DBUS method failed */
-		egg_warning ("RequestName failed: %s", error->message);
-		g_error_free (error);
-		return FALSE;
-	}
-
-	/* free the bus_proxy */
-	g_object_unref (G_OBJECT (bus_proxy));
-
-	/* already running */
-	if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
-		return FALSE;
-
-	dbus_g_object_type_install_info (GPK_TYPE_DBUS, &dbus_glib_gpk_dbus_object_info);
-	dbus_g_error_domain_register (GPK_DBUS_ERROR, NULL, GPK_DBUS_TYPE_ERROR);
-	dbus_g_connection_register_g_object (connection, PK_DBUS_PATH, object);
-
-	return TRUE;
-}
-
-/**
- * pk_dbus_connection_replaced_cb:
- **/
-static void
-pk_dbus_connection_replaced_cb (EggDbusMonitor *monitor, gpointer data)
-{
-	egg_warning ("exiting as we have been replaced");
-	gtk_main_quit ();
-}
-
-/**
  * main:
  **/
 int
@@ -113,14 +52,10 @@ main (int argc, char *argv[])
 	gboolean timed_exit = FALSE;
 	GpkCheckUpdate *cupdate = NULL;
 	GpkWatch *watch = NULL;
-	GpkDbus *dbus = NULL;
 	GpkFirmware *firmware = NULL;
 	GpkHardware *hardware = NULL;
 	GOptionContext *context;
-	GError *error = NULL;
 	gboolean ret;
-	DBusGConnection *connection;
-	EggDbusMonitor *monitor;
 
 	const GOptionEntry options[] = {
 		{ "timed-exit", '\0', 0, G_OPTION_ARG_NONE, &timed_exit,
@@ -170,33 +105,11 @@ main (int argc, char *argv[])
 					   GPK_DATA G_DIR_SEPARATOR_S "icons");
 
 	/* create new objects */
-	dbus = gpk_dbus_new ();
 	cupdate = gpk_check_update_new ();
 	watch = gpk_watch_new ();
 	firmware = gpk_firmware_new ();
 	hardware = gpk_hardware_new ();
 
-	/* find out when we are replaced */
-	monitor = egg_dbus_monitor_new ();
-	egg_dbus_monitor_assign (monitor, EGG_DBUS_MONITOR_SESSION, PK_DBUS_SERVICE);
-	g_signal_connect (monitor, "connection-replaced",
-			  G_CALLBACK (pk_dbus_connection_replaced_cb), NULL);
-
-	/* get the bus */
-	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-	if (error) {
-		egg_warning ("%s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* try to register */
-	ret = gpk_object_register (connection, G_OBJECT (dbus));
-	if (!ret) {
-		egg_warning ("failed to replace running instance.");
-		goto out;
-	}
-
 	/* Only timeout if we have specified iton the command line */
 	if (timed_exit)
 		g_timeout_add_seconds (120, (GSourceFunc) gtk_main_quit, NULL);
@@ -204,13 +117,10 @@ main (int argc, char *argv[])
 	/* wait */
 	gtk_main ();
 
-out:
-	g_object_unref (dbus);
 	g_object_unref (cupdate);
 	g_object_unref (watch);
 	g_object_unref (firmware);
 	g_object_unref (hardware);
-	g_object_unref (monitor);
 
 	return 0;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]