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"
36 #include <system_info.h>
38 gboolean wfd_ug_util_is_profile_common(void)
40 gboolean result = FALSE;
41 char *profile_name = NULL;
43 system_info_get_platform_string("http://tizen.org/feature/profile", &profile_name);
47 if (!strncasecmp(profile_name, "common", 6)) {
48 DBG(LOG_ERROR, "WiFi direct is on common platform\n");
57 void scan_button_create(struct ug_data *ugd)
61 Evas_Object *btn_ly = NULL;
62 Evas_Object *btn = NULL;
64 btn_ly = elm_layout_add(ugd->layout);
65 elm_layout_file_set(btn_ly, WFD_UG_EDJ_PATH, "bottom_btn");
66 ugd->button_layout = btn_ly;
68 btn = elm_button_add(ugd->button_layout);
69 elm_object_style_set(btn, "bottom");
70 elm_object_domain_translatable_text_set(btn, PACKAGE, "IDS_WIFI_SK4_SCAN");
71 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
72 wfd_ug_view_refresh_button(btn, "IDS_WIFI_SK4_SCAN",
75 evas_object_smart_callback_add(btn, "clicked", _scan_btn_cb, (void *)ugd);
76 elm_layout_content_set(ugd->button_layout, WFD_UG_BIG_BUTTON_EDC_PART, btn);
77 ugd->scan_toolbar = btn;
79 elm_object_part_content_set(ugd->naviframe, "toolbar", ugd->button_layout);
80 evas_object_show(ugd->button_layout);
86 * This function let the ug call it when click 'back' button
88 * @param[in] data the pointer to the main data structure
89 * @param[in] obj the pointer to the evas object
90 * @param[in] event_info the pointer to the event information
92 Eina_Bool _back_btn_cb(void *data, Elm_Object_Item *it)
95 struct ug_data *ugd = (struct ug_data *) data;
96 WFD_RETV_IF(ugd == NULL, FALSE, "The param is NULL\n");
99 app_control_h control = NULL;
101 wfd_refresh_wifi_direct_state(ugd);
102 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
103 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
107 if (NULL != ugd->mac_addr_connecting) {
108 if (ugd->is_conn_incoming) {
109 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
110 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
111 if (ret != WIFI_DIRECT_ERROR_NONE)
112 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
114 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
115 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
116 if (ret != WIFI_DIRECT_ERROR_NONE)
117 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
119 ugd->mac_addr_connecting = NULL;
122 if (ugd->raw_connected_peer_cnt == 0) {
123 ret = wifi_direct_is_group_owner(&owner);
124 if (ret == WIFI_DIRECT_ERROR_NONE) {
126 wifi_direct_destroy_group();
131 wfd_ug_view_free_peers(ugd);
132 ret = app_control_create(&control);
134 DBG(LOG_ERROR, "Failed to create control");
136 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
137 app_control_add_extra_data(control, "Connection", "TRUE");
139 app_control_add_extra_data(control, "Connection", "FALSE");
141 ug_send_result(ugd->ug, control);
142 app_control_destroy(control);
145 ug_destroy_me(ugd->ug);
151 * This function let the ug call it when click 'back' button
153 * @param[in] data the pointer to the main data structure
154 * @param[in] obj the pointer to the evas object
155 * @param[in] event_info the pointer to the event information
157 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
160 struct ug_data *ugd = (struct ug_data *) data;
163 app_control_h control = NULL;
166 DBG(LOG_ERROR, "The param is NULL");
170 wfd_refresh_wifi_direct_state(ugd);
171 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
172 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
176 if (NULL != ugd->mac_addr_connecting) {
177 if (ugd->is_conn_incoming) {
178 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
179 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
180 if (ret != WIFI_DIRECT_ERROR_NONE)
181 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
183 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
184 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
185 if (ret != WIFI_DIRECT_ERROR_NONE)
186 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
188 ugd->mac_addr_connecting = NULL;
191 if (ugd->raw_connected_peer_cnt == 0) {
192 ret = wifi_direct_is_group_owner(&owner);
193 if (ret == WIFI_DIRECT_ERROR_NONE) {
195 wifi_direct_destroy_group();
200 wfd_ug_view_free_peers(ugd);
201 ret = app_control_create(&control);
203 DBG(LOG_ERROR, "Failed to create control");
205 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
206 app_control_add_extra_data(control, "Connection", "TRUE");
208 app_control_add_extra_data(control, "Connection", "FALSE");
210 ug_send_result(ugd->ug, control);
211 app_control_destroy(control);
214 ug_destroy_me(ugd->ug);
219 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
223 if (ugd->timer_stop_progress_bar > 0)
224 g_source_remove(ugd->timer_stop_progress_bar);
226 ugd->timer_stop_progress_bar = 0;
231 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
235 if (ugd->timer_delete_not_alive_peer > 0)
236 g_source_remove(ugd->timer_delete_not_alive_peer);
238 ugd->timer_delete_not_alive_peer = 0;
244 * This function let the ug call it when click failed devices item
246 * @param[in] data the pointer to the main data structure
247 * @param[in] obj the pointer to the evas object
248 * @param[in] event_info the pointer to the event information
250 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
254 struct ug_data *ugd = wfd_get_ug_data();
258 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
262 if (ugd->display_timer != NULL) {
263 ecore_timer_del(ugd->display_timer);
264 ugd->display_timer = NULL;
267 wfd_refresh_wifi_direct_state(ugd);
268 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
270 /* if connected, show the popup*/
271 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
272 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);
274 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
275 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
276 if (ret != WIFI_DIRECT_ERROR_NONE) {
277 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
278 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
279 wifi_direct_cancel_discovery();
288 * This function let the ug call it when click 'scan' button
290 * @param[in] data the pointer to the main data structure
291 * @param[in] obj the pointer to the evas object
292 * @param[in] event_info the pointer to the event information
294 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
298 struct ug_data *ugd = (struct ug_data *) data;
300 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
304 const char *btn_text = NULL;
305 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
306 DBG(LOG_INFO, "Button text=%s", btn_text);
308 if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
309 wfd_refresh_wifi_direct_state(ugd);
310 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
311 /* if connected, show the popup*/
312 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
313 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);
314 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
315 wfd_client_switch_on(ugd);
319 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
320 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
321 if (ret != WIFI_DIRECT_ERROR_NONE) {
322 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
323 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
324 wifi_direct_cancel_discovery();
327 } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
328 DBG(LOG_INFO, "Stop pressed.\n");
329 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
330 wfd_cancel_progressbar_stop_timer(ugd);
331 wfd_delete_progressbar_cb(ugd);
332 wfd_cancel_not_alive_delete_timer(ugd);
333 } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
334 DBG(LOG_INFO, "Cancel Connection");
335 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
337 DBG(LOG_INFO, "Invalid Case\n");
343 void wfd_check_gl_busy_peers(struct ug_data *ugd)
346 if (ugd->gl_busy_peer_cnt == 0)
347 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
352 void wfd_check_gl_available_peers(struct ug_data *ugd)
355 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL)
356 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
362 * This function let the ug free some peer in genlist
364 * @param[in] start_pos the start position of peers list
365 * @param[in] mac_addr the mac_addr of peer for free
366 * @param[in] cnt the count of gl peers in list
368 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
371 device_type_s *peer = *start_pos;
372 device_type_s *peer_tmp = peer;
375 DBG(LOG_INFO, "no peer in genlist");
380 if (strcmp(peer->mac_addr, mac_addr)) {
384 if (peer->next != NULL) {
385 peer_tmp->next = peer->next;
388 peer_tmp->next = NULL;
394 if (peer == *start_pos) {
395 DBG(LOG_INFO, "the head is free");
396 *start_pos = peer->next;
401 WFD_IF_DEL_ITEM(peer->gl_item);
409 * This function let the ug call it when click available peer to connect
411 * @param[in] data the pointer to the main data structure
412 * @param[in] obj the pointer to the evas object
413 * @param[in] event_info the pointer to the event information
415 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
420 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
421 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
422 bool is_peer_alive = false;
423 struct ug_data *ugd = wfd_get_ug_data();
424 device_type_s *peer = (device_type_s *)data;
425 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
426 char *format_str = NULL;
429 DBG(LOG_ERROR, "NULL parameters.\n");
433 wfd_ug_get_connected_peers(ugd);
434 DBG(LOG_INFO, "No of connected peers= %d", ugd->raw_connected_peer_cnt);
436 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
437 format_str = D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME");
438 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, format_str, MAX_CONNECTED_PEER_NUM);
439 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
441 elm_genlist_item_selected_set(item, EINA_FALSE);
446 if (ugd->disconnect_btn) {
447 Evas_Object *content;
448 content = elm_object_part_content_unset(ugd->button_layout, WFD_UG_NEXT_BUTTON_EDC_PART);
449 WFD_IF_DEL_OBJ(content);
450 ugd->disconnect_btn = NULL;
451 elm_layout_content_set(ugd->button_layout, WFD_UG_BIG_BUTTON_EDC_PART, ugd->scan_toolbar);
455 elm_genlist_item_selected_set(item, EINA_FALSE);
457 GList *iterator = NULL;
459 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
460 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
461 /* peer is found in last discovery */
462 is_peer_alive = true;
467 if (!is_peer_alive) {
468 /* peer exists only in genlist, waiting to be deleted */
469 device_type_s *peer_start = ugd->gl_avlb_peers_start;
470 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
471 if (!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
472 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
473 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
474 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
475 wfd_check_gl_available_peers(ugd);
476 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
482 wfd_cancel_not_alive_delete_timer(ugd);
485 wfd_refresh_wifi_direct_state(ugd);
487 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
488 peer->is_group_owner == TRUE) {
489 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
490 MAC2SECSTR(peer->mac_addr));
492 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
493 DBG(LOG_DEBUG, "It's in connecting status now.\n");
497 ugd->mac_addr_connecting = peer->mac_addr;
498 res = wfd_client_connect((const char *)peer->mac_addr);
500 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
510 * This function let the ug call it when click busy peer
512 * @param[in] data the pointer to the main data structure
513 * @param[in] obj the pointer to the evas object
514 * @param[in] event_info the pointer to the event information
516 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
519 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
520 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
523 elm_genlist_item_selected_set(item, EINA_FALSE);
526 DBG(LOG_ERROR, "Data is NULL\n");
530 wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
535 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
537 struct ug_data *ugd = (struct ug_data *) data;
540 DBG(LOG_ERROR, "The param is NULL\n");
545 evas_object_del(ugd->ctxpopup);
546 ugd->ctxpopup = NULL;
550 void _ctxpopup_move()
554 int win_w = 0, win_h = 0;
555 int move_x = 0, move_y = 0;
557 struct ug_data *ugd = wfd_get_ug_data();
559 if (!ugd || !ugd->win) {
560 DBG(LOG_ERROR, "NULL parameters.\n");
564 if (!ugd->ctxpopup) {
565 DBG(LOG_INFO, "NULL parameters.\n");
569 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
570 changed_ang = elm_win_rotation_get(ugd->win);
572 switch (changed_ang) {
595 evas_object_move(ugd->ctxpopup, move_x, move_y);
600 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
603 struct ug_data *ugd = (struct ug_data *) data;
604 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
605 WFD_IF_DEL_OBJ(ugd->ctxpopup);
608 wfd_client_free_raw_discovered_peers(ugd);
609 ugd->raw_discovered_peer_cnt = 0;
610 wfd_create_multiconnect_view(ugd);
611 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
612 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
613 if (ret != WIFI_DIRECT_ERROR_NONE) {
614 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
615 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
616 wifi_direct_cancel_discovery();
622 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
626 Evas_Object *naviframe = (Evas_Object *)data;
627 Elm_Object_Item *multi_connect_item = NULL;
628 Elm_Object_Item *rename_item = NULL;
629 struct ug_data *ugd = wfd_get_ug_data();
631 if (!naviframe || !ugd) {
632 DBG(LOG_ERROR, "NULL parameters.\n");
636 ugd->more_btn_multiconnect_item = NULL;
639 evas_object_del(ugd->ctxpopup);
641 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
642 elm_object_style_set(ugd->ctxpopup, "more/default");
643 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
644 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
645 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
646 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
648 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
649 ELM_CTXPOPUP_DIRECTION_LEFT,
650 ELM_CTXPOPUP_DIRECTION_RIGHT,
651 ELM_CTXPOPUP_DIRECTION_DOWN);
655 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
656 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
657 ugd->more_btn_multiconnect_item = multi_connect_item;
659 wfd_refresh_wifi_direct_state(ugd);
660 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
661 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
662 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
663 ugd->raw_connected_peer_cnt > 0) {
664 elm_object_item_disabled_set(multi_connect_item, TRUE);
667 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
668 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
669 evas_object_show(ugd->ctxpopup);
675 * This function make items into group
677 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
681 if (count < 1 || pre_item == NULL)
684 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
689 elm_object_item_signal_emit(item, "elm,state,normal", "");
693 for (i = 0; i < count; i++) {
695 elm_object_item_signal_emit(item, "elm,state,top", "");
696 else if (i == count - 1)
697 elm_object_item_signal_emit(item, "elm,state,bottom", "");
699 elm_object_item_signal_emit(item, "elm,state,center", "");
701 item = elm_genlist_item_next_get(item);
707 * This function let the ug call it when unresized event is received
709 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
712 struct ug_data *ugd = (struct ug_data *)data;
714 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
715 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
716 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
717 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
718 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
723 * This function let the ug call it when resized event is received
725 * @param[in] data the pointer to the main data structure
726 * @param[in] obj the pointer to the evas object
727 * @param[in] event_info the pointer to the event information
729 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
733 if (!data || !event_info) {
734 DBG(LOG_ERROR, "Invalid parameters");
738 struct ug_data *ugd = (struct ug_data *)data;
739 #ifdef ACCESSIBILITY_FEATURE
740 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
741 int index = elm_genlist_item_index_get(item);
745 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
746 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
747 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
748 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
749 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
751 #ifdef ACCESSIBILITY_FEATURE
753 if (GENLIST_HEADER_POS == index && item != NULL) {
754 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
756 Eina_Bool state = elm_check_state_get(check);
758 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
760 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
763 Evas_Object *ao = NULL;
764 ao = elm_object_item_access_object_get(item);
765 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
768 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
771 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
780 * This function let the ug call it when click 'disconnect' button
782 * @param[in] data the pointer to the main data structure
783 * @param[in] obj the pointer to the evas object
784 * @param[in] event_info the pointer to the event information
786 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
789 struct ug_data *ugd = (struct ug_data *)data;
790 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
792 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
798 * This function let the ug call it when click "cancel connection" button
800 * @param[in] data the pointer to the main data structure
801 * @param[in] obj the pointer to the evas object
802 * @param[in] event_info the pointer to the event information
804 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
807 struct ug_data *ugd = (struct ug_data *)data;
808 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
810 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
817 * This function let the ug update the genlist item
819 * @param[in] gl_item the pointer to genlist item
821 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
825 elm_genlist_item_update(gl_item);
831 * This function let the ug refresh the attributes of button
833 * @param[in] tb_item the pointer to the toolbar button
834 * @param[in] text the pointer to the text of button
835 * @param[in] enable whether the button is disabled
837 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
842 if (NULL == tb_item || NULL == text) {
843 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
847 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
848 elm_object_domain_translatable_part_text_set(tb_item, "default",
850 elm_object_disabled_set(tb_item, !enable);
856 * This function let the ug know whether current device is connected by me
857 * @return If connected, return TRUE, else return FALSE
858 * @param[in] ugd the pointer to the main data structure
859 * @param[in] dev the pointer to the device
861 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
866 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
867 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
868 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
878 * This function let the ug know whether current device is connected by other peer
879 * @return If connected, return TRUE, else return FALSE
880 * @param[in] ugd the pointer to the main data structure
881 * @param[in] dev the pointer to the device
883 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
887 if (ugd->I_am_group_owner == TRUE) {
888 if (dev->is_connected || dev->is_group_owner)
893 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE)
896 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE)
899 if (dev->is_connected == FALSE)
908 * This function let the ug calculate how many devices are available
910 * @param[in] ugd the pointer to the main data structure
911 * @param[in] dev the pointer to the number of available devices
913 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
916 GList *iterator = NULL;
918 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
919 /* Not include the device which is connected with me */
920 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
923 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
924 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT)
925 (*no_of_available_dev)++;
933 * This function let the ug calculate how many devices are busy
935 * @param[in] ugd the pointer to the main data structure
936 * @param[in] dev the pointer to the number of busy devices
938 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
941 GList *iterator = NULL;
943 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
944 /* Not include the device which is connected with me */
945 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
948 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data))
957 * This function let the ug calculate how many devices are connected failed
959 * @param[in] ugd the pointer to the main data structure
960 * @param[in] dev the pointer to the number of connected failed devices
962 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
965 GList *iterator = NULL;
967 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
968 /* Not include the device which is connected with me */
969 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
972 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
973 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
974 (*no_of_connect_failed_dev)++;
983 * This function let the ug create the main genlist
984 * @return the main genlist
985 * @param[in] data the pointer to the main data structure
987 static Evas_Object *_create_basic_genlist(void *data)
990 struct ug_data *ugd = (struct ug_data *) data;
991 Evas_Object *genlist;
993 genlist = elm_genlist_add(ugd->layout);
995 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
996 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
998 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1000 /* Wifi ON/OFF toggle button */
1001 #ifdef WFD_ON_OFF_GENLIST
1002 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
1003 NULL, ELM_GENLIST_ITEM_NONE, _onoff_changed_cb, ugd);
1004 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1007 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
1008 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
1009 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
1010 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1011 if (ugd->device_name_item != NULL)
1012 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1019 * This function let the ug create no device item to append the genlist
1020 * @return the main item
1021 * @param[in] data the pointer to the main data structure
1023 Evas_Object *_create_no_device_genlist(void *data)
1026 struct ug_data *ugd = (struct ug_data *) data;
1027 Elm_Object_Item *last_item = NULL;
1030 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1032 if (ugd->conn_wfd_item != NULL) {
1033 last_item = ugd->conn_wfd_item;
1034 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1035 last_item = elm_genlist_item_next_get(last_item);
1038 last_item = ugd->device_name_item;
1041 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1042 &title_no_device_itc, (void *)ugd, NULL, last_item,
1043 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1044 if (ugd->nodevice_title_item != NULL)
1045 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1047 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1048 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1049 if (ugd->nodevice_item != NULL)
1050 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1053 return ugd->genlist;
1057 * This function let the ug create busy device list
1059 * @param[in] data the pointer to the main data structure
1061 int _create_busy_dev_list(void *data)
1064 struct ug_data *ugd = (struct ug_data *) data;
1066 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1067 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1068 if (ugd->busy_wfd_item != NULL)
1069 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1074 void wfd_free_nodivice_item(struct ug_data *ugd)
1077 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1078 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1083 * This function let the ug create available device list
1085 * @param[in] data the pointer to the main data structure
1087 int _create_available_dev_genlist(void *data)
1091 struct ug_data *ugd = (struct ug_data *) data;
1092 Elm_Object_Item *last_item = NULL;
1094 wfd_free_nodivice_item(ugd);
1096 if (ugd->conn_wfd_item != NULL) {
1097 last_item = ugd->conn_wfd_item;
1098 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1099 last_item = elm_genlist_item_next_get(last_item);
1102 last_item = ugd->device_name_item;
1105 ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1106 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1107 if (ugd->avlbl_wfd_item != NULL) {
1108 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1109 elm_genlist_item_update(ugd->avlbl_wfd_item);
1116 * This function let the ug create multi connect device list
1118 * @param[in] data the pointer to the main data structure
1120 static int _create_multi_connect_dev_genlist(void *data)
1123 struct ug_data *ugd = (struct ug_data *) data;
1125 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1126 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1127 if (ugd->multi_connect_wfd_item != NULL)
1128 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1134 * This function let the ug create connected device list
1136 * @param[in] data the pointer to the main data structure
1138 int _create_connected_dev_genlist(void *data)
1141 struct ug_data *ugd = (struct ug_data *) data;
1143 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1144 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1145 if (ugd->conn_wfd_item != NULL) {
1146 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1147 elm_genlist_item_update(ugd->conn_wfd_item);
1155 * This function let the ug create connected falied device list
1157 * @param[in] data the pointer to the main data structure
1159 int _create_connected_failed_dev_genlist(void *data)
1162 struct ug_data *ugd = (struct ug_data *) data;
1163 Elm_Object_Item *last_item = NULL;
1166 if (ugd->avlbl_wfd_item != NULL) {
1167 last_item = ugd->avlbl_wfd_item;
1168 for (i = 0; i < ugd->gl_available_peer_cnt; i++)
1169 last_item = elm_genlist_item_next_get(last_item);
1171 } else if (ugd->conn_wfd_item != NULL) {
1172 last_item = ugd->conn_wfd_item;
1173 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1174 last_item = elm_genlist_item_next_get(last_item);
1177 last_item = ugd->device_name_item;
1180 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1181 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1182 if (ugd->conn_failed_wfd_item != NULL)
1183 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1189 * This function let the ug make the display callback for connect failed peers
1190 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1191 * @param[in] data the pointer to the user data
1193 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1198 struct ug_data *ugd = (struct ug_data *) user_data;
1201 DBG(LOG_ERROR, "NULL parameters.\n");
1202 return ECORE_CALLBACK_CANCEL;
1205 if (ugd->avlbl_wfd_item == NULL)
1206 _create_available_dev_genlist(ugd);
1208 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1209 DBG(LOG_INFO, "Background mode\n");
1210 ugd->display_timer = NULL;
1211 return ECORE_CALLBACK_CANCEL;
1214 /* check the timeout, if not timeout, keep the cb */
1215 interval = time(NULL) - ugd->last_display_time;
1216 if (interval < MAX_DISPLAY_TIME_OUT)
1217 return ECORE_CALLBACK_RENEW;
1219 if (ugd->is_paused == false) {
1220 DBG(LOG_INFO, "Not Paused");
1221 /* start discovery again */
1222 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1223 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1224 if (res != WIFI_DIRECT_ERROR_NONE) {
1225 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1226 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1227 wifi_direct_cancel_discovery();
1231 ugd->display_timer = NULL;
1233 return ECORE_CALLBACK_CANCEL;
1236 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1239 device_type_s *peer_for_free = NULL;
1240 device_type_s *peer = gl_peers_start;
1242 while (peer != NULL && peer->gl_item != NULL) {
1243 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1244 elm_object_item_del(peer->gl_item);
1245 peer->gl_item = NULL;
1246 peer_for_free = peer;
1248 free(peer_for_free);
1253 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1256 if (ugd->gl_connected_peer_cnt == 0)
1257 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1263 * This function let the ug free the peers
1265 * @param[in] data the pointer to the main data structure
1267 void wfd_ug_view_free_peers(void *data)
1271 struct ug_data *ugd = (struct ug_data *) data;
1273 ugd->gl_connected_peer_cnt = 0;
1275 if (ugd->gl_conn_peers_start != NULL) {
1276 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1277 ugd->gl_conn_peers_start = NULL;
1280 ugd->gl_available_peer_cnt = 0;
1282 if (ugd->gl_avlb_peers_start != NULL) {
1283 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1284 ugd->gl_avlb_peers_start = NULL;
1287 ugd->gl_busy_peer_cnt = 0;
1289 if (ugd->gl_busy_peers_start != NULL) {
1290 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1291 ugd->gl_busy_peers_start = NULL;
1294 ugd->gl_multi_connect_peer_cnt = 0;
1296 if (ugd->gl_mul_conn_peers_start != NULL) {
1297 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1298 ugd->gl_mul_conn_peers_start = NULL;
1301 if (ugd->gl_connected_peer_cnt == 0)
1302 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1304 if (ugd->display_timer != NULL) {
1305 ecore_timer_del(ugd->display_timer);
1306 ugd->display_timer = NULL;
1309 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1310 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1311 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1312 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1317 void wfd_ug_update_toolbar(struct ug_data *ugd)
1320 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1323 wfd_refresh_wifi_direct_state(ugd);
1324 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1325 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1326 if (ugd->multi_connect_wfd_item != NULL) {
1327 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1328 btn = elm_button_add(ugd->button_layout);
1329 /* Use "bottom" style button */
1330 elm_object_style_set(btn, "bottom");
1331 elm_object_domain_translatable_text_set(btn, PACKAGE,
1332 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1333 evas_object_smart_callback_add(btn, "clicked",
1334 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1335 /* Set button into "toolbar" swallow part */
1336 elm_object_part_content_set(ugd->button_layout, WFD_UG_NEXT_BUTTON_EDC_PART, btn);
1337 ugd->disconnect_btn = btn;
1338 evas_object_show(ugd->disconnect_btn);
1339 elm_object_part_content_set(ugd->button_layout, WFD_UG_PREV_BUTTON_EDC_PART,
1341 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1342 "IDS_WIFI_SK4_SCAN", FALSE);
1343 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1344 DBG(LOG_INFO, "button: disconnect button added\n");
1346 DBG(LOG_INFO, "scan_toolbar\n");
1347 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1348 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1349 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1350 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1351 DBG(LOG_INFO, "button: stop connect button added\n");
1353 } else if (no_of_conn_dev > 0) {
1354 if (!ugd->multi_connect_toolbar_item) {
1355 btn = elm_button_add(ugd->button_layout);
1356 /* Use "bottom" style button */
1357 elm_object_style_set(btn, "bottom");
1358 elm_object_domain_translatable_text_set(btn, PACKAGE,
1359 "IDS_WIFI_SK_DISCONNECT");
1360 evas_object_smart_callback_add(btn, "clicked",
1361 _wfd_ug_disconnect_button_cb, (void *)ugd);
1362 /* Set button into "toolbar" swallow part */
1363 elm_object_part_content_set(ugd->button_layout, WFD_UG_NEXT_BUTTON_EDC_PART, btn);
1364 ugd->disconnect_btn = btn;
1365 evas_object_show(ugd->disconnect_btn);
1366 DBG(LOG_INFO, "button: disconnect button added\n");
1368 elm_object_part_content_set(ugd->button_layout, WFD_UG_PREV_BUTTON_EDC_PART,
1370 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1371 "IDS_WIFI_SK4_SCAN", TRUE);
1372 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1373 DBG(LOG_INFO, "button: scan button added\n");
1375 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1376 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1377 Evas_Object *content;
1378 content = elm_object_part_content_unset(ugd->button_layout, WFD_UG_NEXT_BUTTON_EDC_PART);
1379 WFD_IF_DEL_OBJ(content);
1380 ugd->disconnect_btn = NULL;
1381 elm_layout_content_set(ugd->button_layout, WFD_UG_BIG_BUTTON_EDC_PART, ugd->scan_toolbar);
1383 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1384 "IDS_WIFI_SK4_SCAN", TRUE);
1385 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1386 DBG(LOG_INFO, "button: scan button added\n");
1392 * This function let the ug init the genlist
1394 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1397 struct ug_data *ugd = (struct ug_data *) data;
1398 int no_of_busy_dev = 0;
1399 int no_of_available_dev = 0;
1400 int no_of_conn_failed_dev = 0;
1402 if (is_free_all_peers)
1403 wfd_ug_view_free_peers(ugd);
1405 if (ugd->gl_failed_peers_start != NULL) {
1406 DBG(LOG_INFO, "These are failed peers, must clear them");
1407 ugd->gl_connected_failed_peer_cnt = 0;
1408 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1409 ugd->gl_failed_peers_start = NULL;
1410 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1413 if (ugd->avlbl_wfd_item != NULL) {
1414 DBG(LOG_INFO, "There are available peers in genlist");
1415 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1419 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1420 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1421 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1427 * This function let the ug find a peer in genlist
1429 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1433 if (start_pos == NULL) {
1434 DBG(LOG_INFO, "no peer in genlist");
1438 device_type_s *peer = start_pos;
1440 while (peer != NULL) {
1441 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1442 peer->is_alive = true;
1443 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1454 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1457 if (*start_pos == NULL) {
1458 DBG(LOG_INFO, "no peer in genlist");
1462 device_type_s *peer = *start_pos;
1463 device_type_s *peer_tmp = NULL;
1464 while (peer != NULL) {
1465 peer_tmp = peer->next;
1466 if (peer->is_alive == false)
1467 free_gl_peer(start_pos, peer->mac_addr, cnt);
1472 // wfd_check_gl_available_peers(ugd);
1473 if (ugd->gl_busy_peer_cnt == 0)
1474 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1480 void set_not_alive_peers(device_type_s *start_pos)
1483 if (start_pos == NULL) {
1484 DBG(LOG_INFO, "no peer in genlist");
1488 device_type_s *peer = start_pos;
1489 while (peer != NULL) {
1490 peer->is_alive = false;
1499 * This function let the ug get the insert position for next item
1501 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1505 device_type_s *peer_ite = NULL;
1506 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1507 Elm_Object_Item *item = NULL;
1509 if (peer_cnt == 0) {
1510 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1514 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1515 if (peer_ite->gl_item != NULL) {
1516 for (i = 0; i < peer_cnt; i++) {
1517 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1518 /* if peer_ite is greater than peer, return previous item */
1520 return elm_genlist_item_prev_get(head);
1522 item = elm_genlist_item_next_get(head);
1524 /* return the last item */
1528 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1534 return elm_genlist_item_prev_get(head);
1538 * This function let the ug insert peer item to genlist
1540 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1541 device_type_s *peer_for_insert, void *callback)
1544 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1545 device_type_s *peer = NULL;
1546 device_type_s *peer_ite = NULL;
1548 peer = (device_type_s *)malloc(sizeof(device_type_s));
1549 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1551 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1554 if (*start_pos == NULL) {
1557 peer_ite = *start_pos;
1558 while (peer_ite->next != NULL) {
1559 /* move pointer to the last peer */
1560 peer_ite = peer_ite->next;
1562 peer_ite->next = peer;
1565 peer->is_alive = true;
1566 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1567 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1568 if (callback == NULL && peer->gl_item != NULL)
1569 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1576 * This function let the ug update connected peers
1578 * @param[in] data the pointer to the main data structure
1580 void wfd_ug_update_connected_peers(void *data)
1584 struct ug_data *ugd = (struct ug_data *) data;
1587 bool is_group_owner = FALSE;
1588 Elm_Object_Item *item = NULL;
1590 res = wifi_direct_is_group_owner(&is_group_owner);
1591 if (res == WIFI_DIRECT_ERROR_NONE)
1592 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1594 if (!ugd->conn_wfd_item)
1595 _create_connected_dev_genlist(ugd);
1597 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1598 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1599 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1600 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1601 &ugd->gl_available_peer_cnt);
1602 wfd_check_gl_available_peers(ugd);
1605 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1606 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1607 &ugd->gl_multi_connect_peer_cnt);
1608 if (ugd->gl_multi_connect_peer_cnt == 0) {
1609 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1610 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1614 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1615 ugd->gl_connected_peer_cnt);
1616 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1617 &ugd->raw_connected_peers[i], NULL);
1621 ugd->gl_connected_peer_cnt++;
1625 /* if is not GO, free all available peers */
1626 if (is_group_owner == FALSE) {
1627 ugd->gl_available_peer_cnt = 0;
1628 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1630 if (ugd->gl_avlb_peers_start != NULL) {
1631 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1632 ugd->gl_avlb_peers_start = NULL;
1636 /* free busy peers */
1637 if (ugd->gl_busy_peers_start != NULL) {
1638 ugd->gl_busy_peer_cnt = 0;
1639 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1641 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1642 ugd->gl_busy_peers_start = NULL;
1650 * This function let the ug update the multi-connect peers
1652 * @param[in] data the pointer to the main data structure
1654 void wfd_ug_view_update_multiconn_peers(void *data)
1658 struct ug_data *ugd = (struct ug_data *) data;
1661 Elm_Object_Item *item = NULL;
1663 if (ugd->raw_multi_selected_peer_cnt > 0) {
1664 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1665 ugd->multi_connect_wfd_item == NULL) {
1666 _create_multi_connect_dev_genlist(ugd);
1669 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1670 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1671 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1672 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1673 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1674 &ugd->raw_multi_selected_peers[i], NULL);
1678 ugd->gl_multi_connect_peer_cnt++;
1687 * This function let the ug update the available and busy peers
1689 void wfd_ug_update_available_peers(void *data)
1693 struct ug_data *ugd = (struct ug_data *) data;
1694 int no_of_busy_dev = 0;
1695 int no_of_available_dev = 0;
1696 int no_of_conn_dev = 0;
1697 bool is_group_owner = FALSE;
1699 Elm_Object_Item *item = NULL;
1700 device_type_s *peer = NULL;
1701 GList *iterator = NULL;
1703 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1704 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1705 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1707 res = wifi_direct_is_group_owner(&is_group_owner);
1708 if (res != WIFI_DIRECT_ERROR_NONE) {
1709 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1710 ugd->I_am_group_owner = FALSE;
1712 ugd->I_am_group_owner = is_group_owner;
1715 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1716 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1717 DBG(LOG_INFO, "There are available or busy peers\n");
1718 wfd_free_nodivice_item(ugd);
1721 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1722 if (ugd->avlbl_wfd_item == NULL)
1723 _create_available_dev_genlist(ugd);
1726 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1727 /* Not include the device which is connected with me */
1728 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1731 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1732 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1733 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1734 /* free disconnected gl peer */
1735 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1736 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1737 &ugd->gl_connected_peer_cnt);
1740 /* free busy gl peer, which is available now */
1741 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1742 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1743 if (ugd->gl_busy_peer_cnt == 0)
1744 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1747 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL)
1750 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1752 item = get_insert_postion((device_type_s *)iterator->data,
1753 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1754 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1755 (device_type_s *)iterator->data, _gl_peer_sel);
1759 ugd->gl_available_peer_cnt++;
1760 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1761 /* if peer is GO, free it */
1762 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1763 &ugd->gl_available_peer_cnt);
1769 wfd_check_gl_available_peers(ugd);
1770 wfd_check_gl_conn_peers(ugd);
1772 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1773 if (ugd->busy_wfd_item == NULL)
1774 _create_busy_dev_list(ugd);
1776 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1777 /* Not include the device which is connected with me */
1778 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1781 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1782 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1783 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1784 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1785 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1786 &ugd->gl_available_peer_cnt);
1787 wfd_check_gl_available_peers(ugd);
1789 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1790 ugd->gl_busy_peer_cnt);
1791 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1792 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1796 ugd->gl_busy_peer_cnt++;
1802 wfd_check_gl_busy_peers(ugd);
1808 * This function let the ug update the failed peers
1810 * @param[in] data the pointer to the main data structure
1812 void wfd_ug_update_failed_peers(void *data)
1815 struct ug_data *ugd = (struct ug_data *) data;
1816 int no_of_conn_failed_dev = 0;
1817 GList *iterator = NULL;
1819 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1820 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1822 if (no_of_conn_failed_dev == 0)
1825 /* add timer for disappearing failed peers after N secs */
1826 if (NULL == ugd->display_timer) {
1827 ugd->last_display_time = time(NULL);
1828 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1831 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1832 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1833 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1834 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1835 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1836 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1837 &ugd->gl_available_peer_cnt);
1838 wfd_check_gl_available_peers(ugd);
1847 #ifdef WFD_ON_OFF_GENLIST
1849 * This function is called when user swipes on/off button
1851 * @param[in] data the pointer to the main data structure
1852 * @param[in] obj the pointer to the evas object
1853 * @param[in] event_info the pointer to the event information
1855 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1858 struct ug_data *ugd = (struct ug_data *)data;
1859 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1860 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1861 wfd_refresh_wifi_direct_state(ugd);
1862 if (ugd->device_name_item != NULL)
1863 elm_genlist_item_update(ugd->device_name_item);
1865 elm_object_disabled_set(ugd->on_off_check, TRUE);
1866 if (ugd->disconnect_btn) {
1867 Evas_Object *content;
1868 content = elm_object_part_content_unset(ugd->button_layout, WFD_UG_NEXT_BUTTON_EDC_PART);
1869 WFD_IF_DEL_OBJ(content);
1870 ugd->disconnect_btn = NULL;
1872 elm_layout_content_set(ugd->button_layout, WFD_UG_BIG_BUTTON_EDC_PART, ugd->scan_toolbar);
1874 /* turn on/off wfd */
1875 if (!ugd->wfd_onoff) {
1876 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1877 DBG(LOG_INFO, "wifi-direct switch on\n");
1878 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1880 wfd_client_switch_on(ugd);
1883 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1884 DBG(LOG_INFO, "wifi-direct switch off\n");
1885 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1887 wfd_client_switch_off(ugd);
1894 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1897 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1898 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1900 wfd_refresh_wifi_direct_state(ugd);
1901 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1902 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING)
1903 elm_object_disabled_set(ugd->on_off_check, TRUE);
1905 elm_object_disabled_set(ugd->on_off_check, FALSE);
1907 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
1908 elm_check_state_set(ugd->on_off_check, TRUE);
1910 elm_check_state_set(ugd->on_off_check, FALSE);
1915 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1918 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1919 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1921 Evas_Object *check = elm_check_add(ugd->naviframe);
1922 elm_object_style_set(check, "naviframe/title_on&off");
1923 elm_check_state_set(check, ugd->wfd_onoff);
1924 evas_object_propagate_events_set(check, EINA_FALSE);
1925 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1926 elm_object_focus_allow_set(check, EINA_TRUE);
1927 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1928 evas_object_show(check);
1929 ugd->on_off_check = check;
1936 * This function let the ug create the main view
1938 * @param[in] data the pointer to the main data structure
1940 void create_wfd_ug_view(void *data)
1943 struct ug_data *ugd = (struct ug_data *) data;
1944 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1945 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1946 Evas_Object *more_btn;
1948 Evas_Object *layout;
1950 ugd->naviframe = elm_naviframe_add(ugd->base);
1951 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1952 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1953 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1954 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1956 ugd->back_btn = elm_button_add(ugd->naviframe);
1957 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1958 evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1959 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1962 layout = elm_layout_add(ugd->naviframe);
1963 elm_layout_theme_set(layout, "layout", "application", "default");
1964 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1965 ugd->layout = layout;
1967 ugd->genlist = _create_basic_genlist(ugd);
1968 if (ugd->genlist == NULL) {
1969 DBG(LOG_ERROR, "Failed to create basic genlist");
1972 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1974 evas_object_show(ugd->base);
1975 elm_object_focus_set(ugd->base, EINA_TRUE);
1977 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1978 ugd->back_btn, NULL, layout, NULL);
1979 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1981 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1982 more_btn = elm_button_add(ugd->naviframe);
1983 elm_object_style_set(more_btn, "naviframe/more/default");
1984 evas_object_smart_callback_add(more_btn, "clicked",
1985 _more_button_cb, ugd->win);
1986 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1990 wifi_direct_initialize();
1991 wifi_direct_get_state(&ugd->wfd_status);
1992 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING)
1993 scan_button_create(ugd);
1995 if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1997 ugd->raw_discovered_peer_cnt = 0;
1998 wfd_create_multiconnect_view(ugd);
1999 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
2000 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
2001 if (ret != WIFI_DIRECT_ERROR_NONE) {
2002 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
2003 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
2004 wifi_direct_cancel_discovery();
2013 * This function let the ug destroy the main view
2015 * @param[in] data the pointer to the main data structure
2017 void destroy_wfd_ug_view(void *data)
2020 struct ug_data *ugd = (struct ug_data *) data;
2021 WFD_IF_DEL_ITEM(ugd->device_name_item);
2022 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2023 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2025 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2026 WFD_IF_DEL_OBJ(ugd->back_btn);
2027 WFD_IF_DEL_OBJ(ugd->toolbar);
2028 WFD_IF_DEL_OBJ(ugd->genlist);
2029 WFD_IF_DEL_OBJ(ugd->button_layout);
2030 WFD_IF_DEL_OBJ(ugd->layout);
2031 WFD_IF_DEL_OBJ(ugd->naviframe);