[packagekit] packagekit: Branch 'master'

Richard Hughes hughsient at kemper.freedesktop.org
Sat Oct 13 05:11:37 PDT 2007


 TODO               |    7 -
 src/pk-inhibit.c   |  275 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/pk-inhibit.h   |    1 
 src/pk-self-test.c |    2 
 4 files changed, 278 insertions(+), 7 deletions(-)

New commits:
diff-tree 7aefc11eb53729e4e2bda9d7d9433550625460f2 (from 7431bfecfc45f22e9927c2baadf04179ff521022)
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Oct 13 13:07:41 2007 +0100

    actually make the locking talk to HAL. Also add lots of unit tests as this code is quite new

diff --git a/TODO b/TODO
index 3d94698..556bdfc 100644
--- a/TODO
+++ b/TODO
@@ -23,11 +23,6 @@ To do rollbacks sanely in PK we need a f
  * write pk_transaction_id_equal to not compare data
  * allow transaction data to be changed in _db
 
-*** Integrate with HAL ***
-Do the HAL inhibit in packagekitd:
-http://people.freedesktop.org/~david/hal-spec/hal-spec.html
+*** Integrate with gnome-power-manager to prevent shutdown ***
 do the g-p-m client stuff ALSO in the client program (for nice error message)
 
-*** add more unit tests ***
-PkInhibit
-
diff --git a/src/pk-inhibit.c b/src/pk-inhibit.c
index 00bbf45..2c21fa5 100644
--- a/src/pk-inhibit.c
+++ b/src/pk-inhibit.c
@@ -31,28 +31,141 @@
 
 #include <glib/gi18n.h>
 #include <glib.h>
+#include <dbus/dbus-glib.h>
 
 #include "pk-debug.h"
 #include "pk-inhibit.h"
 
 #define PK_INHIBIT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_INHIBIT, PkInhibitPrivate))
