diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/bt-connection-handler.c | 560 | ||||
-rw-r--r-- | src/bt-connection-ipc.c | 113 | ||||
-rw-r--r-- | src/bt-connection-main.c | 274 | ||||
-rw-r--r-- | src/bt-connection-view.c | 504 |
4 files changed, 1451 insertions, 0 deletions
diff --git a/src/bt-connection-handler.c b/src/bt-connection-handler.c new file mode 100755 index 0000000..2d554e0 --- /dev/null +++ b/src/bt-connection-handler.c @@ -0,0 +1,560 @@ +/* +* bt-connection-popup +* +* Copyright 2012 Samsung Electronics Co., Ltd +* +* Contact: Hocheol Seo <hocheol.seo@samsung.com> +* Injun Yang <injun.yang@samsung.com> +* Seungyoun Ju <sy39.ju@samsung.com> +* +* Licensed under the Flora License, Version 1.1 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.tizenopensource.org/license +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +#include <aul.h> +#include <bluetooth.h> +#include <vconf.h> + +#include "bt-connection-main.h" +#include "bt-connection-view.h" +#include "bt-connection-handler.h" + +#define VCONFKEY_SAP_STATUS "memory/private/sap/conn_status" +#define BT_ADDRESS_LENGTH 18 + +static bool is_le_disconnecting; + +static int __bt_app_destory_cb(void *data) +{ + bt_app_data_t *ad = NULL; + + DBG(""); + + ad = (bt_app_data_t *)data; + if (ad == NULL) { + ERR("Invalid param"); + return 0; + } + + if (ad->timer) { + ecore_timer_del(ad->timer); + ad->timer = NULL; + } + + _bt_destroy_app(ad); + + return 0; +} + +static void __bt_wms_status_handler(keynode_t *key, void *data) +{ + int status; + int type; + bt_app_data_t *ad; + + ad = (bt_app_data_t *)data; + if (ad == NULL) { + ERR("Invalid param"); + return; + } + + type = vconf_keynode_get_type(key); + if (type == VCONF_TYPE_BOOL) + status = vconf_keynode_get_bool(key); + else { + ERR("Invalid vconf type : %d", type); + return; + } + + DBG("WMS is %s", status == WMS_CONNECTED ? + "connected" : "disconnected" ); + + if (status == WMS_CONNECTED) { + /* To show connected view, create new popup */ + /* or update edc part */ + /* See _bt_update_connect_status_popup() */ + if (ad->timer) { + ecore_timer_del(ad->timer); + ad->timer = NULL; + } + _bt_create_connected_popup(ad); + + _bt_send_result(ad, KEY_VAL_CONNECTED); + + ad->timer = ecore_timer_add(APP_DESTORY_TIMEOUT, + (Ecore_Task_Cb) __bt_app_destory_cb, ad); + } + + return; +} + +static void __bt_hf_connection_state_changed(int result, bool connected, const char *remote_address, bt_audio_profile_type_e type, void *user_data) +{ + if (connected == true) { + DBG("Bluetooth HF is connected"); + } + else { + DBG("Bluetooth HF is disconnected"); + } +} + +static bool __bt_adapter_bonded_device_cb(bt_device_info_s *device_info, void *user_data) +{ + int ret; + bool is_connected = false; + char* remote_address = (char*)user_data; + + if (!(device_info->bt_class.major_device_class & BT_MAJOR_DEVICE_CLASS_COMPUTER) && + !(device_info->bt_class.major_device_class & BT_MAJOR_DEVICE_CLASS_PHONE)) + return true; + + memcpy(remote_address, device_info->remote_address, BT_ADDRESS_LENGTH); + ret = bt_device_is_profile_connected(device_info->remote_address, BT_PROFILE_AG, &is_connected); + if (ret == BT_ERROR_NONE && is_connected) { + remote_address[0] = '\0'; + return false; + } + + return true; +} + +static gboolean __bt_hf_is_connected(const char* remote_address) +{ + int ret; + gboolean is_connected = FALSE; + + ret = bt_adapter_foreach_bonded_device(__bt_adapter_bonded_device_cb, (void*)remote_address); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_foreach_bonded_device is failed 0x%X", ret); + return FALSE; + } + + if (remote_address[0] == '\0') + is_connected = TRUE; + DBG("Aleady HF is %s", is_connected ? "connected" : "disconnected"); + + return is_connected; +} + +static void __bt_adapter_state_changed(int result, + bt_adapter_state_e adapter_state, void *user_data) +{ + int ret; + char remote_address[BT_ADDRESS_LENGTH] = { 0, }; + + if (user_data == NULL) { + ERR("Invalid param"); + return; + } + + if (result != BT_ERROR_NONE) { + ERR("BT Adapter operation is failed : %d", result); + return; + } + + DBG("BT Adapter is %s", adapter_state == BT_ADAPTER_ENABLED ? + "enabled" : "disabled"); + + if (adapter_state == BT_ADAPTER_ENABLED) { + if (__bt_hf_is_connected(&remote_address[0]) == FALSE) { + DBG("Make a HF connection"); + ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG); + if (ret != BT_ERROR_NONE) { + ERR("HF Connection is failed"); + return; + } + } + } + + return; +} + +int _bt_get_wms_status(void) +{ + int ret; + int status = WMS_DISCONNECTED; + + ret = vconf_get_bool(VCONFKEY_WMS_WMANAGER_CONNECTED, &status); + if (ret != 0) { + ERR("Vconf get failed"); + return WMS_DISCONNECTED; + } + + DBG("WMS status : %d", status); + + return status; +} + +void _bt_get_sap_status(void) +{ + int ret; + int status = 0; + + ret = vconf_get_int(VCONFKEY_SAP_STATUS, &status); + if (ret != 0) { + ERR("Vconf get failed"); + } + + DBG("SAP status : %d", status); + + return; +} + +gboolean _bt_send_result(bt_app_data_t *ad, const char *val) +{ + if (ad == NULL) + return FALSE; + + bundle *kb; + bundle *res_b; + int ret; + static gboolean is_sent = FALSE; + + DBG(""); + + if (ad->service_clone == NULL) { + ERR("Invalid param"); + return FALSE; + } + + if (is_sent == TRUE) { + ERR("Aleady send response !!!"); + return FALSE; + } + + ret = service_to_bundle(ad->service_clone, &kb); + if (ret != SERVICE_ERROR_NONE) { + ERR("service is failed : %d", ret); + return FALSE; + } + + aul_create_result_bundle(kb, &res_b); + if (res_b == NULL) + return FALSE; + + bundle_add(res_b, "__BT_CONNECTION__", val); + + aul_send_service_result(res_b); + bundle_free(res_b); + bundle_free(kb); + + is_sent = TRUE; + + DBG("Send result : %s", val); + + return TRUE; +} + +bool __device_check_gatt_cb(bt_profile_e profile, void *user_data) +{ + bool *is_connected = (bool *)user_data; + + if (profile == BT_PROFILE_GATT) { + *is_connected = true; + return false; + } + + return true; +} + +bool __bt_le_is_connected(const char *remote_address) +{ + int ret; + bool is_connected = false; + + if (remote_address == NULL) { + return false; + } + + ret = bt_device_foreach_connected_profiles(remote_address, + __device_check_gatt_cb, &is_connected); + if (ret != BT_ERROR_NONE) { + ERR("bt_device_foreach_connected_profiles fail (0x%08x)", ret); + return false; + } + + return is_connected; +} + +void __bt_gatt_disconnected_cb(int result, void *user_data) +{ + DBG("called"); + if (result != BT_ERROR_NONE) { + ERR("GATT disconnect fail (0x%08x)", result); + is_le_disconnecting = false; + } + + return; +#if 0 + char remote_address[BT_ADDRESS_LENGTH] = { 0, }; + bool is_advertising = false; + int ret; + + if (result != BT_ERROR_NONE) { + ERR("GATT disconnect fail (0x%08x)", result); + return; + } + + if (__bt_hf_is_connected(&remote_address[0]) == TRUE) { + DBG("Handsfree is already connected"); + return; + } + + ret = bt_adapter_is_advertising(&is_advertising); + if (ret == BT_ERROR_NONE && is_advertising) { + ret = bt_adapter_stop_advertising(); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_stop_advertising failed (0x%08x)", ret); + } + } + + DBG("Make a HF connection"); + ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG); + if (ret != BT_ERROR_NONE) { + ERR("HF Connection is failed"); + return; + } + + return; +#endif +} + +static void __bt_device_connection_state_changed_cb(bool connected, + const char *remote_address, + void *user_data) +{ + bool is_advertising = false; + int ret; + char remote_add[BT_ADDRESS_LENGTH] = { 0, }; + + DBG("address: %s, connected: %d", remote_address, connected); + + if (is_le_disconnecting == false || connected == true) { + DBG("is_le_disconnecting IS FALSE"); + return; + } + is_le_disconnecting = false; + + if (__bt_hf_is_connected(&remote_add[0]) == true) { + DBG("Handsfree is already connected"); + return; + } + + if (strncmp(remote_address, remote_add, BT_ADDRESS_LENGTH-1) != 0) { + DBG("remote address is different"); + return; + } + + ret = bt_adapter_is_advertising(&is_advertising); + if (ret == BT_ERROR_NONE && is_advertising) { + ret = bt_adapter_stop_advertising(); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_stop_advertising failed (0x%08x)", ret); + } + } + + DBG("Make a HF connection"); + ret = bt_audio_connect(&remote_add[0], BT_AUDIO_PROFILE_TYPE_AG); + if (ret != BT_ERROR_NONE) { + ERR("HF Connection is failed"); + return; + } + + return; +} + +gboolean _bt_init(void *data) +{ + int ret; + bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED; + char remote_address[BT_ADDRESS_LENGTH] = { 0, }; + bool is_advertising = false; + + bt_app_data_t *ad; + ad = (bt_app_data_t *)data; + + is_le_disconnecting = false; + + if (ad == NULL) { + return FALSE; + } + + if (ad->initialize == TRUE) { + DBG("bt_initialize already done"); + return TRUE; + } + + ret = bt_initialize(); + if (ret != BT_ERROR_NONE) { + ERR("bt_initialize is failed : %d", ret); + return FALSE; + } + + ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, data); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_set_state_changed_cb is failed : %d", ret); + bt_deinitialize(); + return FALSE; + } + + ret = bt_device_set_connection_state_changed_cb(__bt_device_connection_state_changed_cb, + NULL); + if (ret != BT_ERROR_NONE) { + ERR("bt_device_set_connection_state_changed_cb is failed : %d", ret); + return FALSE; + } + + ret = bt_adapter_get_state(&adapter_state); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_get_state is failed : %d", ret); + return FALSE; + } + + ret = bt_audio_initialize(); + if (ret != BT_ERROR_NONE) { + ERR("bt_audio_initialize is failed : %d", ret); + return FALSE; + } + + ret = bt_audio_set_connection_state_changed_cb(__bt_hf_connection_state_changed, NULL); + if (ret != BT_ERROR_NONE) { + ERR("bt_audio_set_connection_state_changed_cb is failed : %d", ret); + bt_hf_deinitialize(); + return FALSE; + } + + if (adapter_state == BT_ADAPTER_ENABLED) { + DBG("Aleady BT enabled"); +#ifdef FEATURE_TIZENW + if (__bt_hf_is_connected(&remote_address[0]) == FALSE) { + DBG("Make a HF connection"); + ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG); + if (ret != BT_ERROR_NONE) { + ERR("HF Connection is failed"); + return FALSE; + } + } +#else + if (__bt_hf_is_connected(&remote_address[0]) == FALSE) { + if (__bt_le_is_connected(&remote_address[0])) { + + ret = bt_adapter_is_advertising(&is_advertising); + if (ret == BT_ERROR_NONE && is_advertising) { + ret = bt_adapter_stop_advertising(); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_stop_advertising failed (0x%08x)", + ret); + } + } + + ret = bt_device_disconnect_le(__bt_gatt_disconnected_cb, &remote_address[0]); + if (ret == BT_ERROR_NONE) + is_le_disconnecting = true; + return TRUE; + } + + DBG("Make a HF connection"); + ret = bt_audio_connect(&remote_address[0], BT_AUDIO_PROFILE_TYPE_AG); + if (ret != BT_ERROR_NONE) { + ERR("HF Connection is failed"); + return FALSE; + } + } +#endif /* FEATURE_TIZENW */ + return TRUE; + } else { + DBG("Enable BT adapter"); + ret = bt_adapter_enable(); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_enable is failed : %d", ret); + return FALSE; + } + } + + return TRUE; +} + +void _bt_deinit(void *data) +{ + int ret; + char remote_address[BT_ADDRESS_LENGTH] = { 0, }; + bool is_advertising = FALSE; + bt_app_data_t *ad; + ad = (bt_app_data_t *)data; + + if (ad == NULL) return; + + if (ad->initialize == FALSE) { + DBG("bt_deinitialize already done"); + return; + } + + if (__bt_hf_is_connected(&remote_address[0]) == FALSE) { + ret = bt_adapter_is_advertising(&is_advertising); + if (ret == BT_ERROR_NONE && !is_advertising) { + ret = bt_adapter_start_advertising(NULL); + if (ret != BT_ERROR_NONE) { + ERR("bt_adapter_stop_advertising failed (0x%08x)", ret); + } + } + } + + ret = bt_audio_unset_connection_state_changed_cb(); + if (ret != BT_ERROR_NONE) + ERR("bt_audio_unset_connection_state_changed_cb is failed : %d", ret); + + ret = bt_audio_deinitialize(); + if (ret != BT_ERROR_NONE) + ERR("bt_audio_deinitialize is failed : %d", ret); + + ret = bt_hf_deinitialize(); + if (ret != BT_ERROR_NONE) + ERR("bt_hf_deinitialize is failed : %d", ret); + + ret = bt_device_unset_connection_state_changed_cb(); + if (ret != BT_ERROR_NONE) + ERR("bt_device_unset_connection_state_changed_cb is failed : %d", ret); + + ret = bt_adapter_unset_state_changed_cb(); + if (ret != BT_ERROR_NONE) + ERR("bt_adapter_unset_state_changed_cb is failed : %d", ret); + + ret = bt_deinitialize(); + if (ret != BT_ERROR_NONE) + ERR("bt_deinitialize is failed : %d", ret); + + return; +} + +gboolean _bt_register_vconf_handler(void *data) +{ + int ret; + + ret = + vconf_notify_key_changed(VCONFKEY_WMS_WMANAGER_CONNECTED, + (vconf_callback_fn) __bt_wms_status_handler, data); + if (ret < 0) { + ERR("Unable to register key handler"); + return FALSE; + } + + return TRUE; +} + +void _bt_unregister_vconf_handler(void) +{ + vconf_ignore_key_changed(VCONFKEY_WMS_WMANAGER_CONNECTED, + (vconf_callback_fn) __bt_wms_status_handler); + + return; +} diff --git a/src/bt-connection-ipc.c b/src/bt-connection-ipc.c new file mode 100644 index 0000000..ff63d22 --- /dev/null +++ b/src/bt-connection-ipc.c @@ -0,0 +1,113 @@ +/* +* bt-connection-popup +* +* Copyright 2012 Samsung Electronics Co., Ltd +* +* Contact: Hocheol Seo <hocheol.seo@samsung.com> +* Injun Yang <injun.yang@samsung.com> +* Seungyoun Ju <sy39.ju@samsung.com> +* +* Licensed under the Flora License, Version 1.1 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.tizenopensource.org/license +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +#include <dbus/dbus.h> +#include <dbus/dbus-glib-bindings.h> + +#include "bt-connection-main.h" +#include "bt-connection-view.h" +#include "bt-connection-handler.h" + +#define DBUS_SENSOR_PATH "/org/tizen/sensor/context/gesture" +#define DBUS_SENSOR_INTERFACE "org.tizen.sensor.context.gesture" +#define DBUS_SENSOR_WAKEUP "wakeup" +#define DBUS_CORE_APPS_PATH "/Org/Tizen/Coreapps/home/raise" +#define DBUS_CORE_APPS_INTERFACE "org.tizen.coreapps.home.raise" +#define DBUS_CORE_APPS_MEMBER "homeraise" + +static void __handle_dbus_signal(void *data, DBusMessage *msg) +{ + bt_app_data_t *ad; + const char *member; + + retm_if(data == NULL, "Invalid argument: data is NULL"); + retm_if(msg == NULL, "Invalid argument: msg is NULL"); + + ad = (bt_app_data_t *)data; + member = dbus_message_get_member(msg); + retm_if(member == NULL, "member value is NULL"); + + if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) + return; + + if (!dbus_message_has_interface(msg, DBUS_SENSOR_INTERFACE) && + !dbus_message_has_interface(msg, DBUS_CORE_APPS_INTERFACE)) + return; + + if (!dbus_message_has_path(msg, DBUS_SENSOR_PATH) && + !dbus_message_has_path(msg, DBUS_CORE_APPS_PATH)) + return; + + DBG("Received signal : %s", member); + + if ((strcasecmp(member, DBUS_SENSOR_WAKEUP) == 0) || + (strcasecmp(member, DBUS_CORE_APPS_MEMBER) == 0)) { + _bt_destroy_app(ad); + } +} + +void _bt_dbus_signal_init(bt_app_data_t *ad) +{ + DBG(""); + + E_DBus_Connection *conn = NULL; + E_DBus_Signal_Handler *sh = NULL; + + e_dbus_init(); + + conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); + retm_if(conn == NULL, "conn is NULL"); + + sh = e_dbus_signal_handler_add(conn, + NULL, + DBUS_SENSOR_PATH, + DBUS_SENSOR_INTERFACE, + DBUS_SENSOR_WAKEUP, + __handle_dbus_signal, ad); + retm_if(sh == NULL, "Connect Event register failed"); + ad->gesture_sh = sh; + + sh = e_dbus_signal_handler_add(conn, + NULL, + DBUS_CORE_APPS_PATH, + DBUS_CORE_APPS_INTERFACE, + DBUS_CORE_APPS_MEMBER, + __handle_dbus_signal, ad); + retm_if(sh == NULL, "Connect Event register failed"); + ad->app_core_sh = sh; + + ad->dbus_conn = conn; + return; +} + + +void _bt_dbus_signal_deinit(bt_app_data_t *ad) +{ + ret_if(ad == NULL); + + DBG(""); + e_dbus_signal_handler_del(ad->dbus_conn, ad->gesture_sh); + e_dbus_signal_handler_del(ad->dbus_conn, ad->app_core_sh); + return; +} + diff --git a/src/bt-connection-main.c b/src/bt-connection-main.c new file mode 100644 index 0000000..96df31d --- /dev/null +++ b/src/bt-connection-main.c @@ -0,0 +1,274 @@ +/* +* bt-connection-popup +* +* Copyright 2012 Samsung Electronics Co., Ltd +* +* Contact: Hocheol Seo <hocheol.seo@samsung.com> +* Injun Yang <injun.yang@samsung.com> +* Seungyoun Ju <sy39.ju@samsung.com> +* +* Licensed under the Flora License, Version 1.1 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.tizenopensource.org/license +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +#include <app.h> +#include <efl_assist.h> + +#include "bt-connection-main.h" +#include "bt-connection-view.h" +#include "bt-connection-handler.h" +#include "bt-connection-ipc.h" + +static Evas_Object* _create_win(const char *name) +{ + Evas_Object *eo; + int w; + int h; + + eo = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC); + if (eo) { + elm_win_title_set(eo, name); + elm_win_borderless_set(eo, EINA_TRUE); + ecore_x_window_size_get(ecore_x_window_root_first_get(), + &w, &h); + evas_object_resize(eo, w, h); + } + + return eo; +} + +static Eina_Bool _pop_cb(void *data, Elm_Object_Item *it) +{ + DBG(""); + + if (!data) { + return EINA_FALSE; + } + + elm_exit(); + return EINA_FALSE; +} + +void __destory_app_cb(void *data, Evas_Object *obj, void *event_info) +{ + if (data == NULL) + return; + + DBG("EA Back on navi"); + + bt_app_data_t *ad = (bt_app_data_t *)data; + + _bt_destroy_app(ad); +} + +static Evas_Object* _create_layout_main(Evas_Object* parent) +{ + Evas_Object *layout; + + if (parent == NULL) + return NULL; + + layout = elm_layout_add(parent); + if (layout == NULL) + return NULL; + + elm_layout_theme_set(layout, "layout", "application", "default"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(parent, "elm.swallow.content", layout); + evas_object_show(layout); + + return layout; +} + +static Evas_Object* _create_naviframe(Evas_Object* parent) +{ + Evas_Object *naviframe; + + if (parent == NULL) + return NULL; + naviframe = elm_naviframe_add(parent); + elm_object_part_content_set(parent, "elm.swallow.content", naviframe); + + return naviframe; +} + +static void _create_view_layout(bt_app_data_t *ad) +{ + if (ad == NULL || ad->navi == NULL) + return; + + ea_object_event_callback_add(ad->navi, EA_CALLBACK_BACK, + __destory_app_cb, ad); + + _bt_create_connection_query_popup(ad); + + DBG("-"); +} + +static int __initialize_view(bt_app_data_t *ad) +{ + DBG("+"); + + Elm_Object_Item *navi_it; + + if (ad == NULL) + return -1; + + ad->layout_main = _create_layout_main(ad->window); + if (!ad->layout_main) + return -1; + + ad->navi = _create_naviframe(ad->layout_main); + + _create_view_layout(ad); + + navi_it = elm_naviframe_item_push(ad->navi, NULL, NULL, NULL, ad->main_layout, NULL); + elm_naviframe_item_title_enabled_set(navi_it, EINA_FALSE, EINA_FALSE); + elm_naviframe_item_pop_cb_set(navi_it, _pop_cb, ad); + elm_naviframe_item_title_visible_set(navi_it, EINA_FALSE); + + DBG("-"); + + return 0; +} + +static bool app_create(void *data) +{ + DBG(""); + + bt_app_data_t *ad; + ad = (bt_app_data_t *)data; + + ad->initialize = FALSE; + ad->window = _create_win(PACKAGE); + if (ad->window == NULL) + return FALSE; + + evas_object_show(ad->window); + + /* Handle rotation */ + if (elm_win_wm_rotation_supported_get(ad->window)) { + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(ad->window, + (const int*)(&rots), 4); + } + + _bt_register_vconf_handler(ad); + + return TRUE; +} + +static void app_terminate(void *data) +{ + DBG(""); + + int status; + bt_app_data_t *ad = (bt_app_data_t *)data; + if (ad == NULL) + return; + + status = _bt_get_wms_status(); + if (status == WMS_DISCONNECTED) { + /* In case WMS_CONNECTED, */ + /* we sent result on connected view */ + DBG("App terminiated. Send response (Not Connected)"); + _bt_send_result(ad, KEY_VAL_NOT_CONNECTED); + } + + _bt_get_sap_status(); /* Check sap status */ + + return; +} + +static void app_pause(void *data) +{ + DBG(""); + return; +} + +static void app_resume(void *data) +{ + DBG(""); + return; +} + +static void app_service(service_h service, void *data) +{ + DBG(""); + + char *caller = NULL; + bt_app_data_t *ad; + + ad = (bt_app_data_t *)data; + if (ad == NULL) + return; + + if (ad->dbus_conn == NULL) { + _bt_dbus_signal_init(ad); + } + + ad->service = service; + service_clone(&ad->service_clone, service); + service_get_caller(service, &caller); + DBG_SECURE("Launched by %s", caller); + + if (__initialize_view(ad) < 0) { + ERR("__initialize_view failed"); + } + + return; +} + +static void app_lang_changed(void *data) +{ + return; +} + +static void app_regeion_changed(void *data) +{ + return; +} + +/** +* @describe +* The entry of the program +* +* @param argc +* @param argv +* @param int +* @exception +*/ +DLL_DEFAULT int main(int argc, char *argv[]) +{ + bt_app_data_t ad; + + app_event_callback_s event_callback; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.service = app_service; + event_callback.low_memory = NULL; + event_callback.low_battery = NULL; + event_callback.device_orientation = NULL; + event_callback.language_changed = app_lang_changed; + event_callback.region_format_changed = app_regeion_changed; + + memset(&ad, 0x0, sizeof(bt_app_data_t)); + setenv("EVAS_NO_DRI_SWAPBUF", "1", 1); + + DBG(""); + return app_efl_main(&argc, &argv, &event_callback, &ad); + +} diff --git a/src/bt-connection-view.c b/src/bt-connection-view.c new file mode 100644 index 0000000..8db4f42 --- /dev/null +++ b/src/bt-connection-view.c @@ -0,0 +1,504 @@ +/* +* bt-connection-popup +* +* Copyright 2012 Samsung Electronics Co., Ltd +* +* Contact: Hocheol Seo <hocheol.seo@samsung.com> +* Injun Yang <injun.yang@samsung.com> +* Seungyoun Ju <sy39.ju@samsung.com> +* +* Licensed under the Flora License, Version 1.1 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.tizenopensource.org/license +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + + +#include "bt-connection-main.h" +#include "bt-connection-view.h" +#include "bt-connection-string.h" +#include "bt-connection-handler.h" +#include "bt-connection-ipc.h" + + +static void __bt_draw_popup(bt_app_data_t *ad, + const char *title, const char *msg, char *btn1_text, + char *btn2_text, void (*func) (void *data, + Evas_Object *obj, void *event_info)) +{ + Evas_Object *btn1; + Evas_Object *btn2; + Evas_Object *scroller; + Evas_Object *label; + char *txt; + + DBG("+"); + + ad->popup = elm_popup_add(ad->window); + evas_object_size_hint_weight_set(ad->popup, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + if (title != NULL) + elm_object_part_text_set(ad->popup, "title,text", title); + + if (msg != NULL) { + scroller = elm_scroller_add(ad->popup); + elm_object_style_set(scroller, "effect"); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_object_content_set(ad->popup, scroller); + evas_object_show(scroller); + + label = elm_label_add(scroller); + elm_object_style_set(label, "popup/default"); + elm_label_line_wrap_set(label, ELM_WRAP_MIXED); + + txt = elm_entry_utf8_to_markup(msg); + elm_object_text_set(label, txt); + free(txt); + + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, + EVAS_HINT_FILL); + elm_object_content_set(scroller, label); + } + + if ((btn1_text != NULL) && (btn2_text != NULL)) { + btn1 = elm_button_add(ad->popup); + elm_object_style_set(btn1, "popup"); + elm_object_text_set(btn1, btn1_text); + elm_object_part_content_set(ad->popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", func, ad); + + btn2 = elm_button_add(ad->popup); + elm_object_style_set(btn2, "popup"); + elm_object_text_set(btn2, btn2_text); + elm_object_part_content_set(ad->popup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", func, ad); + } else if (btn1_text != NULL) { + btn1 = elm_button_add(ad->popup); + elm_object_style_set(btn1, "popup"); + elm_object_text_set(btn1, btn1_text); + elm_object_part_content_set(ad->popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", func, ad); + } + + evas_object_show(ad->popup); + evas_object_show(ad->window); + elm_object_focus_set(ad->popup, EINA_TRUE); + + DBG("-"); +} + + +static void __bt_draw_connect_popup(bt_app_data_t *ad, + const char *msg, char *btn_text, + void (*func) (void *data, + Evas_Object *obj, void *event_info)) +{ + Evas_Object *btn; + Evas_Object *icon; + Evas_Object *scroller; + Evas_Object *label; + Evas_Object *bg; + Evas_Object *layout; + Evas_Object *default_ly; + Evas_Object *scroller_layout; + char *txt; + + DBG("+"); + + bg = elm_bg_add(ad->window); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->window, bg); + evas_object_show(bg); + + default_ly = elm_layout_add(bg); + elm_layout_theme_set(default_ly, "layout", "application", "default"); + evas_object_size_hint_weight_set(default_ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(bg, "elm.swallow.content", default_ly); + evas_object_show(default_ly); + + /* layout */ + layout = elm_layout_add(default_ly); + + elm_layout_file_set(layout, CUSTOM_POPUP_PATH, "connect_popup"); + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + scroller = elm_scroller_add(layout); + elm_object_style_set(scroller, "effect"); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_show(scroller); + + scroller_layout = elm_layout_add(scroller); + elm_layout_file_set(scroller_layout, CUSTOM_POPUP_PATH, "connect_popup_scroller"); + evas_object_size_hint_weight_set(scroller_layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_WATCH); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.watch", icon); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_PHONE); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.phone", icon); + + label = elm_label_add(scroller_layout); + elm_object_style_set(label, "popup/default"); + elm_label_line_wrap_set(label, ELM_WRAP_MIXED); + + txt = elm_entry_utf8_to_markup(msg); + elm_object_text_set(label, txt); + free(txt); + elm_object_part_content_set(scroller_layout, "elm.text.block", label); + + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_content_set(scroller, scroller_layout); + + elm_object_part_content_set(layout, "scroller", scroller); + + evas_object_show(layout); + + if (btn_text != NULL) { + btn = elm_button_add(layout); + elm_object_text_set(btn, btn_text); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(layout, "btn", btn); + evas_object_smart_callback_add(btn, "clicked", func, ad); + } + + elm_object_part_content_set(default_ly, "elm.swallow.content", layout); + elm_object_content_set(ad->window, bg); + + evas_object_show(ad->window); + + DBG("-"); +} + +static void __bt_draw_connected_popup(bt_app_data_t *ad, + const char *msg, void (*func) (void *data, + Evas_Object *obj, void *event_info)) +{ + DBG("+"); + + Evas_Object *icon; + Evas_Object *scroller; + Evas_Object *label; + Evas_Object *bg; + Evas_Object *layout; + Evas_Object *default_ly; + Evas_Object *scroller_layout; + char *txt; + + bg = elm_bg_add(ad->window); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->window, bg); + evas_object_show(bg); + + default_ly = elm_layout_add(bg); + elm_layout_theme_set(default_ly, "layout", "application", "default"); + evas_object_size_hint_weight_set(default_ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(bg, "elm.swallow.content", default_ly); + evas_object_show(default_ly); + + /* layout */ + layout = elm_layout_add(default_ly); + + elm_layout_file_set(layout, CUSTOM_POPUP_PATH, "connected_popup"); + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + scroller = elm_scroller_add(layout); + elm_object_style_set(scroller, "effect"); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_show(scroller); + + scroller_layout = elm_layout_add(scroller); + elm_layout_file_set(scroller_layout, CUSTOM_POPUP_PATH, "connected_popup_scroller"); + evas_object_size_hint_weight_set(scroller_layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_WATCH); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.watch", icon); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_PHONE); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.phone", icon); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_ICON); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.icon", icon); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_CONNECT); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.dot1", icon); + + icon = elm_image_add(scroller_layout); + elm_image_file_set(icon, CUSTOM_POPUP_PATH, BT_IMAGE_CONNECT); + elm_object_part_content_set(scroller_layout, "elm.swallow.img.dot2", icon); + + label = elm_label_add(scroller_layout); + elm_object_style_set(label, "popup/default"); + elm_label_line_wrap_set(label, ELM_WRAP_MIXED); + + txt = elm_entry_utf8_to_markup(msg); + elm_object_text_set(label, txt); + free(txt); + elm_object_part_content_set(scroller_layout, "elm.text.block", label); + + evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL); + + elm_object_content_set(scroller, scroller_layout); + + elm_object_part_content_set(layout, "scroller", scroller); + + evas_object_show(layout); + + elm_object_part_content_set(default_ly, "elm.swallow.content", layout); + elm_object_content_set(ad->window, bg); + + evas_object_show(ad->window); + + DBG("-"); +} + +static void __bt_connection_confirm_cb(void *data, + Evas_Object *obj, void *event_info) +{ + if (obj == NULL || data == NULL) + return; + + bt_app_data_t *ad = (bt_app_data_t *)data; + const char *event = elm_object_text_get(obj); + + if (!g_strcmp0(event, STR_OK)) { + DBG("+ OK"); + _bt_destroy_app(ad); + } else { + DBG("+ Connect"); + + evas_object_del(obj); + _bt_create_connecting_popup(ad); + + if (ad->initialize == FALSE) { + ad->initialize = _bt_init(ad); + } + } +} + +static void __bt_connection_timeout_cb(void *data, + Evas_Object *obj, void *event_info) +{ + bt_app_data_t *ad = NULL; + ad = (bt_app_data_t *)data; + if (ad == NULL) { + ERR("Invalid param"); + return; + } + + if (ad->timer) { + ecore_timer_del(ad->timer); + ad->timer = NULL; + } + + _bt_create_connection_timeout_popup(ad); +} + +static void __bt_connection_retry_cb(void *data, + Evas_Object *obj, void *event_info) +{ + if (obj == NULL || data == NULL) + return; + + bt_app_data_t *ad = (bt_app_data_t *)data; + const char *event = elm_object_text_get(obj); + + if (!g_strcmp0(event, STR_CANCEL)) { + DBG("+ Cancel"); + _bt_destroy_app(ad); + } else { + DBG("+ OK"); + + evas_object_del(obj); + _bt_create_connecting_popup(ad); + + if (ad->initialize == FALSE) { + ad->initialize = _bt_init(ad); + } + } +} + +static void __bt_connecting_cancel_cb(void *data, + Evas_Object *obj, void *event_info) +{ + if (obj == NULL || data == NULL) + return; + + bt_app_data_t *ad = (bt_app_data_t *)data; + const char *event = elm_object_text_get(obj); + + if (!g_strcmp0(event, STR_CANCEL)) { + DBG("+ Cancel"); + _bt_destroy_app(ad); + } +} + +void _bt_create_connection_query_popup(bt_app_data_t *ad) +{ + DBG("+"); + + int ret; + char *str = STR_UNABLE_REFRESH_APP_BT_DISCONNECTED; + char *value = NULL; + + ret = service_get_extra_data(ad->service, "msg", &value); + if (ret == SERVICE_ERROR_NONE) { + if (g_strcmp0(value, "refresh") == 0) + str = STR_UNABLE_REFRESH_APP_BT_DISCONNECTED; + else if (g_strcmp0(value, "perform") == 0) { + str = STR_UNABLE_PERFORM_ACTION_BT_DISCONNECTED;} + else if (g_strcmp0(value, "open") == 0) + str = STR_UNABLE_OPEN_APP_BT_DISCONNECTED; + + free(value); + } + + _bt_destroy_popup(ad); + + __bt_draw_popup(ad, STR_TITLE_ERROR, + str, STR_OK, STR_CONNECT, + __bt_connection_confirm_cb); + + DBG("-"); +} + +void _bt_create_connecting_popup(bt_app_data_t *ad) +{ + DBG("+"); + + _bt_destroy_popup(ad); + + __bt_draw_connect_popup(ad, STR_CONNECTING_BT, + STR_CANCEL, __bt_connecting_cancel_cb); + + ad->timer = ecore_timer_add(CONNECT_TIMEOUT, + (Ecore_Task_Cb) __bt_connection_timeout_cb, ad); + + DBG("-"); +} + +void _bt_create_connection_timeout_popup(bt_app_data_t *ad) +{ + DBG("+"); + + _bt_destroy_popup(ad); + + __bt_draw_popup(ad, STR_TITLE_ERROR, + STR_CONNECTION_TIME_OUT_RETRY, + STR_CANCEL, STR_OK, + __bt_connection_retry_cb); + + DBG("-"); +} + +void _bt_create_connected_popup(bt_app_data_t *ad) +{ + DBG("+"); + + _bt_destroy_popup(ad); + + __bt_draw_connected_popup(ad, STR_CONNECTED_BT, NULL); + + DBG("-"); +} + +void _bt_update_connect_status_popup(bt_app_data_t *ad) +{ + if (ad == NULL) + return; + + Evas_Object *layout; + Evas_Object *button; + + layout = elm_object_content_get(ad->popup); + if (layout == NULL) { + ERR("Unable to get object"); + return; + } + elm_object_part_text_set(layout, "elm.text.subtext", STR_CONNECTED_BT); + + button = elm_object_part_content_get(ad->popup, "button1"); + if (button) { + evas_object_del(button); + } + + evas_object_show(ad->popup); + evas_object_show(ad->window); +} + +void _bt_destroy_popup(bt_app_data_t *ad) +{ + if (ad == NULL) + return; + + DBG(""); + + if (ad->popup) { + evas_object_del(ad->popup); + ad->popup = NULL; + } +} + +void _bt_clean_app(bt_app_data_t *ad) +{ + if (ad == NULL) + return; + + DBG("+"); + + if (ad->timer) { + ecore_timer_del(ad->timer); + ad->timer = NULL; + } + + if (ad->popup) { + evas_object_del(ad->popup); + ad->popup = NULL; + } + + if (ad->window) { + evas_object_del(ad->window); + ad->window = NULL; + } +} + +void _bt_destroy_app(bt_app_data_t *ad) +{ + DBG("Terminate app"); + + _bt_clean_app(ad); + + _bt_dbus_signal_deinit(ad); + _bt_unregister_vconf_handler(); + _bt_deinit(ad); + + elm_exit(); +} + |