f63f041785f5506a067bb793060438381a67647d
[framework/uifw/e17.git] / src / modules / battery / e_mod_dbus.c
1 #include "e.h"
2 #include "e_mod_main.h"
3
4 static void _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error);
5 static void _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error);
6 static void _battery_dbus_battery_property_changed(void *data, DBusMessage *msg);
7 static void _battery_dbus_battery_add(const char *udi);
8 static void _battery_dbus_battery_del(const char *udi);
9 static void _battery_dbus_ac_adapter_add(const char *udi);
10 static void _battery_dbus_ac_adapter_del(const char *udi);
11 static void _battery_dbus_find_battery(void *user_data, void *reply_data, DBusError *err);
12 static void _battery_dbus_find_ac(void *user_data, void *reply_data, DBusError *err);
13 static void _battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err);
14 static void _battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err);
15 static void _battery_dbus_dev_add(void *data, DBusMessage *msg);
16 static void _battery_dbus_dev_del(void *data, DBusMessage *msg);
17
18 extern Eina_List *device_batteries;
19 extern Eina_List *device_ac_adapters;
20 extern double init_time;
21
22 static E_DBus_Connection *e_dbus_conn = NULL;
23
24 int
25 _battery_dbus_start(void)
26 {
27    e_dbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
28    if (!e_dbus_conn) return 0;
29    // FIXME: e_dbus doesn't allow us to track this pending call
30    e_hal_manager_find_device_by_capability
31      (e_dbus_conn, "battery", _battery_dbus_find_battery, NULL);
32    e_hal_manager_find_device_by_capability
33      (e_dbus_conn, "ac_adapter", _battery_dbus_find_ac, NULL);
34    battery_config->dbus.dev_add = 
35      e_dbus_signal_handler_add(e_dbus_conn, E_HAL_SENDER,
36                                E_HAL_MANAGER_PATH,
37                                E_HAL_MANAGER_INTERFACE,
38                                "DeviceAdded", _battery_dbus_dev_add, NULL);
39    battery_config->dbus.dev_del = 
40      e_dbus_signal_handler_add(e_dbus_conn, E_HAL_SENDER,
41                                E_HAL_MANAGER_PATH,
42                                E_HAL_MANAGER_INTERFACE,
43                                "DeviceRemoved", _battery_dbus_dev_del, NULL);
44    init_time = ecore_time_get();
45    return 1;
46 }
47
48
49 void
50 _battery_dbus_stop(void)
51 {
52    Ac_Adapter *ac;
53    Battery *bat;
54
55    if (!e_dbus_conn) return;
56    
57    if (battery_config->dbus.have)
58      {
59         dbus_pending_call_cancel(battery_config->dbus.have);
60         battery_config->dbus.have = NULL;
61      }
62    if (battery_config->dbus.dev_add)
63      {
64         e_dbus_signal_handler_del(e_dbus_conn, battery_config->dbus.dev_add);
65         battery_config->dbus.dev_add = NULL;
66      }
67    if (battery_config->dbus.dev_del)
68      {
69         e_dbus_signal_handler_del(e_dbus_conn, battery_config->dbus.dev_del);
70         battery_config->dbus.dev_del = NULL;
71      }
72    EINA_LIST_FREE(device_ac_adapters, ac)
73      {
74         e_dbus_signal_handler_del(e_dbus_conn, ac->prop_change);
75         eina_stringshare_del(ac->udi);
76         eina_stringshare_del(ac->product);
77         free(ac);
78      }
79    EINA_LIST_FREE(device_batteries, bat)
80      {
81         e_dbus_signal_handler_del(e_dbus_conn, bat->prop_change);
82         eina_stringshare_del(bat->udi);
83         eina_stringshare_del(bat->technology);
84         eina_stringshare_del(bat->type);
85         eina_stringshare_del(bat->charge_units);
86         eina_stringshare_del(bat->model);
87         eina_stringshare_del(bat->vendor);
88         free(bat);
89      }
90    e_dbus_connection_close(e_dbus_conn);
91    e_dbus_conn = NULL;
92 }
93
94 static void
95 _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error __UNUSED__)
96 {
97    E_Hal_Properties *ret = reply_data;
98    Battery *bat = data;
99    int err = 0;
100    const char *str;
101
102    if (dbus_error_is_set(error))
103      {
104         dbus_error_free(error);
105         return;
106      }
107    if (!ret) return;
108
109 #undef GET_BOOL
110 #undef GET_INT
111 #undef GET_STR
112 #define GET_BOOL(val, s) bat->val = e_hal_property_bool_get(ret, s, &err)
113 #define GET_INT(val, s) bat->val = e_hal_property_int_get(ret, s, &err)
114 #define GET_STR(val, s) \
115    if (bat->val) eina_stringshare_del(bat->val); \
116    bat->val = NULL; \
117    str = e_hal_property_string_get(ret, s, &err); \
118    if (str) \
119      { \
120         bat->val = eina_stringshare_ref(str); \
121      }
122    
123    GET_BOOL(present, "battery.present");
124    GET_STR(technology, "battery.reporting.technology");
125    GET_STR(model, "battery.model");
126    GET_STR(vendor, "battery.vendor");
127    GET_STR(type, "battery.type");
128    GET_STR(charge_units, "battery.reporting.unit");
129    GET_INT(percent, "battery.charge_level.percentage");
130    GET_BOOL(can_charge, "battery.is_rechargeable");
131    GET_INT(current_charge, "battery.charge_level.current");
132    GET_INT(charge_rate, "battery.charge_level.rate");
133    GET_INT(design_charge, "battery.charge_level.design");
134    GET_INT(last_full_charge, "battery.charge_level.last_full");
135    if (e_hal_property_bool_get(ret, "battery.rechargeable.is_charging", &err))
136      {
137         bat->charging = 1;
138         GET_INT(time_full, "battery.remaining_time");
139         bat->time_left = -1;
140      }
141    else
142      {
143         bat->charging = 0;
144         GET_INT(time_left, "battery.remaining_time");
145         bat->time_full = -1;
146      }
147    bat->got_prop = 1;
148    _battery_device_update();
149 }
150
151 static void
152 _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error __UNUSED__)
153 {
154    E_Hal_Properties *ret = reply_data;
155    Ac_Adapter *ac = data;
156    int err = 0;
157    const char *str;
158
159    if (dbus_error_is_set(error))
160      {
161         dbus_error_free(error);
162         return;
163      }
164    if (!ret) return;
165    
166 #undef GET_BOOL
167 #undef GET_STR
168 #define GET_BOOL(val, s) ac->val = e_hal_property_bool_get(ret, s, &err)
169 #define GET_STR(val, s) \
170    if (ac->val) eina_stringshare_del(ac->val); \
171    ac->val = NULL; \
172    str = e_hal_property_string_get(ret, s, &err); \
173    if (str) \
174      { \
175         ac->val = eina_stringshare_ref(str); \
176      }
177    
178    GET_BOOL(present, "ac_adapter.present");
179    GET_STR(product, "info.product");
180    _battery_device_update();
181 }
182
183 static void
184 _battery_dbus_battery_property_changed(void *data, DBusMessage *msg __UNUSED__)
185 {
186    // FIXME: e_dbus doesn't allow us to track this pending call
187    e_hal_device_get_all_properties(e_dbus_conn, ((Battery *)data)->udi,
188                                    _battery_dbus_battery_props, data);
189 }
190
191 static void
192 _battery_dbus_ac_adapter_property_changed(void *data, DBusMessage *msg __UNUSED__)
193 {
194    // FIXME: e_dbus doesn't allow us to track this pending call
195    e_hal_device_get_all_properties(e_dbus_conn, ((Ac_Adapter *)data)->udi,
196                                    _battery_dbus_ac_adapter_props, data);
197 }
198
199 static void
200 _battery_dbus_battery_add(const char *udi)
201 {
202    Battery *bat;
203
204    bat = _battery_battery_find(udi);
205    if (!bat)
206      {
207         bat = E_NEW(Battery, 1);
208         if (!bat) return;
209         bat->udi = eina_stringshare_add(udi);
210         device_batteries = eina_list_append(device_batteries, bat);
211         bat->prop_change =
212         e_dbus_signal_handler_add(e_dbus_conn, E_HAL_SENDER, udi,
213                                   E_HAL_DEVICE_INTERFACE, "PropertyModified",
214                                   _battery_dbus_battery_property_changed,
215                                   bat);
216      }
217    // FIXME: e_dbus doesn't allow us to track this pending call
218    e_hal_device_get_all_properties(e_dbus_conn, udi, 
219                                    _battery_dbus_battery_props, bat);
220
221    _battery_device_update();
222 }
223
224 static void
225 _battery_dbus_battery_del(const char *udi)
226 {
227    Eina_List *l;
228    Battery *bat;
229    
230    bat = _battery_battery_find(udi);
231    if (bat)
232      {
233         e_dbus_signal_handler_del(e_dbus_conn, bat->prop_change);
234         l = eina_list_data_find(device_batteries, bat);
235         eina_stringshare_del(bat->udi);
236         eina_stringshare_del(bat->technology);
237         eina_stringshare_del(bat->type);
238         eina_stringshare_del(bat->charge_units);
239         eina_stringshare_del(bat->model);
240         eina_stringshare_del(bat->vendor);
241         free(bat);
242         device_batteries = eina_list_remove_list(device_batteries, l);
243         return;
244      }
245    _battery_device_update();
246 }
247
248 static void
249 _battery_dbus_ac_adapter_add(const char *udi)
250 {
251    Ac_Adapter *ac;
252
253    ac = E_NEW(Ac_Adapter, 1);
254    if (!ac) return;
255    ac->udi = eina_stringshare_add(udi);
256    device_ac_adapters = eina_list_append(device_ac_adapters, ac);
257    ac->prop_change =
258      e_dbus_signal_handler_add(e_dbus_conn, E_HAL_SENDER, udi,
259                                E_HAL_DEVICE_INTERFACE, "PropertyModified",
260                                _battery_dbus_ac_adapter_property_changed, 
261                                ac);
262    // FIXME: e_dbus doesn't allow us to track this pending call
263    e_hal_device_get_all_properties(e_dbus_conn, udi, 
264                                    _battery_dbus_ac_adapter_props, ac);
265    _battery_device_update();
266 }
267
268 static void
269 _battery_dbus_ac_adapter_del(const char *udi)
270 {
271    Eina_List *l;
272    Ac_Adapter *ac;
273    
274    ac = _battery_ac_adapter_find(udi);
275    if (ac)
276      {
277         e_dbus_signal_handler_del(e_dbus_conn, ac->prop_change);
278         l = eina_list_data_find(device_ac_adapters, ac);
279         eina_stringshare_del(ac->udi);
280         eina_stringshare_del(ac->product);
281         free(ac);
282         device_ac_adapters = eina_list_remove_list(device_ac_adapters, l);
283         return;
284      }
285    _battery_device_update();
286 }
287
288 static void
289 _battery_dbus_find_battery(void *user_data __UNUSED__, void *reply_data, DBusError *err __UNUSED__)
290 {
291    Eina_List *l;
292    char *device;
293    E_Hal_Manager_Find_Device_By_Capability_Return *ret;
294
295    ret = reply_data;
296    if (dbus_error_is_set(err))
297      {
298         dbus_error_free(err);
299         return;
300      }
301    if (!ret) return;
302
303    if (eina_list_count(ret->strings) < 1) return;
304    EINA_LIST_FOREACH(ret->strings, l, device)
305      _battery_dbus_battery_add(device);
306 }
307
308 static void
309 _battery_dbus_find_ac(void *user_data __UNUSED__, void *reply_data, DBusError *err __UNUSED__)
310 {
311    Eina_List *l;
312    char *device;
313    E_Hal_Manager_Find_Device_By_Capability_Return *ret;
314
315    
316    ret = reply_data;
317    if (dbus_error_is_set(err))
318      {
319         dbus_error_free(err);
320         return;
321      }
322    if (!ret) return;
323
324    if (eina_list_count(ret->strings) < 1) return;
325    EINA_LIST_FOREACH(ret->strings, l, device)
326      _battery_dbus_ac_adapter_add(device);
327
328 }
329
330 static void
331 _battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err)
332 {
333    char *udi = user_data;
334    E_Hal_Device_Query_Capability_Return *ret;
335
336    
337    ret = reply_data;
338    if (dbus_error_is_set(err))
339      {
340         dbus_error_free(err);
341         goto error;
342      }
343    if (!ret) goto error;
344    if (ret->boolean)
345      _battery_dbus_battery_add(udi);
346    error:
347    eina_stringshare_del(udi);
348 }
349
350 static void
351 _battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err)
352 {
353    char *udi = user_data;
354    E_Hal_Device_Query_Capability_Return *ret;
355
356    
357    ret = reply_data;
358    if (dbus_error_is_set(err))
359      {
360         dbus_error_free(err);
361         goto error;
362      }
363    if (!ret) goto error;
364
365    if (ret->boolean)
366      _battery_dbus_ac_adapter_add(udi);
367    error:
368    eina_stringshare_del(udi);
369 }
370
371 static void
372 _battery_dbus_dev_add(void *data __UNUSED__, DBusMessage *msg)
373 {
374    DBusError err;
375    char *udi = NULL;
376    
377    dbus_error_init(&err);
378    dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
379    if (!udi) return;
380    // FIXME: e_dbus doesn't allow us to track this pending call
381    e_hal_device_query_capability(e_dbus_conn, udi, "battery",
382                                  _battery_dbus_is_battery, (void*)eina_stringshare_add(udi));
383    e_hal_device_query_capability(e_dbus_conn, udi, "ac_adapter",
384                                  _battery_dbus_is_ac_adapter, (void*)eina_stringshare_add(udi));
385 }
386
387 static void
388 _battery_dbus_dev_del(void *data __UNUSED__, DBusMessage *msg)
389 {
390    DBusError err;
391    char *udi = NULL;
392    
393    dbus_error_init(&err);
394    dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
395    if (!udi) return;
396    _battery_dbus_battery_del(udi);
397    _battery_dbus_ac_adapter_del(udi);
398 }