517392f21d21a247ace452cf0c5c024b431487fa
[apps/native/ug-wifi-direct.git] / ug-wifidirect / src / wfd_ug_main_view.c
1 /*
2 *  WiFi-Direct UG
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://www.tizenopensource.org/license
11
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.
17 *
18 */
19
20
21 #include <libintl.h>
22 #include <glib.h>
23
24 #include <Elementary.h>
25 #include <vconf.h>
26 #include <ui-gadget-module.h>
27 #include <app_control.h>
28 #include <efl_extension.h>
29
30 #include "wfd_ug.h"
31 #include "wfd_ug_view.h"
32 #include "wfd_client.h"
33
34 void scan_button_create(struct ug_data *ugd)
35 {
36         __FUNC_ENTER__;
37
38         Evas_Object *btn_ly = NULL;
39         Evas_Object *btn = NULL;
40
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;
44
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",
50                         FALSE);
51         }
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;
55
56         elm_object_part_content_set(ugd->naviframe, "toolbar", ugd->button_layout);
57         evas_object_show(ugd->button_layout);
58
59         __FUNC_EXIT__;
60 }
61
62 /**
63  *      This function let the ug call it when click 'back' button
64  *      @return   void
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
68  */
69 Eina_Bool _back_btn_cb(void *data, Elm_Object_Item *it)
70 {
71         __FUNC_ENTER__;
72         struct ug_data *ugd = (struct ug_data *) data;
73         WFD_RETV_IF(ugd == NULL, FALSE, "The param is NULL\n");
74         int ret = -1;
75         bool owner = FALSE;
76         app_control_h control = NULL;
77
78         wfd_refresh_wifi_direct_state(ugd);
79         if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
80                 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
81                 goto cleanup;
82         }
83
84         if (NULL != ugd->mac_addr_connecting) {
85                 if (ugd->is_conn_incoming) {
86                         DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
87                         ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
88                         if (ret != WIFI_DIRECT_ERROR_NONE)
89                                 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
90                 } else {
91                         DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
92                         ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
93                         if (ret != WIFI_DIRECT_ERROR_NONE)
94                                 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
95                 }
96                 ugd->mac_addr_connecting = NULL;
97         }
98
99         if (ugd->raw_connected_peer_cnt == 0) {
100                 ret = wifi_direct_is_group_owner(&owner);
101                 if (ret == WIFI_DIRECT_ERROR_NONE) {
102                         if (owner)
103                                 wifi_direct_destroy_group();
104                 }
105         }
106
107 cleanup:
108         wfd_ug_view_free_peers(ugd);
109         ret = app_control_create(&control);
110         if (ret) {
111                 DBG(LOG_ERROR, "Failed to create control");
112         } else {
113                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
114                         app_control_add_extra_data(control, "Connection", "TRUE");
115                 else
116                         app_control_add_extra_data(control, "Connection", "FALSE");
117
118                 ug_send_result(ugd->ug, control);
119                 app_control_destroy(control);
120         }
121
122         ug_destroy_me(ugd->ug);
123         __FUNC_EXIT__;
124         return FALSE;
125 }
126
127 /**
128  *      This function let the ug call it when click 'back' button
129  *      @return   void
130  *      @param[in] data the pointer to the main data structure
131  *      @param[in] obj the pointer to the evas object
132  *      @param[in] event_info the pointer to the event information
133  */
134 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
135 {
136         __FUNC_ENTER__;
137         struct ug_data *ugd = (struct ug_data *) data;
138         int ret = -1;
139         bool owner = FALSE;
140         app_control_h control = NULL;
141
142         if (ugd == NULL) {
143                 DBG(LOG_ERROR, "The param is NULL");
144                 return;
145         }
146
147         wfd_refresh_wifi_direct_state(ugd);
148         if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
149                 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
150                 goto cleanup;
151         }
152
153         if (NULL != ugd->mac_addr_connecting) {
154                 if (ugd->is_conn_incoming) {
155                         DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
156                         ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
157                         if (ret != WIFI_DIRECT_ERROR_NONE)
158                                 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
159                 } else {
160                         DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
161                         ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
162                         if (ret != WIFI_DIRECT_ERROR_NONE)
163                                 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
164                 }
165                 ugd->mac_addr_connecting = NULL;
166         }
167
168         if (ugd->raw_connected_peer_cnt == 0) {
169                 ret = wifi_direct_is_group_owner(&owner);
170                 if (ret == WIFI_DIRECT_ERROR_NONE) {
171                         if (owner)
172                                 wifi_direct_destroy_group();
173                 }
174         }
175
176 cleanup:
177         wfd_ug_view_free_peers(ugd);
178         ret = app_control_create(&control);
179         if (ret) {
180                 DBG(LOG_ERROR, "Failed to create control");
181         } else {
182                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
183                         app_control_add_extra_data(control, "Connection", "TRUE");
184                 else
185                         app_control_add_extra_data(control, "Connection", "FALSE");
186
187                 ug_send_result(ugd->ug, control);
188                 app_control_destroy(control);
189         }
190
191         ug_destroy_me(ugd->ug);
192         __FUNC_EXIT__;
193         return;
194 }
195
196 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
197 {
198         __FUNC_ENTER__;
199
200         if (ugd->timer_stop_progress_bar > 0)
201                 g_source_remove(ugd->timer_stop_progress_bar);
202
203         ugd->timer_stop_progress_bar = 0;
204
205         __FUNC_EXIT__;
206 }
207
208 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
209 {
210         __FUNC_ENTER__;
211
212         if (ugd->timer_delete_not_alive_peer > 0)
213                 g_source_remove(ugd->timer_delete_not_alive_peer);
214
215         ugd->timer_delete_not_alive_peer = 0;
216
217         __FUNC_EXIT__;
218 }
219
220 /**
221  *      This function let the ug call it when click failed devices item
222  *      @return   void
223  *      @param[in] data the pointer to the main data structure
224  *      @param[in] obj the pointer to the evas object
225  *      @param[in] event_info the pointer to the event information
226  */
227 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
228 {
229         __FUNC_ENTER__;
230
231         struct ug_data *ugd = wfd_get_ug_data();
232         int ret = -1;
233
234         if (NULL == ugd) {
235                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
236                 return;
237         }
238
239         if (ugd->display_timer != NULL) {
240                 ecore_timer_del(ugd->display_timer);
241                 ugd->display_timer = NULL;
242         }
243
244         wfd_refresh_wifi_direct_state(ugd);
245         DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
246
247         /* if connected, show the popup*/
248         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
249                 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
250         } else {
251                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
252                 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
253                 if (ret != WIFI_DIRECT_ERROR_NONE) {
254                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
255                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
256                         wifi_direct_cancel_discovery();
257                 }
258         }
259
260         __FUNC_EXIT__;
261         return;
262 }
263
264 /**
265  *      This function let the ug call it when click 'scan' button
266  *      @return   void
267  *      @param[in] data the pointer to the main data structure
268  *      @param[in] obj the pointer to the evas object
269  *      @param[in] event_info the pointer to the event information
270  */
271 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
272 {
273         __FUNC_ENTER__;
274
275         struct ug_data *ugd = (struct ug_data *) data;
276         if (NULL == ugd) {
277                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
278                 return;
279         }
280         int ret = -1;
281         const char *btn_text = NULL;
282         btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
283         DBG(LOG_INFO, "Button text=%s", btn_text);
284
285         if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
286                 wfd_refresh_wifi_direct_state(ugd);
287                 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
288                 /* if connected, show the popup*/
289                 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
290                         wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
291                 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
292                         wfd_client_switch_on(ugd);
293                         __FUNC_EXIT__;
294                         return;
295                 } else {
296                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
297                         ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
298                         if (ret != WIFI_DIRECT_ERROR_NONE) {
299                                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
300                                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
301                                 wifi_direct_cancel_discovery();
302                         }
303                 }
304         } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
305                 DBG(LOG_INFO, "Stop pressed.\n");
306                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
307                 wfd_cancel_progressbar_stop_timer(ugd);
308                 wfd_delete_progressbar_cb(ugd);
309                 wfd_cancel_not_alive_delete_timer(ugd);
310         } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
311                 DBG(LOG_INFO, "Cancel Connection");
312                 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
313         } else {
314                 DBG(LOG_INFO, "Invalid Case\n");
315         }
316         __FUNC_EXIT__;
317         return;
318 }
319
320 void wfd_check_gl_busy_peers(struct ug_data *ugd)
321 {
322         __FUNC_ENTER__;
323         if (ugd->gl_busy_peer_cnt == 0)
324                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
325
326         __FUNC_EXIT__;
327 }
328
329 void wfd_check_gl_available_peers(struct ug_data *ugd)
330 {
331         __FUNC_ENTER__;
332         if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL)
333                 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
334
335         __FUNC_EXIT__;
336 }
337
338 /**
339  *      This function let the ug free some peer in genlist
340  *      @return  void
341  *      @param[in] start_pos the start position of peers list
342  *      @param[in] mac_addr the mac_addr of peer for free
343  *      @param[in] cnt the count of gl peers in list
344  */
345 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
346 {
347         __FUNC_ENTER__;
348         device_type_s *peer = *start_pos;
349         device_type_s *peer_tmp = peer;
350
351         if (peer == NULL) {
352                 DBG(LOG_INFO, "no peer in genlist");
353                 return;
354         }
355
356         while (peer) {
357                 if (strcmp(peer->mac_addr, mac_addr)) {
358                         peer_tmp = peer;
359                         peer = peer->next;
360                 } else {
361                         if (peer->next != NULL) {
362                                 peer_tmp->next = peer->next;
363                                 break;
364                         } else {
365                                 peer_tmp->next = NULL;
366                                 break;
367                         }
368                 }
369         }
370
371         if (peer == *start_pos) {
372                 DBG(LOG_INFO, "the head is free");
373                 *start_pos = peer->next;
374         }
375
376         (*cnt)--;
377         if (peer) {
378                 WFD_IF_DEL_ITEM(peer->gl_item);
379                 peer->next = NULL;
380                 free(peer);
381         }
382         __FUNC_EXIT__;
383 }
384
385 /**
386  *      This function let the ug call it when click available peer to connect
387  *      @return   void
388  *      @param[in] data the pointer to the main data structure
389  *      @param[in] obj the pointer to the evas object
390  *      @param[in] event_info the pointer to the event information
391  */
392 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
393 {
394         __FUNC_ENTER__;
395
396         int res = -1;
397         char txt[MAX_POPUP_TEXT_SIZE] = {0,};
398         char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
399         bool is_peer_alive = false;
400         struct ug_data *ugd = wfd_get_ug_data();
401         device_type_s *peer = (device_type_s *)data;
402         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
403         char *format_str = NULL;
404
405         if (!ugd || !peer) {
406                 DBG(LOG_ERROR, "NULL parameters.\n");
407                 return;
408         }
409
410         wfd_ug_get_connected_peers(ugd);
411         DBG(LOG_INFO, "No of connected peers= %d", ugd->raw_connected_peer_cnt);
412
413         if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
414                 format_str = D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME");
415                 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, format_str, MAX_CONNECTED_PEER_NUM);
416                 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
417                 if (item)
418                         elm_genlist_item_selected_set(item, EINA_FALSE);
419
420                 return;
421         }
422
423         if (ugd->disconnect_btn) {
424                 Evas_Object *content;
425                 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
426                 WFD_IF_DEL_OBJ(content);
427                 ugd->disconnect_btn = NULL;
428                 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
429         }
430
431         if (item)
432                 elm_genlist_item_selected_set(item, EINA_FALSE);
433
434         GList *iterator = NULL;
435
436         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
437                 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
438                         /* peer is found in last discovery */
439                         is_peer_alive = true;
440                         break;
441                 }
442         }
443
444         if (!is_peer_alive) {
445                 /* peer exists only in genlist, waiting to be deleted */
446                 device_type_s *peer_start = ugd->gl_avlb_peers_start;
447                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
448                         if (!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
449                                 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
450                                 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
451                                 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
452                                 wfd_check_gl_available_peers(ugd);
453                                 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
454                                 return;
455                         }
456                 }
457         }
458
459         wfd_cancel_not_alive_delete_timer(ugd);
460
461         /* get WFD status */
462         wfd_refresh_wifi_direct_state(ugd);
463
464         if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
465                 peer->is_group_owner == TRUE) {
466                 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
467                         MAC2SECSTR(peer->mac_addr));
468
469                 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
470                         DBG(LOG_DEBUG, "It's in connecting status now.\n");
471                         return;
472                 }
473
474                 ugd->mac_addr_connecting = peer->mac_addr;
475                 res = wfd_client_connect((const char *)peer->mac_addr);
476                 if (res != 0) {
477                         DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
478                         return;
479                 }
480         }
481
482         __FUNC_EXIT__;
483         return;
484 }
485
486 /**
487  *      This function let the ug call it when click busy peer
488  *      @return   void
489  *      @param[in] data the pointer to the main data structure
490  *      @param[in] obj the pointer to the evas object
491  *      @param[in] event_info the pointer to the event information
492  */
493 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
494 {
495         __FUNC_ENTER__;
496         struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
497         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
498
499         if (item)
500                 elm_genlist_item_selected_set(item, EINA_FALSE);
501
502         if (NULL == ugd) {
503                 DBG(LOG_ERROR, "Data is NULL\n");
504                 return;
505         }
506
507         wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
508
509         __FUNC_EXIT__;
510 }
511
512 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
513 {
514         struct ug_data *ugd = (struct ug_data *) data;
515
516         if (!ugd) {
517                 DBG(LOG_ERROR, "The param is NULL\n");
518                 return;
519         }
520
521         if (ugd->ctxpopup) {
522                 evas_object_del(ugd->ctxpopup);
523                 ugd->ctxpopup = NULL;
524         }
525 }
526
527 void _ctxpopup_move()
528 {
529         __FUNC_ENTER__;
530
531         int win_w = 0, win_h = 0;
532         int move_x = 0, move_y = 0;
533         int changed_ang = 0;
534         struct ug_data *ugd = wfd_get_ug_data();
535
536         if (!ugd || !ugd->win) {
537                 DBG(LOG_ERROR, "NULL parameters.\n");
538                 return;
539         }
540
541         if (!ugd->ctxpopup) {
542                 DBG(LOG_INFO, "NULL parameters.\n");
543                 return;
544         }
545
546         elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
547         changed_ang = elm_win_rotation_get(ugd->win);
548
549         switch (changed_ang) {
550         case 0:
551         case 180:
552                 move_x = win_w/2;
553                 move_y = win_h;
554                 break;
555
556         case 90:
557                 move_x = win_h/2;
558                 move_y = win_w;
559                 break;
560
561         case 270:
562                 move_x = win_h/2;
563                 move_y = win_w;
564                 break;
565
566         default:
567                 move_x = 0;
568                 move_y = 0;
569                 break;
570         }
571
572         evas_object_move(ugd->ctxpopup, move_x, move_y);
573
574         __FUNC_EXIT__;
575 }
576
577 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
578 {
579         __FUNC_ENTER__;
580         struct ug_data *ugd = (struct ug_data *) data;
581         WFD_RET_IF(ugd == NULL, "The param is NULL\n");
582         WFD_IF_DEL_OBJ(ugd->ctxpopup);
583         int ret = 0;
584
585         wfd_client_free_raw_discovered_peers(ugd);
586         ugd->raw_discovered_peer_cnt = 0;
587         wfd_create_multiconnect_view(ugd);
588         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
589         ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
590         if (ret != WIFI_DIRECT_ERROR_NONE) {
591                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
592                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
593                 wifi_direct_cancel_discovery();
594         }
595
596         __FUNC_EXIT__;
597 }
598
599 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
600 {
601         __FUNC_ENTER__;
602
603         Evas_Object *naviframe = (Evas_Object *)data;
604         Elm_Object_Item *multi_connect_item = NULL;
605         Elm_Object_Item *rename_item = NULL;
606         struct ug_data *ugd = wfd_get_ug_data();
607
608         if (!naviframe || !ugd) {
609                 DBG(LOG_ERROR, "NULL parameters.\n");
610                 return;
611         }
612
613         ugd->more_btn_multiconnect_item = NULL;
614
615         if (ugd->ctxpopup)
616                 evas_object_del(ugd->ctxpopup);
617
618         ugd->ctxpopup = elm_ctxpopup_add(naviframe);
619         elm_object_style_set(ugd->ctxpopup, "more/default");
620         eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
621         eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
622         evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
623         elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
624
625         elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
626                                         ELM_CTXPOPUP_DIRECTION_LEFT,
627                                         ELM_CTXPOPUP_DIRECTION_RIGHT,
628                                         ELM_CTXPOPUP_DIRECTION_DOWN);
629
630         _ctxpopup_move();
631
632         multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
633         elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
634         ugd->more_btn_multiconnect_item = multi_connect_item;
635
636         wfd_refresh_wifi_direct_state(ugd);
637         if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
638                 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
639                 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
640                 ugd->raw_connected_peer_cnt > 0) {
641                 elm_object_item_disabled_set(multi_connect_item, TRUE);
642         }
643
644         rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
645         elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
646         evas_object_show(ugd->ctxpopup);
647
648         __FUNC_EXIT__;
649 }
650
651 /**
652  *      This function make items into group
653 */
654 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
655 {
656         __FUNC_ENTER__;
657         int i = 0;
658         if (count < 1 || pre_item == NULL)
659                 return;
660
661         Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
662         if (item == NULL)
663                 return;
664
665         if (count == 1) {
666                 elm_object_item_signal_emit(item, "elm,state,normal", "");
667                 return;
668         }
669
670         for (i = 0; i < count; i++) {
671                 if (i == 0)
672                         elm_object_item_signal_emit(item, "elm,state,top", "");
673                 else if (i == count - 1)
674                         elm_object_item_signal_emit(item, "elm,state,bottom", "");
675                 else
676                         elm_object_item_signal_emit(item, "elm,state,center", "");
677
678                 item = elm_genlist_item_next_get(item);
679         }
680         __FUNC_EXIT__;
681 }
682
683 /**
684  *      This function let the ug call it when unresized event is received
685 */
686 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
687 {
688         __FUNC_ENTER__;
689         struct ug_data *ugd = (struct ug_data *)data;
690
691         _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
692         _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
693         _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
694         _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
695         _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
696         __FUNC_EXIT__;
697 }
698
699 /**
700  *      This function let the ug call it when resized event is received
701  *      @return   void
702  *      @param[in] data the pointer to the main data structure
703  *      @param[in] obj the pointer to the evas object
704  *      @param[in] event_info the pointer to the event information
705  */
706 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
707 {
708         __FUNC_ENTER__;
709
710         if (!data || !event_info) {
711                 DBG(LOG_ERROR, "Invalid parameters");
712                 return;
713         }
714
715         struct ug_data *ugd = (struct ug_data *)data;
716 #ifdef ACCESSIBILITY_FEATURE
717         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
718         int index = elm_genlist_item_index_get(item);
719         char *sr_msg = NULL;
720 #endif
721
722         _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
723         _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
724         _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
725         _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
726         _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
727
728 #ifdef ACCESSIBILITY_FEATURE
729         /* screen reader */
730         if (GENLIST_HEADER_POS == index && item != NULL) {
731                 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
732                 if (check) {
733                         Eina_Bool state = elm_check_state_get(check);
734                         if (state)
735                                 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
736                         else
737                                 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
738
739                         if (sr_msg) {
740                                 Evas_Object *ao = NULL;
741                                 ao = elm_object_item_access_object_get(item);
742                                 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
743                                 free(sr_msg);
744                         } else {
745                                 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
746                         }
747                 } else {
748                         DBG(LOG_ERROR, "index = %d, get check box fail!", index);
749                 }
750         }
751 #endif
752
753         __FUNC_EXIT__;
754 }
755
756 /**
757  *      This function let the ug call it when click 'disconnect' button
758  *      @return   void
759  *      @param[in] data the pointer to the main data structure
760  *      @param[in] obj the pointer to the evas object
761  *      @param[in] event_info the pointer to the event information
762  */
763 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
764 {
765         __FUNC_ENTER__;
766         struct ug_data *ugd = (struct ug_data *)data;
767         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
768
769         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
770
771         __FUNC_EXIT__;
772 }
773
774 /**
775  *      This function let the ug call it when click "cancel connection" button
776  *      @return   void
777  *      @param[in] data the pointer to the main data structure
778  *      @param[in] obj the pointer to the evas object
779  *      @param[in] event_info the pointer to the event information
780  */
781 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
782 {
783         __FUNC_ENTER__;
784         struct ug_data *ugd = (struct ug_data *)data;
785         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
786
787         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
788
789         __FUNC_EXIT__;
790 }
791
792
793 /**
794  *      This function let the ug update the genlist item
795  *      @return   void
796  *      @param[in] gl_item the pointer to genlist item
797  */
798 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
799 {
800         __FUNC_ENTER__;
801         if (gl_item != NULL)
802                 elm_genlist_item_update(gl_item);
803
804         __FUNC_EXIT__;
805 }
806
807 /**
808  *      This function let the ug refresh the attributes of button
809  *      @return   void
810  *      @param[in] tb_item the pointer to the toolbar button
811  *      @param[in] text the pointer to the text of button
812  *      @param[in] enable whether the button is disabled
813  */
814 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
815                 int enable)
816 {
817         __FUNC_ENTER__;
818
819         if (NULL == tb_item || NULL == text) {
820                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
821                 return;
822         }
823
824         DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
825         elm_object_domain_translatable_part_text_set(tb_item, "default",
826                          PACKAGE, text);
827         elm_object_disabled_set(tb_item, !enable);
828
829         __FUNC_EXIT__;
830 }
831
832 /**
833  *      This function let the ug know whether current device is connected by me
834  *      @return   If connected, return TRUE, else return FALSE
835  *      @param[in] ugd the pointer to the main data structure
836  *      @param[in] dev the pointer to the device
837  */
838 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
839 {
840         __FUNC_ENTER__;
841         int i = 0;
842
843         for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
844                 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
845                         dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
846                         return TRUE;
847                 }
848         }
849
850         __FUNC_EXIT__;
851         return FALSE;
852 }
853
854 /**
855  *      This function let the ug know whether current device is connected by other peer
856  *      @return   If connected, return TRUE, else return FALSE
857  *      @param[in] ugd the pointer to the main data structure
858  *      @param[in] dev the pointer to the device
859  */
860 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
861 {
862         __FUNC_ENTER__;
863
864         if (ugd->I_am_group_owner == TRUE) {
865                 if (dev->is_connected || dev->is_group_owner)
866                         return TRUE;
867                 else
868                         return FALSE;
869         } else {
870                 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE)
871                         return FALSE;
872
873                 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE)
874                         return TRUE;
875
876                 if (dev->is_connected == FALSE)
877                         return FALSE;
878         }
879
880         __FUNC_EXIT__;
881         return FALSE;
882 }
883
884 /**
885  *      This function let the ug calculate how many devices are available
886  *      @return   TRUE
887  *      @param[in] ugd the pointer to the main data structure
888  *      @param[in] dev the pointer to the number of available devices
889  */
890 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
891 {
892         __FUNC_ENTER__;
893         GList *iterator = NULL;
894
895         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
896                 /* Not include the device which is connected with me */
897                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
898                         continue;
899
900                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
901                         ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT)
902                         (*no_of_available_dev)++;
903         }
904
905         __FUNC_EXIT__;
906         return TRUE;
907 }
908
909 /**
910  *      This function let the ug calculate how many devices are busy
911  *      @return   TRUE
912  *      @param[in] ugd the pointer to the main data structure
913  *      @param[in] dev the pointer to the number of busy devices
914  */
915 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
916 {
917         __FUNC_ENTER__;
918         GList *iterator = NULL;
919
920         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
921                 /* Not include the device which is connected with me */
922                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
923                         continue;
924
925                 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data))
926                         (*no_of_busy_dev)++;
927         }
928
929         __FUNC_EXIT__;
930         return TRUE;
931 }
932
933 /**
934  *      This function let the ug calculate how many devices are connected failed
935  *      @return   TRUE
936  *      @param[in] ugd the pointer to the main data structure
937  *      @param[in] dev the pointer to the number of connected failed devices
938  */
939 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
940 {
941         __FUNC_ENTER__;
942         GList *iterator = NULL;
943
944         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
945                 /* Not include the device which is connected with me */
946                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
947                         continue;
948
949                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
950                         ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
951                         (*no_of_connect_failed_dev)++;
952                 }
953         }
954
955         __FUNC_EXIT__;
956         return TRUE;
957 }
958
959 /**
960  *      This function let the ug create the main genlist
961  *      @return   the main genlist
962  *      @param[in] data the pointer to the main data structure
963  */
964 static Evas_Object *_create_basic_genlist(void *data)
965 {
966         __FUNC_ENTER__;
967         struct ug_data *ugd = (struct ug_data *) data;
968         Evas_Object *genlist;
969
970         genlist = elm_genlist_add(ugd->layout);
971
972         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
973         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
974                         EVAS_HINT_EXPAND);
975         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
976
977         /* Wifi ON/OFF toggle button */
978 #ifdef WFD_ON_OFF_GENLIST
979         ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
980                         NULL, ELM_GENLIST_ITEM_NONE, _onoff_changed_cb, ugd);
981         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
982                                         EINA_FALSE);
983 #endif
984         evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
985         evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
986         ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
987                 ELM_GENLIST_ITEM_NONE, NULL, NULL);
988         if (ugd->device_name_item != NULL)
989                 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
990
991         __FUNC_EXIT__;
992         return genlist;
993 }
994
995 /**
996  *      This function let the ug create no device item to append the genlist
997  *      @return   the main item
998  *      @param[in] data the pointer to the main data structure
999  */
1000 Evas_Object *_create_no_device_genlist(void *data)
1001 {
1002         __FUNC_ENTER__;
1003         struct ug_data *ugd = (struct ug_data *) data;
1004         Elm_Object_Item *last_item = NULL;
1005         int i = 0;
1006
1007         WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1008
1009         if (ugd->conn_wfd_item != NULL) {
1010                 last_item = ugd->conn_wfd_item;
1011                 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1012                         last_item = elm_genlist_item_next_get(last_item);
1013
1014         } else {
1015                 last_item = ugd->device_name_item;
1016         }
1017
1018         ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1019                 &title_no_device_itc, (void *)ugd, NULL, last_item,
1020                 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1021         if (ugd->nodevice_title_item != NULL)
1022                 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1023
1024         ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1025                 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1026         if (ugd->nodevice_item != NULL)
1027                 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1028
1029         __FUNC_EXIT__;
1030         return ugd->genlist;
1031 }
1032
1033 /**
1034  *      This function let the ug create busy device list
1035  *      @return   0
1036  *      @param[in] data the pointer to the main data structure
1037  */
1038 int _create_busy_dev_list(void *data)
1039 {
1040         __FUNC_ENTER__;
1041         struct ug_data *ugd = (struct ug_data *) data;
1042
1043         ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1044                 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1045         if (ugd->busy_wfd_item != NULL)
1046                 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1047         __FUNC_EXIT__;
1048         return 0;
1049 }
1050
1051 void wfd_free_nodivice_item(struct ug_data *ugd)
1052 {
1053         __FUNC_ENTER__;
1054         WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1055         WFD_IF_DEL_ITEM(ugd->nodevice_item);
1056         __FUNC_EXIT__;
1057 }
1058
1059 /**
1060  *      This function let the ug create available device list
1061  *      @return   0
1062  *      @param[in] data the pointer to the main data structure
1063  */
1064 int _create_available_dev_genlist(void *data)
1065 {
1066         __FUNC_ENTER__;
1067         int i = 0;
1068         struct ug_data *ugd = (struct ug_data *) data;
1069         Elm_Object_Item *last_item = NULL;
1070
1071         wfd_free_nodivice_item(ugd);
1072
1073         if (ugd->conn_wfd_item != NULL) {
1074                 last_item = ugd->conn_wfd_item;
1075                 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1076                         last_item = elm_genlist_item_next_get(last_item);
1077
1078         } else {
1079                 last_item = ugd->device_name_item;
1080         }
1081
1082         ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1083                 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1084         if (ugd->avlbl_wfd_item != NULL) {
1085                 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1086                 elm_genlist_item_update(ugd->avlbl_wfd_item);
1087         }
1088         __FUNC_EXIT__;
1089         return 0;
1090 }
1091
1092 /**
1093  *      This function let the ug create multi connect device list
1094  *      @return   0
1095  *      @param[in] data the pointer to the main data structure
1096  */
1097 static int _create_multi_connect_dev_genlist(void *data)
1098 {
1099         __FUNC_ENTER__;
1100         struct ug_data *ugd = (struct ug_data *) data;
1101
1102         ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1103                                                                 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1104         if (ugd->multi_connect_wfd_item != NULL)
1105                 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1106         __FUNC_EXIT__;
1107         return 0;
1108 }
1109
1110 /**
1111  *      This function let the ug create connected device list
1112  *      @return   0
1113  *      @param[in] data the pointer to the main data structure
1114  */
1115 int _create_connected_dev_genlist(void *data)
1116 {
1117         __FUNC_ENTER__;
1118         struct ug_data *ugd = (struct ug_data *) data;
1119
1120         ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1121                 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1122         if (ugd->conn_wfd_item != NULL) {
1123                 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1124                 elm_genlist_item_update(ugd->conn_wfd_item);
1125         }
1126
1127         __FUNC_EXIT__;
1128         return 0;
1129 }
1130
1131 /**
1132  *      This function let the ug create connected falied device list
1133  *      @return   0
1134  *      @param[in] data the pointer to the main data structure
1135  */
1136 int _create_connected_failed_dev_genlist(void *data)
1137 {
1138         __FUNC_ENTER__;
1139         struct ug_data *ugd = (struct ug_data *) data;
1140         Elm_Object_Item *last_item = NULL;
1141         int i = 0;
1142
1143         if (ugd->avlbl_wfd_item != NULL) {
1144                 last_item = ugd->avlbl_wfd_item;
1145                 for (i = 0; i < ugd->gl_available_peer_cnt; i++)
1146                         last_item = elm_genlist_item_next_get(last_item);
1147
1148         } else if (ugd->conn_wfd_item != NULL) {
1149                 last_item = ugd->conn_wfd_item;
1150                 for (i = 0; i < ugd->gl_connected_peer_cnt; i++)
1151                         last_item = elm_genlist_item_next_get(last_item);
1152
1153         } else {
1154                 last_item = ugd->device_name_item;
1155         }
1156
1157         ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1158                                                                 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1159         if (ugd->conn_failed_wfd_item != NULL)
1160                 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1161         __FUNC_EXIT__;
1162         return 0;
1163 }
1164
1165 /**
1166  *      This function let the ug make the display callback for connect failed peers
1167  *      @return   if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1168  *      @param[in] data the pointer to the user data
1169  */
1170 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1171 {
1172         __FUNC_ENTER__;
1173         int interval = 0;
1174         int res = -1;
1175         struct ug_data *ugd = (struct ug_data *) user_data;
1176
1177         if (NULL == ugd) {
1178                 DBG(LOG_ERROR, "NULL parameters.\n");
1179                 return ECORE_CALLBACK_CANCEL;
1180         }
1181
1182         if (ugd->avlbl_wfd_item == NULL)
1183                 _create_available_dev_genlist(ugd);
1184
1185         if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1186                 DBG(LOG_INFO, "Background mode\n");
1187                 ugd->display_timer = NULL;
1188                 return ECORE_CALLBACK_CANCEL;
1189         }
1190
1191         /* check the timeout, if not timeout, keep the cb */
1192         interval = time(NULL) - ugd->last_display_time;
1193         if (interval < MAX_DISPLAY_TIME_OUT)
1194                 return ECORE_CALLBACK_RENEW;
1195
1196         if (ugd->is_paused == false) {
1197                 DBG(LOG_INFO, "Not Paused");
1198                 /* start discovery again */
1199                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1200                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1201                 if (res != WIFI_DIRECT_ERROR_NONE) {
1202                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1203                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1204                         wifi_direct_cancel_discovery();
1205                 }
1206         }
1207
1208         ugd->display_timer = NULL;
1209         __FUNC_EXIT__;
1210         return ECORE_CALLBACK_CANCEL;
1211 }
1212
1213 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1214 {
1215         __FUNC_ENTER__;
1216         device_type_s *peer_for_free = NULL;
1217         device_type_s *peer = gl_peers_start;
1218
1219         while (peer != NULL && peer->gl_item != NULL) {
1220                 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1221                 elm_object_item_del(peer->gl_item);
1222                 peer->gl_item = NULL;
1223                 peer_for_free = peer;
1224                 peer = peer->next;
1225                 free(peer_for_free);
1226         }
1227         __FUNC_EXIT__;
1228 }
1229
1230 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1231 {
1232         __FUNC_ENTER__;
1233         if (ugd->gl_connected_peer_cnt == 0)
1234                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1235
1236         __FUNC_EXIT__;
1237 }
1238
1239 /**
1240  *      This function let the ug free the peers
1241  *      @return   void
1242  *      @param[in] data the pointer to the main data structure
1243  */
1244 void wfd_ug_view_free_peers(void *data)
1245 {
1246         __FUNC_ENTER__;
1247
1248         struct ug_data *ugd = (struct ug_data *) data;
1249
1250         ugd->gl_connected_peer_cnt = 0;
1251
1252         if (ugd->gl_conn_peers_start != NULL) {
1253                 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1254                 ugd->gl_conn_peers_start = NULL;
1255         }
1256
1257         ugd->gl_available_peer_cnt = 0;
1258
1259         if (ugd->gl_avlb_peers_start != NULL) {
1260                 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1261                 ugd->gl_avlb_peers_start = NULL;
1262         }
1263
1264         ugd->gl_busy_peer_cnt = 0;
1265
1266         if (ugd->gl_busy_peers_start != NULL) {
1267                 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1268                 ugd->gl_busy_peers_start = NULL;
1269         }
1270
1271         ugd->gl_multi_connect_peer_cnt = 0;
1272
1273         if (ugd->gl_mul_conn_peers_start != NULL) {
1274                 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1275                 ugd->gl_mul_conn_peers_start = NULL;
1276         }
1277
1278         if (ugd->gl_connected_peer_cnt == 0)
1279                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1280
1281         if (ugd->display_timer != NULL) {
1282                 ecore_timer_del(ugd->display_timer);
1283                 ugd->display_timer = NULL;
1284         }
1285
1286         WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1287         WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1288         WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1289         WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1290
1291         __FUNC_EXIT__;
1292 }
1293
1294 void wfd_ug_update_toolbar(struct ug_data *ugd)
1295 {
1296         __FUNC_ENTER__;
1297         int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1298         Evas_Object *btn;
1299
1300         wfd_refresh_wifi_direct_state(ugd);
1301         if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1302                 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1303                 if (ugd->multi_connect_wfd_item != NULL) {
1304                         DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1305                         btn = elm_button_add(ugd->button_layout);
1306                         /* Use "bottom" style button */
1307                         elm_object_style_set(btn, "bottom");
1308                         elm_object_domain_translatable_text_set(btn, PACKAGE,
1309                                         "IDS_WIFI_SK2_CANCEL_CONNECTION");
1310                         evas_object_smart_callback_add(btn, "clicked",
1311                                         _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1312                         /* Set button into "toolbar" swallow part */
1313                         elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1314                         ugd->disconnect_btn = btn;
1315                         evas_object_show(ugd->disconnect_btn);
1316                         elm_object_part_content_set(ugd->button_layout, "button.prev",
1317                                 ugd->scan_toolbar);
1318                         wfd_ug_view_refresh_button(ugd->scan_toolbar,
1319                                         "IDS_WIFI_SK4_SCAN", FALSE);
1320                         evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1321                         DBG(LOG_INFO, "button: disconnect button added\n");
1322                 } else {
1323                         DBG(LOG_INFO, "scan_toolbar\n");
1324                         WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1325                         wfd_ug_view_refresh_button(ugd->scan_toolbar,
1326                                         "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1327                         evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1328                         DBG(LOG_INFO, "button: stop connect button added\n");
1329                 }
1330         } else if (no_of_conn_dev > 0) {
1331                 if (!ugd->multi_connect_toolbar_item) {
1332                         btn = elm_button_add(ugd->button_layout);
1333                         /* Use "bottom" style button */
1334                         elm_object_style_set(btn, "bottom");
1335                         elm_object_domain_translatable_text_set(btn, PACKAGE,
1336                                         "IDS_WIFI_SK_DISCONNECT");
1337                         evas_object_smart_callback_add(btn, "clicked",
1338                                         _wfd_ug_disconnect_button_cb, (void *)ugd);
1339                         /* Set button into "toolbar" swallow part */
1340                         elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1341                         ugd->disconnect_btn = btn;
1342                         evas_object_show(ugd->disconnect_btn);
1343                         DBG(LOG_INFO, "button: disconnect button added\n");
1344                 }
1345                 elm_object_part_content_set(ugd->button_layout, "button.prev",
1346                                 ugd->scan_toolbar);
1347                 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1348                                 "IDS_WIFI_SK4_SCAN", TRUE);
1349                 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1350                 DBG(LOG_INFO, "button: scan button added\n");
1351         } else {
1352                 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1353                         DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1354                         Evas_Object *content;
1355                         content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1356                         WFD_IF_DEL_OBJ(content);
1357                         ugd->disconnect_btn = NULL;
1358                         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1359                 }
1360                 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1361                         "IDS_WIFI_SK4_SCAN", TRUE);
1362                 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1363                 DBG(LOG_INFO, "button: scan button added\n");
1364         }
1365         __FUNC_EXIT__;
1366 }
1367
1368 /**
1369  *      This function let the ug init the genlist
1370  */
1371 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1372 {
1373         __FUNC_ENTER__;
1374         struct ug_data *ugd = (struct ug_data *) data;
1375         int no_of_busy_dev = 0;
1376         int no_of_available_dev = 0;
1377         int no_of_conn_failed_dev = 0;
1378
1379         if (is_free_all_peers)
1380                 wfd_ug_view_free_peers(ugd);
1381
1382         if (ugd->gl_failed_peers_start != NULL) {
1383                 DBG(LOG_INFO, "These are failed peers, must clear them");
1384                 ugd->gl_connected_failed_peer_cnt = 0;
1385                 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1386                 ugd->gl_failed_peers_start = NULL;
1387                 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1388         }
1389
1390         if (ugd->avlbl_wfd_item != NULL) {
1391                 DBG(LOG_INFO, "There are available peers in genlist");
1392                 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1393                 return;
1394         }
1395
1396         __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1397         __wfd_is_any_device_available(ugd, &no_of_available_dev);
1398         __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1399
1400         __FUNC_EXIT__;
1401 }
1402
1403 /**
1404  *      This function let the ug find a peer in genlist
1405  */
1406 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1407 {
1408         __FUNC_ENTER__;
1409
1410         if (start_pos == NULL) {
1411                 DBG(LOG_INFO, "no peer in genlist");
1412                 return NULL;
1413         }
1414
1415         device_type_s *peer = start_pos;
1416
1417         while (peer != NULL) {
1418                 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1419                         peer->is_alive = true;
1420                         DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1421                         __FUNC_EXIT__;
1422                         return peer;
1423                 }
1424                 peer = peer->next;
1425         }
1426
1427         __FUNC_EXIT__;
1428         return NULL;
1429 }
1430
1431 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1432 {
1433         __FUNC_ENTER__;
1434         if (*start_pos == NULL) {
1435                 DBG(LOG_INFO, "no peer in genlist");
1436                 return;
1437         }
1438
1439         device_type_s *peer = *start_pos;
1440         device_type_s *peer_tmp = NULL;
1441         while (peer != NULL) {
1442                 peer_tmp = peer->next;
1443                 if (peer->is_alive == false)
1444                          free_gl_peer(start_pos, peer->mac_addr, cnt);
1445
1446                 peer = peer_tmp;
1447         }
1448
1449 //      wfd_check_gl_available_peers(ugd);
1450         if (ugd->gl_busy_peer_cnt == 0)
1451                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1452
1453         __FUNC_EXIT__;
1454         return;
1455 }
1456
1457 void set_not_alive_peers(device_type_s *start_pos)
1458 {
1459         __FUNC_ENTER__;
1460         if (start_pos == NULL) {
1461                 DBG(LOG_INFO, "no peer in genlist");
1462                 return;
1463         }
1464
1465         device_type_s *peer = start_pos;
1466         while (peer != NULL) {
1467                 peer->is_alive = false;
1468                 peer = peer->next;
1469         }
1470
1471         __FUNC_EXIT__;
1472         return;
1473 }
1474
1475 /**
1476  *      This function let the ug get the insert position for next item
1477  */
1478 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1479 {
1480         __FUNC_ENTER__;
1481         int i = 0;
1482         device_type_s *peer_ite = NULL;
1483         Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1484         Elm_Object_Item *item = NULL;
1485
1486         if (peer_cnt == 0) {
1487                 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1488                 return pre_item;
1489         }
1490
1491         peer_ite = (device_type_s *)elm_object_item_data_get(head);
1492         if (peer_ite->gl_item != NULL) {
1493                 for (i = 0; i < peer_cnt; i++) {
1494                         if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1495                                 /* if peer_ite is greater than peer, return previous item */
1496                                 __FUNC_EXIT__;
1497                                 return  elm_genlist_item_prev_get(head);
1498                         } else {
1499                                 item = elm_genlist_item_next_get(head);
1500                                 if (item == NULL) {
1501                                         /* return the last item */
1502                                         return head;
1503                                 } else {
1504                                         head = item;
1505                                         peer_ite = (device_type_s *)elm_object_item_data_get(head);
1506                                 }
1507                         }
1508                 }
1509         }
1510         __FUNC_EXIT__;
1511         return elm_genlist_item_prev_get(head);
1512 }
1513
1514 /**
1515  *      This function let the ug insert peer item to genlist
1516  */
1517 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1518                                 device_type_s *peer_for_insert, void *callback)
1519 {
1520         __FUNC_ENTER__;
1521         WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1522         device_type_s *peer = NULL;
1523         device_type_s *peer_ite = NULL;
1524
1525         peer = (device_type_s *)malloc(sizeof(device_type_s));
1526         WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1527
1528         memcpy(peer, peer_for_insert, sizeof(device_type_s));
1529         peer->next = NULL;
1530
1531         if (*start_pos == NULL) {
1532                 *start_pos = peer;
1533         } else {
1534                 peer_ite = *start_pos;
1535                 while (peer_ite->next != NULL) {
1536                         /* move pointer to the last peer */
1537                         peer_ite = peer_ite->next;
1538                 }
1539                 peer_ite->next = peer;
1540         }
1541
1542         peer->is_alive = true;
1543         peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1544                 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1545         if (callback == NULL && peer->gl_item != NULL)
1546                 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1547
1548         __FUNC_EXIT__;
1549         return 0;
1550 }
1551
1552 /**
1553  *      This function let the ug update connected peers
1554  *      @return   void
1555  *      @param[in] data the pointer to the main data structure
1556  */
1557 void wfd_ug_update_connected_peers(void *data)
1558 {
1559         __FUNC_ENTER__;
1560
1561         struct ug_data *ugd = (struct ug_data *) data;
1562         int i = 0 ;
1563         int res;
1564         bool is_group_owner = FALSE;
1565         Elm_Object_Item *item = NULL;
1566
1567         res = wifi_direct_is_group_owner(&is_group_owner);
1568         if (res == WIFI_DIRECT_ERROR_NONE)
1569                 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1570
1571         if (!ugd->conn_wfd_item)
1572                 _create_connected_dev_genlist(ugd);
1573
1574         for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1575                 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1576                         if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1577                                 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1578                                         &ugd->gl_available_peer_cnt);
1579                                 wfd_check_gl_available_peers(ugd);
1580                         }
1581
1582                         if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1583                                 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1584                                         &ugd->gl_multi_connect_peer_cnt);
1585                                 if (ugd->gl_multi_connect_peer_cnt == 0) {
1586                                         WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1587                                         WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1588                                 }
1589                         }
1590
1591                         item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1592                                 ugd->gl_connected_peer_cnt);
1593                         res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1594                                         &ugd->raw_connected_peers[i], NULL);
1595                         if (res != 0)
1596                                 break;
1597
1598                         ugd->gl_connected_peer_cnt++;
1599                 }
1600         }
1601
1602         /* if is not GO, free all available peers */
1603         if (is_group_owner == FALSE) {
1604                 ugd->gl_available_peer_cnt = 0;
1605                 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1606
1607                 if (ugd->gl_avlb_peers_start != NULL) {
1608                         wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1609                         ugd->gl_avlb_peers_start = NULL;
1610                 }
1611         }
1612
1613         /* free busy peers */
1614         if (ugd->gl_busy_peers_start != NULL) {
1615                 ugd->gl_busy_peer_cnt = 0;
1616                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1617
1618                 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1619                 ugd->gl_busy_peers_start = NULL;
1620
1621         }
1622
1623         __FUNC_EXIT__;
1624 }
1625
1626 /**
1627  *      This function let the ug update the multi-connect peers
1628  *      @return   void
1629  *      @param[in] data the pointer to the main data structure
1630  */
1631 void wfd_ug_view_update_multiconn_peers(void *data)
1632 {
1633         __FUNC_ENTER__;
1634
1635         struct ug_data *ugd = (struct ug_data *) data;
1636         int i;
1637         int res;
1638         Elm_Object_Item *item = NULL;
1639
1640         if (ugd->raw_multi_selected_peer_cnt > 0) {
1641                 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1642                         ugd->multi_connect_wfd_item == NULL) {
1643                         _create_multi_connect_dev_genlist(ugd);
1644                 }
1645
1646                 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1647                         if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1648                                 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1649                                         ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1650                                 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1651                                                 &ugd->raw_multi_selected_peers[i], NULL);
1652                                 if (res != 0)
1653                                         break;
1654
1655                                 ugd->gl_multi_connect_peer_cnt++;
1656                         }
1657                 }
1658         }
1659
1660         __FUNC_EXIT__;
1661 }
1662
1663 /**
1664  *      This function let the ug update the available and busy peers
1665  */
1666 void wfd_ug_update_available_peers(void *data)
1667 {
1668         __FUNC_ENTER__;
1669
1670         struct ug_data *ugd = (struct ug_data *) data;
1671         int no_of_busy_dev = 0;
1672         int no_of_available_dev = 0;
1673         int no_of_conn_dev = 0;
1674         bool is_group_owner = FALSE;
1675         int res = 0;
1676         Elm_Object_Item *item = NULL;
1677         device_type_s *peer = NULL;
1678         GList *iterator = NULL;
1679
1680         __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1681         __wfd_is_any_device_available(ugd, &no_of_available_dev);
1682         no_of_conn_dev = ugd->raw_connected_peer_cnt;
1683
1684         res = wifi_direct_is_group_owner(&is_group_owner);
1685         if (res != WIFI_DIRECT_ERROR_NONE) {
1686                 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1687                 ugd->I_am_group_owner = FALSE;
1688         } else {
1689                 ugd->I_am_group_owner = is_group_owner;
1690         }
1691
1692         DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1693         if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1694                 DBG(LOG_INFO, "There are available or busy peers\n");
1695                 wfd_free_nodivice_item(ugd);
1696         }
1697
1698         if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1699                 if (ugd->avlbl_wfd_item == NULL)
1700                         _create_available_dev_genlist(ugd);
1701
1702
1703                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1704                         /* Not include the device which is connected with me */
1705                         if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data))
1706                                 continue;
1707
1708                         if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1709                                 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1710                                 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1711                                 /* free disconnected gl peer */
1712                                 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1713                                         free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1714                                                 &ugd->gl_connected_peer_cnt);
1715                                 }
1716
1717                                 /* free busy gl peer, which is available now */
1718                                 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1719                                         free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1720                                         if (ugd->gl_busy_peer_cnt == 0)
1721                                                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1722                                 }
1723
1724                                 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL)
1725                                         continue;
1726
1727                                 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1728                                 if (peer == NULL) {
1729                                         item = get_insert_postion((device_type_s *)iterator->data,
1730                                                 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1731                                         res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1732                                                         (device_type_s *)iterator->data, _gl_peer_sel);
1733                                         if (res != 0)
1734                                                 break;
1735
1736                                         ugd->gl_available_peer_cnt++;
1737                                 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1738                                         /* if peer is GO, free it */
1739                                         free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1740                                                 &ugd->gl_available_peer_cnt);
1741                                 }
1742                         }
1743                 }
1744         }
1745
1746         wfd_check_gl_available_peers(ugd);
1747         wfd_check_gl_conn_peers(ugd);
1748
1749         if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1750                 if (ugd->busy_wfd_item == NULL)
1751                         _create_busy_dev_list(ugd);
1752
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))
1756                                 continue;
1757
1758                         if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1759                                 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1760                                         if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1761                                                 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1762                                                 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1763                                                         &ugd->gl_available_peer_cnt);
1764                                                 wfd_check_gl_available_peers(ugd);
1765                                         }
1766                                         item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1767                                                 ugd->gl_busy_peer_cnt);
1768                                         res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1769                                                         (device_type_s *)iterator->data, _gl_busy_peer_sel);
1770                                         if (res != 0)
1771                                                 break;
1772
1773                                         ugd->gl_busy_peer_cnt++;
1774                                 }
1775                         }
1776                 }
1777         }
1778
1779         wfd_check_gl_busy_peers(ugd);
1780
1781         __FUNC_EXIT__;
1782 }
1783
1784 /**
1785  *      This function let the ug update the failed peers
1786  *      @return   void
1787  *      @param[in] data the pointer to the main data structure
1788  */
1789 void wfd_ug_update_failed_peers(void *data)
1790 {
1791         __FUNC_ENTER__;
1792         struct ug_data *ugd = (struct ug_data *) data;
1793         int no_of_conn_failed_dev = 0;
1794         GList *iterator = NULL;
1795
1796         __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1797         DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1798
1799         if (no_of_conn_failed_dev == 0)
1800                 return;
1801
1802         /* add timer for disappearing failed peers after N secs */
1803         if (NULL == ugd->display_timer) {
1804                 ugd->last_display_time = time(NULL);
1805                 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1806         }
1807
1808         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1809                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1810                         ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1811                         if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1812                                 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1813                                         free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1814                                                 &ugd->gl_available_peer_cnt);
1815                                         wfd_check_gl_available_peers(ugd);
1816                                 }
1817                         }
1818                 }
1819         }
1820
1821         __FUNC_EXIT__;
1822 }
1823
1824 #ifdef WFD_ON_OFF_GENLIST
1825 /**
1826  *      This function is called when user swipes on/off button
1827  *      @return   void
1828  *      @param[in] data the pointer to the main data structure
1829  *      @param[in] obj the pointer to the evas object
1830  *      @param[in] event_info the pointer to the event information
1831  */
1832 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1833 {
1834         __FUNC_ENTER__;
1835         struct ug_data *ugd = (struct ug_data *)data;
1836         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1837         WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1838         wfd_refresh_wifi_direct_state(ugd);
1839         if (ugd->device_name_item != NULL)
1840                 elm_genlist_item_update(ugd->device_name_item);
1841
1842         elm_object_disabled_set(ugd->on_off_check, TRUE);
1843         if (ugd->disconnect_btn) {
1844                 Evas_Object *content;
1845                 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1846                 WFD_IF_DEL_OBJ(content);
1847                 ugd->disconnect_btn = NULL;
1848         }
1849         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1850
1851         /* turn on/off wfd */
1852         if (!ugd->wfd_onoff) {
1853                 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1854                         DBG(LOG_INFO, "wifi-direct switch on\n");
1855                         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1856                                                                 EINA_FALSE);
1857                         wfd_client_switch_on(ugd);
1858                 }
1859         } else {
1860                 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1861                         DBG(LOG_INFO, "wifi-direct switch off\n");
1862                         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1863                                                                 EINA_FALSE);
1864                         wfd_client_switch_off(ugd);
1865                 }
1866         }
1867
1868         __FUNC_EXIT__;
1869 }
1870
1871 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1872 {
1873         __FUNC_ENTER__;
1874         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1875         WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1876
1877         wfd_refresh_wifi_direct_state(ugd);
1878         if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1879                 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING)
1880                 elm_object_disabled_set(ugd->on_off_check, TRUE);
1881         else
1882                 elm_object_disabled_set(ugd->on_off_check, FALSE);
1883
1884         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
1885                 elm_check_state_set(ugd->on_off_check, TRUE);
1886         else
1887                 elm_check_state_set(ugd->on_off_check, FALSE);
1888
1889         __FUNC_EXIT__;
1890 }
1891
1892 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1893 {
1894         __FUNC_ENTER__;
1895         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1896         WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1897
1898         Evas_Object *check = elm_check_add(ugd->naviframe);
1899         elm_object_style_set(check, "naviframe/title_on&off");
1900         elm_check_state_set(check, ugd->wfd_onoff);
1901         evas_object_propagate_events_set(check, EINA_FALSE);
1902         evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1903         elm_object_focus_allow_set(check, EINA_TRUE);
1904         elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1905         evas_object_show(check);
1906         ugd->on_off_check = check;
1907
1908         __FUNC_EXIT__;
1909 }
1910 #endif
1911
1912 /**
1913  *      This function let the ug create the main view
1914  *      @return   void
1915  *      @param[in] data the pointer to the main data structure
1916  */
1917 void create_wfd_ug_view(void *data)
1918 {
1919         __FUNC_ENTER__;
1920         struct ug_data *ugd = (struct ug_data *) data;
1921         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1922 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1923         Evas_Object *more_btn;
1924 #endif
1925         Evas_Object *layout;
1926
1927         ugd->naviframe = elm_naviframe_add(ugd->base);
1928         elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1929         eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1930         eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1931         elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1932
1933         ugd->back_btn = elm_button_add(ugd->naviframe);
1934         elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1935         evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1936         elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1937
1938         /* Create layout */
1939         layout = elm_layout_add(ugd->naviframe);
1940         elm_layout_theme_set(layout, "layout", "application", "default");
1941         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1942         ugd->layout = layout;
1943
1944         ugd->genlist = _create_basic_genlist(ugd);
1945         if (ugd->genlist == NULL) {
1946                 DBG(LOG_ERROR, "Failed to create basic genlist");
1947                 return;
1948         }
1949         elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1950
1951         evas_object_show(ugd->base);
1952         elm_object_focus_set(ugd->base, EINA_TRUE);
1953
1954         ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1955                         ugd->back_btn, NULL, layout, NULL);
1956         elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1957
1958 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1959         more_btn = elm_button_add(ugd->naviframe);
1960         elm_object_style_set(more_btn, "naviframe/more/default");
1961         evas_object_smart_callback_add(more_btn, "clicked",
1962                         _more_button_cb, ugd->win);
1963         elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1964                         more_btn);
1965 #endif
1966
1967         wifi_direct_initialize();
1968         wifi_direct_get_state(&ugd->wfd_status);
1969         if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING)
1970                 scan_button_create(ugd);
1971
1972         if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1973                 int ret = 0;
1974                 ugd->raw_discovered_peer_cnt = 0;
1975                 wfd_create_multiconnect_view(ugd);
1976                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1977                 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1978                 if (ret != WIFI_DIRECT_ERROR_NONE) {
1979                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1980                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
1981                         wifi_direct_cancel_discovery();
1982                 }
1983                 return;
1984         }
1985
1986         __FUNC_EXIT__;
1987 }
1988
1989 /**
1990  *      This function let the ug destroy the main view
1991  *      @return   void
1992  *      @param[in] data the pointer to the main data structure
1993  */
1994 void destroy_wfd_ug_view(void *data)
1995 {
1996         __FUNC_ENTER__;
1997         struct ug_data *ugd = (struct ug_data *) data;
1998         WFD_IF_DEL_ITEM(ugd->device_name_item);
1999         WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2000         WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2001
2002         WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2003         WFD_IF_DEL_OBJ(ugd->back_btn);
2004         WFD_IF_DEL_OBJ(ugd->toolbar);
2005         WFD_IF_DEL_OBJ(ugd->genlist);
2006         WFD_IF_DEL_OBJ(ugd->button_layout);
2007         WFD_IF_DEL_OBJ(ugd->layout);
2008         WFD_IF_DEL_OBJ(ugd->naviframe);
2009         __FUNC_EXIT__;
2010 }