Tizen 2.1 release
[platform/core/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[4096];
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_new(E_Ofono_Instance      *inst,
221                 Evas_Event_Mouse_Down *ev)
222 {
223    E_Zone *zone;
224    E_Menu *m;
225    int x, y;
226
227    zone = e_util_zone_current_get(e_manager_current_get());
228
229    m = e_menu_new();
230    m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
231    e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
232    e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
233                          1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
234    evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
235                             EVAS_BUTTON_NONE, ev->timestamp, NULL);
236 }
237
238 static void
239 _ofono_tip_new(E_Ofono_Instance *inst)
240 {
241    Evas *e;
242
243    inst->tip = e_gadcon_popup_new(inst->gcc);
244    if (!inst->tip) return;
245
246    e = inst->tip->win->evas;
247
248    inst->o_tip = edje_object_add(e);
249    e_theme_edje_object_set(inst->o_tip, "base/theme/modules/ofono/tip",
250                            "e/modules/ofono/tip");
251
252    _ofono_tip_update(inst);
253
254    e_gadcon_popup_content_set(inst->tip, inst->o_tip);
255    e_gadcon_popup_show(inst->tip);
256 }
257
258 static void
259 _ofono_tip_del(E_Ofono_Instance *inst)
260 {
261    evas_object_del(inst->o_tip);
262    e_object_del(E_OBJECT(inst->tip));
263    inst->tip = NULL;
264    inst->o_tip = NULL;
265 }
266
267 static void
268 _ofono_cb_mouse_down(void            *data,
269                      Evas *evas       __UNUSED__,
270                      Evas_Object *obj __UNUSED__,
271                      void            *event)
272 {
273    E_Ofono_Instance *inst;
274    Evas_Event_Mouse_Down *ev;
275
276    inst = data;
277    if (!inst)
278      return;
279
280    ev = event;
281    if (ev->button == 1)
282      {
283         if (!inst->popup)
284           _ofono_popup_new(inst);
285         else
286           _ofono_popup_del(inst);
287      }
288    else if (ev->button == 2)
289      _ofono_popup_cb_powered_changed(inst, inst->ui.powered, NULL);
290    else if (ev->button == 3)
291      _ofono_menu_new(inst, ev);
292 }
293
294 static void
295 _ofono_cb_mouse_in(void            *data,
296                    Evas *evas       __UNUSED__,
297                    Evas_Object *obj __UNUSED__,
298                    void *event      __UNUSED__)
299 {
300    E_Ofono_Instance *inst = data;
301
302    if (inst->tip)
303      return;
304
305    _ofono_tip_new(inst);
306 }
307
308 static void
309 _ofono_cb_mouse_out(void            *data,
310                     Evas *evas       __UNUSED__,
311                     Evas_Object *obj __UNUSED__,
312                     void *event      __UNUSED__)
313 {
314    E_Ofono_Instance *inst = data;
315
316    if (!inst->tip)
317      return;
318
319    _ofono_tip_del(inst);
320 }
321
322 static void
323 _ofono_edje_view_update(E_Ofono_Instance *inst,
324                         Evas_Object      *o)
325 {
326    Edje_Message_Int msg;
327    char buf[128];
328
329    if (!inst->ctxt->has_manager)
330      {
331         edje_object_signal_emit(o, "e,unavailable", "e");
332         edje_object_part_text_set(o, "e.text.error", _("ofonod is not running"));
333         return;
334      }
335
336    edje_object_signal_emit(o, "e,available", "e");
337
338    if (inst->name)
339      edje_object_part_text_set(o, "e.text.name", inst->name);
340    else
341      edje_object_part_text_set(o, "e.text.name", _("Unknown name"));
342
343    if (!inst->powered)
344      {
345         edje_object_part_text_set(o, "e.text.error", _("Modem powered off"));
346         edje_object_signal_emit(o, "e,netinfo,unavailable", "e");
347         return;
348      }
349
350    if (inst->status)
351      {
352         snprintf(buf, sizeof(buf), "%c%s",
353                  toupper(inst->status[0]), inst->status + 1);
354         edje_object_part_text_set(o, "e.text.status", buf);
355         edje_object_signal_emit(o, "e,netinfo,available", "e");
356      }
357    else
358      edje_object_part_text_set(o, "e.text.status", _("Unknown status"));
359
360    if (inst->op)
361      {
362         edje_object_part_text_set(o, "e.text.op", inst->op);
363         edje_object_signal_emit(o, "e,netinfo,available", "e");
364      }
365    else
366      edje_object_part_text_set(o, "e.text.op", _("Unknown operator"));
367
368    msg.val = inst->strength;
369    edje_object_message_send(o, EDJE_MESSAGE_INT, 1, &msg);
370 }
371
372 static void
373 _ofono_tip_update(E_Ofono_Instance *inst)
374 {
375    _ofono_edje_view_update(inst, inst->o_tip);
376 }
377
378 static void
379 _ofono_gadget_update(E_Ofono_Instance *inst)
380 {
381    E_Ofono_Module_Context *ctxt = inst->ctxt;
382
383    if (!ctxt->has_manager && inst->popup)
384      _ofono_popup_del(inst);
385
386    if (inst->popup)
387      _ofono_popup_update(inst);
388    if (inst->tip)
389      _ofono_tip_update(inst);
390
391    _ofono_edje_view_update(inst, inst->ui.gadget);
392 }
393
394 /* Gadcon Api Functions */
395
396 static E_Gadcon_Client *
397 _gc_init(E_Gadcon   *gc,
398          const char *name,
399          const char *id,
400          const char *style)
401 {
402    E_Ofono_Instance *inst;
403    E_Ofono_Module_Context *ctxt;
404
405    if (!ofono_mod)
406      return NULL;
407
408    ctxt = ofono_mod->data;
409
410    inst = E_NEW(E_Ofono_Instance, 1);
411    inst->ctxt = ctxt;
412    inst->ui.gadget = edje_object_add(gc->evas);
413    e_theme_edje_object_set(inst->ui.gadget, "base/theme/modules/ofono",
414                            "e/modules/ofono/main");
415
416    inst->path = NULL;
417    inst->name = NULL;
418    inst->powered = EINA_FALSE;
419    inst->int_powered = 0;
420    inst->status = NULL;
421    inst->op = NULL;
422    inst->strength = 0;
423    inst->modem_element = NULL;
424    inst->netreg_element = NULL;
425
426    inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->ui.gadget);
427    inst->gcc->data = inst;
428
429    evas_object_event_callback_add
430      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_DOWN, _ofono_cb_mouse_down, inst);
431    evas_object_event_callback_add
432      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_IN, _ofono_cb_mouse_in, inst);
433    evas_object_event_callback_add
434      (inst->ui.gadget, EVAS_CALLBACK_MOUSE_OUT, _ofono_cb_mouse_out, inst);
435
436    _ofono_gadget_update(inst);
437
438    ctxt->instances = eina_list_append(ctxt->instances, inst);
439
440    return inst->gcc;
441 }
442
443 static void
444 _gc_shutdown(E_Gadcon_Client *gcc)
445 {
446    E_Ofono_Module_Context *ctxt;
447    E_Ofono_Instance *inst;
448
449    if (!ofono_mod)
450      return;
451
452    ctxt = ofono_mod->data;
453    if (!ctxt)
454      return;
455
456    inst = gcc->data;
457    if (!inst)
458      return;
459
460    if (inst->popup)
461      _ofono_popup_del(inst);
462    if (inst->tip)
463      _ofono_tip_del(inst);
464
465    evas_object_del(inst->ui.gadget);
466
467    eina_stringshare_del(inst->path);
468    eina_stringshare_del(inst->name);
469    eina_stringshare_del(inst->status);
470    eina_stringshare_del(inst->op);
471
472    ctxt->instances = eina_list_remove(ctxt->instances, inst);
473
474    E_FREE(inst);
475 }
476
477 static void
478 _gc_orient(E_Gadcon_Client       *gcc,
479            E_Gadcon_Orient orient __UNUSED__)
480 {
481    e_gadcon_client_aspect_set(gcc, 16, 16);
482    e_gadcon_client_min_size_set(gcc, 16, 16);
483 }
484
485 static const char *
486 _gc_label(const E_Gadcon_Client_Class *client_class __UNUSED__)
487 {
488    return _(_e_ofono_Name);
489 }
490
491 static Evas_Object *
492 _gc_icon(const E_Gadcon_Client_Class *client_class __UNUSED__,
493          Evas                               *evas)
494 {
495    Evas_Object *o;
496
497    o = edje_object_add(evas);
498    edje_object_file_set(o, e_ofono_theme_path(), "icon");
499    return o;
500 }
501
502 static const char *
503 _gc_id_new(const E_Gadcon_Client_Class *client_class __UNUSED__)
504 {
505    E_Ofono_Module_Context *ctxt;
506    Eina_List *instances;
507
508    if (!ofono_mod)
509      return NULL;
510
511    ctxt = ofono_mod->data;
512    if (!ctxt)
513      return NULL;
514
515    instances = ctxt->instances;
516    snprintf(tmpbuf, sizeof(tmpbuf), "ofono.%d", eina_list_count(instances));
517    return tmpbuf;
518 }
519
520 static const E_Gadcon_Client_Class _gc_class =
521 {
522    GADCON_CLIENT_CLASS_VERSION, _e_ofono_name,
523    {
524       _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
525       e_gadcon_site_is_not_toolbar
526    },
527    E_GADCON_CLIENT_STYLE_PLAIN
528 };
529
530 EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, _e_ofono_Name};
531
532 static Eina_Bool
533 _ofono_manager_changed_do(void *data)
534 {
535    E_Ofono_Module_Context *ctxt = data;
536
537    ctxt->poller.manager_changed = NULL;
538    return ECORE_CALLBACK_CANCEL;
539 }
540
541 static void
542 _ofono_manager_changed(void                          *data,
543                        const E_Ofono_Element *element __UNUSED__)
544 {
545    E_Ofono_Module_Context *ctxt = data;
546    if (ctxt->poller.manager_changed)
547      ecore_poller_del(ctxt->poller.manager_changed);
548    ctxt->poller.manager_changed = ecore_poller_add
549        (ECORE_POLLER_CORE, 1, _ofono_manager_changed_do, ctxt);
550 }
551
552 static Eina_Bool
553 _ofono_event_manager_in(void       *data,
554                         int type    __UNUSED__,
555                         void *event __UNUSED__)
556 {
557    E_Ofono_Element *element;
558    E_Ofono_Module_Context *ctxt = data;
559    E_Ofono_Instance *inst;
560    Eina_List *l;
561
562    DBG("manager in");
563
564    ctxt->has_manager = EINA_TRUE;
565
566    element = e_ofono_manager_get();
567    e_ofono_element_listener_add(element, _ofono_manager_changed, ctxt, NULL);
568
569    EINA_LIST_FOREACH(ctxt->instances, l, inst)
570      _ofono_gadget_update(inst);
571
572    return ECORE_CALLBACK_PASS_ON;
573 }
574
575 static Eina_Bool
576 _ofono_event_manager_out(void       *data,
577                          int type    __UNUSED__,
578                          void *event __UNUSED__)
579 {
580    E_Ofono_Module_Context *ctxt = data;
581    E_Ofono_Instance *inst;
582    Eina_List *l;
583
584    DBG("manager out");
585
586    ctxt->has_manager = EINA_FALSE;
587
588    EINA_LIST_FOREACH(ctxt->instances, l, inst)
589      _ofono_gadget_update(inst);
590
591    return ECORE_CALLBACK_PASS_ON;
592 }
593
594 static Eina_Bool
595 _eofono_event_element_add(void    *data,
596                           int type __UNUSED__,
597                           void    *info)
598 {
599    E_Ofono_Element *element = info;
600    E_Ofono_Module_Context *ctxt = data;
601    E_Ofono_Instance *inst;
602    Eina_List *l;
603    Eina_Bool have_inst = EINA_FALSE;
604
605    DBG(">>> %s %s", element->path, element->interface);
606
607    /* is there any instance taking care of this modem already? */
608    EINA_LIST_FOREACH(ctxt->instances, l, inst)
609      if ((inst->path) && (inst->path == element->path))
610        {
611           have_inst = EINA_TRUE;
612           break;
613        }
614
615    /* if no instance is handling this, is there any instance available */
616    if ((!have_inst) && (e_ofono_element_is_modem(element)))
617      EINA_LIST_FOREACH(ctxt->instances, l, inst)
618        if (!inst->path)
619          {
620             inst->path = eina_stringshare_ref(element->path);
621             DBG("bound %s to an ofono module instance", inst->path);
622             have_inst = EINA_TRUE;
623             break;
624          }
625
626    /* if still orphan, do nothing */
627    if (!have_inst)
628      return ECORE_CALLBACK_PASS_ON;
629
630    if (e_ofono_element_is_modem(element))
631      inst->modem_element = element;
632    else if (e_ofono_element_is_netreg(element))
633      inst->netreg_element = element;
634
635    _ofono_gadget_update(inst);
636
637    return ECORE_CALLBACK_PASS_ON;
638 }
639
640 static Eina_Bool
641 _eofono_event_element_del(void    *data,
642                           int type __UNUSED__,
643                           void    *info)
644 {
645    E_Ofono_Element *element = info;
646    E_Ofono_Module_Context *ctxt = data;
647    E_Ofono_Instance *inst;
648    Eina_List *l;
649    Eina_Bool inst_found = EINA_FALSE;
650
651    DBG("<<< %s %s", element->path, element->interface);
652
653    EINA_LIST_FOREACH(ctxt->instances, l, inst)
654      if ((inst->path) && (inst->path == element->path))
655        {
656           inst_found = EINA_TRUE;
657           break;
658        }
659
660    if (!inst_found)
661      return ECORE_CALLBACK_PASS_ON;
662
663    if (e_ofono_element_is_modem(element))
664      {
665         inst->modem_element = NULL;
666         eina_stringshare_replace(&inst->name, NULL);
667         inst->powered = EINA_FALSE;
668      }
669    else if (e_ofono_element_is_netreg(element))
670      {
671         inst->netreg_element = NULL;
672         eina_stringshare_replace(&inst->status, NULL);
673         eina_stringshare_replace(&inst->op, NULL);
674         inst->strength = 0;
675      }
676
677    _ofono_gadget_update(inst);
678
679    return ECORE_CALLBACK_PASS_ON;
680 }
681
682 static Eina_Bool
683 _eofono_event_element_updated(void    *data,
684                               int type __UNUSED__,
685                               void    *event_info)
686 {
687    E_Ofono_Element *element = event_info;
688    E_Ofono_Module_Context *ctxt = data;
689    E_Ofono_Instance *inst;
690    Eina_List *l;
691    Eina_Bool inst_found = EINA_FALSE;
692    const char *tmp;
693
694    DBG("!!! %s %s", element->path, element->interface);
695
696    EINA_LIST_FOREACH(ctxt->instances, l, inst)
697      if ((inst->path) && (inst->path == element->path))
698        {
699           inst_found = EINA_TRUE;
700           break;
701        }
702
703    if (!inst_found)
704      return ECORE_CALLBACK_PASS_ON;
705
706    if (e_ofono_element_is_modem(element))
707      {
708         if (!e_ofono_modem_powered_get(element, &(inst->powered)))
709           inst->powered = 0;
710
711         if (!e_ofono_modem_name_get(element, &tmp))
712           tmp = NULL;
713         if ((!tmp) || (!tmp[0]))
714           tmp = inst->path;
715         eina_stringshare_replace(&inst->name, tmp);
716
717         DBG("!!! powered = %d, name = %s", inst->powered, inst->name);
718      }
719    else if (e_ofono_element_is_netreg(element))
720      {
721         if (!e_ofono_netreg_status_get(element, &tmp))
722           tmp = NULL;
723         eina_stringshare_replace(&inst->status, tmp);
724
725         if (!e_ofono_netreg_operator_get(element, &tmp))
726           tmp = NULL;
727         eina_stringshare_replace(&inst->op, tmp);
728
729         if (!e_ofono_netreg_strength_get(element, &(inst->strength)))
730           inst->strength = 0;
731
732         DBG("!!! status = %s, operator = %s, strength = %d",
733             inst->status, inst->op, inst->strength);
734      }
735
736    _ofono_gadget_update(inst);
737
738    return ECORE_CALLBACK_PASS_ON;
739 }
740
741 static void
742 _ofono_events_register(E_Ofono_Module_Context *ctxt)
743 {
744    ctxt->event.manager_in = ecore_event_handler_add
745        (E_OFONO_EVENT_MANAGER_IN, _ofono_event_manager_in, ctxt);
746    ctxt->event.manager_out = ecore_event_handler_add
747        (E_OFONO_EVENT_MANAGER_OUT, _ofono_event_manager_out, ctxt);
748    ctxt->event.element_add = ecore_event_handler_add
749        (E_OFONO_EVENT_ELEMENT_ADD, _eofono_event_element_add, ctxt);
750    ctxt->event.element_del = ecore_event_handler_add
751        (E_OFONO_EVENT_ELEMENT_DEL, _eofono_event_element_del, ctxt);
752    ctxt->event.element_updated = ecore_event_handler_add
753        (E_OFONO_EVENT_ELEMENT_UPDATED, _eofono_event_element_updated, ctxt);
754 }
755
756 static void
757 _ofono_events_unregister(E_Ofono_Module_Context *ctxt)
758 {
759    if (ctxt->event.manager_in)
760      ecore_event_handler_del(ctxt->event.manager_in);
761    if (ctxt->event.manager_out)
762      ecore_event_handler_del(ctxt->event.manager_out);
763    if (ctxt->event.element_add)
764      ecore_event_handler_del(ctxt->event.element_add);
765    if (ctxt->event.element_del)
766      ecore_event_handler_del(ctxt->event.element_del);
767    if (ctxt->event.element_updated)
768      ecore_event_handler_del(ctxt->event.element_updated);
769 }
770
771 EAPI void *
772 e_modapi_init(E_Module *m)
773 {
774    E_Ofono_Module_Context *ctxt;
775    E_DBus_Connection *c;
776
777    c = e_dbus_bus_get(DBUS_BUS_SYSTEM);
778    if (!c)
779      goto error_dbus_bus_get;
780    if (!e_ofono_system_init(c))
781      goto error_ofono_system_init;
782
783    ctxt = E_NEW(E_Ofono_Module_Context, 1);
784    if (!ctxt)
785      goto error_ofono_context;
786
787    ofono_mod = m;
788
789    if (_e_ofono_module_log_dom < 0)
790      {
791         _e_ofono_module_log_dom = eina_log_domain_register("e_module_ofono",
792                                                            EINA_COLOR_ORANGE);
793         if (_e_ofono_module_log_dom < 0)
794           {
795              EINA_LOG_CRIT("could not register logging domain e_module_ofono");
796              goto error_log_domain;
797           }
798      }
799
800    e_gadcon_provider_register(&_gc_class);
801
802    _ofono_events_register(ctxt);
803
804    return ctxt;
805
806 error_log_domain:
807    _e_ofono_module_log_dom = -1;
808    ofono_mod = NULL;
809    E_FREE(ctxt);
810 error_ofono_context:
811    e_ofono_system_shutdown();
812 error_ofono_system_init:
813 error_dbus_bus_get:
814    return NULL;
815 }
816
817 static void
818 _ofono_instances_free(E_Ofono_Module_Context *ctxt)
819 {
820    while (ctxt->instances)
821      {
822         E_Ofono_Instance *inst;
823
824         inst = ctxt->instances->data;
825
826         if (inst->popup)
827           _ofono_popup_del(inst);
828         if (inst->tip)
829           _ofono_tip_del(inst);
830
831         e_object_del(E_OBJECT(inst->gcc));
832      }
833 }
834
835 EAPI int
836 e_modapi_shutdown(E_Module *m)
837 {
838    E_Ofono_Module_Context *ctxt;
839    E_Ofono_Element *element;
840
841    ctxt = m->data;
842    if (!ctxt)
843      return 0;
844
845    element = e_ofono_manager_get();
846    e_ofono_element_listener_del(element, _ofono_manager_changed, ctxt);
847
848    _ofono_events_unregister(ctxt);
849
850    _ofono_instances_free(ctxt);
851
852    e_gadcon_provider_unregister(&_gc_class);
853
854    if (ctxt->poller.manager_changed)
855      ecore_poller_del(ctxt->poller.manager_changed);
856
857    E_FREE(ctxt);
858    ofono_mod = NULL;
859
860    e_ofono_system_shutdown();
861
862    return 1;
863 }
864
865 EAPI int
866 e_modapi_save(E_Module *m)
867 {
868    E_Ofono_Module_Context *ctxt;
869
870    ctxt = m->data;
871    if (!ctxt)
872      return 0;
873    return 1;
874 }
875