4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.0 (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 #ifdef WFD_DBUS_LAUNCH
79 if (ugd->dbus_cancellable != NULL) {
80 g_cancellable_cancel(ugd->dbus_cancellable);
81 g_object_unref(ugd->dbus_cancellable);
82 ugd->dbus_cancellable = NULL;
84 g_object_unref(ugd->conn);
87 DBG(LOG_INFO, "Cancel dbus call");
91 wfd_refresh_wifi_direct_state(ugd);
92 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
93 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
97 if (NULL != ugd->mac_addr_connecting) {
98 if (ugd->is_conn_incoming) {
99 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
100 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
101 if (ret != WIFI_DIRECT_ERROR_NONE) {
102 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
105 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
106 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
107 if (ret != WIFI_DIRECT_ERROR_NONE) {
108 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
111 ugd->mac_addr_connecting = NULL;
114 if (ugd->raw_connected_peer_cnt == 0) {
115 ret = wifi_direct_is_group_owner(&owner);
116 if (ret == WIFI_DIRECT_ERROR_NONE) {
118 wifi_direct_destroy_group();
124 wfd_ug_view_free_peers(ugd);
125 ret = app_control_create(&control);
127 DBG(LOG_ERROR, "Failed to create control");
129 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) {
130 app_control_add_extra_data(control, "Connection", "TRUE");
132 app_control_add_extra_data(control, "Connection", "FALSE");
135 ug_send_result(ugd->ug, control);
136 app_control_destroy(control);
139 ug_destroy_me(ugd->ug);
144 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
148 if(ugd->timer_stop_progress_bar > 0) {
149 g_source_remove(ugd->timer_stop_progress_bar);
151 ugd->timer_stop_progress_bar = 0;
156 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
160 if(ugd->timer_delete_not_alive_peer > 0) {
161 g_source_remove(ugd->timer_delete_not_alive_peer);
163 ugd->timer_delete_not_alive_peer = 0;
169 * This function let the ug call it when click failed devices item
171 * @param[in] data the pointer to the main data structure
172 * @param[in] obj the pointer to the evas object
173 * @param[in] event_info the pointer to the event information
175 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
179 struct ug_data *ugd = wfd_get_ug_data();
183 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
187 if (ugd->display_timer != NULL) {
188 ecore_timer_del(ugd->display_timer);
189 ugd->display_timer = NULL;
192 wfd_refresh_wifi_direct_state(ugd);
193 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
195 /* if connected, show the popup*/
196 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
197 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
199 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
200 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
201 if (ret != WIFI_DIRECT_ERROR_NONE) {
202 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
203 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
204 wifi_direct_cancel_discovery();
213 * This function let the ug call it when click 'scan' button
215 * @param[in] data the pointer to the main data structure
216 * @param[in] obj the pointer to the evas object
217 * @param[in] event_info the pointer to the event information
219 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
223 struct ug_data *ugd = (struct ug_data *) data;
225 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
229 const char *btn_text = NULL;
230 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
231 DBG(LOG_INFO, "Button text=%s",btn_text);
233 if (!g_strcmp0(elm_object_text_get(obj), _("IDS_WIFI_SK4_SCAN"))) {
234 wfd_refresh_wifi_direct_state(ugd);
235 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
236 /* if connected, show the popup*/
237 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
238 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
239 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
240 wfd_client_switch_on(ugd);
244 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
245 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
246 if (ret != WIFI_DIRECT_ERROR_NONE) {
247 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
248 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
249 wifi_direct_cancel_discovery();
252 } else if (!g_strcmp0(elm_object_text_get(obj), _("IDS_WIFI_SK_STOP"))) {
253 DBG(LOG_INFO, "Stop pressed.\n");
254 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
255 wfd_cancel_progressbar_stop_timer(ugd);
256 wfd_delete_progressbar_cb(ugd);
257 wfd_cancel_not_alive_delete_timer(ugd);
258 } else if (0 == strcmp(_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
259 DBG(LOG_INFO, "Cancel Connection");
260 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
262 DBG(LOG_INFO, "Invalid Case\n");
268 void wfd_check_gl_busy_peers(struct ug_data *ugd)
271 if (ugd->gl_busy_peer_cnt == 0) {
272 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
277 void wfd_check_gl_available_peers(struct ug_data *ugd)
280 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL) {
281 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
287 * This function let the ug free some peer in genlist
289 * @param[in] start_pos the start position of peers list
290 * @param[in] mac_addr the mac_addr of peer for free
291 * @param[in] cnt the count of gl peers in list
293 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
296 device_type_s *peer = *start_pos;
297 device_type_s *peer_tmp = peer;
300 DBG(LOG_INFO, "no peer in genlist");
305 if(strcmp(peer->mac_addr, mac_addr)) {
309 if(peer->next != NULL) {
310 peer_tmp->next = peer->next;
313 peer_tmp->next = NULL;
319 if (peer == *start_pos) {
320 DBG(LOG_INFO, "the head is free");
321 *start_pos = peer->next;
326 WFD_IF_DEL_ITEM(peer->gl_item);
334 * This function let the ug call it when click avaliable peer to connect
336 * @param[in] data the pointer to the main data structure
337 * @param[in] obj the pointer to the evas object
338 * @param[in] event_info the pointer to the event information
340 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
345 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
346 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
347 bool is_peer_alive = false;
348 struct ug_data *ugd = wfd_get_ug_data();
349 device_type_s *peer = (device_type_s *)data;
350 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
353 DBG(LOG_ERROR, "NULL parameters.\n");
357 wfd_ug_get_connected_peers(ugd);
358 DBG(LOG_INFO, "No of connected peers= %d",ugd->raw_connected_peer_cnt);
360 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
361 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, _("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME"), MAX_CONNECTED_PEER_NUM);
362 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
364 elm_genlist_item_selected_set(item, EINA_FALSE);
369 if (ugd->disconnect_btn) {
370 Evas_Object *content;
371 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
372 WFD_IF_DEL_OBJ(content);
373 ugd->disconnect_btn = NULL;
374 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
378 elm_genlist_item_selected_set(item, EINA_FALSE);
381 GList *iterator = NULL;
383 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
384 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
385 /* peer is found in last discovery */
386 is_peer_alive = true;
391 if (!is_peer_alive) {
392 /* peer exists only in genlist, waiting to be deleted */
393 device_type_s *peer_start = ugd->gl_avlb_peers_start;
394 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
395 if(!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
396 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
397 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
398 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
399 wfd_check_gl_available_peers(ugd);
400 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
406 wfd_cancel_not_alive_delete_timer(ugd);
409 wfd_refresh_wifi_direct_state(ugd);
411 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
412 peer->is_group_owner == TRUE) {
413 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
414 MAC2SECSTR(peer->mac_addr));
416 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
417 DBG(LOG_DEBUG, "It's in connecting status now.\n");
421 ugd->mac_addr_connecting = peer->mac_addr;
422 res = wfd_client_connect((const char *)peer->mac_addr);
424 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
434 * This function let the ug call it when click busy peer
436 * @param[in] data the pointer to the main data structure
437 * @param[in] obj the pointer to the evas object
438 * @param[in] event_info the pointer to the event information
440 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
443 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
444 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
447 elm_genlist_item_selected_set(item, EINA_FALSE);
451 DBG(LOG_ERROR, "Data is NULL\n");
455 wfd_ug_warn_popup(ugd, _("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
460 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
462 struct ug_data *ugd = (struct ug_data *) data;
465 DBG(LOG_ERROR, "The param is NULL\n");
470 evas_object_del(ugd->ctxpopup);
471 ugd->ctxpopup = NULL;
475 void _ctxpopup_move()
479 int win_w = 0, win_h = 0;
480 int move_x = 0, move_y = 0;
482 struct ug_data *ugd = wfd_get_ug_data();
484 if (!ugd || !ugd->win) {
485 DBG(LOG_ERROR, "NULL parameters.\n");
489 if (!ugd->ctxpopup) {
490 DBG(LOG_INFO, "NULL parameters.\n");
494 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
495 changed_ang = elm_win_rotation_get(ugd->win);
497 switch (changed_ang) {
520 evas_object_move(ugd->ctxpopup, move_x, move_y);
525 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
528 struct ug_data *ugd = (struct ug_data *) data;
529 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
530 WFD_IF_DEL_OBJ(ugd->ctxpopup);
533 wfd_client_free_raw_discovered_peers(ugd);
534 ugd->raw_discovered_peer_cnt = 0;
535 wfd_create_multiconnect_view(ugd);
536 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
537 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
538 if (ret != WIFI_DIRECT_ERROR_NONE) {
539 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
540 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
541 wifi_direct_cancel_discovery();
547 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
551 Evas_Object *naviframe = (Evas_Object *)data;
552 Elm_Object_Item *multi_connect_item = NULL;
553 Elm_Object_Item *rename_item = NULL;
554 struct ug_data *ugd = wfd_get_ug_data();
556 if (!naviframe || !ugd) {
557 DBG(LOG_ERROR, "NULL parameters.\n");
561 ugd->more_btn_multiconnect_item = NULL;
564 evas_object_del(ugd->ctxpopup);
567 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
568 elm_object_style_set(ugd->ctxpopup, "more/default");
569 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
570 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
571 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
572 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
574 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
575 ELM_CTXPOPUP_DIRECTION_LEFT,
576 ELM_CTXPOPUP_DIRECTION_RIGHT,
577 ELM_CTXPOPUP_DIRECTION_DOWN);
581 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
582 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
583 ugd->more_btn_multiconnect_item = multi_connect_item;
585 wfd_refresh_wifi_direct_state(ugd);
586 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
587 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
588 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
589 ugd->raw_connected_peer_cnt > 0) {
590 elm_object_item_disabled_set(multi_connect_item, TRUE);
593 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
594 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
595 evas_object_show(ugd->ctxpopup);
601 * This function make items into group
603 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
607 if (count < 1 || pre_item == NULL) {
611 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
617 elm_object_item_signal_emit(item, "elm,state,normal", "");
621 for (i = 0; i < count; i++) {
623 elm_object_item_signal_emit(item, "elm,state,top", "");
624 } else if (i == count - 1) {
625 elm_object_item_signal_emit(item, "elm,state,bottom", "");
627 elm_object_item_signal_emit(item, "elm,state,center", "");
630 item = elm_genlist_item_next_get(item);
636 * This function let the ug call it when unresized event is received
638 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
641 struct ug_data *ugd = (struct ug_data *)data;
643 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
644 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
645 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
646 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
647 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
652 * This function let the ug call it when resized event is received
654 * @param[in] data the pointer to the main data structure
655 * @param[in] obj the pointer to the evas object
656 * @param[in] event_info the pointer to the event information
658 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
662 if (!data || !event_info) {
663 DBG(LOG_ERROR, "Invalid parameters");
667 struct ug_data *ugd = (struct ug_data *)data;
668 #ifdef ACCESSIBILITY_FEATURE
669 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
670 int index = elm_genlist_item_index_get(item);
674 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
675 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
676 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
677 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
678 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
680 #ifdef ACCESSIBILITY_FEATURE
682 if (GENLIST_HEADER_POS == index && item != NULL) {
683 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
685 Eina_Bool state = elm_check_state_get(check);
687 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
689 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
693 Evas_Object *ao = NULL;
694 ao = elm_object_item_access_object_get(item);
695 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
698 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
701 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
710 * This function let the ug call it when click 'disconnect' button
712 * @param[in] data the pointer to the main data structure
713 * @param[in] obj the pointer to the evas object
714 * @param[in] event_info the pointer to the event information
716 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
719 struct ug_data *ugd = (struct ug_data *)data;
720 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
722 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
728 * This function let the ug call it when click "cancel connection" button
730 * @param[in] data the pointer to the main data structure
731 * @param[in] obj the pointer to the evas object
732 * @param[in] event_info the pointer to the event information
734 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
737 struct ug_data *ugd = (struct ug_data *)data;
738 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
740 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
747 * This function let the ug update the genlist item
749 * @param[in] gl_item the pointer to genlist item
751 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
754 if (gl_item != NULL) {
755 elm_genlist_item_update(gl_item);
761 * This function let the ug refresh the attributes of button
763 * @param[in] tb_item the pointer to the toolbar button
764 * @param[in] text the pointer to the text of button
765 * @param[in] enable whether the button is disabled
767 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
772 if (NULL == tb_item || NULL == text) {
773 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
777 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
778 elm_object_domain_translatable_part_text_set(tb_item, "default",
780 elm_object_disabled_set(tb_item, !enable);
786 * This function let the ug know whether current device is connected by me
787 * @return If connected, return TRUE, else return FALSE
788 * @param[in] ugd the pointer to the main data structure
789 * @param[in] dev the pointer to the device
791 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
796 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
797 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
798 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
808 * This function let the ug know whether current device is connected by other peer
809 * @return If connected, return TRUE, else return FALSE
810 * @param[in] ugd the pointer to the main data structure
811 * @param[in] dev the pointer to the device
813 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
817 if (ugd->I_am_group_owner == TRUE) {
818 if (dev->is_connected || dev->is_group_owner) {
824 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE) {
828 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE) {
832 if (dev->is_connected == FALSE) {
842 * This function let the ug calculate how many devices are avaliable
844 * @param[in] ugd the pointer to the main data structure
845 * @param[in] dev the pointer to the number of avaliable devices
847 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
850 GList *iterator = NULL;
852 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
853 /* Not include the device which is connected with me */
854 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
857 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
858 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) {
859 (*no_of_available_dev)++;
868 * This function let the ug calculate how many devices are busy
870 * @param[in] ugd the pointer to the main data structure
871 * @param[in] dev the pointer to the number of busy devices
873 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
876 GList *iterator = NULL;
878 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
879 /* Not include the device which is connected with me */
880 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
883 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data)) {
893 * This function let the ug calculate how many devices are connected failed
895 * @param[in] ugd the pointer to the main data structure
896 * @param[in] dev the pointer to the number of connected failed devices
898 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
901 GList *iterator = NULL;
903 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
904 /* Not include the device which is connected with me */
905 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
908 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
909 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
910 (*no_of_connect_failed_dev)++;
919 * This function let the ug create the main genlist
920 * @return the main genlist
921 * @param[in] data the pointer to the main data structure
923 static Evas_Object *_create_basic_genlist(void *data)
926 struct ug_data *ugd = (struct ug_data *) data;
927 Evas_Object *genlist;
929 genlist = elm_genlist_add(ugd->layout);
931 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
932 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
934 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
936 /* Wifi ON/OFF toggle button */
937 #ifdef WFD_ON_OFF_GENLIST
938 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
939 NULL, ELM_GENLIST_ITEM_NONE,_onoff_changed_cb, ugd);
940 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
943 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
944 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
945 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
946 ELM_GENLIST_ITEM_NONE, NULL, NULL);
947 if(ugd->device_name_item != NULL)
948 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
955 * This function let the ug create no device item to append the genlist
956 * @return the main item
957 * @param[in] data the pointer to the main data structure
959 Evas_Object *_create_no_device_genlist(void *data)
962 struct ug_data *ugd = (struct ug_data *) data;
963 Elm_Object_Item *last_item = NULL;
966 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
968 if (ugd->conn_wfd_item != NULL) {
969 last_item = ugd->conn_wfd_item;
970 for (i = 0; i < ugd->gl_connected_peer_cnt; i++) {
971 last_item = elm_genlist_item_next_get(last_item);
974 last_item = ugd->device_name_item;
977 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
978 &title_no_device_itc, (void *)ugd, NULL, last_item,
979 ELM_GENLIST_ITEM_NONE, NULL, NULL);
980 if(ugd->nodevice_title_item != NULL)
981 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
983 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
984 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
985 if(ugd->nodevice_item != NULL)
986 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
993 * This function let the ug create busy device list
995 * @param[in] data the pointer to the main data structure
997 int _create_busy_dev_list(void *data)
1000 struct ug_data *ugd = (struct ug_data *) data;
1002 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1003 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1004 if(ugd->busy_wfd_item != NULL)
1005 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1010 void wfd_free_nodivice_item(struct ug_data *ugd)
1013 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1014 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1019 * This function let the ug create avaliable device list
1021 * @param[in] data the pointer to the main data structure
1023 int _create_available_dev_genlist(void *data)
1027 struct ug_data *ugd = (struct ug_data *) data;
1028 Elm_Object_Item *last_item = NULL;
1030 wfd_free_nodivice_item(ugd);
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->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1042 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1043 if(ugd->avlbl_wfd_item != NULL) {
1044 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1045 elm_genlist_item_update(ugd->avlbl_wfd_item);
1052 * This function let the ug create multi connect device list
1054 * @param[in] data the pointer to the main data structure
1056 static int _create_multi_connect_dev_genlist(void *data)
1059 struct ug_data *ugd = (struct ug_data *) data;
1061 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1062 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1063 if(ugd->multi_connect_wfd_item != NULL)
1064 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1070 * This function let the ug create connected device list
1072 * @param[in] data the pointer to the main data structure
1074 int _create_connected_dev_genlist(void *data)
1077 struct ug_data *ugd = (struct ug_data *) data;
1079 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1080 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1081 if(ugd->conn_wfd_item != NULL) {
1082 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1083 elm_genlist_item_update(ugd->conn_wfd_item);
1091 * This function let the ug create connected falied device list
1093 * @param[in] data the pointer to the main data structure
1095 int _create_connected_failed_dev_genlist(void *data)
1098 struct ug_data *ugd = (struct ug_data *) data;
1099 Elm_Object_Item *last_item = NULL;
1102 if (ugd->avlbl_wfd_item != NULL) {
1103 last_item = ugd->avlbl_wfd_item;
1104 for (i=0; i<ugd->gl_available_peer_cnt; i++) {
1105 last_item = elm_genlist_item_next_get(last_item);
1107 } else if (ugd->conn_wfd_item != NULL) {
1108 last_item = ugd->conn_wfd_item;
1109 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1110 last_item = elm_genlist_item_next_get(last_item);
1113 last_item = ugd->device_name_item;
1116 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1117 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1118 if(ugd->conn_failed_wfd_item != NULL)
1119 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1125 * This function let the ug make the display callback for connect failed peers
1126 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1127 * @param[in] data the pointer to the user data
1129 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1134 struct ug_data *ugd = (struct ug_data *) user_data;
1137 DBG(LOG_ERROR, "NULL parameters.\n");
1138 return ECORE_CALLBACK_CANCEL;
1141 if (ugd->avlbl_wfd_item == NULL) {
1142 _create_available_dev_genlist(ugd);
1145 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1146 DBG(LOG_INFO, "Background mode\n");
1147 ugd->display_timer = NULL;
1148 return ECORE_CALLBACK_CANCEL;
1151 /* check the timeout, if not timeout, keep the cb */
1152 interval = time(NULL) - ugd->last_display_time;
1153 if (interval < MAX_DISPLAY_TIME_OUT) {
1154 return ECORE_CALLBACK_RENEW;
1157 if (ugd->is_paused == false) {
1158 DBG(LOG_INFO, "Not Paused");
1159 /* start discovery again */
1160 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1161 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1162 if (res != WIFI_DIRECT_ERROR_NONE) {
1163 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1164 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1165 wifi_direct_cancel_discovery();
1169 ugd->display_timer = NULL;
1171 return ECORE_CALLBACK_CANCEL;
1174 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1177 device_type_s *peer_for_free = NULL;
1178 device_type_s *peer = gl_peers_start;
1180 while (peer != NULL && peer->gl_item != NULL) {
1181 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1182 elm_object_item_del(peer->gl_item);
1183 peer->gl_item = NULL;
1184 peer_for_free = peer;
1186 free(peer_for_free);
1191 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1194 if (ugd->gl_connected_peer_cnt == 0) {
1195 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1201 * This function let the ug free the peers
1203 * @param[in] data the pointer to the main data structure
1205 void wfd_ug_view_free_peers(void *data)
1209 struct ug_data *ugd = (struct ug_data *) data;
1211 ugd->gl_connected_peer_cnt = 0;
1213 if (ugd->gl_conn_peers_start != NULL) {
1214 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1215 ugd->gl_conn_peers_start = NULL;
1218 ugd->gl_available_peer_cnt = 0;
1220 if (ugd->gl_avlb_peers_start != NULL) {
1221 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1222 ugd->gl_avlb_peers_start = NULL;
1225 ugd->gl_busy_peer_cnt = 0;
1227 if (ugd->gl_busy_peers_start != NULL) {
1228 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1229 ugd->gl_busy_peers_start = NULL;
1232 ugd->gl_multi_connect_peer_cnt = 0;
1234 if (ugd->gl_mul_conn_peers_start != NULL) {
1235 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1236 ugd->gl_mul_conn_peers_start = NULL;
1239 if (ugd->gl_connected_peer_cnt == 0) {
1240 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1243 if (ugd->display_timer != NULL) {
1244 ecore_timer_del(ugd->display_timer);
1245 ugd->display_timer = NULL;
1248 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1249 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1250 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1251 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1256 void wfd_ug_update_toolbar(struct ug_data *ugd)
1259 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1262 wfd_refresh_wifi_direct_state(ugd);
1263 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1264 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1265 if( ugd->multi_connect_wfd_item != NULL) {
1266 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1267 btn = elm_button_add(ugd->button_layout);
1268 /* Use "bottom" style button */
1269 elm_object_style_set(btn, "bottom");
1270 elm_object_domain_translatable_text_set(btn, PACKAGE,
1271 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1272 evas_object_smart_callback_add(btn, "clicked",
1273 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1274 /* Set button into "toolbar" swallow part */
1275 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1276 ugd->disconnect_btn = btn;
1277 evas_object_show(ugd->disconnect_btn);
1278 elm_object_part_content_set(ugd->button_layout, "button.prev",
1280 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1281 "IDS_WIFI_SK4_SCAN", FALSE);
1282 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1283 DBG(LOG_INFO, "button: disconnect button added\n");
1285 DBG(LOG_INFO, "scan_toolbar\n");
1286 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1287 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1288 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1289 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1290 DBG(LOG_INFO, "button: stop connect button added\n");
1292 } else if (no_of_conn_dev > 0) {
1293 if (!ugd->multi_connect_toolbar_item) {
1294 btn = elm_button_add(ugd->button_layout);
1295 /* Use "bottom" style button */
1296 elm_object_style_set(btn, "bottom");
1297 elm_object_domain_translatable_text_set(btn, PACKAGE,
1298 "IDS_WIFI_SK_DISCONNECT");
1299 evas_object_smart_callback_add(btn, "clicked",
1300 _wfd_ug_disconnect_button_cb, (void *)ugd);
1301 /* Set button into "toolbar" swallow part */
1302 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1303 ugd->disconnect_btn = btn;
1304 evas_object_show(ugd->disconnect_btn);
1306 elm_object_part_content_set(ugd->button_layout, "button.prev",
1308 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1309 "IDS_WIFI_SK4_SCAN", TRUE);
1310 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1311 DBG(LOG_INFO, "button: disconnect button added\n");
1313 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1314 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1315 Evas_Object *content;
1316 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1317 WFD_IF_DEL_OBJ(content);
1318 ugd->disconnect_btn = NULL;
1319 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1321 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1322 "IDS_WIFI_SK4_SCAN", TRUE);
1323 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1324 DBG(LOG_INFO, "button: scan button added\n");
1330 * This function let the ug init the genlist
1332 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1335 struct ug_data *ugd = (struct ug_data *) data;
1336 int no_of_busy_dev = 0;
1337 int no_of_available_dev = 0;
1338 int no_of_conn_failed_dev = 0;
1340 if (is_free_all_peers) {
1341 wfd_ug_view_free_peers(ugd);
1344 if (ugd->gl_failed_peers_start != NULL) {
1345 DBG(LOG_INFO, "These are failed peers, must clear them");
1346 ugd->gl_connected_failed_peer_cnt = 0;
1347 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1348 ugd->gl_failed_peers_start = NULL;
1349 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1352 if (ugd->avlbl_wfd_item != NULL) {
1353 DBG(LOG_INFO, "There are available peers in genlist");
1354 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1358 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1359 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1360 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1366 * This function let the ug find a peer in genlist
1368 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1372 if (start_pos == NULL) {
1373 DBG(LOG_INFO, "no peer in genlist");
1377 device_type_s *peer = start_pos;
1379 while (peer != NULL) {
1380 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1381 peer->is_alive = true;
1382 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1393 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1396 if (*start_pos == NULL) {
1397 DBG(LOG_INFO, "no peer in genlist");
1401 device_type_s *peer = *start_pos;
1402 device_type_s *peer_tmp = NULL;
1403 while (peer != NULL) {
1404 peer_tmp = peer->next;
1405 if(peer->is_alive == false) {
1406 free_gl_peer(start_pos, peer->mac_addr, cnt);
1411 // wfd_check_gl_available_peers(ugd);
1412 if (ugd->gl_busy_peer_cnt == 0) {
1413 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1419 void set_not_alive_peers(device_type_s *start_pos)
1422 if (start_pos == NULL) {
1423 DBG(LOG_INFO, "no peer in genlist");
1427 device_type_s *peer = start_pos;
1428 while (peer != NULL) {
1429 peer->is_alive = false;
1438 * This function let the ug get the insert position for next item
1440 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1444 device_type_s *peer_ite = NULL;
1445 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1446 Elm_Object_Item *item = NULL;
1449 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1453 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1454 if(peer_ite->gl_item != NULL) {
1455 for(i=0; i < peer_cnt; i++) {
1456 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1457 /* if peer_ite is greater than peer, return previous item */
1459 return elm_genlist_item_prev_get(head);
1461 item = elm_genlist_item_next_get(head);
1463 /* return the last item */
1467 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1473 return elm_genlist_item_prev_get(head);
1477 * This function let the ug insert peer item to genlist
1479 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1480 device_type_s *peer_for_insert, void *callback)
1483 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1484 device_type_s *peer = NULL;
1485 device_type_s *peer_ite = NULL;
1487 peer = (device_type_s *)malloc(sizeof(device_type_s));
1488 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1490 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1493 if(*start_pos == NULL) {
1496 peer_ite = *start_pos;
1497 while(peer_ite->next != NULL) {
1498 /* move pointer to the last peer */
1499 peer_ite = peer_ite->next;
1501 peer_ite->next = peer;
1504 peer->is_alive = true;
1505 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1506 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1507 if (callback == NULL && peer->gl_item != NULL) {
1508 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1515 * This function let the ug update connected peers
1517 * @param[in] data the pointer to the main data structure
1519 void wfd_ug_update_connected_peers(void *data)
1523 struct ug_data *ugd = (struct ug_data *) data;
1526 bool is_group_owner = FALSE;
1527 Elm_Object_Item *item = NULL;
1529 res = wifi_direct_is_group_owner(&is_group_owner);
1530 if (res == WIFI_DIRECT_ERROR_NONE) {
1531 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1534 if (!ugd->conn_wfd_item) {
1535 _create_connected_dev_genlist(ugd);
1538 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1539 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1540 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1541 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1542 &ugd->gl_available_peer_cnt);
1543 wfd_check_gl_available_peers(ugd);
1546 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1547 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1548 &ugd->gl_multi_connect_peer_cnt);
1549 if (ugd->gl_multi_connect_peer_cnt == 0) {
1550 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1551 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1555 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1556 ugd->gl_connected_peer_cnt);
1557 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1558 &ugd->raw_connected_peers[i], NULL);
1562 ugd->gl_connected_peer_cnt++;
1566 /* if is not GO, free all available peers */
1567 if (is_group_owner == FALSE) {
1568 ugd->gl_available_peer_cnt = 0;
1569 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1571 if (ugd->gl_avlb_peers_start != NULL) {
1572 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1573 ugd->gl_avlb_peers_start = NULL;
1577 /* free busy peers */
1578 if (ugd->gl_busy_peers_start != NULL) {
1579 ugd->gl_busy_peer_cnt = 0;
1580 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1582 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1583 ugd->gl_busy_peers_start = NULL;
1591 * This function let the ug update the multi-connect peers
1593 * @param[in] data the pointer to the main data structure
1595 void wfd_ug_view_update_multiconn_peers(void *data)
1599 struct ug_data *ugd = (struct ug_data *) data;
1602 Elm_Object_Item *item = NULL;
1604 if (ugd->raw_multi_selected_peer_cnt > 0) {
1605 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1606 ugd->multi_connect_wfd_item == NULL) {
1607 _create_multi_connect_dev_genlist(ugd);
1610 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1611 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1612 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1613 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1614 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1615 &ugd->raw_multi_selected_peers[i], NULL);
1619 ugd->gl_multi_connect_peer_cnt++;
1628 * This function let the ug update the available and busy peers
1630 void wfd_ug_update_available_peers(void *data)
1634 struct ug_data *ugd = (struct ug_data *) data;
1635 int no_of_busy_dev = 0;
1636 int no_of_available_dev = 0;
1637 int no_of_conn_dev = 0;
1638 bool is_group_owner = FALSE;
1640 Elm_Object_Item *item = NULL;
1641 device_type_s *peer = NULL;
1642 GList *iterator = NULL;
1644 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1645 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1646 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1648 res = wifi_direct_is_group_owner(&is_group_owner);
1649 if (res != WIFI_DIRECT_ERROR_NONE) {
1650 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1651 ugd->I_am_group_owner = FALSE;
1653 ugd->I_am_group_owner = is_group_owner;
1656 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1657 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1658 DBG(LOG_INFO, "There are available or busy peers\n");
1659 wfd_free_nodivice_item(ugd);
1662 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1663 if (ugd->avlbl_wfd_item == NULL) {
1664 _create_available_dev_genlist(ugd);
1667 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1668 /* Not include the device which is connected with me */
1669 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1672 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1673 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1674 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1675 /* free disconnected gl peer */
1676 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1677 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1678 &ugd->gl_connected_peer_cnt);
1681 /* free busy gl peer, which is available now */
1682 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1683 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1684 if (ugd->gl_busy_peer_cnt == 0) {
1685 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1689 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL) {
1693 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1695 item = get_insert_postion((device_type_s *)iterator->data,
1696 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1697 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1698 (device_type_s *)iterator->data, _gl_peer_sel);
1702 ugd->gl_available_peer_cnt++;
1703 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1704 /* if peer is GO, free it */
1705 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1706 &ugd->gl_available_peer_cnt);
1712 wfd_check_gl_available_peers(ugd);
1713 wfd_check_gl_conn_peers(ugd);
1715 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1716 if (ugd->busy_wfd_item == NULL) {
1717 _create_busy_dev_list(ugd);
1720 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1721 /* Not include the device which is connected with me */
1722 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1725 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1726 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1727 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1728 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1729 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1730 &ugd->gl_available_peer_cnt);
1731 wfd_check_gl_available_peers(ugd);
1733 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1734 ugd->gl_busy_peer_cnt);
1735 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1736 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1740 ugd->gl_busy_peer_cnt++;
1746 wfd_check_gl_busy_peers(ugd);
1752 * This function let the ug update the failed peers
1754 * @param[in] data the pointer to the main data structure
1756 void wfd_ug_update_failed_peers(void *data)
1759 struct ug_data *ugd = (struct ug_data *) data;
1760 int no_of_conn_failed_dev = 0;
1761 GList *iterator = NULL;
1763 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1764 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1766 if (no_of_conn_failed_dev == 0) {
1770 /* add timer for disappearing failed peers after N secs */
1771 if (NULL == ugd->display_timer) {
1772 ugd->last_display_time = time(NULL);
1773 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1776 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1777 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1778 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1779 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1780 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1781 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1782 &ugd->gl_available_peer_cnt);
1783 wfd_check_gl_available_peers(ugd);
1792 #ifdef WFD_ON_OFF_GENLIST
1794 * This function is called when user swipes on/off button
1796 * @param[in] data the pointer to the main data structure
1797 * @param[in] obj the pointer to the evas object
1798 * @param[in] event_info the pointer to the event information
1800 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1803 struct ug_data *ugd = (struct ug_data *)data;
1804 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1805 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1806 wfd_refresh_wifi_direct_state(ugd);
1807 if(ugd->device_name_item != NULL)
1808 elm_genlist_item_update(ugd->device_name_item);
1810 elm_object_disabled_set(ugd->on_off_check, TRUE);
1811 if(ugd->disconnect_btn) {
1812 Evas_Object *content;
1813 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1814 WFD_IF_DEL_OBJ(content);
1815 ugd->disconnect_btn = NULL;
1817 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1819 /* turn on/off wfd */
1820 if (!ugd->wfd_onoff) {
1821 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1822 DBG(LOG_INFO, "wifi-direct switch on\n");
1823 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1825 wfd_client_switch_on(ugd);
1828 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1829 DBG(LOG_INFO, "wifi-direct switch off\n");
1830 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1832 wfd_client_switch_off(ugd);
1839 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1842 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1843 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1845 wfd_refresh_wifi_direct_state(ugd);
1846 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1847 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING ) {
1848 elm_object_disabled_set(ugd->on_off_check, TRUE);
1850 elm_object_disabled_set(ugd->on_off_check, FALSE);
1852 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1853 elm_check_state_set(ugd->on_off_check, TRUE);
1855 elm_check_state_set(ugd->on_off_check, FALSE);
1861 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1864 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1865 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1867 Evas_Object *check = elm_check_add(ugd->naviframe);
1868 elm_object_style_set(check, "naviframe/title_on&off");
1869 elm_check_state_set(check, ugd->wfd_onoff);
1870 evas_object_propagate_events_set(check, EINA_FALSE);
1871 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1872 elm_object_focus_allow_set(check, EINA_TRUE);
1873 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1874 evas_object_show(check);
1875 ugd->on_off_check = check;
1882 * This function let the ug create the main view
1884 * @param[in] data the pointer to the main data structure
1886 void create_wfd_ug_view(void *data)
1889 struct ug_data *ugd = (struct ug_data *) data;
1890 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1891 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1892 Evas_Object *more_btn;
1894 Evas_Object *layout;
1896 ugd->naviframe = elm_naviframe_add(ugd->base);
1897 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1898 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1899 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1900 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1902 ugd->back_btn = elm_button_add(ugd->naviframe);
1903 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1904 evas_object_smart_callback_add(ugd->back_btn, "clicked", _back_btn_cb, (void *)ugd);
1905 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1908 layout = elm_layout_add(ugd->naviframe);
1909 elm_layout_theme_set(layout, "layout", "application", "default");
1910 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1911 ugd->layout = layout;
1913 ugd->genlist = _create_basic_genlist(ugd);
1914 if (ugd->genlist == NULL) {
1915 DBG(LOG_ERROR, "Failed to create basic genlist");
1920 DBG(LOG_ERROR, "elm_object_part_content_set");
1921 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1922 DBG(LOG_ERROR, "elm_genlist_fx_mode_set");
1923 //elm_genlist_fx_mode_set(ugd->genlist, EINA_FALSE);
1925 DBG(LOG_ERROR, "evas_object_show");
1926 evas_object_show(ugd->base);
1927 DBG(LOG_ERROR, "elm_object_focus_set");
1928 elm_object_focus_set(ugd->base, EINA_TRUE);
1930 DBG(LOG_ERROR, "elm_naviframe_item_push");
1931 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1932 ugd->back_btn, NULL, layout, NULL);
1933 DBG(LOG_ERROR, "elm_naviframe_item_pop_cb_set");
1934 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1936 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1937 more_btn = elm_button_add(ugd->naviframe);
1938 elm_object_style_set(more_btn, "naviframe/more/default");
1939 evas_object_smart_callback_add(more_btn, "clicked",
1940 _more_button_cb, ugd->win);
1941 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1945 wifi_direct_initialize();
1946 wifi_direct_get_state(&ugd->wfd_status);
1947 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING) {
1948 scan_button_create(ugd);
1951 if (ugd->view_type && g_strcmp0(_(ugd->view_type), _("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1953 ugd->raw_discovered_peer_cnt = 0;
1954 wfd_create_multiconnect_view(ugd);
1955 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1956 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1957 if (ret != WIFI_DIRECT_ERROR_NONE) {
1958 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1959 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
1960 wifi_direct_cancel_discovery();
1969 * This function let the ug destroy the main view
1971 * @param[in] data the pointer to the main data structure
1973 void destroy_wfd_ug_view(void *data)
1976 struct ug_data *ugd = (struct ug_data *) data;
1977 WFD_IF_DEL_ITEM(ugd->device_name_item);
1978 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1979 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1981 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
1982 WFD_IF_DEL_OBJ(ugd->back_btn);
1983 WFD_IF_DEL_OBJ(ugd->toolbar);
1984 WFD_IF_DEL_OBJ(ugd->genlist);
1985 WFD_IF_DEL_OBJ(ugd->button_layout);
1986 WFD_IF_DEL_OBJ(ugd->layout);
1987 WFD_IF_DEL_OBJ(ugd->naviframe);