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