davemds pushed a commit to branch master.

http://git.enlightenment.org/enlightenment/modules/places.git/commit/?id=795a9140620d3e93ff18faae5414049b971ef53b

commit 795a9140620d3e93ff18faae5414049b971ef53b
Author: Dave Andreoli <d...@gurumeditation.it>
Date:   Sun Apr 18 13:38:58 2021 +0200

    Finally implemented UDisks2 backend
---
 meson.build         |  19 ++
 meson_options.txt   |   8 +-
 src/e_mod_places.c  |  13 ++
 src/e_mod_places.h  |   5 +-
 src/e_mod_udisks2.c | 645 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/e_mod_udisks2.h |   8 +
 src/meson.build     |   1 +
 7 files changed, 695 insertions(+), 4 deletions(-)

diff --git a/meson.build b/meson.build
index e20db61..0687036 100644
--- a/meson.build
+++ b/meson.build
@@ -28,6 +28,13 @@ config_h.set_quoted('LOCALEDOMAIN', gettext_domain)
 config_dir = include_directories('.')
 
 
+#### Udisks2 support ####
+if get_option('udisks2') == true
+   dependency('udisks2', required: true, version: '>= 2.7.2')
+   config_h.set('PLACES_HAVE_UDISKS2', 1)
+endif
+
+
 #### Udisks1 support ####
 if get_option('udisks') == true
    dependency('udisks', required: true)
@@ -84,3 +91,15 @@ custom_target('e-module-places.edj',
               install_dir: mod_install_dir,
               install    : true
              )
