hal: Branch 'master' - 3 commits

David Zeuthen david at kemper.freedesktop.org
Mon Mar 3 13:07:49 PST 2008


 doc/spec/hal-spec-interfaces.xml             |   38 ++++++
 fdi/policy/10osvendor/20-storage-methods.fdi |    7 -
 hald/hald_dbus.c                             |   90 +++++++++++++++
 hald/hald_dbus.h                             |    2 
 hald/linux/addons/addon-storage.c            |  162 ++++++++++++++++++++-------
 libhal-storage/libhal-storage.c              |    8 +
 libhal-storage/libhal-storage.h              |    1 
 libhal/libhal.c                              |  155 +++++++++++++++++++++++++
 libhal/libhal.h                              |    6 +
 tools/hal-setup-keymap-hash-name.h           |   47 ++++---
 tools/hal-storage-closetray.c                |    3 
 tools/hal-storage-eject.c                    |    3 
 tools/hal-storage-shared.c                   |   22 +++
 tools/hal-storage-shared.h                   |    3 
 14 files changed, 475 insertions(+), 72 deletions(-)

New commits:
commit ad5b75e9c747cc163bc6bd5c2b6a64b8d77f5475
Merge: 2804872... a91b0de...
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Mar 3 16:04:58 2008 -0500

    Merge branch 'master' of ssh://david@git.freedesktop.org/git/hal

commit 28048726d5401e913b8a2321838147a402bd34a6
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Mar 3 16:03:56 2008 -0500

    provide a new org.fd.Hal.D.Storage.Removable interface for polling media
    
    This is used by the gvfs hal backend and Nautilus to properly support
    drives that are not polled for media changes.

diff --git a/doc/spec/hal-spec-interfaces.xml b/doc/spec/hal-spec-interfaces.xml
index ab1308b..3c59e6a 100644
--- a/doc/spec/hal-spec-interfaces.xml
+++ b/doc/spec/hal-spec-interfaces.xml
@@ -1115,6 +1115,44 @@ $ dbus-send --system --print-reply --dest=org.freedesktop.Hal \
     </para>
   </sect1>
 
+  <sect1 id="interface-device-storage-removable">
+    <title>org.freedesktop.Hal.Device.Storage.Removable interface</title>
+    <para>
+      This interface provides a mechanism to interact with a storage
+      device that uses removable media. The following methods are
+      available:
+    </para>
+
+    <informaltable>
+      <tgroup cols="2">
+        <thead>
+          <row>
+            <entry>Method</entry>
+            <entry>Returns</entry>
+            <entry>Parameters</entry>
+            <entry>Throws</entry>
+            <entry>Description</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry>CheckForMedia</entry>
+            <entry>Bool</entry>
+            <entry></entry>
+            <entry></entry>
+            <entry>
+              Polls a storage device for media.
+            </entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </informaltable>
+
+    <para>
+      This interface does not emit any signals.
+    </para>
+  </sect1>
+
   <sect1 id="interface-device-volume">
     <title>org.freedesktop.Hal.Device.Volume interface</title>
     <para>
diff --git a/fdi/policy/10osvendor/20-storage-methods.fdi b/fdi/policy/10osvendor/20-storage-methods.fdi
index 9a0cbf5..df8cc9b 100644
--- a/fdi/policy/10osvendor/20-storage-methods.fdi
+++ b/fdi/policy/10osvendor/20-storage-methods.fdi
@@ -6,10 +6,9 @@
       <append key="info.callouts.add" type="strlist">hal-storage-cleanup-all-mountpoints</append>
     </match>
 
-    <match key="storage.media_check_enabled" bool="true">
-      <match key="storage.removable.support_async_notification" bool="false">
-        <append key="info.addons" type="strlist">hald-addon-storage</append>
-      </match>
+    <!-- poll drives with removable media -->
+    <match key="storage.removable" bool="true">
+      <append key="info.addons" type="strlist">hald-addon-storage</append>
     </match>
 
     <match key="volume.is_disc" bool="true">
diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c
index 85e0518..abf8eaf 100644
--- a/hald/linux/addons/addon-storage.c
+++ b/hald/linux/addons/addon-storage.c
@@ -61,6 +61,8 @@ static GMainLoop *loop;
 static gboolean system_is_idle = FALSE;
 static gboolean check_lock_state = TRUE;
 
