[Packagekit-commit] packagekit: Branch 'master' - 11 commits

Richard Hughes hughsient at kemper.freedesktop.org
Tue Apr 8 17:12:56 PDT 2008


 docs/html/img/pk-update-bugfix.png      |binary
 docs/html/img/pk-update-enhancement.png |binary
 docs/html/img/pk-update-high.png        |binary
 docs/html/img/pk-update-low.png         |binary
 docs/html/img/pk-update-normal.png      |binary
 docs/html/img/pk-update-security.png    |binary
 docs/html/pk-faq.html                   |   21 ++
 docs/html/update-icons.sh               |    2 
 libpackagekit/pk-client.c               |  288 ++++++++++++++++++--------------
 libpackagekit/pk-client.h               |    3 
 libpackagekit/pk-polkit-client.c        |    2 
 libpackagekit/pk-self-test.c            |    2 
 libpackagekit/pk-task-list.c            |  180 +++++++++++++++++++-
 libpackagekit/pk-task-list.h            |   12 +
 src/pk-marshal.list                     |    2 
 src/pk-transaction-list.c               |  115 ++++--------
 src/pk-transaction.c                    |   51 +----
 17 files changed, 435 insertions(+), 243 deletions(-)

New commits:
commit 0bda925c7100fdb38ea21529f29365f5b0510885
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Apr 9 01:07:03 2008 +0100

    now we are listening to PkTransaction::finished, we don't need to manually remove ourselves from the transaction list

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 32b3e44..ac5e83b 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1574,7 +1574,6 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 		pk_debug ("emitting finished '%s'", exit_text);
 		g_signal_emit (transaction, signals [PK_TRANSACTION_FINISHED], 0, exit_text, 0);
 
-		pk_transaction_list_remove (transaction->priv->transaction_list, transaction);
 		dbus_g_method_return (context);
 		return;
 	}
