From 7d393694345b9a49023c24d3a60f6864313b6894 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Sat, 15 Dec 2018 16:03:41 +0000 Subject: [PATCH] bluez5 - add device specific options like unlock and force connect i added 2 more device specific options, so i had to move all of the device controls to an expandable button set. it's not brilliant actually. the icons are poor and these probably should become toggle like states rather than a button with an action. it's just not that intuitive. this i think needs more theme styles in elm core theme though, so for now keep what's there. but this was necessary due to the ever expanding set to keep space usage sane. now the 2 features are "force connect" for any device that is discovered and responds to pings - connect to it if not connected. this seems to not always work and maybe this should eventually be removed, but this leads to there needing to be config per device so we now have config storage for that like adapters. the other feature which is much more interesting is the unlock feature. this means if that bt device is around and responds to pings, e will unlock (and only explicit manual locking will lock it), but when that bt device stops responding to pings, e will lock. you could use your phone, or smartwatch or any other bt device you have on your all the time as some unlock device. this required the fixing of the l2ping support in e_sys and i've fixed it to properly work now and added an optional timeout value as input. the unlock feature uses this and it pings bt devices on a frequency that depends on e's powersave state which is dependent on if on ac, or battery and what battery level is if you have the battery module running. a handy feature to have just there at the click of a button. i've kept the printf logging in for now so people trying it out get some semblance of logging and state so they could figure out why things are doing what they do and maybe debug it more easily. --- src/modules/bluez5/bz.h | 10 +- src/modules/bluez5/bz_obj.c | 180 ++++++++++++++- src/modules/bluez5/e_mod_main.c | 99 ++++++++ src/modules/bluez5/e_mod_main.h | 12 + src/modules/bluez5/e_mod_popup.c | 377 +++++++++++++++++++++++++------ 5 files changed, 608 insertions(+), 70 deletions(-) diff --git a/src/modules/bluez5/bz.h b/src/modules/bluez5/bz.h index 252f20180..2d099977f 100644 --- a/src/modules/bluez5/bz.h +++ b/src/modules/bluez5/bz.h @@ -19,6 +19,10 @@ struct _Obj { unsigned int ref; Eina_Bool in_table : 1; Eina_Bool add_called : 1; + Eina_Bool ping_ok : 1; + Ecore_Timer *ping_timer; + Ecore_Exe *ping_exe; + Ecore_Event_Handler *ping_exe_handler; //// public data to read const char *path; Obj_Type type; @@ -196,9 +200,11 @@ void bz_obj_pair(Obj *o); void bz_obj_pair_cancel(Obj *o); void bz_obj_connect(Obj *o); void bz_obj_disconnect(Obj *o); +void bz_obj_ping_begin(Obj *o); +void bz_obj_ping_end(Obj *o); void bz_obj_remove(Obj *o); -void bz_obj_profile_connect(Obj *o, const char *uuid); -void bz_obj_profile_disconnect(Obj *o, const char *uuid); +//void bz_obj_profile_connect(Obj *o, const char *uuid); +//void bz_obj_profile_disconnect(Obj *o, const char *uuid); void bz_obj_ref(Obj *o); void bz_obj_unref(Obj *o); void bz_obj_discover_start(Obj *o); diff --git a/src/modules/bluez5/bz_obj.c b/src/modules/bluez5/bz_obj.c index a79d2a837..dc6aaf132 100644 --- a/src/modules/bluez5/bz_obj.c +++ b/src/modules/bluez5/bz_obj.c @@ -286,6 +286,12 @@ cb_obj_prop_changed(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSE eldbus_proxy_property_get_all(o->proxy, cb_obj_prop, o); } +static void +cb_obj_discovery_filter(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED) +{ + ERR_PRINT("Discovery Filter Clear"); +} + Obj * bz_obj_add(const char *path) { @@ -339,6 +345,9 @@ bz_obj_add(const char *path) o->prop_sig = eldbus_proxy_signal_handler_add(o->prop_proxy, "PropertiesChanged", cb_obj_prop_changed, o); + // disable the filter for discovery later + eldbus_proxy_call + (o->proxy, "SetDiscoveryFilter", cb_obj_discovery_filter, o, -1, ""); } goto done; } @@ -526,6 +535,157 @@ bz_obj_disconnect(Obj *o) eldbus_proxy_call (o->proxy, "Disconnect", cb_disconnect, o, -1, ""); } + +static Eina_Bool +cb_ping_exit(void *data, int type EINA_UNUSED, void *event) +{ + Obj *o = data; + Ecore_Exe_Event_Del *ev = event; + + printf("@@@EXE EXIT.. %p == %p\n", ev->exe, o->ping_exe); + if (ev->exe != o->ping_exe) return ECORE_CALLBACK_PASS_ON; + printf("@@@PING RESULT... %i\n", ev->exit_code); + o->ping_exe = NULL; + if (ev->exit_code == 0) + { + if (!o->ping_ok) + { + printf("@@@PING SUCCEED\n"); + o->ping_ok = EINA_TRUE; + if (o->fn_change) o->fn_change(o); + } + } + else + { + if (o->ping_ok) + { + printf("@@@PING FAIL\n"); + o->ping_ok = EINA_FALSE; + if (o->fn_change) o->fn_change(o); + } + } + return ECORE_CALLBACK_PASS_ON; +} + +static int +ping_powersave_timeout_get(void) +{ + int timeout = 10; + E_Powersave_Mode pm = e_powersave_mode_get(); + + if (pm <= E_POWERSAVE_MODE_LOW) timeout = 5; + else if (pm <= E_POWERSAVE_MODE_MEDIUM) timeout = 8; + else if (pm <= E_POWERSAVE_MODE_HIGH) timeout = 12; + else if (pm <= E_POWERSAVE_MODE_EXTREME) timeout = 30; + return timeout; +} + +static void +ping_do(Obj *o) +{ + Eina_Strbuf *buf; + + if (!o->ping_exe_handler) + o->ping_exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + cb_ping_exit, o); + buf = eina_strbuf_new(); + if (buf) + { + int timeout = ping_powersave_timeout_get(); + + timeout *= 1000; + eina_strbuf_append_printf + (buf, "%s/enlightenment/utils/enlightenment_sys l2ping %s %i", + e_prefix_lib_get(), o->address, timeout); + o->ping_exe = ecore_exe_run(eina_strbuf_string_get(buf), NULL); + eina_strbuf_free(buf); + printf("@@@ run new ping %s %i = %p\n", o->address, timeout, o->ping_exe); + } +} + +static Eina_Bool cb_ping_timer(void *data); + +static void +ping_schedule(Obj *o) +{ + double timeout = ping_powersave_timeout_get() + 1.0; + + if (o->ping_timer) ecore_timer_del(o->ping_timer); + o->ping_timer = ecore_timer_add(timeout, cb_ping_timer, o); +} + +static Eina_Bool +cb_ping_timer(void *data) +{ + Obj *o = data; + + printf("@@@ ping timer %s\n", o->address); + if (o->ping_exe) + { + printf("@@@PING TIMEOUT\n"); + ecore_exe_free(o->ping_exe); + o->ping_exe = NULL; + if (o->ping_ok) + { + o->ping_ok = EINA_FALSE; + if (o->fn_change) o->fn_change(o); + } + } + ping_do(o); + ping_schedule(o); + return EINA_TRUE; +} + +void +bz_obj_ping_begin(Obj *o) +{ + if (o->ping_timer) return; + if (o->ping_exe_handler) + { + ecore_event_handler_del(o->ping_exe_handler); + o->ping_exe_handler = NULL; + } + if (o->ping_exe) + { + ecore_exe_free(o->ping_exe); + o->ping_exe = NULL; + } + ping_do(o); + ping_schedule(o); + } + +void +bz_obj_ping_end(Obj *o) +{ + if (o->ping_exe_handler) + { + ecore_event_handler_del(o->ping_exe_handler); + o->ping_exe_handler = NULL; + } + if (o->ping_timer) + { + ecore_timer_del(o->ping_timer); + o->ping_timer = NULL; + } + if (o->ping_exe) + { + ecore_exe_free(o->ping_exe); + o->ping_exe = NULL; + } + if (o->ping_ok) + { + printf("@@@PING END %s\n", o->address); + o->ping_ok = EINA_FALSE; + if (o->fn_change) o->fn_change(o); + } +} + +static void +cb_remove(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED) +{ + ERR_PRINT("Remove"); +} + /* void bz_obj_profile_connect(Obj *o, const char *uuid) @@ -541,11 +701,6 @@ bz_obj_profile_disconnect(Obj *o, const char *uuid) eldbus_proxy_call(o->proxy, "DisconnectProfile", NULL, NULL, -1, "s", uuid); } */ -static void -cb_remove(void *data EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED, Eldbus_Pending *pending EINA_UNUSED) -{ - ERR_PRINT("Remove"); -} void bz_obj_remove(Obj *o) @@ -615,6 +770,21 @@ bz_obj_unref(Obj *o) bz_agent_msg_drop(o->agent_msg_ok); o->agent_msg_ok = NULL; } + if (o->ping_exe_handler) + { + ecore_event_handler_del(o->ping_exe_handler); + o->ping_exe_handler = NULL; + } + if (o->ping_timer) + { + ecore_timer_del(o->ping_timer); + o->ping_timer = NULL; + } + if (o->ping_exe) + { + ecore_exe_free(o->ping_exe); + o->ping_exe = NULL; + } free(o); } diff --git a/src/modules/bluez5/e_mod_main.c b/src/modules/bluez5/e_mod_main.c index d0aad0a59..ad576bfba 100644 --- a/src/modules/bluez5/e_mod_main.c +++ b/src/modules/bluez5/e_mod_main.c @@ -5,6 +5,7 @@ static E_Module *mod = NULL; /* Local config */ static E_Config_DD *conf_adapter_edd = NULL; +static E_Config_DD *conf_device_edd = NULL; static E_Config_DD *conf_edd = NULL; Config *ebluez5_config = NULL; @@ -332,6 +333,88 @@ ebluez5_instances_update(void) } } +static void +_device_prop_clean(Config_Device *dev) +{ + if ((!dev->unlock) && (!dev->force_connect)) + { + ebluez5_config->devices = eina_list_remove(ebluez5_config->devices, dev); + eina_stringshare_del(dev->addr); + free(dev); + } +} + +static Config_Device * +_device_prop_new(const char *address) +{ + Config_Device *dev = calloc(1, sizeof(Config_Device)); + if (!dev) return NULL; + dev->addr = eina_stringshare_add(address); + if (!dev->addr) + { + free(dev); + return NULL; + } + ebluez5_config->devices = eina_list_append(ebluez5_config->devices, dev); + return dev; +} + +Config_Device * +ebluez5_device_prop_find(const char *address) +{ + Config_Device *dev; + Eina_List *l; + + if (!address) return NULL; + EINA_LIST_FOREACH(ebluez5_config->devices, l, dev) + { + if ((dev->addr) && (!strcmp(address, dev->addr))) + return dev; + } + return NULL; +} + + +void +ebluez5_device_prop_force_connect_set(const char *address, Eina_Bool enable) +{ + Config_Device *dev; + + if (!address) return; + dev = ebluez5_device_prop_find(address); + if (dev) + { + dev->force_connect = enable; + _device_prop_clean(dev); + return; + } + if (enable) + { + dev = _device_prop_new(address); + dev->force_connect = enable; + } +} + +void +ebluez5_device_prop_unlock_set(const char *address, Eina_Bool enable) +{ + Config_Device *dev; + + if (!address) return; + dev = ebluez5_device_prop_find(address); + if (dev) + { + dev->unlock = enable; + _device_prop_clean(dev); + return; + } + if (enable) + { + dev = _device_prop_new(address); + dev->unlock = enable; + } +} + ///////////////////////////////////////////////////////////////////////////// /* Module Functions */ @@ -349,12 +432,22 @@ e_modapi_init(E_Module *m) E_CONFIG_VAL(D, T, powered, UCHAR); E_CONFIG_VAL(D, T, pairable, UCHAR); + conf_device_edd = E_CONFIG_DD_NEW("Config_Device", Config_Device); +#undef T +#undef D +#define T Config_Device +#define D conf_device_edd + E_CONFIG_VAL(D, T, addr, STR); + E_CONFIG_VAL(D, T, force_connect, UCHAR); + E_CONFIG_VAL(D, T, unlock, UCHAR); + conf_edd = E_CONFIG_DD_NEW("Config", Config); #undef T #undef D #define T Config #define D conf_edd E_CONFIG_LIST(D, T, adapters, conf_adapter_edd); + E_CONFIG_LIST(D, T, devices, conf_device_edd); ebluez5_config = e_config_domain_load("module.ebluez5", conf_edd); if (!ebluez5_config) ebluez5_config = E_NEW(Config, 1); @@ -372,6 +465,7 @@ E_API int e_modapi_shutdown(E_Module *m EINA_UNUSED) { Config_Adapter *ad; + Config_Device *dev; E_CONFIG_DD_FREE(conf_edd); E_CONFIG_DD_FREE(conf_adapter_edd); @@ -381,6 +475,11 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED) eina_stringshare_del(ad->addr); free(ad); } + EINA_LIST_FREE(ebluez5_config->devices, dev) + { + eina_stringshare_del(dev->addr); + free(dev); + } free(ebluez5_config); ebluez5_config = NULL; diff --git a/src/modules/bluez5/e_mod_main.h b/src/modules/bluez5/e_mod_main.h index 788db7a34..e0bef146e 100644 --- a/src/modules/bluez5/e_mod_main.h +++ b/src/modules/bluez5/e_mod_main.h @@ -23,6 +23,7 @@ typedef struct _Config Config; struct _Config { Eina_List *adapters; + Eina_List *devices; }; typedef struct _Config_Adapter Config_Adapter; struct _Config_Adapter @@ -31,6 +32,13 @@ struct _Config_Adapter Eina_Bool powered; Eina_Bool pairable; }; +typedef struct _Config_Device Config_Device; +struct _Config_Device +{ + const char *addr; + Eina_Bool force_connect; + Eina_Bool unlock; +}; extern Config *ebluez5_config; @@ -45,6 +53,10 @@ void ebluez5_popups_show(void); void ebluez5_rfkill_unblock(const char *name); void ebluez5_instances_update(void); +void ebluez5_device_prop_force_connect_set(const char *address, Eina_Bool enable); +void ebluez5_device_prop_unlock_set(const char *address, Eina_Bool enable); +Config_Device *ebluez5_device_prop_find(const char *address); + void ebluez5_popup_hide(Instance *inst); Evas_Object *ebluez5_popup_content_add(Evas_Object *base, Instance *inst); diff --git a/src/modules/bluez5/e_mod_popup.c b/src/modules/bluez5/e_mod_popup.c index d04bc4489..2eb0b1cab 100644 --- a/src/modules/bluez5/e_mod_popup.c +++ b/src/modules/bluez5/e_mod_popup.c @@ -7,12 +7,137 @@ static Eina_List *lists = NULL; static Eina_List *adapters = NULL; static Eina_List *devices = NULL; +static int unlock_count = 0; +static int unlock_do = 0; +static Eina_Bool unlock_block = EINA_FALSE; + +static Config_Device * +_devices_conifg_find(const char *address) +{ + Config_Device *dev; + Eina_List *l; + + if (!ebluez5_config) return NULL; + if (!address) return NULL; + EINA_LIST_FOREACH(ebluez5_config->devices, l, dev) + { + if ((dev->addr) && (!strcmp(address, dev->addr))) return dev; + } + return NULL; +} + +static void +_devices_eval(void) +{ + Obj *o; + Eina_List *l; + Config_Device *dev; + int unlock_count_prev = 0; + + unlock_count_prev = unlock_count; + unlock_count = 0; + unlock_do = 0; + printf("=== _devices_eval...\n"); + EINA_LIST_FOREACH(devices, l, o) + { + if (o->paired) + { + Eina_Bool need_ping = EINA_FALSE; + + dev = _devices_conifg_find(o->address); + if (dev) + { + printf("=== dev: %s|%s [%s]\n", dev->addr, o->address, o->name); + if ((dev->force_connect) && (!o->connected)) + { + printf("=== %s force con, not conn, ping ok=%i\n", o->address, o->ping_ok); + if (o->ping_ok) + { + printf("=== %s force con, not conn, ping ok=%i\n", o->address, o->ping_ok); + bz_obj_connect(o); + } + else need_ping = EINA_TRUE; + } + if (dev->unlock) + { + printf("=== unlock...\n"); + // if a device on our list needs an unlock, then + // add to our possible unlock counts needed + unlock_count++; +#if 0 + // if the device is connected then assume it unlocks + if (o->connected) + { + printf("=== don't need ping1\n"); + unlock_do++; + } + else +#endif + { + printf("=== need ping2\n"); + need_ping = EINA_TRUE; + if (o->ping_ok) unlock_do++; + } + } + } + printf("=== %s need_ping=%i conn=%i ping_ok=%i\n", o->address, need_ping, o->connected, o->ping_ok); + if (need_ping) bz_obj_ping_begin(o); + else bz_obj_ping_end(o); + } + } + printf("=================== unlock: %i/%i\n", unlock_do, unlock_count); + if (unlock_count > 0) + { + if (unlock_do == 0) + { + if (unlock_block) + { + unlock_block = EINA_FALSE; + printf("=== DESKLOCK UNBLOCK\n"); + e_desklock_unblock(); + printf("=== DESLOCK SHOW\n"); + e_desklock_show(EINA_FALSE); + } + } + else + { + if (!unlock_block) + { + unlock_block = EINA_TRUE; + printf("=== DESKLOCK BLOCK\n"); + e_desklock_block(); + } + } + } + else + { + if (unlock_count_prev != unlock_count) + { + if (!e_desklock_manual_get()) + { + if (e_desklock_state_get()) + { + printf("=== DESKLOCK HIDE\n"); + e_desklock_hide(); + } + } + } + if (unlock_block) + { + unlock_block = EINA_FALSE; + printf("=== DESKLOCK UNBLOCK\n"); + e_desklock_unblock(); + } + } +} + static void _adapter_add(Evas_Object *gl, Obj *o) { Elm_Object_Item *it = evas_object_data_get(gl, "adapters_item");; + elm_genlist_item_append(gl, adapt_itc, o, it, ELM_GENLIST_ITEM_NONE, - NULL, NULL); + NULL, NULL); } static int @@ -44,7 +169,8 @@ _device_add(Evas_Object *gl, Obj *o) { Elm_Object_Item *it = evas_object_data_get(gl, "devices_item");; - elm_genlist_item_sorted_insert(gl, dev_itc, o, it, ELM_GENLIST_ITEM_NONE, + elm_genlist_item_sorted_insert(gl, dev_itc, o, it, + ELM_GENLIST_ITEM_NONE, _cb_insert_cmp, NULL, NULL); } @@ -131,6 +257,61 @@ _cb_unpair(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSE bz_obj_remove(o); } +static void +_cb_unlock_start(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Obj *o = data; + printf("unlock start %s\n", o->address); + ebluez5_device_prop_unlock_set(o->address, EINA_TRUE); + ebluez5_popup_device_change(o); +} + +static void +_cb_unlock_stop(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Obj *o = data; + printf("unlock stop %s\n", o->address); + ebluez5_device_prop_unlock_set(o->address, EINA_FALSE); + ebluez5_popup_device_change(o); +} + +static void +_cb_force_connect_start(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Obj *o = data; + ebluez5_device_prop_force_connect_set(o->address, EINA_TRUE); + ebluez5_popup_adapter_change(o); +} + +static void +_cb_force_connect_stop(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Obj *o = data; + ebluez5_device_prop_force_connect_set(o->address, EINA_FALSE); + ebluez5_popup_adapter_change(o); +} + +static void +_cb_flip(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Obj *o = data; + Evas_Object *gl = evas_object_data_get(obj, "genlist"); + Elm_Object_Item *it; + + for (it = elm_genlist_first_item_get(gl); it; + it = elm_genlist_item_next_get(it)) + { + if (o == elm_object_item_data_get(it)) + { + if (elm_genlist_item_flip_get(it)) + elm_genlist_item_flip_set(it, EINA_FALSE); + else + elm_genlist_item_flip_set(it, EINA_TRUE); + break; + } + } +} + static void _agent_done(Obj *o) { @@ -305,7 +486,7 @@ _cb_dev_text_get(void *data, Evas_Object *obj EINA_UNUSED, static Evas_Object * _cb_dev_content_get(void *data EINA_UNUSED, Evas_Object *obj, - const char *part EINA_UNUSED) + const char *part) { Obj *o = data; char buf[512]; @@ -342,14 +523,49 @@ _cb_dev_content_get(void *data EINA_UNUSED, Evas_Object *obj, evas_object_show(ic); return bx; } - else if (!strcmp(part, "elm.swallow.end")) + else if (!strcmp(part, "elm.text.flip")) { - Evas_Object *bx, *ic, *bt, *lb, *tb, *en, *rec; + Evas_Object *bx, *bt, *ic; bx = elm_box_add(obj); elm_box_horizontal_set(bx, EINA_TRUE); + elm_box_align_set(bx, 1.0, 0.5); if (o->paired) { + if (o->paired) + { + Config_Device *dev = ebluez5_device_prop_find(o->address); + + if ((dev) && (dev->unlock)) + { + bt = util_button_icon_add(obj, "changes-allow-symbolic", + _("Stop this from being an unlock device")); + evas_object_smart_callback_add(bt, "clicked", _cb_unlock_stop, o); + } + else + { + bt = util_button_icon_add(obj, "channel-insecure-symbolic", + _("Make this auto unlock when detected (and lock when not)")); + evas_object_smart_callback_add(bt, "clicked", _cb_unlock_start, o); + } + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + if ((dev) && (dev->force_connect)) + { + bt = util_button_icon_add(obj, "checkbox-symbolic", + _("Stop this device from being forcefullty connected")); + evas_object_smart_callback_add(bt, "clicked", _cb_force_connect_stop, o); + } + else + { + bt = util_button_icon_add(obj, "checkbox-checked-symbolic", + _("Force this device to be connected when detected")); + evas_object_smart_callback_add(bt, "clicked", _cb_force_connect_start, o); + } + elm_box_pack_end(bx, bt); + evas_object_show(bt); + } if (o->connected) { bt = util_button_icon_add(obj, "network-offline", @@ -382,64 +598,7 @@ _cb_dev_content_get(void *data EINA_UNUSED, Evas_Object *obj, } if (!o->paired) { - if (o->agent_request) - { - if (o->agent_entry_fn) - { - tb = elm_table_add(obj); - - rec = evas_object_rectangle_add(evas_object_evas_get(obj)); - evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(1)); - elm_table_pack(tb, rec, 0, 0, 1, 1); - - en = elm_entry_add(obj); - elm_entry_single_line_set(en, EINA_TRUE); - elm_entry_scrollable_set(en, EINA_TRUE); - elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); - elm_object_part_text_set(en, "guide", o->agent_request); -// elm_entry_password_set(en, EINA_TRUE); - evas_object_smart_callback_add(en, "activated", _cb_agent_ok, o); - evas_object_smart_callback_add(en, "aborted", _cb_agent_cancel, o); - elm_table_pack(tb, en, 0, 0, 1, 1); - evas_object_show(en); - - elm_box_pack_end(bx, tb); - evas_object_show(tb); - - bt = util_button_icon_add(obj, "list-add", - _("Pair with this device")); - evas_object_data_set(bt, "entry", en); - evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o); - elm_box_pack_end(bx, bt); - evas_object_show(bt); - - bt = util_button_icon_add(obj, "list-remove", - _("Reject pairing")); - evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o); - elm_box_pack_end(bx, bt); - evas_object_show(bt); - } - else - { - lb = elm_label_add(obj); - elm_layout_text_set(lb, NULL, o->agent_request); - elm_box_pack_end(bx, lb); - evas_object_show(lb); - - bt = util_button_icon_add(obj, "list-add", - _("Pair with this device")); - evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o); - elm_box_pack_end(bx, bt); - evas_object_show(bt); - - bt = util_button_icon_add(obj, "list-remove", - _("Reject pairing")); - evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o); - elm_box_pack_end(bx, bt); - evas_object_show(bt); - } - } - else + if (!o->agent_request) { bt = util_button_icon_add(obj, "list-add", _("Pair with this device")); @@ -457,6 +616,90 @@ _cb_dev_content_get(void *data EINA_UNUSED, Evas_Object *obj, evas_object_show(bt); } + bt = util_button_icon_add(obj, "view-more-horizontal", + _("Cancel")); + evas_object_data_set(bt, "genlist", obj); + evas_object_smart_callback_add(bt, "clicked", _cb_flip, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + ic = util_obj_icon_rssi_add(obj, o, 24); + elm_box_pack_end(bx, ic); + evas_object_show(ic); + return bx; + } + else if (!strcmp(part, "elm.swallow.end")) + { + Evas_Object *bx, *ic, *bt, *lb, *tb, *en, *rec; + + bx = elm_box_add(obj); + elm_box_horizontal_set(bx, EINA_TRUE); + + if (o->agent_request) + { + if (o->agent_entry_fn) + { + tb = elm_table_add(obj); + + rec = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(1)); + elm_table_pack(tb, rec, 0, 0, 1, 1); + + en = elm_entry_add(obj); + elm_entry_single_line_set(en, EINA_TRUE); + elm_entry_scrollable_set(en, EINA_TRUE); + elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + elm_object_part_text_set(en, "guide", o->agent_request); +// elm_entry_password_set(en, EINA_TRUE); + evas_object_smart_callback_add(en, "activated", _cb_agent_ok, o); + evas_object_smart_callback_add(en, "aborted", _cb_agent_cancel, o); + elm_table_pack(tb, en, 0, 0, 1, 1); + evas_object_show(en); + + elm_box_pack_end(bx, tb); + evas_object_show(tb); + + bt = util_button_icon_add(obj, "list-add", + _("Pair with this device")); + evas_object_data_set(bt, "entry", en); + evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = util_button_icon_add(obj, "list-remove", + _("Reject pairing")); + evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + } + else + { + lb = elm_label_add(obj); + elm_layout_text_set(lb, NULL, o->agent_request); + elm_box_pack_end(bx, lb); + evas_object_show(lb); + + bt = util_button_icon_add(obj, "list-add", + _("Pair with this device")); + evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = util_button_icon_add(obj, "list-remove", + _("Reject pairing")); + evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + } + } + + bt = util_button_icon_add(obj, "view-more-horizontal", + _("Options for device like conneect, pair etc.")); + evas_object_data_set(bt, "genlist", obj); + evas_object_smart_callback_add(bt, "clicked", _cb_flip, o); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + ic = util_obj_icon_rssi_add(obj, o, 24); elm_box_pack_end(bx, ic); evas_object_show(ic); @@ -581,6 +824,11 @@ ebluze5_popup_init(void) void ebluze5_popup_shutdown(void) { + if (unlock_block) + { + unlock_block = EINA_FALSE; + e_desklock_unblock(); + } ebluze5_popup_clear(); elm_genlist_item_class_free(group_itc); elm_genlist_item_class_free(dev_itc); @@ -717,6 +965,7 @@ ebluez5_popup_device_add(Obj *o) { _device_add(gl, o); } + _devices_eval(); } void @@ -739,6 +988,7 @@ ebluez5_popup_device_del(Obj *o) } } devices = eina_list_remove(devices, o); + _devices_eval(); } void @@ -779,6 +1029,7 @@ ebluez5_popup_device_change(Obj *o) } } } + _devices_eval(); } const Eina_List *