e/bluez4: separate found and created devices

Patch by: Lucas Joia <lucasjoia@profusion.mobi>



SVN revision: 82191
This commit is contained in:
Lucas Joia 2013-01-04 16:12:28 +00:00 committed by Lucas De Marchi
parent 65dc86d3e3
commit 32ba9a1358
4 changed files with 213 additions and 124 deletions

View File

@ -3,8 +3,6 @@
#include "e_mod_main.h"
#include "ebluez4.h"
#define ILIST_HEADER "Devices Found"
/* Local Variables */
static Eina_List *instances = NULL;
static E_Module *mod = NULL;
@ -14,43 +12,85 @@ EAPI E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Bluez4"};
/* Local Functions */
static void
_ebluez4_cb_pair(void *data, void *data2 __UNUSED__)
_ebluez4_search_dialog_del(Instance *inst)
{
if (!inst->search_dialog) return;
e_object_del(E_OBJECT(inst->search_dialog));
inst->search_dialog = NULL;
}
static void
_ebluez4_cb_search_dialog_del(E_Win *win)
{
E_Dialog *dialog = win->data;
_ebluez4_search_dialog_del(dialog->data);
ebluez4_stop_discovery();
DBG("Stopping discovery...");
}
static void
_ebluez4_cb_pair(void *data, E_Dialog *dialog)
{
Instance *inst = data;
const char *addr = e_widget_ilist_selected_value_get(inst->found_list);
if(!addr)
return;
ebluez4_pair_with_device(addr);
}
static void
_ebluez4_cb_search(void *data, void *data2 __UNUSED__)
{
Instance *inst = data;
E_Container *con;
E_Dialog *dialog;
Evas *evas;
if (inst->search_dialog)
_ebluez4_cb_search_dialog_del(inst->search_dialog->win);
con = e_container_current_get(e_manager_current_get());
dialog = e_dialog_new(con, "Search Dialog", "search");
e_dialog_title_set(dialog, "Searching for Devices...");
e_dialog_resizable_set(dialog, EINA_TRUE);
e_win_delete_callback_set(dialog->win, _ebluez4_cb_search_dialog_del);
evas = e_win_evas_get(dialog->win);
inst->found_list = e_widget_ilist_add(evas, 0, 0, NULL);
e_dialog_content_set(dialog, inst->found_list, 250, 220);
e_dialog_button_add(dialog, "Pair", NULL, _ebluez4_cb_pair, inst);
e_dialog_show(dialog);
dialog->data = inst;
inst->search_dialog = dialog;
ebluez4_start_discovery();
DBG("Starting discovery...");
}
static void
_ebluez4_cb_connect(void *data, void *data2 __UNUSED__)
{
Instance *inst = data;
const char *addr = e_widget_ilist_selected_value_get(inst->created_list);
if(!addr)
return;
e_gadcon_popup_hide(inst->popup);
ebluez4_connect_to_device(addr);
}
static Eina_Bool
_ebluez4_cb_stop_search(void *data)
{
Instance *inst = data;
ebluez4_stop_discovery();
e_widget_disabled_set(inst->bt, 0);
DBG("Stopping discovery...");
return ECORE_CALLBACK_CANCEL;
}
static void
_ebluez4_cb_search(void *data, void *data2 __UNUSED__)
{
Instance *inst = data;
e_widget_ilist_clear(inst->found_list);
e_widget_ilist_header_append(inst->found_list, NULL, "Devices Found");
ebluez4_start_discovery();
e_widget_disabled_set(inst->bt, 1);
ecore_timer_add(60, _ebluez4_cb_stop_search, inst);
DBG("Starting discovery...");
}
static void
_ebluez4_popup_new(Instance *inst)
{
Evas_Object *list, *tb, *bt2;
Evas_Object *list, *tb, *conn_bt, *blank, *adap_bt, *search_bt;
Evas_Coord mw, mh;
Evas *evas;
@ -60,19 +100,26 @@ _ebluez4_popup_new(Instance *inst)
evas = inst->popup->win->evas;
list = e_widget_list_add(evas, 0, 0);
inst->found_list = e_widget_ilist_add(evas, 0, 0, NULL);
e_widget_list_object_append(list, inst->found_list, 1, 1, 0.5);
inst->created_list = e_widget_ilist_add(evas, 0, 0, NULL);
e_widget_list_object_append(list, inst->created_list, 1, 1, 0.5);
ebluez4_update_instances(ctxt->devices, LIST_TYPE_CREATED_DEVICES);
e_widget_ilist_header_append(inst->found_list, NULL, ILIST_HEADER);
conn_bt = e_widget_button_add(evas, "Connect", NULL, _ebluez4_cb_connect,
inst, NULL);
search_bt = e_widget_button_add(evas, "Search New Devices", NULL,
_ebluez4_cb_search, inst, NULL);
adap_bt = e_widget_button_add(evas, "Adapters Settings", NULL, NULL, inst,
NULL);
inst->bt = e_widget_button_add(evas, "Search Devices", NULL,
_ebluez4_cb_search, inst, NULL);
bt2 = e_widget_button_add(evas, "Connect", NULL, _ebluez4_cb_pair, inst, NULL);
blank = e_widget_add(evas);
e_widget_size_min_set(blank, 0, 10);
tb = e_widget_table_add(evas, 0);
e_widget_table_object_append(tb, search_bt, 0, 0, 1, 1, 1, 1, 1, 1);
e_widget_table_object_append(tb, adap_bt, 1, 0, 1, 1, 1, 1, 1, 1);
e_widget_table_object_append(tb, inst->bt, 0, 0, 1, 1, 1, 1, 1, 1);
e_widget_table_object_append(tb, bt2, 1, 0, 1, 1, 1, 1, 1, 1);
e_widget_list_object_append(list, conn_bt, 0, 0, 0.5);
e_widget_list_object_append(list, blank, 0, 0, 0.5);
e_widget_list_object_append(list, tb, 1, 0, 0.5);
e_widget_size_min_get(list, &mw, &mh);
@ -166,6 +213,7 @@ _gc_shutdown(E_Gadcon_Client *gcc)
}
_ebluez4_popup_del(inst);
_ebluez4_search_dialog_del(inst);
E_FREE(inst);
}
@ -241,27 +289,25 @@ e_modapi_save(E_Module *m)
/* Public Functions */
void
ebluez4_disabled_set_all_search_buttons(Eina_Bool disabled)
ebluez4_append_to_instances(void *data, int list_type)
{
Eina_List *iter;
Instance *inst;
Device *dev = data;
EINA_LIST_FOREACH(instances, iter, inst)
e_widget_disabled_set(inst->bt, disabled);
if (list_type == LIST_TYPE_FOUND_DEVICES)
EINA_LIST_FOREACH(instances, iter, inst)
e_widget_ilist_append(inst->found_list, NULL, dev->name, NULL, NULL,
dev->addr);
else if (list_type == LIST_TYPE_CREATED_DEVICES)
EINA_LIST_FOREACH(instances, iter, inst)
if (dev->paired)
e_widget_ilist_append(inst->created_list, NULL, dev->name, NULL, NULL,
dev->addr);
}
void
ebluez4_append_to_instances(const char *addr, const char *name)
{
Eina_List *iter;
Instance *inst;
EINA_LIST_FOREACH(instances, iter, inst)
e_widget_ilist_append(inst->found_list, NULL, name, NULL, NULL, addr);
}
void
ebluez4_update_inst(Evas_Object *dest, Eina_List *src)
ebluez4_update_inst(Evas_Object *dest, Eina_List *src, int list_type)
{
Device *dev;
Eina_List *iter;
@ -269,9 +315,8 @@ ebluez4_update_inst(Evas_Object *dest, Eina_List *src)
e_widget_ilist_freeze(dest);
e_widget_ilist_clear(dest);
e_widget_ilist_header_append(dest, NULL, ILIST_HEADER);
EINA_LIST_FOREACH(src, iter, dev)
if (!dev->connected)
if (dev->paired || list_type == LIST_TYPE_FOUND_DEVICES)
e_widget_ilist_append(dest, NULL, dev->name, NULL, NULL, dev->addr);
e_widget_ilist_thaw(dest);
@ -279,14 +324,23 @@ ebluez4_update_inst(Evas_Object *dest, Eina_List *src)
}
void
ebluez4_update_instances(Eina_List *src)
ebluez4_update_instances(Eina_List *src, int list_type)
{
Eina_List *iter;
Instance *inst;
EINA_LIST_FOREACH(instances, iter, inst)
if (inst->found_list)
ebluez4_update_inst(inst->found_list, src);
if (list_type == LIST_TYPE_FOUND_DEVICES)
{
EINA_LIST_FOREACH(instances, iter, inst)
if (inst->found_list)
ebluez4_update_inst(inst->found_list, src, list_type);
}
else if (list_type == LIST_TYPE_CREATED_DEVICES)
{
EINA_LIST_FOREACH(instances, iter, inst)
if (inst->created_list)
ebluez4_update_inst(inst->created_list, src, list_type);
}
}
void
@ -303,5 +357,6 @@ ebluez4_update_all_gadgets_visibility()
{
_ebluez4_set_mod_icon(inst->o_bluez4);
e_gadcon_popup_hide(inst->popup);
_ebluez4_search_dialog_del(inst);
}
}