+static gboolean polling_disabled = FALSE;
+
 static void 
 force_unmount (LibHalContext *ctx, const char *udi)
 {
@@ -277,6 +279,7 @@ enum {
 };
 
 static gboolean poll_for_media (gpointer user_data);
+static gboolean poll_for_media_force ();
 
 static int interval_in_seconds = 2;
 
@@ -286,7 +289,10 @@ static gboolean is_locked_via_o_excl = FALSE;
 static void
 update_proc_title (void)
 {
-        if (is_locked_by_hal) {
+
+        if (polling_disabled) {
+                hal_set_proc_title ("hald-addon-storage: no polling on %s because it is explicitly disabled", device_file);
+        } else if (is_locked_by_hal) {
                 if (is_locked_via_o_excl) {
                         hal_set_proc_title ("hald-addon-storage: no polling because %s is locked via HAL and O_EXCL", device_file);
                 } else {
@@ -335,11 +341,9 @@ update_polling_interval (void)
 static gboolean
 poll_for_media (gpointer user_data)
 {
-	int fd;
-	int got_media;
-
         if (check_lock_state) {
                 DBusError error;
+                dbus_bool_t should_poll;
 
                 check_lock_state = FALSE;
 
@@ -355,14 +359,40 @@ poll_for_media (gpointer user_data)
                         is_locked_by_hal = FALSE;
                         update_proc_title ();
                 }
+
+                dbus_error_init (&error);
+                should_poll = libhal_device_get_property_bool (ctx, udi, "storage.media_check_enabled", &error);
+                if (should_poll) {
+                        polling_disabled = FALSE;
+                        update_proc_title ();
+                } else {
+                        polling_disabled = TRUE;
+                        update_proc_title ();
+                }
+
         }
 
         /* TODO: we could remove the timeout completely... */
-        if (is_locked_by_hal)
+        if (is_locked_by_hal || polling_disabled)
                 goto skip_check;
-	
+
+        poll_for_media_force ();
+
+skip_check:
+	return TRUE;
+}
+
+/* returns: whether the state changed */
+static gboolean
+poll_for_media_force ()
+{
+        int fd;
+        int got_media;
+        int old_media_status;
+
 	got_media = FALSE;
-	
+
+        old_media_status = media_status;
 	if (is_cdrom) {
 		int drive;
 		
@@ -538,51 +568,75 @@ poll_for_media (gpointer user_data)
 	/*HAL_DEBUG (("polling %s; got media=%d", device_file, got_media));*/
 	
 skip_check:
-	return TRUE;
+	return old_media_status != media_status;
 }
 
 #ifdef HAVE_CONKIT
 static gboolean
 get_system_idle_from_ck (void)
 {
-	gboolean ret;
-	DBusError error;
-	DBusMessage *message;
-	DBusMessage *reply;
-
-	ret = FALSE;
-
-	message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
-						"/org/freedesktop/ConsoleKit/Manager",
-						"org.freedesktop.ConsoleKit.Manager",
-						"GetSystemIdleHint");
-	dbus_error_init (&error);
-	reply = dbus_connection_send_with_reply_and_block (con, message, -1, &error);
-	if (reply == NULL || dbus_error_is_set (&error)) {
-		HAL_ERROR (("Error doing Manager.GetSystemIdleHint on ConsoleKit: %s: %s", error.name, error.message));
-		dbus_message_unref (message);
-		if (reply != NULL)
-			dbus_message_unref (reply);
-		goto error;
-	}
-	if (!dbus_message_get_args (reply, NULL,
-				    DBUS_TYPE_BOOLEAN, &(system_is_idle),
-				    DBUS_TYPE_INVALID)) {
-		HAL_ERROR (("Invalid GetSystemIdleHint reply from CK"));
-		goto error;
-	}
-	dbus_message_unref (message);
-	dbus_message_unref (reply);
-
-	ret = TRUE;
+       gboolean ret;
+       DBusError error;
+       DBusMessage *message;
+       DBusMessage *reply;
+
+       ret = FALSE;
+
+       message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", 
+                                               "/org/freedesktop/ConsoleKit/Manager",
+                                               "org.freedesktop.ConsoleKit.Manager",
+                                               "GetSystemIdleHint");
+       dbus_error_init (&error);
+       reply = dbus_connection_send_with_reply_and_block (con, message, -1, &error);
+       if (reply == NULL || dbus_error_is_set (&error)) {
+               HAL_ERROR (("Error doing Manager.GetSystemIdleHint on ConsoleKit: %s: %s", error.name, error.message));
+               dbus_message_unref (message);
+               if (reply != NULL)
+                       dbus_message_unref (reply);
+               goto error;
+       }
+       if (!dbus_message_get_args (reply, NULL,
+                                   DBUS_TYPE_BOOLEAN, &(system_is_idle),
+                                   DBUS_TYPE_INVALID)) {
+               HAL_ERROR (("Invalid GetSystemIdleHint reply from CK"));
+               goto error;
+       }
+       dbus_message_unref (message);
+       dbus_message_unref (reply);
+
+       ret = TRUE;
 
 error:
-	return ret;
+       return ret;
 }
 #endif /* HAVE_CONKIT */
 
 
 static DBusHandlerResult
+direct_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+	if (dbus_message_is_method_call (message, 
+					 "org.freedesktop.Hal.Device.Storage.Removable", 
+					 "CheckForMedia")) {
+                DBusMessage *reply;
+                dbus_bool_t call_had_sideeffect;
+
+                HAL_INFO (("Forcing poll for media becusse CheckForMedia() was called"));
+
+                call_had_sideeffect = poll_for_media_force ();
+
+                reply = dbus_message_new_method_return (message);
+                dbus_message_append_args (reply,
+                                          DBUS_TYPE_BOOLEAN, &call_had_sideeffect,
+                                          DBUS_TYPE_INVALID);
+                dbus_connection_send (connection, reply, NULL);
+                dbus_message_unref (reply);
+        }
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
 dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
 {
 #ifdef HAVE_CONKIT
@@ -667,6 +721,23 @@ main (int argc, char *argv[])
 	dbus_connection_setup_with_g_main (con, NULL);
 	dbus_connection_set_exit_on_disconnect (con, 0);
 
+        LibHalContext *ctx_direct;
+        DBusConnection *con_direct;
+	dbus_error_init (&error);
+	if ((ctx_direct = libhal_ctx_init_direct (&error)) == NULL) {
+		HAL_ERROR (("Cannot connect to hald"));
+                goto out;
+	}
+	dbus_error_init (&error);
+	if (!libhal_device_addon_is_ready (ctx_direct, udi, &error)) {
+                goto out;
+	}
+	con_direct = libhal_ctx_get_dbus_connection (ctx_direct);
+	dbus_connection_setup_with_g_main (con_direct, NULL);
+	dbus_connection_set_exit_on_disconnect (con_direct, 0);
+	dbus_connection_add_filter (con_direct, direct_filter_function, NULL, NULL);
+
+
 	dbus_error_init (&error);
 	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
 		goto out;
@@ -687,6 +758,7 @@ main (int argc, char *argv[])
 
 	media_status = MEDIA_STATUS_UNKNOWN;
 
+
 #ifdef HAVE_CONKIT
 	/* TODO: ideally we should track the sessions on the seats on
 	 * which the device belongs to. But right now we don't really
@@ -733,6 +805,18 @@ main (int argc, char *argv[])
         g_free (str);
 	dbus_connection_add_filter (con, dbus_filter_function, NULL, NULL);
 
+	if (!libhal_device_claim_interface (ctx,
+					    udi, 
+					    "org.freedesktop.Hal.Device.Storage.Removable", 
+					    "    <method name=\"CheckForMedia\">\n"
+					    "      <arg name=\"call_had_sideeffect\" direction=\"out\" type=\"b\"/>\n"
+					    "    </method>\n",
+					    &error)) {
+		HAL_ERROR (("Cannot claim interface 'org.freedesktop.Hal.Device.Storage.Removable'"));
+                goto out;
+	}
+
+
 	update_polling_interval ();
 	g_main_loop_run (loop);
 
diff --git a/libhal-storage/libhal-storage.c b/libhal-storage/libhal-storage.c
index 4da5564..70aeb38 100644
--- a/libhal-storage/libhal-storage.c
+++ b/libhal-storage/libhal-storage.c
@@ -708,6 +708,7 @@ struct LibHalDrive_s {
 	dbus_bool_t is_hotpluggable;
 	dbus_bool_t is_removable;
 	dbus_bool_t is_media_detected;
+	dbus_bool_t is_media_detection_automatic;
 	dbus_bool_t requires_eject;
 
 	LibHalDriveType type;
@@ -978,6 +979,7 @@ libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
 		LIBHAL_PROP_EXTRACT_BOOL   ("storage.hotpluggable",      drive->is_hotpluggable);
 		LIBHAL_PROP_EXTRACT_BOOL   ("storage.removable",         drive->is_removable);
 		LIBHAL_PROP_EXTRACT_BOOL   ("storage.removable.media_available", drive->is_media_detected);
+		LIBHAL_PROP_EXTRACT_BOOL   ("storage.media_check_enabled", drive->is_media_detection_automatic);
 		LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size); 
 		LIBHAL_PROP_EXTRACT_BOOL   ("storage.requires_eject",    drive->requires_eject);
 
@@ -1538,6 +1540,12 @@ libhal_drive_is_media_detected (LibHalDrive *drive)
 	return drive->is_media_detected;
 }
 
+dbus_bool_t
+libhal_drive_is_media_detection_automatic (LibHalDrive *drive)
+{
+	return drive->is_media_detection_automatic;
+}
+
 dbus_uint64_t
 libhal_drive_get_size (LibHalDrive *drive)
 {
diff --git a/libhal-storage/libhal-storage.h b/libhal-storage/libhal-storage.h
index bb963f2..dd3d734 100644
--- a/libhal-storage/libhal-storage.h
+++ b/libhal-storage/libhal-storage.h
@@ -205,6 +205,7 @@ void                 libhal_drive_free                        (LibHalDrive *driv
 dbus_bool_t          libhal_drive_is_hotpluggable          (LibHalDrive      *drive);
 dbus_bool_t          libhal_drive_uses_removable_media     (LibHalDrive      *drive);
 dbus_bool_t          libhal_drive_is_media_detected        (LibHalDrive      *drive);
+dbus_bool_t          libhal_drive_is_media_detection_automatic (LibHalDrive      *drive);
 dbus_uint64_t        libhal_drive_get_size                 (LibHalDrive      *drive);
 dbus_uint64_t        libhal_drive_get_media_size           (LibHalDrive      *drive);
 const char          *libhal_drive_get_partition_scheme     (LibHalDrive      *drive);
diff --git a/tools/hal-setup-keymap-hash-name.h b/tools/hal-setup-keymap-hash-name.h
index a4c8679..143243c 100644
--- a/tools/hal-setup-keymap-hash-name.h
+++ b/tools/hal-setup-keymap-hash-name.h
@@ -31,7 +31,7 @@ error "gperf generated tables don't work with this execution character set. Plea
 
 struct key { const char* name; unsigned short id; };
 
-#define TOTAL_KEYWORDS 364
+#define TOTAL_KEYWORDS 365
 #define MIN_WORD_LENGTH 1
 #define MAX_WORD_LENGTH 16
 #define MIN_HASH_VALUE 1
@@ -100,7 +100,7 @@ hash_input_names (str, len)
       1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
       1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,
       1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356,  180,  195,
-        65,  245,  275,  150,  220,  315,  295,  320,    0, 1356,
+        65,  245,  275,  150,  220,  315,  295,  325,   10, 1356,
       1356, 1356, 1356, 1356, 1356,  105,  270,   35,   15,   10,
        225,  190,   25,  110,  285,  115,  215,   30,   85,    5,
        135,  460,    0,   20,   40,   75,  450,  250,  355,   45,
@@ -541,7 +541,7 @@ lookup_key (str, len)
       {(char*)0},
       {"J", KEY_J},
       {"ZOOMOUT", KEY_ZOOMOUT},
-      {"KP9", KEY_KP9},
+      {(char*)0},
       {"VCR2", KEY_VCR2},
       {(char*)0},
       {"FN_ESC", KEY_FN_ESC},
@@ -555,7 +555,7 @@ lookup_key (str, len)
       {"VIDEO", KEY_VIDEO},
       {(char*)0},
       {"EJECTCLOSECD", KEY_EJECTCLOSECD},
-      {(char*)0},
+      {"KP9", KEY_KP9},
       {"ZENKAKUHANKAKU", KEY_ZENKAKUHANKAKU},
       {"GREEN", KEY_GREEN},
       {"8", KEY_8},
@@ -600,15 +600,14 @@ lookup_key (str, len)
       {"CHANNEL", KEY_CHANNEL},
       {"BRL_DOT7", KEY_BRL_DOT7},
       {"MAIL", KEY_MAIL},
-      {(char*)0},
-      {"9", KEY_9},
-      {(char*)0},
-      {"BRL_DOT9", KEY_BRL_DOT9},
+      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0},
       {"AB", KEY_AB},
-      {(char*)0}, {(char*)0},
+      {"BRL_DOT9", KEY_BRL_DOT9},
+      {(char*)0},
       {"FN_F2", KEY_FN_F2},
-      {(char*)0}, {(char*)0},
+      {"9", KEY_9},
+      {(char*)0},
       {"MHP", KEY_MHP},
       {(char*)0},
       {"102ND", KEY_102ND},
@@ -670,16 +669,16 @@ lookup_key (str, len)
       {"SHUFFLE", KEY_SHUFFLE},
       {(char*)0}, {(char*)0},
       {"AGAIN", KEY_AGAIN},
-      {(char*)0}, {(char*)0},
-      {"F19", KEY_F19},
+      {(char*)0}, {(char*)0}, {(char*)0},
       {"FN_F", KEY_FN_F},
       {"EMAIL", KEY_EMAIL},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0},
       {"KBDILLUMUP", KEY_KBDILLUMUP},
-      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
-      {(char*)0},
+      {(char*)0}, {(char*)0},
+      {"F19", KEY_F19},
+      {(char*)0}, {(char*)0},
       {"Z", KEY_Z},
       {(char*)0}, {(char*)0}, {(char*)0},
       {"PROG3", KEY_PROG3},
@@ -731,15 +730,16 @@ lookup_key (str, len)
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0},
       {"KP7", KEY_KP7},
-      {(char*)0}, {(char*)0}, {(char*)0},
-      {"F9", KEY_F9},
-      {"KP8", KEY_KP8},
-      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+      {(char*)0},
+      {"KP8", KEY_KP8},
+      {(char*)0}, {(char*)0}, {(char*)0},
+      {"F9", KEY_F9},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+      {(char*)0}, {(char*)0}, {(char*)0},
       {"QUESTION", KEY_QUESTION},
       {(char*)0}, {(char*)0},
       {"FN_F10", KEY_FN_F10},
@@ -795,16 +795,16 @@ lookup_key (str, len)
       {"F17", KEY_F17},
       {(char*)0},
       {"VIDEO_PREV", KEY_VIDEO_PREV},
-      {(char*)0}, {(char*)0},
-      {"F18", KEY_F18},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+      {(char*)0}, {(char*)0}, {(char*)0},
+      {"F18", KEY_F18},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
-      {(char*)0}, {(char*)0}, {(char*)0},
+      {(char*)0}, {(char*)0},
       {"FN_F4", KEY_FN_F4},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
@@ -833,9 +833,11 @@ lookup_key (str, len)
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0},
-      {"FN_F9", KEY_FN_F9},
+      {"WIMAX", KEY_WIMAX},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+      {(char*)0},
+      {"FN_F9", KEY_FN_F9},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
@@ -882,7 +884,6 @@ lookup_key (str, len)
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
       {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
-      {(char*)0}, {(char*)0},
       {"EQUAL", KEY_EQUAL}
     };
 
diff --git a/tools/hal-storage-closetray.c b/tools/hal-storage-closetray.c
index 7d89c9c..ef7405d 100644
--- a/tools/hal-storage-closetray.c
+++ b/tools/hal-storage-closetray.c
@@ -146,7 +146,8 @@ main (int argc, char *argv[])
 	}
 
 	/* use handle_eject() with the closetray option */
-	handle_eject (hal_ctx, 
+	handle_eject (system_bus,
+                      hal_ctx, 
 		      libhal_drive_get_udi (drive),
 		      drive,
 		      libhal_drive_get_device_file (drive),
diff --git a/tools/hal-storage-eject.c b/tools/hal-storage-eject.c
index 90d31f7..81d1c8f 100644
--- a/tools/hal-storage-eject.c
+++ b/tools/hal-storage-eject.c
@@ -207,7 +207,8 @@ main (int argc, char *argv[])
 	libhal_free_string_array (volume_udis);
 
 	/* now attempt the eject */
-	handle_eject (hal_ctx, 
+	handle_eject (system_bus,
+                      hal_ctx, 
 		      libhal_drive_get_udi (drive),
 		      drive,
 		      libhal_drive_get_device_file (drive),
diff --git a/tools/hal-storage-shared.c b/tools/hal-storage-shared.c
index 19be0c9..849b0ae 100644
--- a/tools/hal-storage-shared.c
+++ b/tools/hal-storage-shared.c
@@ -533,7 +533,8 @@ line_found:
 }
 
 void
-handle_eject (LibHalContext *hal_ctx, 
+handle_eject (DBusConnection *system_bus,
+              LibHalContext *hal_ctx, 
 	      const char *udi,
 	      LibHalDrive *drive, const char *device, 
 	      const char *invoked_by_uid, const char *invoked_by_syscon_name,
@@ -551,7 +552,7 @@ handle_eject (LibHalContext *hal_ctx,
         DBusError error;
 #endif
 
-	/* When called here all the file systems from this device is
+	/* When called here all the file systems from this device are
 	 * already unmounted. That's actually guaranteed; see
 	 * tools/hal-storage-eject.c for details.
 	 *
@@ -656,7 +657,22 @@ try_open_excl_again:
 		unknown_error (serr);
 	}
 
-	/* eject was succesful... */
+	/* eject was succesful... now.. if we're not polling the drive
+         * invoke CheckForMedia() to make sure the device database is
+         * properly updated...
+         */
+        if (!libhal_drive_is_media_detection_automatic (drive)) {
+                DBusMessage *message;
+                DBusMessage *reply;
+                DBusError error;
+
+                message = dbus_message_new_method_call ("org.freedesktop.Hal",
+                                                        udi,
+                                                        "org.freedesktop.Hal.Device.Storage.Removable",
+                                                        "CheckForMedia");
+                dbus_error_init (&error);
+                reply = dbus_connection_send_with_reply_and_block (system_bus, message, -1, &error);
+        }
 
 #ifdef DEBUG
 	printf ("done ejecting\n");
diff --git a/tools/hal-storage-shared.h b/tools/hal-storage-shared.h
index 1910085..dcf7a0b 100644
--- a/tools/hal-storage-shared.h
+++ b/tools/hal-storage-shared.h
@@ -51,7 +51,8 @@ void handle_unmount (LibHalContext *hal_ctx,
 		     const char *invoked_by_uid, const char *invoked_by_syscon_name,
 		     gboolean option_lazy, gboolean option_force);
 
-void handle_eject (LibHalContext *hal_ctx, 
+void handle_eject (DBusConnection *system_bus,
+                   LibHalContext *hal_ctx, 
 		   const char *udi,
 		   LibHalDrive *drive, const char *device, 
 		   const char *invoked_by_uid, const char *invoked_by_syscon_name,
commit 1f567f93c6ad23371cd75ed5507e24b7d707ca1d
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Mar 3 15:57:06 2008 -0500

    add methods and libhal api to get all devices in properties in one call
    
    This is optionally used by the gvfs hal volume monitor.

diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 2498368..de122ed 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -65,6 +65,10 @@ static CKTracker *ck_tracker = NULL;
 #endif
 static GHashTable *singletons = NULL;
 
+static void foreach_property_append (HalDevice *device, 
+                                     const char *key,
+                                     gpointer user_data);
+
 static void
 raise_error (DBusConnection *connection,
 	     DBusMessage *in_reply_to,
@@ -336,6 +340,83 @@ foreach_device_get_udi (HalDeviceStore *store, HalDevice *device,
 	return TRUE;
 }
 
+static gboolean
+foreach_device_get_udi_with_properties (HalDeviceStore *store, HalDevice *device, gpointer user_data)
+{
+	DBusMessageIter *iter = user_data;
+	DBusMessageIter iter_struct;
+	DBusMessageIter iter_dict;
+	const char *udi;
+
+        dbus_message_iter_open_container (iter,
+                                          DBUS_TYPE_STRUCT,
+                                          NULL,
+                                          &iter_struct);
+
+	udi = hal_device_get_udi (device);
+        dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &udi);
+
+	dbus_message_iter_open_container (&iter_struct, 
+					  DBUS_TYPE_ARRAY,
+					  DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+					  DBUS_TYPE_STRING_AS_STRING
+					  DBUS_TYPE_VARIANT_AS_STRING
+					  DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+					  &iter_dict);
+
+	hal_device_property_foreach (device, foreach_property_append, &iter_dict);
+
+	dbus_message_iter_close_container (&iter_struct, &iter_dict);
+        dbus_message_iter_close_container (iter, &iter_struct);
+	return TRUE;
+}
+
+/** 
+ *  manager_get_all_devices_with_properties:
+ *  @connection:         D-BUS connection
+ *  @message:            Message
+ *
+ *  Returns:             What to do with the message
+ *
+ *  Get all devices.
+ *
+ *  <pre>
+ *  array{struct {object_reference, map{string, any}}} Manager.GetAllDevicesWithProperties()
+ *  </pre>
+ *
+ */
+DBusHandlerResult
+manager_get_all_devices_with_properties (DBusConnection * connection,
+                                         DBusMessage * message)
+{
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter iter_array;
+
+	reply = dbus_message_new_method_return (message);
+	if (reply == NULL)
+		DIE (("No memory"));
+
+	dbus_message_iter_init_append (reply, &iter);
+	dbus_message_iter_open_container (&iter, 
+					  DBUS_TYPE_ARRAY,
+                                          "(sa{sv})",
+					  &iter_array);
+
+	hal_device_store_foreach (hald_get_gdl (),
+				  foreach_device_get_udi_with_properties,
+				  &iter_array);
+
+	dbus_message_iter_close_container (&iter, &iter_array);
+
+	if (!dbus_connection_send (connection, reply, NULL))
+		DIE (("No memory"));
+
+	dbus_message_unref (reply);
+
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
 /** 
  *  manager_get_all_devices: 
  *  @connection:         D-BUS connection
@@ -4323,6 +4404,9 @@ do_introspect (DBusConnection  *connection,
 				       "    <method name=\"GetAllDevices\">\n"
 				       "      <arg name=\"devices\" direction=\"out\" type=\"ao\"/>\n"
 				       "    </method>\n"
+				       "    <method name=\"GetAllDevicesWithProperties\">\n"
+				       "      <arg name=\"devices_with_props\" direction=\"out\" type=\"a(oa{sv})\"/>\n"
+				       "    </method>\n"
 				       "    <method name=\"DeviceExists\">\n"
 				       "      <arg name=\"does_it_exist\" direction=\"out\" type=\"b\"/>\n"
 				       "      <arg name=\"udi\" direction=\"in\" type=\"o\"/>\n"
@@ -4717,6 +4801,12 @@ hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *messag
 			   "/org/freedesktop/Hal/Manager") == 0) {
 		return manager_get_all_devices (connection, message);
 	} else if (dbus_message_is_method_call (message,
+                                                "org.freedesktop.Hal.Manager",
+                                                "GetAllDevicesWithProperties") &&
+		   strcmp (dbus_message_get_path (message),
+			   "/org/freedesktop/Hal/Manager") == 0) {
+		return manager_get_all_devices_with_properties (connection, message);
+	} else if (dbus_message_is_method_call (message,
 						"org.freedesktop.Hal.Manager",
 						"DeviceExists") &&
 		   strcmp (dbus_message_get_path (message),
diff --git a/hald/hald_dbus.h b/hald/hald_dbus.h
index 40187a6..3bc2d04 100644
--- a/hald/hald_dbus.h
+++ b/hald/hald_dbus.h
@@ -32,6 +32,8 @@
 
 DBusHandlerResult manager_get_all_devices           (DBusConnection *connection,
 						     DBusMessage    *message);
+DBusHandlerResult manager_get_all_devices_with_properties (DBusConnection *connection,
+						     DBusMessage    *message);
 DBusHandlerResult manager_find_device_string_match  (DBusConnection *connection,
 						     DBusMessage    *message);
 DBusHandlerResult manager_find_device_by_capability (DBusConnection *connection,
diff --git a/libhal/libhal.c b/libhal/libhal.c
index 8ad8d49..4318485 100644
--- a/libhal/libhal.c
+++ b/libhal/libhal.c
@@ -5113,3 +5113,158 @@ libhal_device_is_caller_privileged (LibHalContext *ctx,
 	dbus_message_unref (reply);
 	return value;
 }
+
+/**
+ * libhal_get_all_devices_with_properties:
+ * @out_num_devices: Return location for number of devices
+ * @out_udi: Return location for array of of udi's. Caller should free this with libhal_free_string_array() when done with it.
+ * @out_properties: Return location for array of #LibHalPropertySet objects. Caller should free each one of them with libhal_free_property_set() when done with it
+ * @error: Return location for error
+ *
+ * Get all devices in the hal database as well as all properties for each device.
+ *
+ * Return: %TRUE if success; %FALSE and @error will be set.
+ **/
+dbus_bool_t libhal_get_all_devices_with_properties (LibHalContext       *ctx, 
+                                                    int                 *out_num_devices, 
+                                                    char              ***out_udi,
+                                                    LibHalPropertySet ***out_properties, 
+                                                    DBusError           *error)
+{
+
+	DBusMessage *message;
+	DBusMessage *reply;
+	DBusMessageIter iter_array, reply_iter;
+	DBusError _error;
+        char **udi_array;
+        char **_udi_array;
+        LibHalPropertySet **prop_array;
+        LibHalPropertySet **_prop_array;
+        size_t count;
+        unsigned int n;
+
+	LIBHAL_CHECK_LIBHALCONTEXT (ctx, FALSE);
+	LIBHAL_CHECK_LIBHALCONTEXT (out_num_devices, FALSE);
+	LIBHAL_CHECK_LIBHALCONTEXT (out_udi, FALSE);
+	LIBHAL_CHECK_LIBHALCONTEXT (out_properties, FALSE);
+
+	*out_num_devices = 0;
+        *out_udi = NULL;
+        *out_properties = NULL;
+
+        count = 0;
+        udi_array  = NULL;
+        prop_array = NULL;
+
+	message = dbus_message_new_method_call ("org.freedesktop.Hal",
+						"/org/freedesktop/Hal/Manager",
+						"org.freedesktop.Hal.Manager",
+						"GetAllDevicesWithProperties");
+	if (message == NULL) {
+		fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
+		goto fail;
+	}
+
+	dbus_error_init (&_error);
+	reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
+
+	dbus_move_error (&_error, error);
+	if (error != NULL && dbus_error_is_set (error)) {
+		dbus_message_unref (message);
+		goto fail;
+	}
+	if (reply == NULL) {
+		dbus_message_unref (message);
+		goto fail;
+	}
+
+	/* now analyze reply */
+	dbus_message_iter_init (reply, &reply_iter);
+
+	if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
+		fprintf (stderr, "%s %d : wrong reply from hald.  Expecting an array.\n", __FILE__, __LINE__);
+		goto fail;
+	}
+	
+	dbus_message_iter_recurse (&reply_iter, &iter_array);
+
+        #define _BLOCK_SIZE 32
+
+        udi_array = (char **) malloc (sizeof (char*) * _BLOCK_SIZE);
+        if (udi_array == NULL)
+                goto fail;
+
+        prop_array = (LibHalPropertySet **) malloc (sizeof (void*) * _BLOCK_SIZE);
+        if (prop_array == NULL)
+                goto fail;
+
+	while (dbus_message_iter_get_arg_type (&iter_array) == DBUS_TYPE_STRUCT) {
+                DBusMessageIter iter_struct;
+		const char *value;
+                LibHalPropertySet *pset;
+		char *udi;
+
+		if ((count % _BLOCK_SIZE) == 0 && count > 0) {
+                        _udi_array = (char **) realloc (udi_array, sizeof (char*) * (count + _BLOCK_SIZE));
+                        _prop_array = (LibHalPropertySet **) realloc (prop_array, sizeof (void*) * (count+_BLOCK_SIZE));
+			if (_udi_array == NULL || _prop_array == NULL)
+				goto fail;
+                        udi_array = _udi_array;
+                        prop_array = _prop_array;
+		}
+
+                dbus_message_iter_recurse (&iter_array, &iter_struct);
+		
+		dbus_message_iter_get_basic (&iter_struct, &value);
+		udi = strdup (value);
+		if (udi == NULL)
+			goto fail;
+
+		dbus_message_iter_next(&iter_struct);
+
+                pset = get_property_set (&iter_struct);
+
+                udi_array[count] = udi;
+                prop_array[count] = pset;
+                count++;
+
+		dbus_message_iter_next (&iter_array);
+	}
+
+        if ((count % _BLOCK_SIZE) == 0 && count > 0) {
+                _udi_array = (char **) realloc (udi_array, sizeof (char*) * (count + _BLOCK_SIZE));
+                _prop_array = (LibHalPropertySet **) realloc (prop_array, sizeof (void*) * (count + _BLOCK_SIZE));
+                if (_udi_array == NULL || _prop_array == NULL)
+                        goto fail;
+                udi_array = _udi_array;
+                prop_array = _prop_array;
+        }
+        udi_array[count] = NULL;
+        prop_array[count] = NULL;
+
+	*out_num_devices = count;
+        *out_udi = udi_array;
+        *out_properties = prop_array;
+		      
+	dbus_message_unref (reply);
+	dbus_message_unref (message);
+
+	return TRUE;
+
+fail:
+        if (udi_array != NULL) {
+                for (n = 0; n < count; n++) {
+                        free (udi_array[n]);
+                }
+                free (udi_array);
+        }
+
+        if (prop_array != NULL) {
+                for (n = 0; n < count; n++) {
+                        free (prop_array[n]);
+                }
+                free (prop_array);
+        }
+
+        return FALSE;
+}
diff --git a/libhal/libhal.h b/libhal/libhal.h
index f5e3b54..99ba191 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -518,6 +518,12 @@ LibHalPropertySet *libhal_device_get_all_properties (LibHalContext *ctx,
 						     const char *udi,
 						     DBusError *error);
 
+/* Get all devices and their properties */
+dbus_bool_t libhal_get_all_devices_with_properties (LibHalContext       *ctx, 
+                                                    int                 *out_num_devices, 
+                                                    char              ***out_udi,
+                                                    LibHalPropertySet ***out_properties, 
+                                                    DBusError           *error);
 
 /* sort all properties according to property name */
 void libhal_property_set_sort (LibHalPropertySet *set);


More information about the hal-commit mailing list