1 /* TODO: config dialog to select which modem to monitor */
4 #include "e_mod_main.h"
6 static E_Module *ofono_mod = NULL;
7 static char tmpbuf[PATH_MAX];
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;
13 static void _ofono_gadget_update(E_Ofono_Instance *inst);
14 static void _ofono_tip_update(E_Ofono_Instance *inst);
17 e_ofono_theme_path(void)
19 #define TF "/e-module-ofono.edj"
22 dirlen = strlen(ofono_mod->dir);
23 if (dirlen >= sizeof(tmpbuf) - sizeof(TF))
26 memcpy(tmpbuf, ofono_mod->dir, dirlen);
27 memcpy(tmpbuf + dirlen, TF, sizeof(TF));
33 static void _ofono_popup_del(E_Ofono_Instance *inst);
36 _ofono_popup_input_window_mouse_up_cb(void *data,
40 Ecore_Event_Mouse_Button *ev = event;
41 E_Ofono_Instance *inst = data;
43 if (ev->window != inst->ui.input.win)
44 return ECORE_CALLBACK_PASS_ON;
46 _ofono_popup_del(inst);
48 return ECORE_CALLBACK_PASS_ON;
52 _ofono_popup_input_window_key_down_cb(void *data,
56 Ecore_Event_Key *ev = event;
57 E_Ofono_Instance *inst = data;
60 if (ev->window != inst->ui.input.win)
61 return ECORE_CALLBACK_PASS_ON;
64 if (!strcmp(keysym, "Escape"))
65 _ofono_popup_del(inst);
67 return ECORE_CALLBACK_PASS_ON;
71 _ofono_popup_input_window_destroy(E_Ofono_Instance *inst)
73 ecore_x_window_free(inst->ui.input.win);
74 inst->ui.input.win = 0;
76 ecore_event_handler_del(inst->ui.input.mouse_up);
77 inst->ui.input.mouse_up = NULL;
79 ecore_event_handler_del(inst->ui.input.key_down);
80 inst->ui.input.key_down = NULL;
84 _ofono_popup_input_window_create(E_Ofono_Instance *inst)
86 Ecore_X_Window_Configure_Mask mask;
87 Ecore_X_Window w, popup_w;
90 man = e_manager_current_get();
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);
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);
104 inst->ui.input.key_down =
105 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
106 _ofono_popup_input_window_key_down_cb, inst);
108 inst->ui.input.win = w;
112 _ofono_toggle_powered_cb(void *data,
113 DBusMessage *msg __UNUSED__,
116 E_Ofono_Instance *inst = data;
118 if ((error) && (dbus_error_is_set(error)))
119 _ofono_dbus_error_show(_("Failed to power modem on/off."), error);
121 DBG("new powered value set");
123 e_widget_disabled_set(inst->ui.powered, (int)EINA_FALSE);
124 inst->powered_pending = EINA_FALSE;
126 dbus_error_free(error);
130 _ofono_popup_cb_powered_changed(void *data,
132 void *event __UNUSED__)
134 E_Ofono_Instance *inst = data;
135 E_Ofono_Module_Context *ctxt = inst->ctxt;
136 Eina_Bool powered = e_widget_check_checked_get(obj);
138 if ((!ctxt) || (!ctxt->has_manager))
140 _ofono_operation_error_show(_("oFono Daemon is not running."));
144 if (!e_ofono_modem_powered_set(inst->modem_element, powered,
145 _ofono_toggle_powered_cb, inst))
147 _ofono_operation_error_show(_("Cannot toggle modem's powered state."));
150 e_widget_disabled_set(obj, EINA_TRUE);
151 inst->powered_pending = EINA_TRUE;
152 DBG("powered = %d pending", !inst->powered);
156 _ofono_popup_update(E_Ofono_Instance *inst)
159 e_widget_label_text_set(inst->ui.name, inst->name);
161 e_widget_label_text_set(inst->ui.name, _("No modem available"));
162 e_widget_check_checked_set(inst->ui.powered, inst->powered);
166 _ofono_popup_del(E_Ofono_Instance *inst)
168 _ofono_popup_input_window_destroy(inst);
169 e_object_del(E_OBJECT(inst->popup));
174 _ofono_popup_new(E_Ofono_Instance *inst)
181 e_gadcon_popup_show(inst->popup);
185 inst->popup = e_gadcon_popup_new(inst->gcc);
186 evas = inst->popup->win->evas;
188 inst->ui.table = e_widget_table_add(evas, 0);
191 inst->ui.name = e_widget_label_add(evas, inst->name);
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);
198 inst->int_powered = inst->powered;
199 inst->ui.powered = e_widget_check_add(evas, _("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);
209 _ofono_popup_update(inst);
211 e_widget_size_min_get(inst->ui.table, &mw, &mh);
212 e_widget_size_min_set(inst->ui.table, mw, mh);
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);
220 _ofono_menu_cb_post(void *data,
221 E_Menu *menu __UNUSED__)
223 E_Ofono_Instance *inst = data;
224 if ((!inst) || (!inst->menu))
228 e_object_del(E_OBJECT(inst->menu));
234 _ofono_menu_new(E_Ofono_Instance *inst,
235 Evas_Event_Mouse_Down *ev)
241 zone = e_util_zone_current_get(e_manager_current_get());
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);
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);
255 _ofono_tip_new(E_Ofono_Instance *inst)
259 inst->tip = e_gadcon_popup_new(inst->gcc);
260 if (!inst->tip) return;
262 e = inst->tip->win->evas;
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");
268 _ofono_tip_update(inst);
270 e_gadcon_popup_content_set(inst->tip, inst->o_tip);
271 e_gadcon_popup_show(inst->tip);
275 _ofono_tip_del(E_Ofono_Instance *inst)
277 evas_object_del(inst->o_tip);
278 e_object_del(E_OBJECT(inst->tip));
284 _ofono_cb_mouse_down(void *data,
285 Evas *evas __UNUSED__,
286 Evas_Object *obj __UNUSED__,
289 E_Ofono_Instance *inst;
290 Evas_Event_Mouse_Down *ev;
300 _ofono_popup_new(inst);
302 _ofono_popup_del(inst);
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);
311 _ofono_cb_mouse_in(void *data,
312 Evas *evas __UNUSED__,
313 Evas_Object *obj __UNUSED__,
314 void *event __UNUSED__)
316 E_Ofono_Instance *inst = data;
321 _ofono_tip_new(inst);
325 _ofono_cb_mouse_out(void *data,
326 Evas *evas __UNUSED__,
327 Evas_Object *obj __UNUSED__,
328 void *event __UNUSED__)
330 E_Ofono_Instance *inst = data;
335 _ofono_tip_del(inst);
339 _ofono_edje_view_update(E_Ofono_Instance *inst,
342 Edje_Message_Int msg;
345 if (!inst->ctxt->has_manager)
347 edje_object_signal_emit(o, "e,unavailable", "e");
348 edje_object_part_text_set(o, "e.text.error", _("ofonod is not running"));
352 edje_object_signal_emit(o, "e,available", "e");
355 edje_object_part_text_set(o, "e.text.name", inst->name);
357 edje_object_part_text_set(o, "e.text.name", _("Unknown name"));
361 edje_object_part_text_set(o, "e.text.error", _("Modem powered off"));
362 edje_object_signal_emit(o, "e,netinfo,unavailable", "e");
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");
374 edje_object_part_text_set(o, "e.text.status", _("Unknown status"));
378 edje_object_part_text_set(o, "e.text.op", inst->op);
379 edje_object_signal_emit(o, "e,netinfo,available", "e");
382 edje_object_part_text_set(o, "e.text.op", _("Unknown operator"));
384 msg.val = inst->strength;
385 edje_object_message_send(o, EDJE_MESSAGE_INT, 1, &msg);
389 _ofono_tip_update(E_Ofono_Instance *inst)
391 _ofono_edje_view_update(inst, inst->o_tip);
395 _ofono_gadget_update(E_Ofono_Instance *inst)
397 E_Ofono_Module_Context *ctxt = inst->ctxt;
399 if (!ctxt->has_manager && inst->popup)
400 _ofono_popup_del(inst);
403 _ofono_popup_update(inst);
405 _ofono_tip_update(inst);
407 _ofono_edje_view_update(inst, inst->ui.gadget);
410 /* Gadcon Api Functions */
412 static E_Gadcon_Client *
413 _gc_init(E_Gadcon *gc,
418 E_Ofono_Instance *inst;
419 E_Ofono_Module_Context *ctxt;
424 ctxt = ofono_mod->data;
426 inst = E_NEW(E_Ofono_Instance, 1);
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");
434 inst->powered = EINA_FALSE;
435 inst->int_powered = 0;
439 inst->modem_element = NULL;
440 inst->netreg_element = NULL;
442 inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->ui.gadget);
443 inst->gcc->data = inst;
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);
452 _ofono_gadget_update(inst);
454 ctxt->instances = eina_list_append(ctxt->instances, inst);
460 _gc_shutdown(E_Gadcon_Client *gcc)
462 E_Ofono_Module_Context *ctxt;
463 E_Ofono_Instance *inst;
468 ctxt = ofono_mod->data;
478 e_menu_post_deactivate_callback_set(inst->menu, NULL, NULL);
479 e_object_del(E_OBJECT(inst->menu));
482 _ofono_popup_del(inst);
484 _ofono_tip_del(inst);
486 evas_object_del(inst->ui.gadget);
488 eina_stringshare_del(inst->path);
489 eina_stringshare_del(inst->name);
490 eina_stringshare_del(inst->status);
491 eina_stringshare_del(inst->op);
493 ctxt->instances = eina_list_remove(ctxt->instances, inst);
499 _gc_orient(E_Gadcon_Client *gcc,
500 E_Gadcon_Orient orient __UNUSED__)
502 e_gadcon_client_aspect_set(gcc, 16, 16);
503 e_gadcon_client_min_size_set(gcc, 16, 16);
507 _gc_label(E_Gadcon_Client_Class *client_class __UNUSED__)
509 return _(_e_ofono_Name);
513 _gc_icon(E_Gadcon_Client_Class *client_class __UNUSED__,
518 o = edje_object_add(evas);
519 edje_object_file_set(o, e_ofono_theme_path(), "icon");
524 _gc_id_new(E_Gadcon_Client_Class *client_class __UNUSED__)
526 E_Ofono_Module_Context *ctxt;
527 Eina_List *instances;
532 ctxt = ofono_mod->data;
536 instances = ctxt->instances;
537 snprintf(tmpbuf, sizeof(tmpbuf), "ofono.%d", eina_list_count(instances));
541 static const E_Gadcon_Client_Class _gc_class =
543 GADCON_CLIENT_CLASS_VERSION, _e_ofono_name,
545 _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
546 e_gadcon_site_is_not_toolbar
548 E_GADCON_CLIENT_STYLE_PLAIN
551 EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, _e_ofono_Name};
554 _ofono_manager_changed_do(void *data)
556 E_Ofono_Module_Context *ctxt = data;
558 ctxt->poller.manager_changed = NULL;
559 return ECORE_CALLBACK_CANCEL;
563 _ofono_manager_changed(void *data,
564 const E_Ofono_Element *element __UNUSED__)
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);
574 _ofono_event_manager_in(void *data,
576 void *event __UNUSED__)
578 E_Ofono_Element *element;
579 E_Ofono_Module_Context *ctxt = data;
580 E_Ofono_Instance *inst;
585 ctxt->has_manager = EINA_TRUE;
587 element = e_ofono_manager_get();
588 e_ofono_element_listener_add(element, _ofono_manager_changed, ctxt, NULL);
590 EINA_LIST_FOREACH(ctxt->instances, l, inst)
591 _ofono_gadget_update(inst);
593 return ECORE_CALLBACK_PASS_ON;
597 _ofono_event_manager_out(void *data,
599 void *event __UNUSED__)
601 E_Ofono_Module_Context *ctxt = data;
602 E_Ofono_Instance *inst;
607 ctxt->has_manager = EINA_FALSE;
609 EINA_LIST_FOREACH(ctxt->instances, l, inst)
610 _ofono_gadget_update(inst);
612 return ECORE_CALLBACK_PASS_ON;
616 _eofono_event_element_add(void *data,
620 E_Ofono_Element *element = info;
621 E_Ofono_Module_Context *ctxt = data;
622 E_Ofono_Instance *inst;
624 Eina_Bool have_inst = EINA_FALSE;
626 DBG(">>> %s %s", element->path, element->interface);
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))
632 have_inst = EINA_TRUE;
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)
641 inst->path = eina_stringshare_ref(element->path);
642 DBG("bound %s to an ofono module instance", inst->path);
643 have_inst = EINA_TRUE;
647 /* if still orphan, do nothing */
649 return ECORE_CALLBACK_PASS_ON;
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;
656 _ofono_gadget_update(inst);
658 return ECORE_CALLBACK_PASS_ON;
662 _eofono_event_element_del(void *data,
666 E_Ofono_Element *element = info;
667 E_Ofono_Module_Context *ctxt = data;
668 E_Ofono_Instance *inst;
670 Eina_Bool inst_found = EINA_FALSE;
672 DBG("<<< %s %s", element->path, element->interface);
674 EINA_LIST_FOREACH(ctxt->instances, l, inst)
675 if ((inst->path) && (inst->path == element->path))
677 inst_found = EINA_TRUE;
682 return ECORE_CALLBACK_PASS_ON;
684 if (e_ofono_element_is_modem(element))
686 inst->modem_element = NULL;
687 eina_stringshare_replace(&inst->name, NULL);
688 inst->powered = EINA_FALSE;
690 else if (e_ofono_element_is_netreg(element))
692 inst->netreg_element = NULL;
693 eina_stringshare_replace(&inst->status, NULL);
694 eina_stringshare_replace(&inst->op, NULL);
698 _ofono_gadget_update(inst);
700 return ECORE_CALLBACK_PASS_ON;
704 _eofono_event_element_updated(void *data,
708 E_Ofono_Element *element = event_info;
709 E_Ofono_Module_Context *ctxt = data;
710 E_Ofono_Instance *inst;
712 Eina_Bool inst_found = EINA_FALSE;
715 DBG("!!! %s %s", element->path, element->interface);
717 EINA_LIST_FOREACH(ctxt->instances, l, inst)
718 if ((inst->path) && (inst->path == element->path))
720 inst_found = EINA_TRUE;
725 return ECORE_CALLBACK_PASS_ON;
727 if (e_ofono_element_is_modem(element))
729 if (!e_ofono_modem_powered_get(element, &(inst->powered)))
732 if (!e_ofono_modem_name_get(element, &tmp))
734 if ((!tmp) || (!tmp[0]))
736 eina_stringshare_replace(&inst->name, tmp);
738 DBG("!!! powered = %d, name = %s", inst->powered, inst->name);
740 else if (e_ofono_element_is_netreg(element))
742 if (!e_ofono_netreg_status_get(element, &tmp))
744 eina_stringshare_replace(&inst->status, tmp);
746 if (!e_ofono_netreg_operator_get(element, &tmp))
748 eina_stringshare_replace(&inst->op, tmp);
750 if (!e_ofono_netreg_strength_get(element, &(inst->strength)))
753 DBG("!!! status = %s, operator = %s, strength = %d",
754 inst->status, inst->op, inst->strength);
757 _ofono_gadget_update(inst);
759 return ECORE_CALLBACK_PASS_ON;
763 _ofono_events_register(E_Ofono_Module_Context *ctxt)
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);
778 _ofono_events_unregister(E_Ofono_Module_Context *ctxt)
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);
793 e_modapi_init(E_Module *m)
795 E_Ofono_Module_Context *ctxt;
796 E_DBus_Connection *c;
798 c = e_dbus_bus_get(DBUS_BUS_SYSTEM);
800 goto error_dbus_bus_get;
801 if (!e_ofono_system_init(c))
802 goto error_ofono_system_init;
804 ctxt = E_NEW(E_Ofono_Module_Context, 1);
806 goto error_ofono_context;
810 if (_e_ofono_module_log_dom < 0)
812 _e_ofono_module_log_dom = eina_log_domain_register("e_module_ofono",
814 if (_e_ofono_module_log_dom < 0)
816 EINA_LOG_CRIT("could not register logging domain e_module_ofono");
817 goto error_log_domain;
821 e_gadcon_provider_register(&_gc_class);
823 _ofono_events_register(ctxt);
828 _e_ofono_module_log_dom = -1;
832 e_ofono_system_shutdown();
833 error_ofono_system_init:
839 _ofono_instances_free(E_Ofono_Module_Context *ctxt)
841 while (ctxt->instances)
843 E_Ofono_Instance *inst;
845 inst = ctxt->instances->data;
848 _ofono_popup_del(inst);
850 _ofono_tip_del(inst);
852 e_object_del(E_OBJECT(inst->gcc));
857 e_modapi_shutdown(E_Module *m)
859 E_Ofono_Module_Context *ctxt;
860 E_Ofono_Element *element;
866 element = e_ofono_manager_get();
867 e_ofono_element_listener_del(element, _ofono_manager_changed, ctxt);
869 _ofono_events_unregister(ctxt);
871 _ofono_instances_free(ctxt);
873 e_gadcon_provider_unregister(&_gc_class);
875 if (ctxt->poller.manager_changed)
876 ecore_poller_del(ctxt->poller.manager_changed);
881 e_ofono_system_shutdown();
887 e_modapi_save(E_Module *m)
889 E_Ofono_Module_Context *ctxt;