+
+
+#### Report ####
+if meson.version().version_compare('>=0.53')
+   summary({'install': lib_install_dir,
+           }, section: 'Directories')
+   summary({'udisks2': get_option('udisks2'),
+            'udisks1': get_option('udisks'),
+            'mount': get_option('mount'),
+            'eeze': get_option('eeze'),
+         }, section: 'Backends', bool_yn: true)
+endif
\ No newline at end of file
diff --git a/meson_options.txt b/meson_options.txt
index 6bcbde6..d26365e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,7 +1,11 @@
-option('udisks',
+option('udisks2',
        type: 'boolean',
        value: true,
-       description: 'enable udisks1 support (default=true)')
+       description: 'enable udisks2 support (default=true)')
+option('udisks',
+       type: 'boolean',
+       value: false,
+       description: 'enable udisks1 support (default=false)')
 option('mount',
        type: 'boolean',
        value: true,
diff --git a/src/e_mod_places.c b/src/e_mod_places.c
index d2d1810..bb8eabf 100644
--- a/src/e_mod_places.c
+++ b/src/e_mod_places.c
@@ -12,6 +12,10 @@
 # include "e_mod_udisks_eldbus.h"
 #endif
 
+#ifdef PLACES_HAVE_UDISKS2
+# include "e_mod_udisks2.h"
+#endif
+
 #ifdef PLACES_HAVE_MOUNT
 # include "e_mod_mount.h"
 #endif
@@ -67,6 +71,9 @@ places_init(void)
 #ifdef PLACES_HAVE_UDISKS
    places_udisks_eldbus_init();
 #endif
+#ifdef PLACES_HAVE_UDISKS2
+   places_udisks2_init();
+#endif
 #ifdef PLACES_HAVE_MOUNT
    places_mount_init();
 #endif
@@ -118,6 +125,9 @@ places_shutdown(void)
 #ifdef PLACES_HAVE_UDISKS
    places_udisks_eldbus_shutdown();
 #endif
+#ifdef PLACES_HAVE_UDISKS2
+   places_udisks2_shutdown();
+#endif
 #ifdef PLACES_HAVE_MOUNT
    places_mount_shutdown();
 #endif
@@ -343,6 +353,7 @@ places_fill_box(Evas_Object *main, Eina_Bool horiz)
         icon = e_icon_add(evas_object_evas_get(main));
         f1 = f2 = f3 = NULL;
         /* optical discs */
+        // TODO more icons: dvd, blueray....
         if (!strcmp(vol->drive_type, "cdrom") ||
             !strcmp(vol->drive_type, "optical_cd"))
           {
@@ -519,6 +530,7 @@ places_print_volume(Volume *v)
    const char *size, *free;
 
    printf("Got volume %s (totals: %d)\n", v->id, eina_list_count(volumes));
+   printf("  valid: %d\n", v->valid);
    printf("  label: %s\n",v->label);
    printf("  mounted: %d\n", v->mounted);
    printf("  m_point: %s\n", v->mount_point);
@@ -531,6 +543,7 @@ places_print_volume(Volume *v)
    printf("  serial: %s\n", v->serial);
    printf("  removable: %d\n", v->removable);
    printf("  requires eject: %d\n", v->requires_eject);
+   printf("  media_available: %d\n", v->media_available);
    size = _places_human_size_get(v->size);
    free = _places_human_size_get(v->free_space);
    printf("  size: %s\n", size);
diff --git a/src/e_mod_places.h b/src/e_mod_places.h
index 2150e49..fd9f3e7 100644
--- a/src/e_mod_places.h
+++ b/src/e_mod_places.h
@@ -28,8 +28,9 @@ struct _Volume
    const char *model;
    const char *vendor;
    const char *serial;
-   unsigned char removable;
-   unsigned char requires_eject;
+   Eina_Bool removable;
+   Eina_Bool requires_eject;
+   Eina_Bool media_available;
    Eina_Bool unlocked;
    Eina_Bool encrypted;
 
diff --git a/src/e_mod_udisks2.c b/src/e_mod_udisks2.c
new file mode 100644
index 0000000..fc81730
--- /dev/null
+++ b/src/e_mod_udisks2.c
@@ -0,0 +1,645 @@
+
+#include "places_config.h"
+
+
+#ifdef PLACES_HAVE_UDISKS2
+
+#include <e.h>
+#include <Eldbus.h>
+#include "e_mod_main.h"
+#include "e_mod_places.h"
+
+
+/* UDisks2 defines */
+#define UDISKS2_BUS "org.freedesktop.UDisks2"
+#define UDISKS2_PATH "/org/freedesktop/UDisks2"
+
+#define UDISKS2_MANAGER_PATH "/org/freedesktop/UDisks2/Manager"
+#define UDISKS2_MANAGER_IFACE "org.freedesktop.UDisks2.Manager"
+
+#define UDISKS2_BLOCK_IFACE          "org.freedesktop.UDisks2.Block"
+#define UDISKS2_PARTITION_IFACE      "org.freedesktop.UDisks2.Partition"
+#define UDISKS2_FILESYSTEM_IFACE     "org.freedesktop.UDisks2.Filesystem"
+#define UDISKS2_DRIVE_IFACE          "org.freedesktop.UDisks2.Drive"
+#define UDISKS2_PARTITIONTABLE_IFACE "org.freedesktop.UDisks2.PartitionTable"
+#define UDISKS2_LOOP_IFACE           "org.freedesktop.UDisks2.Loop"
+#define UDISKS2_SWAPSPACE_IFACE      "org.freedesktop.UDisks2.Swapspace"
+
+#define UDISKS2_BLOCK_PREFIX "/org/freedesktop/UDisks2/block_devices/"
+#define UDISKS2_DRIVE_PREFIX "/org/freedesktop/UDisks2/drives/"
+
+
+/* Local backend data */
+typedef struct Places_UDisks2_Backend_Data
+{
+   Eldbus_Object *block_obj;
+   Eldbus_Object *drive_obj;
+} Places_UDisks2_Backend_Data;
+
+
+/* Local Function Prototypes */
+static void _places_ud2_name_start(void *data, const Eldbus_Message *msg, 
Eldbus_Pending *pending);
+
+static void _places_ud2_get_managed_objects_cb(void *data, const 
Eldbus_Message *msg, Eldbus_Pending *pending);
+static void _places_ud2_interfaces_added_cb(void *data, const Eldbus_Message 
*msg);
+static void _places_ud2_interfaces_removed_cb(void *data, const Eldbus_Message 
*msg);
+static void _places_ud2_block_props_changed_cb(void *data, const 
Eldbus_Message *msg);
+static void _places_ud2_drive_props_changed_cb(void *data, const 
Eldbus_Message *msg);
+
+static void _places_ud2_read_block_ifaces(const char *obj_path, 
Eldbus_Message_Iter *ifaces_array, Eina_Bool first_time);
+static void _places_ud2_read_drive_properies(Volume *vol, Eldbus_Message_Iter* 
props_array);
+static void _places_ud2_drive_props_cb(void *data, const Eldbus_Message *msg, 
Eldbus_Pending *pending);
+
+static Volume* _places_ud2_volume_add(const char *block_obj_path,  const char* 
drive_obj_path, Eina_Bool first_time);
+static void _places_ud2_volume_finalize(Volume *vol);
+static void _places_ud2_mount_func(Volume *vol, Eina_List *opts);
+static void _places_ud2_unmount_func(Volume *vol, Eina_List *opts);
+static void _places_ud2_eject_func(Volume *vol, Eina_List *opts);
+static void _places_ud2_volume_free_func(Volume *vol);
+
+
+/* Local Variables */
+static Eldbus_Connection *_places_ud2_conn = NULL;
+static Eldbus_Object *_places_ud2_object_manager = NULL;
+
+
+Eina_Bool
+places_udisks2_init(void)
+{
+   printf("PLACES: udisks2: init()\n");
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(eldbus_init(), EINA_FALSE);
+
+   _places_ud2_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
+   if (!_places_ud2_conn)
+   {
+      printf("PLACES: udisks2: Error connecting to system bus.\n");
+      return EINA_FALSE;
+   }
+
+   eldbus_name_start(_places_ud2_conn, UDISKS2_BUS, 0,
+                     _places_ud2_name_start, NULL);
+   return EINA_TRUE;
+}
+
+
+void
+places_udisks2_shutdown(void)
+{
+   printf("PLACES: udisks2: shutdown()\n");
+   E_FREE_FUNC(_places_ud2_object_manager, eldbus_object_unref);
+   E_FREE_FUNC(_places_ud2_conn, eldbus_connection_unref);
+   eldbus_shutdown();
+}
+
+
+static Volume*
+_places_ud2_volume_add(const char *block_obj_path, const char* drive_obj_path, 
Eina_Bool first_time)
+{
+   Places_UDisks2_Backend_Data *bdata;
+   Volume *vol;
+
+   // return a previously created Volume
+   vol = places_volume_by_id_get(block_obj_path);
+   if (vol) return vol;
+
+   // create the backend data struct
+   bdata = E_NEW(Places_UDisks2_Backend_Data, 1);
+   if (!bdata) return NULL;
+
+   // create the Eldbus block_device object
+   bdata->block_obj = eldbus_object_get(_places_ud2_conn, UDISKS2_BUS, 
+                                        block_obj_path);
+   if (!bdata->block_obj) return NULL;
+
+   // create the Eldbus drive object (if exists)
+   if (drive_obj_path && drive_obj_path[0] && !eina_streq(drive_obj_path, 
"/")) 
+   {
+      bdata->drive_obj = eldbus_object_get(_places_ud2_conn, UDISKS2_BUS, 
+                                           drive_obj_path);
+      if (!bdata->drive_obj) return NULL;
+   }
+
+   // create the places Volume
+   vol = places_volume_add(block_obj_path, first_time);
+   if (!vol) return NULL;
+   vol->backend_data = bdata;
+   vol->mount_func = _places_ud2_mount_func;
+   vol->unmount_func = _places_ud2_unmount_func;
+   vol->eject_func = _places_ud2_eject_func;
+   vol->free_func = _places_ud2_volume_free_func;
+
+   // Get notifications on object change properties
+   eldbus_object_signal_handler_add(bdata->block_obj, 
+                                    ELDBUS_FDO_INTERFACE_PROPERTIES, 
+                                    "PropertiesChanged",
+                                    _places_ud2_block_props_changed_cb, vol);
+   if (bdata->drive_obj)
+      eldbus_object_signal_handler_add(bdata->drive_obj, 
+                                       ELDBUS_FDO_INTERFACE_PROPERTIES, 
+                                       "PropertiesChanged",
+                                       _places_ud2_drive_props_changed_cb, 
vol);
+
+   return vol;
+}
+
+
+static void
+_places_ud2_volume_free_func(Volume *vol)
+{
+   Places_UDisks2_Backend_Data *bdata = vol->backend_data;
+   if (bdata)
+   {
+      E_FREE_FUNC(bdata->block_obj, eldbus_object_unref);
+      E_FREE_FUNC(bdata->drive_obj, eldbus_object_unref);
+      E_FREE(vol->backend_data);
+   }
+}
+
+
+/* Some strings in UDisks2 are exposed as array of char (ay), need to convert 
*/
+static char*
+_places_udisks2_string_convert(Eldbus_Message_Iter *ay)
+{
+   char *p, buf[PATH_MAX] = {0};
+   p = buf;
+   while (eldbus_message_iter_get_and_next(ay, 'y', p))
+   {
+      if (!p) break;
+      p++;
+   }
+   // printf("PLACES: stupid string %s\n", str);
+   return strdup(buf);
+}
+
+
+/* The Udisks2 service is up and running, setup the ObjectManager */
+static void
+_places_ud2_name_start(void *data, const Eldbus_Message *msg,
+                           Eldbus_Pending *pending)
+{
+   Eldbus_Proxy *proxy;
+
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   // get the UDisks2 ObjectManager object
+   _places_ud2_object_manager = eldbus_object_get(_places_ud2_conn, 
+                                                      UDISKS2_BUS, 
+                                                      UDISKS2_PATH);
+   proxy = eldbus_proxy_get(_places_ud2_object_manager, 
+                            ELDBUS_FDO_INTERFACE_OBJECT_MANAGER);
+   // NOTE: proxy will be automatically deleted on obj deletion
+   
+   // request all the objects managed by the ObjectManager
+   eldbus_proxy_call(proxy, "GetManagedObjects",
+                     _places_ud2_get_managed_objects_cb, NULL, -1, "");
+
+   // connect the ObjectManager InterfacesAdded/Removed signal handlers
+   eldbus_proxy_signal_handler_add(proxy, "InterfacesAdded",
+                                  _places_ud2_interfaces_added_cb, NULL);
+   eldbus_proxy_signal_handler_add(proxy, "InterfacesRemoved",
+                                  _places_ud2_interfaces_removed_cb, NULL);
+}
+
+
+/* Callback for the DBus ObjectManager method 'GetManagedObjects' */
+static void 
+_places_ud2_get_managed_objects_cb(void *data, const Eldbus_Message *msg, 
Eldbus_Pending *pending)
+{
+   Eldbus_Message_Iter *objs_array, *obj_entry;
+   Eldbus_Message_Iter *ifaces_array;
+   const char *obj_path;
+
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   printf("PLACES: GetManagedObjects\n");
+   if (!eldbus_message_arguments_get(msg, "a{oa{sa{sv}}}", &objs_array))
+     return;
+   
+   while (eldbus_message_iter_get_and_next(objs_array, 'e', &obj_entry))
+   {
+      if (eldbus_message_iter_arguments_get(obj_entry, "oa{sa{sv}}", 
+                                            &obj_path, &ifaces_array))
+      {
+         // we are only interested at block_device objects
+         if (eina_str_has_prefix(obj_path, UDISKS2_BLOCK_PREFIX))
+            _places_ud2_read_block_ifaces(obj_path, ifaces_array, EINA_TRUE);
+      }
+   }
+}
+
+
+/* Callback for the ObjectManager signal 'InterfacesAdded' */
+static void
+_places_ud2_interfaces_added_cb(void *data, const Eldbus_Message *msg)
+{
+   const char *obj_path;
+   Eldbus_Message_Iter *ifaces_array;
+
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   if (eldbus_message_arguments_get(msg, "oa{sa{sv}}", &obj_path, 
&ifaces_array))
+   {
+      printf("PLACES: InterfacesAdded on obj: %s\n", obj_path);
+      // we are only interested at block_device objects
+      if (eina_str_has_prefix(obj_path, UDISKS2_BLOCK_PREFIX))
+         _places_ud2_read_block_ifaces(obj_path, ifaces_array, EINA_FALSE);
+   }
+}
+
+
+/* Callback for the ObjectManager signal 'InterfacesRemoved' */
+static void
+_places_ud2_interfaces_removed_cb(void *data, const Eldbus_Message *msg)
+{
+   const char *obj_path, *iface_name;
+   Eldbus_Message_Iter *array_ifaces;
+   Volume *vol;
+
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   if (!eldbus_message_arguments_get(msg, "oas", &obj_path, &array_ifaces))
+     return;
+
+   while (eldbus_message_iter_get_and_next(array_ifaces, 's', &iface_name))
+   {
+      printf("PLACES: InterfaceRemoved obj:%s - iface:%s\n", obj_path, 
iface_name);
+      if (eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
+         if ((vol = places_volume_by_id_get(obj_path)))
+            places_volume_del(vol);
+   }
+}
+
+
+/* Callback for DBUS signal "PropertiesChanged" on the block_device objects */
+static void
+_places_ud2_block_props_changed_cb(void *data, const Eldbus_Message *msg)
+{
+   Volume *vol = data;
+   Eldbus_Message_Iter *changed_props, *invalidated_props, *props_entry, *var;
+   const char *iface_name, *prop_name;
+   char *mount_point = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN(vol);
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface_name, 
+                                     &changed_props, &invalidated_props))
+     return;
+   
+   printf("PLACES: PropertiesChanged  obj:%s - iface:%s\n", vol->id, 
iface_name);
+   
+   // atm we are only intrested in the mounted state (on the FS iface)
+   if (!eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
+      return;
+
+   while (eldbus_message_iter_get_and_next(changed_props, 'e', &props_entry))
+   {
+      if (!eldbus_message_iter_arguments_get(props_entry, "sv", &prop_name, 
&var))
+         continue;
+
+      printf("PLACES:   Changed prop: %s\n", prop_name);
+      if (eina_streq(prop_name, "MountPoints"))
+      {
+         Eldbus_Message_Iter *mounts_array, *ay;
+         if (eldbus_message_iter_arguments_get(var, "aay", &mounts_array))
+            if (eldbus_message_iter_arguments_get(mounts_array, "ay", &ay))
+               mount_point = _places_udisks2_string_convert(ay);
+         eina_stringshare_replace(&vol->mount_point, mount_point);
+         if (mount_point) free(mount_point);
+         _places_ud2_volume_finalize(vol);
+      }
+   }
+}
+
+
+/* Callback for DBUS signal "PropertiesChanged" on the drive objects */
+static void
+_places_ud2_drive_props_changed_cb(void *data, const Eldbus_Message *msg)
+{
+   Volume *vol = data;
+   Eldbus_Message_Iter *changed_props, *invalidated_props;
+   const char *iface_name;
+
+   EINA_SAFETY_ON_NULL_RETURN(vol);
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+
+   if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface_name, 
+                                     &changed_props, &invalidated_props))
+     return;
+   
+   printf("PLACES: PropertiesChanged  obj:%s - iface:%s\n", vol->id, 
iface_name);
+   if (eina_streq(iface_name, UDISKS2_DRIVE_IFACE))
+      _places_ud2_read_drive_properies(vol, changed_props);
+}
+
+
+/* Read all the ifaces for a block_device object */
+static void 
+_places_ud2_read_block_ifaces(const char *block_obj_path, Eldbus_Message_Iter 
*ifaces_array, Eina_Bool first_time)
+{
+   Eldbus_Message_Iter *iface_entry, *props_array, *props_entry, *chrarray, 
*var;
+   const char *iface_name, *key;
+   Eina_Bool bool_val;
+   
+   char *device = NULL;
+   char *mount_point = NULL;
+   const char *drive_obj_path = NULL;
+   const char *block_label = NULL;
+   const char *partition_name = NULL;
+   const char *fstype = NULL;
+   unsigned long long blockdevice_size = 0;
+   unsigned long long filesystem_size = 0;
+
+   printf("PLACES: Parsing block_device: %s\n", block_obj_path);
+   
+   while (eldbus_message_iter_get_and_next(ifaces_array, 'e', &iface_entry))
+   {
+      if (!eldbus_message_iter_arguments_get(iface_entry, "sa{sv}", 
&iface_name, &props_array))
+         continue;
+      
+      // printf("PLACES:    Iface: %s\n", iface_name);
+      while (eldbus_message_iter_get_and_next(props_array, 'e', &props_entry))
+      {
+         if (!eldbus_message_iter_arguments_get(props_entry, "sv", &key, &var))
+            continue;
+         // printf("PLACES:      Prop: %s\n", key);
+
+         /* block device with the following ifaces must be ignored */
+         if(eina_streq(iface_name, UDISKS2_PARTITIONTABLE_IFACE) ||
+            eina_streq(iface_name, UDISKS2_LOOP_IFACE) ||
+            eina_streq(iface_name, UDISKS2_SWAPSPACE_IFACE))
+         {
+            goto skip;
+         }
+
+         /* Block iface */
+         else if (eina_streq(iface_name, UDISKS2_BLOCK_IFACE)) 
+         {
+            // skip volumes with HintIgnore set
+            if (eina_streq(key, "HintIgnore"))
+            {
+               eldbus_message_iter_arguments_get(var, "b", &bool_val);
+               if (bool_val) goto skip;
+            }
+            else if (eina_streq(key, "Device"))
+            {
+               eldbus_message_iter_arguments_get(var, "ay", &chrarray);
+               device = _places_udisks2_string_convert(chrarray);
+            }
+            else if (eina_streq(key, "IdLabel"))
+               eldbus_message_iter_arguments_get(var, "s", &block_label);
+            else if (eina_streq(key, "IdType"))
+               eldbus_message_iter_arguments_get(var, "s", &fstype);
+            else if (eina_streq(key, "Size"))
+               eldbus_message_iter_arguments_get(var, "t", &blockdevice_size);
+            else if (eina_streq(key, "Drive"))
+               eldbus_message_iter_arguments_get(var, "o", &drive_obj_path);
+         }
+         
+         /* Partition iface */
+         else if (eina_streq(iface_name, UDISKS2_PARTITION_IFACE))
+         {
+            if (eina_streq(key, "Name"))
+               eldbus_message_iter_arguments_get(var, "s", &partition_name);
+         }
+
+         /* Filesystem iface */
+         else if (eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
+         {
+            if (eina_streq(key, "Size"))
+               eldbus_message_iter_arguments_get(var, "t", &filesystem_size);
+            else if (eina_streq(key, "MountPoints")) 
+            {
+               Eldbus_Message_Iter *inner_array, *chrarray;
+               if (eldbus_message_iter_arguments_get(var, "aay", &inner_array))
+                  if (eldbus_message_iter_arguments_get(inner_array, "ay", 
&chrarray))
+                     mount_point = _places_udisks2_string_convert(chrarray);
+            }
+         }
+         // else printf("PLACES: WARNING - Unknown iface: %s\n", iface_name);
+      }
+   }
+
+   printf("PLACES: Found device: %s\n", block_obj_path);
+
+   // create (or get an already created) places Volume
+   Volume *vol = _places_ud2_volume_add(block_obj_path, drive_obj_path, 
first_time);
+   EINA_SAFETY_ON_NULL_GOTO(vol, skip);
+
+   // choose the best label
+   if (partition_name && partition_name[0])
+      eina_stringshare_replace(&vol->label, partition_name);
+   else if (block_label && block_label[0])
+      eina_stringshare_replace(&vol->label, block_label);
+   else if (device && device[0])
+      eina_stringshare_replace(&vol->label, device);
+
+   // store all other props in the Volume
+   if (mount_point) eina_stringshare_replace(&vol->mount_point, mount_point);
+   if (device) eina_stringshare_replace(&vol->device, device);
+   if (fstype) eina_stringshare_replace(&vol->fstype, fstype);
+   vol->size = filesystem_size > 0 ? filesystem_size : blockdevice_size;
+
+   // now request the properties of the parent Drive
+   Places_UDisks2_Backend_Data *bdata = vol->backend_data;
+   if (bdata->drive_obj) 
+   {
+      Eldbus_Proxy *proxy;
+      proxy = eldbus_proxy_get(bdata->drive_obj, UDISKS2_DRIVE_IFACE);
+      eldbus_proxy_property_get_all(proxy, _places_ud2_drive_props_cb, vol);
+      eldbus_proxy_unref(proxy);
+   } 
+   else printf("PLACES: WARNING - NO DRIVE FOR OBJECT %s\n", block_obj_path);
+
+skip:
+   if (device) free(device);
+   if (mount_point) free(mount_point);
+}
+
+
+/* Callback for DBUS signal "PropertiesChanged" on the drive objects */
+static void
+_places_ud2_drive_props_cb(void *data, const Eldbus_Message *msg, 
Eldbus_Pending *pending)
+{
+   Volume *vol = data;
+   Eldbus_Message_Iter *props_array;
+
+   EINA_SAFETY_ON_NULL_RETURN(vol);
+   EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
+   EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "a{sv}", 
&props_array));
+   printf("PLACES: Drive properties for: %s\n", vol->id);
+   _places_ud2_read_drive_properies(vol, props_array);
+}
+
+
+/* Read the properties of a drive object (Drive ifaces) */
+static void
+_places_ud2_read_drive_properies(Volume *vol, Eldbus_Message_Iter* props_array)
+{
+   Eldbus_Message_Iter *prop_entry, *var;
+   const char *key = NULL;
+   const char *string = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN(vol);
+
+   while (eldbus_message_iter_get_and_next(props_array, 'e', &prop_entry))
+   {
+      if (!eldbus_message_iter_arguments_get(prop_entry, "sv", &key, &var))
+         continue;
+
+      if (eina_streq(key, "ConnectionBus"))
+      {
+         eldbus_message_iter_arguments_get(var, "s", &string);
+         eina_stringshare_replace(&vol->bus, string);
+      }
+      else if (eina_streq(key, "Serial"))
+      {
+         eldbus_message_iter_arguments_get(var, "s", &string);
+         eina_stringshare_replace(&vol->serial, string);
+      }
+      else if (eina_streq(key, "Vendor"))
+      {
+         eldbus_message_iter_arguments_get(var, "s", &string);
+         eina_stringshare_replace(&vol->vendor, string);
+      }
+      else if (eina_streq(key, "Model")) 
+      {
+         eldbus_message_iter_arguments_get(var, "s", &string);
+         eina_stringshare_replace(&vol->model, string);
+      }
+      else if (eina_streq(key, "Media"))
+      {
+         eldbus_message_iter_arguments_get(var, "s", &string);
+         eina_stringshare_replace(&vol->drive_type, string);
+      }
+      else if (eina_streq(key, "MediaAvailable"))
+         eldbus_message_iter_arguments_get(var, "b", &vol->media_available);
+      else if (eina_streq(key, "MediaRemovable"))
+         eldbus_message_iter_arguments_get(var, "b", &vol->removable);
+      else if (eina_streq(key, "Ejectable"))
+         eldbus_message_iter_arguments_get(var, "b", &vol->requires_eject);
+   }
+
+   _places_ud2_volume_finalize(vol);
+}
+
+
+/* Called after all properties has been readed */
+static void
+_places_ud2_volume_finalize(Volume *vol)
+{
+   Eina_Bool is_valid = EINA_TRUE;
+   printf("PLACES: Validating %s\n", vol->id);
+
+   // set mounted state
+   if (vol->mount_point && vol->mount_point[0])
+      vol->mounted = EINA_TRUE;
+   else
+      vol->mounted = EINA_FALSE;
+
+   // media must be available
+   if (!vol->media_available)
+   {
+      is_valid = EINA_FALSE;
+   }
+
+   if (is_valid != vol->valid)
+   {
+      // trigger a full redraw, is the only way to show/hide a new device
+      vol->valid = is_valid;
+      places_update_all_gadgets();
+   }
+
+   // the update is always needed to trigger auto_mount/auto_open
+   places_volume_update(vol);
+
+   places_print_volume(vol);  // TODO REMOVEME
+}
+
+
+/* Callback for mount(), umont() and eject() calls */
+static void
+_places_udisks2_task_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending 
*pending)
+{
+   const char *str;
+   Eina_Bool ret;
+
+   if (eldbus_message_error_get(msg, NULL, NULL))
+   {
+      ret = eldbus_message_arguments_get(msg, "s", &str);
+      e_util_dialog_internal(D_("Operation failed"),
+                             ret ? str : D_("Unknown error"));
+   }
+}
+
+
+static void
+_places_ud2_mount_func(Volume *vol, Eina_List *opts)
+{
+   Places_UDisks2_Backend_Data *bdata = vol->backend_data;
+   Eldbus_Message_Iter *iter, *array;
+   Eldbus_Message *msg;
+
+   EINA_SAFETY_ON_NULL_RETURN(bdata);
+
+   // Call the Mount(a{sv}) method on the Filesystem iface
+   msg = eldbus_object_method_call_new(bdata->block_obj, 
+                                       UDISKS2_FILESYSTEM_IFACE, "Mount");
+   iter = eldbus_message_iter_get(msg);
+   eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
+   eldbus_message_iter_container_close(iter, array);
+   eldbus_object_send(bdata->block_obj, msg, _places_udisks2_task_cb, vol, -1);
+   
+   // TODO options?? still needed??
+   // eldbus_message_iter_arguments_append(main_iter, "sas", vol->fstype, 
&array);
+   // Eina_List *l;
+   // const char *opt_txt;
+   // EINA_LIST_FOREACH(opts, l, opt_txt)
+   // {
+   //    // printf("  opt: '%s'\n", opt_txt);
+   //    eldbus_message_iter_basic_append(array, 's', opt_txt);
+   // }
+   // eldbus_message_iter_container_close(main_iter, array);
+}
+
+
+static void
+_places_ud2_unmount_func(Volume *vol, Eina_List *opts)
+{
+   Places_UDisks2_Backend_Data *bdata = vol->backend_data;
+   Eldbus_Message_Iter *iter, *array;
+   Eldbus_Message *msg;
+
+   EINA_SAFETY_ON_NULL_RETURN(bdata);
+
+   // Call the Unmount(a{sv}) method on the Filesystem iface
+   msg = eldbus_object_method_call_new(bdata->block_obj, 
+                                       UDISKS2_FILESYSTEM_IFACE, "Unmount");
+   iter = eldbus_message_iter_get(msg);
+   eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
+   eldbus_message_iter_container_close(iter, array);
+   eldbus_object_send(bdata->block_obj, msg, _places_udisks2_task_cb, vol, -1);
+}
+
+
+static void
+_places_ud2_eject_func(Volume *vol, Eina_List *opts)
+{
+   Places_UDisks2_Backend_Data *bdata = vol->backend_data;
+   Eldbus_Message_Iter *iter, *array;
+   Eldbus_Message *msg;
+
+   EINA_SAFETY_ON_NULL_RETURN(bdata);
+
+   // Call the Eject(a{sv}) method on the drive object (Drive iface)
+   msg = eldbus_object_method_call_new(bdata->drive_obj, 
+                                       UDISKS2_DRIVE_IFACE, "Eject");
+   iter = eldbus_message_iter_get(msg);
+   eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
+   eldbus_message_iter_container_close(iter, array);
+   eldbus_object_send(bdata->drive_obj, msg, _places_udisks2_task_cb, vol, -1);
+}
+
+
+#endif
diff --git a/src/e_mod_udisks2.h b/src/e_mod_udisks2.h
new file mode 100644
index 0000000..1b05421
--- /dev/null
+++ b/src/e_mod_udisks2.h
@@ -0,0 +1,8 @@
+#ifndef E_MOD_PLACES_UDISKS2_H
+#define E_MOD_PLACES_UDISKS2_H
+
+void places_udisks2_init(void);
+void places_udisks2_shutdown(void);
+
+#endif
+
diff --git a/src/meson.build b/src/meson.build
index 7a576b0..4c8798d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -5,6 +5,7 @@ module = shared_module(
    'e_mod_config.c',
    'e_mod_places.c',
 
+   'e_mod_udisks2.c',
    'e_mod_udisks_eldbus.c',
    'e_mod_mount.c',
    'e_mod_eeze.c',

-- 


Reply via email to