summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Andreoli <dave@gurumeditation.it>2021-04-18 13:38:58 +0200
committerDave Andreoli <dave@gurumeditation.it>2021-04-18 13:38:58 +0200
commit795a9140620d3e93ff18faae5414049b971ef53b (patch)
tree1b3b4f7fb88bdd53e7687d81624a7b4473926e26
parentefe3ca51151cc6c79f019f53ddfa5c5a9b8d41b9 (diff)
Finally implemented UDisks2 backend
-rw-r--r--meson.build19
-rw-r--r--meson_options.txt8
-rw-r--r--src/e_mod_places.c13
-rw-r--r--src/e_mod_places.h5
-rw-r--r--src/e_mod_udisks2.c645
-rw-r--r--src/e_mod_udisks2.h8
-rw-r--r--src/meson.build1
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)
28config_dir = include_directories('.') 28config_dir = include_directories('.')
29 29
30 30
31#### Udisks2 support ####
32if get_option('udisks2') == true
33 dependency('udisks2', required: true, version: '>= 2.7.2')
34 config_h.set('PLACES_HAVE_UDISKS2', 1)
35endif
36
37
31#### Udisks1 support #### 38#### Udisks1 support ####
32if get_option('udisks') == true 39if get_option('udisks') == true
33 dependency('udisks', required: true) 40 dependency('udisks', required: true)
@@ -84,3 +91,15 @@ custom_target('e-module-places.edj',
84 install_dir: mod_install_dir, 91 install_dir: mod_install_dir,
85 install : true 92 install : true
86 ) 93 )
94
95
96#### Report ####
97if meson.version().version_compare('>=0.53')
98 summary({'install': lib_install_dir,
99 }, section: 'Directories')
100 summary({'udisks2': get_option('udisks2'),
101 'udisks1': get_option('udisks'),
102 'mount': get_option('mount'),
103 'eeze': get_option('eeze'),
104 }, section: 'Backends', bool_yn: true)
105endif \ 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 @@
1option('udisks', 1option('udisks2',
2 type: 'boolean', 2 type: 'boolean',
3 value: true, 3 value: true,
4 description: 'enable udisks1 support (default=true)') 4 description: 'enable udisks2 support (default=true)')
5option('udisks',
6 type: 'boolean',
7 value: false,
8 description: 'enable udisks1 support (default=false)')
5option('mount', 9option('mount',
6 type: 'boolean', 10 type: 'boolean',
7 value: true, 11 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 @@
12# include "e_mod_udisks_eldbus.h" 12# include "e_mod_udisks_eldbus.h"
13#endif 13#endif
14 14
15#ifdef PLACES_HAVE_UDISKS2
16# include "e_mod_udisks2.h"
17#endif
18
15#ifdef PLACES_HAVE_MOUNT 19#ifdef PLACES_HAVE_MOUNT
16# include "e_mod_mount.h" 20# include "e_mod_mount.h"
17#endif 21#endif
@@ -67,6 +71,9 @@ places_init(void)
67#ifdef PLACES_HAVE_UDISKS 71#ifdef PLACES_HAVE_UDISKS
68 places_udisks_eldbus_init(); 72 places_udisks_eldbus_init();
69#endif 73#endif
74#ifdef PLACES_HAVE_UDISKS2
75 places_udisks2_init();
76#endif
70#ifdef PLACES_HAVE_MOUNT 77#ifdef PLACES_HAVE_MOUNT
71 places_mount_init(); 78 places_mount_init();
72#endif 79#endif
@@ -118,6 +125,9 @@ places_shutdown(void)
118#ifdef PLACES_HAVE_UDISKS 125#ifdef PLACES_HAVE_UDISKS
119 places_udisks_eldbus_shutdown(); 126 places_udisks_eldbus_shutdown();
120#endif 127#endif
128#ifdef PLACES_HAVE_UDISKS2
129 places_udisks2_shutdown();
130#endif
121#ifdef PLACES_HAVE_MOUNT 131#ifdef PLACES_HAVE_MOUNT
122 places_mount_shutdown(); 132 places_mount_shutdown();
123#endif 133#endif
@@ -343,6 +353,7 @@ places_fill_box(Evas_Object *main, Eina_Bool horiz)
343 icon = e_icon_add(evas_object_evas_get(main)); 353 icon = e_icon_add(evas_object_evas_get(main));
344 f1 = f2 = f3 = NULL; 354 f1 = f2 = f3 = NULL;
345 /* optical discs */ 355 /* optical discs */
356 // TODO more icons: dvd, blueray....
346 if (!strcmp(vol->drive_type, "cdrom") || 357 if (!strcmp(vol->drive_type, "cdrom") ||
347 !strcmp(vol->drive_type, "optical_cd")) 358 !strcmp(vol->drive_type, "optical_cd"))
348 { 359 {
@@ -519,6 +530,7 @@ places_print_volume(Volume *v)
519 const char *size, *free; 530 const char *size, *free;
520 531
521 printf("Got volume %s (totals: %d)\n", v->id, eina_list_count(volumes)); 532 printf("Got volume %s (totals: %d)\n", v->id, eina_list_count(volumes));
533 printf(" valid: %d\n", v->valid);
522 printf(" label: %s\n",v->label); 534 printf(" label: %s\n",v->label);
523 printf(" mounted: %d\n", v->mounted); 535 printf(" mounted: %d\n", v->mounted);
524 printf(" m_point: %s\n", v->mount_point); 536 printf(" m_point: %s\n", v->mount_point);
@@ -531,6 +543,7 @@ places_print_volume(Volume *v)
531 printf(" serial: %s\n", v->serial); 543 printf(" serial: %s\n", v->serial);
532 printf(" removable: %d\n", v->removable); 544 printf(" removable: %d\n", v->removable);
533 printf(" requires eject: %d\n", v->requires_eject); 545 printf(" requires eject: %d\n", v->requires_eject);
546 printf(" media_available: %d\n", v->media_available);
534 size = _places_human_size_get(v->size); 547 size = _places_human_size_get(v->size);
535 free = _places_human_size_get(v->free_space); 548 free = _places_human_size_get(v->free_space);
536 printf(" size: %s\n", size); 549 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
28 const char *model; 28 const char *model;
29 const char *vendor; 29 const char *vendor;
30 const char *serial; 30 const char *serial;
31 unsigned char removable; 31 Eina_Bool removable;
32 unsigned char requires_eject; 32 Eina_Bool requires_eject;
33 Eina_Bool media_available;
33 Eina_Bool unlocked; 34 Eina_Bool unlocked;
34 Eina_Bool encrypted; 35 Eina_Bool encrypted;
35 36
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 @@
1
2#include "places_config.h"
3
4
5#ifdef PLACES_HAVE_UDISKS2
6
7#include <e.h>
8#include <Eldbus.h>
9#include "e_mod_main.h"
10#include "e_mod_places.h"
11
12
13/* UDisks2 defines */
14#define UDISKS2_BUS "org.freedesktop.UDisks2"
15#define UDISKS2_PATH "/org/freedesktop/UDisks2"
16
17#define UDISKS2_MANAGER_PATH "/org/freedesktop/UDisks2/Manager"
18#define UDISKS2_MANAGER_IFACE "org.freedesktop.UDisks2.Manager"
19
20#define UDISKS2_BLOCK_IFACE "org.freedesktop.UDisks2.Block"
21#define UDISKS2_PARTITION_IFACE "org.freedesktop.UDisks2.Partition"
22#define UDISKS2_FILESYSTEM_IFACE "org.freedesktop.UDisks2.Filesystem"
23#define UDISKS2_DRIVE_IFACE "org.freedesktop.UDisks2.Drive"
24#define UDISKS2_PARTITIONTABLE_IFACE "org.freedesktop.UDisks2.PartitionTable"
25#define UDISKS2_LOOP_IFACE "org.freedesktop.UDisks2.Loop"
26#define UDISKS2_SWAPSPACE_IFACE "org.freedesktop.UDisks2.Swapspace"
27
28#define UDISKS2_BLOCK_PREFIX "/org/freedesktop/UDisks2/block_devices/"
29#define UDISKS2_DRIVE_PREFIX "/org/freedesktop/UDisks2/drives/"
30
31
32/* Local backend data */
33typedef struct Places_UDisks2_Backend_Data
34{
35 Eldbus_Object *block_obj;
36 Eldbus_Object *drive_obj;
37} Places_UDisks2_Backend_Data;
38
39
40/* Local Function Prototypes */
41static void _places_ud2_name_start(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending);
42
43static void _places_ud2_get_managed_objects_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending);
44static void _places_ud2_interfaces_added_cb(void *data, const Eldbus_Message *msg);
45static void _places_ud2_interfaces_removed_cb(void *data, const Eldbus_Message *msg);
46static void _places_ud2_block_props_changed_cb(void *data, const Eldbus_Message *msg);
47static void _places_ud2_drive_props_changed_cb(void *data, const Eldbus_Message *msg);
48
49static void _places_ud2_read_block_ifaces(const char *obj_path, Eldbus_Message_Iter *ifaces_array, Eina_Bool first_time);
50static void _places_ud2_read_drive_properies(Volume *vol, Eldbus_Message_Iter* props_array);
51static void _places_ud2_drive_props_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending);
52
53static Volume* _places_ud2_volume_add(const char *block_obj_path, const char* drive_obj_path, Eina_Bool first_time);
54static void _places_ud2_volume_finalize(Volume *vol);
55static void _places_ud2_mount_func(Volume *vol, Eina_List *opts);
56static void _places_ud2_unmount_func(Volume *vol, Eina_List *opts);
57static void _places_ud2_eject_func(Volume *vol, Eina_List *opts);
58static void _places_ud2_volume_free_func(Volume *vol);
59
60
61/* Local Variables */
62static Eldbus_Connection *_places_ud2_conn = NULL;
63static Eldbus_Object *_places_ud2_object_manager = NULL;
64
65
66Eina_Bool
67places_udisks2_init(void)
68{
69 printf("PLACES: udisks2: init()\n");
70
71 EINA_SAFETY_ON_FALSE_RETURN_VAL(eldbus_init(), EINA_FALSE);
72
73 _places_ud2_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
74 if (!_places_ud2_conn)
75 {
76 printf("PLACES: udisks2: Error connecting to system bus.\n");
77 return EINA_FALSE;
78 }
79
80 eldbus_name_start(_places_ud2_conn, UDISKS2_BUS, 0,
81 _places_ud2_name_start, NULL);
82 return EINA_TRUE;
83}
84
85
86void
87places_udisks2_shutdown(void)
88{
89 printf("PLACES: udisks2: shutdown()\n");
90 E_FREE_FUNC(_places_ud2_object_manager, eldbus_object_unref);
91 E_FREE_FUNC(_places_ud2_conn, eldbus_connection_unref);
92 eldbus_shutdown();
93}
94
95
96static Volume*
97_places_ud2_volume_add(const char *block_obj_path, const char* drive_obj_path, Eina_Bool first_time)
98{
99 Places_UDisks2_Backend_Data *bdata;
100 Volume *vol;
101
102 // return a previously created Volume
103 vol = places_volume_by_id_get(block_obj_path);
104 if (vol) return vol;
105
106 // create the backend data struct
107 bdata = E_NEW(Places_UDisks2_Backend_Data, 1);
108 if (!bdata) return NULL;
109
110 // create the Eldbus block_device object
111 bdata->block_obj = eldbus_object_get(_places_ud2_conn, UDISKS2_BUS,
112 block_obj_path);
113 if (!bdata->block_obj) return NULL;
114
115 // create the Eldbus drive object (if exists)
116 if (drive_obj_path && drive_obj_path[0] && !eina_streq(drive_obj_path, "/"))
117 {
118 bdata->drive_obj = eldbus_object_get(_places_ud2_conn, UDISKS2_BUS,
119 drive_obj_path);
120 if (!bdata->drive_obj) return NULL;
121 }
122
123 // create the places Volume
124 vol = places_volume_add(block_obj_path, first_time);
125 if (!vol) return NULL;
126 vol->backend_data = bdata;
127 vol->mount_func = _places_ud2_mount_func;
128 vol->unmount_func = _places_ud2_unmount_func;
129 vol->eject_func = _places_ud2_eject_func;
130 vol->free_func = _places_ud2_volume_free_func;
131
132 // Get notifications on object change properties
133 eldbus_object_signal_handler_add(bdata->block_obj,
134 ELDBUS_FDO_INTERFACE_PROPERTIES,
135 "PropertiesChanged",
136 _places_ud2_block_props_changed_cb, vol);
137 if (bdata->drive_obj)
138 eldbus_object_signal_handler_add(bdata->drive_obj,
139 ELDBUS_FDO_INTERFACE_PROPERTIES,
140 "PropertiesChanged",
141 _places_ud2_drive_props_changed_cb, vol);
142
143 return vol;
144}
145
146
147static void
148_places_ud2_volume_free_func(Volume *vol)
149{
150 Places_UDisks2_Backend_Data *bdata = vol->backend_data;
151 if (bdata)
152 {
153 E_FREE_FUNC(bdata->block_obj, eldbus_object_unref);
154 E_FREE_FUNC(bdata->drive_obj, eldbus_object_unref);
155 E_FREE(vol->backend_data);
156 }
157}
158
159
160/* Some strings in UDisks2 are exposed as array of char (ay), need to convert */
161static char*
162_places_udisks2_string_convert(Eldbus_Message_Iter *ay)
163{
164 char *p, buf[PATH_MAX] = {0};
165 p = buf;
166 while (eldbus_message_iter_get_and_next(ay, 'y', p))
167 {
168 if (!p) break;
169 p++;
170 }
171 // printf("PLACES: stupid string %s\n", str);
172 return strdup(buf);
173}
174
175
176/* The Udisks2 service is up and running, setup the ObjectManager */
177static void
178_places_ud2_name_start(void *data, const Eldbus_Message *msg,
179 Eldbus_Pending *pending)
180{
181 Eldbus_Proxy *proxy;
182
183 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
184
185 // get the UDisks2 ObjectManager object
186 _places_ud2_object_manager = eldbus_object_get(_places_ud2_conn,
187 UDISKS2_BUS,
188 UDISKS2_PATH);
189 proxy = eldbus_proxy_get(_places_ud2_object_manager,
190 ELDBUS_FDO_INTERFACE_OBJECT_MANAGER);
191 // NOTE: proxy will be automatically deleted on obj deletion
192
193 // request all the objects managed by the ObjectManager
194 eldbus_proxy_call(proxy, "GetManagedObjects",
195 _places_ud2_get_managed_objects_cb, NULL, -1, "");
196
197 // connect the ObjectManager InterfacesAdded/Removed signal handlers
198 eldbus_proxy_signal_handler_add(proxy, "InterfacesAdded",
199 _places_ud2_interfaces_added_cb, NULL);
200 eldbus_proxy_signal_handler_add(proxy, "InterfacesRemoved",
201 _places_ud2_interfaces_removed_cb, NULL);
202}
203
204
205/* Callback for the DBus ObjectManager method 'GetManagedObjects' */
206static void
207_places_ud2_get_managed_objects_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
208{
209 Eldbus_Message_Iter *objs_array, *obj_entry;
210 Eldbus_Message_Iter *ifaces_array;
211 const char *obj_path;
212
213 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
214
215 printf("PLACES: GetManagedObjects\n");
216 if (!eldbus_message_arguments_get(msg, "a{oa{sa{sv}}}", &objs_array))
217 return;
218
219 while (eldbus_message_iter_get_and_next(objs_array, 'e', &obj_entry))
220 {
221 if (eldbus_message_iter_arguments_get(obj_entry, "oa{sa{sv}}",
222 &obj_path, &ifaces_array))
223 {
224 // we are only interested at block_device objects
225 if (eina_str_has_prefix(obj_path, UDISKS2_BLOCK_PREFIX))
226 _places_ud2_read_block_ifaces(obj_path, ifaces_array, EINA_TRUE);
227 }
228 }
229}
230
231
232/* Callback for the ObjectManager signal 'InterfacesAdded' */
233static void
234_places_ud2_interfaces_added_cb(void *data, const Eldbus_Message *msg)
235{
236 const char *obj_path;
237 Eldbus_Message_Iter *ifaces_array;
238
239 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
240
241 if (eldbus_message_arguments_get(msg, "oa{sa{sv}}", &obj_path, &ifaces_array))
242 {
243 printf("PLACES: InterfacesAdded on obj: %s\n", obj_path);
244 // we are only interested at block_device objects
245 if (eina_str_has_prefix(obj_path, UDISKS2_BLOCK_PREFIX))
246 _places_ud2_read_block_ifaces(obj_path, ifaces_array, EINA_FALSE);
247 }
248}
249
250
251/* Callback for the ObjectManager signal 'InterfacesRemoved' */
252static void
253_places_ud2_interfaces_removed_cb(void *data, const Eldbus_Message *msg)
254{
255 const char *obj_path, *iface_name;
256 Eldbus_Message_Iter *array_ifaces;
257 Volume *vol;
258
259 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
260
261 if (!eldbus_message_arguments_get(msg, "oas", &obj_path, &array_ifaces))
262 return;
263
264 while (eldbus_message_iter_get_and_next(array_ifaces, 's', &iface_name))
265 {
266 printf("PLACES: InterfaceRemoved obj:%s - iface:%s\n", obj_path, iface_name);
267 if (eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
268 if ((vol = places_volume_by_id_get(obj_path)))
269 places_volume_del(vol);
270 }
271}
272
273
274/* Callback for DBUS signal "PropertiesChanged" on the block_device objects */
275static void
276_places_ud2_block_props_changed_cb(void *data, const Eldbus_Message *msg)
277{
278 Volume *vol = data;
279 Eldbus_Message_Iter *changed_props, *invalidated_props, *props_entry, *var;
280 const char *iface_name, *prop_name;
281 char *mount_point = NULL;
282
283 EINA_SAFETY_ON_NULL_RETURN(vol);
284 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
285
286 if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface_name,
287 &changed_props, &invalidated_props))
288 return;
289
290 printf("PLACES: PropertiesChanged obj:%s - iface:%s\n", vol->id, iface_name);
291
292 // atm we are only intrested in the mounted state (on the FS iface)
293 if (!eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
294 return;
295
296 while (eldbus_message_iter_get_and_next(changed_props, 'e', &props_entry))
297 {
298 if (!eldbus_message_iter_arguments_get(props_entry, "sv", &prop_name, &var))
299 continue;
300
301 printf("PLACES: Changed prop: %s\n", prop_name);
302 if (eina_streq(prop_name, "MountPoints"))
303 {
304 Eldbus_Message_Iter *mounts_array, *ay;
305 if (eldbus_message_iter_arguments_get(var, "aay", &mounts_array))
306 if (eldbus_message_iter_arguments_get(mounts_array, "ay", &ay))
307 mount_point = _places_udisks2_string_convert(ay);
308 eina_stringshare_replace(&vol->mount_point, mount_point);
309 if (mount_point) free(mount_point);
310 _places_ud2_volume_finalize(vol);
311 }
312 }
313}
314
315
316/* Callback for DBUS signal "PropertiesChanged" on the drive objects */
317static void
318_places_ud2_drive_props_changed_cb(void *data, const Eldbus_Message *msg)
319{
320 Volume *vol = data;
321 Eldbus_Message_Iter *changed_props, *invalidated_props;
322 const char *iface_name;
323
324 EINA_SAFETY_ON_NULL_RETURN(vol);
325 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
326
327 if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface_name,
328 &changed_props, &invalidated_props))
329 return;
330
331 printf("PLACES: PropertiesChanged obj:%s - iface:%s\n", vol->id, iface_name);
332 if (eina_streq(iface_name, UDISKS2_DRIVE_IFACE))
333 _places_ud2_read_drive_properies(vol, changed_props);
334}
335
336
337/* Read all the ifaces for a block_device object */
338static void
339_places_ud2_read_block_ifaces(const char *block_obj_path, Eldbus_Message_Iter *ifaces_array, Eina_Bool first_time)
340{
341 Eldbus_Message_Iter *iface_entry, *props_array, *props_entry, *chrarray, *var;
342 const char *iface_name, *key;
343 Eina_Bool bool_val;
344
345 char *device = NULL;
346 char *mount_point = NULL;
347 const char *drive_obj_path = NULL;
348 const char *block_label = NULL;
349 const char *partition_name = NULL;
350 const char *fstype = NULL;
351 unsigned long long blockdevice_size = 0;
352 unsigned long long filesystem_size = 0;
353
354 printf("PLACES: Parsing block_device: %s\n", block_obj_path);
355
356 while (eldbus_message_iter_get_and_next(ifaces_array, 'e', &iface_entry))
357 {
358 if (!eldbus_message_iter_arguments_get(iface_entry, "sa{sv}", &iface_name, &props_array))
359 continue;
360
361 // printf("PLACES: Iface: %s\n", iface_name);
362 while (eldbus_message_iter_get_and_next(props_array, 'e', &props_entry))
363 {
364 if (!eldbus_message_iter_arguments_get(props_entry, "sv", &key, &var))
365 continue;
366 // printf("PLACES: Prop: %s\n", key);
367
368 /* block device with the following ifaces must be ignored */
369 if(eina_streq(iface_name, UDISKS2_PARTITIONTABLE_IFACE) ||
370 eina_streq(iface_name, UDISKS2_LOOP_IFACE) ||
371 eina_streq(iface_name, UDISKS2_SWAPSPACE_IFACE))
372 {
373 goto skip;
374 }
375
376 /* Block iface */
377 else if (eina_streq(iface_name, UDISKS2_BLOCK_IFACE))
378 {
379 // skip volumes with HintIgnore set
380 if (eina_streq(key, "HintIgnore"))
381 {
382 eldbus_message_iter_arguments_get(var, "b", &bool_val);
383 if (bool_val) goto skip;
384 }
385 else if (eina_streq(key, "Device"))
386 {
387 eldbus_message_iter_arguments_get(var, "ay", &chrarray);
388 device = _places_udisks2_string_convert(chrarray);
389 }
390 else if (eina_streq(key, "IdLabel"))
391 eldbus_message_iter_arguments_get(var, "s", &block_label);
392 else if (eina_streq(key, "IdType"))
393 eldbus_message_iter_arguments_get(var, "s", &fstype);
394 else if (eina_streq(key, "Size"))
395 eldbus_message_iter_arguments_get(var, "t", &blockdevice_size);
396 else if (eina_streq(key, "Drive"))
397 eldbus_message_iter_arguments_get(var, "o", &drive_obj_path);
398 }
399
400 /* Partition iface */
401 else if (eina_streq(iface_name, UDISKS2_PARTITION_IFACE))
402 {
403 if (eina_streq(key, "Name"))
404 eldbus_message_iter_arguments_get(var, "s", &partition_name);
405 }
406
407 /* Filesystem iface */
408 else if (eina_streq(iface_name, UDISKS2_FILESYSTEM_IFACE))
409 {
410 if (eina_streq(key, "Size"))
411 eldbus_message_iter_arguments_get(var, "t", &filesystem_size);
412 else if (eina_streq(key, "MountPoints"))
413 {
414 Eldbus_Message_Iter *inner_array, *chrarray;
415 if (eldbus_message_iter_arguments_get(var, "aay", &inner_array))
416 if (eldbus_message_iter_arguments_get(inner_array, "ay", &chrarray))
417 mount_point = _places_udisks2_string_convert(chrarray);
418 }
419 }
420 // else printf("PLACES: WARNING - Unknown iface: %s\n", iface_name);
421 }
422 }
423
424 printf("PLACES: Found device: %s\n", block_obj_path);
425
426 // create (or get an already created) places Volume
427 Volume *vol = _places_ud2_volume_add(block_obj_path, drive_obj_path, first_time);
428 EINA_SAFETY_ON_NULL_GOTO(vol, skip);
429
430 // choose the best label
431 if (partition_name && partition_name[0])
432 eina_stringshare_replace(&vol->label, partition_name);
433 else if (block_label && block_label[0])
434 eina_stringshare_replace(&vol->label, block_label);
435 else if (device && device[0])
436 eina_stringshare_replace(&vol->label, device);
437
438 // store all other props in the Volume
439 if (mount_point) eina_stringshare_replace(&vol->mount_point, mount_point);
440 if (device) eina_stringshare_replace(&vol->device, device);
441 if (fstype) eina_stringshare_replace(&vol->fstype, fstype);
442 vol->size = filesystem_size > 0 ? filesystem_size : blockdevice_size;
443
444 // now request the properties of the parent Drive
445 Places_UDisks2_Backend_Data *bdata = vol->backend_data;
446 if (bdata->drive_obj)
447 {
448 Eldbus_Proxy *proxy;
449 proxy = eldbus_proxy_get(bdata->drive_obj, UDISKS2_DRIVE_IFACE);
450 eldbus_proxy_property_get_all(proxy, _places_ud2_drive_props_cb, vol);
451 eldbus_proxy_unref(proxy);
452 }
453 else printf("PLACES: WARNING - NO DRIVE FOR OBJECT %s\n", block_obj_path);
454
455skip:
456 if (device) free(device);
457 if (mount_point) free(mount_point);
458}
459
460
461/* Callback for DBUS signal "PropertiesChanged" on the drive objects */
462static void
463_places_ud2_drive_props_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
464{
465 Volume *vol = data;
466 Eldbus_Message_Iter *props_array;
467
468 EINA_SAFETY_ON_NULL_RETURN(vol);
469 EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL));
470 EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "a{sv}", &props_array));
471 printf("PLACES: Drive properties for: %s\n", vol->id);
472 _places_ud2_read_drive_properies(vol, props_array);
473}
474
475
476/* Read the properties of a drive object (Drive ifaces) */
477static void
478_places_ud2_read_drive_properies(Volume *vol, Eldbus_Message_Iter* props_array)
479{
480 Eldbus_Message_Iter *prop_entry, *var;
481 const char *key = NULL;
482 const char *string = NULL;
483
484 EINA_SAFETY_ON_NULL_RETURN(vol);
485
486 while (eldbus_message_iter_get_and_next(props_array, 'e', &prop_entry))
487 {
488 if (!eldbus_message_iter_arguments_get(prop_entry, "sv", &key, &var))
489 continue;
490
491 if (eina_streq(key, "ConnectionBus"))
492 {
493 eldbus_message_iter_arguments_get(var, "s", &string);
494 eina_stringshare_replace(&vol->bus, string);
495 }
496 else if (eina_streq(key, "Serial"))
497 {
498 eldbus_message_iter_arguments_get(var, "s", &string);
499 eina_stringshare_replace(&vol->serial, string);
500 }
501 else if (eina_streq(key, "Vendor"))
502 {
503 eldbus_message_iter_arguments_get(var, "s", &string);
504 eina_stringshare_replace(&vol->vendor, string);
505 }
506 else if (eina_streq(key, "Model"))
507 {
508 eldbus_message_iter_arguments_get(var, "s", &string);
509 eina_stringshare_replace(&vol->model, string);
510 }
511 else if (eina_streq(key, "Media"))
512 {
513 eldbus_message_iter_arguments_get(var, "s", &string);
514 eina_stringshare_replace(&vol->drive_type, string);
515 }
516 else if (eina_streq(key, "MediaAvailable"))
517 eldbus_message_iter_arguments_get(var, "b", &vol->media_available);
518 else if (eina_streq(key, "MediaRemovable"))
519 eldbus_message_iter_arguments_get(var, "b", &vol->removable);
520 else if (eina_streq(key, "Ejectable"))
521 eldbus_message_iter_arguments_get(var, "b", &vol->requires_eject);
522 }
523
524 _places_ud2_volume_finalize(vol);
525}
526
527
528/* Called after all properties has been readed */
529static void
530_places_ud2_volume_finalize(Volume *vol)
531{
532 Eina_Bool is_valid = EINA_TRUE;
533 printf("PLACES: Validating %s\n", vol->id);
534
535 // set mounted state
536 if (vol->mount_point && vol->mount_point[0])
537 vol->mounted = EINA_TRUE;
538 else
539 vol->mounted = EINA_FALSE;
540
541 // media must be available
542 if (!vol->media_available)
543 {
544 is_valid = EINA_FALSE;
545 }
546
547 if (is_valid != vol->valid)
548 {
549 // trigger a full redraw, is the only way to show/hide a new device
550 vol->valid = is_valid;
551 places_update_all_gadgets();
552 }
553
554 // the update is always needed to trigger auto_mount/auto_open
555 places_volume_update(vol);
556
557 places_print_volume(vol); // TODO REMOVEME
558}
559
560
561/* Callback for mount(), umont() and eject() calls */
562static void
563_places_udisks2_task_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
564{
565 const char *str;
566 Eina_Bool ret;
567
568 if (eldbus_message_error_get(msg, NULL, NULL))
569 {
570 ret = eldbus_message_arguments_get(msg, "s", &str);
571 e_util_dialog_internal(D_("Operation failed"),
572 ret ? str : D_("Unknown error"));
573 }
574}
575
576
577static void
578_places_ud2_mount_func(Volume *vol, Eina_List *opts)
579{
580 Places_UDisks2_Backend_Data *bdata = vol->backend_data;
581 Eldbus_Message_Iter *iter, *array;
582 Eldbus_Message *msg;
583
584 EINA_SAFETY_ON_NULL_RETURN(bdata);
585
586 // Call the Mount(a{sv}) method on the Filesystem iface
587 msg = eldbus_object_method_call_new(bdata->block_obj,
588 UDISKS2_FILESYSTEM_IFACE, "Mount");
589 iter = eldbus_message_iter_get(msg);
590 eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
591 eldbus_message_iter_container_close(iter, array);
592 eldbus_object_send(bdata->block_obj, msg, _places_udisks2_task_cb, vol, -1);
593
594 // TODO options?? still needed??
595 // eldbus_message_iter_arguments_append(main_iter, "sas", vol->fstype, &array);
596 // Eina_List *l;
597 // const char *opt_txt;
598 // EINA_LIST_FOREACH(opts, l, opt_txt)
599 // {
600 // // printf(" opt: '%s'\n", opt_txt);
601 // eldbus_message_iter_basic_append(array, 's', opt_txt);
602 // }
603 // eldbus_message_iter_container_close(main_iter, array);
604}
605
606
607static void
608_places_ud2_unmount_func(Volume *vol, Eina_List *opts)
609{
610 Places_UDisks2_Backend_Data *bdata = vol->backend_data;
611 Eldbus_Message_Iter *iter, *array;
612 Eldbus_Message *msg;
613
614 EINA_SAFETY_ON_NULL_RETURN(bdata);
615
616 // Call the Unmount(a{sv}) method on the Filesystem iface
617 msg = eldbus_object_method_call_new(bdata->block_obj,
618 UDISKS2_FILESYSTEM_IFACE, "Unmount");
619 iter = eldbus_message_iter_get(msg);
620 eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
621 eldbus_message_iter_container_close(iter, array);
622 eldbus_object_send(bdata->block_obj, msg, _places_udisks2_task_cb, vol, -1);
623}
624
625
626static void
627_places_ud2_eject_func(Volume *vol, Eina_List *opts)
628{
629 Places_UDisks2_Backend_Data *bdata = vol->backend_data;
630 Eldbus_Message_Iter *iter, *array;
631 Eldbus_Message *msg;
632
633 EINA_SAFETY_ON_NULL_RETURN(bdata);
634
635 // Call the Eject(a{sv}) method on the drive object (Drive iface)
636 msg = eldbus_object_method_call_new(bdata->drive_obj,
637 UDISKS2_DRIVE_IFACE, "Eject");
638 iter = eldbus_message_iter_get(msg);
639 eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
640 eldbus_message_iter_container_close(iter, array);
641 eldbus_object_send(bdata->drive_obj, msg, _places_udisks2_task_cb, vol, -1);
642}
643
644
645#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 @@
1#ifndef E_MOD_PLACES_UDISKS2_H
2#define E_MOD_PLACES_UDISKS2_H
3
4void places_udisks2_init(void);
5void places_udisks2_shutdown(void);
6
7#endif
8
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(
5 'e_mod_config.c', 5 'e_mod_config.c',
6 'e_mod_places.c', 6 'e_mod_places.c',
7 7
8 'e_mod_udisks2.c',
8 'e_mod_udisks_eldbus.c', 9 'e_mod_udisks_eldbus.c',
9 'e_mod_mount.c', 10 'e_mod_mount.c',
10 'e_mod_eeze.c', 11 'e_mod_eeze.c',