View File

@ -6,8 +6,10 @@ struct _Instance
{
E_Gadcon_Client *gcc;
E_Gadcon_Popup *popup;
Evas_Object *o_bluez4, *bt;
Evas_Object *o_bluez4;
Evas_Object *created_list;
Evas_Object *found_list;
E_Dialog *search_dialog;
};
EAPI extern E_Module_Api e_modapi;
@ -16,10 +18,9 @@ EAPI void *e_modapi_init(E_Module *m);
EAPI int e_modapi_shutdown(E_Module *m);
EAPI int e_modapi_save(E_Module *m);
void ebluez4_disabled_set_all_search_buttons(Eina_Bool disabled);
void ebluez4_append_to_instances(const char *addr, const char *name);
void ebluez4_update_inst(Evas_Object *dest, Eina_List *src);
void ebluez4_update_instances(Eina_List *src);
void ebluez4_append_to_instances(void *data, int list_type);
void ebluez4_update_inst(Evas_Object *dest, Eina_List *src, int list_type);
void ebluez4_update_instances(Eina_List *src, int list_type);
void ebluez4_update_all_gadgets_visibility();
#endif

View File

@ -52,10 +52,11 @@ _unset_adapter()
_free_dev_list(&ctxt->devices);
ctxt->devices = NULL;
_free_dev_list(&ctxt->found_devices);
ctxt->found_devices = NULL;
edbus_object_unref(ctxt->adap_obj);
ctxt->adap_obj = NULL;
ebluez4_disabled_set_all_search_buttons(EINA_TRUE);
ebluez4_update_instances(ctxt->devices);
ebluez4_update_instances(ctxt->devices, LIST_TYPE_CREATED_DEVICES);
ebluez4_update_all_gadgets_visibility();
}
@ -97,6 +98,47 @@ _set_dev_services(Device *dev, EDBus_Message_Iter *uuids)
}
}
static void
_retrieve_properties(EDBus_Message_Iter *dict, const char **addr,
const char **name, Eina_Bool *paired, Eina_Bool *connected,
EDBus_Message_Iter **uuids)
{
EDBus_Message_Iter *entry, *variant;
const char *key;
while (edbus_message_iter_get_and_next(dict, 'e', &entry))
{
if(!edbus_message_iter_arguments_get(entry, "sv", &key, &variant))
return;
if (!strcmp(key, "Address"))
{
if(!edbus_message_iter_arguments_get(variant, "s", addr))
return;
}
else if (!strcmp(key, "Name"))
{
if(!edbus_message_iter_arguments_get(variant, "s", name))
return;
}
else if (!strcmp(key, "Paired"))
{
if(!edbus_message_iter_arguments_get(variant, "b", paired))
return;
}
else if (!strcmp(key, "Connected"))
{
if(!edbus_message_iter_arguments_get(variant, "b", connected))
return;
}
else if (!strcmp(key, "UUIDs"))
{
if(!edbus_message_iter_arguments_get(variant, "as", uuids))
return;
}
}
}
static void
_on_prop_changed(void *context, const EDBus_Message *msg)
{
@ -104,6 +146,8 @@ _on_prop_changed(void *context, const EDBus_Message *msg)
Eina_Bool paired, connected;
EDBus_Message_Iter *variant, *uuids;
Device *dev = context;
Device *found_dev = eina_list_search_unsorted(ctxt->found_devices, _addr_cmp,
dev->addr);
if (!edbus_message_arguments_get(msg, "sv", &key, &variant))
{
@ -118,7 +162,12 @@ _on_prop_changed(void *context, const EDBus_Message *msg)
DBG("'%s' property of %s changed to %s", key, dev->name, name);
eina_stringshare_del(dev->name);
dev->name = eina_stringshare_add(name);
ebluez4_update_instances(ctxt->devices);
if (found_dev)
{
eina_stringshare_del(found_dev->name);
found_dev->name = eina_stringshare_add(name);
}
}
else if (!strcmp(key, "Paired"))
{
@ -126,6 +175,9 @@ _on_prop_changed(void *context, const EDBus_Message *msg)
return;
DBG("'%s' property of %s changed to %d", key, dev->name, paired);
dev->paired = paired;
if (found_dev)
found_dev->paired = paired;
}
else if (!strcmp(key, "Connected"))
{
@ -133,14 +185,17 @@ _on_prop_changed(void *context, const EDBus_Message *msg)
return;
DBG("'%s' property of %s changed to %d", key, dev->name, connected);
dev->connected = connected;
ebluez4_update_instances(ctxt->devices);
}
else if (!strcmp(key, "UUIDs"))
{
if(!edbus_message_iter_arguments_get(variant, "as", &uuids))
return;
_set_dev_services(dev, uuids);
return;
}
ebluez4_update_instances(ctxt->found_devices, LIST_TYPE_FOUND_DEVICES);
ebluez4_update_instances(ctxt->devices, LIST_TYPE_CREATED_DEVICES);
}
static void
@ -165,9 +220,6 @@ _try_to_connect(EDBus_Proxy *proxy)
static void
_on_paired(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
{
const char *path;
Device *dev = data;
const char *err_name, *err_msg;
if (edbus_message_error_get(msg, &err_name, &err_msg))
@ -175,21 +227,13 @@ _on_paired(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
ERR("%s: %s", err_name, err_msg);
return;
}
if (!edbus_message_arguments_get(msg, "o", &path))
{
ERR("Error reading device object path");
return;
}
ebluez4_connect_to_device(dev->addr);
}
static void
_on_dev_properties(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
{
EDBus_Message_Iter *dict, *entry, *variant, *uuids;
const char *key, *addr, *name;
EDBus_Message_Iter *dict, *uuids;
const char *addr, *name;
Eina_Bool paired;
Eina_Bool connected;
Device *dev = data;
@ -197,44 +241,14 @@ _on_dev_properties(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
if (!edbus_message_arguments_get(msg, "a{sv}", &dict))
return;
while (edbus_message_iter_get_and_next(dict,'e', &entry))
{
if(!edbus_message_iter_arguments_get(entry, "sv", &key, &variant))
return;
if (!strcmp(key, "Address"))
{
if(!edbus_message_iter_arguments_get(variant, "s", &addr))
return;
}
else if (!strcmp(key, "Name"))
{
if(!edbus_message_iter_arguments_get(variant, "s", &name))
return;
}
else if (!strcmp(key, "Paired"))
{
if(!edbus_message_iter_arguments_get(variant, "b", &paired))
return;
}
else if (!strcmp(key, "Connected"))
{
if(!edbus_message_iter_arguments_get(variant, "b", &connected))
return;
}
else if (!strcmp(key, "UUIDs"))
{
if(!edbus_message_iter_arguments_get(variant, "as", &uuids))
return;
}
}
_retrieve_properties(dict, &addr, &name, &paired, &connected, &uuids);
dev->addr = eina_stringshare_add(addr);
dev->name = eina_stringshare_add(name);
dev->paired = paired;
dev->connected = connected;
_set_dev_services(dev, uuids);
ebluez4_append_to_instances(addr, name);
ebluez4_append_to_instances(dev, LIST_TYPE_CREATED_DEVICES);
}
static void
@ -265,17 +279,29 @@ _on_created(void *context, const EDBus_Message *msg)
static void
_on_device_found(void *context, const EDBus_Message *msg)
{
EDBus_Message_Iter *dict;
const char *addr;
EDBus_Message_Iter *dict, *uuids;
const char *addr, *name;
Eina_Bool paired, connected;
Device *dev;
if (!edbus_message_arguments_get(msg, "sa{sv}", &addr, &dict))
return;
if(eina_list_search_unsorted(ctxt->devices, _addr_cmp, addr))
if(eina_list_search_unsorted(ctxt->found_devices, _addr_cmp, addr))
return;
edbus_proxy_call(ctxt->adap_proxy, "CreateDevice", NULL, NULL, -1, "s",
addr);
if (!edbus_message_arguments_get(msg, "a{sv}", &dict))
return;
_retrieve_properties(dict, &addr, &name, &paired, &connected, &uuids);
dev = calloc(1, sizeof(Device));
dev->addr = eina_stringshare_add(addr);
dev->name = eina_stringshare_add(name);
dev->paired = paired;
ctxt->found_devices = eina_list_append(ctxt->found_devices, dev);
ebluez4_append_to_instances(dev, LIST_TYPE_FOUND_DEVICES);
}
static void
@ -313,7 +339,6 @@ _set_adapter(const EDBus_Message *msg)
ctxt->adap_obj = edbus_object_get(ctxt->conn, BLUEZ_BUS, adap_path);
ctxt->adap_proxy = edbus_proxy_get(ctxt->adap_obj, ADAPTER_INTERFACE);
ebluez4_disabled_set_all_search_buttons(EINA_FALSE);
edbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceFound",
_on_device_found, NULL);
edbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceCreated",
@ -402,6 +427,7 @@ void
ebluez4_edbus_shutdown()
{
_free_dev_list(&ctxt->devices);
_free_dev_list(&ctxt->found_devices);
edbus_connection_unref(ctxt->conn);
free(ctxt);
@ -411,7 +437,8 @@ ebluez4_edbus_shutdown()
void
ebluez4_start_discovery()
{
ebluez4_update_instances(ctxt->devices);
_free_dev_list(&ctxt->found_devices);
ebluez4_update_instances(ctxt->found_devices, LIST_TYPE_FOUND_DEVICES);
edbus_proxy_call(ctxt->adap_proxy, "StartDiscovery", NULL, NULL, -1, "");
}
@ -425,13 +452,14 @@ void
ebluez4_connect_to_device(const char *addr)
{
Device *dev = eina_list_search_unsorted(ctxt->devices, _addr_cmp, addr);
if (dev->paired)
{
_try_to_connect(dev->proxy.input);
_try_to_connect(dev->proxy.audio_source);
_try_to_connect(dev->proxy.audio_sink);
}
else
edbus_proxy_call(ctxt->adap_proxy, "CreatePairedDevice", _on_paired, dev,
-1, "sos", dev->addr, AGENT_PATH, "KeyboardDisplay");
_try_to_connect(dev->proxy.input);
_try_to_connect(dev->proxy.audio_source);
_try_to_connect(dev->proxy.audio_sink);
}
void
ebluez4_pair_with_device(const char *addr)
{
edbus_proxy_call(ctxt->adap_proxy, "CreatePairedDevice", _on_paired, NULL,
-1, "sos", addr, AGENT_PATH, "KeyboardDisplay");
}

View File

@ -13,6 +13,9 @@
#define AudioSource_UUID "0000110a-0000-1000-8000-00805f9b34fb"
#define AudioSink_UUID "0000110b-0000-1000-8000-00805f9b34fb"
#define LIST_TYPE_FOUND_DEVICES 0
#define LIST_TYPE_CREATED_DEVICES 1
typedef enum _Profile
{
INPUT,
@ -51,6 +54,7 @@ typedef struct _Context
EDBus_Proxy *man_proxy;
EDBus_Proxy *adap_proxy;
Eina_List *devices;
Eina_List *found_devices;
} Context;
Context *ctxt;
@ -60,3 +64,4 @@ void ebluez4_edbus_shutdown();
void ebluez4_start_discovery();
void ebluez4_stop_discovery();
void ebluez4_connect_to_device(const char *addr);
void ebluez4_pair_with_device(const char *addr);