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);
145 * This function let the ug call it when click 'back' button
147 * @param[in] data the pointer to the main data structure
148 * @param[in] obj the pointer to the evas object
149 * @param[in] event_info the pointer to the event information
151 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
154 struct ug_data *ugd = (struct ug_data *) data;
157 app_control_h control = NULL;
160 DBG(LOG_ERROR, "The param is NULL");
164 #ifdef WFD_DBUS_LAUNCH
165 if (ugd->dbus_cancellable != NULL) {
166 g_cancellable_cancel(ugd->dbus_cancellable);
167 g_object_unref(ugd->dbus_cancellable);
168 ugd->dbus_cancellable = NULL;
170 g_object_unref(ugd->conn);
173 DBG(LOG_INFO, "Cancel dbus call");
177 wfd_refresh_wifi_direct_state(ugd);
178 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
179 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
183 if (NULL != ugd->mac_addr_connecting) {
184 if (ugd->is_conn_incoming) {
185 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
186 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
187 if (ret != WIFI_DIRECT_ERROR_NONE) {
188 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
191 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
192 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
193 if (ret != WIFI_DIRECT_ERROR_NONE) {
194 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
197 ugd->mac_addr_connecting = NULL;
200 if (ugd->raw_connected_peer_cnt == 0) {
201 ret = wifi_direct_is_group_owner(&owner);
202 if (ret == WIFI_DIRECT_ERROR_NONE) {
204 wifi_direct_destroy_group();
210 wfd_ug_view_free_peers(ugd);
211 ret = app_control_create(&control);
213 DBG(LOG_ERROR, "Failed to create control");
215 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) {
216 app_control_add_extra_data(control, "Connection", "TRUE");
218 app_control_add_extra_data(control, "Connection", "FALSE");
221 ug_send_result(ugd->ug, control);
222 app_control_destroy(control);
225 ug_destroy_me(ugd->ug);
230 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
234 if(ugd->timer_stop_progress_bar > 0) {
235 g_source_remove(ugd->timer_stop_progress_bar);
237 ugd->timer_stop_progress_bar = 0;
242 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
246 if(ugd->timer_delete_not_alive_peer > 0) {
247 g_source_remove(ugd->timer_delete_not_alive_peer);
249 ugd->timer_delete_not_alive_peer = 0;
255 * This function let the ug call it when click failed devices item
257 * @param[in] data the pointer to the main data structure
258 * @param[in] obj the pointer to the evas object
259 * @param[in] event_info the pointer to the event information
261 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
265 struct ug_data *ugd = wfd_get_ug_data();
269 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
273 if (ugd->display_timer != NULL) {
274 ecore_timer_del(ugd->display_timer);
275 ugd->display_timer = NULL;
278 wfd_refresh_wifi_direct_state(ugd);
279 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
281 /* if connected, show the popup*/
282 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
283 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);
285 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
286 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
287 if (ret != WIFI_DIRECT_ERROR_NONE) {
288 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
289 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
290 wifi_direct_cancel_discovery();
299 * This function let the ug call it when click 'scan' button
301 * @param[in] data the pointer to the main data structure
302 * @param[in] obj the pointer to the evas object
303 * @param[in] event_info the pointer to the event information
305 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
309 struct ug_data *ugd = (struct ug_data *) data;
311 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
315 const char *btn_text = NULL;
316 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
317 DBG(LOG_INFO, "Button text=%s",btn_text);
319 if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
320 wfd_refresh_wifi_direct_state(ugd);
321 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
322 /* if connected, show the popup*/
323 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
324 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);
325 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
326 wfd_client_switch_on(ugd);
330 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
331 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
332 if (ret != WIFI_DIRECT_ERROR_NONE) {
333 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
334 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
335 wifi_direct_cancel_discovery();
338 } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
339 DBG(LOG_INFO, "Stop pressed.\n");
340 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
341 wfd_cancel_progressbar_stop_timer(ugd);
342 wfd_delete_progressbar_cb(ugd);
343 wfd_cancel_not_alive_delete_timer(ugd);
344 } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
345 DBG(LOG_INFO, "Cancel Connection");
346 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
348 DBG(LOG_INFO, "Invalid Case\n");
354 void wfd_check_gl_busy_peers(struct ug_data *ugd)
357 if (ugd->gl_busy_peer_cnt == 0) {
358 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
363 void wfd_check_gl_available_peers(struct ug_data *ugd)
366 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL) {
367 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
373 * This function let the ug free some peer in genlist
375 * @param[in] start_pos the start position of peers list
376 * @param[in] mac_addr the mac_addr of peer for free
377 * @param[in] cnt the count of gl peers in list
379 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
382 device_type_s *peer = *start_pos;
383 device_type_s *peer_tmp = peer;
386 DBG(LOG_INFO, "no peer in genlist");
391 if(strcmp(peer->mac_addr, mac_addr)) {
395 if(peer->next != NULL) {
396 peer_tmp->next = peer->next;
399 peer_tmp->next = NULL;
405 if (peer == *start_pos) {
406 DBG(LOG_INFO, "the head is free");
407 *start_pos = peer->next;
412 WFD_IF_DEL_ITEM(peer->gl_item);
420 * This function let the ug call it when click avaliable peer to connect
422 * @param[in] data the pointer to the main data structure
423 * @param[in] obj the pointer to the evas object
424 * @param[in] event_info the pointer to the event information
426 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
431 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
432 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
433 bool is_peer_alive = false;
434 struct ug_data *ugd = wfd_get_ug_data();
435 device_type_s *peer = (device_type_s *)data;
436 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
439 DBG(LOG_ERROR, "NULL parameters.\n");
443 wfd_ug_get_connected_peers(ugd);
444 DBG(LOG_INFO, "No of connected peers= %d",ugd->raw_connected_peer_cnt);
446 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
447 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME"), MAX_CONNECTED_PEER_NUM);
448 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
450 elm_genlist_item_selected_set(item, EINA_FALSE);
455 if (ugd->disconnect_btn) {
456 Evas_Object *content;
457 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
458 WFD_IF_DEL_OBJ(content);
459 ugd->disconnect_btn = NULL;
460 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
464 elm_genlist_item_selected_set(item, EINA_FALSE);
467 GList *iterator = NULL;
469 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
470 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
471 /* peer is found in last discovery */
472 is_peer_alive = true;
477 if (!is_peer_alive) {
478 /* peer exists only in genlist, waiting to be deleted */
479 device_type_s *peer_start = ugd->gl_avlb_peers_start;
480 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
481 if(!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
482 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
483 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
484 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
485 wfd_check_gl_available_peers(ugd);
486 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
492 wfd_cancel_not_alive_delete_timer(ugd);
495 wfd_refresh_wifi_direct_state(ugd);
497 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
498 peer->is_group_owner == TRUE) {
499 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
500 MAC2SECSTR(peer->mac_addr));
502 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
503 DBG(LOG_DEBUG, "It's in connecting status now.\n");
507 ugd->mac_addr_connecting = peer->mac_addr;
508 res = wfd_client_connect((const char *)peer->mac_addr);
510 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
520 * This function let the ug call it when click busy peer
522 * @param[in] data the pointer to the main data structure
523 * @param[in] obj the pointer to the evas object
524 * @param[in] event_info the pointer to the event information
526 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
529 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
530 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
533 elm_genlist_item_selected_set(item, EINA_FALSE);
537 DBG(LOG_ERROR, "Data is NULL\n");
541 wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
546 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
548 struct ug_data *ugd = (struct ug_data *) data;
551 DBG(LOG_ERROR, "The param is NULL\n");
556 evas_object_del(ugd->ctxpopup);
557 ugd->ctxpopup = NULL;
561 void _ctxpopup_move()
565 int win_w = 0, win_h = 0;
566 int move_x = 0, move_y = 0;
568 struct ug_data *ugd = wfd_get_ug_data();
570 if (!ugd || !ugd->win) {
571 DBG(LOG_ERROR, "NULL parameters.\n");
575 if (!ugd->ctxpopup) {
576 DBG(LOG_INFO, "NULL parameters.\n");
580 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
581 changed_ang = elm_win_rotation_get(ugd->win);
583 switch (changed_ang) {
606 evas_object_move(ugd->ctxpopup, move_x, move_y);
611 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
614 struct ug_data *ugd = (struct ug_data *) data;
615 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
616 WFD_IF_DEL_OBJ(ugd->ctxpopup);
619 wfd_client_free_raw_discovered_peers(ugd);
620 ugd->raw_discovered_peer_cnt = 0;
621 wfd_create_multiconnect_view(ugd);
622 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
623 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
624 if (ret != WIFI_DIRECT_ERROR_NONE) {
625 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
626 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
627 wifi_direct_cancel_discovery();
633 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
637 Evas_Object *naviframe = (Evas_Object *)data;
638 Elm_Object_Item *multi_connect_item = NULL;
639 Elm_Object_Item *rename_item = NULL;
640 struct ug_data *ugd = wfd_get_ug_data();
642 if (!naviframe || !ugd) {
643 DBG(LOG_ERROR, "NULL parameters.\n");
647 ugd->more_btn_multiconnect_item = NULL;
650 evas_object_del(ugd->ctxpopup);
653 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
654 elm_object_style_set(ugd->ctxpopup, "more/default");
655 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
656 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
657 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
658 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
660 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
661 ELM_CTXPOPUP_DIRECTION_LEFT,
662 ELM_CTXPOPUP_DIRECTION_RIGHT,
663 ELM_CTXPOPUP_DIRECTION_DOWN);
667 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
668 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
669 ugd->more_btn_multiconnect_item = multi_connect_item;
671 wfd_refresh_wifi_direct_state(ugd);
672 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
673 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
674 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
675 ugd->raw_connected_peer_cnt > 0) {
676 elm_object_item_disabled_set(multi_connect_item, TRUE);
679 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
680 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
681 evas_object_show(ugd->ctxpopup);
687 * This function make items into group
689 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
693 if (count < 1 || pre_item == NULL) {
697 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
703 elm_object_item_signal_emit(item, "elm,state,normal", "");
707 for (i = 0; i < count; i++) {
709 elm_object_item_signal_emit(item, "elm,state,top", "");
710 } else if (i == count - 1) {
711 elm_object_item_signal_emit(item, "elm,state,bottom", "");
713 elm_object_item_signal_emit(item, "elm,state,center", "");
716 item = elm_genlist_item_next_get(item);
722 * This function let the ug call it when unresized event is received
724 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
727 struct ug_data *ugd = (struct ug_data *)data;
729 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
730 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
731 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
732 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
733 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
738 * This function let the ug call it when resized event is received
740 * @param[in] data the pointer to the main data structure
741 * @param[in] obj the pointer to the evas object
742 * @param[in] event_info the pointer to the event information
744 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
748 if (!data || !event_info) {
749 DBG(LOG_ERROR, "Invalid parameters");
753 struct ug_data *ugd = (struct ug_data *)data;
754 #ifdef ACCESSIBILITY_FEATURE
755 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
756 int index = elm_genlist_item_index_get(item);
760 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
761 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
762 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
763 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
764 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
766 #ifdef ACCESSIBILITY_FEATURE
768 if (GENLIST_HEADER_POS == index && item != NULL) {
769 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
771 Eina_Bool state = elm_check_state_get(check);
773 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
775 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
779 Evas_Object *ao = NULL;
780 ao = elm_object_item_access_object_get(item);
781 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
784 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
787 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
796 * This function let the ug call it when click 'disconnect' button
798 * @param[in] data the pointer to the main data structure
799 * @param[in] obj the pointer to the evas object
800 * @param[in] event_info the pointer to the event information
802 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
805 struct ug_data *ugd = (struct ug_data *)data;
806 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
808 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
814 * This function let the ug call it when click "cancel connection" button
816 * @param[in] data the pointer to the main data structure
817 * @param[in] obj the pointer to the evas object
818 * @param[in] event_info the pointer to the event information
820 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
823 struct ug_data *ugd = (struct ug_data *)data;
824 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
826 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
833 * This function let the ug update the genlist item
835 * @param[in] gl_item the pointer to genlist item
837 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
840 if (gl_item != NULL) {
841 elm_genlist_item_update(gl_item);
847 * This function let the ug refresh the attributes of button
849 * @param[in] tb_item the pointer to the toolbar button
850 * @param[in] text the pointer to the text of button
851 * @param[in] enable whether the button is disabled
853 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
858 if (NULL == tb_item || NULL == text) {
859 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
863 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
864 elm_object_domain_translatable_part_text_set(tb_item, "default",
866 elm_object_disabled_set(tb_item, !enable);
872 * This function let the ug know whether current device is connected by me
873 * @return If connected, return TRUE, else return FALSE
874 * @param[in] ugd the pointer to the main data structure
875 * @param[in] dev the pointer to the device
877 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
882 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
883 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
884 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
894 * This function let the ug know whether current device is connected by other peer
895 * @return If connected, return TRUE, else return FALSE
896 * @param[in] ugd the pointer to the main data structure
897 * @param[in] dev the pointer to the device
899 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
903 if (ugd->I_am_group_owner == TRUE) {
904 if (dev->is_connected || dev->is_group_owner) {
910 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE) {
914 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE) {
918 if (dev->is_connected == FALSE) {
928 * This function let the ug calculate how many devices are avaliable
930 * @param[in] ugd the pointer to the main data structure
931 * @param[in] dev the pointer to the number of avaliable devices
933 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
936 GList *iterator = NULL;
938 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
939 /* Not include the device which is connected with me */
940 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
943 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
944 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) {
945 (*no_of_available_dev)++;
954 * This function let the ug calculate how many devices are busy
956 * @param[in] ugd the pointer to the main data structure
957 * @param[in] dev the pointer to the number of busy devices
959 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
962 GList *iterator = NULL;
964 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
965 /* Not include the device which is connected with me */
966 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
969 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data)) {
979 * This function let the ug calculate how many devices are connected failed
981 * @param[in] ugd the pointer to the main data structure
982 * @param[in] dev the pointer to the number of connected failed devices
984 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
987 GList *iterator = NULL;
989 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
990 /* Not include the device which is connected with me */
991 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
994 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
995 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
996 (*no_of_connect_failed_dev)++;
1005 * This function let the ug create the main genlist
1006 * @return the main genlist
1007 * @param[in] data the pointer to the main data structure
1009 static Evas_Object *_create_basic_genlist(void *data)
1012 struct ug_data *ugd = (struct ug_data *) data;
1013 Evas_Object *genlist;
1015 genlist = elm_genlist_add(ugd->layout);
1017 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
1018 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
1020 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1022 /* Wifi ON/OFF toggle button */
1023 #ifdef WFD_ON_OFF_GENLIST
1024 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
1025 NULL, ELM_GENLIST_ITEM_NONE,_onoff_changed_cb, ugd);
1026 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1029 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
1030 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
1031 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
1032 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1033 if(ugd->device_name_item != NULL)
1034 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1041 * This function let the ug create no device item to append the genlist
1042 * @return the main item
1043 * @param[in] data the pointer to the main data structure
1045 Evas_Object *_create_no_device_genlist(void *data)
1048 struct ug_data *ugd = (struct ug_data *) data;
1049 Elm_Object_Item *last_item = NULL;
1052 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1054 if (ugd->conn_wfd_item != NULL) {
1055 last_item = ugd->conn_wfd_item;
1056 for (i = 0; i < ugd->gl_connected_peer_cnt; i++) {
1057 last_item = elm_genlist_item_next_get(last_item);
1060 last_item = ugd->device_name_item;
1063 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1064 &title_no_device_itc, (void *)ugd, NULL, last_item,
1065 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1066 if(ugd->nodevice_title_item != NULL)
1067 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1069 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1070 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1071 if(ugd->nodevice_item != NULL)
1072 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1075 return ugd->genlist;
1079 * This function let the ug create busy device list
1081 * @param[in] data the pointer to the main data structure
1083 int _create_busy_dev_list(void *data)
1086 struct ug_data *ugd = (struct ug_data *) data;
1088 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1089 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1090 if(ugd->busy_wfd_item != NULL)
1091 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1096 void wfd_free_nodivice_item(struct ug_data *ugd)
1099 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1100 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1105 * This function let the ug create avaliable device list
1107 * @param[in] data the pointer to the main data structure
1109 int _create_available_dev_genlist(void *data)
1113 struct ug_data *ugd = (struct ug_data *) data;
1114 Elm_Object_Item *last_item = NULL;
1116 wfd_free_nodivice_item(ugd);
1118 if (ugd->conn_wfd_item != NULL) {
1119 last_item = ugd->conn_wfd_item;
1120 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1121 last_item = elm_genlist_item_next_get(last_item);
1124 last_item = ugd->device_name_item;
1127 ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1128 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1129 if(ugd->avlbl_wfd_item != NULL) {
1130 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1131 elm_genlist_item_update(ugd->avlbl_wfd_item);
1138 * This function let the ug create multi connect device list
1140 * @param[in] data the pointer to the main data structure
1142 static int _create_multi_connect_dev_genlist(void *data)
1145 struct ug_data *ugd = (struct ug_data *) data;
1147 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1148 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1149 if(ugd->multi_connect_wfd_item != NULL)
1150 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1156 * This function let the ug create connected device list
1158 * @param[in] data the pointer to the main data structure
1160 int _create_connected_dev_genlist(void *data)
1163 struct ug_data *ugd = (struct ug_data *) data;
1165 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1166 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1167 if(ugd->conn_wfd_item != NULL) {
1168 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1169 elm_genlist_item_update(ugd->conn_wfd_item);
1177 * This function let the ug create connected falied device list
1179 * @param[in] data the pointer to the main data structure
1181 int _create_connected_failed_dev_genlist(void *data)
1184 struct ug_data *ugd = (struct ug_data *) data;
1185 Elm_Object_Item *last_item = NULL;
1188 if (ugd->avlbl_wfd_item != NULL) {
1189 last_item = ugd->avlbl_wfd_item;
1190 for (i=0; i<ugd->gl_available_peer_cnt; i++) {
1191 last_item = elm_genlist_item_next_get(last_item);
1193 } else if (ugd->conn_wfd_item != NULL) {
1194 last_item = ugd->conn_wfd_item;
1195 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1196 last_item = elm_genlist_item_next_get(last_item);
1199 last_item = ugd->device_name_item;
1202 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1203 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1204 if(ugd->conn_failed_wfd_item != NULL)
1205 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1211 * This function let the ug make the display callback for connect failed peers
1212 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1213 * @param[in] data the pointer to the user data
1215 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1220 struct ug_data *ugd = (struct ug_data *) user_data;
1223 DBG(LOG_ERROR, "NULL parameters.\n");
1224 return ECORE_CALLBACK_CANCEL;
1227 if (ugd->avlbl_wfd_item == NULL) {
1228 _create_available_dev_genlist(ugd);
1231 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1232 DBG(LOG_INFO, "Background mode\n");
1233 ugd->display_timer = NULL;
1234 return ECORE_CALLBACK_CANCEL;
1237 /* check the timeout, if not timeout, keep the cb */
1238 interval = time(NULL) - ugd->last_display_time;
1239 if (interval < MAX_DISPLAY_TIME_OUT) {
1240 return ECORE_CALLBACK_RENEW;
1243 if (ugd->is_paused == false) {
1244 DBG(LOG_INFO, "Not Paused");
1245 /* start discovery again */
1246 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1247 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1248 if (res != WIFI_DIRECT_ERROR_NONE) {
1249 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1250 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1251 wifi_direct_cancel_discovery();
1255 ugd->display_timer = NULL;
1257 return ECORE_CALLBACK_CANCEL;
1260 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1263 device_type_s *peer_for_free = NULL;
1264 device_type_s *peer = gl_peers_start;
1266 while (peer != NULL && peer->gl_item != NULL) {
1267 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1268 elm_object_item_del(peer->gl_item);
1269 peer->gl_item = NULL;
1270 peer_for_free = peer;
1272 free(peer_for_free);
1277 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1280 if (ugd->gl_connected_peer_cnt == 0) {
1281 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1287 * This function let the ug free the peers
1289 * @param[in] data the pointer to the main data structure
1291 void wfd_ug_view_free_peers(void *data)
1295 struct ug_data *ugd = (struct ug_data *) data;
1297 ugd->gl_connected_peer_cnt = 0;
1299 if (ugd->gl_conn_peers_start != NULL) {
1300 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1301 ugd->gl_conn_peers_start = NULL;
1304 ugd->gl_available_peer_cnt = 0;
1306 if (ugd->gl_avlb_peers_start != NULL) {
1307 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1308 ugd->gl_avlb_peers_start = NULL;
1311 ugd->gl_busy_peer_cnt = 0;
1313 if (ugd->gl_busy_peers_start != NULL) {
1314 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1315 ugd->gl_busy_peers_start = NULL;
1318 ugd->gl_multi_connect_peer_cnt = 0;
1320 if (ugd->gl_mul_conn_peers_start != NULL) {
1321 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1322 ugd->gl_mul_conn_peers_start = NULL;
1325 if (ugd->gl_connected_peer_cnt == 0) {
1326 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1329 if (ugd->display_timer != NULL) {
1330 ecore_timer_del(ugd->display_timer);
1331 ugd->display_timer = NULL;
1334 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1335 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1336 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1337 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1342 void wfd_ug_update_toolbar(struct ug_data *ugd)
1345 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1348 wfd_refresh_wifi_direct_state(ugd);
1349 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1350 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1351 if( ugd->multi_connect_wfd_item != NULL) {
1352 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1353 btn = elm_button_add(ugd->button_layout);
1354 /* Use "bottom" style button */
1355 elm_object_style_set(btn, "bottom");
1356 elm_object_domain_translatable_text_set(btn, PACKAGE,
1357 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1358 evas_object_smart_callback_add(btn, "clicked",
1359 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1360 /* Set button into "toolbar" swallow part */
1361 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1362 ugd->disconnect_btn = btn;
1363 evas_object_show(ugd->disconnect_btn);
1364 elm_object_part_content_set(ugd->button_layout, "button.prev",
1366 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1367 "IDS_WIFI_SK4_SCAN", FALSE);
1368 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1369 DBG(LOG_INFO, "button: disconnect button added\n");
1371 DBG(LOG_INFO, "scan_toolbar\n");
1372 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1373 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1374 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1375 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1376 DBG(LOG_INFO, "button: stop connect button added\n");
1378 } else if (no_of_conn_dev > 0) {
1379 if (!ugd->multi_connect_toolbar_item) {
1380 btn = elm_button_add(ugd->button_layout);
1381 /* Use "bottom" style button */
1382 elm_object_style_set(btn, "bottom");
1383 elm_object_domain_translatable_text_set(btn, PACKAGE,
1384 "IDS_WIFI_SK_DISCONNECT");
1385 evas_object_smart_callback_add(btn, "clicked",
1386 _wfd_ug_disconnect_button_cb, (void *)ugd);
1387 /* Set button into "toolbar" swallow part */
1388 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1389 ugd->disconnect_btn = btn;
1390 evas_object_show(ugd->disconnect_btn);
1392 elm_object_part_content_set(ugd->button_layout, "button.prev",
1394 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1395 "IDS_WIFI_SK4_SCAN", TRUE);
1396 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1397 DBG(LOG_INFO, "button: disconnect button added\n");
1399 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1400 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1401 Evas_Object *content;
1402 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1403 WFD_IF_DEL_OBJ(content);
1404 ugd->disconnect_btn = NULL;
1405 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1407 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1408 "IDS_WIFI_SK4_SCAN", TRUE);
1409 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1410 DBG(LOG_INFO, "button: scan button added\n");
1416 * This function let the ug init the genlist
1418 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1421 struct ug_data *ugd = (struct ug_data *) data;
1422 int no_of_busy_dev = 0;
1423 int no_of_available_dev = 0;
1424 int no_of_conn_failed_dev = 0;
1426 if (is_free_all_peers) {
1427 wfd_ug_view_free_peers(ugd);
1430 if (ugd->gl_failed_peers_start != NULL) {
1431 DBG(LOG_INFO, "These are failed peers, must clear them");
1432 ugd->gl_connected_failed_peer_cnt = 0;
1433 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1434 ugd->gl_failed_peers_start = NULL;
1435 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1438 if (ugd->avlbl_wfd_item != NULL) {
1439 DBG(LOG_INFO, "There are available peers in genlist");
1440 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1444 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1445 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1446 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1452 * This function let the ug find a peer in genlist
1454 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1458 if (start_pos == NULL) {
1459 DBG(LOG_INFO, "no peer in genlist");
1463 device_type_s *peer = start_pos;
1465 while (peer != NULL) {
1466 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1467 peer->is_alive = true;
1468 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1479 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1482 if (*start_pos == NULL) {
1483 DBG(LOG_INFO, "no peer in genlist");
1487 device_type_s *peer = *start_pos;
1488 device_type_s *peer_tmp = NULL;
1489 while (peer != NULL) {
1490 peer_tmp = peer->next;
1491 if(peer->is_alive == false) {
1492 free_gl_peer(start_pos, peer->mac_addr, cnt);
1497 // wfd_check_gl_available_peers(ugd);
1498 if (ugd->gl_busy_peer_cnt == 0) {
1499 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1505 void set_not_alive_peers(device_type_s *start_pos)
1508 if (start_pos == NULL) {
1509 DBG(LOG_INFO, "no peer in genlist");
1513 device_type_s *peer = start_pos;
1514 while (peer != NULL) {
1515 peer->is_alive = false;
1524 * This function let the ug get the insert position for next item
1526 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1530 device_type_s *peer_ite = NULL;
1531 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1532 Elm_Object_Item *item = NULL;
1535 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1539 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1540 if(peer_ite->gl_item != NULL) {
1541 for(i=0; i < peer_cnt; i++) {
1542 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1543 /* if peer_ite is greater than peer, return previous item */
1545 return elm_genlist_item_prev_get(head);
1547 item = elm_genlist_item_next_get(head);
1549 /* return the last item */
1553 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1559 return elm_genlist_item_prev_get(head);
1563 * This function let the ug insert peer item to genlist
1565 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1566 device_type_s *peer_for_insert, void *callback)
1569 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1570 device_type_s *peer = NULL;
1571 device_type_s *peer_ite = NULL;
1573 peer = (device_type_s *)malloc(sizeof(device_type_s));
1574 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1576 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1579 if(*start_pos == NULL) {
1582 peer_ite = *start_pos;
1583 while(peer_ite->next != NULL) {
1584 /* move pointer to the last peer */
1585 peer_ite = peer_ite->next;
1587 peer_ite->next = peer;
1590 peer->is_alive = true;
1591 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1592 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1593 if (callback == NULL && peer->gl_item != NULL) {
1594 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1601 * This function let the ug update connected peers
1603 * @param[in] data the pointer to the main data structure
1605 void wfd_ug_update_connected_peers(void *data)
1609 struct ug_data *ugd = (struct ug_data *) data;
1612 bool is_group_owner = FALSE;
1613 Elm_Object_Item *item = NULL;
1615 res = wifi_direct_is_group_owner(&is_group_owner);
1616 if (res == WIFI_DIRECT_ERROR_NONE) {
1617 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1620 if (!ugd->conn_wfd_item) {
1621 _create_connected_dev_genlist(ugd);
1624 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1625 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1626 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1627 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1628 &ugd->gl_available_peer_cnt);
1629 wfd_check_gl_available_peers(ugd);
1632 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1633 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1634 &ugd->gl_multi_connect_peer_cnt);
1635 if (ugd->gl_multi_connect_peer_cnt == 0) {
1636 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1637 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1641 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1642 ugd->gl_connected_peer_cnt);
1643 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1644 &ugd->raw_connected_peers[i], NULL);
1648 ugd->gl_connected_peer_cnt++;
1652 /* if is not GO, free all available peers */
1653 if (is_group_owner == FALSE) {
1654 ugd->gl_available_peer_cnt = 0;
1655 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1657 if (ugd->gl_avlb_peers_start != NULL) {
1658 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1659 ugd->gl_avlb_peers_start = NULL;
1663 /* free busy peers */
1664 if (ugd->gl_busy_peers_start != NULL) {
1665 ugd->gl_busy_peer_cnt = 0;
1666 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1668 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1669 ugd->gl_busy_peers_start = NULL;
1677 * This function let the ug update the multi-connect peers
1679 * @param[in] data the pointer to the main data structure
1681 void wfd_ug_view_update_multiconn_peers(void *data)
1685 struct ug_data *ugd = (struct ug_data *) data;
1688 Elm_Object_Item *item = NULL;
1690 if (ugd->raw_multi_selected_peer_cnt > 0) {
1691 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1692 ugd->multi_connect_wfd_item == NULL) {
1693 _create_multi_connect_dev_genlist(ugd);
1696 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1697 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1698 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1699 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1700 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1701 &ugd->raw_multi_selected_peers[i], NULL);
1705 ugd->gl_multi_connect_peer_cnt++;
1714 * This function let the ug update the available and busy peers
1716 void wfd_ug_update_available_peers(void *data)
1720 struct ug_data *ugd = (struct ug_data *) data;
1721 int no_of_busy_dev = 0;
1722 int no_of_available_dev = 0;
1723 int no_of_conn_dev = 0;
1724 bool is_group_owner = FALSE;
1726 Elm_Object_Item *item = NULL;
1727 device_type_s *peer = NULL;
1728 GList *iterator = NULL;
1730 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1731 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1732 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1734 res = wifi_direct_is_group_owner(&is_group_owner);
1735 if (res != WIFI_DIRECT_ERROR_NONE) {
1736 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1737 ugd->I_am_group_owner = FALSE;
1739 ugd->I_am_group_owner = is_group_owner;
1742 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1743 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1744 DBG(LOG_INFO, "There are available or busy peers\n");
1745 wfd_free_nodivice_item(ugd);
1748 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1749 if (ugd->avlbl_wfd_item == NULL) {
1750 _create_available_dev_genlist(ugd);
1753 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1754 /* Not include the device which is connected with me */
1755 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1758 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1759 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1760 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1761 /* free disconnected gl peer */
1762 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1763 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1764 &ugd->gl_connected_peer_cnt);
1767 /* free busy gl peer, which is available now */
1768 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1769 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1770 if (ugd->gl_busy_peer_cnt == 0) {
1771 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1775 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL) {
1779 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1781 item = get_insert_postion((device_type_s *)iterator->data,
1782 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1783 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1784 (device_type_s *)iterator->data, _gl_peer_sel);
1788 ugd->gl_available_peer_cnt++;
1789 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1790 /* if peer is GO, free it */
1791 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1792 &ugd->gl_available_peer_cnt);
1798 wfd_check_gl_available_peers(ugd);
1799 wfd_check_gl_conn_peers(ugd);
1801 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1802 if (ugd->busy_wfd_item == NULL) {
1803 _create_busy_dev_list(ugd);
1806 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1807 /* Not include the device which is connected with me */
1808 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1811 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1812 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1813 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1814 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1815 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1816 &ugd->gl_available_peer_cnt);
1817 wfd_check_gl_available_peers(ugd);
1819 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1820 ugd->gl_busy_peer_cnt);
1821 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1822 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1826 ugd->gl_busy_peer_cnt++;
1832 wfd_check_gl_busy_peers(ugd);
1838 * This function let the ug update the failed peers
1840 * @param[in] data the pointer to the main data structure
1842 void wfd_ug_update_failed_peers(void *data)
1845 struct ug_data *ugd = (struct ug_data *) data;
1846 int no_of_conn_failed_dev = 0;
1847 GList *iterator = NULL;
1849 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1850 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1852 if (no_of_conn_failed_dev == 0) {
1856 /* add timer for disappearing failed peers after N secs */
1857 if (NULL == ugd->display_timer) {
1858 ugd->last_display_time = time(NULL);
1859 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1862 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1863 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1864 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1865 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1866 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1867 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1868 &ugd->gl_available_peer_cnt);
1869 wfd_check_gl_available_peers(ugd);
1878 #ifdef WFD_ON_OFF_GENLIST
1880 * This function is called when user swipes on/off button
1882 * @param[in] data the pointer to the main data structure
1883 * @param[in] obj the pointer to the evas object
1884 * @param[in] event_info the pointer to the event information
1886 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1889 struct ug_data *ugd = (struct ug_data *)data;
1890 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1891 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1892 wfd_refresh_wifi_direct_state(ugd);
1893 if(ugd->device_name_item != NULL)
1894 elm_genlist_item_update(ugd->device_name_item);
1896 elm_object_disabled_set(ugd->on_off_check, TRUE);
1897 if(ugd->disconnect_btn) {
1898 Evas_Object *content;
1899 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1900 WFD_IF_DEL_OBJ(content);
1901 ugd->disconnect_btn = NULL;
1903 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1905 /* turn on/off wfd */
1906 if (!ugd->wfd_onoff) {
1907 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1908 DBG(LOG_INFO, "wifi-direct switch on\n");
1909 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1911 wfd_client_switch_on(ugd);
1914 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1915 DBG(LOG_INFO, "wifi-direct switch off\n");
1916 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1918 wfd_client_switch_off(ugd);
1925 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1928 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1929 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1931 wfd_refresh_wifi_direct_state(ugd);
1932 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1933 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING ) {
1934 elm_object_disabled_set(ugd->on_off_check, TRUE);
1936 elm_object_disabled_set(ugd->on_off_check, FALSE);
1938 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1939 elm_check_state_set(ugd->on_off_check, TRUE);
1941 elm_check_state_set(ugd->on_off_check, FALSE);
1947 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1950 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1951 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1953 Evas_Object *check = elm_check_add(ugd->naviframe);
1954 elm_object_style_set(check, "naviframe/title_on&off");
1955 elm_check_state_set(check, ugd->wfd_onoff);
1956 evas_object_propagate_events_set(check, EINA_FALSE);
1957 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1958 elm_object_focus_allow_set(check, EINA_TRUE);
1959 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1960 evas_object_show(check);
1961 ugd->on_off_check = check;
1968 * This function let the ug create the main view
1970 * @param[in] data the pointer to the main data structure
1972 void create_wfd_ug_view(void *data)
1975 struct ug_data *ugd = (struct ug_data *) data;
1976 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1977 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1978 Evas_Object *more_btn;
1980 Evas_Object *layout;
1982 ugd->naviframe = elm_naviframe_add(ugd->base);
1983 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1984 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1985 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1986 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1988 ugd->back_btn = elm_button_add(ugd->naviframe);
1989 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1990 evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1991 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1994 layout = elm_layout_add(ugd->naviframe);
1995 elm_layout_theme_set(layout, "layout", "application", "default");
1996 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1997 ugd->layout = layout;
1999 ugd->genlist = _create_basic_genlist(ugd);
2000 if (ugd->genlist == NULL) {
2001 DBG(LOG_ERROR, "Failed to create basic genlist");
2004 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
2006 evas_object_show(ugd->base);
2007 elm_object_focus_set(ugd->base, EINA_TRUE);
2009 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
2010 ugd->back_btn, NULL, layout, NULL);
2011 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
2013 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
2014 more_btn = elm_button_add(ugd->naviframe);
2015 elm_object_style_set(more_btn, "naviframe/more/default");
2016 evas_object_smart_callback_add(more_btn, "clicked",
2017 _more_button_cb, ugd->win);
2018 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
2022 wifi_direct_initialize();
2023 wifi_direct_get_state(&ugd->wfd_status);
2024 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING) {
2025 scan_button_create(ugd);
2028 if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
2030 ugd->raw_discovered_peer_cnt = 0;
2031 wfd_create_multiconnect_view(ugd);
2032 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
2033 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
2034 if (ret != WIFI_DIRECT_ERROR_NONE) {
2035 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
2036 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
2037 wifi_direct_cancel_discovery();
2046 * This function let the ug destroy the main view
2048 * @param[in] data the pointer to the main data structure
2050 void destroy_wfd_ug_view(void *data)
2053 struct ug_data *ugd = (struct ug_data *) data;
2054 WFD_IF_DEL_ITEM(ugd->device_name_item);
2055 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2056 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2058 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2059 WFD_IF_DEL_OBJ(ugd->back_btn);
2060 WFD_IF_DEL_OBJ(ugd->toolbar);
2061 WFD_IF_DEL_OBJ(ugd->genlist);
2062 WFD_IF_DEL_OBJ(ugd->button_layout);
2063 WFD_IF_DEL_OBJ(ugd->layout);
2064 WFD_IF_DEL_OBJ(ugd->naviframe);