commit 564b58fa0e2bb04c58da3058f7145456b8774af4
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Apr 9 01:06:12 2008 +0100

    don't check pk_transaction_tid_valid anymore, we can just check for finished

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 34677de..32b3e44 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -375,33 +375,6 @@ pk_transaction_get_text (PkTransaction *transaction)
 }
 
 /**
- * pk_transaction_tid_valid:
- **/
-static gboolean
-pk_transaction_tid_valid (PkTransaction *transaction)
-{
-	const gchar *c_tid;
-
-	g_return_val_if_fail (PK_IS_TRANSACTION (transaction), FALSE);
-	g_return_val_if_fail (transaction->priv->tid != NULL, FALSE);
-
-	/* have we already been marked as finished? */
-	if (transaction->priv->finished) {
-		pk_debug ("Already finished, so it can't be us");
-		return FALSE;
-	}
-
-	/* get currently running */
-	c_tid = pk_backend_get_current_tid (transaction->priv->backend);
-	if (c_tid == NULL) {
-		pk_warning ("could not get current tid");
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/**
  * pk_transaction_finish_invalidate_caches:
  **/
 static gboolean
@@ -538,7 +511,6 @@ pk_transaction_files_cb (PkBackend *backend, const gchar *package_id,
 static void
 pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit, PkTransaction *transaction)
 {
-	gboolean valid;
 	const gchar *exit_text;
 	guint time;
 	gchar *packages;
@@ -546,9 +518,9 @@ pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit, PkTransaction *
 	g_return_if_fail (PK_IS_TRANSACTION (transaction));
 	g_return_if_fail (transaction->priv->tid != NULL);
 
-	/* are we still talking about the same backend instance */
-	valid = pk_transaction_tid_valid (transaction);
-	if (valid == FALSE) {
+	/* have we already been marked as finished? */
+	if (transaction->priv->finished) {
+		pk_warning ("Already finished");
 		return;
 	}
 
@@ -639,14 +611,13 @@ pk_transaction_package_cb (PkBackend *backend, PkInfoEnum info, const gchar *pac
 			   const gchar *summary, PkTransaction *transaction)
 {
 	const gchar *info_text;
-	gboolean valid;
 
 	g_return_if_fail (PK_IS_TRANSACTION (transaction));
 	g_return_if_fail (transaction->priv->tid != NULL);
 
-	/* are we still talking about the same backend instance */
-	valid = pk_transaction_tid_valid (transaction);
-	if (valid == FALSE) {
+	/* have we already been marked as finished? */
+	if (transaction->priv->finished) {
+		pk_warning ("Already finished");
 		return;
 	}
 
@@ -752,15 +723,14 @@ pk_transaction_require_restart_cb (PkBackend *backend, PkRestartEnum restart, co
 static void
 pk_transaction_status_changed_cb (PkBackend *backend, PkStatusEnum status, PkTransaction *transaction)
 {
-	gboolean valid;
 	const gchar *status_text;
 
 	g_return_if_fail (PK_IS_TRANSACTION (transaction));
 	g_return_if_fail (transaction->priv->tid != NULL);
 
-	/* are we still talking about the same backend instance */
-	valid = pk_transaction_tid_valid (transaction);
-	if (valid == FALSE) {
+	/* have we already been marked as finished? */
+	if (transaction->priv->finished) {
+		pk_warning ("Already finished");
 		return;
 	}
 
commit 83d112db1f50d4357fb1946696efdf603159e48d
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Apr 9 00:38:26 2008 +0100

    fit PkTaskList to multiplex cetrain signals for us, and add some unit tests also

diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c
index e1227f6..b964f63 100644
--- a/libpackagekit/pk-self-test.c
+++ b/libpackagekit/pk-self-test.c
@@ -38,6 +38,7 @@ void libst_extra (LibSelfTest *test);
 void libst_extra_obj (LibSelfTest *test);
 void libst_client (LibSelfTest *test);
 void libst_control (LibSelfTest *test);
+void libst_task_list (LibSelfTest *test);
 
 int
 main (int argc, char **argv)
@@ -60,6 +61,7 @@ main (int argc, char **argv)
 	libst_extra_obj (&test);
 	libst_client (&test);
 	libst_control (&test);
+	libst_task_list (&test);
 
 	return (libst_finish (&test));
 }
diff --git a/libpackagekit/pk-task-list.c b/libpackagekit/pk-task-list.c
index ecfa53e..a81b692 100644
--- a/libpackagekit/pk-task-list.c
+++ b/libpackagekit/pk-task-list.c
@@ -67,6 +67,9 @@ struct _PkTaskListPrivate
 
 typedef enum {
 	PK_TASK_LIST_CHANGED,
+	PK_TASK_LIST_MESSAGE,
+	PK_TASK_LIST_FINISHED,
+	PK_TASK_LIST_ERROR_CODE,
 	PK_TASK_LIST_LAST_SIGNAL
 } PkSignals;
 
@@ -144,10 +147,10 @@ pk_task_list_find_existing_tid (PkTaskList *tlist, const gchar *tid)
 }
 
 /**
- * pk_task_list_job_status_changed_cb:
+ * pk_task_list_status_changed_cb:
  **/
 static void
-pk_task_list_job_status_changed_cb (PkClient *client, PkStatusEnum status, PkTaskList *tlist)
+pk_task_list_status_changed_cb (PkClient *client, PkStatusEnum status, PkTaskList *tlist)
 {
 	gchar *tid;
 	PkTaskListItem *item;
@@ -163,7 +166,40 @@ pk_task_list_job_status_changed_cb (PkClient *client, PkStatusEnum status, PkTas
 	g_free (tid);
 
 	pk_debug ("emit task-list-changed");
-	g_signal_emit (tlist , signals [PK_TASK_LIST_CHANGED], 0);
+	g_signal_emit (tlist, signals [PK_TASK_LIST_CHANGED], 0);
+}
+
+/**
+ * gpk_task_list_finished_cb:
+ **/
+static void
+gpk_task_list_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, PkTaskList *tlist)
+{
+	g_return_if_fail (PK_IS_TASK_LIST (tlist));
+	pk_debug ("emit finished");
+	g_signal_emit (tlist, signals [PK_TASK_LIST_FINISHED], 0, client, exit, runtime);
+}
+
+/**
+ * gpk_task_list_error_code_cb:
+ **/
+static void
+gpk_task_list_error_code_cb (PkClient *client, PkErrorCodeEnum error_code, const gchar *details, PkTaskList *tlist)
+{
+	g_return_if_fail (PK_IS_TASK_LIST (tlist));
+	pk_debug ("emit error-code");
+	g_signal_emit (tlist, signals [PK_TASK_LIST_ERROR_CODE], 0, client, error_code, details);
+}
+
+/**
+ * gpk_task_list_message_cb:
+ **/
+static void
+gpk_task_list_message_cb (PkClient *client, PkMessageEnum message, const gchar *details, PkTaskList *tlist)
+{
+	g_return_if_fail (PK_IS_TASK_LIST (tlist));
+	pk_debug ("emit message");
+	g_signal_emit (tlist, signals [PK_TASK_LIST_MESSAGE], 0, client, message, details);
 }
 
 /**
@@ -179,6 +215,8 @@ pk_task_list_refresh (PkTaskList *tlist)
 	guint length;
 	const gchar *tid;
 	const gchar **array;
+	GError *error = NULL;
+	gboolean ret;
 
 	g_return_val_if_fail (PK_IS_TASK_LIST (tlist), FALSE);
 
@@ -204,8 +242,19 @@ pk_task_list_refresh (PkTaskList *tlist)
 			item->tid = g_strdup (tid);
 			item->monitor = pk_client_new ();
 			g_signal_connect (item->monitor, "status-changed",
-					  G_CALLBACK (pk_task_list_job_status_changed_cb), tlist);
-			pk_client_set_tid (item->monitor, tid, NULL);
+					  G_CALLBACK (pk_task_list_status_changed_cb), tlist);
+			g_signal_connect (item->monitor, "finished",
+					  G_CALLBACK (gpk_task_list_finished_cb), tlist);
+			g_signal_connect (item->monitor, "error-code",
+					  G_CALLBACK (gpk_task_list_error_code_cb), tlist);
+			g_signal_connect (item->monitor, "message",
+					  G_CALLBACK (gpk_task_list_message_cb), tlist);
+			ret = pk_client_set_tid (item->monitor, tid, &error);
+			if (!ret) {
+				pk_error ("could not set tid: %s", error->message);
+				g_error_free (error);
+				break;
+			}
 			pk_client_get_role (item->monitor, &item->role, &item->package_id, NULL);
 			pk_client_get_status (item->monitor, &item->status, NULL);
 
@@ -220,7 +269,7 @@ pk_task_list_refresh (PkTaskList *tlist)
 	/* find and remove non-valid watches */
 	for (i=0; i<tlist->priv->task_list->len; i++) {
 		item = g_ptr_array_index (tlist->priv->task_list, i);
-		if (item->valid == FALSE) {
+		if (!item->valid) {
 			pk_debug ("remove %s", item->tid);
 			g_object_unref (item->monitor);
 			g_ptr_array_remove (tlist->priv->task_list, item);
@@ -261,7 +310,7 @@ pk_task_list_get_item (PkTaskList *tlist, guint item)
  * pk_task_list_transaction_list_changed_cb:
  **/
 static void
-pk_task_list_transaction_list_changed_cb (PkControl *jlist, PkTaskList *tlist)
+pk_task_list_transaction_list_changed_cb (PkControl *control, PkTaskList *tlist)
 {
 	/* for now, just refresh all the jobs. a little inefficient me thinks */
 	pk_task_list_refresh (tlist);
@@ -279,11 +328,62 @@ pk_task_list_class_init (PkTaskListClass *klass)
 
 	object_class->finalize = pk_task_list_finalize;
 
+	/**
+	 * PkTaskList::task-list-changed:
+	 *
+	 * The ::task-list-changed signal is emitted when the transaction list has changed
+	 **/
 	signals [PK_TASK_LIST_CHANGED] =
 		g_signal_new ("task-list-changed",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
+	/**
+	 * PkTaskList::message:
+	 * @client: the #PkTaskList instance that emitted the signal
+	 * @message: the PkMessageEnum type of the message, e.g. PK_MESSAGE_ENUM_WARNING
+	 * @details: the non-localised message details
+	 *
+	 * The ::message signal is emitted when the transaction wants to tell
+	 * the user something.
+	 **/
+	signals [PK_TASK_LIST_MESSAGE] =
+		g_signal_new ("message",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkTaskListClass, message),
+			      NULL, NULL, pk_marshal_VOID__POINTER_UINT_STRING,
+			      G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING);
+	/**
+	 * PkTaskList::finished:
+	 * @client: the #PkTaskList instance that emitted the signal
+	 * @exit: the #PkExitEnum status value, e.g. PK_EXIT_ENUM_SUCCESS
+	 * @runtime: the time in seconds the transaction has been running
+	 *
+	 * The ::finished signal is emitted when the transaction is complete.
+	 **/
+	signals [PK_TASK_LIST_FINISHED] =
+		g_signal_new ("finished",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkTaskListClass, finished),
+			      NULL, NULL, pk_marshal_VOID__POINTER_UINT_UINT,
+			      G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);
+	/**
+	 * PkClient::error-code:
+	 * @client: the #PkClient instance that emitted the signal
+	 * @code: the #PkErrorCodeEnum of the error, e.g. PK_ERROR_ENUM_DEP_RESOLUTION_FAILED
+	 * @details: the non-locaised details about the error
+	 *
+	 * The ::error-code signal is emitted when the transaction wants to
+	 * convey an error in the transaction.
+	 *
+	 * This can only happen once in a transaction.
+	 **/
+	signals [PK_TASK_LIST_ERROR_CODE] =
+		g_signal_new ("error-code",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (PkTaskListClass, error_code),
+			      NULL, NULL, pk_marshal_VOID__POINTER_UINT_STRING,
+			      G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING);
 
 	g_type_class_add_private (klass, sizeof (PkTaskListPrivate));
 }
@@ -350,3 +450,69 @@ pk_task_list_new (void)
 	return PK_TASK_LIST (tlist);
 }
 
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+static gboolean finished = FALSE;
+
+static void
+libst_task_list_finished_cb (PkTaskList *tlist, PkClient *client, PkExitEnum exit, guint runtime, LibSelfTest *test)
+{
+	g_return_if_fail (PK_IS_CLIENT (client));
+	g_return_if_fail (PK_IS_TASK_LIST (tlist));
+	finished = TRUE;
+	libst_loopquit (test);
+}
+
+void
+libst_task_list (LibSelfTest *test)
+{
+	PkTaskList *tlist;
+	PkClient *client;
+	gboolean ret;
+	GError *error = NULL;
+
+	if (libst_start (test, "PkTaskList", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "get client");
+	tlist = pk_task_list_new ();
+	if (tlist != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+	g_signal_connect (tlist, "finished",
+			  G_CALLBACK (libst_task_list_finished_cb), test);
+
+	/************************************************************/
+	libst_title (test, "search for power");
+	client = pk_client_new ();
+	ret = pk_client_search_name (client, "none", "power", &error);
+	if (!ret) {
+		libst_failed (test, "failed: %s", error->message);
+		g_error_free (error);
+	}
+	libst_loopwait (test, 5000);
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "we finished?");
+	if (finished) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "not finished");
+	}
+
+	g_object_unref (tlist);
+	g_object_unref (client);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-task-list.h b/libpackagekit/pk-task-list.h
index a049802..8746bb5 100644
--- a/libpackagekit/pk-task-list.h
+++ b/libpackagekit/pk-task-list.h
@@ -58,6 +58,18 @@ struct _PkTaskList
 struct _PkTaskListClass
 {
 	GObjectClass	parent_class;
+	void		(* message)			(PkTaskList	*tlist,
+							 PkClient	*client,
+							 PkMessageEnum	 message,
+							 const gchar	*details);
+	void		(* finished)			(PkTaskList	*tlist,
+							 PkClient	*client,
+							 PkExitEnum	 exit,
+							 guint		 runtime);
+	void		(* error_code)			(PkTaskList	*tlist,
+							 PkClient	*client,
+							 PkErrorCodeEnum code,
+							 const gchar	*details);
 };
 
 GType		 pk_task_list_get_type			(void) G_GNUC_CONST;
diff --git a/src/pk-marshal.list b/src/pk-marshal.list
index 5532e9c..ace2354 100644
--- a/src/pk-marshal.list
+++ b/src/pk-marshal.list
@@ -31,4 +31,6 @@ VOID:STRING,STRING,UINT,UINT,UINT
 VOID:STRING,STRING,BOOL,UINT,UINT,STRING
 VOID:STRING,STRING,STRING,BOOL,STRING,UINT,STRING
 VOID:STRING,STRING,BOOL,STRING,UINT,STRING
+VOID:POINTER,UINT,STRING
+VOID:POINTER,UINT,UINT
 
commit 207b2664f9e467c7c16fd8a231cbef25e349c3c3
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Apr 9 00:34:11 2008 +0100

    only fire the ::transaction-list-changed signal _after_ the other ::finished handlers have run

diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c
index 598a850..e7db7b6 100644
--- a/src/pk-transaction-list.c
+++ b/src/pk-transaction-list.c
@@ -274,8 +274,8 @@ pk_transaction_list_create (PkTransactionList *tlist, const gchar *tid)
 	}
 
 	item->transaction = pk_transaction_new ();
-	g_signal_connect (item->transaction, "finished",
-			  G_CALLBACK (pk_transaction_list_transaction_finished_cb), tlist);
+	g_signal_connect_after (item->transaction, "finished",
+				G_CALLBACK (pk_transaction_list_transaction_finished_cb), tlist);
 	pk_transaction_set_tid (item->transaction, item->tid);
 	dbus_g_object_type_install_info (PK_TYPE_TRANSACTION, &dbus_glib_pk_transaction_object_info);
 	dbus_g_connection_register_g_object (connection, item->tid, G_OBJECT (item->transaction));
commit 258a1118818d9044a8680419c7d3375c4e133deb
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed Apr 9 00:08:49 2008 +0100

    connect to Pktransaction::finished rather than PkBackend::finished, as we should allow
    the transaction::finished signal to propogate before we do ::transaction-list-changed

diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c
index c387a1c..598a850 100644
--- a/src/pk-transaction-list.c
+++ b/src/pk-transaction-list.c
@@ -102,30 +102,6 @@ pk_transaction_list_get_from_transaction (PkTransactionList *tlist, PkTransactio
 }
 
 /**
- * pk_transaction_list_get_from_tid:
- **/
-static PkTransactionItem *
-pk_transaction_list_get_from_tid (PkTransactionList *tlist, const gchar *tid)
-{
-	guint i;
-	guint length;
-	PkTransactionItem *item;
-
-	g_return_val_if_fail (tlist != NULL, NULL);
-	g_return_val_if_fail (PK_IS_TRANSACTION_LIST (tlist), NULL);
-
-	/* find the runner with the transaction ID */
-	length = tlist->priv->array->len;
-	for (i=0; i<length; i++) {
-		item = (PkTransactionItem *) g_ptr_array_index (tlist->priv->array, i);
-		if (pk_transaction_id_equal (item->tid, tid)) {
-			return item;
-		}
-	}
-	return NULL;
-}
-
-/**
  * pk_transaction_list_role_present:
  *
  * if there is a queued transaction with this role, useful to avoid having
@@ -162,42 +138,6 @@ pk_transaction_list_role_present (PkTransactionList *tlist, PkRoleEnum role)
 }
 
 /**
- * pk_transaction_list_create:
- **/
-gboolean
-pk_transaction_list_create (PkTransactionList *tlist, const gchar *tid)
-{
-	PkTransactionItem *item;
-	DBusGConnection *connection;
-
-	g_return_val_if_fail (PK_IS_TRANSACTION_LIST (tlist), FALSE);
-	g_return_val_if_fail (tid != NULL, FALSE);
-
-	/* add to the array */
-	item = g_new0 (PkTransactionItem, 1);
-	item->committed = FALSE;
-	item->running = FALSE;
-	item->finished = FALSE;
-	item->transaction = NULL;
-	item->tid = g_strdup (tid);
-
-	/* get another connection */
-	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
-	if (connection == NULL) {
-		pk_error ("no connection");
-	}
-
-	item->transaction = pk_transaction_new ();
-	pk_transaction_set_tid (item->transaction, item->tid);
-	dbus_g_object_type_install_info (PK_TYPE_TRANSACTION, &dbus_glib_pk_transaction_object_info);
-	dbus_g_connection_register_g_object (connection, item->tid, G_OBJECT (item->transaction));
-
-	pk_debug ("adding transaction %p, item %p", item->transaction, item);
-	g_ptr_array_add (tlist->priv->array, item);
-	return TRUE;
-}
-
-/**
  * pk_transaction_list_remove:
  **/
 gboolean
@@ -249,29 +189,22 @@ pk_transaction_list_remove_item_timeout (gpointer data)
 }
 
 /**
- * pk_transaction_list_backend_finished_cb:
+ * pk_transaction_list_transaction_finished_cb:
  **/
 static void
-pk_transaction_list_backend_finished_cb (PkBackend *backend, PkExitEnum exit, PkTransactionList *tlist)
+pk_transaction_list_transaction_finished_cb (PkTransaction *transaction, const gchar *exit_text, guint time, PkTransactionList *tlist)
 {
 	guint i;
 	guint length;
 	gboolean ret;
 	PkTransactionItem *item;
 	PkTransactionFinished *finished;
-	const gchar *c_tid;
 
 	g_return_if_fail (PK_IS_TRANSACTION_LIST (tlist));
 
-	c_tid = pk_backend_get_current_tid (backend);
-	if (c_tid == NULL) {
-		pk_warning ("could not get current tid");
-		return;
-	}
-
-	item = pk_transaction_list_get_from_tid (tlist, c_tid);
+	item = pk_transaction_list_get_from_transaction (tlist, transaction);
 	if (item == NULL) {
-		pk_error ("no transaction list found!");
+		pk_error ("no transaction list item found!");
 	}
 
 	/* transaction is already finished? */
@@ -315,6 +248,44 @@ pk_transaction_list_backend_finished_cb (PkBackend *backend, PkExitEnum exit, Pk
 }
 
 /**
+ * pk_transaction_list_create:
+ **/
+gboolean
+pk_transaction_list_create (PkTransactionList *tlist, const gchar *tid)
+{
+	PkTransactionItem *item;
+	DBusGConnection *connection;
+
+	g_return_val_if_fail (PK_IS_TRANSACTION_LIST (tlist), FALSE);
+	g_return_val_if_fail (tid != NULL, FALSE);
+
+	/* add to the array */
+	item = g_new0 (PkTransactionItem, 1);
+	item->committed = FALSE;
+	item->running = FALSE;
+	item->finished = FALSE;
+	item->transaction = NULL;
+	item->tid = g_strdup (tid);
+
+	/* get another connection */
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+	if (connection == NULL) {
+		pk_error ("no connection");
+	}
+
+	item->transaction = pk_transaction_new ();
+	g_signal_connect (item->transaction, "finished",
+			  G_CALLBACK (pk_transaction_list_transaction_finished_cb), tlist);
+	pk_transaction_set_tid (item->transaction, item->tid);
+	dbus_g_object_type_install_info (PK_TYPE_TRANSACTION, &dbus_glib_pk_transaction_object_info);
+	dbus_g_connection_register_g_object (connection, item->tid, G_OBJECT (item->transaction));
+
+	pk_debug ("adding transaction %p, item %p", item->transaction, item);
+	g_ptr_array_add (tlist->priv->array, item);
+	return TRUE;
+}
+
+/**
  * pk_transaction_list_number_running:
  **/
 static guint
@@ -451,8 +422,6 @@ pk_transaction_list_init (PkTransactionList *tlist)
 	tlist->priv = PK_TRANSACTION_LIST_GET_PRIVATE (tlist);
 	tlist->priv->array = g_ptr_array_new ();
 	tlist->priv->backend = pk_backend_new ();
-	g_signal_connect (tlist->priv->backend, "finished",
-			  G_CALLBACK (pk_transaction_list_backend_finished_cb), tlist);
 }
 
 /**
commit a56f3d08e2021744113098edc68bb114888dc9c0
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 23:30:22 2008 +0100

    add a self test for a copy client (where we set the tid and fix up all the fallout

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 5827bf9..8466274 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -400,76 +400,13 @@ pk_client_package_buffer_get_item (PkClient *client, guint item)
 }
 
 /**
- * pk_client_reset:
- * @client: a valid #PkClient instance
- * @error: a %GError to put the error code and message in, or %NULL
- *
- * Resetting the client way be needed if we canceled the request without
- * waiting for ::finished, or if we want to reuse the #PkClient without
- * unreffing and creating it again.
- *
- * If you call pk_client_reset() on a running transaction, then it will be
- * automatically cancelled. If the cancel fails, the reset will fail.
- *
- * Return value: %TRUE if we reset the client
- **/
-gboolean
-pk_client_reset (PkClient *client, GError **error)
-{
-	gboolean ret;
-
-	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
-
-	if (client->priv->is_finished != TRUE) {
-		pk_debug ("not exit status, will try to cancel");
-		/* we try to cancel the running tranaction */
-		ret = pk_client_cancel (client, error);
-		if (!ret) {
-			return FALSE;
-		}
-	}
-
-	g_free (client->priv->tid);
-	g_free (client->priv->cached_package_id);
-	g_free (client->priv->cached_key_id);
-	g_free (client->priv->cached_transaction_id);
-	g_free (client->priv->cached_full_path);
-	g_free (client->priv->cached_filter);
-	g_free (client->priv->cached_search);
-	g_strfreev (client->priv->cached_package_ids);
-
-	client->priv->tid = NULL;
-	client->priv->cached_package_id = NULL;
-	client->priv->cached_key_id = NULL;
-	client->priv->cached_transaction_id = NULL;
-	client->priv->cached_full_path = NULL;
-	client->priv->cached_filter = NULL;
-	client->priv->cached_search = NULL;
-	client->priv->cached_package_ids = NULL;
-	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
-	client->priv->role = PK_ROLE_ENUM_UNKNOWN;
-	client->priv->is_finished = FALSE;
-
-	pk_package_list_clear (client->priv->package_list);
-	return TRUE;
-}
-
-/******************************************************************************
- *                    SIGNALS
- ******************************************************************************/
-
-/**
  * pk_client_finished_cb:
  */
 static void
-pk_client_finished_cb (DBusGProxy  *proxy,
-		       const gchar *exit_text,
-		       guint        runtime,
-		       PkClient    *client)
+pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime, PkClient *client)
 {
 	PkExitEnum exit;
 
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	exit = pk_exit_enum_from_text (exit_text);
@@ -496,11 +433,9 @@ pk_client_finished_cb (DBusGProxy  *proxy,
  * pk_client_progress_changed_cb:
  */
 static void
-pk_client_progress_changed_cb (DBusGProxy  *proxy,
-			       guint percentage, guint subpercentage,
+pk_client_progress_changed_cb (DBusGProxy *proxy, guint percentage, guint subpercentage,
 			       guint elapsed, guint remaining, PkClient *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit progress-changed %i, %i, %i, %i", percentage, subpercentage, elapsed, remaining);
@@ -527,7 +462,6 @@ pk_client_status_changed_cb (DBusGProxy *proxy, const gchar *status_text, PkClie
 {
 	PkStatusEnum status;
 
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	status = pk_status_enum_from_text (status_text);
@@ -546,7 +480,6 @@ pk_client_package_cb (DBusGProxy   *proxy,
 {
 	PkInfoEnum info;
 
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit package %s, %s, %s", info_text, package_id, summary);
@@ -569,7 +502,6 @@ pk_client_transaction_cb (DBusGProxy *proxy, const gchar *old_tid, const gchar *
 			  const gchar *data, PkClient *client)
 {
 	PkRoleEnum role;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	role = pk_role_enum_from_text (role_text);
@@ -595,7 +527,6 @@ pk_client_update_detail_cb (DBusGProxy  *proxy,
 			    PkClient    *client)
 {
 	PkRestartEnum restart;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit update-detail %s, %s, %s, %s, %s, %s, %s, %s",
@@ -619,7 +550,6 @@ pk_client_description_cb (DBusGProxy  *proxy,
 			  PkClient    *client)
 {
 	PkGroupEnum group;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	group = pk_group_enum_from_text (group_text);
@@ -638,7 +568,6 @@ pk_client_files_cb (DBusGProxy  *proxy,
 		    const gchar *filelist,
 		    PkClient    *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit files %s, %s", package_id, filelist);
@@ -655,7 +584,6 @@ pk_client_repo_signature_required_cb (DBusGProxy *proxy, const gchar *package_id
 				      const gchar *key_fingerprint, const gchar *key_timestamp,
 				      const gchar *type_text, PkClient *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit repo_signature_required %s, %s, %s, %s, %s, %s, %s, %s",
@@ -673,7 +601,6 @@ static void
 pk_client_repo_detail_cb (DBusGProxy *proxy, const gchar *repo_id,
 			  const gchar *description, gboolean enabled, PkClient *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit repo-detail %s, %s, %i", repo_id, description, enabled);
@@ -690,7 +617,6 @@ pk_client_error_code_cb (DBusGProxy  *proxy,
 			 PkClient    *client)
 {
 	PkErrorCodeEnum code;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	code = pk_error_enum_from_text (code_text);
@@ -704,7 +630,6 @@ pk_client_error_code_cb (DBusGProxy  *proxy,
 static void
 pk_client_allow_cancel_cb (DBusGProxy *proxy, gboolean allow_cancel, PkClient *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit allow-cancel %i", allow_cancel);
@@ -752,7 +677,6 @@ pk_client_caller_active_changed_cb (DBusGProxy  *proxy,
 				    gboolean     is_active,
 				    PkClient    *client)
 {
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit caller-active-changed %i", is_active);
@@ -769,7 +693,6 @@ pk_client_require_restart_cb (DBusGProxy  *proxy,
 			      PkClient    *client)
 {
 	PkRestartEnum restart;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	restart = pk_restart_enum_from_text (restart_text);
@@ -788,7 +711,6 @@ static void
 pk_client_message_cb (DBusGProxy  *proxy, const gchar *message_text, const gchar *details, PkClient *client)
 {
 	PkMessageEnum message;
-	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	message = pk_message_enum_from_text (message_text);
@@ -796,10 +718,6 @@ pk_client_message_cb (DBusGProxy  *proxy, const gchar *message_text, const gchar
 	g_signal_emit (client , signals [PK_CLIENT_MESSAGE], 0, message, details);
 }
 
-/******************************************************************************
- *                    TRANSACTION ID USING METHODS
- ******************************************************************************/
-
 /**
  * pk_client_get_status:
  * @client: a valid #PkClient instance
@@ -3257,6 +3175,104 @@ pk_connection_changed_cb (PkConnection *pconnection, gboolean connected, PkClien
 }
 
 /**
+ * pk_client_disconnect_proxy:
+ **/
+static gboolean
+pk_client_disconnect_proxy (PkClient *client)
+{
+	if (client->priv->proxy == NULL) {
+		return FALSE;
+	}
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Finished",
+				        G_CALLBACK (pk_client_finished_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "ProgressChanged",
+				        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, "Package",
+				        G_CALLBACK (pk_client_package_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Transaction",
+				        G_CALLBACK (pk_client_transaction_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Description",
+				        G_CALLBACK (pk_client_description_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Files",
+				        G_CALLBACK (pk_client_files_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "RepoSignatureRequired",
+				        G_CALLBACK (pk_client_repo_signature_required_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "ErrorCode",
+				        G_CALLBACK (pk_client_error_code_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "RequireRestart",
+				        G_CALLBACK (pk_client_require_restart_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Message",
+				        G_CALLBACK (pk_client_message_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "CallerActiveChanged",
+					G_CALLBACK (pk_client_caller_active_changed_cb), client);
+	dbus_g_proxy_disconnect_signal (client->priv->proxy, "AllowCancel",
+				        G_CALLBACK (pk_client_allow_cancel_cb), client);
+	g_object_unref (G_OBJECT (client->priv->proxy));
+	client->priv->proxy = NULL;
+	return TRUE;
+}
+
+/**
+ * pk_client_reset:
+ * @client: a valid #PkClient instance
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Resetting the client way be needed if we canceled the request without
+ * waiting for ::finished, or if we want to reuse the #PkClient without
+ * unreffing and creating it again.
+ *
+ * If you call pk_client_reset() on a running transaction, then it will be
+ * automatically cancelled. If the cancel fails, the reset will fail.
+ *
+ * Return value: %TRUE if we reset the client
+ **/
+gboolean
+pk_client_reset (PkClient *client, GError **error)
+{
+	gboolean ret;
+
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+
+	if (client->priv->is_finished != TRUE) {
+		pk_debug ("not exit status, will try to cancel");
+		/* we try to cancel the running tranaction */
+		ret = pk_client_cancel (client, error);
+		if (!ret) {
+			return FALSE;
+		}
+	}
+
+	g_free (client->priv->tid);
+	g_free (client->priv->cached_package_id);
+	g_free (client->priv->cached_key_id);
+	g_free (client->priv->cached_transaction_id);
+	g_free (client->priv->cached_full_path);
+	g_free (client->priv->cached_filter);
+	g_free (client->priv->cached_search);
+	g_strfreev (client->priv->cached_package_ids);
+
+	/* we need to do this now we have multiple paths */
+	pk_client_disconnect_proxy (client);
+
+	client->priv->tid = NULL;
+	client->priv->cached_package_id = NULL;
+	client->priv->cached_key_id = NULL;
+	client->priv->cached_transaction_id = NULL;
+	client->priv->cached_full_path = NULL;
+	client->priv->cached_filter = NULL;
+	client->priv->cached_search = NULL;
+	client->priv->cached_package_ids = NULL;
+	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
+	client->priv->role = PK_ROLE_ENUM_UNKNOWN;
+	client->priv->is_finished = FALSE;
+
+	pk_package_list_clear (client->priv->package_list);
+	return TRUE;
+}
+
+/**
  * pk_client_init:
  **/
 static void
@@ -3397,35 +3413,7 @@ pk_client_finalize (GObject *object)
 	g_main_loop_unref (client->priv->loop);
 
 	/* disconnect signal handlers */
-	if (client->priv->proxy != NULL) {
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "Finished",
-					        G_CALLBACK (pk_client_finished_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "ProgressChanged",
-					        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, "Package",
-					        G_CALLBACK (pk_client_package_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "Transaction",
-					        G_CALLBACK (pk_client_transaction_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "Description",
-					        G_CALLBACK (pk_client_description_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "Files",
-					        G_CALLBACK (pk_client_files_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "RepoSignatureRequired",
-					        G_CALLBACK (pk_client_repo_signature_required_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "ErrorCode",
-					        G_CALLBACK (pk_client_error_code_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "RequireRestart",
-					        G_CALLBACK (pk_client_require_restart_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "Message",
-					        G_CALLBACK (pk_client_message_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "CallerActiveChanged",
-						G_CALLBACK (pk_client_caller_active_changed_cb), client);
-		dbus_g_proxy_disconnect_signal (client->priv->proxy, "AllowCancel",
-					        G_CALLBACK (pk_client_allow_cancel_cb), client);
-		g_object_unref (G_OBJECT (client->priv->proxy));
-	}
+	pk_client_disconnect_proxy (client);
 	g_object_unref (client->priv->pconnection);
 	g_object_unref (client->priv->polkit);
 	g_object_unref (client->priv->package_list);
@@ -3458,21 +3446,36 @@ pk_client_new (void)
 #include <glib/gstdio.h>
 
 static gboolean finished = FALSE;
+static guint clone_packages = 0;
 
 static void
-libst_client_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpointer data)
+libst_client_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, LibSelfTest *test)
 {
 	finished = TRUE;
 	/* this is actually quite common */
 	g_object_unref (client);
 }
 
+static void
+libst_client_copy_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, LibSelfTest *test)
+{
+	libst_loopquit (test);
+}
+
+static void
+libst_client_copy_package_cb (PkClient *client, PkInfoEnum info, const gchar *package_id, const gchar *summary, LibSelfTest *test)
+{
+	clone_packages++;
+}
+
 void
 libst_client (LibSelfTest *test)
 {
 	PkClient *client;
+	PkClient *client_copy;
 	gboolean ret;
 	GError *error = NULL;
+	gchar *tid;
 	guint size;
 	guint size_new;
 	guint i;
@@ -3522,7 +3525,7 @@ libst_client (LibSelfTest *test)
 
 	/* check use after finalise */
 	g_signal_connect (client, "finished",
-			  G_CALLBACK (libst_client_finished_cb), NULL);
+			  G_CALLBACK (libst_client_finished_cb), test);
 
 	/* run the method */
 	pk_client_set_synchronous (client, TRUE, NULL);
@@ -3566,7 +3569,7 @@ libst_client (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "do lots of loops");
-	for (i=0;i<10;i++) {
+	for (i=0;i<5;i++) {
 		ret = pk_client_reset (client, &error);
 		if (!ret) {
 			libst_failed (test, "failed: to reset: %s", error->message);
@@ -3583,8 +3586,49 @@ libst_client (LibSelfTest *test)
 			libst_failed (test, "old size %i, new size %", size, size_new);
 		}
 	}
-	libst_success (test, "10 search name loops completed in %ims", libst_elapsed (test));
+	libst_success (test, "%i search name loops completed in %ims", i, libst_elapsed (test));
+	g_object_unref (client);
+
+	/************************************************************/
+	libst_title (test, "try to clone");
+
+	/* set up the source */
+	client = pk_client_new ();
+	g_signal_connect (client, "finished",
+			  G_CALLBACK (libst_client_copy_finished_cb), test);
+	/* set up the copy */
+	client_copy = pk_client_new ();
+	g_signal_connect (client_copy, "package",
+			  G_CALLBACK (libst_client_copy_package_cb), test);
+
+	/* search with the source */
+	ret = pk_client_search_name (client, "none", "power", &error);
+	if (!ret) {
+		libst_failed (test, "failed: %s", error->message);
+		g_error_free (error);
+	}
+
+	/* get the tid */
+	tid = pk_client_get_tid (client);
+	if (tid == NULL) {
+		libst_failed (test, "failed to get tid");
+	}
+
+	/* set the tid on the copy */
+	ret = pk_client_set_tid (client_copy, tid, &error);
+	if (!ret) {
+		libst_failed (test, "failed to set tid: %s", error->message);
+		g_error_free (error);
+	}
+
+	libst_loopwait (test, 5000);
+	if (clone_packages != 4) {
+		libst_failed (test, "failed to get correct number of packages: %i", clone_packages);
+	}
+	libst_success (test, "cloned in %i", libst_elapsed (test));
+
 	g_object_unref (client);
+	g_object_unref (client_copy);
 
 	libst_end (test);
 }
commit 459e1702bb42df4daaab56cedc61b4b3f9b06aa0
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 23:29:12 2008 +0100

    enforce we check pk_client_set_tid

diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index d530932..3de0875 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -160,7 +160,8 @@ PkClient	*pk_client_new				(void);
 
 gboolean	 pk_client_set_tid			(PkClient	*client,
 							 const gchar	*tid,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		*pk_client_get_tid			(PkClient	*client);
 
 gboolean	 pk_client_set_use_buffer		(PkClient	*client,
commit 5f4f8c9dd77d5c89a44ed8378490a74826363b82
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 19:58:05 2008 +0100

    be more useful for debugging when we are setting an error

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 9c7ba29..5827bf9 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -1035,11 +1035,16 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error)
 	/* get and set a new ID */
 	ret = pk_control_allocate_transaction_id (client->priv->control, &tid, error);
 	if (!ret) {
+		pk_warning ("failed to get a TID: %s", (*error)->message);
 		return FALSE;
 	}
 	ret = pk_client_set_tid (client, tid, error);
 	g_free (tid);
-	return ret;
+	if (!ret) {
+		pk_warning ("failed to set TID: %s", (*error)->message);
+		return FALSE;
+	}
+	return TRUE;
 }
 
 /**
diff --git a/libpackagekit/pk-polkit-client.c b/libpackagekit/pk-polkit-client.c
index 8827c30..dceb656 100644
--- a/libpackagekit/pk-polkit-client.c
+++ b/libpackagekit/pk-polkit-client.c
@@ -168,7 +168,7 @@ pk_polkit_client_error_denied_by_policy (GError *error)
 
 	/* not a dbus error */
 	if (error->code != DBUS_GERROR_REMOTE_EXCEPTION) {
-		pk_warning ("not a remote exception, is this sane?");
+		pk_warning ("not a remote exception: %s", error->message);
 		return FALSE;
 	}
 
commit ca1ca0a8c85a376e8a54eece8ae0ce9658964c0c
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 18:34:38 2008 +0100

    add the status icons to the FAQ page

diff --git a/docs/html/img/pk-update-bugfix.png b/docs/html/img/pk-update-bugfix.png
new file mode 100644
index 0000000..5456998
Binary files /dev/null and b/docs/html/img/pk-update-bugfix.png differ
diff --git a/docs/html/img/pk-update-enhancement.png b/docs/html/img/pk-update-enhancement.png
new file mode 100644
index 0000000..084b754
Binary files /dev/null and b/docs/html/img/pk-update-enhancement.png differ
diff --git a/docs/html/img/pk-update-high.png b/docs/html/img/pk-update-high.png
new file mode 100644
index 0000000..2d4ecae
Binary files /dev/null and b/docs/html/img/pk-update-high.png differ
diff --git a/docs/html/img/pk-update-low.png b/docs/html/img/pk-update-low.png
new file mode 100644
index 0000000..e7ad608
Binary files /dev/null and b/docs/html/img/pk-update-low.png differ
diff --git a/docs/html/img/pk-update-normal.png b/docs/html/img/pk-update-normal.png
new file mode 100644
index 0000000..95a86cb
Binary files /dev/null and b/docs/html/img/pk-update-normal.png differ
diff --git a/docs/html/img/pk-update-security.png b/docs/html/img/pk-update-security.png
new file mode 100644
index 0000000..6223571
Binary files /dev/null and b/docs/html/img/pk-update-security.png differ
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 7d15c3c..5193ef6 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -23,13 +23,14 @@
 <ul>
 <li><a href="#how-complete">How complete are the backends?</a></li>
 <li><a href="#selinux">Why doesn't PackageKit work with SELinux?</a></li>
+<li><a href="#tray-icons">What do the tray icons mean?</a></li>
 <li><a href="#no-percentage-updates">What if we don't support percentage updates?</a></li>
 <li><a href="#remaining-times">Why are the remaining times sometimes wildly wrong?</a></li>
 <li><a href="#different-options">How will PackageKit support all the different options?</a></li>
 <li><a href="#error-codes">Error codes are different on each backend?</a></li>
 <li><a href="#user-interaction">Installation an application that needs user interaction?</a></li>
 <li><a href="#up2date">Does PackageKit replace up2date?</a></li>
-<li><a href="#system=daemon">Is PackageKit a system daemon, always running and using resources?</a></li>
+<li><a href="#system-daemon">Is PackageKit a system daemon, always running and using resources?</a></li>
 <li><a href="#dependencies">How does PackageKit handle dependencies?</a></li>
 <li><a href="#rcd">Does PackageKit replace the Red Carpet service?</a></li>
 <li><a href="#how-fast">How fast is PackageKit?</a></li>
@@ -531,6 +532,24 @@
 </table>
 
 <hr>
+<h3><a name="tray-icons">What do the tray icons mean?</a></h3>
+<table>
+<tr><td><img src="img/pk-update-bugfix.png"/></td><td>Bugfix update</td></tr>
+<tr><td><img src="img/pk-update-enhancement.png"/></td><td>Enhancement update</td></tr>
+<tr><td><img src="img/pk-update-high.png"/></td><td>High priority update</td></tr>
+<tr><td><img src="img/pk-update-low.png"/></td><td>Low priority update</td></tr>
+<tr><td><img src="img/pk-update-normal.png"/></td><td>Normal update</td></tr>
+<tr><td><img src="img/pk-update-security.png"/></td><td>Security update</td></tr>
+</table>
+<p>
+<b>NOTE:</b>Not all the icons may show for some backends.
+</p>
+<p>
+If you are using Fedora rawhide then only the bugfix icon will be show due to missing metadata.
+In the released versions of Fedora metadata is added to updates and the type of update can be found.
+</p>
+
+<hr>
 <h3><a name="selinux">Why doesn't PackageKit work with SELinux?</a></h3>
 <p>
 The process <code>packagekitd</code> is not recognized by SELinux in Fedora 8.
diff --git a/docs/html/update-icons.sh b/docs/html/update-icons.sh
new file mode 100755
index 0000000..c510728
--- /dev/null
+++ b/docs/html/update-icons.sh
@@ -0,0 +1,2 @@
+cp -v ../../../gnome-packagekit/data/icons/48x48/status/pk-update-*.png img/
+
commit 323383297addf4bc81b9941330ab8f75fd41a95e
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 18:05:21 2008 +0100

    fix another error special case

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index e3b905f..9c7ba29 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -999,7 +999,8 @@ pk_client_cancel (PkClient *client, GError **error)
 
 	/* special case - if the tid is already finished, then cancel should
 	 * return TRUE as it's what we wanted */
-	if (pk_strequal (error_local->message, "cancelling a non-running transaction")) {
+	if (pk_strequal (error_local->message, "cancelling a non-running transaction") ||
+	    g_str_has_suffix (error_local->message, " doesn't exist")) {
 		pk_debug ("error ignored '%s' as we are trying to cancel", error_local->message);
 		g_error_free (error_local);
 		return TRUE;
commit 6ab907bcfa3e9ef90983f991e27f9eb6c4096b11
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Apr 8 18:05:12 2008 +0100

    fix getting the updates from cache

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 293bb91..34677de 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1596,7 +1596,7 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 			package = pk_package_list_get_item (updates_cache, i);
 			info_text = pk_info_enum_to_text (package->info);
 			g_signal_emit (transaction, signals [PK_TRANSACTION_PACKAGE], 0,
-				       transaction->priv->tid, info_text, package->package_id, package->summary);
+				       info_text, package->package_id, package->summary);
 		}
 
 		/* we are done */


More information about the PackageKit-commit mailing list