4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.tizenopensource.org/license
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include <Elementary.h>
26 #include <ui-gadget-module.h>
27 #include <app_control.h>
28 #include <efl_extension.h>
31 #include "wfd_ug_view.h"
32 #include "wfd_client.h"
34 void scan_button_create(struct ug_data *ugd)
38 Evas_Object *btn_ly = NULL;
39 Evas_Object *btn = NULL;
41 btn_ly = elm_layout_add(ugd->layout);
42 elm_layout_file_set(btn_ly, WFD_UG_EDJ_PATH, "bottom_btn");
43 ugd->button_layout = btn_ly;
45 btn = elm_button_add(ugd->button_layout);
46 elm_object_style_set(btn, "bottom");
47 elm_object_domain_translatable_text_set(btn, PACKAGE, "IDS_WIFI_SK4_SCAN");
48 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
49 wfd_ug_view_refresh_button(btn, "IDS_WIFI_SK4_SCAN",
52 evas_object_smart_callback_add(btn, "clicked", _scan_btn_cb, (void *)ugd);
53 elm_layout_content_set(ugd->button_layout, "button.big", btn);
54 ugd->scan_toolbar = btn;
56 elm_object_part_content_set(ugd->naviframe, "toolbar", ugd->button_layout);
57 evas_object_show(ugd->button_layout);
63 * This function let the ug call it when click 'back' button
65 * @param[in] data the pointer to the main data structure
66 * @param[in] obj the pointer to the evas object
67 * @param[in] event_info the pointer to the event information
69 Eina_Bool _back_btn_cb(void *data, Elm_Object_Item *it)
72 struct ug_data *ugd = (struct ug_data *) data;
73 WFD_RETV_IF(ugd == NULL, FALSE, "The param is NULL\n");
76 app_control_h control = NULL;
78 wfd_refresh_wifi_direct_state(ugd);
79 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
80 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
84 if (NULL != ugd->mac_addr_connecting) {
85 if (ugd->is_conn_incoming) {
86 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
87 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
88 if (ret != WIFI_DIRECT_ERROR_NONE)
89 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
91 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
92 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
93 if (ret != WIFI_DIRECT_ERROR_NONE)
94 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
96 ugd->mac_addr_connecting = NULL;
99 if (ugd->raw_connected_peer_cnt == 0) {
100 ret = wifi_direct_is_group_owner(&owner);
101 if (ret == WIFI_DIRECT_ERROR_NONE) {
103 wifi_direct_destroy_group();
108 wfd_ug_view_free_peers(ugd);
109 ret = app_control_create(&control);
111 DBG(LOG_ERROR, "Failed to create control");
113 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
114 app_control_add_extra_data(control, "Connection", "TRUE");
116 app_control_add_extra_data(control, "Connection", "FALSE");
118 ug_send_result(ugd->ug, control);
119 app_control_destroy(control);
122 ug_destroy_me(ugd->ug);
128 * This function let the ug call it when click 'back' button
130 * @param[in] data the pointer to the main data structure
131 * @param[in] obj the pointer to the evas object
132 * @param[in] event_info the pointer to the event information
134 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
137 struct ug_data *ugd = (struct ug_data *) data;
140 app_control_h control = NULL;
143 DBG(LOG_ERROR, "The param is NULL");
147 wfd_refresh_wifi_direct_state(ugd);
148 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
149 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
153 if (NULL != ugd->mac_addr_connecting) {
154 if (ugd->is_conn_incoming) {
155 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
156 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
157 if (ret != WIFI_DIRECT_ERROR_NONE)
158 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
160 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
161 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
162 if (ret != WIFI_DIRECT_ERROR_NONE)
163 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
165 ugd->mac_addr_connecting = NULL;
168 if (ugd->raw_connected_peer_cnt == 0) {
169 ret = wifi_direct_is_group_owner(&owner);
170 if (ret == WIFI_DIRECT_ERROR_NONE) {
172 wifi_direct_destroy_group();
177 wfd_ug_view_free_peers(ugd);
178 ret = app_control_create(&control);
180 DBG(LOG_ERROR, "Failed to create control");
182 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
183 app_control_add_extra_data(control, "Connection", "TRUE");
185 app_control_add_extra_data(control, "Connection", "FALSE");
187 ug_send_result(ugd->ug, control);
188 app_control_destroy(control);
191 ug_destroy_me(ugd->ug);
196 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
200 if (ugd->timer_stop_progress_bar > 0)
201 g_source_remove(ugd->timer_stop_progress_bar);
203 ugd->timer_stop_progress_bar = 0;
208 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
212 if (ugd->timer_delete_not_alive_peer > 0)
213 g_source_remove(ugd->timer_delete_not_alive_peer);
215 ugd->timer_delete_not_alive_peer = 0;
221 * This function let the ug call it when click failed devices item
223 * @param[in] data the pointer to the main data structure
224 * @param[in] obj the pointer to the evas object
225 * @param[in] event_info the pointer to the event information
227 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
231 struct ug_data *ugd = wfd_get_ug_data();
235 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
239 if (ugd->display_timer != NULL) {
240 ecore_timer_del(ugd->display_timer);
241 ugd->display_timer = NULL;
244 wfd_refresh_wifi_direct_state(ugd);
245 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
247 /* if connected, show the popup*/
248 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
249 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
251 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
252 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
253 if (ret != WIFI_DIRECT_ERROR_NONE) {
254 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
255 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
256 wifi_direct_cancel_discovery();
265 * This function let the ug call it when click 'scan' button
267 * @param[in] data the pointer to the main data structure
268 * @param[in] obj the pointer to the evas object
269 * @param[in] event_info the pointer to the event information
271 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
275 struct ug_data *ugd = (struct ug_data *) data;
277 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
281 const char *btn_text = NULL;
282 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
283 DBG(LOG_INFO, "Button text=%s", btn_text);
285 if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
286 wfd_refresh_wifi_direct_state(ugd);
287 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
288 /* if connected, show the popup*/
289 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
290 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
291 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
292 wfd_client_switch_on(ugd);
296 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
297 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
298 if (ret != WIFI_DIRECT_ERROR_NONE) {
299 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
300 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
301 wifi_direct_cancel_discovery();
304 } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
305 DBG(LOG_INFO, "Stop pressed.\n");
306 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
307 wfd_cancel_progressbar_stop_timer(ugd);
308 wfd_delete_progressbar_cb(ugd);
309 wfd_cancel_not_alive_delete_timer(ugd);
310 } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
311 DBG(LOG_INFO, "Cancel Connection");
312 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
314 DBG(LOG_INFO, "Invalid Case\n");
320 void wfd_check_gl_busy_peers(struct ug_data *ugd)
323 if (ugd->gl_busy_peer_cnt == 0)
324 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
329 void wfd_check_gl_available_peers(struct ug_data *ugd)
332 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL)
333 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
339 * This function let the ug free some peer in genlist
341 * @param[in] start_pos the start position of peers list
342 * @param[in] mac_addr the mac_addr of peer for free
343 * @param[in] cnt the count of gl peers in list
345 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
348 device_type_s *peer = *start_pos;
349 device_type_s *peer_tmp = peer;
352 DBG(LOG_INFO, "no peer in genlist");
357 if (strcmp(peer->mac_addr, mac_addr)) {
361 if (peer->next != NULL) {
362 peer_tmp->next = peer->next;
365 peer_tmp->next = NULL;
371 if (peer == *start_pos) {
372 DBG(LOG_INFO, "the head is free");
373 *start_pos = peer->next;
378 WFD_IF_DEL_ITEM(peer->gl_item);
386 * This function let the ug call it when click available peer to connect
388 * @param[in] data the pointer to the main data structure
389 * @param[in] obj the pointer to the evas object
390 * @param[in] event_info the pointer to the event information
392 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
397 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
398 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
399 bool is_peer_alive = false;
400 struct ug_data *ugd = wfd_get_ug_data();
401 device_type_s *peer = (device_type_s *)data;
402 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
403 char *format_str = NULL;
406 DBG(LOG_ERROR, "NULL parameters.\n");
410 wfd_ug_get_connected_peers(ugd);
411 DBG(LOG_INFO, "No of connected peers= %d", ugd->raw_connected_peer_cnt);
413 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
414 format_str = D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME");
415 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, format_str, MAX_CONNECTED_PEER_NUM);
416 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
418 elm_genlist_item_selected_set(item, EINA_FALSE);
423 if (ugd->disconnect_btn) {
424 Evas_Object *content;
425 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
426 WFD_IF_DEL_OBJ(content);
427 ugd->disconnect_btn = NULL;
428 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
432 elm_genlist_item_selected_set(item, EINA_FALSE);
434 GList *iterator = NULL;
436 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
437 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
438 /* peer is found in last discovery */
439 is_peer_alive = true;
444 if (!is_peer_alive) {
445 /* peer exists only in genlist, waiting to be deleted */
446 device_type_s *peer_start = ugd->gl_avlb_peers_start;
447 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
448 if (!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
449 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
450 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
451 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
452 wfd_check_gl_available_peers(ugd);
453 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
459 wfd_cancel_not_alive_delete_timer(ugd);
462 wfd_refresh_wifi_direct_state(ugd);
464 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
465 peer->is_group_owner == TRUE) {
466 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
467 MAC2SECSTR(peer->mac_addr));
469 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
470 DBG(LOG_DEBUG, "It's in connecting status now.\n");
474 ugd->mac_addr_connecting = peer->mac_addr;
475 res = wfd_client_connect((const char *)peer->mac_addr);
477 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
487 * This function let the ug call it when click busy peer
489 * @param[in] data the pointer to the main data structure
490 * @param[in] obj the pointer to the evas object
491 * @param[in] event_info the pointer to the event information
493 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
496 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
497 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
500 elm_genlist_item_selected_set(item, EINA_FALSE);
503 DBG(LOG_ERROR, "Data is NULL\n");
507 wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
512 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
514 struct ug_data *ugd = (struct ug_data *) data;
517 DBG(LOG_ERROR, "The param is NULL\n");
522 evas_object_del(ugd->ctxpopup);
523 ugd->ctxpopup = NULL;
527 void _ctxpopup_move()
531 int win_w = 0, win_h = 0;
532 int move_x = 0, move_y = 0;
534 struct ug_data *ugd = wfd_get_ug_data();
536 if (!ugd || !ugd->win) {
537 DBG(LOG_ERROR, "NULL parameters.\n");
541 if (!ugd->ctxpopup) {
542 DBG(LOG_INFO, "NULL parameters.\n");
546 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
547 changed_ang = elm_win_rotation_get(ugd->win);
549 switch (changed_ang) {
572 evas_object_move(ugd->ctxpopup, move_x, move_y);
577 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
580 struct ug_data *ugd = (struct ug_data *) data;
581 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
582 WFD_IF_DEL_OBJ(ugd->ctxpopup);
585 wfd_client_free_raw_discovered_peers(ugd);
586 ugd->raw_discovered_peer_cnt = 0;
587 wfd_create_multiconnect_view(ugd);
588 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
589 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
590 if (ret != WIFI_DIRECT_ERROR_NONE) {
591 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
592 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
593 wifi_direct_cancel_discovery();
599 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
603 Evas_Object *naviframe = (Evas_Object *)data;
604 Elm_Object_Item *multi_connect_item = NULL;
605 Elm_Object_Item *rename_item = NULL;
606 struct ug_data *ugd = wfd_get_ug_data();
608 if (!naviframe || !ugd) {
609 DBG(LOG_ERROR, "NULL parameters.\n");
613 ugd->more_btn_multiconnect_item = NULL;
616 evas_object_del(ugd->ctxpopup);
618 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
619 elm_object_style_set(ugd->ctxpopup, "more/default");
620 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
621 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
622 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
623 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
625 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
626 ELM_CTXPOPUP_DIRECTION_LEFT,
627 ELM_CTXPOPUP_DIRECTION_RIGHT,
628 ELM_CTXPOPUP_DIRECTION_DOWN);
632 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
633 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
634 ugd->more_btn_multiconnect_item = multi_connect_item;
636 wfd_refresh_wifi_direct_state(ugd);
637 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
638 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
639 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
640 ugd->raw_connected_peer_cnt > 0) {
641 elm_object_item_disabled_set(multi_connect_item, TRUE);
644 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
645 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
646 evas_object_show(ugd->ctxpopup);
652 * This function make items into group
654 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
658 if (count < 1 || pre_item == NULL)
661 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
666 elm_object_item_signal_emit(item, "elm,state,normal", "");
670 for (i = 0; i < count; i++) {
672 elm_object_item_signal_emit(item, "elm,state,top", "");
673 else if (i == count - 1)
674 elm_object_item_signal_emit(item, "elm,state,bottom", "");
676 elm_object_item_signal_emit(item, "elm,state,center", "");
678 item = elm_genlist_item_next_get(item);
684 * This function let the ug call it when unresized event is received
686 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
689 struct ug_data *ugd = (struct ug_data *)data;
691 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
692 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
693 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
694 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
695 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
700 * This function let the ug call it when resized event is received
702 * @param[in] data the pointer to the main data structure
703 * @param[in] obj the pointer to the evas object
704 * @param[in] event_info the pointer to the event information
706 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
710 if (!data || !event_info) {
711 DBG(LOG_ERROR, "Invalid parameters");
715 struct ug_data *ugd = (struct ug_data *)data;
716 #ifdef ACCESSIBILITY_FEATURE
717 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
718 int index = elm_genlist_item_index_get(item);
722 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
723 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
724 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
725 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
726 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
728 #ifdef ACCESSIBILITY_FEATURE
730 if (GENLIST_HEADER_POS == index && item != NULL) {
731 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
733 Eina_Bool state = elm_check_state_get(check);
735 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
737 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
740 Evas_Object *ao = NULL;
741 ao = elm_object_item_access_object_get(item);
742 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
745 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
748 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
757 * This function let the ug call it when click 'disconnect' button
759 * @param[in] data the pointer to the main data structure
760 * @param[in] obj the pointer to the evas object
761 * @param[in] event_info the pointer to the event information
763 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
766 struct ug_data *ugd = (struct ug_data *)data;
767 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
769 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
775 * This function let the ug call it when click "cancel connection" button
777 * @param[in] data the pointer to the main data structure
778 * @param[in] obj the pointer to the evas object
779 * @param[in] event_info the pointer to the event information
781 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
784 struct ug_data *ugd = (struct ug_data *)data;
785 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
787 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
794 * This function let the ug update the genlist item
796 * @param[in] gl_item the pointer to genlist item
798 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
802 elm_genlist_item_update(gl_item);
808 * This function let the ug refresh the attributes of button
810 * @param[in] tb_item the pointer to the toolbar button
811 * @param[in] text the pointer to the text of button
812 * @param[in] enable whether the button is disabled
814 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
819 if (NULL == tb_item || NULL == text) {
820 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
824 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
825 elm_object_domain_translatable_part_text_set(tb_item, "default",
827 elm_object_disabled_set(tb_item, !enable);
833 * This function let the ug know whether current device is connected by me
834 * @return If connected, return TRUE, else return FALSE
835 * @param[in] ugd the pointer to the main data structure
836 * @param[in] dev the pointer to the device
838 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
843 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
844 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
845 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
855 * This function let the ug know whether current device is connected by other peer
856 * @return If connected, return TRUE, else return FALSE
857 * @param[in] ugd the pointer to the main data structure
858 * @param[in] dev the pointer to the device
860 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
864 if (ugd->I_am_group_owner == TRUE) {
865 if (dev->is_connected || dev->is_group_owner)
870 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE)
873 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE)
876 if (dev->is_connected == FALSE)
885 * This function let the ug calculate how many devices are available
887 * @param[in] ugd the pointer to the main data structure
888 * @param[in] dev the pointer to the number of available devices
890 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
893 GList *iterator = NULL;
895 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
896 /* Not include the device which is connected with me */
897 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
900 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
901 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT)
902 (*no_of_available_dev)++;
910 * This function let the ug calculate how many devices are busy
912 * @param[in] ugd the pointer to the main data structure
913 * @param[in] dev the pointer to the number of busy devices
915 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
918 GList *iterator = NULL;
920 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
921 /* Not include the device which is connected with me */
922 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
925 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data))
934 * This function let the ug calculate how many devices are connected failed
936 * @param[in] ugd the pointer to the main data structure
937 * @param[in] dev the pointer to the number of connected failed devices
939 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
942 GList *iterator = NULL;
944 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
945 /* Not include the device which is connected with me */
946 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
949 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
950 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
951 (*no_of_connect_failed_dev)++;
960 * This function let the ug create the main genlist
961 * @return the main genlist
962 * @param[in] data the pointer to the main data structure
964 static Evas_Object *_create_basic_genlist(void *data)
967 struct ug_data *ugd = (struct ug_data *) data;
968 Evas_Object *genlist;
970 genlist = elm_genlist_add(ugd->layout);
972 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
973 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
975 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
977 /* Wifi ON/OFF toggle button */
978 #ifdef WFD_ON_OFF_GENLIST
979 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
980 NULL, ELM_GENLIST_ITEM_NONE, _onoff_changed_cb, ugd);
981 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
984 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
985 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
986 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
987 ELM_GENLIST_ITEM_NONE, NULL, NULL);
988 if (ugd->device_name_item != NULL)
989 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
996 * This function let the ug create no device item to append the genlist
997 * @return the main item
998 * @param[in] data the pointer to the main data structure
1000 Evas_Object *_create_no_device_genlist(void *data)
1003 struct ug_data *ugd = (struct ug_data *) data;
1004 Elm_Object_Item *last_item = NULL;
1007 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1009 if (ugd->conn_wfd_item != NULL) {
1010 last_item = ugd->conn_wfd_item;
1011 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1012 last_item = elm_genlist_item_next_get(last_item);
1015 last_item = ugd->device_name_item;
1018 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1019 &title_no_device_itc, (void *)ugd, NULL, last_item,
1020 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1021 if (ugd->nodevice_title_item != NULL)
1022 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1024 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1025 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1026 if (ugd->nodevice_item != NULL)
1027 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1030 return ugd->genlist;
1034 * This function let the ug create busy device list
1036 * @param[in] data the pointer to the main data structure
1038 int _create_busy_dev_list(void *data)
1041 struct ug_data *ugd = (struct ug_data *) data;
1043 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1044 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1045 if (ugd->busy_wfd_item != NULL)
1046 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1051 void wfd_free_nodivice_item(struct ug_data *ugd)
1054 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1055 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1060 * This function let the ug create available device list
1062 * @param[in] data the pointer to the main data structure
1064 int _create_available_dev_genlist(void *data)
1068 struct ug_data *ugd = (struct ug_data *) data;
1069 Elm_Object_Item *last_item = NULL;
1071 wfd_free_nodivice_item(ugd);
1073 if (ugd->conn_wfd_item != NULL) {
1074 last_item = ugd->conn_wfd_item;
1075 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1076 last_item = elm_genlist_item_next_get(last_item);
1079 last_item = ugd->device_name_item;
1082 ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1083 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1084 if (ugd->avlbl_wfd_item != NULL) {
1085 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1086 elm_genlist_item_update(ugd->avlbl_wfd_item);
1093 * This function let the ug create multi connect device list
1095 * @param[in] data the pointer to the main data structure
1097 static int _create_multi_connect_dev_genlist(void *data)
1100 struct ug_data *ugd = (struct ug_data *) data;
1102 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1103 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1104 if (ugd->multi_connect_wfd_item != NULL)
1105 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1111 * This function let the ug create connected device list
1113 * @param[in] data the pointer to the main data structure
1115 int _create_connected_dev_genlist(void *data)
1118 struct ug_data *ugd = (struct ug_data *) data;
1120 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1121 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1122 if (ugd->conn_wfd_item != NULL) {
1123 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1124 elm_genlist_item_update(ugd->conn_wfd_item);
1132 * This function let the ug create connected falied device list
1134 * @param[in] data the pointer to the main data structure
1136 int _create_connected_failed_dev_genlist(void *data)
1139 struct ug_data *ugd = (struct ug_data *) data;
1140 Elm_Object_Item *last_item = NULL;
1143 if (ugd->avlbl_wfd_item != NULL) {
1144 last_item = ugd->avlbl_wfd_item;
1145 for (i = 0; i < ugd->gl_available_peer_cnt; i++)
1146 last_item = elm_genlist_item_next_get(last_item);
1148 } else if (ugd->conn_wfd_item != NULL) {
1149 last_item = ugd->conn_wfd_item;
1150 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1151 last_item = elm_genlist_item_next_get(last_item);
1154 last_item = ugd->device_name_item;
1157 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1158 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1159 if (ugd->conn_failed_wfd_item != NULL)
1160 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1166 * This function let the ug make the display callback for connect failed peers
1167 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1168 * @param[in] data the pointer to the user data
1170 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1175 struct ug_data *ugd = (struct ug_data *) user_data;
1178 DBG(LOG_ERROR, "NULL parameters.\n");
1179 return ECORE_CALLBACK_CANCEL;
1182 if (ugd->avlbl_wfd_item == NULL)
1183 _create_available_dev_genlist(ugd);
1185 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1186 DBG(LOG_INFO, "Background mode\n");
1187 ugd->display_timer = NULL;
1188 return ECORE_CALLBACK_CANCEL;
1191 /* check the timeout, if not timeout, keep the cb */
1192 interval = time(NULL) - ugd->last_display_time;
1193 if (interval < MAX_DISPLAY_TIME_OUT)
1194 return ECORE_CALLBACK_RENEW;
1196 if (ugd->is_paused == false) {
1197 DBG(LOG_INFO, "Not Paused");
1198 /* start discovery again */
1199 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1200 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1201 if (res != WIFI_DIRECT_ERROR_NONE) {
1202 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1203 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1204 wifi_direct_cancel_discovery();
1208 ugd->display_timer = NULL;
1210 return ECORE_CALLBACK_CANCEL;
1213 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1216 device_type_s *peer_for_free = NULL;
1217 device_type_s *peer = gl_peers_start;
1219 while (peer != NULL && peer->gl_item != NULL) {
1220 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1221 elm_object_item_del(peer->gl_item);
1222 peer->gl_item = NULL;
1223 peer_for_free = peer;
1225 free(peer_for_free);
1230 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1233 if (ugd->gl_connected_peer_cnt == 0)
1234 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1240 * This function let the ug free the peers
1242 * @param[in] data the pointer to the main data structure
1244 void wfd_ug_view_free_peers(void *data)
1248 struct ug_data *ugd = (struct ug_data *) data;
1250 ugd->gl_connected_peer_cnt = 0;
1252 if (ugd->gl_conn_peers_start != NULL) {
1253 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1254 ugd->gl_conn_peers_start = NULL;
1257 ugd->gl_available_peer_cnt = 0;
1259 if (ugd->gl_avlb_peers_start != NULL) {
1260 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1261 ugd->gl_avlb_peers_start = NULL;
1264 ugd->gl_busy_peer_cnt = 0;
1266 if (ugd->gl_busy_peers_start != NULL) {
1267 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1268 ugd->gl_busy_peers_start = NULL;
1271 ugd->gl_multi_connect_peer_cnt = 0;
1273 if (ugd->gl_mul_conn_peers_start != NULL) {
1274 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1275 ugd->gl_mul_conn_peers_start = NULL;
1278 if (ugd->gl_connected_peer_cnt == 0)
1279 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1281 if (ugd->display_timer != NULL) {
1282 ecore_timer_del(ugd->display_timer);
1283 ugd->display_timer = NULL;
1286 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1287 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1288 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1289 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1294 void wfd_ug_update_toolbar(struct ug_data *ugd)
1297 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1300 wfd_refresh_wifi_direct_state(ugd);
1301 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1302 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1303 if (ugd->multi_connect_wfd_item != NULL) {
1304 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1305 btn = elm_button_add(ugd->button_layout);
1306 /* Use "bottom" style button */
1307 elm_object_style_set(btn, "bottom");
1308 elm_object_domain_translatable_text_set(btn, PACKAGE,
1309 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1310 evas_object_smart_callback_add(btn, "clicked",
1311 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1312 /* Set button into "toolbar" swallow part */
1313 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1314 ugd->disconnect_btn = btn;
1315 evas_object_show(ugd->disconnect_btn);
1316 elm_object_part_content_set(ugd->button_layout, "button.prev",
1318 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1319 "IDS_WIFI_SK4_SCAN", FALSE);
1320 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1321 DBG(LOG_INFO, "button: disconnect button added\n");
1323 DBG(LOG_INFO, "scan_toolbar\n");
1324 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1325 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1326 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1327 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1328 DBG(LOG_INFO, "button: stop connect button added\n");
1330 } else if (no_of_conn_dev > 0) {
1331 if (!ugd->multi_connect_toolbar_item) {
1332 btn = elm_button_add(ugd->button_layout);
1333 /* Use "bottom" style button */
1334 elm_object_style_set(btn, "bottom");
1335 elm_object_domain_translatable_text_set(btn, PACKAGE,
1336 "IDS_WIFI_SK_DISCONNECT");
1337 evas_object_smart_callback_add(btn, "clicked",
1338 _wfd_ug_disconnect_button_cb, (void *)ugd);
1339 /* Set button into "toolbar" swallow part */
1340 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1341 ugd->disconnect_btn = btn;
1342 evas_object_show(ugd->disconnect_btn);
1343 DBG(LOG_INFO, "button: disconnect button added\n");
1345 elm_object_part_content_set(ugd->button_layout, "button.prev",
1347 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1348 "IDS_WIFI_SK4_SCAN", TRUE);
1349 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1350 DBG(LOG_INFO, "button: scan button added\n");
1352 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1353 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1354 Evas_Object *content;
1355 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1356 WFD_IF_DEL_OBJ(content);
1357 ugd->disconnect_btn = NULL;
1358 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1360 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1361 "IDS_WIFI_SK4_SCAN", TRUE);
1362 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1363 DBG(LOG_INFO, "button: scan button added\n");
1369 * This function let the ug init the genlist
1371 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1374 struct ug_data *ugd = (struct ug_data *) data;
1375 int no_of_busy_dev = 0;
1376 int no_of_available_dev = 0;
1377 int no_of_conn_failed_dev = 0;
1379 if (is_free_all_peers)
1380 wfd_ug_view_free_peers(ugd);
1382 if (ugd->gl_failed_peers_start != NULL) {
1383 DBG(LOG_INFO, "These are failed peers, must clear them");
1384 ugd->gl_connected_failed_peer_cnt = 0;
1385 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1386 ugd->gl_failed_peers_start = NULL;
1387 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1390 if (ugd->avlbl_wfd_item != NULL) {
1391 DBG(LOG_INFO, "There are available peers in genlist");
1392 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1396 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1397 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1398 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1404 * This function let the ug find a peer in genlist
1406 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1410 if (start_pos == NULL) {
1411 DBG(LOG_INFO, "no peer in genlist");
1415 device_type_s *peer = start_pos;
1417 while (peer != NULL) {
1418 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1419 peer->is_alive = true;
1420 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1431 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1434 if (*start_pos == NULL) {
1435 DBG(LOG_INFO, "no peer in genlist");
1439 device_type_s *peer = *start_pos;
1440 device_type_s *peer_tmp = NULL;
1441 while (peer != NULL) {
1442 peer_tmp = peer->next;
1443 if (peer->is_alive == false)
1444 free_gl_peer(start_pos, peer->mac_addr, cnt);
1449 // wfd_check_gl_available_peers(ugd);
1450 if (ugd->gl_busy_peer_cnt == 0)
1451 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1457 void set_not_alive_peers(device_type_s *start_pos)
1460 if (start_pos == NULL) {
1461 DBG(LOG_INFO, "no peer in genlist");
1465 device_type_s *peer = start_pos;
1466 while (peer != NULL) {
1467 peer->is_alive = false;
1476 * This function let the ug get the insert position for next item
1478 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1482 device_type_s *peer_ite = NULL;
1483 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1484 Elm_Object_Item *item = NULL;
1486 if (peer_cnt == 0) {
1487 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1491 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1492 if (peer_ite->gl_item != NULL) {
1493 for (i = 0; i < peer_cnt; i++) {
1494 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1495 /* if peer_ite is greater than peer, return previous item */
1497 return elm_genlist_item_prev_get(head);
1499 item = elm_genlist_item_next_get(head);
1501 /* return the last item */
1505 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1511 return elm_genlist_item_prev_get(head);
1515 * This function let the ug insert peer item to genlist
1517 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1518 device_type_s *peer_for_insert, void *callback)
1521 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1522 device_type_s *peer = NULL;
1523 device_type_s *peer_ite = NULL;
1525 peer = (device_type_s *)malloc(sizeof(device_type_s));
1526 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1528 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1531 if (*start_pos == NULL) {
1534 peer_ite = *start_pos;
1535 while (peer_ite->next != NULL) {
1536 /* move pointer to the last peer */
1537 peer_ite = peer_ite->next;
1539 peer_ite->next = peer;
1542 peer->is_alive = true;
1543 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1544 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1545 if (callback == NULL && peer->gl_item != NULL)
1546 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1553 * This function let the ug update connected peers
1555 * @param[in] data the pointer to the main data structure
1557 void wfd_ug_update_connected_peers(void *data)
1561 struct ug_data *ugd = (struct ug_data *) data;
1564 bool is_group_owner = FALSE;
1565 Elm_Object_Item *item = NULL;
1567 res = wifi_direct_is_group_owner(&is_group_owner);
1568 if (res == WIFI_DIRECT_ERROR_NONE)
1569 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1571 if (!ugd->conn_wfd_item)
1572 _create_connected_dev_genlist(ugd);
1574 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1575 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1576 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1577 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1578 &ugd->gl_available_peer_cnt);
1579 wfd_check_gl_available_peers(ugd);
1582 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1583 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1584 &ugd->gl_multi_connect_peer_cnt);
1585 if (ugd->gl_multi_connect_peer_cnt == 0) {
1586 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1587 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1591 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1592 ugd->gl_connected_peer_cnt);
1593 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1594 &ugd->raw_connected_peers[i], NULL);
1598 ugd->gl_connected_peer_cnt++;
1602 /* if is not GO, free all available peers */
1603 if (is_group_owner == FALSE) {
1604 ugd->gl_available_peer_cnt = 0;
1605 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1607 if (ugd->gl_avlb_peers_start != NULL) {
1608 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1609 ugd->gl_avlb_peers_start = NULL;
1613 /* free busy peers */
1614 if (ugd->gl_busy_peers_start != NULL) {
1615 ugd->gl_busy_peer_cnt = 0;
1616 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1618 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1619 ugd->gl_busy_peers_start = NULL;
1627 * This function let the ug update the multi-connect peers
1629 * @param[in] data the pointer to the main data structure
1631 void wfd_ug_view_update_multiconn_peers(void *data)
1635 struct ug_data *ugd = (struct ug_data *) data;
1638 Elm_Object_Item *item = NULL;
1640 if (ugd->raw_multi_selected_peer_cnt > 0) {
1641 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1642 ugd->multi_connect_wfd_item == NULL) {
1643 _create_multi_connect_dev_genlist(ugd);
1646 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1647 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1648 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1649 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1650 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1651 &ugd->raw_multi_selected_peers[i], NULL);
1655 ugd->gl_multi_connect_peer_cnt++;
1664 * This function let the ug update the available and busy peers
1666 void wfd_ug_update_available_peers(void *data)
1670 struct ug_data *ugd = (struct ug_data *) data;
1671 int no_of_busy_dev = 0;
1672 int no_of_available_dev = 0;
1673 int no_of_conn_dev = 0;
1674 bool is_group_owner = FALSE;
1676 Elm_Object_Item *item = NULL;
1677 device_type_s *peer = NULL;
1678 GList *iterator = NULL;
1680 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1681 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1682 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1684 res = wifi_direct_is_group_owner(&is_group_owner);
1685 if (res != WIFI_DIRECT_ERROR_NONE) {
1686 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1687 ugd->I_am_group_owner = FALSE;
1689 ugd->I_am_group_owner = is_group_owner;
1692 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1693 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1694 DBG(LOG_INFO, "There are available or busy peers\n");
1695 wfd_free_nodivice_item(ugd);
1698 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1699 if (ugd->avlbl_wfd_item == NULL)
1700 _create_available_dev_genlist(ugd);
1703 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1704 /* Not include the device which is connected with me */
1705 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1708 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1709 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1710 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1711 /* free disconnected gl peer */
1712 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1713 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1714 &ugd->gl_connected_peer_cnt);
1717 /* free busy gl peer, which is available now */
1718 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1719 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1720 if (ugd->gl_busy_peer_cnt == 0)
1721 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1724 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL)
1727 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1729 item = get_insert_postion((device_type_s *)iterator->data,
1730 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1731 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1732 (device_type_s *)iterator->data, _gl_peer_sel);
1736 ugd->gl_available_peer_cnt++;
1737 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1738 /* if peer is GO, free it */
1739 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1740 &ugd->gl_available_peer_cnt);
1746 wfd_check_gl_available_peers(ugd);
1747 wfd_check_gl_conn_peers(ugd);
1749 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1750 if (ugd->busy_wfd_item == NULL)
1751 _create_busy_dev_list(ugd);
1753 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1754 /* Not include the device which is connected with me */
1755 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1758 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1759 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1760 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1761 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1762 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1763 &ugd->gl_available_peer_cnt);
1764 wfd_check_gl_available_peers(ugd);
1766 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1767 ugd->gl_busy_peer_cnt);
1768 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1769 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1773 ugd->gl_busy_peer_cnt++;
1779 wfd_check_gl_busy_peers(ugd);
1785 * This function let the ug update the failed peers
1787 * @param[in] data the pointer to the main data structure
1789 void wfd_ug_update_failed_peers(void *data)
1792 struct ug_data *ugd = (struct ug_data *) data;
1793 int no_of_conn_failed_dev = 0;
1794 GList *iterator = NULL;
1796 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1797 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1799 if (no_of_conn_failed_dev == 0)
1802 /* add timer for disappearing failed peers after N secs */
1803 if (NULL == ugd->display_timer) {
1804 ugd->last_display_time = time(NULL);
1805 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1808 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1809 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1810 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1811 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1812 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1813 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1814 &ugd->gl_available_peer_cnt);
1815 wfd_check_gl_available_peers(ugd);
1824 #ifdef WFD_ON_OFF_GENLIST
1826 * This function is called when user swipes on/off button
1828 * @param[in] data the pointer to the main data structure
1829 * @param[in] obj the pointer to the evas object
1830 * @param[in] event_info the pointer to the event information
1832 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1835 struct ug_data *ugd = (struct ug_data *)data;
1836 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1837 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1838 wfd_refresh_wifi_direct_state(ugd);
1839 if (ugd->device_name_item != NULL)
1840 elm_genlist_item_update(ugd->device_name_item);
1842 elm_object_disabled_set(ugd->on_off_check, TRUE);
1843 if (ugd->disconnect_btn) {
1844 Evas_Object *content;
1845 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1846 WFD_IF_DEL_OBJ(content);
1847 ugd->disconnect_btn = NULL;
1849 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1851 /* turn on/off wfd */
1852 if (!ugd->wfd_onoff) {
1853 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1854 DBG(LOG_INFO, "wifi-direct switch on\n");
1855 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1857 wfd_client_switch_on(ugd);
1860 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1861 DBG(LOG_INFO, "wifi-direct switch off\n");
1862 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1864 wfd_client_switch_off(ugd);
1871 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1874 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1875 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1877 wfd_refresh_wifi_direct_state(ugd);
1878 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1879 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING)
1880 elm_object_disabled_set(ugd->on_off_check, TRUE);
1882 elm_object_disabled_set(ugd->on_off_check, FALSE);
1884 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
1885 elm_check_state_set(ugd->on_off_check, TRUE);
1887 elm_check_state_set(ugd->on_off_check, FALSE);
1892 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1895 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1896 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1898 Evas_Object *check = elm_check_add(ugd->naviframe);
1899 elm_object_style_set(check, "naviframe/title_on&off");
1900 elm_check_state_set(check, ugd->wfd_onoff);
1901 evas_object_propagate_events_set(check, EINA_FALSE);
1902 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1903 elm_object_focus_allow_set(check, EINA_TRUE);
1904 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1905 evas_object_show(check);
1906 ugd->on_off_check = check;
1913 * This function let the ug create the main view
1915 * @param[in] data the pointer to the main data structure
1917 void create_wfd_ug_view(void *data)
1920 struct ug_data *ugd = (struct ug_data *) data;
1921 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1922 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1923 Evas_Object *more_btn;
1925 Evas_Object *layout;
1927 ugd->naviframe = elm_naviframe_add(ugd->base);
1928 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1929 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1930 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1931 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1933 ugd->back_btn = elm_button_add(ugd->naviframe);
1934 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1935 evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1936 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1939 layout = elm_layout_add(ugd->naviframe);
1940 elm_layout_theme_set(layout, "layout", "application", "default");
1941 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1942 ugd->layout = layout;
1944 ugd->genlist = _create_basic_genlist(ugd);
1945 if (ugd->genlist == NULL) {
1946 DBG(LOG_ERROR, "Failed to create basic genlist");
1949 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1951 evas_object_show(ugd->base);
1952 elm_object_focus_set(ugd->base, EINA_TRUE);
1954 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1955 ugd->back_btn, NULL, layout, NULL);
1956 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1958 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1959 more_btn = elm_button_add(ugd->naviframe);
1960 elm_object_style_set(more_btn, "naviframe/more/default");
1961 evas_object_smart_callback_add(more_btn, "clicked",
1962 _more_button_cb, ugd->win);
1963 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1967 wifi_direct_initialize();
1968 wifi_direct_get_state(&ugd->wfd_status);
1969 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING)
1970 scan_button_create(ugd);
1972 if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1974 ugd->raw_discovered_peer_cnt = 0;
1975 wfd_create_multiconnect_view(ugd);
1976 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1977 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1978 if (ret != WIFI_DIRECT_ERROR_NONE) {
1979 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1980 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
1981 wifi_direct_cancel_discovery();
1990 * This function let the ug destroy the main view
1992 * @param[in] data the pointer to the main data structure
1994 void destroy_wfd_ug_view(void *data)
1997 struct ug_data *ugd = (struct ug_data *) data;
1998 WFD_IF_DEL_ITEM(ugd->device_name_item);
1999 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2000 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2002 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2003 WFD_IF_DEL_OBJ(ugd->back_btn);
2004 WFD_IF_DEL_OBJ(ugd->toolbar);
2005 WFD_IF_DEL_OBJ(ugd->genlist);
2006 WFD_IF_DEL_OBJ(ugd->button_layout);
2007 WFD_IF_DEL_OBJ(ugd->layout);
2008 WFD_IF_DEL_OBJ(ugd->naviframe);