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);
104 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
105 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
106 if (ret != WIFI_DIRECT_ERROR_NONE)
107 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
109 ugd->mac_addr_connecting = NULL;
112 if (ugd->raw_connected_peer_cnt == 0) {
113 ret = wifi_direct_is_group_owner(&owner);
114 if (ret == WIFI_DIRECT_ERROR_NONE) {
116 wifi_direct_destroy_group();
121 wfd_ug_view_free_peers(ugd);
122 ret = app_control_create(&control);
124 DBG(LOG_ERROR, "Failed to create control");
126 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
127 app_control_add_extra_data(control, "Connection", "TRUE");
129 app_control_add_extra_data(control, "Connection", "FALSE");
131 ug_send_result(ugd->ug, control);
132 app_control_destroy(control);
135 ug_destroy_me(ugd->ug);
141 * This function let the ug call it when click 'back' button
143 * @param[in] data the pointer to the main data structure
144 * @param[in] obj the pointer to the evas object
145 * @param[in] event_info the pointer to the event information
147 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
150 struct ug_data *ugd = (struct ug_data *) data;
153 app_control_h control = NULL;
156 DBG(LOG_ERROR, "The param is NULL");
160 #ifdef WFD_DBUS_LAUNCH
161 if (ugd->dbus_cancellable != NULL) {
162 g_cancellable_cancel(ugd->dbus_cancellable);
163 g_object_unref(ugd->dbus_cancellable);
164 ugd->dbus_cancellable = NULL;
166 g_object_unref(ugd->conn);
169 DBG(LOG_INFO, "Cancel dbus call");
173 wfd_refresh_wifi_direct_state(ugd);
174 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
175 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
179 if (NULL != ugd->mac_addr_connecting) {
180 if (ugd->is_conn_incoming) {
181 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
182 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
183 if (ret != WIFI_DIRECT_ERROR_NONE)
184 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
186 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
187 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
188 if (ret != WIFI_DIRECT_ERROR_NONE)
189 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
191 ugd->mac_addr_connecting = NULL;
194 if (ugd->raw_connected_peer_cnt == 0) {
195 ret = wifi_direct_is_group_owner(&owner);
196 if (ret == WIFI_DIRECT_ERROR_NONE) {
198 wifi_direct_destroy_group();
203 wfd_ug_view_free_peers(ugd);
204 ret = app_control_create(&control);
206 DBG(LOG_ERROR, "Failed to create control");
208 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
209 app_control_add_extra_data(control, "Connection", "TRUE");
211 app_control_add_extra_data(control, "Connection", "FALSE");
213 ug_send_result(ugd->ug, control);
214 app_control_destroy(control);
217 ug_destroy_me(ugd->ug);
222 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
226 if (ugd->timer_stop_progress_bar > 0)
227 g_source_remove(ugd->timer_stop_progress_bar);
229 ugd->timer_stop_progress_bar = 0;
234 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
238 if (ugd->timer_delete_not_alive_peer > 0)
239 g_source_remove(ugd->timer_delete_not_alive_peer);
241 ugd->timer_delete_not_alive_peer = 0;
247 * This function let the ug call it when click failed devices item
249 * @param[in] data the pointer to the main data structure
250 * @param[in] obj the pointer to the evas object
251 * @param[in] event_info the pointer to the event information
253 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
257 struct ug_data *ugd = wfd_get_ug_data();
261 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
265 if (ugd->display_timer != NULL) {
266 ecore_timer_del(ugd->display_timer);
267 ugd->display_timer = NULL;
270 wfd_refresh_wifi_direct_state(ugd);
271 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
273 /* if connected, show the popup*/
274 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
275 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);
277 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
278 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
279 if (ret != WIFI_DIRECT_ERROR_NONE) {
280 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
281 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
282 wifi_direct_cancel_discovery();
291 * This function let the ug call it when click 'scan' button
293 * @param[in] data the pointer to the main data structure
294 * @param[in] obj the pointer to the evas object
295 * @param[in] event_info the pointer to the event information
297 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
301 struct ug_data *ugd = (struct ug_data *) data;
303 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
307 const char *btn_text = NULL;
308 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
309 DBG(LOG_INFO, "Button text=%s", btn_text);
311 if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
312 wfd_refresh_wifi_direct_state(ugd);
313 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
314 /* if connected, show the popup*/
315 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
316 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);
317 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
318 wfd_client_switch_on(ugd);
322 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
323 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
324 if (ret != WIFI_DIRECT_ERROR_NONE) {
325 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
326 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
327 wifi_direct_cancel_discovery();
330 } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
331 DBG(LOG_INFO, "Stop pressed.\n");
332 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
333 wfd_cancel_progressbar_stop_timer(ugd);
334 wfd_delete_progressbar_cb(ugd);
335 wfd_cancel_not_alive_delete_timer(ugd);
336 } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
337 DBG(LOG_INFO, "Cancel Connection");
338 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
340 DBG(LOG_INFO, "Invalid Case\n");
346 void wfd_check_gl_busy_peers(struct ug_data *ugd)
349 if (ugd->gl_busy_peer_cnt == 0)
350 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
355 void wfd_check_gl_available_peers(struct ug_data *ugd)
358 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL)
359 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
365 * This function let the ug free some peer in genlist
367 * @param[in] start_pos the start position of peers list
368 * @param[in] mac_addr the mac_addr of peer for free
369 * @param[in] cnt the count of gl peers in list
371 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
374 device_type_s *peer = *start_pos;
375 device_type_s *peer_tmp = peer;
378 DBG(LOG_INFO, "no peer in genlist");
383 if (strcmp(peer->mac_addr, mac_addr)) {
387 if (peer->next != NULL) {
388 peer_tmp->next = peer->next;
391 peer_tmp->next = NULL;
397 if (peer == *start_pos) {
398 DBG(LOG_INFO, "the head is free");
399 *start_pos = peer->next;
404 WFD_IF_DEL_ITEM(peer->gl_item);
412 * This function let the ug call it when click available peer to connect
414 * @param[in] data the pointer to the main data structure
415 * @param[in] obj the pointer to the evas object
416 * @param[in] event_info the pointer to the event information
418 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
423 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
424 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
425 bool is_peer_alive = false;
426 struct ug_data *ugd = wfd_get_ug_data();
427 device_type_s *peer = (device_type_s *)data;
428 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
429 char *format_str = NULL;
432 DBG(LOG_ERROR, "NULL parameters.\n");
436 wfd_ug_get_connected_peers(ugd);
437 DBG(LOG_INFO, "No of connected peers= %d", ugd->raw_connected_peer_cnt);
439 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
440 format_str = D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME");
441 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, format_str, MAX_CONNECTED_PEER_NUM);
442 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
444 elm_genlist_item_selected_set(item, EINA_FALSE);
449 if (ugd->disconnect_btn) {
450 Evas_Object *content;
451 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
452 WFD_IF_DEL_OBJ(content);
453 ugd->disconnect_btn = NULL;
454 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
458 elm_genlist_item_selected_set(item, EINA_FALSE);
460 GList *iterator = NULL;
462 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
463 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
464 /* peer is found in last discovery */
465 is_peer_alive = true;
470 if (!is_peer_alive) {
471 /* peer exists only in genlist, waiting to be deleted */
472 device_type_s *peer_start = ugd->gl_avlb_peers_start;
473 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
474 if (!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
475 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
476 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
477 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
478 wfd_check_gl_available_peers(ugd);
479 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
485 wfd_cancel_not_alive_delete_timer(ugd);
488 wfd_refresh_wifi_direct_state(ugd);
490 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
491 peer->is_group_owner == TRUE) {
492 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
493 MAC2SECSTR(peer->mac_addr));
495 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
496 DBG(LOG_DEBUG, "It's in connecting status now.\n");
500 ugd->mac_addr_connecting = peer->mac_addr;
501 res = wfd_client_connect((const char *)peer->mac_addr);
503 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
513 * This function let the ug call it when click busy peer
515 * @param[in] data the pointer to the main data structure
516 * @param[in] obj the pointer to the evas object
517 * @param[in] event_info the pointer to the event information
519 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
522 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
523 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
526 elm_genlist_item_selected_set(item, EINA_FALSE);
529 DBG(LOG_ERROR, "Data is NULL\n");
533 wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
538 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
540 struct ug_data *ugd = (struct ug_data *) data;
543 DBG(LOG_ERROR, "The param is NULL\n");
548 evas_object_del(ugd->ctxpopup);
549 ugd->ctxpopup = NULL;
553 void _ctxpopup_move()
557 int win_w = 0, win_h = 0;
558 int move_x = 0, move_y = 0;
560 struct ug_data *ugd = wfd_get_ug_data();
562 if (!ugd || !ugd->win) {
563 DBG(LOG_ERROR, "NULL parameters.\n");
567 if (!ugd->ctxpopup) {
568 DBG(LOG_INFO, "NULL parameters.\n");
572 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
573 changed_ang = elm_win_rotation_get(ugd->win);
575 switch (changed_ang) {
598 evas_object_move(ugd->ctxpopup, move_x, move_y);
603 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
606 struct ug_data *ugd = (struct ug_data *) data;
607 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
608 WFD_IF_DEL_OBJ(ugd->ctxpopup);
611 wfd_client_free_raw_discovered_peers(ugd);
612 ugd->raw_discovered_peer_cnt = 0;
613 wfd_create_multiconnect_view(ugd);
614 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
615 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
616 if (ret != WIFI_DIRECT_ERROR_NONE) {
617 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
618 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
619 wifi_direct_cancel_discovery();
625 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
629 Evas_Object *naviframe = (Evas_Object *)data;
630 Elm_Object_Item *multi_connect_item = NULL;
631 Elm_Object_Item *rename_item = NULL;
632 struct ug_data *ugd = wfd_get_ug_data();
634 if (!naviframe || !ugd) {
635 DBG(LOG_ERROR, "NULL parameters.\n");
639 ugd->more_btn_multiconnect_item = NULL;
642 evas_object_del(ugd->ctxpopup);
644 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
645 elm_object_style_set(ugd->ctxpopup, "more/default");
646 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
647 eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
648 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
649 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
651 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
652 ELM_CTXPOPUP_DIRECTION_LEFT,
653 ELM_CTXPOPUP_DIRECTION_RIGHT,
654 ELM_CTXPOPUP_DIRECTION_DOWN);
658 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
659 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
660 ugd->more_btn_multiconnect_item = multi_connect_item;
662 wfd_refresh_wifi_direct_state(ugd);
663 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
664 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
665 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
666 ugd->raw_connected_peer_cnt > 0) {
667 elm_object_item_disabled_set(multi_connect_item, TRUE);
670 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
671 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
672 evas_object_show(ugd->ctxpopup);
678 * This function make items into group
680 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
684 if (count < 1 || pre_item == NULL)
687 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
692 elm_object_item_signal_emit(item, "elm,state,normal", "");
696 for (i = 0; i < count; i++) {
698 elm_object_item_signal_emit(item, "elm,state,top", "");
699 else if (i == count - 1)
700 elm_object_item_signal_emit(item, "elm,state,bottom", "");
702 elm_object_item_signal_emit(item, "elm,state,center", "");
704 item = elm_genlist_item_next_get(item);
710 * This function let the ug call it when unresized event is received
712 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
715 struct ug_data *ugd = (struct ug_data *)data;
717 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
718 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
719 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
720 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
721 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
726 * This function let the ug call it when resized event is received
728 * @param[in] data the pointer to the main data structure
729 * @param[in] obj the pointer to the evas object
730 * @param[in] event_info the pointer to the event information
732 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
736 if (!data || !event_info) {
737 DBG(LOG_ERROR, "Invalid parameters");
741 struct ug_data *ugd = (struct ug_data *)data;
742 #ifdef ACCESSIBILITY_FEATURE
743 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
744 int index = elm_genlist_item_index_get(item);
748 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
749 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
750 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
751 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
752 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
754 #ifdef ACCESSIBILITY_FEATURE
756 if (GENLIST_HEADER_POS == index && item != NULL) {
757 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
759 Eina_Bool state = elm_check_state_get(check);
761 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
763 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
766 Evas_Object *ao = NULL;
767 ao = elm_object_item_access_object_get(item);
768 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
771 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
774 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
783 * This function let the ug call it when click 'disconnect' button
785 * @param[in] data the pointer to the main data structure
786 * @param[in] obj the pointer to the evas object
787 * @param[in] event_info the pointer to the event information
789 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
792 struct ug_data *ugd = (struct ug_data *)data;
793 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
795 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
801 * This function let the ug call it when click "cancel connection" button
803 * @param[in] data the pointer to the main data structure
804 * @param[in] obj the pointer to the evas object
805 * @param[in] event_info the pointer to the event information
807 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
810 struct ug_data *ugd = (struct ug_data *)data;
811 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
813 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
820 * This function let the ug update the genlist item
822 * @param[in] gl_item the pointer to genlist item
824 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
828 elm_genlist_item_update(gl_item);
834 * This function let the ug refresh the attributes of button
836 * @param[in] tb_item the pointer to the toolbar button
837 * @param[in] text the pointer to the text of button
838 * @param[in] enable whether the button is disabled
840 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
845 if (NULL == tb_item || NULL == text) {
846 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
850 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
851 elm_object_domain_translatable_part_text_set(tb_item, "default",
853 elm_object_disabled_set(tb_item, !enable);
859 * This function let the ug know whether current device is connected by me
860 * @return If connected, return TRUE, else return FALSE
861 * @param[in] ugd the pointer to the main data structure
862 * @param[in] dev the pointer to the device
864 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
869 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
870 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
871 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
881 * This function let the ug know whether current device is connected by other peer
882 * @return If connected, return TRUE, else return FALSE
883 * @param[in] ugd the pointer to the main data structure
884 * @param[in] dev the pointer to the device
886 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
890 if (ugd->I_am_group_owner == TRUE) {
891 if (dev->is_connected || dev->is_group_owner)
896 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE)
899 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE)
902 if (dev->is_connected == FALSE)
911 * This function let the ug calculate how many devices are available
913 * @param[in] ugd the pointer to the main data structure
914 * @param[in] dev the pointer to the number of available devices
916 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
919 GList *iterator = NULL;
921 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
922 /* Not include the device which is connected with me */
923 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
926 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
927 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT)
928 (*no_of_available_dev)++;
936 * This function let the ug calculate how many devices are busy
938 * @param[in] ugd the pointer to the main data structure
939 * @param[in] dev the pointer to the number of busy devices
941 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
944 GList *iterator = NULL;
946 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
947 /* Not include the device which is connected with me */
948 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
951 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data))
960 * This function let the ug calculate how many devices are connected failed
962 * @param[in] ugd the pointer to the main data structure
963 * @param[in] dev the pointer to the number of connected failed devices
965 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
968 GList *iterator = NULL;
970 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
971 /* Not include the device which is connected with me */
972 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
975 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
976 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
977 (*no_of_connect_failed_dev)++;
986 * This function let the ug create the main genlist
987 * @return the main genlist
988 * @param[in] data the pointer to the main data structure
990 static Evas_Object *_create_basic_genlist(void *data)
993 struct ug_data *ugd = (struct ug_data *) data;
994 Evas_Object *genlist;
996 genlist = elm_genlist_add(ugd->layout);
998 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
999 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
1001 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1003 /* Wifi ON/OFF toggle button */
1004 #ifdef WFD_ON_OFF_GENLIST
1005 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
1006 NULL, ELM_GENLIST_ITEM_NONE, _onoff_changed_cb, ugd);
1007 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1010 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
1011 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
1012 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
1013 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1014 if (ugd->device_name_item != NULL)
1015 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1022 * This function let the ug create no device item to append the genlist
1023 * @return the main item
1024 * @param[in] data the pointer to the main data structure
1026 Evas_Object *_create_no_device_genlist(void *data)
1029 struct ug_data *ugd = (struct ug_data *) data;
1030 Elm_Object_Item *last_item = NULL;
1033 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1035 if (ugd->conn_wfd_item != NULL) {
1036 last_item = ugd->conn_wfd_item;
1037 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1038 last_item = elm_genlist_item_next_get(last_item);
1041 last_item = ugd->device_name_item;
1044 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1045 &title_no_device_itc, (void *)ugd, NULL, last_item,
1046 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1047 if (ugd->nodevice_title_item != NULL)
1048 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1050 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1051 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1052 if (ugd->nodevice_item != NULL)
1053 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1056 return ugd->genlist;
1060 * This function let the ug create busy device list
1062 * @param[in] data the pointer to the main data structure
1064 int _create_busy_dev_list(void *data)
1067 struct ug_data *ugd = (struct ug_data *) data;
1069 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1070 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1071 if (ugd->busy_wfd_item != NULL)
1072 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1077 void wfd_free_nodivice_item(struct ug_data *ugd)
1080 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1081 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1086 * This function let the ug create available device list
1088 * @param[in] data the pointer to the main data structure
1090 int _create_available_dev_genlist(void *data)
1094 struct ug_data *ugd = (struct ug_data *) data;
1095 Elm_Object_Item *last_item = NULL;
1097 wfd_free_nodivice_item(ugd);
1099 if (ugd->conn_wfd_item != NULL) {
1100 last_item = ugd->conn_wfd_item;
1101 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1102 last_item = elm_genlist_item_next_get(last_item);
1105 last_item = ugd->device_name_item;
1108 ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1109 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1110 if (ugd->avlbl_wfd_item != NULL) {
1111 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1112 elm_genlist_item_update(ugd->avlbl_wfd_item);
1119 * This function let the ug create multi connect device list
1121 * @param[in] data the pointer to the main data structure
1123 static int _create_multi_connect_dev_genlist(void *data)
1126 struct ug_data *ugd = (struct ug_data *) data;
1128 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1129 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1130 if (ugd->multi_connect_wfd_item != NULL)
1131 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1137 * This function let the ug create connected device list
1139 * @param[in] data the pointer to the main data structure
1141 int _create_connected_dev_genlist(void *data)
1144 struct ug_data *ugd = (struct ug_data *) data;
1146 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1147 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1148 if (ugd->conn_wfd_item != NULL) {
1149 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1150 elm_genlist_item_update(ugd->conn_wfd_item);
1158 * This function let the ug create connected falied device list
1160 * @param[in] data the pointer to the main data structure
1162 int _create_connected_failed_dev_genlist(void *data)
1165 struct ug_data *ugd = (struct ug_data *) data;
1166 Elm_Object_Item *last_item = NULL;
1169 if (ugd->avlbl_wfd_item != NULL) {
1170 last_item = ugd->avlbl_wfd_item;
1171 for (i = 0; i < ugd->gl_available_peer_cnt; i++)
1172 last_item = elm_genlist_item_next_get(last_item);
1174 } else if (ugd->conn_wfd_item != NULL) {
1175 last_item = ugd->conn_wfd_item;
1176 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1177 last_item = elm_genlist_item_next_get(last_item);
1180 last_item = ugd->device_name_item;
1183 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1184 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1185 if (ugd->conn_failed_wfd_item != NULL)
1186 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1192 * This function let the ug make the display callback for connect failed peers
1193 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1194 * @param[in] data the pointer to the user data
1196 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1201 struct ug_data *ugd = (struct ug_data *) user_data;
1204 DBG(LOG_ERROR, "NULL parameters.\n");
1205 return ECORE_CALLBACK_CANCEL;
1208 if (ugd->avlbl_wfd_item == NULL)
1209 _create_available_dev_genlist(ugd);
1211 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1212 DBG(LOG_INFO, "Background mode\n");
1213 ugd->display_timer = NULL;
1214 return ECORE_CALLBACK_CANCEL;
1217 /* check the timeout, if not timeout, keep the cb */
1218 interval = time(NULL) - ugd->last_display_time;
1219 if (interval < MAX_DISPLAY_TIME_OUT)
1220 return ECORE_CALLBACK_RENEW;
1222 if (ugd->is_paused == false) {
1223 DBG(LOG_INFO, "Not Paused");
1224 /* start discovery again */
1225 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1226 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1227 if (res != WIFI_DIRECT_ERROR_NONE) {
1228 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1229 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1230 wifi_direct_cancel_discovery();
1234 ugd->display_timer = NULL;
1236 return ECORE_CALLBACK_CANCEL;
1239 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1242 device_type_s *peer_for_free = NULL;
1243 device_type_s *peer = gl_peers_start;
1245 while (peer != NULL && peer->gl_item != NULL) {
1246 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1247 elm_object_item_del(peer->gl_item);
1248 peer->gl_item = NULL;
1249 peer_for_free = peer;
1251 free(peer_for_free);
1256 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1259 if (ugd->gl_connected_peer_cnt == 0)
1260 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1266 * This function let the ug free the peers
1268 * @param[in] data the pointer to the main data structure
1270 void wfd_ug_view_free_peers(void *data)
1274 struct ug_data *ugd = (struct ug_data *) data;
1276 ugd->gl_connected_peer_cnt = 0;
1278 if (ugd->gl_conn_peers_start != NULL) {
1279 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1280 ugd->gl_conn_peers_start = NULL;
1283 ugd->gl_available_peer_cnt = 0;
1285 if (ugd->gl_avlb_peers_start != NULL) {
1286 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1287 ugd->gl_avlb_peers_start = NULL;
1290 ugd->gl_busy_peer_cnt = 0;
1292 if (ugd->gl_busy_peers_start != NULL) {
1293 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1294 ugd->gl_busy_peers_start = NULL;
1297 ugd->gl_multi_connect_peer_cnt = 0;
1299 if (ugd->gl_mul_conn_peers_start != NULL) {
1300 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1301 ugd->gl_mul_conn_peers_start = NULL;
1304 if (ugd->gl_connected_peer_cnt == 0)
1305 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1307 if (ugd->display_timer != NULL) {
1308 ecore_timer_del(ugd->display_timer);
1309 ugd->display_timer = NULL;
1312 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1313 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1314 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1315 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1320 void wfd_ug_update_toolbar(struct ug_data *ugd)
1323 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1326 wfd_refresh_wifi_direct_state(ugd);
1327 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1328 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1329 if (ugd->multi_connect_wfd_item != NULL) {
1330 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1331 btn = elm_button_add(ugd->button_layout);
1332 /* Use "bottom" style button */
1333 elm_object_style_set(btn, "bottom");
1334 elm_object_domain_translatable_text_set(btn, PACKAGE,
1335 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1336 evas_object_smart_callback_add(btn, "clicked",
1337 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1338 /* Set button into "toolbar" swallow part */
1339 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1340 ugd->disconnect_btn = btn;
1341 evas_object_show(ugd->disconnect_btn);
1342 elm_object_part_content_set(ugd->button_layout, "button.prev",
1344 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1345 "IDS_WIFI_SK4_SCAN", FALSE);
1346 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1347 DBG(LOG_INFO, "button: disconnect button added\n");
1349 DBG(LOG_INFO, "scan_toolbar\n");
1350 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1351 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1352 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1353 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1354 DBG(LOG_INFO, "button: stop connect button added\n");
1356 } else if (no_of_conn_dev > 0) {
1357 if (!ugd->multi_connect_toolbar_item) {
1358 btn = elm_button_add(ugd->button_layout);
1359 /* Use "bottom" style button */
1360 elm_object_style_set(btn, "bottom");
1361 elm_object_domain_translatable_text_set(btn, PACKAGE,
1362 "IDS_WIFI_SK_DISCONNECT");
1363 evas_object_smart_callback_add(btn, "clicked",
1364 _wfd_ug_disconnect_button_cb, (void *)ugd);
1365 /* Set button into "toolbar" swallow part */
1366 elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1367 ugd->disconnect_btn = btn;
1368 evas_object_show(ugd->disconnect_btn);
1369 DBG(LOG_INFO, "button: disconnect button added\n");
1371 elm_object_part_content_set(ugd->button_layout, "button.prev",
1373 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1374 "IDS_WIFI_SK4_SCAN", TRUE);
1375 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1376 DBG(LOG_INFO, "button: scan button added\n");
1378 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1379 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1380 Evas_Object *content;
1381 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1382 WFD_IF_DEL_OBJ(content);
1383 ugd->disconnect_btn = NULL;
1384 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1386 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1387 "IDS_WIFI_SK4_SCAN", TRUE);
1388 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1389 DBG(LOG_INFO, "button: scan button added\n");
1395 * This function let the ug init the genlist
1397 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1400 struct ug_data *ugd = (struct ug_data *) data;
1401 int no_of_busy_dev = 0;
1402 int no_of_available_dev = 0;
1403 int no_of_conn_failed_dev = 0;
1405 if (is_free_all_peers)
1406 wfd_ug_view_free_peers(ugd);
1408 if (ugd->gl_failed_peers_start != NULL) {
1409 DBG(LOG_INFO, "These are failed peers, must clear them");
1410 ugd->gl_connected_failed_peer_cnt = 0;
1411 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1412 ugd->gl_failed_peers_start = NULL;
1413 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1416 if (ugd->avlbl_wfd_item != NULL) {
1417 DBG(LOG_INFO, "There are available peers in genlist");
1418 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1422 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1423 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1424 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1430 * This function let the ug find a peer in genlist
1432 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1436 if (start_pos == NULL) {
1437 DBG(LOG_INFO, "no peer in genlist");
1441 device_type_s *peer = start_pos;
1443 while (peer != NULL) {
1444 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1445 peer->is_alive = true;
1446 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1457 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1460 if (*start_pos == NULL) {
1461 DBG(LOG_INFO, "no peer in genlist");
1465 device_type_s *peer = *start_pos;
1466 device_type_s *peer_tmp = NULL;
1467 while (peer != NULL) {
1468 peer_tmp = peer->next;
1469 if (peer->is_alive == false)
1470 free_gl_peer(start_pos, peer->mac_addr, cnt);
1475 // wfd_check_gl_available_peers(ugd);
1476 if (ugd->gl_busy_peer_cnt == 0)
1477 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1483 void set_not_alive_peers(device_type_s *start_pos)
1486 if (start_pos == NULL) {
1487 DBG(LOG_INFO, "no peer in genlist");
1491 device_type_s *peer = start_pos;
1492 while (peer != NULL) {
1493 peer->is_alive = false;
1502 * This function let the ug get the insert position for next item
1504 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1508 device_type_s *peer_ite = NULL;
1509 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1510 Elm_Object_Item *item = NULL;
1512 if (peer_cnt == 0) {
1513 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1517 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1518 if (peer_ite->gl_item != NULL) {
1519 for (i = 0; i < peer_cnt; i++) {
1520 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1521 /* if peer_ite is greater than peer, return previous item */
1523 return elm_genlist_item_prev_get(head);
1525 item = elm_genlist_item_next_get(head);
1527 /* return the last item */
1531 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1537 return elm_genlist_item_prev_get(head);
1541 * This function let the ug insert peer item to genlist
1543 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1544 device_type_s *peer_for_insert, void *callback)
1547 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1548 device_type_s *peer = NULL;
1549 device_type_s *peer_ite = NULL;
1551 peer = (device_type_s *)malloc(sizeof(device_type_s));
1552 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1554 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1557 if (*start_pos == NULL) {
1560 peer_ite = *start_pos;
1561 while (peer_ite->next != NULL) {
1562 /* move pointer to the last peer */
1563 peer_ite = peer_ite->next;
1565 peer_ite->next = peer;
1568 peer->is_alive = true;
1569 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1570 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1571 if (callback == NULL && peer->gl_item != NULL)
1572 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1579 * This function let the ug update connected peers
1581 * @param[in] data the pointer to the main data structure
1583 void wfd_ug_update_connected_peers(void *data)
1587 struct ug_data *ugd = (struct ug_data *) data;
1590 bool is_group_owner = FALSE;
1591 Elm_Object_Item *item = NULL;
1593 res = wifi_direct_is_group_owner(&is_group_owner);
1594 if (res == WIFI_DIRECT_ERROR_NONE)
1595 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1597 if (!ugd->conn_wfd_item)
1598 _create_connected_dev_genlist(ugd);
1600 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1601 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1602 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1603 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1604 &ugd->gl_available_peer_cnt);
1605 wfd_check_gl_available_peers(ugd);
1608 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1609 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1610 &ugd->gl_multi_connect_peer_cnt);
1611 if (ugd->gl_multi_connect_peer_cnt == 0) {
1612 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1613 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1617 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1618 ugd->gl_connected_peer_cnt);
1619 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1620 &ugd->raw_connected_peers[i], NULL);
1624 ugd->gl_connected_peer_cnt++;
1628 /* if is not GO, free all available peers */
1629 if (is_group_owner == FALSE) {
1630 ugd->gl_available_peer_cnt = 0;
1631 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1633 if (ugd->gl_avlb_peers_start != NULL) {
1634 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1635 ugd->gl_avlb_peers_start = NULL;
1639 /* free busy peers */
1640 if (ugd->gl_busy_peers_start != NULL) {
1641 ugd->gl_busy_peer_cnt = 0;
1642 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1644 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1645 ugd->gl_busy_peers_start = NULL;
1653 * This function let the ug update the multi-connect peers
1655 * @param[in] data the pointer to the main data structure
1657 void wfd_ug_view_update_multiconn_peers(void *data)
1661 struct ug_data *ugd = (struct ug_data *) data;
1664 Elm_Object_Item *item = NULL;
1666 if (ugd->raw_multi_selected_peer_cnt > 0) {
1667 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1668 ugd->multi_connect_wfd_item == NULL) {
1669 _create_multi_connect_dev_genlist(ugd);
1672 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1673 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1674 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1675 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1676 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1677 &ugd->raw_multi_selected_peers[i], NULL);
1681 ugd->gl_multi_connect_peer_cnt++;
1690 * This function let the ug update the available and busy peers
1692 void wfd_ug_update_available_peers(void *data)
1696 struct ug_data *ugd = (struct ug_data *) data;
1697 int no_of_busy_dev = 0;
1698 int no_of_available_dev = 0;
1699 int no_of_conn_dev = 0;
1700 bool is_group_owner = FALSE;
1702 Elm_Object_Item *item = NULL;
1703 device_type_s *peer = NULL;
1704 GList *iterator = NULL;
1706 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1707 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1708 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1710 res = wifi_direct_is_group_owner(&is_group_owner);
1711 if (res != WIFI_DIRECT_ERROR_NONE) {
1712 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1713 ugd->I_am_group_owner = FALSE;
1715 ugd->I_am_group_owner = is_group_owner;
1718 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1719 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1720 DBG(LOG_INFO, "There are available or busy peers\n");
1721 wfd_free_nodivice_item(ugd);
1724 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1725 if (ugd->avlbl_wfd_item == NULL)
1726 _create_available_dev_genlist(ugd);
1729 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1730 /* Not include the device which is connected with me */
1731 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1734 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1735 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1736 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1737 /* free disconnected gl peer */
1738 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1739 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1740 &ugd->gl_connected_peer_cnt);
1743 /* free busy gl peer, which is available now */
1744 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1745 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1746 if (ugd->gl_busy_peer_cnt == 0)
1747 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1750 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL)
1753 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1755 item = get_insert_postion((device_type_s *)iterator->data,
1756 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1757 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1758 (device_type_s *)iterator->data, _gl_peer_sel);
1762 ugd->gl_available_peer_cnt++;
1763 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1764 /* if peer is GO, free it */
1765 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1766 &ugd->gl_available_peer_cnt);
1772 wfd_check_gl_available_peers(ugd);
1773 wfd_check_gl_conn_peers(ugd);
1775 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1776 if (ugd->busy_wfd_item == NULL)
1777 _create_busy_dev_list(ugd);
1779 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1780 /* Not include the device which is connected with me */
1781 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1784 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1785 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1786 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1787 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1788 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1789 &ugd->gl_available_peer_cnt);
1790 wfd_check_gl_available_peers(ugd);
1792 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1793 ugd->gl_busy_peer_cnt);
1794 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1795 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1799 ugd->gl_busy_peer_cnt++;
1805 wfd_check_gl_busy_peers(ugd);
1811 * This function let the ug update the failed peers
1813 * @param[in] data the pointer to the main data structure
1815 void wfd_ug_update_failed_peers(void *data)
1818 struct ug_data *ugd = (struct ug_data *) data;
1819 int no_of_conn_failed_dev = 0;
1820 GList *iterator = NULL;
1822 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1823 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1825 if (no_of_conn_failed_dev == 0)
1828 /* add timer for disappearing failed peers after N secs */
1829 if (NULL == ugd->display_timer) {
1830 ugd->last_display_time = time(NULL);
1831 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1834 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1835 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1836 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1837 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1838 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1839 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1840 &ugd->gl_available_peer_cnt);
1841 wfd_check_gl_available_peers(ugd);
1850 #ifdef WFD_ON_OFF_GENLIST
1852 * This function is called when user swipes on/off button
1854 * @param[in] data the pointer to the main data structure
1855 * @param[in] obj the pointer to the evas object
1856 * @param[in] event_info the pointer to the event information
1858 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1861 struct ug_data *ugd = (struct ug_data *)data;
1862 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1863 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1864 wfd_refresh_wifi_direct_state(ugd);
1865 if (ugd->device_name_item != NULL)
1866 elm_genlist_item_update(ugd->device_name_item);
1868 elm_object_disabled_set(ugd->on_off_check, TRUE);
1869 if (ugd->disconnect_btn) {
1870 Evas_Object *content;
1871 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1872 WFD_IF_DEL_OBJ(content);
1873 ugd->disconnect_btn = NULL;
1875 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1877 /* turn on/off wfd */
1878 if (!ugd->wfd_onoff) {
1879 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1880 DBG(LOG_INFO, "wifi-direct switch on\n");
1881 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1883 wfd_client_switch_on(ugd);
1886 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1887 DBG(LOG_INFO, "wifi-direct switch off\n");
1888 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1890 wfd_client_switch_off(ugd);
1897 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1900 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1901 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1903 wfd_refresh_wifi_direct_state(ugd);
1904 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1905 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING)
1906 elm_object_disabled_set(ugd->on_off_check, TRUE);
1908 elm_object_disabled_set(ugd->on_off_check, FALSE);
1910 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
1911 elm_check_state_set(ugd->on_off_check, TRUE);
1913 elm_check_state_set(ugd->on_off_check, FALSE);
1918 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1921 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1922 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1924 Evas_Object *check = elm_check_add(ugd->naviframe);
1925 elm_object_style_set(check, "naviframe/title_on&off");
1926 elm_check_state_set(check, ugd->wfd_onoff);
1927 evas_object_propagate_events_set(check, EINA_FALSE);
1928 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1929 elm_object_focus_allow_set(check, EINA_TRUE);
1930 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1931 evas_object_show(check);
1932 ugd->on_off_check = check;
1939 * This function let the ug create the main view
1941 * @param[in] data the pointer to the main data structure
1943 void create_wfd_ug_view(void *data)
1946 struct ug_data *ugd = (struct ug_data *) data;
1947 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1948 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1949 Evas_Object *more_btn;
1951 Evas_Object *layout;
1953 ugd->naviframe = elm_naviframe_add(ugd->base);
1954 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1955 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1956 eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1957 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1959 ugd->back_btn = elm_button_add(ugd->naviframe);
1960 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1961 evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1962 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1965 layout = elm_layout_add(ugd->naviframe);
1966 elm_layout_theme_set(layout, "layout", "application", "default");
1967 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1968 ugd->layout = layout;
1970 ugd->genlist = _create_basic_genlist(ugd);
1971 if (ugd->genlist == NULL) {
1972 DBG(LOG_ERROR, "Failed to create basic genlist");
1975 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1977 evas_object_show(ugd->base);
1978 elm_object_focus_set(ugd->base, EINA_TRUE);
1980 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1981 ugd->back_btn, NULL, layout, NULL);
1982 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1984 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1985 more_btn = elm_button_add(ugd->naviframe);
1986 elm_object_style_set(more_btn, "naviframe/more/default");
1987 evas_object_smart_callback_add(more_btn, "clicked",
1988 _more_button_cb, ugd->win);
1989 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1993 wifi_direct_initialize();
1994 wifi_direct_get_state(&ugd->wfd_status);
1995 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING)
1996 scan_button_create(ugd);
1998 if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
2000 ugd->raw_discovered_peer_cnt = 0;
2001 wfd_create_multiconnect_view(ugd);
2002 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
2003 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
2004 if (ret != WIFI_DIRECT_ERROR_NONE) {
2005 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
2006 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
2007 wifi_direct_cancel_discovery();
2016 * This function let the ug destroy the main view
2018 * @param[in] data the pointer to the main data structure
2020 void destroy_wfd_ug_view(void *data)
2023 struct ug_data *ugd = (struct ug_data *) data;
2024 WFD_IF_DEL_ITEM(ugd->device_name_item);
2025 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2026 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2028 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2029 WFD_IF_DEL_OBJ(ugd->back_btn);
2030 WFD_IF_DEL_OBJ(ugd->toolbar);
2031 WFD_IF_DEL_OBJ(ugd->genlist);
2032 WFD_IF_DEL_OBJ(ugd->button_layout);
2033 WFD_IF_DEL_OBJ(ugd->layout);
2034 WFD_IF_DEL_OBJ(ugd->naviframe);