[packagekit] packagekit: Branch 'master' - 19 commits

Richard Hughes hughsient at kemper.freedesktop.org
Mon Mar 31 08:54:18 PDT 2008


 backends/alpm/pk-backend-alpm.c         |    2 
 backends/apt/helpers/aptBackend.py      |    2 
 backends/apt/helpers/get-repo-list.py   |    4 
 backends/apt/pk-backend-apt.c           |    4 
 backends/box/pk-backend-box.c           |    2 
 backends/conary/helpers/Makefile.am     |    1 
 backends/conary/helpers/update.py       |   18 ++
 backends/conary/pk-backend-conary.c     |    4 
 backends/dummy/pk-backend-dummy.c       |    2 
 backends/pisi/pk-backend-pisi.c         |    4 
 backends/poldek/pk-backend-poldek.c     |    2 
 backends/smart/helpers/get-repo-list.py |    4 
 backends/smart/helpers/smartBackend.py  |    2 
 backends/smart/pk-backend-smart.c       |    4 
 backends/test/pk-backend-test-succeed.c |    2 
 backends/yum/helpers/get-repo-list.py   |    4 
 backends/yum/helpers/yumBackend.py      |    7 
 backends/yum/pk-backend-yum.c           |    4 
 backends/yum2/helpers/yumDBUSBackend.py |   29 +--
 backends/yum2/pk-backend-yum2.c         |    4 
 client/Makefile.am                      |    3 
 client/pk-console.c                     |    2 
 client/pk-import-desktop.c              |    4 
 client/pk-import-specspo.c              |    4 
 client/pk-monitor.c                     |   20 ++
 docs/spec/pk-methods.xml                |   23 ++
 libpackagekit/Makefile.am               |    3 
 libpackagekit/pk-client.c               |  145 ++++++++----------
 libpackagekit/pk-client.h               |    5 
 libpackagekit/pk-common.h               |   14 +
 libpackagekit/pk-enum.c                 |    4 
 libpackagekit/pk-enum.h                 |    4 
 libpackagekit/pk-notify.c               |  249 ++++++++++++++++++++++++++++++++
 libpackagekit/pk-notify.h               |   72 +++++++++
 libpackagekit/pk-self-test.c            |    2 
 python/packagekit/backend.py            |    2 
 python/packagekit/daemonBackend.py      |    6 
 src/.gitignore                          |    2 
 src/Makefile.am                         |   13 +
 src/pk-backend-dbus.c                   |    3 
 src/pk-backend-dbus.h                   |    3 
 src/pk-backend-spawn.c                  |   11 -
 src/pk-backend.c                        |   38 ++++
 src/pk-backend.h                        |    4 
 src/pk-engine.c                         |   73 +++------
 src/pk-engine.h                         |    1 
 src/pk-interface-notify.xml             |   12 +
 src/pk-interface.xml                    |    7 
 src/pk-notify.c                         |  228 +++++++++++++++++++++++++++++
 src/pk-notify.h                         |   63 ++++++++
 src/pk-runner.c                         |   13 +
 src/pk-runner.h                         |    3 
 src/pk-spawn.c                          |    8 -
 53 files changed, 943 insertions(+), 206 deletions(-)

New commits:
commit c0de63ca64909e66a962ebab44050f4de0caac83
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Mar 31 13:58:38 2008 +0100

    Fix 'No package to instal' typo, fixes rh#439778

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 18874eb..404b528 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -821,7 +821,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         if txmbrs:
             self._runYumTransaction()
         else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"No packages to instal")
+            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"This package could not be installed as it is already installed")
 
     def _checkForNewer(self,po):
         pkgs = self.yumbase.pkgSack.returnNewestByName(name=po.name)
commit 2d3784df3565c88a1330210aa33927b04d47cd2d
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Mar 31 13:41:46 2008 +0100

    correct some grammar pointed out in rh#439780

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index b8f55da..18874eb 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -910,7 +910,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             self._check_for_reboot()
             if removedeps == False:
                 if len(self.yumbase.tsInfo) > 1:
-                    retmsg = 'package could not be remove, because something depends on it'
+                    retmsg = 'package could not be removed, as other packages depend on it'
                     self.error(ERROR_DEP_RESOLUTION_FAILED,retmsg)
                     return
 
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index f6eb4f5..a5f7fd2 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -1689,7 +1689,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         self._check_for_reboot()
 
         if removedeps == False and len(self.yumbase.tsInfo) > 1:
-            retmsg = 'package could not be removed, because something depends on it'
+            retmsg = 'package could not be removed, as other packages depend on it'
             self._unlock_yum()
             self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,retmsg)
             self.Finished(EXIT_FAILED)
commit f1d44a825ac6d935d573e9cdd71e2d45158b3142
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Mar 31 13:14:57 2008 +0100

    install pk-import-* into libexec as they are not meant to be run by users

diff --git a/client/Makefile.am b/client/Makefile.am
index 4d01db3..2846b9a 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -29,6 +29,9 @@ PK_LIBS =						\
 bin_PROGRAMS =						\
 	pkcon						\
 	pkmon						\
+	$(NULL)
+
+libexec_PROGRAMS =					\
 	pk-import-desktop				\
 	pk-import-specspo				\
 	$(NULL)
commit 1baa6434bc799fcd13c72b0d90e7a3fbbb72cf60
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Mar 31 12:58:44 2008 +0100

    display to the user why the pk-import-* tools fail to open the PkExtra database - fixes rh#439738

diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c
index b4c3736..e83e690 100644
--- a/client/pk-import-desktop.c
+++ b/client/pk-import-desktop.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <dbus/dbus-glib.h>
 
 #include <pk-debug.h>
@@ -277,7 +278,8 @@ main (int argc, char *argv[])
 	extra = pk_extra_new ();
 	ret = pk_extra_set_database (extra, database_location);
 	if (!ret) {
-		pk_warning ("could not open database %s", database_location);
+		g_print (_("Could not open database: %s\n"), database_location);
+		g_print (_("You probably need to run this program as the root user\n"));
 		goto out;
 	}
 
diff --git a/client/pk-import-specspo.c b/client/pk-import-specspo.c
index b80ff24..4cb6451 100644
--- a/client/pk-import-specspo.c
+++ b/client/pk-import-specspo.c
@@ -28,6 +28,7 @@
 #include <libintl.h>
 #include <locale.h>
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <dbus/dbus-glib.h>
 
 #include <pk-debug.h>
@@ -165,7 +166,8 @@ main (int argc, char *argv[])
 	extra = pk_extra_new ();
 	ret = pk_extra_set_database (extra, database_location);
 	if (!ret) {
-		pk_warning ("could not open database %s", database_location);
+		g_print (_("Could not open database: %s\n"), database_location);
+		g_print (_("You probably need to run this program as the root user\n"));
 		goto out;
 	}
 
commit c62920b1da7b203407a3622cd1387d411b861912
Author: Ken VanDine <ken at vandine.org>
Date:   Mon Mar 31 00:07:38 2008 -0400

    Added update.py

diff --git a/backends/conary/helpers/Makefile.am b/backends/conary/helpers/Makefile.am
index ab7da29..33133a8 100644
--- a/backends/conary/helpers/Makefile.am
+++ b/backends/conary/helpers/Makefile.am
@@ -11,6 +11,7 @@ dist_helper_DATA = 			\
 	get-updates.py			\
 	get-update-detail.py		\
 	install.py			\
+	update.py			\
 	refresh-cache.py		\
 	remove.py			\
 	resolve.py			\
diff --git a/backends/conary/helpers/update.py b/backends/conary/helpers/update.py
new file mode 100755
index 0000000..5e5ead7
--- /dev/null
+++ b/backends/conary/helpers/update.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ken VanDine <ken at vandine.org>
+#
+# 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.
+
+import sys
+from conaryBackend import PackageKitConaryBackend
+
+package = sys.argv[1]
+backend = PackageKitConaryBackend(sys.argv[1:])
+backend.install(package)
+sys.exit(0)
commit 8d515ea32c7f1cc7481fae2336d36c7b09be3e76
Merge: 1c769e4... 8e6fe11...
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 18:36:42 2008 +0100

    Merge branch 'master' into interface

commit 8e6fe1131443db8f86ac3a6587e922d31948cf20
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 17:38:06 2008 +0100

    resolve the path before passing it to the backend to fix rh:439692

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 0a8760f..bf18c62 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -2501,6 +2501,33 @@ pk_client_install_file_action (PkClient *client, const gchar *file, GError **err
 }
 
 /**
+ * pk_resolve_local_path:
+ *
+ * Resolves paths like ../../Desktop/bar.rpm to /home/hughsie/Desktop/bar.rpm
+ * TODO: We should use canonicalize_filename() in gio/glocalfile.c as realpath()
+ * is crap.
+ **/
+static gchar *
+pk_resolve_local_path (const gchar *rel_path)
+{
+	gchar *real = NULL;
+	gchar *temp;
+
+	/* don't trust realpath one little bit */
+	if (rel_path == NULL) {
+		return NULL;
+	}
+
+	temp = realpath (rel_path, NULL);
+	if (temp != NULL) {
+		real = g_strdup (temp);
+		/* yes, free, not g_free */
+		free (temp);
+	}
+	return real;
+}
+
+/**
  * pk_client_install_file:
  * @client: a valid #PkClient instance
  * @file: a file such as "/home/hughsie/Desktop/hal-devel-0.10.0.rpm"
@@ -2512,14 +2539,15 @@ pk_client_install_file_action (PkClient *client, const gchar *file, GError **err
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_install_file (PkClient *client, const gchar *file, GError **error)
+pk_client_install_file (PkClient *client, const gchar *file_rel, GError **error)
 {
 	gboolean ret;
+	gchar *file;
 	GError *error_pk = NULL; /* we can't use the same error as we might be NULL */
 
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
-	g_return_val_if_fail (file != NULL, FALSE);
+	g_return_val_if_fail (file_rel != NULL, FALSE);
 
 	/* check to see if we already have a transaction */
 	ret = pk_client_allocate_transaction_id (client, error);
@@ -2527,6 +2555,10 @@ pk_client_install_file (PkClient *client, const gchar *file, GError **error)
 		return FALSE;
 	}
 