+#define HAL_DBUS_SERVICE		"org.freedesktop.Hal"
+#define HAL_DBUS_PATH_COMPUTER		"/org/freedesktop/Hal/devices/computer"
+#define HAL_DBUS_INTERFACE_DEVICE	"org.freedesktop.Hal.Device"
+#define HAL_DBUS_INTERFACE_PM		"org.freedesktop.Hal.Device.SystemPowerManagement"
+
 
 struct PkInhibitPrivate
 {
 	GPtrArray		*array;
+	gboolean		 is_locked;
+	DBusGProxy		*proxy;
 };
 
 G_DEFINE_TYPE (PkInhibit, pk_inhibit, G_TYPE_OBJECT)
 static gpointer pk_inhibit_object = NULL;
 
 /**
+ * pk_inhibit_locked:
+ **/
+gboolean
+pk_inhibit_locked (PkInhibit *inhibit)
+{
+	g_return_val_if_fail (inhibit != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_INHIBIT (inhibit), FALSE);
+	return inhibit->priv->is_locked;
+}
+
+/**
+ * pk_inhibit_lock:
+ **/
+static gboolean
+pk_inhibit_lock (PkInhibit *inhibit)
+{
+	GError *error = NULL;
+	gboolean ret;
+
+	g_return_val_if_fail (inhibit != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_INHIBIT (inhibit), FALSE);
+
+	pk_debug ("Trying to AcquireInterfaceLock");
+	if (inhibit->priv->proxy == NULL) {
+		pk_warning ("not connected to HAL");
+		return FALSE;
+	}
+	if (inhibit->priv->is_locked == TRUE) {
+		pk_warning ("already inhibited, not trying again");
+		return FALSE;
+	}
+
+	/* Lock the interface */
+	ret = dbus_g_proxy_call (inhibit->priv->proxy, "AcquireInterfaceLock", &error,
+				 G_TYPE_STRING, HAL_DBUS_INTERFACE_PM,
+				 G_TYPE_BOOLEAN, FALSE,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (error != NULL) {
+		printf ("DEBUG: ERROR: %s\n", error->message);
+		g_error_free (error);
+	}
+	if (ret == TRUE) {
+		inhibit->priv->is_locked = TRUE;
+		pk_debug ("setting is_locked %i", inhibit->priv->is_locked);
+	}
+
+	return ret;
+}
+
+/**
+ * pk_inhibit_unlock:
+ **/
+static gboolean
+pk_inhibit_unlock (PkInhibit *inhibit)
+{
+	GError *error = NULL;
+	gboolean ret;
+
+	g_return_val_if_fail (inhibit != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_INHIBIT (inhibit), FALSE);
+
+	pk_debug ("Trying to ReleaseInterfaceLock");
+	if (inhibit->priv->proxy == NULL) {
+		pk_warning ("not connected to HAL");
+		return FALSE;
+	}
+	if (inhibit->priv->is_locked == FALSE) {
+		pk_warning ("not inhibited, not trying to unlock");
+		return FALSE;
+	}
+
+	/* Lock the interface */
+	ret = dbus_g_proxy_call (inhibit->priv->proxy, "ReleaseInterfaceLock", &error,
+				 G_TYPE_STRING, HAL_DBUS_INTERFACE_PM,
+				 G_TYPE_BOOLEAN, FALSE,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (error != NULL) {
+		printf ("DEBUG: ERROR: %s\n", error->message);
+		g_error_free (error);
+	}
+	if (ret == TRUE) {
+		inhibit->priv->is_locked = FALSE;
+		pk_debug ("setting is_locked %i", inhibit->priv->is_locked);
+	}
+
+	return ret;
+}
+
+/**
  * pk_inhibit_add:
  **/
 gboolean
 pk_inhibit_add (PkInhibit *inhibit, gpointer data)
 {
+	guint i;
+
 	g_return_val_if_fail (inhibit != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_INHIBIT (inhibit), FALSE);
+
+	for (i=0; i<inhibit->priv->array->len; i++) {
+		if (g_ptr_array_index (inhibit->priv->array, i) == data) {
+			pk_debug ("trying to add item %p already in array", data);
+			return FALSE;
+		}
+	}
+	g_ptr_array_add (inhibit->priv->array, data);
+	/* do inhibit */
+	if (inhibit->priv->array->len == 1) {
+		pk_inhibit_lock (inhibit);
+	}
 	return TRUE;
 }
 
@@ -62,9 +175,22 @@ pk_inhibit_add (PkInhibit *inhibit, gpoi
 gboolean
 pk_inhibit_remove (PkInhibit *inhibit, gpointer data)
 {
+	guint i;
+
 	g_return_val_if_fail (inhibit != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_INHIBIT (inhibit), FALSE);
-	return TRUE;
+
+	for (i=0; i<inhibit->priv->array->len; i++) {
+		if (g_ptr_array_index (inhibit->priv->array, i) == data) {
+			g_ptr_array_remove_index (inhibit->priv->array, i);
+			if (inhibit->priv->array->len == 0) {
+				pk_inhibit_unlock (inhibit);
+			}
+			return TRUE;
+		}
+	}
+	pk_debug ("cannot find item %p", data);
+	return FALSE;
 }
 
 /**
@@ -78,7 +204,12 @@ pk_inhibit_finalize (GObject *object)
 	g_return_if_fail (PK_IS_INHIBIT (object));
 	inhibit = PK_INHIBIT (object);
 
+	/* force an unlock if we are inhibited */
+	if (inhibit->priv->is_locked == TRUE) {
+		pk_inhibit_unlock (inhibit);
+	}
 	g_ptr_array_free (inhibit->priv->array, TRUE);
+	g_object_unref (inhibit->priv->proxy);
 
 	G_OBJECT_CLASS (pk_inhibit_parent_class)->finalize (object);
 }
@@ -104,8 +235,30 @@ pk_inhibit_class_init (PkInhibitClass *k
 static void
 pk_inhibit_init (PkInhibit *inhibit)
 {
+	GError *error = NULL;
+	DBusGConnection *connection;
+
 	inhibit->priv = PK_INHIBIT_GET_PRIVATE (inhibit);
+	inhibit->priv->is_locked = FALSE;
 	inhibit->priv->array = g_ptr_array_new ();
+
+	/* connect to system bus */
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (error != NULL) {
+		pk_warning ("Cannot connect to system bus: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	/* use gnome-power-manager for the battery detection */
+	inhibit->priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
+				  HAL_DBUS_SERVICE, HAL_DBUS_PATH_COMPUTER,
+				  HAL_DBUS_INTERFACE_DEVICE, &error);
+	if (error != NULL) {
+		pk_warning ("Cannot connect to HAL: %s", error->message);
+		g_error_free (error);
+	}
+
 }
 
 /**
@@ -124,3 +277,123 @@ pk_inhibit_new (void)
 	return PK_INHIBIT (pk_inhibit_object);
 }
 
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_inhibit (LibSelfTest *test)
+{
+	PkInhibit *inhibit;
+	gboolean ret;
+
+	if (libst_start (test, "PkInhibit", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "get an instance");
+	inhibit = pk_inhibit_new ();
+	if (inhibit != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "check we have a connection");
+	if (inhibit->priv->proxy != NULL) {
+		libst_success (test, "got proxy");
+	} else {
+		libst_failed (test, "could not get proxy");
+	}
+
+	/************************************************************/
+	libst_title (test, "check we are not inhibited");
+	ret = pk_inhibit_locked (inhibit);
+	if (ret == FALSE) {
+		libst_success (test, "marked correctly");
+	} else {
+		libst_failed (test, "not marked correctly");
+	}
+
+	/************************************************************/
+	libst_title (test, "add 123");
+	ret = pk_inhibit_add (inhibit, GUINT_TO_POINTER (123));
+	if (ret == TRUE) {
+		libst_success (test, "inhibited");
+	} else {
+		libst_failed (test, "could not inhibit");
+	}
+
+	/************************************************************/
+	libst_title (test, "check we are inhibited");
+	ret = pk_inhibit_locked (inhibit);
+	if (ret == TRUE) {
+		libst_success (test, "marked correctly");
+	} else {
+		libst_failed (test, "not marked correctly");
+	}
+
+	/************************************************************/
+	libst_title (test, "add 123 (again)");
+	ret = pk_inhibit_add (inhibit, GUINT_TO_POINTER (123));
+	if (ret == FALSE) {
+		libst_success (test, "correctly ignored second");
+	} else {
+		libst_failed (test, "added the same number twice");
+	}
+
+	/************************************************************/
+	libst_title (test, "add 456");
+	ret = pk_inhibit_add (inhibit, GUINT_TO_POINTER (456));
+	if (ret == TRUE) {
+		libst_success (test, "inhibited");
+	} else {
+		libst_failed (test, "could not inhibit");
+	}
+
+	/************************************************************/
+	libst_title (test, "remove 123");
+	ret = pk_inhibit_remove (inhibit, GUINT_TO_POINTER (123));
+	if (ret == TRUE) {
+		libst_success (test, "removed first inhibit");
+	} else {
+		libst_failed (test, "could not remove inhibit");
+	}
+
+	/************************************************************/
+	libst_title (test, "check we are still inhibited");
+	ret = pk_inhibit_locked (inhibit);
+	if (ret == TRUE) {
+		libst_success (test, "marked correctly");
+	} else {
+		libst_failed (test, "not marked correctly");
+	}
+
+	/************************************************************/
+	libst_title (test, "remove 456");
+	ret = pk_inhibit_remove (inhibit, GUINT_TO_POINTER (456));
+	if (ret == TRUE) {
+		libst_success (test, "removed second inhibit");
+	} else {
+		libst_failed (test, "could not remove inhibit");
+	}
+
+	/************************************************************/
+	libst_title (test, "check we are not inhibited");
+	ret = pk_inhibit_locked (inhibit);
+	if (ret == FALSE) {
+		libst_success (test, "marked correctly");
+	} else {
+		libst_failed (test, "not marked correctly");
+	}
+
+	g_object_unref (inhibit);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/src/pk-inhibit.h b/src/pk-inhibit.h
index d71784b..836c70f 100644
--- a/src/pk-inhibit.h
+++ b/src/pk-inhibit.h
@@ -49,6 +49,7 @@ typedef struct
 GType		 pk_inhibit_get_type		(void);
 PkInhibit	*pk_inhibit_new			(void);
 
+gboolean	 pk_inhibit_locked		(PkInhibit	*inhibit);
 gboolean	 pk_inhibit_add			(PkInhibit	*inhibit,
 						 gpointer	 data);
 gboolean	 pk_inhibit_remove		(PkInhibit	*inhibit,
diff --git a/src/pk-self-test.c b/src/pk-self-test.c
index ea73015..1102b89 100644
--- a/src/pk-self-test.c
+++ b/src/pk-self-test.c
@@ -26,6 +26,7 @@
 
 /* prototypes */
 void libst_conf (LibSelfTest *test);
+void libst_inhibit (LibSelfTest *test);
 void libst_spawn (LibSelfTest *test);
 void libst_thread_list (LibSelfTest *test);
 void libst_transaction_list (LibSelfTest *test);
@@ -44,6 +45,7 @@ main (int argc, char **argv)
 
 	/* tests go here */
 	libst_conf (&test);
+	libst_inhibit (&test);
 	libst_spawn (&test);
 	libst_thread_list (&test);
 	libst_transaction_list (&test);



More information about the PackageKit mailing list