From 5d2150998606d6180520a14cc7b0e5ad904f733c Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Sat, 2 Jan 2010 05:25:27 +0000 Subject: [PATCH] connman improvements, almost fully usable. * interacts with offline mode (menu > settings > mode > offline) * asks password if service requrires a password or failed to connect. * on server exit stringshares go wrong and it crashes. It is very weird that this does not happen with e_dbus_connman_test and valgrind reports no error there. It is easy to reproduce, but hard to track as things are asynchronously and stringshare will report the error on the last _del(), that might the correct one and the spurious happened before. * part of the usability issues are due connman server (connmand), it should have an "authentication failed" error (instead of generic "Failed: input/output error" and it should stop entering "InProgress" when it is not (often happens when one enters invalid password, gets an Failed i/o error, then system keeps into InProgress). Toggling offline mode might help reset the status. SVN revision: 44847 --- data/themes/default.edc | 140 ++++- data/themes/images/Makefile.am | 6 +- .../images/connman-disconnect-offline.png | Bin 0 -> 7200 bytes src/modules/connman/e_mod_main.c | 519 +++++++++++++++--- src/modules/connman/e_mod_main.h | 2 + 5 files changed, 586 insertions(+), 81 deletions(-) create mode 100644 data/themes/images/connman-disconnect-offline.png diff --git a/data/themes/default.edc b/data/themes/default.edc index 7f13ade4b..5963f6116 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -6997,6 +6997,7 @@ collections { /* begin the collection of edje groups that are in this file */ // e,changed,ipv4_address,{yes,no} // // PARTS: +// e.text.offline_mode (filled with offline message) // e.text.name // e.text.error // e.text.technology @@ -7008,6 +7009,7 @@ collections { /* begin the collection of edje groups that are in this file */ group { name: "e/modules/connman/main"; images { image: "connman-disconnect.png" COMP; + image: "connman-disconnect-offline.png" COMP; image: "connman-ethernet.png" COMP; image: "connman-wifi-good.png" COMP; image: "connman-wifi-medium.png" COMP; @@ -7113,6 +7115,22 @@ collections { /* begin the collection of edje groups that are in this file */ after: "state,pulse,0"; } + program { name: "e,changed,state,failure"; + signal: "e,changed,state,failure"; + source: "e"; + script { + stop_program(PROGRAM:"state,pulse,0"); + stop_program(PROGRAM:"state,pulse,1"); + } + after: "state,failure,apply"; + } + program { name: "state,failure,apply"; + action: STATE_SET "default" 0.0; + target: "state-clipper"; + transition: LINEAR 0.1; + // TODO: something else to notify failure? + } + program { name: "state,pulse,0"; action: STATE_SET "default" 0.0; target: "state-clipper"; @@ -7152,6 +7170,10 @@ collections { /* begin the collection of edje groups that are in this file */ fixed: 1 1; image.normal: "connman-disconnect.png"; } + description { state: "offline" 0.0; + inherit: "default" 0.0; + image.normal: "connman-disconnect-offline.png"; + } } part { name: "ethernet-visibility"; @@ -7236,6 +7258,19 @@ collections { /* begin the collection of edje groups that are in this file */ // add wimax, cellular, bluetooth } + program { + signal: "e,changed,offline_mode,yes"; + source: "e"; + action: STATE_SET "offline" 0.0; + target: "disconnected"; + } + program { + signal: "e,changed,offline_mode,no"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "disconnected"; + } + program { name: "e,changed,technology,none"; signal: "e,changed,technology,none"; source: "e"; @@ -7335,10 +7370,11 @@ collections { /* begin the collection of edje groups that are in this file */ images { image: "inset_sunk.png" COMP; image: "connman-disconnect.png" COMP; + image: "connman-disconnect-offline.png" COMP; image: "connman-ethernet.png" COMP; image: "connman-wifi.png" COMP; } - min: 300 148; + min: 350 148; script { public message(Msg_Type:type, id, ...) { if ((type == MSG_INT) && (id == 1)) { @@ -7408,6 +7444,22 @@ collections { /* begin the collection of edje groups that are in this file */ after: "state,pulse,0"; } + program { name: "e,changed,state,failure"; + signal: "e,changed,state,failure"; + source: "e"; + script { + stop_program(PROGRAM:"state,pulse,0"); + stop_program(PROGRAM:"state,pulse,1"); + } + after: "state,failure,apply"; + } + program { name: "state,failure,apply"; + action: STATE_SET "default" 0.0; + target: "state-clipper"; + transition: LINEAR 0.1; + // TODO: something else to notify failure? + } + program { name: "state,pulse,0"; action: STATE_SET "default" 0.0; target: "state-clipper"; @@ -7470,6 +7522,10 @@ collections { /* begin the collection of edje groups that are in this file */ rel1.to: "technology"; rel2.to: "technology"; } + description { state: "offline" 0.0; + inherit: "default" 0.0; + image.normal: "connman-disconnect-offline.png"; + } } programs { program { @@ -7564,6 +7620,19 @@ collections { /* begin the collection of edje groups that are in this file */ // add wimax, cellular, bluetooth } + program { + signal: "e,changed,offline_mode,yes"; + source: "e"; + action: STATE_SET "offline" 0.0; + target: "disconnected"; + } + program { + signal: "e,changed,offline_mode,no"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "disconnected"; + } + program { name: "e,changed,technology,none"; signal: "e,changed,technology,none"; source: "e"; @@ -7659,6 +7728,7 @@ collections { /* begin the collection of edje groups that are in this file */ state: "default" 0.0; color: 16 16 16 255; align: 0.0 0.0; + fixed: 1 1; rel1 { to_x: "technology"; to_y: "e.text.name"; @@ -7687,7 +7757,7 @@ collections { /* begin the collection of edje groups that are in this file */ description { state: "default" 0.0; min: 100 10; - max: 100 99999; + max: 99999 99999; rel1 { to_x: "technology"; to_y: "strength"; @@ -7695,10 +7765,9 @@ collections { /* begin the collection of edje groups that are in this file */ offset: 10 -2; } rel2 { - to_x: "technology"; to_y: "strength"; relative: 1.0 1.0; - offset: 109 1; + offset: -10 1; } image { normal: "inset_sunk.png"; @@ -7964,6 +8033,69 @@ collections { /* begin the collection of edje groups that are in this file */ target: "e.text.ipv4_address"; } } + + + part { name: "e.text.offline_mode"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + color: 16 16 16 255; + align: 0.0 0.0; + fixed: 1 1; + rel1 { + to_x: "technology"; + to_y: "e.text.ipv4_address"; + relative: 1.0 1.0; + offset: 10 10; + } + rel2 { + to_y: "e.text.ipv4_address"; + relative: 1.0 1.0; + offset: -10 25; + } + text { + font: "Sans"; + size: 10; + align: 0.0 0.0; + text: ""; + min: 1 1; + } + } + description { + state: "hidden" 0.0; + inherit: "default" 0.0; + max: 0 0; + visible: 0; + rel1 { + to_x: "technology"; + to_y: "e.text.ipv4_address"; + relative: 1.0 1.0; + offset: 0 0; + } + rel2 { /* = rel1 */ + to_x: "technology"; + to_y: "e.text.ipv4_address"; + relative: 1.0 1.0; + offset: 0 0; + } + } + } + + programs { + program { name: "e,changed,offline_mode,yes"; + signal: "e,changed,offline_mode,yes"; + source: "e"; + action: STATE_SET "default" 0.0; + target: "e.text.offline_mode"; + } + program { name: "e,changed,offline_mode,no"; + signal: "e,changed,offline_mode,no"; + source: "e"; + action: STATE_SET "hidden" 0.0; + target: "e.text.offline_mode"; + } + } } } diff --git a/data/themes/images/Makefile.am b/data/themes/images/Makefile.am index 28c2c5661..16669e548 100644 --- a/data/themes/images/Makefile.am +++ b/data/themes/images/Makefile.am @@ -573,6 +573,10 @@ exq-bar.png \ exq-bglight.png \ exq-logo.png \ connman-disconnect.png \ +connman-disconnect-offline.png \ connman-ethernet.png \ -connman-wifi.png +connman-wifi.png \ +connman-wifi-good.png \ +connman-wifi-medium.png \ +connman-wifi-bad.png diff --git a/data/themes/images/connman-disconnect-offline.png b/data/themes/images/connman-disconnect-offline.png new file mode 100644 index 0000000000000000000000000000000000000000..bcaca81a0208397e67765dee69040f9c229dde61 GIT binary patch literal 7200 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 Settings > Mode > Offline) * * IDEAS: * 1. create static connections @@ -44,6 +44,7 @@ static const char *e_str_ready = NULL; static const char *e_str_disconnect = NULL; static const char *e_str_failure = NULL; +static void _connman_service_ask_pass_and_connect(E_Connman_Service *service); static void _connman_default_service_changed_delayed(E_Connman_Module_Context *ctxt); static void _connman_gadget_update(E_Connman_Instance *inst); static void _connman_tip_update(E_Connman_Instance *inst); @@ -65,6 +66,18 @@ e_connman_theme_path(void) #undef TF } +static inline E_Connman_Service * +_connman_ctxt_find_service_stringshare(const E_Connman_Module_Context *ctxt, const char *service_path) +{ + E_Connman_Service *itr; + + EINA_INLIST_FOREACH(ctxt->services, itr) + if (itr->path == service_path) + return itr; + + return NULL; +} + static inline void _connman_dbus_error_show(const char *msg, const DBusError *error) { @@ -81,7 +94,7 @@ _connman_dbus_error_show(const char *msg, const DBusError *error) e_util_dialog_show(_("Connman Server Operation Failed"), _("Could not execute remote operation:
" "%s
" - "Server Error %s: %s"), + "Server Error %s: %s"), msg, name, error->message); } @@ -102,7 +115,7 @@ _connman_toggle_offline_mode_cb(void *data, DBusMessage *msg __UNUSED__, DBusErr { printf("DBG CONNMAN: successfuly toggled to offline mode\n"); // XXX hack: connman does not emit propertychanged for this, they need to fix it - e_connman_element_properties_sync(e_connman_manager_get()); + e_connman_manager_sync_elements(); _connman_default_service_changed_delayed(ctxt); return; } @@ -111,6 +124,14 @@ _connman_toggle_offline_mode_cb(void *data, DBusMessage *msg __UNUSED__, DBusErr dbus_error_free(error); } +static void +_connman_toggle_offline_mode_pending_cb(void *data, DBusMessage *msg, DBusError *error) +{ + E_Connman_Module_Context *ctxt = data; + ctxt->offline_mode_pending = EINA_FALSE; + _connman_toggle_offline_mode_cb(data, msg, error); +} + static void _connman_toggle_offline_mode(E_Connman_Module_Context *ctxt) { @@ -151,6 +172,174 @@ _connman_cb_toggle_offline_mode(E_Object *obj __UNUSED__, const char *params __U _connman_toggle_offline_mode(ctxt); } +struct connman_passphrase_data +{ + void (*cb)(void *data, const char *password, const char *service_path); + void *data; + const char *service_path; + char *passphrase; + E_Connman_Module_Context *ctxt; + E_Dialog *dia; + Evas_Object *entry; + Eina_Bool canceled; + int cleartext; +}; + +static void +_connman_passphrase_ask_cleartext_changed(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + struct connman_passphrase_data *d = data; + e_widget_entry_password_set(d->entry, !e_widget_check_checked_get(obj)); + e_widget_entry_readonly_set(d->entry, 0); + e_widget_focus_set(d->entry, 1); +} + +static void +_connman_passphrase_ask_ok(void *data, E_Dialog *dia) +{ + struct connman_passphrase_data *d = data; + d->canceled = EINA_FALSE; + e_object_del(E_OBJECT(dia)); +} + +static void +_connman_passphrase_ask_cancel(void *data, E_Dialog *dia) +{ + struct connman_passphrase_data *d = data; + d->canceled = EINA_TRUE; + e_object_del(E_OBJECT(dia)); +} + +static void +_connman_passphrase_ask_del(void *data) +{ + E_Dialog *dia = data; + struct connman_passphrase_data *d = e_object_data_get(E_OBJECT(dia)); + + if (d->canceled) + { + free(d->passphrase); + d->passphrase = NULL; + } + + d->cb(d->data, d->passphrase, d->service_path); + + eina_stringshare_del(d->service_path); + free(d->passphrase); + E_FREE(d); +} + +static void +_connman_passphrase_ask_key_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event) +{ + Evas_Event_Key_Down *ev = event; + struct connman_passphrase_data *d = data; + + if (strcmp(ev->keyname, "Return") == 0) + _connman_passphrase_ask_ok(d, d->dia); + else if (strcmp(ev->keyname, "Escape") == 0) + _connman_passphrase_ask_cancel(d, d->dia); +} + +static void +_connman_passphrase_ask(E_Connman_Service *service, void (*cb)(void *data, const char *password, const char *service_path), const void *data) +{ + struct connman_passphrase_data *d; + Evas_Object *list, *o; + Evas *evas; + char buf[512]; + const char *passphrase; + int mw, mh; + + if (!cb) + return; + if (!service) + { + cb((void *)data, NULL, NULL); + return; + } + + d = E_NEW(struct connman_passphrase_data, 1); + if (!d) + { + cb((void *)data, NULL, NULL); + return; + } + d->cb = cb; + d->data = (void *)data; + d->service_path = eina_stringshare_add(service->path); + d->ctxt = service->ctxt; + d->canceled = EINA_TRUE; /* closing the dialog defaults to cancel */ + d->dia = e_dialog_new(NULL, "E", "connman_ask_passphrase"); + + e_dialog_title_set(d->dia, _("ConnMan needs your passphrase")); + e_dialog_icon_set(d->dia, "dialog-ask", 64); + e_dialog_border_icon_set(d->dia, "dialog-ask"); + + evas = d->dia->win->evas; + + list = e_widget_list_add(evas, 0, 0); + + o = edje_object_add(evas); + e_theme_edje_object_set(o, "base/theme/dialog", + "e/widgets/dialog/text"); + snprintf(buf, sizeof(buf), + _("Connection Manager needs your passphrase for
" + "the service %s"), + service->name); + edje_object_part_text_set(o, "e.textblock.message", buf); + edje_object_size_min_calc(o, &mw, &mh); + evas_object_size_hint_min_set(o, mw, mh); + evas_object_resize(o, mw, mh); + evas_object_show(o); + e_widget_list_object_append(list, o, 1, 1, 0.5); + + if (!e_connman_service_passphrase_get(service->element, &passphrase)) + passphrase = NULL; + if (passphrase && passphrase[0]) + d->passphrase = strdup(passphrase); + else + d->passphrase = NULL; + + d->entry = o = e_widget_entry_add(evas, &d->passphrase, NULL, NULL, NULL); + e_widget_entry_password_set(o, 0); + evas_object_show(o); + e_widget_list_object_append(list, o, 1, 0, 0.0); + +#if 0 // NOT WORKING, e_widget_entry_password_set() changes stops editing!!! + d->cleartext = 1; + o = e_widget_check_add(evas, _("Show passphrase as clear text"), + &d->cleartext); + evas_object_smart_callback_add + (o, "changed", _connman_passphrase_ask_cleartext_changed, d); + evas_object_show(o); + e_widget_list_object_append(list, o, 1, 0, 0.0); +#endif + + e_widget_size_min_get(list, &mw, &mh); + e_dialog_content_set(d->dia, list, mw, mh); + + e_dialog_button_add + (d->dia, _("Ok"), NULL, _connman_passphrase_ask_ok, d); + e_dialog_button_add + (d->dia, _("Cancel"), NULL, _connman_passphrase_ask_cancel, d); + + evas_object_event_callback_add + (d->dia->bg_object, EVAS_CALLBACK_KEY_DOWN, + _connman_passphrase_ask_key_down, d); + + e_object_del_attach_func_set + (E_OBJECT(d->dia), _connman_passphrase_ask_del); + e_object_data_set(E_OBJECT(d->dia), d); + + e_dialog_button_focus_num(d->dia, 0); + e_widget_focus_set(d->entry, 1); + + e_dialog_resizable_set(d->dia, 1); + e_win_centered_set(d->dia->win, 1); + e_dialog_show(d->dia); +} + static void _connman_service_free(E_Connman_Service *service) { @@ -176,10 +365,13 @@ _connman_service_changed(void *data, const E_Connman_Element *element) unsigned char u8; bool b; -#define GSTR(name, getter) \ +#define GSTR(name_, getter) \ + str = NULL; \ if (!getter(element, &str)) \ str = NULL; \ - eina_stringshare_replace(&service->name, str) + if (service->name_ != str) \ + printf("changing "#name_": %s (%p) with %s (%p)\n", service->name_, service->name_, str, str); \ + eina_stringshare_replace(&service->name_, str) GSTR(name, e_connman_service_name_get); GSTR(type, e_connman_service_type_get); @@ -196,10 +388,11 @@ _connman_service_changed(void *data, const E_Connman_Element *element) u8 = 0; service->strength = u8; -#define GBOOL(name, getter) \ +#define GBOOL(name_, getter) \ + b = EINA_FALSE; \ if (!getter(element, &b)) \ b = EINA_FALSE; \ - service->name = b + service->name_ = b GBOOL(favorite, e_connman_service_favorite_get); GBOOL(auto_connect, e_connman_service_auto_connect_get); @@ -273,10 +466,11 @@ _connman_service_new(E_Connman_Module_Context *ctxt, E_Connman_Element *element) service->element = element; service->path = eina_stringshare_add(element->path); -#define GSTR(name, getter) \ +#define GSTR(name_, getter) \ + str = NULL; \ if (!getter(element, &str)) \ str = NULL; \ - service->name = eina_stringshare_add(str) + service->name_ = eina_stringshare_add(str) GSTR(name, e_connman_service_name_get); GSTR(type, e_connman_service_type_get); @@ -293,10 +487,11 @@ _connman_service_new(E_Connman_Module_Context *ctxt, E_Connman_Element *element) u8 = 0; service->strength = u8; -#define GBOOL(name, getter) \ +#define GBOOL(name_, getter) \ + b = EINA_FALSE; \ if (!getter(element, &b)) \ b = EINA_FALSE; \ - service->name = b + service->name_ = b GBOOL(favorite, e_connman_service_favorite_get); GBOOL(auto_connect, e_connman_service_auto_connect_get); @@ -310,36 +505,6 @@ _connman_service_new(E_Connman_Module_Context *ctxt, E_Connman_Element *element) return service; } -static void -_connman_service_ask_pass_and_connect(E_Connman_Service *service) -{ - e_util_dialog_show("TODO", "TODO!"); -} - -static void -_connman_service_connect_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error) -{ - E_Connman_Module_Context *ctxt = data; - - if (error && dbus_error_is_set(error)) - { - if (strcmp(error->message, - "org.moblin.connman.Error.AlreadyConnected") != 0) - _connman_dbus_error_show(_("Connect to network service."), error); - dbus_error_free(error); - } - - _connman_default_service_changed_delayed(ctxt); -} - -static void -_connman_service_connect(E_Connman_Service *service) -{ - if (!e_connman_service_connect - (service->element, _connman_service_connect_cb, service->ctxt)) - _connman_operation_error_show(_("Connect to network service.")); -} - static void _connman_service_disconnect_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error) { @@ -364,6 +529,144 @@ _connman_service_disconnect(E_Connman_Service *service) _connman_operation_error_show(_("Disconnect to network service.")); } +struct connman_service_connect_data +{ + const char *service_path; + E_Connman_Module_Context *ctxt; +}; + +static void +_connman_service_connect_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error) +{ + struct connman_service_connect_data *d = data; + + if (error && dbus_error_is_set(error)) + { + if ((strcmp(error->name, + "org.moblin.connman.Error.PassphraseRequired") == 0) || + (strcmp(error->name, + "org.moblin.connman.Error.Failed") == 0)) + { + E_Connman_Service *service; + + service = _connman_ctxt_find_service_stringshare + (d->ctxt, d->service_path); + if (!service) + _connman_operation_error_show + (_("Service does not exist anymore")); + else + { + _connman_service_disconnect(service); + _connman_service_ask_pass_and_connect(service); + } + } + else if (strcmp(error->name, + "org.moblin.connman.Error.AlreadyConnected") != 0) + _connman_dbus_error_show(_("Connect to network service."), error); + + dbus_error_free(error); + } + + _connman_default_service_changed_delayed(d->ctxt); + eina_stringshare_del(d->service_path); + E_FREE(d); +} + +static void +_connman_service_connect(E_Connman_Service *service) +{ + struct connman_service_connect_data *d; + + d = E_NEW(struct connman_service_connect_data, 1); + if (!d) + return; + + d->service_path = eina_stringshare_ref(service->path); + d->ctxt = service->ctxt; + + if (!e_connman_service_connect + (service->element, _connman_service_connect_cb, d)) + { + eina_stringshare_del(d->service_path); + E_FREE(d); + _connman_operation_error_show(_("Connect to network service.")); + } +} + +struct connman_service_ask_pass_data +{ + const char *service_path; + E_Connman_Module_Context *ctxt; +}; + +static void +_connman_service_ask_pass_and_connect__set_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error) +{ + struct connman_service_ask_pass_data *d = data; + E_Connman_Service *service; + + service = _connman_ctxt_find_service_stringshare(d->ctxt, d->service_path); + if (!service) + { + _connman_operation_error_show(_("Service does not exist anymore")); + goto end; + } + + if ((!error) || (!dbus_error_is_set(error))) + _connman_service_connect(service); + // TODO: check if connman reports password was invalid and ask again? + + end: + if ((error) && (dbus_error_is_set(error))) + dbus_error_free(error); + eina_stringshare_del(d->service_path); + E_FREE(d); +} + +static void +_connman_service_ask_pass_and_connect__ask_cb(void *data, const char *passphrase, const char *service_path) +{ + E_Connman_Module_Context *ctxt = data; + E_Connman_Service *service; + struct connman_service_ask_pass_data *d; + + service = _connman_ctxt_find_service_stringshare(ctxt, service_path); + if (!service) + { + _connman_operation_error_show(_("Service does not exist anymore")); + return; + } + + if (!passphrase) + { + _connman_service_disconnect(service); + return; + } + + d = E_NEW(struct connman_service_ask_pass_data, 1); + if (!d) + return; + d->service_path = eina_stringshare_ref(service_path); + d->ctxt = ctxt; + + if (!e_connman_service_passphrase_set + (service->element, passphrase, + _connman_service_ask_pass_and_connect__set_cb, d)) + { + eina_stringshare_del(d->service_path); + E_FREE(d); + _connman_operation_error_show(_("Could not set service's passphrase")); + return; + } +} + +static void +_connman_service_ask_pass_and_connect(E_Connman_Service *service) +{ + _connman_passphrase_ask + (service, _connman_service_ask_pass_and_connect__ask_cb, service->ctxt); +} + static void _connman_services_free(E_Connman_Module_Context *ctxt) { @@ -454,6 +757,14 @@ _connman_default_service_changed(E_Connman_Module_Context *ctxt) if (!e_connman_manager_offline_mode_get(&ctxt->offline_mode)) ctxt->offline_mode = EINA_FALSE; + if ((e_config->mode.offline != ctxt->offline_mode) && + (!ctxt->offline_mode_pending)) + { + e_config->mode.offline = ctxt->offline_mode; + e_config_mode_changed(); + e_config_save_queue(); + } + ctxt->default_service = def; EINA_LIST_FOREACH(ctxt->instances, l, inst) _connman_gadget_update(inst); @@ -480,6 +791,8 @@ _connman_default_service_changed_delayed_do(void *data) static void _connman_default_service_changed_delayed(E_Connman_Module_Context *ctxt) { + if (!ctxt->has_manager) + return; printf("\033[1;31mDBG CONNMAN: request delayed change\033[0m\n"); if (ctxt->poller.default_service_changed) ecore_poller_del(ctxt->poller.default_service_changed); @@ -611,21 +924,18 @@ _connman_popup_service_selected(void *data) if (!inst->service_path) return; - EINA_INLIST_FOREACH(ctxt->services, service) - { - if (service->path == inst->service_path) - { - _connman_popup_del(inst); + service = _connman_ctxt_find_service_stringshare(ctxt, inst->service_path); + if (!service) + return; - if (service->pass_required) - _connman_service_ask_pass_and_connect(service); - else if (service->state == e_str_ready) - _connman_service_disconnect(service); - else - _connman_service_connect(service); - return; - } - } + _connman_popup_del(inst); + + if (service->pass_required) + _connman_service_ask_pass_and_connect(service); + else if (service->state == e_str_ready) + _connman_service_disconnect(service); + else + _connman_service_connect(service); } static void @@ -831,6 +1141,35 @@ _connman_menu_new(E_Connman_Instance *inst, Evas_Event_Mouse_Down *ev) EVAS_BUTTON_NONE, ev->timestamp, NULL); } +static void +_connman_tip_new(E_Connman_Instance *inst) +{ + Evas *e; + + inst->tip = e_gadcon_popup_new(inst->gcc); + if (!inst->tip) return; + + e = inst->tip->win->evas; + + inst->o_tip = edje_object_add(e); + e_theme_edje_object_set(inst->o_tip, "base/theme/modules/connman/tip", + "e/modules/connman/tip"); + + _connman_tip_update(inst); + + e_gadcon_popup_content_set(inst->tip, inst->o_tip); + e_gadcon_popup_show(inst->tip); +} + +static void +_connman_tip_del(E_Connman_Instance *inst) +{ + evas_object_del(inst->o_tip); + e_object_del(E_OBJECT(inst->tip)); + inst->tip = NULL; + inst->o_tip = NULL; +} + static void _connman_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) { @@ -859,24 +1198,11 @@ static void _connman_cb_mouse_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) { E_Connman_Instance *inst = data; - Evas *e; if (inst->tip) return; - inst->tip = e_gadcon_popup_new(inst->gcc); - if (!inst->tip) return; - - e = inst->tip->win->evas; - - inst->o_tip = edje_object_add(e); - e_theme_edje_object_set(inst->o_tip, "base/theme/modules/connman/tip", - "e/modules/connman/tip"); - - _connman_tip_update(inst); - - e_gadcon_popup_content_set(inst->tip, inst->o_tip); - e_gadcon_popup_show(inst->tip); + _connman_tip_new(inst); } static void @@ -887,10 +1213,7 @@ _connman_cb_mouse_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUS if (!inst->tip) return; - evas_object_del(inst->o_tip); - e_object_del(E_OBJECT(inst->tip)); - inst->tip = NULL; - inst->o_tip = NULL; + _connman_tip_del(inst); } static void @@ -908,15 +1231,24 @@ _connman_edje_view_update(E_Connman_Instance *inst, Evas_Object *o) edje_object_part_text_set(o, "e.text.error", _("No ConnMan server found.")); edje_object_signal_emit(o, "e,changed,connected,no", "e"); + edje_object_part_text_set(o, "e.text.offline_mode", ""); + edje_object_signal_emit(o, "e,changed,offline_mode,no", "e"); return; } edje_object_signal_emit(o, "e,available", "e"); if (ctxt->offline_mode) - edje_object_signal_emit(o, "e,changed,offline_mode,yes", "e"); + { + edje_object_signal_emit(o, "e,changed,offline_mode,yes", "e"); + edje_object_part_text_set(o, "e.text.offline_mode", + _("Offline mode: all radios are turned off")); + } else - edje_object_signal_emit(o, "e,changed,offline_mode,no", "e"); + { + edje_object_signal_emit(o, "e,changed,offline_mode,no", "e"); + edje_object_part_text_set(o, "e.text.offline_mode", ""); + } if (ctxt->technology && ctxt->technology[0]) { @@ -926,7 +1258,7 @@ _connman_edje_view_update(E_Connman_Instance *inst, Evas_Object *o) ctxt->technology); edje_object_signal_emit(o, buf, "e"); } - else + else if (!ctxt->default_service) { edje_object_part_text_set(o, "e.text.technology", ""); edje_object_signal_emit(o, "e,changed,technology,none", "e"); @@ -980,6 +1312,13 @@ _connman_edje_view_update(E_Connman_Instance *inst, Evas_Object *o) snprintf(buf, sizeof(buf), "e,changed,service,%s", service->type); edje_object_signal_emit(o, buf, "e"); + if (!ctxt->technology) + { + edje_object_part_text_set(o, "e.text.technology", service->type); + snprintf(buf, sizeof(buf), "e,changed,technology,%s", service->type); + edje_object_signal_emit(o, buf, "e"); + } + snprintf(buf, sizeof(buf), "e,changed,state,%s", service->state); edje_object_signal_emit(o, buf, "e"); edje_object_part_text_set(o, "e.text.state", _(service->state)); @@ -1251,6 +1590,24 @@ _connman_event_manager_out(void *data, int type __UNUSED__, void *event __UNUSED return 1; } +static int +_connman_event_mode_changed(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + E_Connman_Module_Context *ctxt = data; + if ((ctxt->offline_mode == e_config->mode.offline) || + (!ctxt->has_manager)) + return 1; + + if (!e_connman_manager_offline_mode_set + (e_config->mode.offline, _connman_toggle_offline_mode_pending_cb, ctxt)) + _connman_operation_error_show + (_("Cannot toggle system's offline mode.")); + else + ctxt->offline_mode_pending = EINA_TRUE; + + return 1; +} + static void _connman_events_register(E_Connman_Module_Context *ctxt) { @@ -1258,6 +1615,8 @@ _connman_events_register(E_Connman_Module_Context *ctxt) (E_CONNMAN_EVENT_MANAGER_IN, _connman_event_manager_in, ctxt); ctxt->event.manager_out = ecore_event_handler_add (E_CONNMAN_EVENT_MANAGER_OUT, _connman_event_manager_out, ctxt); + ctxt->event.mode_changed = ecore_event_handler_add + (E_EVENT_CONFIG_MODE_CHANGED, _connman_event_mode_changed, ctxt); } static void @@ -1267,6 +1626,8 @@ _connman_events_unregister(E_Connman_Module_Context *ctxt) ecore_event_handler_del(ctxt->event.manager_in); if (ctxt->event.manager_out) ecore_event_handler_del(ctxt->event.manager_out); + if (ctxt->event.mode_changed) + ecore_event_handler_del(ctxt->event.mode_changed); } EAPI void * @@ -1309,6 +1670,12 @@ _connman_instances_free(E_Connman_Module_Context *ctxt) E_Connman_Instance *inst; inst = ctxt->instances->data; + + if (inst->popup) + _connman_popup_del(inst); + if (inst->tip) + _connman_tip_del(inst); + e_object_del(E_OBJECT(inst->gcc)); } } diff --git a/src/modules/connman/e_mod_main.h b/src/modules/connman/e_mod_main.h index 39708cb44..ca7852283 100644 --- a/src/modules/connman/e_mod_main.h +++ b/src/modules/connman/e_mod_main.h @@ -80,6 +80,7 @@ struct E_Connman_Module_Context { Ecore_Event_Handler *manager_in; Ecore_Event_Handler *manager_out; + Ecore_Event_Handler *mode_changed; } event; struct @@ -90,6 +91,7 @@ struct E_Connman_Module_Context Eina_Bool has_manager:1; bool offline_mode; + bool offline_mode_pending; const char *technology; const E_Connman_Service *default_service; Eina_Inlist *services;