update for beta release
[framework/uifw/e17.git] / src / modules / ofono / e_mod_main.c
1 /* TODO: config dialog to select which modem to monitor */
2
3 #include "e.h"
4 #include "e_mod_main.h"
5
6 static E_Module *ofono_mod = NULL;
7 static char tmpbuf[PATH_MAX];
8
9 const char _e_ofono_name[] = "ofono";
10 const char _e_ofono_Name[] = N_("Mobile Modems Info");
11 int _e_ofono_module_log_dom = -1;
12
13 static void _ofono_gadget_update(E_Ofono_Instance *inst);
14 static void _ofono_tip_update(E_Ofono_Instance *inst);
15
16 const char *
17 e_ofono_theme_path(void)
18 {
19 #define TF "/e-module-ofono.edj"
20    size_t dirlen;
21
22    dirlen = strlen(ofono_mod->dir);
23    if (dirlen >= sizeof(tmpbuf) - sizeof(TF))
24      return NULL;
25
26    memcpy(tmpbuf, ofono_mod->dir, dirlen);
27    memcpy(tmpbuf + dirlen, TF, sizeof(TF));
28
29    return tmpbuf;
30 #undef TF
31 }
32
33 static void _ofono_popup_del(E_Ofono_Instance *inst);
34
35 static Eina_Bool
36 _ofono_popup_input_window_mouse_up_cb(void    *data,
37                                       int type __UNUSED__,
38                                       void    *event)
39 {
40    Ecore_Event_Mouse_Button *ev = event;
41    E_Ofono_Instance *inst = data;
42
43    if (ev->window != inst->ui.input.win)
44      return ECORE_CALLBACK_PASS_ON;
45
46    _ofono_popup_del(inst);
47
48    return ECORE_CALLBACK_PASS_ON;
49 }
50
51 static Eina_Bool
52 _ofono_popup_input_window_key_down_cb(void    *data,
53                                       int type __UNUSED__,
54                                       void    *event)
55 {
56    Ecore_Event_Key *ev = event;
57    E_Ofono_Instance *inst = data;
58    const char *keysym;
59
60    if (ev->window != inst->ui.input.win)
61      return ECORE_CALLBACK_PASS_ON;
62
63    keysym = ev->key;
64    if (!strcmp(keysym, "Escape"))
65      _ofono_popup_del(inst);
66
67    return ECORE_CALLBACK_PASS_ON;
68 }
69
70 static void
71 _ofono_popup_input_window_destroy(E_Ofono_Instance *inst)
72 {
73    ecore_x_window_free(inst->ui.input.win);
74    inst->ui.input.win = 0;
75
76    ecore_event_handler_del(inst->ui.input.mouse_up);
77    inst->ui.input.mouse_up = NULL;
78
79    ecore_event_handler_del(inst->ui.input.key_down);
80    inst->ui.input.key_down = NULL;
81 }
82
83 static void
84 _ofono_popup_input_window_create(E_Ofono_Instance *inst)
85 {
86    Ecore_X_Window_Configure_Mask mask;
87    Ecore_X_Window w, popup_w;
88    E_Manager *man;
89
90    man = e_manager_current_get();
91
92    w = ecore_x_window_input_new(man->root, 0, 0, man->w, man->h);
93    mask = (ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE |
94            ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING);
95    popup_w = inst->popup->win->evas_win;
96    ecore_x_window_configure(w, mask, 0, 0, 0, 0, 0, popup_w,
97                             ECORE_X_WINDOW_STACK_BELOW);
98    ecore_x_window_show(w);
99
100    inst->ui.input.mouse_up =
101      ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
102                              _ofono_popup_input_window_mouse_up_cb, inst);
103
104    inst->ui.input.key_down =
105      ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
106                              _ofono_popup_input_window_key_down_cb, inst);
107
108    inst->ui.input.win = w;
109 }
110
111 static void
112 _ofono_toggle_powered_cb(void            *data,
113                          DBusMessage *msg __UNUSED__,
114                          DBusError       *error)
115 {
116    E_Ofono_Instance *inst = data;
117
118    if ((error) && (dbus_error_is_set(error)))
119      _ofono_dbus_error_show(_("Failed to power modem on/off."), error);
120    else
121      DBG("new powered value set");
122
123    e_widget_disabled_set(inst->ui.powered, (int)EINA_FALSE);
124    inst->powered_pending = EINA_FALSE;
125
126    dbus_error_free(error);
127 }
128
129 static void
130 _ofono_popup_cb_powered_changed(void        *data,
131                                 Evas_Object *obj,
132                                 void *event  __UNUSED__)
133 {
134    E_Ofono_Instance *inst = data;
135    E_Ofono_Module_Context *ctxt = inst->ctxt;
136    Eina_Bool powered = e_widget_check_checked_get(obj);
137
138    if ((!ctxt) || (!ctxt->has_manager))
139      {
140         _ofono_operation_error_show(_("oFono Daemon is not running."));
141         return;
142      }
143
144    if (!e_ofono_modem_powered_set(inst->modem_element, powered,
145                                   _ofono_toggle_powered_cb, inst))
146      {
147         _ofono_operation_error_show(_("Cannot toggle modem's powered state."));
148         return;
149      }
150    e_widget_disabled_set(obj, EINA_TRUE);
151    inst->powered_pending = EINA_TRUE;
152    DBG("powered = %d pending", !inst->powered);
153 }
154
155 static void
156 _ofono_popup_update(E_Ofono_Instance *inst)
157 {
158    if (inst->name)
159      e_widget_label_text_set(inst->ui.name, inst->name);
160    else
161      e_widget_label_text_set(inst->ui.name, _("No modem available"));
162    e_widget_check_checked_set(inst->ui.powered, inst->powered);
163 }
164
165 static void
166 _ofono_popup_del(E_Ofono_Instance *inst)
167 {
168    _ofono_popup_input_window_destroy(inst);
169    e_object_del(E_OBJECT(inst->popup));
170    inst->popup = NULL;
171 }
172
173 static void
174 _ofono_popup_new(E_Ofono_Instance *inst)
175 {
176    Evas *evas;
177    Evas_Coord mw, mh;
178
179    if (inst->popup)
180      {
181         e_gadcon_popup_show(inst->popup);
182         return;
183      }
184
185    inst->popup = e_gadcon_popup_new(inst->gcc);
186    evas = inst->popup->win->evas;
187
188    inst->ui.table = e_widget_table_add(evas, 0);
189
190    if (inst->name)
191      inst->ui.name = e_widget_label_add(evas, inst->name);
192    else
193      inst->ui.name = e_widget_label_add(evas, "No modem available");
194    e_widget_table_object_append(inst->ui.table, inst->ui.name,
195                                 0, 0, 1, 1, 1, 1, 1, 1);
196    evas_object_show(inst->ui.name);
197
198    inst->int_powered = inst->powered;
199    inst->ui.powered = e_widget_check_add(evas, _("Powered"),
200                                          &inst->int_powered);
201    e_widget_table_object_append(inst->ui.table, inst->ui.powered,
202                                 0, 1, 1, 1, 1, 1, 1, 1);
203    if (inst->powered_pending)
204      e_widget_disabled_set(inst->ui.powered, (int)EINA_TRUE);
205    evas_object_show(inst->ui.powered);
206    evas_object_smart_callback_add(inst->ui.powered, "changed",
207                                   _ofono_popup_cb_powered_changed, inst);
208
209    _ofono_popup_update(inst);
210
211    e_widget_size_min_get(inst->ui.table, &mw, &mh);
212    e_widget_size_min_set(inst->ui.table, mw, mh);
213
214    e_gadcon_popup_content_set(inst->popup, inst->ui.table);
215    e_gadcon_popup_show(inst->popup);
216    _ofono_popup_input_window_create(inst);
217 }
218
219 static void
220 _ofono_menu_cb_post(void        *data,
221                     E_Menu *menu __UNUSED__)
222 {
223    E_Ofono_Instance *inst = data;
224    if ((!inst) || (!inst->menu))
225      return;
226    if (inst->menu)
227      {
228         e_object_del(E_OBJECT(inst->menu));
229         inst->menu = NULL;
230      }
231 }
232
233 static void
234 _ofono_menu_new(E_Ofono_Instance      *inst,
235                 Evas_Event_Mouse_Down *ev)
236 {
237    E_Zone *zone;
238    E_Menu *m;
239    int x, y;
240
241    zone = e_util_zone_current_get(e_manager_current_get());
242
243    m = e_menu_new();
244    m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
245    e_menu_post_deactivate_callback_set(m, _ofono_menu_cb_post, inst);
246    inst->menu = m;
247    e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
248    e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
249                          1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
250    evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
251                             EVAS_BUTTON_NONE, ev->timestamp, NULL);
252 }
253
254 static void
255 _ofono_tip_new(E_Ofono_Instance *inst)
256 {
257    Evas *e;
258
259    inst->tip = e_gadcon_popup_new(inst->gcc);
260    if (!inst->tip) return;
261
262    e = inst->tip->win->evas;
263
264    inst->o_tip = edje_object_add(e);
265    e_theme_edje_object_set(inst->o_tip, "base/theme/modules/ofono/tip",
266                            "e/modules/ofono/tip");
267
268    _ofono_tip_update(inst);
269
270    e_gadcon_popup_content_set(inst->tip, inst->o_tip);
271    e_gadcon_popup_show(inst->tip);
272 }
273
274 static void
275 _ofono_tip_del(E_Ofono_Instance *inst)
276 {
277    evas_object_del(inst->o_tip);
278    e_object_del(E_OBJECT(inst->tip));
279    inst->tip = NULL;
280    inst->o_tip = NULL;
281 }
282
283 static void
284 _ofono_cb_mouse_down(void            *data,
285                      Evas *evas       __UNUSED__,
286                      Evas_Object *obj __UNUSED__,
287                      void            *event)
288 {
289    E_Ofono_Instance *inst;
290    Evas_Event_Mouse_Down *ev;
291
292    inst = data;
293    if (!inst)
294      return;
295
296    ev = event;
297    if (ev->button == 1)
298      {
299         if (!inst->popup)
300           _ofono_popup_new(inst);
301         else
302           _ofono_popup_del(inst);
303      }
304    else if (ev->button == 2)
305      _ofono_popup_cb_powered_changed(inst, inst->ui.powered, NULL);
306    else if ((ev->button == 3) && (!inst->menu))
307      _ofono_menu_new(inst, ev);
308 }
309
310 static void
311 _ofono_cb_mouse_in(void            *data,
312                    Evas *evas       __UNUSED__,
313                    Evas_Object *obj __UNUSED__,
314                    void *event      __UNUSED__)
315 {
316    E_Ofono_Instance *inst = data;
317
318    if (inst->tip)
319      return;
320
321    _ofono_tip_new(inst);
322 }
323
324 static void
325 _ofono_cb_mouse_out(void            *data,
326                     Evas *evas       __UNUSED__,
327                     Evas_Object *obj __UNUSED__,
328                     void *event      __UNUSED__)
329 {
330    E_Ofono_Instance *inst = data;
331
332    if (!inst->tip)
333      return;
334
335    _ofono_tip_del(inst);
336 }
337
338 static void
339 _ofono_edje_view_update(E_Ofono_Instance *inst,
340                         Evas_Object      *o)
341 {
342    Edje_Message_Int msg;
343    char buf[128];
344
345    if (!inst->ctxt->has_manager)
346      {
347         edje_object_signal_emit(o, "e,unavailable", "e");
348         edje_object_part_text_set(o, "e.text.error", _("ofonod is not running"));
349         return;
350      }
351
352    edje_object_signal_emit(o, "e,available", "e");
353
354    if (inst->name)
355      edje_object_part_text_set(o, "e.text.name", inst->name);
356    else
357      edje_object_part_text_set(o, "e.text.name", _("Unknown name"));
358
359    if (!inst->powered)
360      {
361         edje_object_part_text_set(o, "e.text.error", _("Modem powered off"));
362         edje_object_signal_emit(o, "e,netinfo,unavailable", "e");
363         return;
364      }
365
366    if (inst->status)
367      {
368         snprintf(buf, sizeof(buf), "%c%s",
369                  toupper(inst->status[0]), inst->status + 1);
370         edje_object_part_text_set(o, "e.text.status", buf);
371         edje_object_signal_emit(o, "e,netinfo,available", "e");
372      }
373    else
374      edje_object_part_text_set(o, "e.text.status", _("Unknown status"));
375
376    if (inst->op)
377      {
378         edje_object_part_text_set(o, "e.text.op", inst->op);
379         edje_object_signal_emit(o, "e,netinfo,available", "e");
380      }
381    else
382      edje_object_part_text_set(o, "e.text.op", _("Unknown operator"));
383
384    msg.val = inst->strength;
385    edje_object_message_send(o, EDJE_MESSAGE_INT, 1, &msg);
386 }
387
388 static void
389 _ofono_tip_update(E_Ofono_Instance *inst)
390 {
391    _ofono_edje_view_update(inst, inst->o_tip);
392 }
393
394 static void
395 _ofono_gadget_update(E_Ofono_Instance *inst)
396 {
397    E_Ofono_Module_Context *ctxt = inst->ctxt;
398
399    if (!ctxt->has_manager && inst->popup)
400      _ofono_popup_del(inst);
401
402    if (inst->popup)
403      _ofono_popup_update(inst);
404    if (inst->tip)
405      _ofono_tip_update(inst);
406
407    _ofono_edje_view_update(inst, inst->ui.gadget);
408 }
409
410 /* Gadcon Api Functions */
411
412 static E_Gadcon_Client *
413 _gc_init(E_Gadcon   *gc,
414          const char *name,
415          const char *id,
416          const char *style)
417 {
418    E_Ofono_Instance *inst;
419    E_Ofono_Module_Context *ctxt;
420
421    if (!ofono_mod)
422      return NULL;
423
424    ctxt = ofono_mod->data;
425
426    inst = E_NEW(E_Ofono_Instance, 1);
427    inst->ctxt = ctxt;
428    inst->ui.gadget = edje_object_add(gc->evas);
429    e_theme_edje_object_set(inst->ui.gadget, "base/theme/modules/ofono",
430                            "e/modules/ofono/main");
431
432    inst->path = NULL;
433    inst->name = NULL;
434    inst->powered = EINA_FALSE;
435    inst->int_powered = 0;
436    inst->status = NULL;
437    inst->op = NULL;
438    inst->strength = 0;
439    inst->modem_element = NULL;
440    inst->netreg_element = NULL;
441
442    inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->ui.gadget);
443    inst->gcc->data = inst;
444
445    evas_object_event_callback_add
446      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_DOWN, _ofono_cb_mouse_down, inst);
447    evas_object_event_callback_add
448      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_IN, _ofono_cb_mouse_in, inst);
449    evas_object_event_callback_add
450      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_OUT, _ofono_cb_mouse_out, inst);
451
452    _ofono_gadget_update(inst);
453
454    ctxt->instances = eina_list_append(ctxt->instances, inst);
455
456    return inst->gcc;
457 }
458
459 static void
460 _gc_shutdown(E_Gadcon_Client *gcc)
461 {
462    E_Ofono_Module_Context *ctxt;
463    E_Ofono_Instance *inst;
464
465    if (!ofono_mod)
466      return;
467
468    ctxt = ofono_mod->data;
469    if (!ctxt)
470      return;
471
472    inst = gcc->data;
473    if (!inst)
474      return;
475
476    if (inst->menu)
477      {
478         e_menu_post_deactivate_callback_set(inst->menu, NULL, NULL);
479         e_object_del(E_OBJECT(inst->menu));
480      }
481    if (inst->popup)
482      _ofono_popup_del(inst);
483    if (inst->tip)
484      _ofono_tip_del(inst);
485
486    evas_object_del(inst->ui.gadget);
487
488    eina_stringshare_del(inst->path);
489    eina_stringshare_del(inst->name);
490    eina_stringshare_del(inst->status);
491    eina_stringshare_del(inst->op);
492
493    ctxt->instances = eina_list_remove(ctxt->instances, inst);
494
495    E_FREE(inst);
496 }
497
498 static void
499 _gc_orient(E_Gadcon_Client       *gcc,
500            E_Gadcon_Orient orient __UNUSED__)
501 {
502    e_gadcon_client_aspect_set(gcc, 16, 16);
503    e_gadcon_client_min_size_set(gcc, 16, 16);
504 }
505
506 static const char *
507 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
508 {
509    return _(_e_ofono_Name);
510 }
511
512 static Evas_Object *
513 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__,
514          Evas                               *evas)
515 {
516    Evas_Object *o;
517
518    o = edje_object_add(evas);
519    edje_object_file_set(o, e_ofono_theme_path(), "icon");
520    return o;
521 }
522
523 static const char *
524 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
525 {
526    E_Ofono_Module_Context *ctxt;
527    Eina_List *instances;
528
529    if (!ofono_mod)
530      return NULL;
531
532    ctxt = ofono_mod->data;
533    if (!ctxt)
534      return NULL;
535
536    instances = ctxt->instances;
537    snprintf(tmpbuf, sizeof(tmpbuf), "ofono.%d", eina_list_count(instances));
538    return tmpbuf;
539 }
540
541 static const E_Gadcon_Client_Class _gc_class =
542 {
543    GADCON_CLIENT_CLASS_VERSION, _e_ofono_name,
544    {
545       _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
546       e_gadcon_site_is_not_toolbar
547    },
548    E_GADCON_CLIENT_STYLE_PLAIN
549 };
550
551 EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, _e_ofono_Name};
552
553 static Eina_Bool
554 _ofono_manager_changed_do(void *data)
555 {
556    E_Ofono_Module_Context *ctxt = data;
557
558    ctxt->poller.manager_changed = NULL;
559    return ECORE_CALLBACK_CANCEL;
560 }
561
562 static void
563 _ofono_manager_changed(void                          *data,
564                        const E_Ofono_Element *element __UNUSED__)
565 {
566    E_Ofono_Module_Context *ctxt = data;
567    if (ctxt->poller.manager_changed)
568      ecore_poller_del(ctxt->poller.manager_changed);
569    ctxt->poller.manager_changed = ecore_poller_add
570        (ECORE_POLLER_CORE, 1, _ofono_manager_changed_do, ctxt);
571 }
572
573 static Eina_Bool
574 _ofono_event_manager_in(void       *data,
575                         int type    __UNUSED__,
576                         void *event __UNUSED__)
577 {
578    E_Ofono_Element *element;
579    E_Ofono_Module_Context *ctxt = data;
580    E_Ofono_Instance *inst;
581    Eina_List *l;
582
583    DBG("manager in");
584
585    ctxt->has_manager = EINA_TRUE;
586
587    element = e_ofono_manager_get();
588    e_ofono_element_listener_add(element, _ofono_manager_changed, ctxt, NULL);
589
590    EINA_LIST_FOREACH(ctxt->instances, l, inst)
591      _ofono_gadget_update(inst);
592
593    return ECORE_CALLBACK_PASS_ON;
594 }
595
596 static Eina_Bool
597 _ofono_event_manager_out(void       *data,
598                          int type    __UNUSED__,
599                          void *event __UNUSED__)
600 {
601    E_Ofono_Module_Context *ctxt = data;
602    E_Ofono_Instance *inst;
603    Eina_List *l;
604
605    DBG("manager out");
606
607    ctxt->has_manager = EINA_FALSE;
608
609    EINA_LIST_FOREACH(ctxt->instances, l, inst)
610      _ofono_gadget_update(inst);
611
612    return ECORE_CALLBACK_PASS_ON;
613 }
614
615 static Eina_Bool
616 _eofono_event_element_add(void    *data,
617                           int type __UNUSED__,
618                           void    *info)
619 {
620    E_Ofono_Element *element = info;
621    E_Ofono_Module_Context *ctxt = data;
622    E_Ofono_Instance *inst;
623    Eina_List *l;
624    Eina_Bool have_inst = EINA_FALSE;
625
626    DBG(">>> %s %s", element->path, element->interface);
627
628    /* is there any instance taking care of this modem already? */
629    EINA_LIST_FOREACH(ctxt->instances, l, inst)
630      if ((inst->path) && (inst->path == element->path))
631        {
632           have_inst = EINA_TRUE;
633           break;
634        }
635
636    /* if no instance is handling this, is there any instance available */
637    if ((!have_inst) && (e_ofono_element_is_modem(element)))
638      EINA_LIST_FOREACH(ctxt->instances, l, inst)
639        if (!inst->path)
640          {
641             inst->path = eina_stringshare_ref(element->path);
642             DBG("bound %s to an ofono module instance", inst->path);
643             have_inst = EINA_TRUE;
644             break;
645          }
646
647    /* if still orphan, do nothing */
648    if (!have_inst)
649      return ECORE_CALLBACK_PASS_ON;
650
651    if (e_ofono_element_is_modem(element))
652      inst->modem_element = element;
653    else if (e_ofono_element_is_netreg(element))
654      inst->netreg_element = element;
655
656    _ofono_gadget_update(inst);
657
658    return ECORE_CALLBACK_PASS_ON;
659 }
660
661 static Eina_Bool
662 _eofono_event_element_del(void    *data,
663                           int type __UNUSED__,
664                           void    *info)
665 {
666    E_Ofono_Element *element = info;
667    E_Ofono_Module_Context *ctxt = data;
668    E_Ofono_Instance *inst;
669    Eina_List *l;
670    Eina_Bool inst_found = EINA_FALSE;
671
672    DBG("<<< %s %s", element->path, element->interface);
673
674    EINA_LIST_FOREACH(ctxt->instances, l, inst)
675      if ((inst->path) && (inst->path == element->path))
676        {
677           inst_found = EINA_TRUE;
678           break;
679        }
680
681    if (!inst_found)
682      return ECORE_CALLBACK_PASS_ON;
683
684    if (e_ofono_element_is_modem(element))
685      {
686         inst->modem_element = NULL;
687         eina_stringshare_replace(&inst->name, NULL);
688         inst->powered = EINA_FALSE;
689      }
690    else if (e_ofono_element_is_netreg(element))
691      {
692         inst->netreg_element = NULL;
693         eina_stringshare_replace(&inst->status, NULL);
694         eina_stringshare_replace(&inst->op, NULL);
695         inst->strength = 0;
696      }
697
698    _ofono_gadget_update(inst);
699
700    return ECORE_CALLBACK_PASS_ON;
701 }
702
703 static Eina_Bool
704 _eofono_event_element_updated(void    *data,
705                               int type __UNUSED__,
706                               void    *event_info)
707 {
708    E_Ofono_Element *element = event_info;
709    E_Ofono_Module_Context *ctxt = data;
710    E_Ofono_Instance *inst;
711    Eina_List *l;
712    Eina_Bool inst_found = EINA_FALSE;
713    const char *tmp;
714
715    DBG("!!! %s %s", element->path, element->interface);
716
717    EINA_LIST_FOREACH(ctxt->instances, l, inst)
718      if ((inst->path) && (inst->path == element->path))
719        {
720           inst_found = EINA_TRUE;
721           break;
722        }
723
724    if (!inst_found)
725      return ECORE_CALLBACK_PASS_ON;
726
727    if (e_ofono_element_is_modem(element))
728      {
729         if (!e_ofono_modem_powered_get(element, &(inst->powered)))
730           inst->powered = 0;
731
732         if (!e_ofono_modem_name_get(element, &tmp))
733           tmp = NULL;
734         if ((!tmp) || (!tmp[0]))
735           tmp = inst->path;
736         eina_stringshare_replace(&inst->name, tmp);
737
738         DBG("!!! powered = %d, name = %s", inst->powered, inst->name);
739      }
740    else if (e_ofono_element_is_netreg(element))
741      {
742         if (!e_ofono_netreg_status_get(element, &tmp))
743           tmp = NULL;
744         eina_stringshare_replace(&inst->status, tmp);
745
746         if (!e_ofono_netreg_operator_get(element, &tmp))
747           tmp = NULL;
748         eina_stringshare_replace(&inst->op, tmp);
749
750         if (!e_ofono_netreg_strength_get(element, &(inst->strength)))
751           inst->strength = 0;
752
753         DBG("!!! status = %s, operator = %s, strength = %d",
754             inst->status, inst->op, inst->strength);
755      }
756
757    _ofono_gadget_update(inst);
758
759    return ECORE_CALLBACK_PASS_ON;
760 }
761
762 static void
763 _ofono_events_register(E_Ofono_Module_Context *ctxt)
764 {
765    ctxt->event.manager_in = ecore_event_handler_add
766        (E_OFONO_EVENT_MANAGER_IN, _ofono_event_manager_in, ctxt);
767    ctxt->event.manager_out = ecore_event_handler_add
768        (E_OFONO_EVENT_MANAGER_OUT, _ofono_event_manager_out, ctxt);
769    ctxt->event.element_add = ecore_event_handler_add
770        (E_OFONO_EVENT_ELEMENT_ADD, _eofono_event_element_add, ctxt);
771    ctxt->event.element_del = ecore_event_handler_add
772        (E_OFONO_EVENT_ELEMENT_DEL, _eofono_event_element_del, ctxt);
773    ctxt->event.element_updated = ecore_event_handler_add
774        (E_OFONO_EVENT_ELEMENT_UPDATED, _eofono_event_element_updated, ctxt);
775 }
776
777 static void
778 _ofono_events_unregister(E_Ofono_Module_Context *ctxt)
779 {
780    if (ctxt->event.manager_in)
781      ecore_event_handler_del(ctxt->event.manager_in);
782    if (ctxt->event.manager_out)
783      ecore_event_handler_del(ctxt->event.manager_out);
784    if (ctxt->event.element_add)
785      ecore_event_handler_del(ctxt->event.element_add);
786    if (ctxt->event.element_del)
787      ecore_event_handler_del(ctxt->event.element_del);
788    if (ctxt->event.element_updated)
789      ecore_event_handler_del(ctxt->event.element_updated);
790 }
791
792 EAPI void *
793 e_modapi_init(E_Module *m)
794 {
795    E_Ofono_Module_Context *ctxt;
796    E_DBus_Connection *c;
797
798    c = e_dbus_bus_get(DBUS_BUS_SYSTEM);
799    if (!c)
800      goto error_dbus_bus_get;
801    if (!e_ofono_system_init(c))
802      goto error_ofono_system_init;
803
804    ctxt = E_NEW(E_Ofono_Module_Context, 1);
805    if (!ctxt)
806      goto error_ofono_context;
807
808    ofono_mod = m;
809
810    if (_e_ofono_module_log_dom < 0)
811      {
812         _e_ofono_module_log_dom = eina_log_domain_register("e_module_ofono",
813                                                            EINA_COLOR_ORANGE);
814         if (_e_ofono_module_log_dom < 0)
815           {
816              EINA_LOG_CRIT("could not register logging domain e_module_ofono");
817              goto error_log_domain;
818           }
819      }
820
821    e_gadcon_provider_register(&_gc_class);
822
823    _ofono_events_register(ctxt);
824
825    return ctxt;
826
827 error_log_domain:
828    _e_ofono_module_log_dom = -1;
829    ofono_mod = NULL;
830    E_FREE(ctxt);
831 error_ofono_context:
832    e_ofono_system_shutdown();
833 error_ofono_system_init:
834 error_dbus_bus_get:
835    return NULL;
836 }
837
838 static void
839 _ofono_instances_free(E_Ofono_Module_Context *ctxt)
840 {
841    while (ctxt->instances)
842      {
843         E_Ofono_Instance *inst;
844
845         inst = ctxt->instances->data;
846
847         if (inst->popup)
848           _ofono_popup_del(inst);
849         if (inst->tip)
850           _ofono_tip_del(inst);
851
852         e_object_del(E_OBJECT(inst->gcc));
853      }
854 }
855
856 EAPI int
857 e_modapi_shutdown(E_Module *m)
858 {
859    E_Ofono_Module_Context *ctxt;
860    E_Ofono_Element *element;
861
862    ctxt = m->data;
863    if (!ctxt)
864      return 0;
865
866    element = e_ofono_manager_get();
867    e_ofono_element_listener_del(element, _ofono_manager_changed, ctxt);
868
869    _ofono_events_unregister(ctxt);
870
871    _ofono_instances_free(ctxt);
872
873    e_gadcon_provider_unregister(&_gc_class);
874
875    if (ctxt->poller.manager_changed)
876      ecore_poller_del(ctxt->poller.manager_changed);
877
878    E_FREE(ctxt);
879    ofono_mod = NULL;
880
881    e_ofono_system_shutdown();
882
883    return 1;
884 }
885
886 EAPI int
887 e_modapi_save(E_Module *m)
888 {
889    E_Ofono_Module_Context *ctxt;
890
891    ctxt = m->data;
892    if (!ctxt)
893      return 0;
894    return 1;
895 }
896