diff --git a/src/modules/connman/E_Connman.h b/src/modules/connman/E_Connman.h index 8df064870..a57c17691 100644 --- a/src/modules/connman/E_Connman.h +++ b/src/modules/connman/E_Connman.h @@ -50,12 +50,15 @@ struct Connman_Manager /* Properties */ enum Connman_State state; bool offline_mode; + bool powered; /* Private */ struct { DBusPendingCall *get_services; DBusPendingCall *get_properties; + DBusPendingCall *get_wifi_properties; + DBusPendingCall *set_powered; DBusPendingCall *register_agent; } pending; }; @@ -85,8 +88,8 @@ struct Connman_Service extern int E_CONNMAN_EVENT_MANAGER_IN; extern int E_CONNMAN_EVENT_MANAGER_OUT; -/* Daemon monitoring */ +/* Daemon monitoring */ unsigned int e_connman_system_init(E_DBus_Connection *edbus_conn) EINA_ARG_NONNULL(1); unsigned int e_connman_system_shutdown(void); @@ -102,6 +105,8 @@ typedef void (*Econnman_Simple_Cb)(void *data, const char *error); bool econnman_service_connect(struct Connman_Service *cs, Econnman_Simple_Cb cb, void *data); bool econnman_service_disconnect(struct Connman_Service *cs, Econnman_Simple_Cb cb, void *data); +void econnman_powered_set(struct Connman_Manager *cm, Eina_Bool powered); + /* UI calls from econnman */ /* diff --git a/src/modules/connman/e_connman.c b/src/modules/connman/e_connman.c index aaec70d53..0dcbdcfff 100644 --- a/src/modules/connman/e_connman.c +++ b/src/modules/connman/e_connman.c @@ -12,6 +12,7 @@ #define CONNMAN_BUS_NAME "net.connman" #define CONNMAN_MANAGER_IFACE CONNMAN_BUS_NAME ".Manager" #define CONNMAN_SERVICE_IFACE CONNMAN_BUS_NAME ".Service" +#define CONNMAN_TECHNOLOGY_IFACE CONNMAN_BUS_NAME ".Technology" #define MILLI_PER_SEC 1000 #define CONNMAN_CONNECTION_TIMEOUT 60 * MILLI_PER_SEC @@ -670,6 +671,70 @@ static void _manager_get_prop_cb(void *data, DBusMessage *reply, } } +static bool _manager_parse_wifi_prop_changed(struct Connman_Manager *cm, + const char *name, + DBusMessageIter *value) +{ + if (strcmp(name, "Powered") == 0) + cm->powered = _dbus_bool_get(value); + else + return false; + + econnman_mod_manager_update(cm); + return true; +} + +static void _manager_wifi_prop_changed(void *data, DBusMessage *msg) +{ + struct Connman_Manager *cm = data; + DBusMessageIter iter, var; + const char *name; + + if (!msg || !dbus_message_iter_init(msg, &iter)) + { + ERR("Could not parse message %p", msg); + return; + } + + dbus_message_iter_get_basic(&iter, &name); + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &var); + + _manager_parse_wifi_prop_changed(cm, name, &var); +} + +static void _manager_get_wifi_prop_cb(void *data, DBusMessage *reply, + DBusError *err) +{ + struct Connman_Manager *cm = data; + DBusMessageIter iter, dict; + + cm->pending.get_wifi_properties = NULL; + + if (dbus_error_is_set(err)) + { + DBG("Could not get properties. %s: %s", err->name, err->message); + return; + } + + dbus_message_iter_init(reply, &iter); + dbus_message_iter_recurse(&iter, &dict); + + for (; dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID; + dbus_message_iter_next(&dict)) + { + DBusMessageIter entry, var; + const char *name; + + dbus_message_iter_recurse(&dict, &entry); + dbus_message_iter_get_basic(&entry, &name); + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &var); + + _manager_parse_wifi_prop_changed(cm, name, &var); + } +} + static void _manager_agent_unregister(void) { @@ -760,6 +825,18 @@ static void _manager_free(struct Connman_Manager *cm) cm->pending.get_properties = NULL; } + if (cm->pending.get_wifi_properties) + { + dbus_pending_call_cancel(cm->pending.get_wifi_properties); + cm->pending.get_wifi_properties = NULL; + } + + if (cm->pending.set_powered) + { + dbus_pending_call_cancel(cm->pending.set_powered); + cm->pending.set_powered = NULL; + } + if (cm->pending.register_agent) { dbus_pending_call_cancel(cm->pending.register_agent); @@ -770,18 +847,69 @@ static void _manager_free(struct Connman_Manager *cm) free(cm); } +static void _manager_powered_cb(void *data, DBusMessage *reply, + DBusError *err) +{ + struct Connman_Manager *cm = data; + DBusMessage *msg; + + cm->pending.set_powered = NULL; + if (!((err) && (dbus_error_is_set(err)))) + { + if (cm->pending.get_wifi_properties) + dbus_pending_call_cancel(cm->pending.get_wifi_properties); + msg = dbus_message_new_method_call(CONNMAN_BUS_NAME, + "/net/connman/technology/wifi", + CONNMAN_TECHNOLOGY_IFACE, + "GetProperties"); + cm->pending.get_wifi_properties = + e_dbus_message_send(conn, msg, _manager_get_wifi_prop_cb, -1, cm); + } +} + +void econnman_powered_set(struct Connman_Manager *cm, Eina_Bool powered) +{ + DBusMessageIter itr, var; + DBusMessage *msg; + const char *p = "Powered"; + int v = 0; + + if (powered) v = 1; + if (cm->pending.set_powered) + dbus_pending_call_cancel(cm->pending.set_powered); + msg = dbus_message_new_method_call(CONNMAN_BUS_NAME, + "/net/connman/technology/wifi", + CONNMAN_TECHNOLOGY_IFACE, + "SetProperty"); + dbus_message_iter_init_append(msg, &itr); + dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &p); + if (dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, "b", &var)) + { + dbus_message_iter_append_basic(&var, DBUS_TYPE_BOOLEAN, &v); + dbus_message_iter_close_container(&itr, &var); + } + cm->pending.set_powered = + e_dbus_message_send(conn, msg, _manager_powered_cb, -1, cm); + +} + static struct Connman_Manager *_manager_new(void) { - DBusMessage *msg_props, *msg_services; + DBusMessage *msg_props, *msg_services, *msg_wifi_props; const char *path = "/"; struct E_DBus_Signal_Handler *h; struct Connman_Manager *cm; msg_services = dbus_message_new_method_call(CONNMAN_BUS_NAME, "/", - CONNMAN_MANAGER_IFACE, "GetServices"); + CONNMAN_MANAGER_IFACE, + "GetServices"); msg_props = dbus_message_new_method_call(CONNMAN_BUS_NAME, "/", - CONNMAN_MANAGER_IFACE, "GetProperties"); - + CONNMAN_MANAGER_IFACE, + "GetProperties"); + msg_wifi_props = dbus_message_new_method_call(CONNMAN_BUS_NAME, + "/net/connman/technology/wifi", + CONNMAN_TECHNOLOGY_IFACE, + "GetProperties"); if (!msg_services || !msg_services) { ERR("Could not create D-Bus messages"); @@ -803,6 +931,12 @@ static struct Connman_Manager *_manager_new(void) _manager_services_changed, cm); cm->obj.handlers = eina_list_append(cm->obj.handlers, h); + h = e_dbus_signal_handler_add(conn, bus_owner, + "/net/connman/technology/wifi", + CONNMAN_TECHNOLOGY_IFACE, "PropertyChanged", + _manager_wifi_prop_changed, cm); + cm->obj.handlers = eina_list_append(cm->obj.handlers, h); + /* * PropertyChanged signal in service's path is guaranteed to arrive only * after ServicesChanged above. So we only add the handler later, in a per @@ -810,10 +944,14 @@ static struct Connman_Manager *_manager_new(void) */ cm->pending.get_services = e_dbus_message_send(conn, msg_services, - _manager_get_services_cb, -1, cm); + _manager_get_services_cb, + -1, cm); cm->pending.get_properties = e_dbus_message_send(conn, msg_props, - _manager_get_prop_cb, -1, cm); - + _manager_get_prop_cb, + -1, cm); + cm->pending.get_wifi_properties = e_dbus_message_send(conn, msg_wifi_props, + _manager_get_wifi_prop_cb, + -1, cm); return cm; } diff --git a/src/modules/connman/e_mod_main.c b/src/modules/connman/e_mod_main.c index 200635cb9..439a6c237 100644 --- a/src/modules/connman/e_mod_main.c +++ b/src/modules/connman/e_mod_main.c @@ -128,6 +128,7 @@ static void _econnman_popup_update(struct Connman_Manager *cm, E_Connman_Instance *inst) { Evas_Object *list = inst->ui.popup.list; + Evas_Object *powered = inst->ui.popup.powered; Evas *evas = evas_object_evas_get(list); struct Connman_Service *cs; const char *hidden = "«hidden»"; @@ -148,6 +149,12 @@ static void _econnman_popup_update(struct Connman_Manager *cm, e_widget_ilist_thaw(list); e_widget_ilist_go(list); + + if (inst->ctxt) + { + inst->ctxt->powered = cm->powered; + } + e_widget_check_checked_set(powered, cm->powered); } void econnman_mod_services_changed(struct Connman_Manager *cm) @@ -243,10 +250,21 @@ _econnman_configure_cb(void *data, void *data2 __UNUSED__) _econnman_app_launch(inst); } +static void +_econnman_powered_changed(void *data, Evas_Object *obj, void *info __UNUSED__) +{ + E_Connman_Instance *inst = data; + E_Connman_Module_Context *ctxt = inst->ctxt; + + if (!ctxt) return; + if (!ctxt->cm) return; + econnman_powered_set(ctxt->cm, ctxt->powered); +} + static void _econnman_popup_new(E_Connman_Instance *inst) { E_Connman_Module_Context *ctxt = inst->ctxt; - Evas_Object *list, *bt; + Evas_Object *list, *bt, *ck; Evas_Coord mw, mh; Evas *evas; @@ -263,9 +281,15 @@ static void _econnman_popup_new(E_Connman_Instance *inst) e_widget_size_min_set(inst->ui.popup.list, 120, 100); e_widget_list_object_append(list, inst->ui.popup.list, 1, 1, 0.5); + ck = e_widget_check_add(evas, _("Wifi On"), &(ctxt->powered)); + inst->ui.popup.powered = ck; + e_widget_list_object_append(list, ck, 1, 0, 0.5); + evas_object_smart_callback_add(ck, "changed", + _econnman_powered_changed, inst); + _econnman_popup_update(ctxt->cm, inst); - bt = e_widget_button_add(evas, "Configure", NULL, + bt = e_widget_button_add(evas, _("Configure"), NULL, _econnman_configure_cb, inst, NULL); e_widget_list_object_append(list, bt, 1, 0, 0.5); diff --git a/src/modules/connman/e_mod_main.h b/src/modules/connman/e_mod_main.h index 8a2e143f9..4aa939543 100644 --- a/src/modules/connman/e_mod_main.h +++ b/src/modules/connman/e_mod_main.h @@ -29,6 +29,7 @@ struct E_Connman_Instance struct { Evas_Object *list; + Evas_Object *powered; Ecore_X_Window input_win; Ecore_Event_Handler *input_mouse_up; @@ -49,6 +50,7 @@ struct E_Connman_Module_Context struct Connman_Manager *cm; Eina_Bool offline_mode; + int powered; }; EAPI extern E_Module_Api e_modapi;