diff options
Diffstat (limited to 'ug-wifidirect/src')
-rwxr-xr-x | ug-wifidirect/src/wfd_client.c | 1431 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug.c | 524 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug_about_view.c | 116 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug_genlist.c | 793 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug_main_view.c | 1190 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug_multiconnect_view.c | 807 | ||||
-rwxr-xr-x | ug-wifidirect/src/wfd_ug_popup.c | 379 |
7 files changed, 5240 insertions, 0 deletions
diff --git a/ug-wifidirect/src/wfd_client.c b/ug-wifidirect/src/wfd_client.c new file mode 100755 index 0000000..60092bb --- /dev/null +++ b/ug-wifidirect/src/wfd_client.c @@ -0,0 +1,1431 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <stdio.h> +#include <stdbool.h> +#include <libintl.h> + +#include <Elementary.h> +#include <pmapi.h> +#include <vconf.h> +//#include <vconf-keys.h> +#include <tethering.h> +#include <network-cm-intf.h> +#include <network-wifi-intf.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +/** + * This function let the ug make a change callback for wifi state + * @return void + * @param[in] key the pointer to the key + * @param[in] data the pointer to the main data structure + */ +static void _wifi_state_cb(keynode_t *key, void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + int wifi_state; + + res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + if (res != 0) { + WDUG_LOGE("Failed to get wifi state from vconf. [%d]\n", res); + return; + } + + if (wifi_state == VCONFKEY_WIFI_OFF) { + WDUG_LOGI("WiFi is turned off\n"); + wfd_client_swtch_force(ugd, TRUE); + } else { + WDUG_LOGI("WiFi is turned on\n"); + } + + res = net_deregister_client(); + if (res != NET_ERR_NONE) { + WDUG_LOGE("Failed to deregister network client. [%d]\n", res); + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug make a event callback for network registering + * @return void + * @param[in] event_info the pointer to the information of network event + * @param[in] user_data the pointer to the user data + */ +static void _network_event_cb(net_event_info_t *event_info, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + WDUG_LOGI("Event from network. [%d]\n", event_info->Event); + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug turn wifi off + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_wifi_off(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + + res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd); + if (res == -1) { + WDUG_LOGE("Failed to register vconf callback\n"); + return -1; + } + + WDUG_LOGI("Vconf key callback is registered\n"); + + res = net_register_client((net_event_cb_t) _network_event_cb, NULL); + if (res != NET_ERR_NONE) { + WDUG_LOGE("Failed to register network client. [%d]\n", res); + return -1; + } + + WDUG_LOGI("Network client is registered\n"); + + res = net_wifi_power_off(); + if (res != NET_ERR_NONE) { + WDUG_LOGE("Failed to turn off wifi. [%d]\n", res); + return -1; + } + + WDUG_LOGI("WiFi power off\n"); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug make a change callback for enabling hotspot state + * @return void + * @param[in] key the pointer to the key + * @param[in] data the pointer to the main data structure + */ +static void _enable_hotspot_state_cb(keynode_t *key, void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + int hotspot_mode; + tethering_error_e ret = TETHERING_ERROR_NONE; + tethering_h th = NULL; + + res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode); + if (res != 0) { + WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res); + return; + } + + if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) { + WDUG_LOGI(" Mobile hotspot is activated\n"); + } + + th = ugd->hotspot_handle; + + if (th != NULL) { + /* Deregister cbs */ + ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_unset_enabled_cb is failed(%d)\n", ret); + } + + /* Destroy tethering handle */ + ret = tethering_destroy(th); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_destroy is failed(%d)\n", ret); + } + + ugd->hotspot_handle = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug make a change callback for disabling hotspot state + * @return void + * @param[in] key the pointer to the key + * @param[in] data the pointer to the main data structure + */ +static void _disable_hotspot_state_cb(keynode_t *key, void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + int hotspot_mode; + tethering_error_e ret = TETHERING_ERROR_NONE; + tethering_h th = NULL; + + res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode); + if (res != 0) { + WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res); + return; + } + + if (!(hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)) { + WDUG_LOGI(" Mobile hotspot is deactivated\n"); + wfd_client_swtch_force(ugd, TRUE); + } + + th = ugd->hotspot_handle; + + if (th != NULL) { + /* Deregister cbs */ + ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_unset_disabled_cb is failed(%d)\n", ret); + } + + /* Destroy tethering handle */ + ret = tethering_destroy(th); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_destroy is failed(%d)\n", ret); + } + + ugd->hotspot_handle = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug make a callback for setting tethering mode enabled + * @return void + * @param[in] error the returned error code + * @param[in] type the type of tethering + * @param[in] is_requested whether tethering mode is enabled + * @param[in] data the pointer to the user data + */ +static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (error != TETHERING_ERROR_NONE) { + if (is_requested != TRUE) { + return; + } + + WDUG_LOGE("error !!! TETHERING is not enabled.\n"); + return; + } + + WDUG_LOGI("TETHERING is enabled.\n"); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug make a callback for setting tethering mode disabled + * @return void + * @param[in] error the returned error code + * @param[in] type the type of tethering + * @param[in] code whether tethering mode is enabled + * @param[in] data the pointer to the user data + */ +static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (error != TETHERING_ERROR_NONE) { + if (code != TETHERING_DISABLED_BY_REQUEST) { + return; + } + + WDUG_LOGE("error !!! TETHERING is not disabled.\n"); + return; + } + + WDUG_LOGI("TETHERING is disabled.\n"); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug turn AP on + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_mobile_ap_on(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + tethering_error_e ret = TETHERING_ERROR_NONE; + tethering_h th = NULL; + + res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb, ugd); + if (res == -1) { + WDUG_LOGE("Failed to register vconf callback\n"); + return -1; + } + + /* Create tethering handle */ + ret = tethering_create(&th); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("Failed to tethering_create() [%d]\n", ret); + return -1; + } else { + WDUG_LOGI("Succeeded to tethering_create()\n"); + } + + /* Register cbs */ + ret = tethering_set_enabled_cb(th, TETHERING_TYPE_WIFI, __enabled_cb, NULL); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_set_enabled_cb is failed\n", ret); + return -1; + } + + /* Enable tethering */ + ret = tethering_enable(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("Failed to turn on mobile hotspot. [%d]\n", ret); + return -1; + } else { + WDUG_LOGI("Succeeded to turn on mobile hotspot\n"); + } + + ugd->hotspot_handle = th; + ugd->is_hotspot_off = FALSE; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug turn AP off + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_mobile_ap_off(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + tethering_error_e ret = TETHERING_ERROR_NONE; + tethering_h th = NULL; + + res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb, ugd); + if (res == -1) { + WDUG_LOGE("Failed to register vconf callback\n"); + return -1; + } + + /* Create tethering handle */ + ret = tethering_create(&th); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("Failed to tethering_create() [%d]\n", ret); + return -1; + } else { + WDUG_LOGI("Succeeded to tethering_create()\n"); + } + + /* Register cbs */ + ret = tethering_set_disabled_cb(th, TETHERING_TYPE_WIFI, __disabled_cb, NULL); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_set_disabled_cb is failed\n", ret); + return -1; + } + + /* Disable tethering */ + ret = tethering_disable(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("Failed to turn off mobile hotspot. [%d]\n", ret); + return -1; + } else { + WDUG_LOGI("Succeeded to turn off mobile hotspot\n"); + } + + ugd->hotspot_handle = th; + ugd->is_hotspot_off = TRUE; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug find the peer by mac address + * @return the found peer + * @param[in] data the pointer to the main data structure + * @param[in] mac_addr the pointer to mac address + */ +static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int i; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) { + for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) { + WDUG_LOGI("[Multi Connect] check %dth peer\n", i); + if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH)) { + WDUG_LOGI("selected found peer. [%d]\n", i); + __WDUG_LOG_FUNC_EXIT__; + return &ugd->raw_multi_selected_peers[i]; + } + } + } else { + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + WDUG_LOGI("check %dth peer\n", i); + if (!strncmp(mac_addr, (const char *)ugd->raw_discovered_peers[i].mac_addr, MAC_LENGTH)) { + WDUG_LOGI("found peer. [%d]\n", i); + __WDUG_LOG_FUNC_EXIT__; + return &ugd->raw_discovered_peers[i]; + } + } + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug make a callback for registering activation event + * @return void + * @param[in] error_code the returned error code + * @param[in] device_state the state of device + * @param[in] user_data the pointer to the main data structure + */ +void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + int res = -1; + struct ug_data *ugd = (struct ug_data *)user_data; + + wfd_refresh_wifi_direct_state(ugd); + + switch (device_state) { + case WIFI_DIRECT_DEVICE_STATE_ACTIVATED: + WDUG_LOGI("WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n"); + if (error_code != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Error in Activation/Deactivation [%d]\n", error_code); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL); + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + ugd->wfd_onoff = 0; + wfd_ug_view_refresh_glitem(ugd->head); + return; + } + + ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED; + ugd->wfd_onoff = 1; + wfd_ug_view_refresh_glitem(ugd->head); + + wfg_ug_act_popup_remove(ugd); + + res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for wifi state\n"); + } + + res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n"); + } + + res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to start discovery. [%d]\n", res); + ugd->is_re_discover = TRUE; + wifi_direct_cancel_discovery(); + } else { + WDUG_LOGI("Discovery is started\n"); + ugd->is_re_discover = FALSE; + } + + break; + case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED: + WDUG_LOGI("WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n"); + if (error_code != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Error in Activation/Deactivation [%d]\n", error_code); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL); + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + ugd->wfd_onoff = 1; + wfd_ug_view_refresh_glitem(ugd->head); + return; + } + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + ugd->wfd_onoff = 0; + + /* + * when deactivated, clear all the + * discovered peers and connected peers + */ + if (ugd->raw_discovered_peer_cnt > 0) { + memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s)); + } + + if (ugd->raw_connected_peer_cnt > 0) { + memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s)); + } + + ugd->raw_discovered_peer_cnt = 0; + ugd->raw_connected_peer_cnt = 0; + + wfd_ug_view_update_peers(ugd); + + /* remove the callback for hotspot */ + res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n"); + } + + /* when deactivated, stop the timer */ + if (ugd->monitor_timer) { + ecore_timer_del(ugd->monitor_timer); + ugd->monitor_timer = NULL; + } + break; + default: + break; + } + + wfd_ug_view_refresh_glitem(ugd->head); + + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + + if (ugd->back_btn) { + elm_object_disabled_set(ugd->back_btn, FALSE); + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug make a callback for discovering peer + * @return TRUE + * @param[in] peer the pointer to the discovered peer + * @param[in] user_data the pointer to the main data structure + */ +bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + if (NULL == peer || NULL == user_data) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + __WDUG_LOG_FUNC_EXIT__; + return FALSE; + } + + struct ug_data *ugd = (struct ug_data *)user_data; + int peer_cnt = ugd->raw_discovered_peer_cnt; + + WDUG_LOGI("%dth discovered peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address); + + strncpy(ugd->raw_discovered_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_discovered_peers[peer_cnt].ssid)); + ugd->raw_discovered_peers[peer_cnt].category = peer->primary_device_type; + strncpy(ugd->raw_discovered_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH); + strncpy(ugd->raw_discovered_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH); + ugd->raw_discovered_peers[peer_cnt].is_group_owner = peer->is_group_owner; + ugd->raw_discovered_peers[peer_cnt].is_persistent_group_owner = peer->is_persistent_group_owner; + ugd->raw_discovered_peers[peer_cnt].is_connected = peer->is_connected; + + if (TRUE == peer->is_connected) { + ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED; + } else { + ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED; + } + + WDUG_LOGI("\tSSID: [%s]\n", ugd->raw_discovered_peers[peer_cnt].ssid); + WDUG_LOGI("\tPeer category [%d] -> [%d]\n", peer->primary_device_type, ugd->raw_discovered_peers[peer_cnt].category); + WDUG_LOGI("\tStatus: [%d]\n", ugd->raw_discovered_peers[peer_cnt].conn_status); + + ugd->raw_discovered_peer_cnt++; + + free(peer->device_name); + free(peer->mac_address); + free(peer->interface_address); + free(peer); + + __WDUG_LOG_FUNC_EXIT__; + return TRUE; +} + +/** + * This function let the ug make a callback for connected peer + * @return TRUE + * @param[in] peer the pointer to the connected peer + * @param[in] user_data the pointer to the main data structure + */ +bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + if (NULL == peer || NULL == user_data) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + __WDUG_LOG_FUNC_EXIT__; + return FALSE; + } + + struct ug_data *ugd = (struct ug_data *)user_data; + int peer_cnt = ugd->raw_connected_peer_cnt; + + WDUG_LOGI("%dth connected peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address); + + strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid)); + ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type; + strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH); + strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH); + ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED; + + WDUG_LOGI("\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status); + WDUG_LOGI("\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category); + WDUG_LOGI("\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid); + WDUG_LOGI("\tMAC addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].mac_addr); + WDUG_LOGI("\tIface addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].if_addr); + + ugd->raw_connected_peer_cnt++; + + free(peer->device_name); + free(peer->mac_address); + free(peer->interface_address); + free(peer); + + __WDUG_LOG_FUNC_EXIT__; + return TRUE; +} + +/** + * This function let the ug get the found peers + * @return If success, return 0, else return -1 + * @param[in] ugd the pointer to the main data structure + */ +int wfd_ug_get_discovered_peers(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + int res = 0; + + if (ugd == NULL) { + return -1; + } + + ugd->raw_discovered_peer_cnt = 0; + res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd); + if (res != WIFI_DIRECT_ERROR_NONE) { + ugd->raw_discovered_peer_cnt = 0; + WDUG_LOGE("Get discovery result failed: %d\n", res); + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug get the connected peers + * @return If success, return 0, else return -1 + * @param[in] ugd the pointer to the main data structure + */ +int wfd_ug_get_connected_peers(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + int res = 0; + + if (ugd == NULL) { + return -1; + } + + ugd->raw_connected_peer_cnt = 0; + res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd); + if (res != WIFI_DIRECT_ERROR_NONE) { + ugd->raw_connected_peer_cnt = 0; + WDUG_LOGE("Get connected peer failed: %d\n", res); + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug make a callback for deactivating wfd automatically + * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW + * @param[in] user_data the pointer to the main data structure + */ +static Eina_Bool _wfd_automatic_deactivated_for_no_connection_cb(void *user_data) +{ + int res = -1; + int interval = 0; + struct ug_data *ugd = (struct ug_data *)user_data; + + if (NULL == ugd) { + WDUG_LOGE("NULL parameters.\n"); + return ECORE_CALLBACK_CANCEL; + } + + /* check the action, if action is exist, keep the cb */ + res = wifi_direct_get_state(&ugd->wfd_status); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to get link status. [%d]\n", res); + return ECORE_CALLBACK_CANCEL; + } + + if (ugd->last_wfd_status != ugd->wfd_status) { + WDUG_LOGE("Action is exist, last status: %d\n", + ugd->last_wfd_status); + ugd->last_wfd_status = ugd->wfd_status; + ugd->last_wfd_time = time(NULL); + return ECORE_CALLBACK_RENEW; + } + + /* check the timeout, if not timeout, keep the cb */ + interval = time(NULL) - ugd->last_wfd_time; + if (interval < MAX_NO_ACTION_TIME_OUT) { + return ECORE_CALLBACK_RENEW; + } + + /* turn off the Wi-Fi Direct */ + wifi_direct_get_state(&ugd->wfd_status); + if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) { + WDUG_LOGE("Wi-Fi Direct is already deactivated\n"); + } else { + wfd_ug_warn_popup(ugd, IDS_WFD_POP_AUTOMATIC_TURN_OFF, POP_TYPE_AUTOMATIC_TURN_OFF); + } + + return ECORE_CALLBACK_CANCEL; +} + +/** + * This function let the ug make a callback for registering discover event + * @return void + * @param[in] error_code the returned error code + * @param[in] discovery_state the state of discover + * @param[in] user_data the pointer to the main data structure + */ +void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)user_data; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + WDUG_LOGI("Discovery event [%d], error_code [%d]\n", discovery_state, error_code); + + if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED) { + __WDUG_LOG_FUNC_EXIT__; + return; + } else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) { + ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING; + + /* clear all the previous discovered peers */ + if (ugd->raw_discovered_peer_cnt > 0) { + memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s)); + } + + ugd->raw_discovered_peer_cnt = 0; + } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) { + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_get_discovered_peers(ugd); + } else { + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + + if (TRUE == ugd->is_re_discover) { + ugd->is_re_discover = FALSE; + wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + } else { + /* start LISTEN ONLY mode */ + wifi_direct_start_discovery(TRUE, 0); + } + } + + wfd_ug_view_refresh_glitem(ugd->head); + wfd_ug_view_update_peers(ugd); + wfd_update_multiconnect_device(ugd); + + if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state) { + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE); + } + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE); + } + } else { + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug make a callback for registering connection event + * @return void + * @param[in] error_code the returned error code + * @param[in] connection_state the state of connection + * @param[in] mac_address the mac address of peer + * @param[in] user_data the pointer to the main data structure + */ +void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)user_data; + device_type_s *peer = NULL; + bool owner = FALSE; + int res = 0; + + WDUG_LOGI("Connection event [%d], error_code [%d], multi_connect_mode [%d]\n", + connection_state, error_code, ugd->multi_connect_mode); + + if (mac_address == NULL) { + WDUG_LOGE("Incorrect parameter(peer mac is NULL)\n"); + return; + } + + /* when not in connection, mac_address is empty */ + if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) { + peer = wfd_client_find_peer_by_mac(ugd, mac_address); + + if (NULL == peer || '\0' == peer->ssid[0]) { + WDUG_LOGE("invalid peer from connection !!\n"); + goto refresh_button; + } + } + + if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) { + switch (connection_state) { + case WIFI_DIRECT_CONNECTION_RSP: + WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_RSP\n"); + + if (error_code == WIFI_DIRECT_ERROR_NONE) { + peer->conn_status = PEER_CONN_STATUS_CONNECTED; + wfd_ug_get_connected_peers(ugd); + } else { + peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT; + } + + wfd_ug_view_update_peers(ugd); + + /* connect the next peer */ + ugd->g_source_multi_connect_next = g_timeout_add(1000, wfd_multi_connect_next_cb, ugd); + break; + case WIFI_DIRECT_CONNECTION_IN_PROGRESS: + WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n"); + peer->conn_status = PEER_CONN_STATUS_CONNECTING; + wfd_ug_view_update_peers(ugd); + break; + case WIFI_DIRECT_GROUP_CREATED: + WDUG_LOGI("MULTI: WIFI_DIRECT_GROUP_CREATED\n"); + wfd_multi_connect_next_cb(ugd); + break; + default: + break; + } + } else { + switch (connection_state) { + case WIFI_DIRECT_CONNECTION_RSP: + WDUG_LOGI("WIFI_DIRECT_CONNECTION_RSP\n"); + + if (error_code == WIFI_DIRECT_ERROR_NONE) { + peer->conn_status = PEER_CONN_STATUS_CONNECTED; + wfd_ug_get_connected_peers(ugd); + } else { + peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT; + } + + wfd_ug_view_update_peers(ugd); + break; + case WIFI_DIRECT_DISASSOCIATION_IND: + WDUG_LOGI("WIFI_DIRECT_DISASSOCIATION_IND\n"); + /* change the multi connection mode, it can be connected now */ + if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) { + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS; + } + + /* if other peer disconnected, get connected peers and update */ + peer->conn_status = PEER_CONN_STATUS_WAIT_FOR_CONNECT; + wfd_ug_get_connected_peers(ugd); + wfd_ug_view_update_peers(ugd); + break; + case WIFI_DIRECT_DISCONNECTION_RSP: + case WIFI_DIRECT_DISCONNECTION_IND: + WDUG_LOGI("WIFI_DIRECT_DISCONNECTION_X\n"); + + /* when disconnection, clear all the connected peers */ + if (ugd->raw_connected_peer_cnt > 0) { + memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s)); + } + + ugd->raw_connected_peer_cnt = 0; + + /* start discovery again */ + res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to start discovery. [%d]\n", res); + ugd->is_re_discover = TRUE; + wifi_direct_cancel_discovery(); + } else { + WDUG_LOGI("Discovery is started\n"); + ugd->is_re_discover = FALSE; + } + + break; + case WIFI_DIRECT_CONNECTION_IN_PROGRESS: + WDUG_LOGI("WIFI_DIRECT_CONNECTION_IN_PROGRESS\n"); + peer->conn_status = PEER_CONN_STATUS_CONNECTING; + wfd_ug_view_update_peers(ugd); + break; + case WIFI_DIRECT_CONNECTION_REQ: + case WIFI_DIRECT_CONNECTION_WPS_REQ: + WDUG_LOGI("WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n"); + break; + default: + break; + } + } + + if (peer != NULL) { + wfd_ug_view_refresh_glitem(peer->gl_item); + } + + _change_multi_button_title(ugd); + +refresh_button: + /* refresh the scan button */ + wfd_refresh_wifi_direct_state(ugd); + if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status || + WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) { + res = wifi_direct_is_group_owner(&owner); + if (res == WIFI_DIRECT_ERROR_NONE) { + if (!owner) { + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + } + } else { + WDUG_LOGE("Failed to get whether client is group owner. [%d]\n", res); + } + } else { + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE); + } + } + + /* if no connection, start the monitor timer */ + wifi_direct_get_state(&ugd->wfd_status); + WDUG_LOGI("status: %d", ugd->wfd_status); + + if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) { + if (ugd->monitor_timer) { + ecore_timer_del(ugd->monitor_timer); + ugd->monitor_timer = NULL; + } + } else { + if (NULL == ugd->monitor_timer) { + WDUG_LOGI("start the monitor timer\n"); + ugd->last_wfd_time = time(NULL); + ugd->monitor_timer = ecore_timer_add(5.0, + (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd); + } + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug get wi-fi direct status from vconf + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_get_vconf_status(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + char *dev_name; + int wifi_direct_state = 0; + + /* get wifi direct status from vconf */ + if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) { + WDUG_LOGE("Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE); + return -1; + } + + ugd->wfd_status = wifi_direct_state; + + /* get device name from vconf */ + dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); + if (dev_name == NULL) { + ugd->dev_name = strdup(DEFAULT_DEV_NAME); + WDUG_LOGE("The AP name is NULL(setting default value)\n"); + } else { + ugd->dev_name = strdup(dev_name); + free(dev_name); + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug refresh current status of wi-fi direct + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_refresh_wifi_direct_state(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + wifi_direct_state_e wfd_status; + + res = wifi_direct_get_state(&wfd_status); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to get link status. [%d]\n", res); + return -1; + } + + WDUG_LOGI("WFD status [%d]", wfd_status); + ugd->wfd_status = wfd_status; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug do initialization + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int init_wfd_client(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res = 0; + + res = wifi_direct_initialize(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to initialize wifi direct. [%d]\n", res); + return -1; + } + + res = wifi_direct_initialize(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to initialize Wi-Fi Direct. error code = [%d]\n", res); + return -1; + } + + res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to register _cb_activation. error code = [%d]\n", res); + return -1; + } + + res = wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *)ugd); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to register _cb_discover. error code = [%d]\n", res); + return -1; + } + + res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to register _cb_connection. error code = [%d]\n", res); + return -1; + } + + /* update WFD status */ + wfd_refresh_wifi_direct_state(ugd); + if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) { + ugd->wfd_onoff = 1; + } else { + ugd->wfd_onoff = 0; + } + + WDUG_LOGI("WFD link status. [%d]\n", ugd->wfd_status); + + /* start the monitor timer */ + ugd->last_wfd_time = time(NULL); + ugd->last_wfd_status = WIFI_DIRECT_STATE_DEACTIVATED; + ugd->monitor_timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd); + + ugd->is_re_discover = FALSE; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug do de-initialization + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int deinit_wfd_client(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res = 0; + tethering_error_e ret = TETHERING_ERROR_NONE; + tethering_h th = NULL; + + wfd_refresh_wifi_direct_state(ugd); + + if (ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) { + WDUG_LOGI("Stop discovery before deregister client\n"); + wifi_direct_cancel_discovery(); + } + + res = wifi_direct_deinitialize(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to deregister client. [%d]\n", res); + } + + /* release monitor timer */ + if (ugd->monitor_timer) { + ecore_timer_del(ugd->monitor_timer); + ugd->monitor_timer = NULL; + } + + /* release vconf, hotspot.. */ + res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for wifi state\n"); + } + + res = net_deregister_client(); + if (res != NET_ERR_NONE) { + WDUG_LOGE("Failed to deregister network client. [%d]\n", res); + } + + res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n"); + } + + res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb); + if (res == -1) { + WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n"); + } + + th = ugd->hotspot_handle; + + if (th != NULL) { + /* Deregister cbs */ + ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_unset_enabled_cb is failed(%d)\n", ret); + } + + ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_unset_disabled_cb is failed(%d)\n", ret); + } + + /* Destroy tethering handle */ + ret = tethering_destroy(th); + if (ret != TETHERING_ERROR_NONE) { + WDUG_LOGE("tethering_destroy is failed(%d)\n", ret); + } + + ugd->hotspot_handle = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug turn wi-fi direct on + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_client_switch_on(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + + wfd_refresh_wifi_direct_state(ugd); + WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status); + + if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) { + int wifi_state; + res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + if (res != 0) { + WDUG_LOGE("Failed to get wifi state from vconf. [%d]\n", res); + return -1; + } + + int hotspot_mode; + res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode); + if (res != 0) { + WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res); + return -1; + } + + if (wifi_state > VCONFKEY_WIFI_OFF) { + WDUG_LOGI("WiFi is connected, so have to turn off WiFi"); + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"), POPUP_TYPE_WIFI_OFF); + } else if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) { + WDUG_LOGI("WiFi is connected, so have to turn off WiFi"); + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_HOTSPOT_OFF"), POPUP_TYPE_HOTSPOT_OFF); + } else { + res = wifi_direct_activate(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE); + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + return -1; + } + + /* refresh the header */ + ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING; + wfd_ug_view_refresh_glitem(ugd->head); + + /* while activating, disable the buttons */ + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->multi_scan_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->back_btn) { + elm_object_disabled_set(ugd->back_btn, TRUE); + } + } + } else { + WDUG_LOGI("Wi-Fi Direct is already activated\n"); + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug turn wi-fi direct off + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_client_switch_off(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + + wfd_refresh_wifi_direct_state(ugd); + WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status); + + if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) { + WDUG_LOGI("Wi-Fi Direct is already deactivated\n"); + } else { + /*if connected, disconnect all devices*/ + if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) { + res = wifi_direct_disconnect_all(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res); + return -1; + } + } + + res = wifi_direct_deactivate(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE); + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + return -1; + } + + /* refresh the header */ + ugd->head_text_mode = HEAD_TEXT_TYPE_DEACTIVATING; + wfd_ug_view_refresh_glitem(ugd->head); + + /* while deactivating, disable the buttons */ + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->multi_scan_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->back_btn) { + elm_object_disabled_set(ugd->back_btn, TRUE); + } + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug turn wi-fi direct on/off forcely + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + * @param[in] onoff whether to turn on/off wi-fi direct + */ +int wfd_client_swtch_force(void *data, int onoff) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + + if (onoff) { + res = wifi_direct_activate(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE); + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + return -1; + } + } else { + res = wifi_direct_deactivate(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res); + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE); + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + return -1; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create a group + * @return If success, return 0, else return -1 + */ +int wfd_client_group_add() +{ + __WDUG_LOG_FUNC_ENTER__; + int res; + + res = wifi_direct_create_group(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to add group"); + __WDUG_LOG_FUNC_EXIT__; + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug connect to the device by mac address + * @return If success, return 0, else return -1 + * @param[in] mac_addr the pointer to the mac address of device + */ +int wfd_client_connect(const char *mac_addr) +{ + __WDUG_LOG_FUNC_ENTER__; + int res; + + WDUG_LOGE("connect to peer=[%s]\n", mac_addr); + res = wifi_direct_connect(mac_addr); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to send connection request. [%d]\n", res); + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug disconnect to the device by mac address + * @return If success, return 0, else return -1 + * @param[in] mac_addr the pointer to the mac address of device + */ +int wfd_client_disconnect(const char *mac_addr) +{ + __WDUG_LOG_FUNC_ENTER__; + int res; + + if (mac_addr == NULL) { + res = wifi_direct_disconnect_all(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res); + return -1; + } + } else { + res = wifi_direct_disconnect(mac_addr); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to send disconnection request. [%d]\n", res); + return -1; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug set the intent of a group owner + * @return If success, return 0, else return -1 + * @param[in] go_intent the intent parameter + */ +int wfd_client_set_p2p_group_owner_intent(int go_intent) +{ + __WDUG_LOG_FUNC_ENTER__; + int res; + + res = wifi_direct_set_group_owner_intent(go_intent); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res); + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} diff --git a/ug-wifidirect/src/wfd_ug.c b/ug-wifidirect/src/wfd_ug.c new file mode 100755 index 0000000..18dcb67 --- /dev/null +++ b/ug-wifidirect/src/wfd_ug.c @@ -0,0 +1,524 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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. +* +*/ + + +#ifndef UG_MODULE_API +#define UG_MODULE_API __attribute__ ((visibility("default"))) +#endif + + +#include <sys/time.h> +#include <libintl.h> +#include <sys/utsname.h> + +#include <vconf.h> +#include <Elementary.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +void initialize_gen_item_class(); + +struct ug_data *global_ugd = NULL; + +struct ug_data *wfd_get_ug_data() +{ + return global_ugd; +} + +/** + * This function let the ug create backgroud + * @return backgroud + * @param[in] ugd the pointer to the parent object + * @param[in] ugd the pointer to the main data structure + */ +static Evas_Object *_create_bg(Evas_Object *parent, char *style) +{ + __WDUG_LOG_FUNC_ENTER__; + Evas_Object *bg; + + bg = elm_bg_add(parent); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_style_set(bg, style); + elm_win_resize_object_add(parent, bg); + evas_object_show(bg); + + __WDUG_LOG_FUNC_EXIT__; + return bg; +} + +/** + * This function let the ug create full view + * @return full view + * @param[in] ugd the pointer to the parent object + * @param[in] ugd the pointer to the main data structure + */ +static Evas_Object *_create_fullview(Evas_Object *parent, struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + Evas_Object *base; + + if (parent == NULL) { + WDUG_LOGE( "Incorrenct parameter"); + return NULL; + } + + /* Create Full view */ + base = elm_layout_add(parent); + if (!base) { + WDUG_LOGE( "Failed to add layout"); + return NULL; + } + + elm_layout_theme_set(base, "layout", "application", "default"); + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL); + + __WDUG_LOG_FUNC_EXIT__; + return base; +} + +/** + * This function let the ug create frame view + * @return frame view + * @param[in] ugd the pointer to the parent object + * @param[in] ugd the pointer to the main data structure + */ +static Evas_Object *_create_frameview(Evas_Object *parent, struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + Evas_Object *base; + + if (parent == NULL) { + WDUG_LOGE( "Incorrenct parameter"); + return NULL; + } + + /* Create Frame view */ + base = elm_layout_add(parent); + if (!base) { + WDUG_LOGE( "Failed to add layout"); + return NULL; + } + + elm_layout_theme_set(base, "layout", "application", "default"); + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL); + + __WDUG_LOG_FUNC_EXIT__; + return base; +} + +/** + * This function let the ug destroy the main view + * @return void + * @param[in] data the pointer to the main data structure + */ +void destroy_wfd_ug_view(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (ugd->genlist) { + evas_object_del(ugd->genlist); + ugd->genlist = NULL; + } + + if (ugd->naviframe) { + evas_object_del(ugd->naviframe); + ugd->naviframe = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug initialize wfd when timeout + * @return if stop the timer, return false, else return true + * @param[in] data the pointer to the main data structure + */ +gboolean _wfd_init_cb(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + int res = -1; + struct ug_data *ugd = (struct ug_data *) data; + + if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATED) { + res = init_wfd_client(ugd); + if (res != 0) { + WDUG_LOGE( "Failed to initialize WFD client library\n"); + return true; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return false; +} + +static void *on_create(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd; + int res = 0; + + if (!ug || !priv) { + return NULL; + } + + ugd = priv; + ugd->ug = ug; + + bindtextdomain(PACKAGE, LOCALEDIR); + + ugd->win = ug_get_window(); + if (!ugd->win) { + return NULL; + } + + if (mode == UG_MODE_FULLVIEW) { + ugd->base = _create_fullview(ugd->win, ugd); + } else { + ugd->base = _create_frameview(ugd->win, ugd); + } + + if (ugd->base) { + ugd->bg = _create_bg(ugd->win, "group_list"); + elm_object_part_content_set(ugd->base, "elm.swallow.bg", ugd->bg); + } else { + WDUG_LOGE( "Failed to create base layout\n"); + return NULL; + } + + /* check status of wifi-direct from vconf */ + wfd_get_vconf_status(ugd); + + /* + * if not deactivated, do initialization at once; + * otherwise, do initialization later + */ + if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATED || service) { + res = init_wfd_client(ugd); + if (res != 0) { + WDUG_LOGE( "Failed to initialize WFD client library\n"); + } + + if (service) { + int status = 0; + char *data = NULL; + + /* get the status from appsvc */ + service_get_extra_data(service, "status", &data); + if (data) { + status = atoi(data); + } + + /* + * status - + * 0 : No operation, + * 1 : Activate , + * 2 : Deactivate + */ + if (status == 0x01) { + wfd_client_switch_on(ugd); + } else if (status == 0x02) { + wfd_client_switch_off(ugd); + } + } + } else { + g_timeout_add(100, _wfd_init_cb, ugd); + } + + if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) { + wfd_ug_get_discovered_peers(ugd); + } + + if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) { + wfd_ug_get_connected_peers(ugd); + } + + if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED) { + /* start discovery */ + res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to start discovery. [%d]\n", res); + ugd->is_re_discover = TRUE; + wifi_direct_cancel_discovery(); + } else { + WDUG_LOGI("Discovery is started\n"); + ugd->is_re_discover = FALSE; + } + } + + /* draw UI */ + initialize_gen_item_class(); + create_wfd_ug_view(ugd); + wfd_ug_view_update_peers(ugd); + + evas_object_show(ugd->base); + + __WDUG_LOG_FUNC_EXIT__; + return ugd->base; +} + +static void on_start(ui_gadget_h ug, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd; + int res; + + if (!ug || !priv) { + return; + } + + ugd = priv; + + struct utsname kernel_info; + res = uname(&kernel_info); + if (res != 0) { + WDUG_LOGE( "Failed to detect target type\n"); + } else { + WDUG_LOGI("HW ID of this device [%s]\n", kernel_info.machine); + if (strncmp(kernel_info.machine, "arm", 3) != 0) { + wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_NOT_SUPPORTED_DEVICE"), POPUP_TYPE_TERMINATE); + return; + } + } + + __WDUG_LOG_FUNC_EXIT__; +} + +static void on_pause(ui_gadget_h ug, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + __WDUG_LOG_FUNC_EXIT__; +} + +static void on_resume(ui_gadget_h ug, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + __WDUG_LOG_FUNC_EXIT__; +} + +static void on_destroy(ui_gadget_h ug, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (!ug || !priv) { + WDUG_LOGE( "The param is NULL\n"); + return; + } + + struct ug_data *ugd = priv; + if (ugd == NULL || ugd->base == NULL) { + WDUG_LOGE( "The param is NULL\n"); + return; + } + + deinit_wfd_client(ugd); + WDUG_LOGI("WFD client deregistered"); + + destroy_wfd_ug_view(ugd); + WDUG_LOGI("Destroying About item"); + + wfd_ug_view_free_peers(ugd); + + WDUG_LOGI("WFD client deregistered"); + if (ugd->bg) { + evas_object_del(ugd->bg); + ugd->bg = NULL; + } + WDUG_LOGI("WFD client deregistered"); + + if (ugd->base) { + evas_object_del(ugd->base); + ugd->base = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +static void on_message(ui_gadget_h ug, service_h msg, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + __WDUG_LOG_FUNC_EXIT__; +} + +static void on_event(ui_gadget_h ug, enum ug_event event, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (!ug || !priv) { + WDUG_LOGE( "The param is NULL\n"); + return; + } + + switch (event) { + case UG_EVENT_LOW_MEMORY: + WDUG_LOGI("UG_EVENT_LOW_MEMORY\n"); + break; + case UG_EVENT_LOW_BATTERY: + WDUG_LOGI("UG_EVENT_LOW_BATTERY\n"); + break; + case UG_EVENT_LANG_CHANGE: + WDUG_LOGI("UG_EVENT_LANG_CHANGE\n"); + break; + case UG_EVENT_ROTATE_PORTRAIT: + WDUG_LOGI("UG_EVENT_ROTATE_PORTRAIT\n"); + break; + case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN: + WDUG_LOGI("UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN\n"); + break; + case UG_EVENT_ROTATE_LANDSCAPE: + WDUG_LOGI("UG_EVENT_ROTATE_LANDSCAPE\n"); + break; + case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN: + WDUG_LOGI("UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN\n"); + break; + default: + WDUG_LOGI("default\n"); + break; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +static void on_key_event(ui_gadget_h ug, enum ug_key_event event, service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (!ug || !priv) { + WDUG_LOGE( "The param is NULL\n"); + return; + } + + switch (event) { + case UG_KEY_EVENT_END: + WDUG_LOGI("UG_KEY_EVENT_END\n"); + break; + default: + break; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd; + + if (!ops) { + WDUG_LOGE( "The param is NULL\n"); + return -1; + } + + ugd = calloc(1, sizeof(struct ug_data)); + if (ugd == NULL) { + WDUG_LOGE( "Failed to allocate memory for UG data\n"); + return -1; + } + + global_ugd = ugd; + + ops->create = on_create; + ops->start = on_start; + ops->pause = on_pause; + ops->resume = on_resume; + ops->destroy = on_destroy; + ops->message = on_message; + ops->event = on_event; + ops->key_event = on_key_event; + ops->priv = ugd; + ops->opt = UG_OPT_INDICATOR_ENABLE; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops) +{ + __WDUG_LOG_FUNC_ENTER__; + + struct ug_data *ugd; + + if (!ops) { + WDUG_LOGE( "The param is NULL\n"); + return; + } + + ugd = ops->priv; + + if (ugd) { + free(ugd); + } + + __WDUG_LOG_FUNC_EXIT__; +} + +UG_MODULE_API int setting_plugin_reset(service_h service, void *priv) +{ + __WDUG_LOG_FUNC_ENTER__; + int res = -1; + wifi_direct_state_e state; + + res = wifi_direct_initialize(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to initialize wifi direct. [%d]\n", res); + return -1; + } + + res = wifi_direct_get_state(&state); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to get link status. [%d]\n", res); + return -1; + } + + if (state < WIFI_DIRECT_STATE_ACTIVATING) { + WDUG_LOGI("No need to reset Wi-Fi Direct.\n"); + } else { + /*if connected, disconnect all devices*/ + if (WIFI_DIRECT_STATE_CONNECTED == state) { + res = wifi_direct_disconnect_all(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to send disconnection request to all. [%d]\n", res); + return -1; + } + } + + res = wifi_direct_deactivate(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to reset Wi-Fi Direct. [%d]\n", res); + return -1; + } + } + + res = wifi_direct_deinitialize(); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE( "Failed to deinitialize wifi direct. [%d]\n", res); + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + diff --git a/ug-wifidirect/src/wfd_ug_about_view.c b/ug-wifidirect/src/wfd_ug_about_view.c new file mode 100755 index 0000000..44774b9 --- /dev/null +++ b/ug-wifidirect/src/wfd_ug_about_view.c @@ -0,0 +1,116 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <libintl.h> + +#include <assert.h> +#include <glib.h> + +#include <Elementary.h> +#include <vconf.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +static Elm_Genlist_Item_Class itc; + +/** + * This function let the ug get the label of about + * @return the label of about + * @param[in] parent the pointer to the label's parent + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_wfd_gl_label_help_dialogue_get(void *data, Evas_Object *obj, const char *part) +{ + return strdup(_("IDS_WFD_BODY_ABOUT_WIFI")); +} + +/** + * This function let the ug call it when click 'back' button + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _about_view_back_btn_cb(void *data, Evas_Object * obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (!ugd) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + elm_naviframe_item_pop(ugd->naviframe); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug create about view + * @return void + * @param[in] ugd the pointer to the main data structure + */ +void _wifid_create_about_view(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + + Evas_Object *back_btn = NULL; + Elm_Object_Item *navi_item = NULL; + Evas_Object *genlist = NULL; + Elm_Object_Item *item = NULL; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)"); + return; + } + + genlist = elm_genlist_add(ugd->naviframe); + if (NULL == genlist) { + WDUG_LOGE("Create genlist failed\n"); + return; + } + + elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS); + + /* Set multiline item class */ + itc.item_style = "multiline/1text"; + itc.func.text_get = _wfd_gl_label_help_dialogue_get; + itc.func.content_get = NULL; + itc.func.state_get = NULL; + itc.func.del = NULL; + + item = elm_genlist_item_append(genlist, &itc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + back_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(back_btn, "naviframe/back_btn/default"); + evas_object_smart_callback_add(back_btn, "clicked", _about_view_back_btn_cb, (void *)ugd); + elm_object_focus_allow_set(back_btn, EINA_FALSE); + + navi_item = elm_naviframe_item_push(ugd->naviframe, IDS_WFD_TITLE_ABOUT_WIFI_DIRECT, back_btn, NULL, genlist, NULL); + + __WDUG_LOG_FUNC_EXIT__; +} diff --git a/ug-wifidirect/src/wfd_ug_genlist.c b/ug-wifidirect/src/wfd_ug_genlist.c new file mode 100755 index 0000000..bb2345c --- /dev/null +++ b/ug-wifidirect/src/wfd_ug_genlist.c @@ -0,0 +1,793 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <libintl.h> + +#include <assert.h> +#include <glib.h> + +#include <Elementary.h> +#include <vconf.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +Elm_Gen_Item_Class head_itc; +Elm_Gen_Item_Class name_itc; +Elm_Gen_Item_Class title_itc; +Elm_Gen_Item_Class peer_itc; +Elm_Gen_Item_Class noitem_itc; +Elm_Gen_Item_Class button_itc; + +Elm_Gen_Item_Class title_conn_itc; +Elm_Gen_Item_Class peer_conn_itc; + +Elm_Gen_Item_Class title_busy_itc; +Elm_Gen_Item_Class peer_busy_itc; + +Elm_Gen_Item_Class title_multi_connect_itc; +Elm_Gen_Item_Class peer_multi_connect_itc; + +Elm_Gen_Item_Class title_conn_failed_itc; +Elm_Gen_Item_Class peer_conn_failed_itc; + +/** + * This function let the ug get the label of header + * @return the label of header + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_header_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + WDUG_LOGI("%s", part); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text.1")) { + WDUG_LOGI("Current text mode [%d]\n", ugd->head_text_mode); + switch (ugd->head_text_mode) { + case HEAD_TEXT_TYPE_DIRECT: + case HEAD_TEXT_TYPE_ACTIVATED: + case HEAD_TEXT_TYPE_SCANING: + return strdup(dgettext("sys_string", "IDS_COM_OPT1_WI_FI_DIRECT")); + break; + case HEAD_TEXT_TYPE_DEACTIVATING: + return strdup(_("IDS_WFD_BODY_DEACTIVATING")); + break; + case HEAD_TEXT_TYPE_ACTIVATING: + return strdup(_("IDS_WFD_BODY_ACTIVATING")); + break; + default: + break; + } + } else if (!strcmp(part, "elm.text.1")) { + return strdup(dgettext("sys_string", "IDS_COM_OPT1_WI_FI_DIRECT")); + } else if (!strcmp(part, "elm.text.2")) { + return strdup(ugd->dev_name); + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the icon of header + * @return the icon of header + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_gl_header_icon_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + Evas_Object *onoff = NULL; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (ugd->head_text_mode == HEAD_TEXT_TYPE_ACTIVATING || + ugd->head_text_mode == HEAD_TEXT_TYPE_DEACTIVATING) { + return NULL; + } + + if (!strcmp(part, "elm.icon")) { + onoff = elm_check_add(obj); + elm_object_style_set(onoff, "on&off"); + elm_check_state_set(onoff, ugd->wfd_onoff); + evas_object_show(onoff); + } + + __WDUG_LOG_FUNC_EXIT__; + return onoff; +} + +/** + * This function let the ug get the label of about item + * @return the label of about item + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_name_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + WDUG_LOGI("%s", part); + + if (!strcmp(part, "elm.text")) { + return strdup(IDS_WFD_TITLE_ABOUT_WIFI_DIRECT); + } else if (!strcmp(part, "elm.text.2")) { + return strdup(ugd->dev_name); + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the label of titile + * @return the label of titile + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_title_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text")) { + if (ugd->multiconn_view_genlist != NULL) { + // It's called at Multi connect view... + if (ugd->gl_available_dev_cnt_at_multiconn_view > 0) { + return strdup(_("IDS_WFD_BODY_AVAILABLE_DEVICES")); + } else { + return strdup(_("IDS_WFD_BODY_WIFI_DIRECT_DEVICES")); + } + } else { + // It's called at Main View + if (ugd->gl_available_peer_cnt > 0) { + return strdup(_("IDS_WFD_BODY_AVAILABLE_DEVICES")); + } else { + return strdup(_("IDS_WFD_BODY_WIFI_DIRECT_DEVICES")); + } + } + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the content of titile + * @return the content of titile + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_gl_title_content_get(void *data, Evas_Object *obj, const char *part) +{ + Evas_Object *progressbar = NULL; + struct ug_data *ugd = (struct ug_data *) data; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.icon")) { + if (HEAD_TEXT_TYPE_SCANING == ugd->head_text_mode) { + progressbar = elm_progressbar_add(obj); + elm_object_style_set(progressbar, "list_process_small"); + elm_progressbar_horizontal_set(progressbar, EINA_TRUE); + elm_progressbar_pulse(progressbar, EINA_TRUE); + evas_object_show(progressbar); + } else { + return NULL; + } + } + + return progressbar; +} + +/** + * This function let the ug get the label of peer item + * @return the label of peer item + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_peer_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == part, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + char buf[WFD_GLOBALIZATION_STR_LENGTH] = { 0, }; + WDUG_LOGI("%s", part); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text.1")) { + __WDUG_LOG_FUNC_EXIT__; + return strdup(peer->ssid); + } else if (!strcmp(part, "elm.text.2")) { + switch (peer->conn_status) { + case PEER_CONN_STATUS_DISCONNECTED: + g_strlcpy(buf, _("IDS_WFD_TAP_TO_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + break; + case PEER_CONN_STATUS_CONNECTING: + g_strlcpy(buf, _("IDS_WFD_CONNECTING"), WFD_GLOBALIZATION_STR_LENGTH); + break; + case PEER_CONN_STATUS_CONNECTED: + if (peer->is_group_owner == FALSE) { + g_strlcpy(buf, _("IDS_WFD_CONNECTED"), WFD_GLOBALIZATION_STR_LENGTH); + } else { + g_strlcpy(buf, _("IDS_WFD_TAP_TO_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + } + break; + case PEER_CONN_STATUS_FAILED_TO_CONNECT: + g_strlcpy(buf, _("IDS_WFD_FAILED_TO_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + break; + case PEER_CONN_STATUS_WAIT_FOR_CONNECT: + g_strlcpy(buf, _("IDS_WFD_WAITING_FOR_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + break; + default: + g_strlcpy(buf, _("IDS_WFD_TAP_TO_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + break; + } + } else { + __WDUG_LOG_FUNC_EXIT__; + return NULL; + } + + __WDUG_LOG_FUNC_EXIT__; + return strdup(buf); +} + +/** + * This function let the ug get the icon of peer item + * @return the icon of peer item + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_gl_peer_icon_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == part, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + Evas_Object *icon = NULL; + struct ug_data *ugd = wfd_get_ug_data(); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.icon.2")) { + WDUG_LOGI("elm.icon.2 - connection status [%d]\n", peer->conn_status); + if (peer->conn_status == PEER_CONN_STATUS_CONNECTING) { + icon = elm_progressbar_add(obj); + elm_object_style_set(icon, "list_process"); + elm_progressbar_pulse(icon, EINA_TRUE); + } else if (peer->conn_status == PEER_CONN_STATUS_CONNECTED) { + return NULL; + } + + evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_icon_resizable_set(icon, 1, 1); + evas_object_show(icon); + } else if (!strcmp(part, "elm.icon.1")) { + WDUG_LOGI("elm.icon.1 - category [%d]\n", peer->category); + char *img_path = NULL; + int status = -1; + + status = wfd_get_device_status(ugd, peer); + + /* + * the icon of connected device is + * different from available and busy device + */ + switch (peer->category) { + case WFD_DEVICE_TYPE_COMPUTER: + if (1 == status) { + img_path = WFD_ICON_DEVICE_COMPUTER_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_COMPUTER; + } + break; + case WFD_DEVICE_TYPE_INPUT_DEVICE: + if (1 == status) { + img_path = WFD_ICON_DEVICE_INPUT_DEVICE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_INPUT_DEVICE; + } + break; + case WFD_DEVICE_TYPE_PRINTER: + if (1 == status) { + img_path = WFD_ICON_DEVICE_PRINTER_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_PRINTER; + } + break; + case WFD_DEVICE_TYPE_CAMERA: + if (1 == status) { + img_path = WFD_ICON_DEVICE_CAMERA_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_CAMERA; + } + break; + case WFD_DEVICE_TYPE_STORAGE: + if (1 == status) { + img_path = WFD_ICON_DEVICE_STORAGE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_STORAGE; + } + break; + case WFD_DEVICE_TYPE_NW_INFRA: + if (1 == status) { + img_path = WFD_ICON_DEVICE_NETWORK_INFRA_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_NETWORK_INFRA; + } + break; + case WFD_DEVICE_TYPE_DISPLAYS: + if (1 == status) { + img_path = WFD_ICON_DEVICE_DISPLAY_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_DISPLAY; + } + break; + case WFD_DEVICE_TYPE_MM_DEVICES: + if (1 == status) { + img_path = WFD_ICON_DEVICE_MULTIMEDIA_DEVICE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_MULTIMEDIA_DEVICE; + } + break; + case WFD_DEVICE_TYPE_GAME_DEVICES: + if (1 == status) { + img_path = WFD_ICON_DEVICE_GAMING_DEVICE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_GAMING_DEVICE; + } + break; + case WFD_DEVICE_TYPE_TELEPHONE: + if (1 == status) { + img_path = WFD_ICON_DEVICE_TELEPHONE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_TELEPHONE; + } + break; + case WFD_DEVICE_TYPE_AUDIO: + if (1 == status) { + img_path = WFD_ICON_DEVICE_AUDIO_DEVICE_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_AUDIO_DEVICE; + } + break; + default: + if (1 == status) { + img_path = WFD_ICON_DEVICE_COMPUTER_CONNECT; + } else { + img_path = WFD_ICON_DEVICE_COMPUTER; + } + break; + } + + if (img_path != NULL) { + icon = elm_icon_add(obj); + elm_icon_file_set(icon, img_path, NULL); + evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_icon_resizable_set(icon, 1, 1); + evas_object_show(icon); + } else { + return NULL; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return icon; +} + +/** + * This function let the ug get the text of no device item + * @return the text of no device item + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_noitem_text_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + __WDUG_LOG_FUNC_EXIT__; + return strdup(_("IDS_WFD_NOCONTENT")); +} + +/** + * This function let the ug get the multi connect button + * @return the multi connect button + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_gl_button_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + WDUG_LOGI("%s", part); + ugd->multi_btn = elm_button_add(obj); + wfd_refresh_wifi_direct_state(ugd); + + if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_CANCEL")); + WDUG_LOGI("button: Cancel connect\n"); + } else { + if (ugd->gl_connected_peer_cnt > 1) { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_DISCONNECT_ALL")); + WDUG_LOGI("button: Disconnect All\n"); + } else if (ugd->gl_connected_peer_cnt == 1) { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_DISCONNECT")); + WDUG_LOGI("button: Disconnect\n"); + } else { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_MULTI")); + WDUG_LOGI("button: Multi connect\n"); + } + } + + evas_object_smart_callback_add(ugd->multi_btn, "clicked", _wifid_create_multibutton_cb, ugd); + evas_object_show(ugd->multi_btn); + + __WDUG_LOG_FUNC_EXIT__; + return ugd->multi_btn; +} + +/** + * This function let the ug get the title label of connected device list + * @return the title label of connected device list + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_conn_dev_title_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text")) { + return strdup(_("IDS_WFD_BODY_CONNECTED_DEVICES")); + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the label of connected device + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_peer_conn_dev_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == part, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + char buf[WFD_GLOBALIZATION_STR_LENGTH] = { 0, }; + WDUG_LOGI("%s", part); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text.1")) { + return strdup(peer->ssid); + } else { + g_strlcpy(buf, _("IDS_WFD_CONNECTED"), WFD_GLOBALIZATION_STR_LENGTH); + __WDUG_LOG_FUNC_EXIT__; + return strdup(buf); + } +} + +/** + * This function let the ug get the title label of connected failed device list + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_conn_failed_dev_title_label_get(void *data, Evas_Object *obj, + const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text")) { + return strdup(IDS_WFD_BODY_FAILED_DEVICES); + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the label of connected failed device + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_peer_conn_failed_dev_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == part, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + char buf[WFD_GLOBALIZATION_STR_LENGTH] = { 0, }; + WDUG_LOGI("%s", part); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text.1")) { + return strdup(peer->ssid); + } else { + g_strlcpy(buf, _("IDS_WFD_FAILED_TO_CONNECT"), WFD_GLOBALIZATION_STR_LENGTH); + __WDUG_LOG_FUNC_EXIT__; + return strdup(buf); + } +} + +/** + * This function let the ug get the title label of multi connect list + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_multi_connect_dev_title_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = wfd_get_ug_data(); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text")) { + if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) { + return strdup(_("IDS_WFD_BODY_AVAILABLE_DEVICES")); + } else if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) { + return strdup(IDS_WFD_BODY_FAILED_DEVICES); + } + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the title label of busy device list + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_busy_dev_title_label_get(void *data, Evas_Object *obj, + const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + if (!strcmp(part, "elm.text")) { + return strdup(_("IDS_WFD_BODY_BUSY_DEVICES")); + } + + __WDUG_LOG_FUNC_EXIT__; + return NULL; +} + +/** + * This function let the ug get the label of busy device + * @return the label of connected device + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_gl_peer_busy_dev_label_get(void *data, Evas_Object *obj, const char *part) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == part, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + char buf[WFD_GLOBALIZATION_STR_LENGTH] = { 0, }; + WDUG_LOGI("%s", part); + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return NULL; + } + + WDUG_LOGI("peer->ssid = %s", peer->ssid); + + if (!strcmp(part, "elm.text.1")) { + return strdup(peer->ssid); + } else { + g_strlcpy(buf, _("IDS_WFD_CONNECTED_WITH_OTHER_DEVICE"), WFD_GLOBALIZATION_STR_LENGTH); + __WDUG_LOG_FUNC_EXIT__; + return strdup(buf); + } +} + +/** + * This function let the ug delete the peer item + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + */ +static void _gl_peer_del(void *data, Evas_Object *obj) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == data, "NULL!!"); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug initialize the items of genlist + * @return void + */ +void initialize_gen_item_class() +{ + __WDUG_LOG_FUNC_ENTER__; + head_itc.item_style = "dialogue/2text.1icon.10"; + head_itc.func.text_get = _gl_header_label_get; + head_itc.func.content_get = _gl_header_icon_get; + head_itc.func.state_get = NULL; + + name_itc.item_style = "dialogue/1text"; + name_itc.func.text_get = _gl_name_label_get; + name_itc.func.content_get = NULL; + name_itc.func.state_get = NULL; + name_itc.func.del = NULL; + + title_itc.item_style = "dialogue/title"; + title_itc.func.text_get = _gl_title_label_get; + title_itc.func.content_get = _gl_title_content_get; + title_itc.func.state_get = NULL; + title_itc.func.del = NULL; + + peer_itc.item_style = "dialogue/2text.2icon.3"; + peer_itc.func.text_get = _gl_peer_label_get; + peer_itc.func.content_get = _gl_peer_icon_get; + peer_itc.func.state_get = NULL; + peer_itc.func.del = _gl_peer_del; + + noitem_itc.item_style = "dialogue/1text"; + noitem_itc.func.text_get = _gl_noitem_text_get; + noitem_itc.func.content_get = NULL; + noitem_itc.func.state_get = NULL; + noitem_itc.func.del = NULL; + + button_itc.item_style = "1icon"; + button_itc.func.text_get = NULL; + button_itc.func.content_get = _gl_button_get; + button_itc.func.state_get = NULL; + button_itc.func.del = NULL; + + title_conn_itc.item_style = "dialogue/title"; + title_conn_itc.func.text_get = _gl_conn_dev_title_label_get; + title_conn_itc.func.content_get = NULL; + title_conn_itc.func.state_get = NULL; + title_conn_itc.func.del = NULL; + + peer_conn_itc.item_style = "dialogue/2text.2icon.3"; + peer_conn_itc.func.text_get = _gl_peer_conn_dev_label_get; + peer_conn_itc.func.content_get = _gl_peer_icon_get; + peer_conn_itc.func.state_get = NULL; + peer_conn_itc.func.del = _gl_peer_del; + + title_conn_failed_itc.item_style = "dialogue/title"; + title_conn_failed_itc.func.text_get = _gl_conn_failed_dev_title_label_get; + title_conn_failed_itc.func.content_get = NULL; + title_conn_failed_itc.func.state_get = NULL; + title_conn_failed_itc.func.del = NULL; + + peer_conn_failed_itc.item_style = "dialogue/2text.2icon.3"; + peer_conn_failed_itc.func.text_get = _gl_peer_conn_failed_dev_label_get; + peer_conn_failed_itc.func.content_get = _gl_peer_icon_get; + peer_conn_failed_itc.func.state_get = NULL; + peer_conn_failed_itc.func.del = _gl_peer_del; + + title_busy_itc.item_style = "dialogue/title"; + title_busy_itc.func.text_get = _gl_busy_dev_title_label_get; + title_busy_itc.func.content_get = NULL; + title_busy_itc.func.state_get = NULL; + title_busy_itc.func.del = NULL; + + peer_busy_itc.item_style = "dialogue/2text.2icon.3"; + peer_busy_itc.func.text_get = _gl_peer_busy_dev_label_get; + peer_busy_itc.func.content_get = _gl_peer_icon_get; + peer_busy_itc.func.state_get = NULL; + peer_busy_itc.func.del = _gl_peer_del; + + title_multi_connect_itc.item_style = "dialogue/title"; + title_multi_connect_itc.func.text_get = _gl_multi_connect_dev_title_label_get; + title_multi_connect_itc.func.content_get = NULL; + title_multi_connect_itc.func.state_get = NULL; + title_multi_connect_itc.func.del = NULL; + + __WDUG_LOG_FUNC_EXIT__; + +} diff --git a/ug-wifidirect/src/wfd_ug_main_view.c b/ug-wifidirect/src/wfd_ug_main_view.c new file mode 100755 index 0000000..59c2439 --- /dev/null +++ b/ug-wifidirect/src/wfd_ug_main_view.c @@ -0,0 +1,1190 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <libintl.h> + +#include <assert.h> +#include <glib.h> + +#include <Elementary.h> +#include <vconf.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +/** + * This function let the ug call it when click 'back' button + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _back_btn_cb(void *data, Evas_Object * obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (!ugd) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + wfd_ug_view_free_peers(ugd); + + int ret = -1; + service_h service = NULL; + ret = service_create(&service); + if (ret) { + WDUG_LOGE("Failed to create service"); + return; + } + + wfd_refresh_wifi_direct_state(ugd); + if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) { + service_add_extra_data(service, "Connection", "TRUE"); + } else { + service_add_extra_data(service, "Connection", "FALSE"); + } + + ug_send_result(ugd->ug, service); + service_destroy(service); + ug_destroy_me(ugd->ug); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug call it when click 'scan' button + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + + struct ug_data *ugd = (struct ug_data *) data; + int ret = -1; + char *btn_text = NULL; + + if (NULL == ugd) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + btn_text = (char *)elm_object_text_get(obj); + if (NULL == btn_text) { + WDUG_LOGE("Incorrect button text(NULL)\n"); + return; + } + + if (0 == strcmp(btn_text, _("IDS_WFD_BUTTON_SCAN"))) { + wfd_refresh_wifi_direct_state(ugd); + WDUG_LOGD("Start discovery again, status: %d\n", ugd->wfd_status); + + /* if connected, show the popup*/ + if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) { + wfd_ug_act_popup(ugd, IDS_WFD_POP_SCAN_AGAIN, POP_TYPE_SCAN_AGAIN); + } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) { + wfd_client_switch_on(ugd); + __WDUG_LOG_FUNC_EXIT__; + return; + } else { + ret = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + if (ret != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to start discovery. [%d]\n", ret); + ugd->is_re_discover = TRUE; + wifi_direct_cancel_discovery(); + } else { + WDUG_LOGD("Discovery is started\n"); + ugd->is_re_discover = FALSE; + } + } + } else if (0 == strcmp(btn_text, _("IDS_WFD_BUTTON_STOPSCAN"))) { + WDUG_LOGD("Stop discoverying.\n"); + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + + /* stop scaning */ + ugd->is_re_discover = FALSE; + wifi_direct_cancel_discovery(); + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug call it when click header + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _gl_header_sel(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + if (NULL == data) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + __WDUG_LOG_FUNC_EXIT__; + return; + } + + struct ug_data *ugd = (struct ug_data *) data; + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + + if (item != NULL) { + elm_genlist_item_selected_set(item, EINA_FALSE); + } + + /* turn on/off wfd */ + if (!ugd->wfd_onoff) { + WDUG_LOGD("wifi-direct switch on\n"); + wfd_client_switch_on(ugd); + } else { + WDUG_LOGD("wifi-direct switch off\n"); + wfd_client_switch_off(ugd); + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click avaliable peer to connect + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == obj, "NULL!!"); + assertm_if(NULL == data, "NULL!!"); + device_type_s *peer = (device_type_s *) data; + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + int res; + + if (data == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + if (item != NULL) { + elm_genlist_item_selected_set(item, EINA_FALSE); + } + + if (peer->conn_status == PEER_CONN_STATUS_DISCONNECTED || peer->is_group_owner == TRUE) { + WDUG_LOGD("Connect with peer [%s]\n", peer->mac_addr); + res = wfd_client_connect((const char *) peer->mac_addr); + if (res != 0) { + WDUG_LOGE("Failed to send connection request. [%d]\n", res); + return; + } + } else { + res = wfd_client_disconnect((const char *)peer->mac_addr); + if (res != 0) { + WDUG_LOGE("Failed to send disconnection request. [%d]\n", res); + return; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug call it when click busy peer + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE); + WDUG_LOGD("Busy device is clicked"); + wfd_ug_warn_popup(ugd, IDS_WFD_POP_WARN_BUSY_DEVICE, POP_TYPE_BUSY_DEVICE_POPUP); + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click about item + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _gl_about_wifi_sel(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + WDUG_LOGD("About wifi clicked"); + _wifid_create_about_view(ugd); + elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE); + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'multi connect' button + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _wifid_create_multibutton_cb(void *data, Evas_Object * obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + const char *text_lbl = NULL; + + text_lbl = elm_object_text_get(ugd->multi_btn); + WDUG_LOGD("text_lbl = %s", text_lbl); + + if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) { + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE; + if (0 == strcmp(_("IDS_WFD_BUTTON_CANCEL"), text_lbl)) { + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_CANCEL_CONNECT"), POP_TYPE_DISCONNECT_ALL); + } else { + WDUG_LOGD("Invalid Case\n"); + } + } else { + if (0 == strcmp(_("IDS_WFD_BUTTON_MULTI"), text_lbl)) { + wfd_create_multiconnect_view(ugd); + } else if (0 == strcmp(_("IDS_WFD_BUTTON_CANCEL"), text_lbl)) { + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_CANCEL_CONNECT"), POP_TYPE_DISCONNECT_ALL); + } else if (0 == strcmp(_("IDS_WFD_BUTTON_DISCONNECT_ALL"), text_lbl)) { + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_DISCONNECT"), POP_TYPE_DISCONNECT_ALL); + } else if (0 == strcmp(_("IDS_WFD_BUTTON_DISCONNECT"), text_lbl)) { + wfd_ug_act_popup(ugd, _("IDS_WFD_POP_DISCONNECT"), POP_TYPE_DISCONNECT); + } else { + WDUG_LOGD("Invalid Case\n"); + } + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug change the text of multi button + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int _change_multi_button_title(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (ugd->multi_button_item == NULL) { + return -1; + } + + wfd_refresh_wifi_direct_state(ugd); + if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_CANCEL")); + } else if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) { + if (ugd->gl_connected_peer_cnt > 1) { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_DISCONNECT_ALL")); + } else { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_DISCONNECT")); + } + } else { + elm_object_text_set(ugd->multi_btn, _("IDS_WFD_BUTTON_MULTI")); + } + + evas_object_show(ugd->multi_btn); + __WDUG_LOG_FUNC_EXIT__; + + return 0; +} + +/** + * This function let the ug update the genlist item + * @return void + * @param[in] obj the pointer to genlist item + */ +void wfd_ug_view_refresh_glitem(void *obj) +{ + __WDUG_LOG_FUNC_ENTER__; + elm_genlist_item_update(obj); + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug refresh the attributes of button + * @return void + * @param[in] obj the pointer to the button + * @param[in] text the pointer to the text of button + * @param[in] enable whether the button is disabled + */ +void wfd_ug_view_refresh_button(void *obj, const char *text, int enable) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (NULL == obj || NULL == text) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + WDUG_LOGD("Set the attributes of button: text[%s], enabled[%d]\n", text, enable); + elm_object_text_set(obj, text); + elm_object_disabled_set(obj, !enable); + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug know whether current device is connected by me + * @return If connected, return TRUE, else return FALSE + * @param[in] ugd the pointer to the main data structure + * @param[in] dev the pointer to the device + */ +static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + + for (i = 0; i < ugd->raw_connected_peer_cnt; i++) { + if (strncmp(ugd->raw_connected_peers[i].mac_addr, + dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) { + return TRUE; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return FALSE; +} + +/** + * This function let the ug know whether current device is connected by other peer + * @return If connected, return TRUE, else return FALSE + * @param[in] ugd the pointer to the main data structure + * @param[in] dev the pointer to the device + */ +static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev) +{ + __WDUG_LOG_FUNC_ENTER__; + + if (ugd->I_am_group_owner == TRUE) { + if (dev->is_connected || dev->is_group_owner) { + return TRUE; + } else { + return FALSE; + } + } else { + if (dev->is_connected == TRUE && dev->is_group_owner == TRUE) { + return FALSE; + } + + if (dev->is_connected == TRUE && dev->is_group_owner == FALSE) { + return TRUE; + } + + if (dev->is_connected == FALSE) { + return FALSE; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return FALSE; +} + +/** + * This function let the ug calculate how many devices are avaliable + * @return TRUE + * @param[in] ugd the pointer to the main data structure + * @param[in] dev the pointer to the number of avaliable devices + */ +static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (!__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i]) && + ugd->raw_discovered_peers[i].conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) { + (*no_of_available_dev)++; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return TRUE; +} + +/** + * This function let the ug calculate how many devices are busy + * @return TRUE + * @param[in] ugd the pointer to the main data structure + * @param[in] dev the pointer to the number of busy devices + */ +static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i])) { + (*no_of_busy_dev)++; + } + } + + __WDUG_LOG_FUNC_EXIT__; + return TRUE; +} + +/** + * This function let the ug calculate how many devices are connected failed + * @return TRUE + * @param[in] ugd the pointer to the main data structure + * @param[in] dev the pointer to the number of connected failed devices + */ +static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (!__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i]) && + ugd->raw_discovered_peers[i].conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) { + (*no_of_connect_failed_dev)++; + } + + } + + __WDUG_LOG_FUNC_EXIT__; + return TRUE; +} + +/** + * This function let the ug get the device status + * @return If success, return 0-3(available: 0, connected: 1, busy: 2, connected failed: 3), else return -1 + * @param[in] ugd the pointer to the main data structure + * @param[in] device the pointer to the number of connected failed devices + */ +int wfd_get_device_status(void *data, device_type_s *device) +{ + __WDUG_LOG_FUNC_ENTER__; + int ret = -1; + int status = -1; + struct ug_data *ugd = (struct ug_data *) data; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)"); + return -1; + } + + /* check whether it is connected device */ + ret = __wfd_is_device_connected_with_me(ugd, device); + if (ret) { + WDUG_LOGD("This is connected device"); + status = 1; + goto err_exit; + } + + /* check whether it is busy device */ + ret = __wfd_is_device_busy(ugd, device); + if (ret) { + WDUG_LOGD("This is busy device"); + status = 2; + goto err_exit; + } + + /* check whether it is available device */ + if (device->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) { + WDUG_LOGD("This is available device"); + status = 0; + } else { + WDUG_LOGD("This is connected failed device"); + status = 3; + } + +err_exit: + __WDUG_LOG_FUNC_EXIT__; + return status; +} + +/** + * This function let the ug delete the separator + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + */ +static void __wfd_separator_del(void *data, Evas_Object *obj) +{ + __WDUG_LOG_FUNC_ENTER__; + elm_genlist_item_class_free(data); + return; +} + +/** + * This function let the ug add a dialogue separator + * @return the separator item + * @param[in] genlist the pointer to the genlist + * @param[in] separator_style the style of separator + */ +Elm_Object_Item *wfd_add_dialogue_separator(Evas_Object *genlist, const char *separator_style) +{ + __WDUG_LOG_FUNC_ENTER__; + assertm_if(NULL == genlist, "NULL!!"); + + static Elm_Genlist_Item_Class *separator_itc; + separator_itc = elm_genlist_item_class_new(); + separator_itc->item_style = separator_style; + separator_itc->func.text_get = NULL; + separator_itc->func.content_get = NULL; + separator_itc->func.state_get = NULL; + separator_itc->func.del = __wfd_separator_del; + + Elm_Object_Item *sep = elm_genlist_item_append( + genlist, + separator_itc, + separator_itc, + NULL, + ELM_GENLIST_ITEM_GROUP, + NULL, + NULL); + + assertm_if(NULL == sep, "NULL!!"); + + elm_genlist_item_select_mode_set(sep, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + __WDUG_LOG_FUNC_EXIT__; + return sep; +} + +/** + * This function let the ug create the main genlist + * @return the main genlist + * @param[in] data the pointer to the main data structure + */ +static Evas_Object *_create_basic_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + Evas_Object *genlist; + + genlist = elm_genlist_add(ugd->naviframe); + wfd_add_dialogue_separator(genlist, "dialogue/separator"); + ugd->head = elm_genlist_item_append(genlist, &head_itc, ugd, NULL, + ELM_GENLIST_ITEM_NONE, _gl_header_sel, (void *)ugd); + + __WDUG_LOG_FUNC_EXIT__; + return genlist; +} + +/** + * This function let the ug create the about item to append the genlist + * @return the main item + * @param[in] data the pointer to the main data structure + */ +static Evas_Object *_create_about_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->about_wfd_sep_high_item = wfd_add_dialogue_separator(ugd->genlist, "dialogue/separator"); + ugd->about_wfd_item = elm_genlist_item_append(ugd->genlist, &name_itc, ugd, NULL, + ELM_GENLIST_ITEM_NONE, _gl_about_wifi_sel, (void *)ugd); + ugd->about_wfd_sep_low_item = wfd_add_dialogue_separator(ugd->genlist, "dialogue/separator/end"); + + __WDUG_LOG_FUNC_EXIT__; + return ugd->genlist; +} + +/** + * This function let the ug create no device item to append the genlist + * @return the main item + * @param[in] data the pointer to the main data structure + */ +static Evas_Object *_create_no_device_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->nodevice_title_item = elm_genlist_item_append(ugd->genlist, &title_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + ugd->nodevice_item = elm_genlist_item_append(ugd->genlist, &noitem_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + __WDUG_LOG_FUNC_EXIT__; + return ugd->genlist; +} + +/** + * This function let the ug create multi connect button + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int _create_multi_button_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + wfd_refresh_wifi_direct_state(ugd); + + /* show the button */ + if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) { + if (ugd->raw_multi_selected_peer_cnt > 1 || + ugd->gl_connected_peer_cnt > 0 || + ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) { + ugd->multi_button_sep_item = wfd_add_dialogue_separator(ugd->genlist, "dialogue/separator"); + ugd->multi_button_item = elm_genlist_item_append(ugd->genlist, &button_itc, ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + } + } else { + if (ugd->gl_available_peer_cnt > 1 || + ugd->gl_connected_peer_cnt > 0 || + ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) { + ugd->multi_button_sep_item = wfd_add_dialogue_separator(ugd->genlist, "dialogue/separator"); + ugd->multi_button_item = elm_genlist_item_append(ugd->genlist, &button_itc, ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + } + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create busy device list + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int _create_busy_dev_list(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create avaliable device list + * @return 0 + * @param[in] data the pointer to the main data structure + */ +static int _create_available_dev_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->avlbl_wfd_item = elm_genlist_item_append(ugd->genlist, &title_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create multi connect device list + * @return 0 + * @param[in] data the pointer to the main data structure + */ +static int _create_multi_connect_dev_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->multi_connect_wfd_item = elm_genlist_item_append(ugd->genlist, &title_multi_connect_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create connected device list + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int _create_connected_dev_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->conn_wfd_item = elm_genlist_item_append(ugd->genlist, &title_conn_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create connected falied device list + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int _create_connected_failed_dev_genlist(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->conn_failed_wfd_item = elm_genlist_item_append(ugd->genlist, &title_conn_failed_itc, (void *)ugd, NULL, + ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug make the display callback for connect failed peers + * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW + * @param[in] data the pointer to the user data + */ +static Eina_Bool _connect_failed_peers_display_cb(void *user_data) +{ + int interval = 0; + int res = -1; + struct ug_data *ugd = (struct ug_data *) user_data; + + if (NULL == ugd) { + WDUG_LOGE("NULL parameters.\n"); + return ECORE_CALLBACK_CANCEL; + } + + /* check the timeout, if not timeout, keep the cb */ + interval = time(NULL) - ugd->last_display_time; + if (interval < MAX_DISPLAY_TIME_OUT) { + return ECORE_CALLBACK_RENEW; + } + + /* start discovery again */ + res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGE("Failed to start discovery. [%d]\n", res); + ugd->is_re_discover = TRUE; + wifi_direct_cancel_discovery(); + } else { + WDUG_LOGD("Discovery is started\n"); + ugd->is_re_discover = FALSE; + } + + return ECORE_CALLBACK_CANCEL; +} + +/** + * This function let the ug free the peers + * @return void + * @param[in] data the pointer to the main data structure + */ +void wfd_ug_view_free_peers(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + int i = 0; + + for (i = 0; i < ugd->gl_connected_peer_cnt; i++) { + WDUG_LOGD("%dth connected peer = %x is deleted\n", i, ugd->gl_connected_peers[i]); + if (ugd->gl_connected_peers[i].gl_item != NULL) { + elm_object_item_del(ugd->gl_connected_peers[i].gl_item); + ugd->gl_connected_peers[i].gl_item = NULL; + WDUG_LOGD("Deleted item\n"); + } + } + + ugd->gl_connected_peer_cnt = 0; + + for (i = 0; i < ugd->gl_connected_failed_peer_cnt; i++) { + WDUG_LOGD("%dth connected failed peer = %x is deleted\n", i, ugd->gl_connected_failed_peers[i]); + if (ugd->gl_connected_failed_peers[i].gl_item != NULL) { + elm_object_item_del(ugd->gl_connected_failed_peers[i].gl_item); + ugd->gl_connected_failed_peers[i].gl_item = NULL; + WDUG_LOGD("Deleted item\n"); + } + } + + ugd->gl_connected_failed_peer_cnt = 0; + + for (i = 0; i < ugd->gl_available_peer_cnt; i++) { + WDUG_LOGD("%dth discovered peer = %x is deleted\n", i, ugd->gl_available_peers[i]); + if (ugd->gl_available_peers[i].gl_item != NULL) { + elm_object_item_del(ugd->gl_available_peers[i].gl_item); + ugd->gl_available_peers[i].gl_item = NULL; + WDUG_LOGD("Deleted item\n"); + } + } + + ugd->gl_available_peer_cnt = 0; + + for (i = 0; i < ugd->gl_busy_peer_cnt; i++) { + WDUG_LOGD("%dth busy peer = %x is deleted\n", i, ugd->gl_busy_peers[i]); + if (ugd->gl_busy_peers[i].gl_item != NULL) { + elm_object_item_del(ugd->gl_busy_peers[i].gl_item); + ugd->gl_busy_peers[i].gl_item = NULL; + WDUG_LOGD("Deleted item\n"); + } + } + + ugd->gl_busy_peer_cnt = 0; + + for (i = 0; i < ugd->gl_multi_connect_peer_cnt; i++) { + WDUG_LOGD("%dth multi connect peer = %x is deleted\n", i, ugd->gl_multi_connect_peers[i]); + if (ugd->gl_multi_connect_peers[i].gl_item != NULL) { + elm_object_item_del(ugd->gl_multi_connect_peers[i].gl_item); + ugd->gl_multi_connect_peers[i].gl_item = NULL; + WDUG_LOGD("Deleted item\n"); + } + } + + ugd->gl_multi_connect_peer_cnt = 0; + + if (ugd->nodevice_title_item != NULL) { + elm_object_item_del(ugd->nodevice_title_item); + ugd->nodevice_title_item = NULL; + } + + if (ugd->nodevice_item != NULL) { + elm_object_item_del(ugd->nodevice_item); + ugd->nodevice_item = NULL; + } + + if (ugd->about_wfd_item != NULL) { + elm_object_item_del(ugd->about_wfd_item); + ugd->about_wfd_item = NULL; + } + + if (ugd->about_wfd_sep_high_item != NULL) { + elm_object_item_del(ugd->about_wfd_sep_high_item); + ugd->about_wfd_sep_high_item = NULL; + } + + if (ugd->about_wfd_sep_low_item != NULL) { + elm_object_item_del(ugd->about_wfd_sep_low_item); + ugd->about_wfd_sep_low_item = NULL; + } + + if (ugd->conn_wfd_item != NULL) { + elm_object_item_del(ugd->conn_wfd_item); + ugd->conn_wfd_item = NULL; + } + + if (ugd->conn_failed_wfd_item != NULL) { + elm_object_item_del(ugd->conn_failed_wfd_item); + ugd->conn_failed_wfd_item = NULL; + } + + if (ugd->display_timer != NULL) { + ecore_timer_del(ugd->display_timer); + ugd->display_timer = NULL; + } + + if (ugd->multi_connect_wfd_item != NULL) { + elm_object_item_del(ugd->multi_connect_wfd_item); + ugd->multi_connect_wfd_item = NULL; + } + + if (ugd->avlbl_wfd_item != NULL) { + elm_object_item_del(ugd->avlbl_wfd_item); + ugd->avlbl_wfd_item = NULL; + } + + if (ugd->busy_wfd_item != NULL) { + elm_object_item_del(ugd->busy_wfd_item); + ugd->busy_wfd_item = NULL; + } + + if (ugd->multi_button_item != NULL) { + elm_object_item_del(ugd->multi_button_item); + ugd->multi_button_item = NULL; + } + + if (ugd->multi_button_sep_item != NULL) { + elm_object_item_del(ugd->multi_button_sep_item); + ugd->multi_button_sep_item = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug update the peers + * @return void + * @param[in] data the pointer to the main data structure + */ +void wfd_ug_view_update_peers(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + int no_of_busy_dev = 0; + int no_of_available_dev = 0; + int no_of_conn_dev = 0; + int no_of_conn_failed_dev = 0; + int i = 0 ; + int res = 0; + bool is_group_owner = FALSE; + int count = 0; + + wfd_ug_view_free_peers(ugd); + + if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATED) { + WDUG_LOGD("Device is deactivated, no need to update UI."); + _create_about_genlist(ugd); + return; + } + + res = wifi_direct_is_group_owner(&is_group_owner); + if (res != WIFI_DIRECT_ERROR_NONE) { + WDUG_LOGD("Fail to get group_owner_state. ret=[%d]", res); + ugd->I_am_group_owner = FALSE; + } else { + ugd->I_am_group_owner = is_group_owner; + } + + __wfd_is_any_device_busy(ugd, &no_of_busy_dev); + __wfd_is_any_device_available(ugd, &no_of_available_dev); + __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev); + no_of_conn_dev = ugd->raw_connected_peer_cnt; + + ugd->gl_available_peer_cnt = no_of_available_dev; + ugd->gl_connected_peer_cnt = no_of_conn_dev; + ugd->gl_connected_failed_peer_cnt = no_of_conn_failed_dev; + ugd->gl_busy_peer_cnt = no_of_busy_dev; + + WDUG_LOGD("conn_dev=[%d], conn_failed_dev=[%d], avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", + no_of_conn_dev, no_of_conn_failed_dev, no_of_available_dev, no_of_busy_dev, is_group_owner); + + if (no_of_conn_dev == 0 && no_of_conn_failed_dev == 0 && + no_of_available_dev == 0 && no_of_busy_dev == 0) { + WDUG_LOGE("There are No peers\n"); + _create_no_device_genlist(ugd); + _create_about_genlist(ugd); + return; + } + + /* display connect peers */ + if (no_of_conn_dev > 0) { + if (!ugd->conn_wfd_item) { + _create_connected_dev_genlist(ugd); + } + + count = 0; + for (i = 0; i < ugd->raw_connected_peer_cnt; i++) { + if (ugd->gl_connected_peers[count].gl_item) { + elm_object_item_del(ugd->gl_connected_peers[count].gl_item); + } + + memcpy(&ugd->gl_connected_peers[count], &ugd->raw_connected_peers[i], sizeof(device_type_s)); + ugd->gl_connected_peers[count].gl_item = elm_genlist_item_append(ugd->genlist, &peer_conn_itc, + (void *)&(ugd->gl_connected_peers[i]), NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->gl_connected_peers[count].gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + count++; + } + } + + if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) { + if (ugd->raw_multi_selected_peer_cnt > 0) { + if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt && + ugd->multi_connect_wfd_item == NULL) { + _create_multi_connect_dev_genlist(ugd); + } + + count = 0; + for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) { + if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) { + if (ugd->gl_multi_connect_peers[count].gl_item) { + elm_object_item_del(ugd->gl_multi_connect_peers[count].gl_item); + } + + memcpy(&ugd->gl_multi_connect_peers[count], &ugd->raw_multi_selected_peers[i], sizeof(device_type_s)); + ugd->gl_multi_connect_peers[count].gl_item = elm_genlist_item_append(ugd->genlist, &peer_itc, + (void *) &(ugd->gl_multi_connect_peers[count]), NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + count++; + } + } + + ugd->gl_multi_connect_peer_cnt = count; + } + + _create_multi_button_genlist(ugd); + } else { + /* + * Note that + * If GC, no display available peers + * Otherwise, display available peers + */ + if (no_of_available_dev > 0 && (no_of_conn_dev == 0 || is_group_owner == TRUE)) { + if (ugd->avlbl_wfd_item == NULL) { + _create_available_dev_genlist(ugd); + } + + count = 0; + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (!__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i]) && + ugd->raw_discovered_peers[i].conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) { + if (ugd->gl_available_peers[count].gl_item) { + elm_object_item_del(ugd->gl_available_peers[count].gl_item); + } + + memcpy(&ugd->gl_available_peers[count], &ugd->raw_discovered_peers[i], sizeof(device_type_s)); + ugd->gl_available_peers[count].gl_item = elm_genlist_item_append(ugd->genlist, &peer_itc, + (void *)&(ugd->gl_available_peers[count]), NULL, ELM_GENLIST_ITEM_NONE, _gl_peer_sel, + (void *)&(ugd->gl_available_peers[count])); + count++; + } + } + } + + /* display connect failed peers */ + if (no_of_conn_failed_dev > 0) { + if (!ugd->conn_failed_wfd_item) { + _create_connected_failed_dev_genlist(ugd); + } + + /* add timer for disappearing failed peers after N secs */ + if (NULL == ugd->display_timer) { + ugd->last_display_time = time(NULL); + ugd->display_timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd); + } + + count = 0; + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (!__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i]) && + ugd->raw_discovered_peers[i].conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) { + if (ugd->gl_connected_failed_peers[count].gl_item) { + elm_object_item_del(ugd->gl_connected_failed_peers[count].gl_item); + } + + memcpy(&ugd->gl_connected_failed_peers[count], &ugd->raw_discovered_peers[i], sizeof(device_type_s)); + ugd->gl_connected_failed_peers[count].gl_item = elm_genlist_item_append(ugd->genlist, &peer_conn_failed_itc, + (void *)&(ugd->gl_connected_failed_peers[count]), NULL, ELM_GENLIST_ITEM_NONE, NULL, ugd); + elm_genlist_item_select_mode_set(ugd->gl_connected_failed_peers[count].gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + count++; + } + } + } + + _create_multi_button_genlist(ugd); + + /* If connected, not display busy device */ + if (no_of_conn_dev == 0 && no_of_busy_dev > 0) { + if (ugd->busy_wfd_item == NULL) { + _create_busy_dev_list(ugd); + } + + count = 0; + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + /* Not include the device which is connected with me */ + if (__wfd_is_device_connected_with_me(ugd, &ugd->raw_discovered_peers[i])) { + continue; + } + if (__wfd_is_device_busy(ugd, &ugd->raw_discovered_peers[i]) == TRUE) { + if (ugd->gl_busy_peers[count].gl_item) { + elm_object_item_del(ugd->gl_busy_peers[count].gl_item); + } + + memcpy(&ugd->gl_busy_peers[count], &ugd->raw_discovered_peers[i], sizeof(device_type_s)); + ugd->gl_busy_peers[count].gl_item = elm_genlist_item_append(ugd->genlist, &peer_busy_itc, + (void *)&(ugd->gl_busy_peers[count]), NULL, ELM_GENLIST_ITEM_NONE, _gl_busy_peer_sel, ugd); + count++; + } + } + } + } + _create_about_genlist(ugd); + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug create the main view + * @return void + * @param[in] data the pointer to the main data structure + */ +void create_wfd_ug_view(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + Elm_Object_Item *navi_item = NULL; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)"); + return; + } + + ugd->naviframe = elm_naviframe_add(ugd->base); + elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe); + evas_object_show(ugd->naviframe); + + ugd->back_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default"); + evas_object_smart_callback_add(ugd->back_btn, "clicked", _back_btn_cb, (void *)ugd); + elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE); + + ugd->genlist = _create_basic_genlist(ugd); + if (ugd->genlist == NULL) { + WDUG_LOGE("Failed to create basic genlist"); + return; + } + + evas_object_show(ugd->genlist); + wfd_refresh_wifi_direct_state(ugd); + if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) { + ugd->wfd_onoff = TRUE; + } + + navi_item = elm_naviframe_item_push(ugd->naviframe, _("IDS_WFD_HEADER_WIFI_DIRECT"), ugd->back_btn, NULL, ugd->genlist, NULL); + /* create scan button */ + ugd->scan_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(ugd->scan_btn, "naviframe/toolbar/default"); + elm_object_text_set(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN")); + evas_object_smart_callback_add(ugd->scan_btn, "clicked", _scan_btn_cb, (void *)ugd); + elm_object_item_part_content_set(navi_item, "toolbar_button1", ugd->scan_btn); + + __WDUG_LOG_FUNC_EXIT__; +} diff --git a/ug-wifidirect/src/wfd_ug_multiconnect_view.c b/ug-wifidirect/src/wfd_ug_multiconnect_view.c new file mode 100755 index 0000000..4b21c9a --- /dev/null +++ b/ug-wifidirect/src/wfd_ug_multiconnect_view.c @@ -0,0 +1,807 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <libintl.h> + +#include <assert.h> +#include <glib.h> + +#include <Elementary.h> +#include <vconf.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +Elm_Gen_Item_Class select_all_itc; +Elm_Gen_Item_Class device_itc; + +/** + * This function let the ug call it when click 'back' button in multi connect view + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _multiconnect_view_back_btn_cb(void *data, Evas_Object * obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + + if (!ugd) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + ugd->multiconn_view_genlist = NULL; + elm_naviframe_item_pop(ugd->naviframe); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug reset the connected failed peers + * @return false + * @param[in] event_info the pointer to the event information + */ +gboolean __wfd_multi_connect_reset_cb(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + struct ug_data *ugd = (struct ug_data *)data; + + /* remove the failed peers*/ + for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) { + if (ugd->raw_multi_selected_peers[i].conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) { + memset(&ugd->raw_multi_selected_peers[i], 0x00, sizeof(device_type_s)); + ugd->raw_multi_selected_peer_cnt--; + } + } + + wfd_ug_view_update_peers(ugd); + + __WDUG_LOG_FUNC_EXIT__; + return false; +} + +/** + * This function let the ug free the selected peers in multi connect view + * @return void + * @param[in] data the pointer to the main data structure + */ +void wfd_free_multi_selected_peers(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + struct ug_data *ugd = (struct ug_data *)data; + + /* destroy the created group */ + wifi_direct_destroy_group(); + + /* release the selected peers */ + for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) { + memset(&ugd->raw_multi_selected_peers[i], 0x00, sizeof(device_type_s)); + } + + ugd->raw_multi_selected_peer_cnt = 0; + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE; + + __WDUG_LOG_FUNC_EXIT__; + +} + +/** + * This function let the ug stop to connect to selected peer + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_stop_multi_connect(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + + /* change the title of failed peers */ + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_COMPLETED; + wfd_ug_view_refresh_glitem(ugd->multi_connect_wfd_item); + + wfd_client_set_p2p_group_owner_intent(7); + + /* after 30s, remove the failed peers */ + g_timeout_add(30000 /*ms*/, __wfd_multi_connect_reset_cb, ugd); + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug start to connect the selected peers + * @return If success, return 0, else return -1 + * @param[in] data the pointer to the main data structure + */ +int wfd_start_multi_connect(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int res; + + if (ugd->raw_multi_selected_peer_cnt > 0) { + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS; + + res = wfd_client_group_add(); + if (res == -1) { + WDUG_LOGE("Failed to add group"); + wfd_free_multi_selected_peers(ugd); + + __WDUG_LOG_FUNC_EXIT__; + return -1; + } + + } else { + WDUG_LOGD("No selected peers.\n"); + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug connect to the next selected peer automatically + * @return If stop the timer, return false, else return true + * @param[in] data the pointer to the main data structure + */ +gboolean wfd_multi_connect_next_cb(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int i; + int res; + + // Reset g_source handler.. + ugd->g_source_multi_connect_next = 0; + + if (ugd->raw_multi_selected_peer_cnt > 0) { + ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS; + for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) { + if (ugd->raw_multi_selected_peers[i].conn_status == PEER_CONN_STATUS_WAIT_FOR_CONNECT) { + res = wfd_client_connect(ugd->raw_multi_selected_peers[i].mac_addr); + if (res == -1) { + WDUG_LOGD("Failed to connect [%s].\n", ugd->raw_multi_selected_peers[i].ssid); + ugd->raw_multi_selected_peers[i].conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT; + } else { + ugd->raw_multi_selected_peers[i].conn_status = PEER_CONN_STATUS_CONNECTING; + break; + } + } + } + + if (i >= ugd->raw_multi_selected_peer_cnt) { + // All selected peers are touched. + WDUG_LOGD("Stop Multi Connect...\n"); + wfd_stop_multi_connect(ugd); + } + } else { + WDUG_LOGD("No selected peers.\n"); + return -1; + } + + __WDUG_LOG_FUNC_EXIT__; + return false; +} + +/** + * This function let the ug call it when click 'connect' button in multi connect view + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +void _connect_btn_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + int i = 0; + int count = 0; + char popup_text[MAX_POPUP_TEXT_SIZE] = {0}; + WDUG_LOGD("_connect_btn_cb \n"); + + for (i = 0; i < ugd->gl_available_peer_cnt ; i++) { + if (TRUE == ugd->multi_conn_dev_list[i].dev_sel_state) { + WDUG_LOGD("ugd->peers[i].mac_addr = %s, i = %d\n", ugd->multi_conn_dev_list[i].peer.mac_addr, i); + + memcpy(&ugd->raw_multi_selected_peers[count], &ugd->multi_conn_dev_list[i].peer, sizeof(device_type_s)); + ugd->raw_multi_selected_peers[count].conn_status = PEER_CONN_STATUS_WAIT_FOR_CONNECT; + count++; + } + } + + ugd->raw_multi_selected_peer_cnt = count; + + /* if more than 7 device selected, show the popup */ + if (count > MAX_POPUP_PEER_NUM) { + snprintf(popup_text, MAX_POPUP_TEXT_SIZE, _("IDS_WFD_POP_MULTI_CONNECT"), count); + wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP); + } + + /* start multi connection */ + wfd_start_multi_connect(ugd); + + elm_naviframe_item_pop(ugd->naviframe); + + //ToDo: Do we need to free multiconn_view_genlist? + ugd->multiconn_view_genlist = NULL; + _change_multi_button_title(ugd); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug delete 'select(n)' notify + * @return void + * @param[in] data the pointer to the main data structure + */ +static void _wfd_multi_del_select_info_label(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *)data; + + if (NULL == ugd) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + if (ugd->notify) { + evas_object_del(ugd->notify); + ugd->notify = NULL; + } + + if (ugd->notify_layout) { + evas_object_del(ugd->notify_layout); + ugd->notify_layout = NULL; + } + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug add 'select(n)' notify + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] count the number of selected peers + */ +static void _wfd_multi_add_select_info_label(void *data, int count) +{ + __WDUG_LOG_FUNC_ENTER__; + + char select_lablel[MAX_POPUP_TEXT_SIZE] = {0}; + struct ug_data *ugd = (struct ug_data *)data; + + if (NULL == ugd || count <= 0) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + /* delete previous notify */ + _wfd_multi_del_select_info_label(ugd); + + /* add notify */ + ugd->notify = elm_notify_add(ugd->base); + if (NULL == ugd->notify) { + WDUG_LOGE("Add notify failed\n"); + return; + } + + /* set the align to center of bottom */ + elm_notify_align_set(ugd->notify, ELM_NOTIFY_ALIGN_FILL, 1.0); + + ugd->notify_layout = elm_layout_add(ugd->notify); + if (NULL == ugd->notify_layout) { + evas_object_del(ugd->notify); + ugd->notify = NULL; + return; + } + + elm_layout_theme_set(ugd->notify_layout, "standard", "selectioninfo", "vertical/bottom_64"); + elm_object_content_set(ugd->notify, ugd->notify_layout); + + snprintf(select_lablel, MAX_POPUP_TEXT_SIZE, _("IDS_WFD_POP_SELECTED_DEVICE_NUM"), count); + elm_object_part_text_set(ugd->notify_layout, "elm.text", select_lablel); + elm_notify_timeout_set(ugd->notify, 3); + evas_object_show(ugd->notify); + + __WDUG_LOG_FUNC_EXIT__; + return; +} + +/** + * This function let the ug call it when click the peer in multi connect view + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_gl_multi_sel_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + + int i = 0; + int index = 0; + int sel_count = 0; + bool is_sel = FALSE; + bool is_selct_all = TRUE; + Eina_Bool state = 0; + Evas_Object *chk_box = NULL; + char msg[MAX_POPUP_TEXT_SIZE] = {0}; + struct ug_data *ugd = (struct ug_data *)data; + Elm_Object_Item *item = (Elm_Object_Item *)event_info; + + if (NULL == ugd || NULL == item) { + WDUG_LOGE("The param is NULL\n"); + return; + } + + elm_genlist_item_selected_set(item, EINA_FALSE); + index = elm_genlist_item_index_get(item) - 3; /* subtract the previous items */ + WDUG_LOGD("selected index = %d \n", index); + if (index < 0) { + WDUG_LOGE("The index is invalid.\n"); + return; + } + + chk_box = elm_object_item_part_content_get((Elm_Object_Item *)event_info, "elm.icon.1"); + state = elm_check_state_get(chk_box); + WDUG_LOGD("state = %d \n", state); + elm_check_state_set(chk_box, !state); + + ugd->multi_conn_dev_list[index].dev_sel_state = !state; + WDUG_LOGD("ptr->dev_sel_state = %d \n", ugd->multi_conn_dev_list[index].dev_sel_state); + WDUG_LOGD("ptr->peer.mac_addr = %s \n", ugd->multi_conn_dev_list[index].peer.mac_addr); + + /* update the checkbox and button */ + for (; i < ugd->gl_available_dev_cnt_at_multiconn_view; i++) { + if (ugd->multi_conn_dev_list[i].dev_sel_state) { + is_sel = TRUE; + sel_count++; + } else { + is_selct_all = FALSE; + } + } + + chk_box = elm_object_item_part_content_get(ugd->mcview_select_all_item, "elm.icon"); + elm_check_state_set(chk_box, is_selct_all); + + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_connect_btn, _("IDS_WFD_BUTTON_CONNECT"), is_sel); + } + + if (sel_count > 0) { + snprintf(msg, MAX_POPUP_TEXT_SIZE, _("IDS_WFD_POP_SELECTED_DEVICE_NUM"), sel_count); + _wfd_multi_add_select_info_label(ugd, sel_count); + } else { + _wfd_multi_del_select_info_label(ugd); + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click the 'select all' item in multi connect view + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_gl_sel_cb(void *data, Evas_Object *obj, void *event_info) +{ + int sel_count = 0; + char msg[MAX_POPUP_TEXT_SIZE] = {0}; + struct ug_data *ugd = (struct ug_data *)data; + + elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE); + + if (NULL == ugd || NULL == obj) { + WDUG_LOGE("NULL parameters.\n"); + return; + } + + Evas_Object *sel_chkbox = elm_object_item_part_content_get(ugd->mcview_select_all_item, "elm.icon"); + if (sel_chkbox == NULL) { + WDUG_LOGD("select-all chkbox is NULL\n"); + return; + } + + Eina_Bool state = elm_check_state_get(sel_chkbox); + if (state == TRUE) { + state = FALSE; + } else { + state = TRUE; + } + + elm_check_state_set(sel_chkbox, state); + WDUG_LOGD("state = %d \n", state); + + int i = 0; + bool is_sel = FALSE; + Elm_Object_Item *item = NULL; + Evas_Object *chk_box = NULL; + + /* set the state of all the available devices */ + for (i = 0; i < ugd->gl_available_dev_cnt_at_multiconn_view; i++) { + is_sel = state; + ugd->multi_conn_dev_list[i].dev_sel_state = state; + item = ugd->multi_conn_dev_list[i].peer.gl_item; + chk_box = elm_object_item_part_content_get(item, "elm.icon.1"); + elm_check_state_set(chk_box, state); + + if (state) { + sel_count++; + } + } + + /* update the connect button */ + if (ugd->multi_connect_btn) { + wfd_ug_view_refresh_button(ugd->multi_connect_btn, _("IDS_WFD_BUTTON_CONNECT"), is_sel); + } + + /* tickernoti popup */ + if (sel_count > 0) { + snprintf(msg, MAX_POPUP_TEXT_SIZE, _("IDS_WFD_POP_SELECTED_DEVICE_NUM"), sel_count); + _wfd_multi_add_select_info_label(ugd, sel_count); + } else { + _wfd_multi_del_select_info_label(ugd); + } +} + +/** + * This function let the ug get the label of peer + * @return the label of peer + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_wfd_gl_device_label_get(void *data, Evas_Object *obj, const char *part) +{ + WDUG_LOGD("part %s", part); + device_type_s *peer = (device_type_s *)data; + + if (NULL == peer) { + return NULL; + } + + if (!strcmp(part, "elm.text")) { + return strdup(peer->ssid); + } + return NULL; +} + +/** + * This function let the ug get the icon path of peer + * @return the icon path of titile + * @param[in] peer the pointer to the peer + */ +static char *__wfd_get_device_icon_path(device_type_s *peer) +{ + char *img_path = NULL; + + switch (peer->category) { + case WFD_DEVICE_TYPE_COMPUTER: + img_path = WFD_ICON_DEVICE_COMPUTER; + break; + case WFD_DEVICE_TYPE_INPUT_DEVICE: + img_path = WFD_ICON_DEVICE_INPUT_DEVICE; + break; + case WFD_DEVICE_TYPE_PRINTER: + img_path = WFD_ICON_DEVICE_PRINTER; + break; + case WFD_DEVICE_TYPE_CAMERA: + img_path = WFD_ICON_DEVICE_CAMERA; + break; + case WFD_DEVICE_TYPE_STORAGE: + img_path = WFD_ICON_DEVICE_STORAGE; + break; + case WFD_DEVICE_TYPE_NW_INFRA: + img_path = WFD_ICON_DEVICE_NETWORK_INFRA; + break; + case WFD_DEVICE_TYPE_DISPLAYS: + img_path = WFD_ICON_DEVICE_DISPLAY; + break; + case WFD_DEVICE_TYPE_MM_DEVICES: + img_path = WFD_ICON_DEVICE_MULTIMEDIA_DEVICE; + break; + case WFD_DEVICE_TYPE_GAME_DEVICES: + img_path = WFD_ICON_DEVICE_GAMING_DEVICE; + break; + case WFD_DEVICE_TYPE_TELEPHONE: + img_path = WFD_ICON_DEVICE_TELEPHONE; + break; + case WFD_DEVICE_TYPE_AUDIO: + img_path = WFD_ICON_DEVICE_AUDIO_DEVICE; + break; + default: + img_path = WFD_ICON_DEVICE_COMPUTER; + break; + } + + return img_path; +} + + +/** + * This function let the ug call it when click the check box + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_check_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + if (NULL == obj) { + WDUG_LOGE("NULL parameters.\n"); + return; + } + + Eina_Bool state = elm_check_state_get(obj); + elm_check_state_set(obj, !state); + WDUG_LOGD("state = %d \n", state); +} + +/** + * This function let the ug get the icon of peer + * @return the icon of peer + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_wfd_gl_device_icon_get(void *data, Evas_Object *obj, const char *part) +{ + char *img_path = NULL; + device_type_s *peer = (device_type_s *) data; + Evas_Object *icon = NULL; + + WDUG_LOGD("Part %s", part); + + if (!strcmp(part, "elm.icon.1")) { + WDUG_LOGD("Part %s", part); + icon = elm_check_add(obj); + elm_check_state_set(icon, EINA_FALSE); + evas_object_smart_callback_add(icon, "changed", _wfd_check_clicked_cb, (void *)data); + } else if (!strcmp(part, "elm.icon.2")) { + img_path = __wfd_get_device_icon_path(peer); + icon = elm_icon_add(obj); + elm_icon_file_set(icon, img_path, NULL); + evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_icon_resizable_set(icon, 1, 1); + evas_object_show(icon); + } + + return icon; +} + +/** + * This function let the ug get the label of select all + * @return the label of select all + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static char *_wfd_gl_select_all_label_get(void *data, Evas_Object *obj, const char *part) +{ + if (!strcmp(part, "elm.text")) { + WDUG_LOGD("Adding text %s", part); + return strdup("Select all"); + } + return NULL; +} + +/** + * This function let the ug get the icon of select all + * @return the icon of select all + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] part the pointer to the part of item + */ +static Evas_Object *_wfd_gl_select_all_icon_get(void *data, Evas_Object *obj, const char *part) +{ + Evas_Object *icon = NULL; + + if (!strcmp(part, "elm.icon")) { + WDUG_LOGD("Part %s", part); + icon = elm_check_add(obj); + elm_check_state_set(icon, EINA_FALSE); + evas_object_smart_callback_add(icon, "changed", _wfd_check_clicked_cb, (void *)data); + } + + return icon; +} + +/** + * This function let the ug fee the multi connect devices + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int wfd_free_multiconnect_device(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + + int i = 0; + + if (ugd->multiconn_view_genlist == NULL) { + return 0; + } + + if (ugd->mcview_title_item != NULL) { + elm_object_item_del(ugd->mcview_title_item); + ugd->mcview_title_item = NULL; + } + + if (ugd->mcview_select_all_item != NULL) { + elm_object_item_del(ugd->mcview_select_all_item); + ugd->mcview_select_all_item = NULL; + } + + if (ugd->mcview_nodevice_item != NULL) { + elm_object_item_del(ugd->mcview_nodevice_item); + ugd->mcview_nodevice_item = NULL; + } + + for (i = 0; i < ugd->gl_available_dev_cnt_at_multiconn_view; i++) { + if (ugd->multi_conn_dev_list[i].peer.gl_item != NULL) { + elm_object_item_del(ugd->multi_conn_dev_list[i].peer.gl_item); + ugd->multi_conn_dev_list[i].peer.gl_item = NULL; + } + } + ugd->gl_available_dev_cnt_at_multiconn_view = 0; + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug update the multi connect devices + * @return 0 + * @param[in] data the pointer to the main data structure + */ +int wfd_update_multiconnect_device(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + + int count = 0; + device_type_s *device = NULL; + Evas_Object *genlist = NULL; + int i = 0; + + genlist = ugd->multiconn_view_genlist; + if (ugd->multiconn_view_genlist == NULL) { + return 0; + } + + wfd_free_multiconnect_device(ugd); + + count = 0; + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + device = &ugd->raw_discovered_peers[i]; + if (device->is_connected == FALSE) { + count++; + } + } + ugd->gl_available_dev_cnt_at_multiconn_view = count; + + if (ugd->gl_available_dev_cnt_at_multiconn_view == 0) { + WDUG_LOGE("There are No peers\n"); + ugd->mcview_title_item = elm_genlist_item_append(genlist, &title_itc, ugd, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->mcview_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + ugd->mcview_nodevice_item = elm_genlist_item_append(genlist, &noitem_itc, (void *)ugd, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->mcview_nodevice_item , ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } else { + ugd->mcview_title_item = elm_genlist_item_append(genlist, &title_itc, ugd, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + elm_genlist_item_select_mode_set(ugd->mcview_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + ugd->mcview_select_all_item = elm_genlist_item_append(genlist, &select_all_itc, ugd, NULL, ELM_GENLIST_ITEM_NONE, _wfd_gl_sel_cb, ugd); + + count = 0; + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + device = &ugd->raw_discovered_peers[i]; + if (device->is_connected == FALSE) { + WDUG_LOGD("%dth peer being added on genlist\n", i); + + if (ugd->multi_conn_dev_list[count].peer.gl_item != NULL) { + elm_object_item_del(ugd->multi_conn_dev_list[count].peer.gl_item); + } + + ugd->multi_conn_dev_list[count].peer.gl_item = NULL; + memcpy(&ugd->multi_conn_dev_list[count].peer, device, sizeof(device_type_s)); + ugd->multi_conn_dev_list[count].dev_sel_state = FALSE; + ugd->multi_conn_dev_list[count].peer.gl_item = elm_genlist_item_append(genlist, &device_itc, + (void *)&ugd->multi_conn_dev_list[count].peer, NULL, ELM_GENLIST_ITEM_NONE, _wfd_gl_multi_sel_cb, ugd); + count++; + } + } + } + + __WDUG_LOG_FUNC_EXIT__; + return 0; +} + +/** + * This function let the ug create the view for multi connection + * @return void + * @param[in] ugd the pointer to the main data structure + */ +void wfd_create_multiconnect_view(struct ug_data *ugd) +{ + __WDUG_LOG_FUNC_ENTER__; + + Evas_Object *back_btn = NULL; + Evas_Object *genlist = NULL; + Elm_Object_Item *navi_item = NULL; + + if (ugd == NULL) { + WDUG_LOGE("Incorrect parameter(NULL)"); + return; + } + + select_all_itc.item_style = "1text.1icon.3"; + select_all_itc.func.text_get = _wfd_gl_select_all_label_get; + select_all_itc.func.content_get = _wfd_gl_select_all_icon_get; + select_all_itc.func.state_get = NULL; + select_all_itc.func.del = NULL; + + device_itc.item_style = "1text.2icon.2"; + device_itc.func.text_get = _wfd_gl_device_label_get; + device_itc.func.content_get = _wfd_gl_device_icon_get; + device_itc.func.state_get = NULL; + device_itc.func.del = NULL; + + WDUG_LOGD("_wifid_create_multiconnect_view"); + back_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(back_btn, "naviframe/back_btn/default"); + evas_object_smart_callback_add(back_btn, "clicked", _multiconnect_view_back_btn_cb, (void *)ugd); + elm_object_focus_allow_set(back_btn, EINA_FALSE); + + genlist = elm_genlist_add(ugd->naviframe); + ugd->multiconn_view_genlist = genlist; + ugd->mcview_title_item = NULL; + + wfd_update_multiconnect_device(ugd); + + evas_object_show(genlist); + + navi_item = elm_naviframe_item_push(ugd->naviframe, _("Multi connect"), back_btn, NULL, genlist, NULL); + + /* create scan button */ + ugd->multi_scan_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(ugd->multi_scan_btn, "naviframe/toolbar/default"); + elm_object_text_set(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN")); + evas_object_smart_callback_add(ugd->multi_scan_btn, "clicked", _scan_btn_cb, (void *)ugd); + elm_object_item_part_content_set(navi_item, "toolbar_button1", ugd->multi_scan_btn); + + /* create connect button */ + ugd->multi_connect_btn = elm_button_add(ugd->naviframe); + elm_object_style_set(ugd->multi_connect_btn, "naviframe/toolbar/default"); + elm_object_text_set(ugd->multi_connect_btn, _("IDS_WFD_BUTTON_CONNECT")); + evas_object_smart_callback_add(ugd->multi_connect_btn, "clicked", _connect_btn_cb, (void *)ugd); + elm_object_disabled_set(ugd->multi_connect_btn, EINA_TRUE); + elm_object_item_part_content_set(navi_item, "toolbar_button2", ugd->multi_connect_btn); + + __WDUG_LOG_FUNC_EXIT__; +} diff --git a/ug-wifidirect/src/wfd_ug_popup.c b/ug-wifidirect/src/wfd_ug_popup.c new file mode 100755 index 0000000..b7778b3 --- /dev/null +++ b/ug-wifidirect/src/wfd_ug_popup.c @@ -0,0 +1,379 @@ +/* +* WiFi-Direct UG +* +* Copyright 2012 Samsung Electronics Co., Ltd + +* Licensed under the Flora License, Version 1.0 (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 <libintl.h> + +#include <assert.h> +#include <glib.h> + +#include <Elementary.h> +#include <vconf.h> +#include <ui-gadget-module.h> +#include <wifi-direct.h> + +#include "wfd_ug.h" +#include "wfd_ug_view.h" +#include "wfd_client.h" + +/** + * This function let the ug call it when click 'ok' button in hotspot action popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_hotspot_ok_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + int result = -1; + struct ug_data *ugd = (struct ug_data *) data; + + result = wfd_mobile_ap_off(ugd); + if (0 == result) { + /* refresh the header */ + ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING; + wfd_ug_view_refresh_glitem(ugd->head); + + /* while activating/deactivating, disable the buttons */ + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->multi_scan_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->back_btn) { + elm_object_disabled_set(ugd->back_btn, TRUE); + } + } + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'cancel' button in hotspot action popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_hotspot_cancel_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'ok' button in wifi action popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_wifi_ok_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + int result = -1; + struct ug_data *ugd = (struct ug_data *) data; + + result = wfd_wifi_off(ugd); + if (0 == result) { + /* refresh the header */ + ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING; + wfd_ug_view_refresh_glitem(ugd->head); + + /* while activating/deactivating, disable the buttons */ + if (ugd->scan_btn) { + wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->multi_scan_btn) { + wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE); + } + + if (ugd->back_btn) { + elm_object_disabled_set(ugd->back_btn, TRUE); + } + } + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'cancel' button in wifi action popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_wifi_cancel_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT; + wfd_ug_view_refresh_glitem(ugd->head); + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'ok' button in disconnect all popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_disconnect_all_ok_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + int i = 0; + struct ug_data *ugd = (struct ug_data *) data; + if (NULL == ugd) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + wfd_client_disconnect(NULL); + + if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) { + wfd_free_multi_selected_peers(ugd); + } else { + /* update the connecting icon */ + for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) { + ugd->raw_discovered_peers[i].conn_status = PEER_CONN_STATUS_DISCONNECTED; + wfd_ug_view_refresh_glitem(ugd->raw_discovered_peers[i].gl_item); + } + } + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'cancel' button in disconnect all popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_act_popup_disconnect_all_cancel_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + + struct ug_data *ugd = (struct ug_data *) data; + if (NULL == ugd) { + WDUG_LOGE("Incorrect parameter(NULL)\n"); + return; + } + + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug create a action popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] message the pointer to the text of popup + * @param[in] popup_type the message type + */ +void wfd_ug_act_popup(void *data, const char *message, int popup_type) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + Evas_Object *popup = NULL; + Evas_Object *btn1 = NULL, *btn2 = NULL; + + popup = elm_popup_add(ugd->base); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, message); + + btn1 = elm_button_add(popup); + btn2 = elm_button_add(popup); + elm_object_style_set(btn1, "popup_button/default"); + elm_object_style_set(btn2, "popup_button/default"); + + /* set the different text by type */ + if (popup_type == POPUP_TYPE_WIFI_OFF || popup_type == POPUP_TYPE_HOTSPOT_OFF) { + elm_object_text_set(btn1, S_("IDS_COM_SK_YES")); + elm_object_text_set(btn2, S_("IDS_COM_SK_NO")); + } else { + elm_object_text_set(btn1, S_("IDS_COM_SK_OK")); + elm_object_text_set(btn2, S_("IDS_COM_SK_CANCEL")); + } + + elm_object_part_content_set(popup, "button1", btn1); + elm_object_part_content_set(popup, "button2", btn2); + + /* set the different callback by type */ + if (popup_type == POPUP_TYPE_WIFI_OFF) { + evas_object_smart_callback_add(btn1, "clicked", _wfd_ug_act_popup_wifi_ok_cb, (void *)ugd); + evas_object_smart_callback_add(btn2, "clicked", _wfd_ug_act_popup_wifi_cancel_cb, (void *)ugd); + } else if (popup_type == POPUP_TYPE_HOTSPOT_OFF) { + evas_object_smart_callback_add(btn1, "clicked", _wfd_ug_act_popup_hotspot_ok_cb, (void *)ugd); + evas_object_smart_callback_add(btn2, "clicked", _wfd_ug_act_popup_hotspot_cancel_cb, (void *)ugd); + } else if (popup_type == POP_TYPE_DISCONNECT || + popup_type == POP_TYPE_DISCONNECT_ALL || + popup_type == POP_TYPE_SCAN_AGAIN) { + evas_object_smart_callback_add(btn1, "clicked", _wfd_ug_act_popup_disconnect_all_ok_cb, (void *)ugd); + evas_object_smart_callback_add(btn2, "clicked", _wfd_ug_act_popup_disconnect_all_cancel_cb, (void *)ugd); + } + + evas_object_show(popup); + ugd->act_popup = popup; + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug remove the action popup + * @return void + * @param[in] data the pointer to the main data structure + */ +void wfg_ug_act_popup_remove(void *data) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + if (ugd->act_popup) { + evas_object_del(ugd->act_popup); + ugd->act_popup = NULL; + } + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'ok' button in warning popup of terminated problem + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_terminate_popup_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + evas_object_del(ugd->warn_popup); + ugd->warn_popup = NULL; + + wfd_ug_view_free_peers(ugd); + + ug_destroy_me(ugd->ug); + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'ok' button in warning popup of turning off WFD automatically + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_automatic_turn_off_popup_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + evas_object_del(ugd->warn_popup); + ugd->warn_popup = NULL; + + /* turn off the Wi-Fi Direct */ + wfd_client_switch_off(ugd); + + /* antomaticlly turn on tethering mode */ + if (TRUE == ugd->is_hotspot_off) { + wfd_mobile_ap_on(ugd); + } + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug call it when click 'ok' button in warning popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] obj the pointer to the evas object + * @param[in] event_info the pointer to the event information + */ +static void _wfd_ug_warn_popup_cb(void *data, Evas_Object *obj, void *event_info) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + + evas_object_del(ugd->warn_popup); + ugd->warn_popup = NULL; + + __WDUG_LOG_FUNC_EXIT__; +} + +/** + * This function let the ug create a warning popup + * @return void + * @param[in] data the pointer to the main data structure + * @param[in] message the pointer to the text of popup + * @param[in] popup_type the message type + */ +void wfd_ug_warn_popup(void *data, const char *message, int popup_type) +{ + __WDUG_LOG_FUNC_ENTER__; + struct ug_data *ugd = (struct ug_data *) data; + Evas_Object *popup = NULL; + Evas_Object *btn = NULL; + + popup = elm_popup_add(ugd->base); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_text_set(popup, "title,text", _("IDS_WFD_POP_TITILE_CONNECTION")); + elm_object_text_set(popup, message); + + btn = elm_button_add(popup); + elm_object_style_set(btn, "popup_button/default"); + elm_object_text_set(btn, S_("IDS_COM_SK_OK")); + elm_object_part_content_set(popup, "button1", btn); + if (popup_type == POPUP_TYPE_TERMINATE) { + evas_object_smart_callback_add(btn, "clicked", _wfd_ug_terminate_popup_cb, (void *)ugd); + } else if (popup_type == POP_TYPE_AUTOMATIC_TURN_OFF) { + evas_object_smart_callback_add(btn, "clicked", _wfd_ug_automatic_turn_off_popup_cb, (void *)ugd); + } else { + evas_object_smart_callback_add(btn, "clicked", _wfd_ug_warn_popup_cb, (void *)ugd); + } + + evas_object_show(popup); + ugd->warn_popup = popup; + __WDUG_LOG_FUNC_EXIT__; +} + |