+	/* resolve to an absolute path */
+	file = pk_resolve_local_path (file_rel);
+	pk_debug ("resolved %s to %s", file_rel, file);
+
 	/* save this so we can re-issue it */
 	client->priv->role = PK_ROLE_ENUM_INSTALL_FILE;
 	client->priv->cached_full_path = g_strdup (file);
@@ -2560,6 +2592,7 @@ pk_client_install_file (PkClient *client, const gchar *file, GError **error)
 		}
 	}
 
+	g_free (file);
 	return ret;
 }
 
@@ -3775,12 +3808,42 @@ libst_client (LibSelfTest *test)
 	guint size;
 	guint size_new;
 	guint i;
+	gchar *file;
 
 	if (libst_start (test, "PkClient", CLASS_AUTO) == FALSE) {
 		return;
 	}
 
 	/************************************************************/
+	libst_title (test, "test resolve NULL");
+	file = pk_resolve_local_path (NULL);
+	if (file == NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "test resolve /etc/hosts");
+	file = pk_resolve_local_path ("/etc/hosts");
+	if (file != NULL && pk_strequal (file, "/etc/hosts")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "got: %s", file);
+	}
+	g_free (file);
+
+	/************************************************************/
+	libst_title (test, "test resolve /etc/../etc/hosts");
+	file = pk_resolve_local_path ("/etc/../etc/hosts");
+	if (file != NULL && pk_strequal (file, "/etc/hosts")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "got: %s", file);
+	}
+	g_free (file);
+
+	/************************************************************/
 	libst_title (test, "get client");
 	client = pk_client_new ();
 	if (client != NULL) {
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 0fe7584..aef96d7 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -285,7 +285,7 @@ gboolean	 pk_client_update_packages_strv		(PkClient	*client,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_install_file			(PkClient	*client,
-							 const gchar	*file,
+							 const gchar	*file_rel,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_resolve			(PkClient	*client,
commit 1c769e4b7099494ec3033f9a2954cdad774a0adb
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 16:40:07 2008 +0100

    Add a new DBUS interface org.freedesktop.PackageKit.Notify so we can get
    system wide notifications from PackageKit, without having to bodge PkClient
    to do this for us.
    
    As a general note, PackageKit abuses the concept of DBUS paths, having all the
    transactions on on path, and doing the demux itself. This patch is the first
    of many to make the DBUS interface a whole lot more sane.
    
    This was triggered by someone pointing out why this comment existed:
    /* we always emit, even if the tid does not match */

diff --git a/client/pk-monitor.c b/client/pk-monitor.c
index e9ed835..3b67a92 100644
--- a/client/pk-monitor.c
+++ b/client/pk-monitor.c
@@ -31,6 +31,7 @@
 #include <pk-debug.h>
 #include <pk-common.h>
 #include <pk-client.h>
+#include <pk-notify.h>
 #include <pk-task-list.h>
 #include <pk-connection.h>
 
@@ -125,12 +126,21 @@ pk_monitor_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpoint
  * pk_monitor_repo_list_changed_cb:
  **/
 static void
-pk_monitor_repo_list_changed_cb (PkClient *client, gpointer data)
+pk_monitor_repo_list_changed_cb (PkNotify *notify, gpointer data)
 {
 	g_print ("repo-list-changed\n");
 }
 
 /**
+ * pk_monitor_updates_changed_cb:
+ **/
+static void
+pk_monitor_updates_changed_cb (PkNotify *notify, gpointer data)
+{
+	g_print ("updates-changed\n");
+}
+
+/**
  * pk_connection_changed_cb:
  **/
 static void
@@ -147,6 +157,7 @@ main (int argc, char *argv[])
 {
 	PkTaskList *tlist;
 	PkClient *client;
+	PkNotify *notify;
 	gboolean ret;
 	GMainLoop *loop;
 	PkConnection *pconnection;
@@ -206,8 +217,12 @@ main (int argc, char *argv[])
 			  G_CALLBACK (pk_monitor_package_cb), NULL);
 	g_signal_connect (client, "allow-cancel",
 			  G_CALLBACK (pk_monitor_allow_cancel_cb), NULL);
-	g_signal_connect (client, "repo-list-changed",
+
+	notify = pk_notify_new ();
+	g_signal_connect (notify, "repo-list-changed",
 			  G_CALLBACK (pk_monitor_repo_list_changed_cb), NULL);
+	g_signal_connect (notify, "updates-changed",
+			  G_CALLBACK (pk_monitor_updates_changed_cb), NULL);
 
 	tlist = pk_task_list_new ();
 	g_signal_connect (tlist, "task-list-changed",
@@ -223,6 +238,7 @@ main (int argc, char *argv[])
 	g_main_loop_run (loop);
 
 	g_object_unref (client);
+	g_object_unref (notify);
 	g_object_unref (tlist);
 	g_object_unref (pconnection);
 
diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 97fc768..704db72 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -46,6 +46,7 @@ libpackagekit_include_HEADERS =					\
 	pk-common.h						\
 	pk-filter.h						\
 	pk-client.h						\
+	pk-notify.h						\
 	pk-task-list.h						\
 	pk-job-list.h						\
 	pk-polkit-client.h					\
@@ -79,6 +80,8 @@ libpackagekit_la_SOURCES =					\
 	pk-filter.h						\
 	pk-client.c						\
 	pk-client.h						\
+	pk-notify.c						\
+	pk-notify.h						\
 	pk-task-list.c						\
 	pk-task-list.h						\
 	pk-job-list.c						\
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 0a8760f..e20ccad 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -98,8 +98,6 @@ typedef enum {
 	PK_CLIENT_FINISHED,
 	PK_CLIENT_PACKAGE,
 	PK_CLIENT_PROGRESS_CHANGED,
-	PK_CLIENT_UPDATES_CHANGED,
-	PK_CLIENT_REPO_LIST_CHANGED,
 	PK_CLIENT_REQUIRE_RESTART,
 	PK_CLIENT_MESSAGE,
 	PK_CLIENT_TRANSACTION,
@@ -696,36 +694,6 @@ pk_client_package_cb (DBusGProxy   *proxy,
 }
 
 /**
- * pk_client_updates_changed_cb:
- */
-static void
-pk_client_updates_changed_cb (DBusGProxy *proxy, const gchar *tid, PkClient *client)
-{
-	g_return_if_fail (client != NULL);
-	g_return_if_fail (PK_IS_CLIENT (client));
-
-	/* we always emit, even if the tid does not match */
-	pk_debug ("emitting updates-changed");
-	g_signal_emit (client, signals [PK_CLIENT_UPDATES_CHANGED], 0);
-
-}
-
-/**
- * pk_client_repo_list_changed_cb:
- */
-static void
-pk_client_repo_list_changed_cb (DBusGProxy *proxy, const gchar *tid, PkClient *client)
-{
-	g_return_if_fail (client != NULL);
-	g_return_if_fail (PK_IS_CLIENT (client));
-
-	/* we always emit, even if the tid does not match */
-	pk_debug ("emitting repo-list-changed");
-	g_signal_emit (client, signals [PK_CLIENT_REPO_LIST_CHANGED], 0);
-
-}
-
-/**
  * pk_client_transaction_cb:
  */
 static void
@@ -3146,32 +3114,6 @@ pk_client_class_init (PkClientClass *klass)
 			      NULL, NULL, g_cclosure_marshal_VOID__UINT,
 			      G_TYPE_NONE, 1, G_TYPE_UINT);
 	/**
-	 * PkClient::updates-changed:
-	 * @client: the #PkClient instance that emitted the signal
-	 *
-	 * The ::updates-changed signal is emitted when the update list may have
-	 * changed and the client program may have to update some UI.
-	 **/
-	signals [PK_CLIENT_UPDATES_CHANGED] =
-		g_signal_new ("updates-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (PkClientClass, updates_changed),
-			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
-	/**
-	 * PkClient::repo-list-changed:
-	 * @client: the #PkClient instance that emitted the signal
-	 *
-	 * The ::repo-list-changed signal is emitted when the repo list may have
-	 * changed and the client program may have to update some UI.
-	 **/
-	signals [PK_CLIENT_REPO_LIST_CHANGED] =
-		g_signal_new ("repo-list-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (PkClientClass, repo_list_changed),
-			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
-	/**
 	 * PkClient::progress-changed:
 	 * @client: the #PkClient instance that emitted the signal
 	 * @percentage: the percentage of the transaction
@@ -3593,16 +3535,6 @@ pk_client_init (PkClient *client)
 	dbus_g_proxy_connect_signal (proxy, "Transaction",
 				     G_CALLBACK (pk_client_transaction_cb), client, NULL);
 
-	dbus_g_proxy_add_signal (proxy, "UpdatesChanged",
-				 G_TYPE_STRING, G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (proxy, "UpdatesChanged",
-				     G_CALLBACK (pk_client_updates_changed_cb), client, NULL);
-
-	dbus_g_proxy_add_signal (proxy, "RepoListChanged",
-				 G_TYPE_STRING, G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal (proxy, "RepoListChanged",
-				     G_CALLBACK (pk_client_repo_list_changed_cb), client, NULL);
-
 	dbus_g_proxy_add_signal (proxy, "UpdateDetail",
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
@@ -3697,10 +3629,6 @@ pk_client_finalize (GObject *object)
 				        G_CALLBACK (pk_client_progress_changed_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "StatusChanged",
 				        G_CALLBACK (pk_client_status_changed_cb), client);
-	dbus_g_proxy_disconnect_signal (client->priv->proxy, "UpdatesChanged",
-				        G_CALLBACK (pk_client_updates_changed_cb), client);
-	dbus_g_proxy_disconnect_signal (client->priv->proxy, "RepoListChanged",
-				        G_CALLBACK (pk_client_repo_list_changed_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Package",
 				        G_CALLBACK (pk_client_package_cb), client);
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Transaction",
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 0fe7584..c81b4b4 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -82,8 +82,6 @@ struct _PkClientClass
 	/* Signals */
 	void		(* status_changed)		(PkClient	*client,
 							 PkStatusEnum	 status);
-	void		(* updates_changed)		(PkClient	*client);
-	void		(* repo_list_changed)		(PkClient	*client);
 	void		(* progress_changed)		(PkClient	*client,
 							 guint		 percentage,
 							 guint		 subpercentage,
diff --git a/libpackagekit/pk-common.h b/libpackagekit/pk-common.h
index de9fea4..88cc2f4 100644
--- a/libpackagekit/pk-common.h
+++ b/libpackagekit/pk-common.h
@@ -41,12 +41,26 @@ G_BEGIN_DECLS
 #define	PK_DBUS_PATH			"/org/freedesktop/PackageKit"
 
 /**
+ * PK_DBUS_PATH_NOTIFY:
+ *
+ * The DBUS path for the notifications (why can't we use PK_DBUS_PATH?)
+ */
+#define	PK_DBUS_PATH_NOTIFY		"/org/freedesktop/PackageKit/Notify"
+
+/**
  * PK_DBUS_INTERFACE:
  *
  * The DBUS interface
  */
 #define	PK_DBUS_INTERFACE		"org.freedesktop.PackageKit"
 
+/**
+ * PK_DBUS_INTERFACE:
+ *
+ * The DBUS interface for the notifications
+ */
+#define	PK_DBUS_INTERFACE_NOTIFY	"org.freedesktop.PackageKit.Notify"
+
 guint		 pk_strlen				(gchar		*text,
 							 guint		 max_length)
 							 G_GNUC_WARN_UNUSED_RESULT;
diff --git a/libpackagekit/pk-notify.c b/libpackagekit/pk-notify.c
new file mode 100644
index 0000000..30adb30
--- /dev/null
+++ b/libpackagekit/pk-notify.c
@@ -0,0 +1,249 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at 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.
+ */
+
+/**
+ * SECTION:pk-notify
+ * @short_description: GObject class for PackageKit notifications
+ *
+ * A nice GObject to use for detecting system wide changes in PackageKit
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <dbus/dbus-glib.h>
+
+#include "pk-enum.h"
+#include "pk-notify.h"
+#include "pk-debug.h"
+#include "pk-marshal.h"
+#include "pk-common.h"
+
+static void     pk_notify_class_init	(PkNotifyClass *klass);
+static void     pk_notify_init		(PkNotify      *notify);
+static void     pk_notify_finalize	(GObject       *object);
+
+#define PK_NOTIFY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NOTIFY, PkNotifyPrivate))
+
+/**
+ * PkNotifyPrivate:
+ *
+ * Private #PkNotify data
+ **/
+struct _PkNotifyPrivate
+{
+	DBusGConnection		*connection;
+	DBusGProxy		*proxy;
+};
+
+typedef enum {
+	PK_NOTIFY_UPDATES_CHANGED,
+	PK_NOTIFY_REPO_LIST_CHANGED,
+	PK_NOTIFY_LAST_SIGNAL
+} PkSignals;
+
+static guint signals [PK_NOTIFY_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkNotify, pk_notify, G_TYPE_OBJECT)
+
+/**
+ * pk_notify_updates_changed_cb:
+ */
+static void
+pk_notify_updates_changed_cb (DBusGProxy *proxy, const gchar *tid, PkNotify *notify)
+{
+	g_return_if_fail (notify != NULL);
+	g_return_if_fail (PK_IS_NOTIFY (notify));
+
+	pk_debug ("emitting updates-changed");
+	g_signal_emit (notify, signals [PK_NOTIFY_UPDATES_CHANGED], 0);
+
+}
+
+/**
+ * pk_notify_repo_list_changed_cb:
+ */
+static void
+pk_notify_repo_list_changed_cb (DBusGProxy *proxy, const gchar *tid, PkNotify *notify)
+{
+	g_return_if_fail (notify != NULL);
+	g_return_if_fail (PK_IS_NOTIFY (notify));
+
+	pk_debug ("emitting repo-list-changed");
+	g_signal_emit (notify, signals [PK_NOTIFY_REPO_LIST_CHANGED], 0);
+
+}
+
+/**
+ * pk_notify_class_init:
+ **/
+static void
+pk_notify_class_init (PkNotifyClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = pk_notify_finalize;
+
+	/**
+	 * PkNotify::updates-changed:
+	 * @notify: the #PkNotify instance that emitted the signal
+	 *
+	 * The ::updates-changed signal is emitted when the update list may have
+	 * changed and the notify program may have to update some UI.
+	 **/
+	signals [PK_NOTIFY_UPDATES_CHANGED] =
+		g_signal_new ("updates-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkNotifyClass, updates_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+	/**
+	 * PkNotify::repo-list-changed:
+	 * @notify: the #PkNotify instance that emitted the signal
+	 *
+	 * The ::repo-list-changed signal is emitted when the repo list may have
+	 * changed and the notify program may have to update some UI.
+	 **/
+	signals [PK_NOTIFY_REPO_LIST_CHANGED] =
+		g_signal_new ("repo-list-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkNotifyClass, repo_list_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
+	g_type_class_add_private (klass, sizeof (PkNotifyPrivate));
+}
+
+/**
+ * pk_notify_init:
+ **/
+static void
+pk_notify_init (PkNotify *notify)
+{
+	GError *error = NULL;
+	notify->priv = PK_NOTIFY_GET_PRIVATE (notify);
+
+	/* check dbus connections, exit if not valid */
+	notify->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (error != NULL) {
+		pk_warning ("%s", error->message);
+		g_error_free (error);
+		g_error ("This program cannot start until you start the dbus system service.");
+	}
+
+	/* get a connection */
+	notify->priv->proxy = dbus_g_proxy_new_for_name (notify->priv->connection,
+							 PK_DBUS_SERVICE, PK_DBUS_PATH_NOTIFY,
+							 PK_DBUS_INTERFACE_NOTIFY);
+	if (notify->priv->proxy == NULL) {
+		g_error ("Cannot connect to PackageKit.");
+	}
+
+	dbus_g_proxy_add_signal (notify->priv->proxy, "UpdatesChanged",
+				 G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (notify->priv->proxy, "UpdatesChanged",
+				     G_CALLBACK (pk_notify_updates_changed_cb), notify, NULL);
+
+	dbus_g_proxy_add_signal (notify->priv->proxy, "RepoListChanged",
+				 G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (notify->priv->proxy, "RepoListChanged",
+				     G_CALLBACK (pk_notify_repo_list_changed_cb), notify, NULL);
+}
+
+/**
+ * pk_notify_finalize:
+ **/
+static void
+pk_notify_finalize (GObject *object)
+{
+	PkNotify *notify;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NOTIFY (object));
+	notify = PK_NOTIFY (object);
+	g_return_if_fail (notify->priv != NULL);
+
+	/* disconnect signal handlers */
+	dbus_g_proxy_disconnect_signal (notify->priv->proxy, "UpdatesChanged",
+				        G_CALLBACK (pk_notify_updates_changed_cb), notify);
+	dbus_g_proxy_disconnect_signal (notify->priv->proxy, "RepoListChanged",
+				        G_CALLBACK (pk_notify_repo_list_changed_cb), notify);
+
+	/* free the proxy */
+	g_object_unref (G_OBJECT (notify->priv->proxy));
+
+	G_OBJECT_CLASS (pk_notify_parent_class)->finalize (object);
+}
+
+/**
+ * pk_notify_new:
+ *
+ * PkNotify is a nice GObject wrapper for PackageKit and makes writing
+ * frontends easy.
+ *
+ * Return value: A new %PkNotify instance
+ **/
+PkNotify *
+pk_notify_new (void)
+{
+	PkNotify *notify;
+	notify = g_object_new (PK_TYPE_NOTIFY, NULL);
+	return PK_NOTIFY (notify);
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_notify (LibSelfTest *test)
+{
+	PkNotify *notify;
+
+	if (libst_start (test, "PkNotify", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "get notify");
+	notify = pk_notify_new ();
+	if (notify != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+	g_object_unref (notify);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-notify.h b/libpackagekit/pk-notify.h
new file mode 100644
index 0000000..84c57c0
--- /dev/null
+++ b/libpackagekit/pk-notify.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at 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.
+ */
+
+#ifndef __PK_NOTIFY_H
+#define __PK_NOTIFY_H
+
+#include <glib-object.h>
+#include "pk-enum.h"
+#include "pk-enum-list.h"
+#include "pk-package-list.h"
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NOTIFY		(pk_notify_get_type ())
+#define PK_NOTIFY(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NOTIFY, PkNotify))
+#define PK_NOTIFY_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NOTIFY, PkNotifyClass))
+#define PK_IS_NOTIFY(o)	 	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NOTIFY))
+#define PK_IS_NOTIFY_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NOTIFY))
+#define PK_NOTIFY_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NOTIFY, PkNotifyClass))
+#define PK_NOTIFY_ERROR	 	(pk_notify_error_quark ())
+#define PK_NOTIFY_TYPE_ERROR	(pk_notify_error_get_type ())
+
+typedef struct _PkNotifyPrivate		PkNotifyPrivate;
+typedef struct _PkNotify		PkNotify;
+typedef struct _PkNotifyClass		PkNotifyClass;
+
+struct _PkNotify
+{
+	GObject		 parent;
+	PkNotifyPrivate	*priv;
+};
+
+struct _PkNotifyClass
+{
+	GObjectClass	parent_class;
+	/* signals */
+	void		(* updates_changed)		(PkNotify	*notify);
+	void		(* repo_list_changed)		(PkNotify	*notify);
+	/* padding for future expansion */
+	void (*_pk_reserved1) (void);
+	void (*_pk_reserved2) (void);
+	void (*_pk_reserved3) (void);
+	void (*_pk_reserved4) (void);
+	void (*_pk_reserved5) (void);
+};
+
+GType		 pk_notify_error_get_type		(void);
+GType		 pk_notify_get_type			(void);
+PkNotify	*pk_notify_new				(void);
+
+G_END_DECLS
+
+#endif /* __PK_NOTIFY_H */
+
diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c
index 05255a7..c62674d 100644
--- a/libpackagekit/pk-self-test.c
+++ b/libpackagekit/pk-self-test.c
@@ -37,6 +37,7 @@ void libst_enum_list (LibSelfTest *test);
 void libst_extra (LibSelfTest *test);
 void libst_extra_obj (LibSelfTest *test);
 void libst_client (LibSelfTest *test);
+void libst_notify (LibSelfTest *test);
 
 int
 main (int argc, char **argv)
@@ -58,6 +59,7 @@ main (int argc, char **argv)
 	libst_extra (&test);
 	libst_extra_obj (&test);
 	libst_client (&test);
+	libst_notify (&test);
 
 	return (libst_finish (&test));
 }
diff --git a/src/.gitignore b/src/.gitignore
index dc4a293..f3ad734 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -3,7 +3,7 @@
 *.o
 pk-marshal.h
 pk-marshal.c
-pk-interface.h
+pk-interface*.h
 packagekitd
 pk-self-test
 debug.log
diff --git a/src/Makefile.am b/src/Makefile.am
index 23ce93e..cff2004 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,6 +52,8 @@ shared_SOURCES =					\
 	pk-time.c					\
 	pk-conf.c					\
 	pk-conf.h					\
+	pk-notify.c					\
+	pk-notify.h					\
 	pk-spawn.c					\
 	pk-spawn.h					\
 	pk-engine.h					\
@@ -113,6 +115,7 @@ BUILT_SOURCES = 					\
 	pk-marshal.c					\
 	pk-marshal.h					\
 	pk-interface.h					\
+	pk-interface-notify.h					\
 	$(NULL)
 
 pk-marshal.c: pk-marshal.list
@@ -126,9 +129,16 @@ pk-interface.h: pk-interface.xml
 	$(LIBTOOL) --mode=execute dbus-binding-tool	\
 		--prefix=pk_engine			\
 		--mode=glib-server			\
-		--output=pk-interface.h	\
+		--output=pk-interface.h			\
 		$(srcdir)/pk-interface.xml
 
+pk-interface-notify.h: pk-interface-notify.xml
+	$(LIBTOOL) --mode=execute dbus-binding-tool	\
+		--prefix=pk_notify			\
+		--mode=glib-server			\
+		--output=pk-interface-notify.h		\
+		$(srcdir)/pk-interface-notify.xml
+
 if PK_BUILD_TESTS
 
 check_PROGRAMS =					\
@@ -172,6 +182,7 @@ EXTRA_DIST =						\
 	pk-security-polkit.c				\
 	pk-security-dummy.c				\
 	pk-interface.xml				\
+	pk-interface-notify.xml				\
 	$(NULL)
 
 clean-local:
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 36ec593..7f91d6a 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -55,7 +55,9 @@
 #include "pk-transaction-list.h"
 #include "pk-inhibit.h"
 #include "pk-marshal.h"
+#include "pk-notify.h"
 #include "pk-security.h"
+#include "pk-interface-notify.h"
 
 static void     pk_engine_class_init	(PkEngineClass *klass);
 static void     pk_engine_init		(PkEngine      *engine);
@@ -87,6 +89,7 @@ struct PkEnginePrivate
 	PkInhibit		*inhibit;
 	PkNetwork		*network;
 	PkSecurity		*security;
+	PkNotify		*notify;
 	PkEnumList		*actions;
 	PkEnumList		*groups;
 	PkEnumList		*filters;
@@ -97,14 +100,12 @@ enum {
 	PK_ENGINE_TRANSACTION_LIST_CHANGED,
 	PK_ENGINE_STATUS_CHANGED,
 	PK_ENGINE_PROGRESS_CHANGED,
+	PK_ENGINE_REPO_SIGNATURE_REQUIRED,
 	PK_ENGINE_PACKAGE,
 	PK_ENGINE_TRANSACTION,
 	PK_ENGINE_ERROR_CODE,
 	PK_ENGINE_REQUIRE_RESTART,
 	PK_ENGINE_MESSAGE,
-	PK_ENGINE_UPDATES_CHANGED,
-	PK_ENGINE_REPO_LIST_CHANGED,
-	PK_ENGINE_REPO_SIGNATURE_REQUIRED,
 	PK_ENGINE_FINISHED,
 	PK_ENGINE_UPDATE_DETAIL,
 	PK_ENGINE_DESCRIPTION,
@@ -327,8 +328,7 @@ pk_engine_updates_changed_cb (PkBackend *backend, PkEngine *engine)
 		pk_warning ("could not get current tid from backend");
 		return;
 	}
-	pk_debug ("emitting updates-changed tid:%s", c_tid);
-	g_signal_emit (engine, signals [PK_ENGINE_UPDATES_CHANGED], 0, c_tid);
+	pk_notify_updates_changed (engine->priv->notify, c_tid);
 }
 
 /**
@@ -486,25 +486,6 @@ pk_engine_files_cb (PkBackend *backend, const gchar *package_id,
 }
 
 /**
- * pk_engine_finished_updates_changed_cb:
- **/
-static gboolean
-pk_engine_finished_updates_changed_cb (gpointer data)
-{
-	const gchar *tid;
-	PkEngine *engine = PK_ENGINE (data);
-
-	g_return_val_if_fail (engine != NULL, FALSE);
-	g_return_val_if_fail (PK_IS_ENGINE (engine), FALSE);
-
-	tid = (const gchar *) g_object_get_data (G_OBJECT (engine), "calling-tid");
-
-	pk_debug ("emitting updates-changed tid:%s", tid);
-	g_signal_emit (engine, signals [PK_ENGINE_UPDATES_CHANGED], 0, tid);
-	return FALSE;
-}
-
-/**
  * pk_engine_finish_invalidate_caches:
  **/
 static gboolean
@@ -562,8 +543,7 @@ pk_engine_finish_invalidate_caches (PkEngine *engine, PkTransactionItem *item, P
 	    role == PK_ROLE_ENUM_REPO_SET_DATA ||
 	    role == PK_ROLE_ENUM_REFRESH_CACHE) {
 		/* this needs to be done after a small delay */
-		g_object_set_data (G_OBJECT (engine), "calling-tid", g_strdup (c_tid));
-		g_timeout_add (PK_ENGINE_UPDATES_CHANGED_TIMEOUT, pk_engine_finished_updates_changed_cb, engine);
+		pk_notify_wait_updates_changed (engine->priv->notify, c_tid, PK_ENGINE_UPDATES_CHANGED_TIMEOUT);
 	}
 	return TRUE;
 }
@@ -630,8 +610,7 @@ pk_engine_finished_cb (PkBackend *backend, PkExitEnum exit, PkEngine *engine)
 	if (role == PK_ROLE_ENUM_SERVICE_PACK ||
 	    role == PK_ROLE_ENUM_REPO_ENABLE ||
 	    role == PK_ROLE_ENUM_REPO_SET_DATA) {
-		pk_debug ("emitting repo-list-changed tid:%s", c_tid);
-		g_signal_emit (engine, signals [PK_ENGINE_REPO_LIST_CHANGED], 0, c_tid);
+		pk_notify_repo_list_changed (engine->priv->notify, c_tid);
 	}
 
 	/* only reset the time if we succeeded */
@@ -2753,8 +2732,7 @@ pk_engine_state_changed_cb (gpointer data)
 		g_object_unref (engine->priv->updates_cache);
 		engine->priv->updates_cache = NULL;
 	}
-	pk_debug ("emitting updates-changed tid:%s", "unknown");
-	g_signal_emit (engine, signals [PK_ENGINE_UPDATES_CHANGED], 0, "unknown");
+	pk_notify_updates_changed (engine->priv->notify, "unknown");
 
 	/* reset, now valid */
 	engine->priv->signal_state_timeout = 0;
@@ -2982,16 +2960,6 @@ pk_engine_class_init (PkEngineClass *klass)
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING_STRING,
 			      G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
-	signals [PK_ENGINE_UPDATES_CHANGED] =
-		g_signal_new ("updates-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      0, NULL, NULL, pk_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
-	signals [PK_ENGINE_REPO_LIST_CHANGED] =
-		g_signal_new ("repo-list-changed",
-			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
-			      0, NULL, NULL, pk_marshal_VOID__STRING,
-			      G_TYPE_NONE, 1, G_TYPE_STRING);
 	signals [PK_ENGINE_REPO_SIGNATURE_REQUIRED] =
 		g_signal_new ("repo-signature-required",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
@@ -3057,6 +3025,7 @@ pk_engine_class_init (PkEngineClass *klass)
 static void
 pk_engine_init (PkEngine *engine)
 {
+	DBusGConnection *connection;
 	PkRunner *runner;
 	gboolean ret;
 
@@ -3124,6 +3093,18 @@ pk_engine_init (PkEngine *engine)
 	/* we need an auth framework */
 	engine->priv->security = pk_security_new ();
 
+	/* get another connection */
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+	if (connection == NULL) {
+		pk_error ("no connection");
+	}
+
+	/* add the interface */
+	engine->priv->notify = pk_notify_new ();
+	dbus_g_object_type_install_info (PK_TYPE_NOTIFY, &dbus_glib_pk_notify_object_info);
+	dbus_g_connection_register_g_object (connection, PK_DBUS_PATH_NOTIFY,
+					     G_OBJECT (engine->priv->notify));
+
 	engine->priv->transaction_list = pk_transaction_list_new ();
 	g_signal_connect (engine->priv->transaction_list, "changed",
 			  G_CALLBACK (pk_engine_transaction_list_changed_cb), engine);
@@ -3175,6 +3156,7 @@ pk_engine_finalize (GObject *object)
 	g_object_unref (engine->priv->transaction_db);
 	g_object_unref (engine->priv->network);
 	g_object_unref (engine->priv->security);
+	g_object_unref (engine->priv->notify);
 	g_object_unref (engine->priv->backend);
 
 	/* optional gobjects */
diff --git a/src/pk-interface-notify.xml b/src/pk-interface-notify.xml
new file mode 100644
index 0000000..b0281a9
--- /dev/null
+++ b/src/pk-interface-notify.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+  <interface name="org.freedesktop.PackageKit.Notify">
+    <signal name="RepoListChanged">
+      <arg type="s" name="tid" direction="out"/>
+    </signal>
+    <signal name="UpdatesChanged">
+      <arg type="s" name="tid" direction="out"/>
+    </signal>
+  </interface>
+</node>
+
diff --git a/src/pk-interface.xml b/src/pk-interface.xml
index 84c1a5a..fe683f6 100644
--- a/src/pk-interface.xml
+++ b/src/pk-interface.xml
@@ -181,12 +181,6 @@
       <arg type="s" name="message" direction="out"/>
       <arg type="s" name="details" direction="out"/> <!-- non-localized detail -->
     </signal>
-    <signal name="UpdatesChanged">
-      <arg type="s" name="tid" direction="out"/>
-    </signal>
-    <signal name="RepoListChanged">
-      <arg type="s" name="tid" direction="out"/>
-    </signal>
     <signal name="Locked">
       <arg type="b" name="is_locked" direction="out"/>
     </signal>
diff --git a/src/pk-notify.c b/src/pk-notify.c
new file mode 100644
index 0000000..a39cf57
--- /dev/null
+++ b/src/pk-notify.c
@@ -0,0 +1,228 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "pk-debug.h"
+#include "pk-notify.h"
+#include "pk-marshal.h"
+
+#define PK_NOTIFY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_NOTIFY, PkNotifyPrivate))
+
+struct PkNotifyPrivate
+{
+	gboolean		 dummy;
+	gchar			*tid;
+	guint			 timeout_id;
+};
+
+enum {
+	PK_NOTIFY_REPO_LIST_CHANGED,
+	PK_NOTIFY_UPDATES_CHANGED,
+	PK_NOTIFY_LAST_SIGNAL
+};
+
+static gpointer pk_notify_object = NULL;
+static guint signals [PK_NOTIFY_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkNotify, pk_notify, G_TYPE_OBJECT)
+
+/**
+ * pk_notify_repo_list_changed:
+ **/
+gboolean
+pk_notify_repo_list_changed (PkNotify *notify, const gchar *tid)
+{
+	g_return_val_if_fail (notify != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_NOTIFY (notify), FALSE);
+
+	pk_debug ("emitting repo-list-changed tid:%s", tid);
+	g_signal_emit (notify, signals [PK_NOTIFY_REPO_LIST_CHANGED], 0, tid);
+	return TRUE;
+}
+
+/**
+ * pk_notify_updates_changed:
+ **/
+gboolean
+pk_notify_updates_changed (PkNotify *notify, const gchar *tid)
+{
+	g_return_val_if_fail (notify != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_NOTIFY (notify), FALSE);
+
+	pk_debug ("emitting updates-changed tid:%s", tid);
+	g_signal_emit (notify, signals [PK_NOTIFY_UPDATES_CHANGED], 0, tid);
+	return TRUE;
+}
+
+/**
+ * pk_notify_finished_updates_changed_cb:
+ **/
+static gboolean
+pk_notify_finished_updates_changed_cb (gpointer data)
+{
+	PkNotify *notify = PK_NOTIFY (data);
+	pk_notify_updates_changed (notify, notify->priv->tid);
+	notify->priv->timeout_id = 0;
+	return FALSE;
+}
+
+
+/**
+ * pk_notify_wait_updates_changed:
+ **/
+gboolean
+pk_notify_wait_updates_changed (PkNotify *notify, const gchar *tid, guint timeout)
+{
+	g_return_val_if_fail (notify != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_NOTIFY (notify), FALSE);
+
+	/* check if we did this more than once */
+	if (notify->priv->timeout_id != 0) {
+		pk_warning ("already scheduled");
+		return FALSE;
+	}
+
+	/* save */
+	g_free (notify->priv->tid);
+	notify->priv->tid = g_strdup (tid);
+
+	/* schedule */
+	notify->priv->timeout_id = g_timeout_add (timeout, pk_notify_finished_updates_changed_cb, notify);
+	return TRUE;
+}
+
+/**
+ * pk_notify_finalize:
+ **/
+static void
+pk_notify_finalize (GObject *object)
+{
+	PkNotify *notify;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (PK_IS_NOTIFY (object));
+	notify = PK_NOTIFY (object);
+
+	/* cancel the delayed signals */
+	if (notify->priv->timeout_id != 0) {
+		g_source_remove (notify->priv->timeout_id);
+	}
+
+	g_free (notify->priv->tid);
+	G_OBJECT_CLASS (pk_notify_parent_class)->finalize (object);
+}
+
+/**
+ * pk_notify_class_init:
+ **/
+static void
+pk_notify_class_init (PkNotifyClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_notify_finalize;
+	signals [PK_NOTIFY_REPO_LIST_CHANGED] =
+		g_signal_new ("repo-list-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__STRING,
+			      G_TYPE_NONE, 1, G_TYPE_STRING);
+	signals [PK_NOTIFY_UPDATES_CHANGED] =
+		g_signal_new ("updates-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__STRING,
+			      G_TYPE_NONE, 1, G_TYPE_STRING);
+
+	g_type_class_add_private (klass, sizeof (PkNotifyPrivate));
+}
+
+/**
+ * pk_notify_init:
+ *
+ * initializes the notify class. NOTE: We expect notify objects
+ * to *NOT* be removed or added during the session.
+ * We only control the first notify object if there are more than one.
+ **/
+static void
+pk_notify_init (PkNotify *notify)
+{
+	notify->priv = PK_NOTIFY_GET_PRIVATE (notify);
+	notify->priv->tid = NULL;
+	notify->priv->timeout_id = 0;
+}
+
+/**
+ * pk_notify_new:
+ * Return value: A new notify class instance.
+ **/
+PkNotify *
+pk_notify_new (void)
+{
+	if (pk_notify_object != NULL) {
+		g_object_ref (pk_notify_object);
+	} else {
+		pk_notify_object = g_object_new (PK_TYPE_NOTIFY, NULL);
+		g_object_add_weak_pointer (pk_notify_object, &pk_notify_object);
+	}
+	return PK_NOTIFY (pk_notify_object);
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_notify (LibSelfTest *test)
+{
+	PkNotify *notify;
+
+	if (libst_start (test, "PkNotify", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "get an instance");
+	notify = pk_notify_new ();
+	if (notify != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	g_object_unref (notify);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/src/pk-notify.h b/src/pk-notify.h
new file mode 100644
index 0000000..03c219e
--- /dev/null
+++ b/src/pk-notify.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at 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.
+ */
+
+#ifndef __PK_NOTIFY_H
+#define __PK_NOTIFY_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_NOTIFY		(pk_notify_get_type ())
+#define PK_NOTIFY(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_NOTIFY, PkNotify))
+#define PK_NOTIFY_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_NOTIFY, PkNotifyClass))
+#define PK_IS_NOTIFY(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_NOTIFY))
+#define PK_IS_NOTIFY_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NOTIFY))
+#define PK_NOTIFY_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NOTIFY, PkNotifyClass))
+
+typedef struct PkNotifyPrivate PkNotifyPrivate;
+
+typedef struct
+{
+	GObject		      parent;
+	PkNotifyPrivate     *priv;
+} PkNotify;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} PkNotifyClass;
+
+GType		 pk_notify_get_type		(void);
+PkNotify	*pk_notify_new			(void);
+
+gboolean	 pk_notify_repo_list_changed	(PkNotify	*notify,
+						 const gchar	*tid);
+gboolean	 pk_notify_updates_changed	(PkNotify	*notify,
+						 const gchar	*tid);
+gboolean	 pk_notify_wait_updates_changed	(PkNotify	*notify,
+						 const gchar	*tid,
+						 guint		 timeout);
+
+G_END_DECLS
+
+#endif /* __PK_NOTIFY_H */
+
commit c365aeb6b76d7a8028da9be6095566e655ac9870
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 14:32:26 2008 +0100

    don't throw an error just for cancelling

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index b6f3261..c135cfd 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -355,13 +355,6 @@ pk_backend_spawn_finished_cb (PkSpawn *spawn, PkExitEnum exit, PkBackendSpawn *b
 	pk_debug ("deleting spawn %p, exit %s", backend_spawn, pk_exit_enum_to_text (exit));
 	pk_backend_spawn_helper_delete (backend_spawn);
 
-	/* if we quit the process, set an error */
-	if (exit == PK_EXIT_ENUM_CANCELLED) {
-		/* we just call this failed, and set an error */
-		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED,
-				       "Transaction was cancelled");
-	}
-
 	/* if we killed the process, set an error */
 	if (exit == PK_EXIT_ENUM_KILLED) {
 		/* we just call this failed, and set an error */
commit 10d484db9bcf0b9cf2301efb1c76868c5a349920
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 14:31:07 2008 +0100

    when the backend has finished, manually set the alow cancel to FALSE, so the UI does the right thing

diff --git a/src/pk-backend.c b/src/pk-backend.c
index c85470f..5f2a5aa 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1132,6 +1132,9 @@ pk_backend_finished (PkBackend *backend)
 		pk_warning ("GUI will remain unchanged!");
 	}
 
+	/* make any UI insensitive */
+	pk_backend_set_allow_cancel (backend, FALSE);
+
 	/* mark as finished for the UI that might only be watching status */
 	pk_backend_set_status (backend, PK_STATUS_ENUM_FINISHED);
 
commit 6905666d075b8b4b83bfbd446031759ec4c57dbf
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 14:21:12 2008 +0100

    rename the exit constants to be less PkSpawn-centric

diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 53308ba..c726b60 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -42,8 +42,8 @@ static PkEnumMatch enum_exit[] = {
 	{PK_EXIT_ENUM_UNKNOWN,			"unknown"},	/* fall though value */
 	{PK_EXIT_ENUM_SUCCESS,			"success"},
 	{PK_EXIT_ENUM_FAILED,			"failed"},
-	{PK_EXIT_ENUM_QUIT,			"quit"},
-	{PK_EXIT_ENUM_KILL,			"kill"},
+	{PK_EXIT_ENUM_CANCELLED,		"cancelled"},
+	{PK_EXIT_ENUM_KILLED,			"killed"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 9a0c224..dc90d6e 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -125,8 +125,8 @@ typedef enum {
 typedef enum {
 	PK_EXIT_ENUM_SUCCESS,
 	PK_EXIT_ENUM_FAILED,
-	PK_EXIT_ENUM_QUIT, /* normal cancel */
-	PK_EXIT_ENUM_KILL,
+	PK_EXIT_ENUM_CANCELLED,
+	PK_EXIT_ENUM_KILLED, /* when we forced the cancel, but had to SIGKILL */
 	PK_EXIT_ENUM_UNKNOWN
 } PkExitEnum;
 
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index e36525d..b6f3261 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -356,17 +356,17 @@ pk_backend_spawn_finished_cb (PkSpawn *spawn, PkExitEnum exit, PkBackendSpawn *b
 	pk_backend_spawn_helper_delete (backend_spawn);
 
 	/* if we quit the process, set an error */
-	if (exit == PK_EXIT_ENUM_QUIT) {
+	if (exit == PK_EXIT_ENUM_CANCELLED) {
 		/* we just call this failed, and set an error */
 		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_TRANSACTION_CANCELLED,
 				       "Transaction was cancelled");
 	}
 
 	/* if we killed the process, set an error */
-	if (exit == PK_EXIT_ENUM_KILL) {
+	if (exit == PK_EXIT_ENUM_KILLED) {
 		/* we just call this failed, and set an error */
 		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_PROCESS_KILL,
-				       "Transaction was cancelled");
+				       "Process had to be killed to be cancelled");
 	}
 
 	if (FALSE && /*TODO: backend_spawn->priv->set_error == FALSE*/
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 628ed19..c85470f 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1030,7 +1030,7 @@ pk_backend_get_role (PkBackend *backend)
 /**
  * pk_backend_set_exit_code:
  *
- * Should only be used internally, or from PkRunner when setting PK_EXIT_ENUM_QUIT.
+ * Should only be used internally, or from PkRunner when setting CANCELLED.
  **/
 gboolean
 pk_backend_set_exit_code (PkBackend *backend, PkExitEnum exit)
diff --git a/src/pk-runner.c b/src/pk-runner.c
index eda2048..5003fb6 100644
--- a/src/pk-runner.c
+++ b/src/pk-runner.c
@@ -241,7 +241,7 @@ pk_runner_cancel (PkRunner *runner, gchar **error_text)
 	pk_backend_set_allow_cancel (runner->priv->backend, FALSE);
 
 	/* we need ::finished to not return success or failed */
-	pk_backend_set_exit_code (runner->priv->backend, PK_EXIT_ENUM_QUIT);
+	pk_backend_set_exit_code (runner->priv->backend, PK_EXIT_ENUM_CANCELLED);
 
 	/* actually run the method */
 	runner->priv->backend->desc->cancel (runner->priv->backend);
diff --git a/src/pk-spawn.c b/src/pk-spawn.c
index b0fbe54..dac56e0 100644
--- a/src/pk-spawn.c
+++ b/src/pk-spawn.c
@@ -211,7 +211,7 @@ pk_spawn_sigkill_cb (PkSpawn *spawn)
 	}
 
 	/* we won't overwrite this if not unknown */
-	spawn->priv->exit = PK_EXIT_ENUM_KILL;
+	spawn->priv->exit = PK_EXIT_ENUM_KILLED;
 
 	pk_warning ("sending SIGKILL %i", spawn->priv->child_pid);
 	retval = kill (spawn->priv->child_pid, SIGKILL);
@@ -246,7 +246,7 @@ pk_spawn_kill (PkSpawn *spawn)
 	}
 
 	/* we won't overwrite this if not unknown */
-	spawn->priv->exit = PK_EXIT_ENUM_QUIT;
+	spawn->priv->exit = PK_EXIT_ENUM_CANCELLED;
 
 	pk_debug ("sending SIGQUIT %i", spawn->priv->child_pid);
 	retval = kill (spawn->priv->child_pid, SIGQUIT);
@@ -573,7 +573,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure finished in SIGKILL");
-	if (mexit == PK_EXIT_ENUM_KILL) {
+	if (mexit == PK_EXIT_ENUM_KILLED) {
 		libst_success (test, NULL);
 	} else {
 		libst_failed (test, "finish %i!", mexit);
@@ -601,7 +601,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure finished in SIGQUIT");
-	if (mexit == PK_EXIT_ENUM_QUIT) {
+	if (mexit == PK_EXIT_ENUM_CANCELLED) {
 		libst_success (test, NULL);
 	} else {
 		libst_failed (test, "finish %i!", mexit);
commit 596a602e78d65a7d021d753c6ce1f775b80bb6aa
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 14:07:09 2008 +0100

    set the backend exit code to cancelled when we cancel the running transaction, else we report success

diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 69bb3c6..9a0c224 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -125,7 +125,7 @@ typedef enum {
 typedef enum {
 	PK_EXIT_ENUM_SUCCESS,
 	PK_EXIT_ENUM_FAILED,
-	PK_EXIT_ENUM_QUIT,
+	PK_EXIT_ENUM_QUIT, /* normal cancel */
 	PK_EXIT_ENUM_KILL,
 	PK_EXIT_ENUM_UNKNOWN
 } PkExitEnum;
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 8f29d27..628ed19 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -934,7 +934,7 @@ pk_backend_error_code (PkBackend *backend, PkErrorCodeEnum code, const gchar *fo
 							     pk_backend_error_timeout_delay_cb, backend);
 
 	/* we mark any transaction with errors as failed */
-	backend->priv->exit = PK_EXIT_ENUM_FAILED;
+	pk_backend_set_exit_code (backend, PK_EXIT_ENUM_FAILED);
 
 	pk_debug ("emit error-code %i, %s", code, buffer);
 	g_signal_emit (backend, signals [PK_BACKEND_ERROR_CODE], 0, code, buffer);
@@ -1028,6 +1028,30 @@ pk_backend_get_role (PkBackend *backend)
 }
 
 /**
+ * pk_backend_set_exit_code:
+ *
+ * Should only be used internally, or from PkRunner when setting PK_EXIT_ENUM_QUIT.
+ **/
+gboolean
+pk_backend_set_exit_code (PkBackend *backend, PkExitEnum exit)
+{
+	g_return_val_if_fail (backend != NULL, PK_ROLE_ENUM_UNKNOWN);
+	g_return_val_if_fail (PK_IS_BACKEND (backend), PK_ROLE_ENUM_UNKNOWN);
+	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
+
+	if (backend->priv->exit != PK_EXIT_ENUM_UNKNOWN) {
+		pk_warning ("already set exit status: old=%s, new=%s",
+			    pk_exit_enum_to_text (backend->priv->exit),
+			    pk_exit_enum_to_text (exit));
+		return FALSE;
+	}
+
+	/* new value */
+	backend->priv->exit = exit;
+	return TRUE;
+}
+
+/**
  * pk_backend_finished_delay:
  *
  * We can call into this function if we *know* it's safe.
@@ -1036,6 +1060,12 @@ static gboolean
 pk_backend_finished_delay (gpointer data)
 {
 	PkBackend *backend = PK_BACKEND (data);
+
+	/* this wasn't set otherwise, assume success */
+	if (backend->priv->exit == PK_EXIT_ENUM_UNKNOWN) {
+		pk_backend_set_exit_code (backend, PK_EXIT_ENUM_SUCCESS);
+	}
+
 	pk_debug ("emit finished %i", backend->priv->exit);
 	g_signal_emit (backend, signals [PK_BACKEND_FINISHED], 0, backend->priv->exit);
 	return FALSE;
@@ -1135,7 +1165,6 @@ pk_backend_not_implemented_yet (PkBackend *backend, const gchar *method)
 	}
 	pk_backend_error_code (backend, PK_ERROR_ENUM_NOT_SUPPORTED, "the method '%s' is not implemented yet", method);
 	/* don't wait, do this now */
-	backend->priv->exit = PK_EXIT_ENUM_FAILED;
 	pk_backend_finished_delay (backend);
 	return TRUE;
 }
@@ -1327,7 +1356,7 @@ pk_backend_reset (PkBackend *backend)
 	backend->priv->allow_cancel = FALSE;
 	backend->priv->finished = FALSE;
 	backend->priv->status = PK_STATUS_ENUM_UNKNOWN;
-	backend->priv->exit = PK_EXIT_ENUM_SUCCESS;
+	backend->priv->exit = PK_EXIT_ENUM_UNKNOWN;
 	backend->priv->role = PK_ROLE_ENUM_UNKNOWN;
 	backend->priv->last_remaining = 0;
 	backend->priv->last_percentage = PK_BACKEND_PERCENTAGE_DEFAULT;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 6ba2804..4a9a3e8 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -46,6 +46,8 @@ gboolean	 pk_backend_set_percentage		(PkBackend	*backend,
 							 guint		 percentage);
 gboolean	 pk_backend_set_sub_percentage		(PkBackend	*backend,
 							 guint		 percentage);
+gboolean	 pk_backend_set_exit_code		(PkBackend	*backend,
+							 PkExitEnum	 exit);
 gboolean	 pk_backend_no_percentage_updates	(PkBackend	*backend);
 gboolean	 pk_backend_set_transaction_data	(PkBackend	*backend,
 							 const gchar	*data);
diff --git a/src/pk-runner.c b/src/pk-runner.c
index 11d820b..eda2048 100644
--- a/src/pk-runner.c
+++ b/src/pk-runner.c
@@ -240,6 +240,9 @@ pk_runner_cancel (PkRunner *runner, gchar **error_text)
 	/* we don't want to cancel twice */
 	pk_backend_set_allow_cancel (runner->priv->backend, FALSE);
 
+	/* we need ::finished to not return success or failed */
+	pk_backend_set_exit_code (runner->priv->backend, PK_EXIT_ENUM_QUIT);
+
 	/* actually run the method */
 	runner->priv->backend->desc->cancel (runner->priv->backend);
 	return TRUE;
commit e8d987a31193e1b1d06202060bec3847b14870ad
Merge: a7a6795... 7d2e4a2...
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 13:36:24 2008 +0100

    Merge branch 'master' into get-repo-filter

commit 7d2e4a200a9a19300f4e2bc033639c8fefe6b4ed
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun Mar 30 13:17:17 2008 +0100

    when we are asked to cancel, then send ::set-allow-cancel(false) to update UI elements

diff --git a/src/pk-runner.c b/src/pk-runner.c
index 842a6e8..e29007c 100644
--- a/src/pk-runner.c
+++ b/src/pk-runner.c
@@ -237,6 +237,9 @@ pk_runner_cancel (PkRunner *runner, gchar **error_text)
 	/* set the state, as cancelling might take a few seconds */
 	pk_backend_set_status (runner->priv->backend, PK_STATUS_ENUM_CANCEL);
 
+	/* we don't want to cancel twice */
+	pk_backend_set_allow_cancel (runner->priv->backend, FALSE);
+
 	/* actually run the method */
 	runner->priv->backend->desc->cancel (runner->priv->backend);
 	return TRUE;
commit 1472b3500cd0836ef867da78f820f1ae7aedd166
Author: Luke Macken <lmacken at redhat.com>
Date:   Sat Mar 29 10:05:43 2008 -0400

    yum2: Remove file extensions from the MetaDataMap.
    
    This fixes the issue where the file 'comps-f8.xml' gets marked as being
    'unknown' in the metadata.

diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index ff7a969..d26659d 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -210,15 +210,12 @@ groupMap = {
 }
 
 MetaDataMap = {
-'repomd.xml'             : "repository",
-'primary.sqlite.bz2'     : "package",
-'primary.xml.gz'         : "package",
-'filelists.sqlite.bz2'   : "filelist",
-'filelists.xml.gz'       : "filelist",
-'other.sqlite.bz2'       : "changelog",
-'other.xml.gz'           : "changelog",
-'comps.xml'              : "group",
-'updateinfo.xml.gz'      : "update"
+    'repomd'        : "repository",
+    'primary'       : "package",
+    'filelists'     : "filelist",
+    'other'         : "changelog",
+    'comps'         : "group",
+    'updateinfo'    : "update"
 }
 
 GUI_KEYS = re.compile(r'(qt)|(gtk)')
@@ -1971,10 +1968,11 @@ class DownloadCallback( BaseMeter ):
                 if pkg: # show package to download
                     self.base._show_package(pkg,INFO_DOWNLOADING)
                 else:
-                    if name in MetaDataMap:
-                        typ = MetaDataMap[name]
-                    else:
-                        typ = 'unknown'
+                    typ = 'unknown'
+                    for key in MetaDataMap.keys():
+                        if key in name:
+                            typ = MetaDataMap[key]
+                            break
                     self.base.MetaData(typ,name)
             self.base.SubPercentageChanged(0)
         else:
commit 240550f1b017ce34ac31e5299dd02f5bab32629f
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 12:20:11 2008 +0000

    yum(2): Set NoPercentageUpdates when doing a dep resolve

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 159601d..4f9ad77 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1442,6 +1442,7 @@ class DepSolveCallback(object):
     def start(self):
        if not self.started:
            self.backend.status(STATUS_DEP_RESOLVE)
+           self.backend.percentage(None)
 
     # Be lazy and not define the others explicitly
     def _do_nothing(self, *args, **kwargs):
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index f57fdd8..ff7a969 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -2078,6 +2078,7 @@ class DepSolveCallback(object):
     def start(self):
        if not self.started:
            self.backend.StatusChanged(STATUS_DEP_RESOLVE)
+           self.backend.NoPercentageUpdates()
 
     # Be lazy and not define the others explicitly
     def _do_nothing(self, *args, **kwargs):
commit a7a6795a78ac9e226653a2565ba6785b827a0366
Merge: 351332a... 4320467...
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 12:02:50 2008 +0000

    fix conflict

diff --cc libpackagekit/pk-client.h
index bb4874f,24605fc..0fe7584
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@@ -287,8 -306,8 +306,9 @@@ gboolean	 pk_client_requeue			(PkClien
  
  /* repo stuff */
  gboolean	 pk_client_get_repo_list		(PkClient	*client,
 +							 const gchar	*filter,
- 							 GError		**error);
+ 							 GError		**error)
+ 							 G_GNUC_WARN_UNUSED_RESULT;
  gboolean	 pk_client_repo_enable			(PkClient	*client,
  							 const gchar	*repo_id,
  							 gboolean	 enabled,
commit 351332a641cbd3e38b78e35d313c8f0252b9b286
Merge: 6734fab... c37c0e1...
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 18:13:55 2008 +0000

    Merge branch 'master' into get-repo-filter

commit 6734fab62be322219b504e2e0c79987aec64f03a
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 13:21:14 2008 +0000

    change the API of GetRepoList(void) to GetRepoList(filter) to allow us to filter out some different types of repo

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 63191b2..3b43aee 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -769,7 +769,7 @@ backend_install_file (PkBackend *backend, const gchar *path)
 }
 
 void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
   g_return_if_fail (backend != NULL);
   backend_initialize (backend);
diff --git a/backends/apt/helpers/aptBackend.py b/backends/apt/helpers/aptBackend.py
index a9def34..d804cf5 100644
--- a/backends/apt/helpers/aptBackend.py
+++ b/backends/apt/helpers/aptBackend.py
@@ -395,7 +395,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
                 repo[name] = {"entry":entry}
         return repo
 
-    def get_repo_list(self):
+    def get_repo_list(self, filters):
         '''
         Implement the {backend}-get-repo-list functionality
         '''
diff --git a/backends/apt/helpers/get-repo-list.py b/backends/apt/helpers/get-repo-list.py
index 4481b7f..5529f72 100755
--- a/backends/apt/helpers/get-repo-list.py
+++ b/backends/apt/helpers/get-repo-list.py
@@ -12,7 +12,9 @@
 import sys
 
 from aptBackend import PackageKitAptBackend
+filters = sys.argv[1]
+
 backend = PackageKitAptBackend(sys.argv[2:])
-backend.get_repo_list()
+backend.get_repo_list(filters)
 backend.unLock()
 sys.exit(0)
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index d36610c..2172d12 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -235,11 +235,11 @@ backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_i
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (spawn != NULL);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", NULL);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filter, NULL);
 }
 
 PK_BACKEND_OPTIONS (
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index f2b8258..ce912e1 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -795,7 +795,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	GList *list;
 	GList *li;
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 3445162..adec1d1 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -350,11 +350,11 @@ backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_i
  */
 /**
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (spawn != NULL);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", NULL);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filter, NULL);
 }
  */
 
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index ce06e3f..d0240ab 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -596,7 +596,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
index 5504a25..5a8d7a3 100644
--- a/backends/pisi/pk-backend-pisi.c
+++ b/backends/pisi/pk-backend-pisi.c
@@ -338,11 +338,11 @@ backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_i
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (spawn != NULL);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", NULL);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filter, NULL);
 }
 
 /**
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 69ff91d..7a63ba8 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -1935,7 +1935,7 @@ backend_update_packages (PkBackend *backend, gchar **package_ids)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter
 {
 	tn_array	*sources = NULL;
 
diff --git a/backends/smart/helpers/get-repo-list.py b/backends/smart/helpers/get-repo-list.py
index c372f1e..6f26ffb 100755
--- a/backends/smart/helpers/get-repo-list.py
+++ b/backends/smart/helpers/get-repo-list.py
@@ -13,6 +13,8 @@
 import sys
 
 from smartBackend import PackageKitSmartBackend
+filters = sys.argv[1]
+
 backend = PackageKitSmartBackend(sys.argv[2:])
-backend.get_repo_list()
+backend.get_repo_list(filters)
 sys.exit(0)
diff --git a/backends/smart/helpers/smartBackend.py b/backends/smart/helpers/smartBackend.py
index 6fc76b3..feb15a1 100644
--- a/backends/smart/helpers/smartBackend.py
+++ b/backends/smart/helpers/smartBackend.py
@@ -259,7 +259,7 @@ class PackageKitSmartBackend(PackageKitBaseBackend):
         for package in providers.keys():
             self._show_package(package)
 
-    def get_repo_list(self):
+    def get_repo_list(self, filters):
         channels = smart.sysconf.get("channels", ())
         for alias in channels:
             channel = smart.sysconf.get(("channels", alias))
diff --git a/backends/smart/pk-backend-smart.c b/backends/smart/pk-backend-smart.c
index 834efa0..c8ba33b 100644
--- a/backends/smart/pk-backend-smart.c
+++ b/backends/smart/pk-backend-smart.c
@@ -235,11 +235,11 @@ backend_update_system (PkBackend *backend)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (spawn != NULL);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", NULL);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filter, NULL);
 }
 
 /**
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 0b4c80a..d95c770 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -279,7 +279,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	pk_backend_finished (backend);
diff --git a/backends/yum/helpers/get-repo-list.py b/backends/yum/helpers/get-repo-list.py
index 96ff86a..7c0a3a5 100755
--- a/backends/yum/helpers/get-repo-list.py
+++ b/backends/yum/helpers/get-repo-list.py
@@ -12,7 +12,9 @@
 import sys
 
 from yumBackend import PackageKitYumBackend
+filters = sys.argv[1]
+
 backend = PackageKitYumBackend(sys.argv[2:])
-backend.get_repo_list()
+backend.get_repo_list(filters)
 backend.unLock()
 sys.exit(0)
diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 755d4c1..8c289d0 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1075,7 +1075,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         except yum.Errors.RepoError,e:
             self.error(ERROR_REPO_NOT_FOUND, "repo %s is not found" % repoid)
 
-    def get_repo_list(self):
+    def get_repo_list(self, filters):
         '''
         Implement the {backend}-get-repo-list functionality
         '''
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 789db09..e3c101b 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -345,11 +345,11 @@ backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_i
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (spawn != NULL);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", NULL);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filter, NULL);
 }
 
 /**
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index bbd8be8..6375421 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -1167,7 +1167,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
     @threaded
     @async
-    def doGetRepoList(self):
+    def doGetRepoList(self, filters):
         '''
         Implement the {backend}-get-repo-list functionality
         '''
diff --git a/backends/yum2/pk-backend-yum2.c b/backends/yum2/pk-backend-yum2.c
index 5473a38..5484147 100644
--- a/backends/yum2/pk-backend-yum2.c
+++ b/backends/yum2/pk-backend-yum2.c
@@ -329,11 +329,11 @@ backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_i
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend)
+backend_get_repo_list (PkBackend *backend, const gchar *filter)
 {
 	g_return_if_fail (backend != NULL);
 	g_return_if_fail (dbus != NULL);
-	pk_backend_dbus_get_repo_list (dbus);
+	pk_backend_dbus_get_repo_list (dbus, filter);
 }
 
 /**
diff --git a/client/pk-console.c b/client/pk-console.c
index da7dd80..e8d1c4a 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -942,7 +942,7 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], GError **
 			pk_enum_list_print (elist);
 			g_object_unref (elist);
 		} else if (strcmp (value, "repos") == 0) {
-			ret = pk_client_get_repo_list (client, error);
+			ret = pk_client_get_repo_list (client, "none", error);
 		} else if (strcmp (value, "groups") == 0) {
 			elist = pk_client_get_groups (client);
 			pk_enum_list_print (elist);
diff --git a/docs/spec/pk-methods.xml b/docs/spec/pk-methods.xml
index 329cb4a..03f4e2e 100644
--- a/docs/spec/pk-methods.xml
+++ b/docs/spec/pk-methods.xml
@@ -789,10 +789,29 @@
       Return the list of repositories used in the system.
     </para>
     <para>
-      There are no arguments.
+      The arguments are:
     </para>
+    <informaltable>
+      <tgroup cols="2">
+        <thead>
+          <row>
+            <entry>Option</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry><literal>filter</literal></entry>
+            <entry>
+              A correct filter, e.g. <literal>none</literal> or
+              <literal>~devel</literal>
+            </entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </informaltable>
     <para>
-      This method typically emits
+      This method should emit
       <literal>RepoDetail</literal>.
     </para>
   </sect1>
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 65805b7..d4b4f0e 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -2572,7 +2572,7 @@ pk_client_install_file (PkClient *client, const gchar *file, GError **error)
  * Return value: %TRUE if the daemon queued the transaction
  */
 gboolean
-pk_client_get_repo_list (PkClient *client, GError **error)
+pk_client_get_repo_list (PkClient *client, const gchar *filter, GError **error)
 {
 	gboolean ret;
 
@@ -2587,9 +2587,11 @@ pk_client_get_repo_list (PkClient *client, GError **error)
 
 	/* save this so we can re-issue it */
 	client->priv->role = PK_ROLE_ENUM_GET_REPO_LIST;
+	client->priv->cached_filter = g_strdup (filter);
 
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetRepoList", error,
 				 G_TYPE_STRING, client->priv->tid,
+				 G_TYPE_STRING, filter,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	pk_client_error_fixup (error);
 	if (ret) {
@@ -3109,6 +3111,8 @@ pk_client_requeue (PkClient *client, GError **error)
 		ret = pk_client_update_packages_strv (client, priv->cached_package_ids, error);
 	} else if (priv->role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
 		ret = pk_client_update_system (client, error);
+	} else if (priv->role == PK_ROLE_ENUM_GET_REPO_LIST) {
+		ret = pk_client_get_repo_list (client, priv->cached_filter, error);
 	} else {
 		pk_client_error_set (error, PK_CLIENT_ERROR_ROLE_UNKNOWN, "role unknown for reque");
 		return FALSE;
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index acd9c7c..bb4874f 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -287,6 +287,7 @@ gboolean	 pk_client_requeue			(PkClient	*client,
 
 /* repo stuff */
 gboolean	 pk_client_get_repo_list		(PkClient	*client,
+							 const gchar	*filter,
 							 GError		**error);
 gboolean	 pk_client_repo_enable			(PkClient	*client,
 							 const gchar	*repo_id,
diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index 933231e..debc19a 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -433,7 +433,7 @@ class PackageKitBaseBackend:
         '''
         self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
 
-    def get_repo_list(self):
+    def get_repo_list(self, filters):
         '''
         Implement the {backend}-get-repo-list functionality
         Needed to be implemented in a sub class
diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py
index c9dedc6..a8c12f7 100644
--- a/python/packagekit/daemonBackend.py
+++ b/python/packagekit/daemonBackend.py
@@ -727,14 +727,14 @@ class PackageKitBaseBackend(dbus.service.Object):
 
     @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
                          in_signature='', out_signature='')
-    def GetRepoList(self):
+    def GetRepoList(self, filters):
         '''
         Implement the {backend}-get-repo-list functionality
         '''
         pklog.info("GetRepoList()")
-        self.doGetRepoList()
+        self.doGetRepoList(filters)
 
-    def doGetRepoList(self):
+    def doGetRepoList(self, filters):
         '''
         Should be replaced in the corresponding backend sub class
         '''
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index fa6945e..7bdd53b 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -537,7 +537,7 @@ pk_backend_dbus_get_updates (PkBackendDbus *backend_dbus, const gchar *filter)
  * pk_backend_dbus_get_repo_list:
  **/
 gboolean
-pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus)
+pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus, const gchar *filter)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -548,6 +548,7 @@ pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus)
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetRepoList", &error,
+				 G_TYPE_STRING, filter,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	if (error != NULL) {
 		pk_warning ("%s", error->message);
diff --git a/src/pk-backend-dbus.h b/src/pk-backend-dbus.h
index bf98cb8..bc3d919 100644
--- a/src/pk-backend-dbus.h
+++ b/src/pk-backend-dbus.h
@@ -123,7 +123,8 @@ gboolean	 pk_backend_dbus_repo_set_data		(PkBackendDbus	*backend_dbus,
 							 const gchar	*rid,
 							 const gchar	*parameter,
 							 const gchar	*value);
-gboolean	 pk_backend_dbus_get_repo_list		(PkBackendDbus	*backend_dbus);
+gboolean	 pk_backend_dbus_get_repo_list		(PkBackendDbus	*backend_dbus,
+							 const gchar	*filter);
 gboolean	 pk_backend_dbus_cancel			(PkBackendDbus	*backend_dbus);
 gboolean	 pk_backend_dbus_get_updates		(PkBackendDbus	*backend_dbus,
 							 const gchar	*filter);
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 506e974..6ba2804 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -151,7 +151,7 @@ typedef struct {
 	void		(*search_name)		(PkBackend *backend, const gchar *filter, const gchar *search);
 	void		(*update_packages)	(PkBackend *backend, gchar **package_ids);
 	void		(*update_system)	(PkBackend *backend);
-	void		(*get_repo_list)	(PkBackend *backend);
+	void		(*get_repo_list)	(PkBackend *backend, const gchar *filter);
 	void		(*repo_enable)		(PkBackend *backend, const gchar *repo_id, gboolean enabled);
 	void		(*repo_set_data)	(PkBackend *backend, const gchar *repo_id, const gchar *parameter, const gchar *value);
 	void		(*service_pack)		(PkBackend *backend, const gchar *location, gboolean enabled);
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 5600498..36ec593 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -2299,7 +2299,7 @@ pk_engine_update_packages (PkEngine *engine, const gchar *tid, gchar **package_i
  * pk_engine_get_repo_list:
  **/
 void
-pk_engine_get_repo_list (PkEngine *engine, const gchar *tid, DBusGMethodInvocation *context)
+pk_engine_get_repo_list (PkEngine *engine, const gchar *tid, const gchar *filter, DBusGMethodInvocation *context)
 {
 	gboolean ret;
 	GError *error;
@@ -2319,13 +2319,20 @@ pk_engine_get_repo_list (PkEngine *engine, const gchar *tid, DBusGMethodInvocati
 		return;
 	}
 
+	/* check the filter */
+	ret = pk_engine_filter_check (filter, &error);
+	if (!ret) {
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
 	/* create a new runner object */
 	item->runner = pk_engine_runner_new (engine);
 
 	/* set the dbus name, so we can get the disconnect */
 	pk_runner_set_dbus_name (item->runner, dbus_g_method_get_sender (context));
 
-	ret = pk_runner_get_repo_list (item->runner);
+	ret = pk_runner_get_repo_list (item->runner, filter);
 	if (!ret) {
 		error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_NOT_SUPPORTED,
 				     "Operation not yet supported by backend");
diff --git a/src/pk-engine.h b/src/pk-engine.h
index 410aea1..f9ec5cd 100644
--- a/src/pk-engine.h
+++ b/src/pk-engine.h
@@ -232,6 +232,7 @@ gboolean	 pk_engine_get_allow_cancel		(PkEngine	*engine,
 /* repo stuff */
 void		 pk_engine_get_repo_list		(PkEngine	*engine,
 							 const gchar	*tid,
+							 const gchar	*filter,
 							 DBusGMethodInvocation *context);
 void		 pk_engine_repo_enable			(PkEngine	*engine,
 							 const gchar	*tid,
diff --git a/src/pk-interface.xml b/src/pk-interface.xml
index f375696..84c1a5a 100644
--- a/src/pk-interface.xml
+++ b/src/pk-interface.xml
@@ -207,6 +207,7 @@
     <method name="GetRepoList">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg type="s" name="tid" direction="in"/>
+      <arg type="s" name="filter" direction="in"/>
     </method>
     <method name="RepoEnable">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
diff --git a/src/pk-runner.c b/src/pk-runner.c
index 842a6e8..277513b 100644
--- a/src/pk-runner.c
+++ b/src/pk-runner.c
@@ -306,7 +306,7 @@ pk_runner_set_running (PkRunner *runner)
 	} else if (priv->role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
 		desc->update_system (priv->backend);
 	} else if (priv->role == PK_ROLE_ENUM_GET_REPO_LIST) {
-		desc->get_repo_list (priv->backend);
+		desc->get_repo_list (priv->backend, priv->cached_filter);
 	} else if (priv->role == PK_ROLE_ENUM_REPO_ENABLE) {
 		desc->repo_enable (priv->backend, priv->cached_repo_id, priv->cached_enabled);
 	} else if (priv->role == PK_ROLE_ENUM_REPO_SET_DATA) {
@@ -692,13 +692,14 @@ pk_runner_update_system (PkRunner *runner)
  * pk_runner_get_repo_list:
  */
 gboolean
-pk_runner_get_repo_list (PkRunner *runner)
+pk_runner_get_repo_list (PkRunner *runner, const gchar *filter)
 {
 	g_return_val_if_fail (runner != NULL, FALSE);
 	if (runner->priv->backend->desc->get_repo_list == NULL) {
 		pk_debug ("Not implemented yet: GetRepoList");
 		return FALSE;
 	}
+	runner->priv->cached_filter = g_strdup (filter);
 	runner->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_runner_set_role (runner, PK_ROLE_ENUM_GET_REPO_LIST);
 	return TRUE;
@@ -708,7 +709,7 @@ pk_runner_get_repo_list (PkRunner *runner)
  * pk_runner_repo_enable:
  */
 gboolean
-pk_runner_repo_enable (PkRunner *runner, const gchar	*repo_id, gboolean enabled)
+pk_runner_repo_enable (PkRunner *runner, const gchar *repo_id, gboolean enabled)
 {
 	g_return_val_if_fail (runner != NULL, FALSE);
 	if (runner->priv->backend->desc->repo_enable == NULL) {
diff --git a/src/pk-runner.h b/src/pk-runner.h
index c8034cc..3e806c7 100644
--- a/src/pk-runner.h
+++ b/src/pk-runner.h
@@ -109,7 +109,8 @@ gboolean	 pk_runner_search_name			(PkRunner	*runner,
 gboolean	 pk_runner_update_packages		(PkRunner	*runner,
 							 gchar		**package_ids);
 gboolean	 pk_runner_update_system		(PkRunner	*runner);
-gboolean	 pk_runner_get_repo_list		(PkRunner	*runner);
+gboolean	 pk_runner_get_repo_list		(PkRunner	*runner,
+							 const gchar	*filter);
 gboolean	 pk_runner_repo_enable			(PkRunner	*runner,
 							 const gchar	*repo_id,
 							 gboolean	 enabled);



More information about the PackageKit mailing list