Fix Svace issues WGID 143851, 152686, 152691
[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.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
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 #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;
83                 if (ugd->conn) {
84                         g_object_unref(ugd->conn);
85                         ugd->conn = NULL;
86                 }
87                 DBG(LOG_INFO, "Cancel dbus call");
88         }
89 #endif
90
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");
94                 goto cleanup;
95         }
96
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);
103                 } else {
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);
108                 }
109                 ugd->mac_addr_connecting = NULL;
110         }
111
112         if (ugd->raw_connected_peer_cnt == 0) {
113                 ret = wifi_direct_is_group_owner(&owner);
114                 if (ret == WIFI_DIRECT_ERROR_NONE) {
115                         if (owner)
116                                 wifi_direct_destroy_group();
117                 }
118         }
119
120 cleanup:
121         wfd_ug_view_free_peers(ugd);
122         ret = app_control_create(&control);
123         if (ret) {
124                 DBG(LOG_ERROR, "Failed to create control");
125         } else {
126                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
127                         app_control_add_extra_data(control, "Connection", "TRUE");
128                 else
129                         app_control_add_extra_data(control, "Connection", "FALSE");
130
131                 ug_send_result(ugd->ug, control);
132                 app_control_destroy(control);
133         }
134
135         ug_destroy_me(ugd->ug);
136         __FUNC_EXIT__;
137         return FALSE;
138 }
139
140 /**
141  *      This function let the ug call it when click 'back' button
142  *      @return   void
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
146  */
147 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
148 {
149         __FUNC_ENTER__;
150         struct ug_data *ugd = (struct ug_data *) data;
151         int ret = -1;
152         bool owner = FALSE;
153         app_control_h control = NULL;
154
155         if (ugd == NULL) {
156                 DBG(LOG_ERROR, "The param is NULL");
157                 return;
158         }
159
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;
165                 if (ugd->conn) {
166                         g_object_unref(ugd->conn);
167                         ugd->conn = NULL;
168                 }
169                 DBG(LOG_INFO, "Cancel dbus call");
170         }
171 #endif
172
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");
176                 goto cleanup;
177         }
178
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);
185                 } else {
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);
190                 }
191                 ugd->mac_addr_connecting = NULL;
192         }
193
194         if (ugd->raw_connected_peer_cnt == 0) {
195                 ret = wifi_direct_is_group_owner(&owner);
196                 if (ret == WIFI_DIRECT_ERROR_NONE) {
197                         if (owner)
198                                 wifi_direct_destroy_group();
199                 }
200         }
201
202 cleanup:
203         wfd_ug_view_free_peers(ugd);
204         ret = app_control_create(&control);
205         if (ret) {
206                 DBG(LOG_ERROR, "Failed to create control");
207         } else {
208                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING)
209                         app_control_add_extra_data(control, "Connection", "TRUE");
210                 else
211                         app_control_add_extra_data(control, "Connection", "FALSE");
212
213                 ug_send_result(ugd->ug, control);
214                 app_control_destroy(control);
215         }
216
217         ug_destroy_me(ugd->ug);
218         __FUNC_EXIT__;
219         return;
220 }
221
222 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
223 {
224         __FUNC_ENTER__;
225
226         if (ugd->timer_stop_progress_bar > 0)
227                 g_source_remove(ugd->timer_stop_progress_bar);
228
229         ugd->timer_stop_progress_bar = 0;
230
231         __FUNC_EXIT__;
232 }
233
234 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
235 {
236         __FUNC_ENTER__;
237
238         if (ugd->timer_delete_not_alive_peer > 0)
239                 g_source_remove(ugd->timer_delete_not_alive_peer);
240
241         ugd->timer_delete_not_alive_peer = 0;
242
243         __FUNC_EXIT__;
244 }
245
246 /**
247  *      This function let the ug call it when click failed devices item
248  *      @return   void
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
252  */
253 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
254 {
255         __FUNC_ENTER__;
256
257         struct ug_data *ugd = wfd_get_ug_data();
258         int ret = -1;
259
260         if (NULL == ugd) {
261                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
262                 return;
263         }
264
265         if (ugd->display_timer != NULL) {
266                 ecore_timer_del(ugd->display_timer);
267                 ugd->display_timer = NULL;
268         }
269
270         wfd_refresh_wifi_direct_state(ugd);
271         DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
272
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);
276         } else {
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();
283                 }
284         }
285
286         __FUNC_EXIT__;
287         return;
288 }
289
290 /**
291  *      This function let the ug call it when click 'scan' button
292  *      @return   void
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
296  */
297 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
298 {
299         __FUNC_ENTER__;
300
301         struct ug_data *ugd = (struct ug_data *) data;
302         if (NULL == ugd) {
303                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
304                 return;
305         }
306         int ret = -1;
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);
310
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);
319                         __FUNC_EXIT__;
320                         return;
321                 } else {
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();
328                         }
329                 }
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);
339         } else {
340                 DBG(LOG_INFO, "Invalid Case\n");
341         }
342         __FUNC_EXIT__;
343         return;
344 }
345
346 void wfd_check_gl_busy_peers(struct ug_data *ugd)
347 {
348         __FUNC_ENTER__;
349         if (ugd->gl_busy_peer_cnt == 0)
350                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
351
352         __FUNC_EXIT__;
353 }
354
355 void wfd_check_gl_available_peers(struct ug_data *ugd)
356 {
357         __FUNC_ENTER__;
358         if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL)
359                 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
360
361         __FUNC_EXIT__;
362 }
363
364 /**
365  *      This function let the ug free some peer in genlist
366  *      @return  void
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
370  */
371 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
372 {
373         __FUNC_ENTER__;
374         device_type_s *peer = *start_pos;
375         device_type_s *peer_tmp = peer;
376
377         if (peer == NULL) {
378                 DBG(LOG_INFO, "no peer in genlist");
379                 return;
380         }
381
382         while (peer) {
383                 if (strcmp(peer->mac_addr, mac_addr)) {
384                         peer_tmp = peer;
385                         peer = peer->next;
386                 } else {
387                         if (peer->next != NULL) {
388                                 peer_tmp->next = peer->next;
389                                 break;
390                         } else {
391                                 peer_tmp->next = NULL;
392                                 break;
393                         }
394                 }
395         }
396
397         if (peer == *start_pos) {
398                 DBG(LOG_INFO, "the head is free");
399                 *start_pos = peer->next;
400         }
401
402         (*cnt)--;
403         if (peer) {
404                 WFD_IF_DEL_ITEM(peer->gl_item);
405                 peer->next = NULL;
406                 free(peer);
407         }
408         __FUNC_EXIT__;
409 }
410
411 /**
412  *      This function let the ug call it when click available peer to connect
413  *      @return   void
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
417  */
418 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
419 {
420         __FUNC_ENTER__;
421
422         int res = -1;
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;
430
431         if (!ugd || !peer) {
432                 DBG(LOG_ERROR, "NULL parameters.\n");
433                 return;
434         }
435
436         wfd_ug_get_connected_peers(ugd);
437         DBG(LOG_INFO, "No of connected peers= %d", ugd->raw_connected_peer_cnt);
438
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);
443                 if (item)
444                         elm_genlist_item_selected_set(item, EINA_FALSE);
445
446                 return;
447         }
448
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);
455         }
456
457         if (item)
458                 elm_genlist_item_selected_set(item, EINA_FALSE);
459
460         GList *iterator = NULL;
461
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;
466                         break;
467                 }
468         }
469
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);
480                                 return;
481                         }
482                 }
483         }
484
485         wfd_cancel_not_alive_delete_timer(ugd);
486
487         /* get WFD status */
488         wfd_refresh_wifi_direct_state(ugd);
489
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));
494
495                 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
496                         DBG(LOG_DEBUG, "It's in connecting status now.\n");
497                         return;
498                 }
499
500                 ugd->mac_addr_connecting = peer->mac_addr;
501                 res = wfd_client_connect((const char *)peer->mac_addr);
502                 if (res != 0) {
503                         DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
504                         return;
505                 }
506         }
507
508         __FUNC_EXIT__;
509         return;
510 }
511
512 /**
513  *      This function let the ug call it when click busy peer
514  *      @return   void
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
518  */
519 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
520 {
521         __FUNC_ENTER__;
522         struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
523         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
524
525         if (item)
526                 elm_genlist_item_selected_set(item, EINA_FALSE);
527
528         if (NULL == ugd) {
529                 DBG(LOG_ERROR, "Data is NULL\n");
530                 return;
531         }
532
533         wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
534
535         __FUNC_EXIT__;
536 }
537
538 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
539 {
540         struct ug_data *ugd = (struct ug_data *) data;
541
542         if (!ugd) {
543                 DBG(LOG_ERROR, "The param is NULL\n");
544                 return;
545         }
546
547         if (ugd->ctxpopup) {
548                 evas_object_del(ugd->ctxpopup);
549                 ugd->ctxpopup = NULL;
550         }
551 }
552
553 void _ctxpopup_move()
554 {
555         __FUNC_ENTER__;
556
557         int win_w = 0, win_h = 0;
558         int move_x = 0, move_y = 0;
559         int changed_ang = 0;
560         struct ug_data *ugd = wfd_get_ug_data();
561
562         if (!ugd || !ugd->win) {
563                 DBG(LOG_ERROR, "NULL parameters.\n");
564                 return;
565         }
566
567         if (!ugd->ctxpopup) {
568                 DBG(LOG_INFO, "NULL parameters.\n");
569                 return;
570         }
571
572         elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
573         changed_ang = elm_win_rotation_get(ugd->win);
574
575         switch (changed_ang) {
576         case 0:
577         case 180:
578                 move_x = win_w/2;
579                 move_y = win_h;
580                 break;
581
582         case 90:
583                 move_x = win_h/2;
584                 move_y = win_w;
585                 break;
586
587         case 270:
588                 move_x = win_h/2;
589                 move_y = win_w;
590                 break;
591
592         default:
593                 move_x = 0;
594                 move_y = 0;
595                 break;
596         }
597
598         evas_object_move(ugd->ctxpopup, move_x, move_y);
599
600         __FUNC_EXIT__;
601 }
602
603 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
604 {
605         __FUNC_ENTER__;
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);
609         int ret = 0;
610
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();
620         }
621
622         __FUNC_EXIT__;
623 }
624
625 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
626 {
627         __FUNC_ENTER__;
628
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();
633
634         if (!naviframe || !ugd) {
635                 DBG(LOG_ERROR, "NULL parameters.\n");
636                 return;
637         }
638
639         ugd->more_btn_multiconnect_item = NULL;
640
641         if (ugd->ctxpopup)
642                 evas_object_del(ugd->ctxpopup);
643
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);
650
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);
655
656         _ctxpopup_move();
657
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;
661
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);
668         }
669
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);
673
674         __FUNC_EXIT__;
675 }
676
677 /**
678  *      This function make items into group
679 */
680 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
681 {
682         __FUNC_ENTER__;
683         int i = 0;
684         if (count < 1 || pre_item == NULL)
685                 return;
686
687         Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
688         if (item == NULL)
689                 return;
690
691         if (count == 1) {
692                 elm_object_item_signal_emit(item, "elm,state,normal", "");
693                 return;
694         }
695
696         for (i = 0; i < count; i++) {
697                 if (i == 0)
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", "");
701                 else
702                         elm_object_item_signal_emit(item, "elm,state,center", "");
703
704                 item = elm_genlist_item_next_get(item);
705         }
706         __FUNC_EXIT__;
707 }
708
709 /**
710  *      This function let the ug call it when unresized event is received
711 */
712 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
713 {
714         __FUNC_ENTER__;
715         struct ug_data *ugd = (struct ug_data *)data;
716
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);
722         __FUNC_EXIT__;
723 }
724
725 /**
726  *      This function let the ug call it when resized event is received
727  *      @return   void
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
731  */
732 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
733 {
734         __FUNC_ENTER__;
735
736         if (!data || !event_info) {
737                 DBG(LOG_ERROR, "Invalid parameters");
738                 return;
739         }
740
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);
745         char *sr_msg = NULL;
746 #endif
747
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);
753
754 #ifdef ACCESSIBILITY_FEATURE
755         /* screen reader */
756         if (GENLIST_HEADER_POS == index && item != NULL) {
757                 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
758                 if (check) {
759                         Eina_Bool state = elm_check_state_get(check);
760                         if (state)
761                                 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
762                         else
763                                 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
764
765                         if (sr_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);
769                                 free(sr_msg);
770                         } else {
771                                 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
772                         }
773                 } else {
774                         DBG(LOG_ERROR, "index = %d, get check box fail!", index);
775                 }
776         }
777 #endif
778
779         __FUNC_EXIT__;
780 }
781
782 /**
783  *      This function let the ug call it when click 'disconnect' button
784  *      @return   void
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
788  */
789 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
790 {
791         __FUNC_ENTER__;
792         struct ug_data *ugd = (struct ug_data *)data;
793         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
794
795         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
796
797         __FUNC_EXIT__;
798 }
799
800 /**
801  *      This function let the ug call it when click "cancel connection" button
802  *      @return   void
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
806  */
807 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
808 {
809         __FUNC_ENTER__;
810         struct ug_data *ugd = (struct ug_data *)data;
811         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
812
813         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
814
815         __FUNC_EXIT__;
816 }
817
818
819 /**
820  *      This function let the ug update the genlist item
821  *      @return   void
822  *      @param[in] gl_item the pointer to genlist item
823  */
824 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
825 {
826         __FUNC_ENTER__;
827         if (gl_item != NULL)
828                 elm_genlist_item_update(gl_item);
829
830         __FUNC_EXIT__;
831 }
832
833 /**
834  *      This function let the ug refresh the attributes of button
835  *      @return   void
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
839  */
840 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
841                 int enable)
842 {
843         __FUNC_ENTER__;
844
845         if (NULL == tb_item || NULL == text) {
846                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
847                 return;
848         }
849
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",
852                          PACKAGE, text);
853         elm_object_disabled_set(tb_item, !enable);
854
855         __FUNC_EXIT__;
856 }
857
858 /**
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
863  */
864 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
865 {
866         __FUNC_ENTER__;
867         int i = 0;
868
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) {
872                         return TRUE;
873                 }
874         }
875
876         __FUNC_EXIT__;
877         return FALSE;
878 }
879
880 /**
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
885  */
886 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
887 {
888         __FUNC_ENTER__;
889
890         if (ugd->I_am_group_owner == TRUE) {
891                 if (dev->is_connected || dev->is_group_owner)
892                         return TRUE;
893                 else
894                         return FALSE;
895         } else {
896                 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE)
897                         return FALSE;
898
899                 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE)
900                         return TRUE;
901
902                 if (dev->is_connected == FALSE)
903                         return FALSE;
904         }
905
906         __FUNC_EXIT__;
907         return FALSE;
908 }
909
910 /**
911  *      This function let the ug calculate how many devices are available
912  *      @return   TRUE
913  *      @param[in] ugd the pointer to the main data structure
914  *      @param[in] dev the pointer to the number of available devices
915  */
916 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
917 {
918         __FUNC_ENTER__;
919         GList *iterator = NULL;
920
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))
924                         continue;
925
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)++;
929         }
930
931         __FUNC_EXIT__;
932         return TRUE;
933 }
934
935 /**
936  *      This function let the ug calculate how many devices are busy
937  *      @return   TRUE
938  *      @param[in] ugd the pointer to the main data structure
939  *      @param[in] dev the pointer to the number of busy devices
940  */
941 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
942 {
943         __FUNC_ENTER__;
944         GList *iterator = NULL;
945
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))
949                         continue;
950
951                 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data))
952                         (*no_of_busy_dev)++;
953         }
954
955         __FUNC_EXIT__;
956         return TRUE;
957 }
958
959 /**
960  *      This function let the ug calculate how many devices are connected failed
961  *      @return   TRUE
962  *      @param[in] ugd the pointer to the main data structure
963  *      @param[in] dev the pointer to the number of connected failed devices
964  */
965 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
966 {
967         __FUNC_ENTER__;
968         GList *iterator = NULL;
969
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))
973                         continue;
974
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)++;
978                 }
979         }
980
981         __FUNC_EXIT__;
982         return TRUE;
983 }
984
985 /**
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
989  */
990 static Evas_Object *_create_basic_genlist(void *data)
991 {
992         __FUNC_ENTER__;
993         struct ug_data *ugd = (struct ug_data *) data;
994         Evas_Object *genlist;
995
996         genlist = elm_genlist_add(ugd->layout);
997
998         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
999         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
1000                         EVAS_HINT_EXPAND);
1001         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1002
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,
1008                                         EINA_FALSE);
1009 #endif
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);
1016
1017         __FUNC_EXIT__;
1018         return genlist;
1019 }
1020
1021 /**
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
1025  */
1026 Evas_Object *_create_no_device_genlist(void *data)
1027 {
1028         __FUNC_ENTER__;
1029         struct ug_data *ugd = (struct ug_data *) data;
1030         Elm_Object_Item *last_item = NULL;
1031         int i = 0;
1032
1033         WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1034
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);
1039
1040         } else {
1041                 last_item = ugd->device_name_item;
1042         }
1043
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);
1049
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);
1054
1055         __FUNC_EXIT__;
1056         return ugd->genlist;
1057 }
1058
1059 /**
1060  *      This function let the ug create busy device list
1061  *      @return   0
1062  *      @param[in] data the pointer to the main data structure
1063  */
1064 int _create_busy_dev_list(void *data)
1065 {
1066         __FUNC_ENTER__;
1067         struct ug_data *ugd = (struct ug_data *) data;
1068
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);
1073         __FUNC_EXIT__;
1074         return 0;
1075 }
1076
1077 void wfd_free_nodivice_item(struct ug_data *ugd)
1078 {
1079         __FUNC_ENTER__;
1080         WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1081         WFD_IF_DEL_ITEM(ugd->nodevice_item);
1082         __FUNC_EXIT__;
1083 }
1084
1085 /**
1086  *      This function let the ug create available device list
1087  *      @return   0
1088  *      @param[in] data the pointer to the main data structure
1089  */
1090 int _create_available_dev_genlist(void *data)
1091 {
1092         __FUNC_ENTER__;
1093         int i = 0;
1094         struct ug_data *ugd = (struct ug_data *) data;
1095         Elm_Object_Item *last_item = NULL;
1096
1097         wfd_free_nodivice_item(ugd);
1098
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);
1103
1104         } else {
1105                 last_item = ugd->device_name_item;
1106         }
1107
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);
1113         }
1114         __FUNC_EXIT__;
1115         return 0;
1116 }
1117
1118 /**
1119  *      This function let the ug create multi connect device list
1120  *      @return   0
1121  *      @param[in] data the pointer to the main data structure
1122  */
1123 static int _create_multi_connect_dev_genlist(void *data)
1124 {
1125         __FUNC_ENTER__;
1126         struct ug_data *ugd = (struct ug_data *) data;
1127
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);
1132         __FUNC_EXIT__;
1133         return 0;
1134 }
1135
1136 /**
1137  *      This function let the ug create connected device list
1138  *      @return   0
1139  *      @param[in] data the pointer to the main data structure
1140  */
1141 int _create_connected_dev_genlist(void *data)
1142 {
1143         __FUNC_ENTER__;
1144         struct ug_data *ugd = (struct ug_data *) data;
1145
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);
1151         }
1152
1153         __FUNC_EXIT__;
1154         return 0;
1155 }
1156
1157 /**
1158  *      This function let the ug create connected falied device list
1159  *      @return   0
1160  *      @param[in] data the pointer to the main data structure
1161  */
1162 int _create_connected_failed_dev_genlist(void *data)
1163 {
1164         __FUNC_ENTER__;
1165         struct ug_data *ugd = (struct ug_data *) data;
1166         Elm_Object_Item *last_item = NULL;
1167         int i = 0;
1168
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);
1173
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);
1178
1179         } else {
1180                 last_item = ugd->device_name_item;
1181         }
1182
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);
1187         __FUNC_EXIT__;
1188         return 0;
1189 }
1190
1191 /**
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
1195  */
1196 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1197 {
1198         __FUNC_ENTER__;
1199         int interval = 0;
1200         int res = -1;
1201         struct ug_data *ugd = (struct ug_data *) user_data;
1202
1203         if (NULL == ugd) {
1204                 DBG(LOG_ERROR, "NULL parameters.\n");
1205                 return ECORE_CALLBACK_CANCEL;
1206         }
1207
1208         if (ugd->avlbl_wfd_item == NULL)
1209                 _create_available_dev_genlist(ugd);
1210
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;
1215         }
1216
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;
1221
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();
1231                 }
1232         }
1233
1234         ugd->display_timer = NULL;
1235         __FUNC_EXIT__;
1236         return ECORE_CALLBACK_CANCEL;
1237 }
1238
1239 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1240 {
1241         __FUNC_ENTER__;
1242         device_type_s *peer_for_free = NULL;
1243         device_type_s *peer = gl_peers_start;
1244
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;
1250                 peer = peer->next;
1251                 free(peer_for_free);
1252         }
1253         __FUNC_EXIT__;
1254 }
1255
1256 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1257 {
1258         __FUNC_ENTER__;
1259         if (ugd->gl_connected_peer_cnt == 0)
1260                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1261
1262         __FUNC_EXIT__;
1263 }
1264
1265 /**
1266  *      This function let the ug free the peers
1267  *      @return   void
1268  *      @param[in] data the pointer to the main data structure
1269  */
1270 void wfd_ug_view_free_peers(void *data)
1271 {
1272         __FUNC_ENTER__;
1273
1274         struct ug_data *ugd = (struct ug_data *) data;
1275
1276         ugd->gl_connected_peer_cnt = 0;
1277
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;
1281         }
1282
1283         ugd->gl_available_peer_cnt = 0;
1284
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;
1288         }
1289
1290         ugd->gl_busy_peer_cnt = 0;
1291
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;
1295         }
1296
1297         ugd->gl_multi_connect_peer_cnt = 0;
1298
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;
1302         }
1303
1304         if (ugd->gl_connected_peer_cnt == 0)
1305                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1306
1307         if (ugd->display_timer != NULL) {
1308                 ecore_timer_del(ugd->display_timer);
1309                 ugd->display_timer = NULL;
1310         }
1311
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);
1316
1317         __FUNC_EXIT__;
1318 }
1319
1320 void wfd_ug_update_toolbar(struct ug_data *ugd)
1321 {
1322         __FUNC_ENTER__;
1323         int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1324         Evas_Object *btn;
1325
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",
1343                                 ugd->scan_toolbar);
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");
1348                 } else {
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");
1355                 }
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");
1370                 }
1371                 elm_object_part_content_set(ugd->button_layout, "button.prev",
1372                                 ugd->scan_toolbar);
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");
1377         } else {
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);
1385                 }
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");
1390         }
1391         __FUNC_EXIT__;
1392 }
1393
1394 /**
1395  *      This function let the ug init the genlist
1396  */
1397 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1398 {
1399         __FUNC_ENTER__;
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;
1404
1405         if (is_free_all_peers)
1406                 wfd_ug_view_free_peers(ugd);
1407
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);
1414         }
1415
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);
1419                 return;
1420         }
1421
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);
1425
1426         __FUNC_EXIT__;
1427 }
1428
1429 /**
1430  *      This function let the ug find a peer in genlist
1431  */
1432 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1433 {
1434         __FUNC_ENTER__;
1435
1436         if (start_pos == NULL) {
1437                 DBG(LOG_INFO, "no peer in genlist");
1438                 return NULL;
1439         }
1440
1441         device_type_s *peer = start_pos;
1442
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);
1447                         __FUNC_EXIT__;
1448                         return peer;
1449                 }
1450                 peer = peer->next;
1451         }
1452
1453         __FUNC_EXIT__;
1454         return NULL;
1455 }
1456
1457 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
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         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);
1471
1472                 peer = peer_tmp;
1473         }
1474
1475 //      wfd_check_gl_available_peers(ugd);
1476         if (ugd->gl_busy_peer_cnt == 0)
1477                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1478
1479         __FUNC_EXIT__;
1480         return;
1481 }
1482
1483 void set_not_alive_peers(device_type_s *start_pos)
1484 {
1485         __FUNC_ENTER__;
1486         if (start_pos == NULL) {
1487                 DBG(LOG_INFO, "no peer in genlist");
1488                 return;
1489         }
1490
1491         device_type_s *peer = start_pos;
1492         while (peer != NULL) {
1493                 peer->is_alive = false;
1494                 peer = peer->next;
1495         }
1496
1497         __FUNC_EXIT__;
1498         return;
1499 }
1500
1501 /**
1502  *      This function let the ug get the insert position for next item
1503  */
1504 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1505 {
1506         __FUNC_ENTER__;
1507         int i = 0;
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;
1511
1512         if (peer_cnt == 0) {
1513                 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1514                 return pre_item;
1515         }
1516
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 */
1522                                 __FUNC_EXIT__;
1523                                 return  elm_genlist_item_prev_get(head);
1524                         } else {
1525                                 item = elm_genlist_item_next_get(head);
1526                                 if (item == NULL) {
1527                                         /* return the last item */
1528                                         return head;
1529                                 } else {
1530                                         head = item;
1531                                         peer_ite = (device_type_s *)elm_object_item_data_get(head);
1532                                 }
1533                         }
1534                 }
1535         }
1536         __FUNC_EXIT__;
1537         return elm_genlist_item_prev_get(head);
1538 }
1539
1540 /**
1541  *      This function let the ug insert peer item to genlist
1542  */
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)
1545 {
1546         __FUNC_ENTER__;
1547         WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1548         device_type_s *peer = NULL;
1549         device_type_s *peer_ite = NULL;
1550
1551         peer = (device_type_s *)malloc(sizeof(device_type_s));
1552         WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1553
1554         memcpy(peer, peer_for_insert, sizeof(device_type_s));
1555         peer->next = NULL;
1556
1557         if (*start_pos == NULL) {
1558                 *start_pos = peer;
1559         } else {
1560                 peer_ite = *start_pos;
1561                 while (peer_ite->next != NULL) {
1562                         /* move pointer to the last peer */
1563                         peer_ite = peer_ite->next;
1564                 }
1565                 peer_ite->next = peer;
1566         }
1567
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);
1573
1574         __FUNC_EXIT__;
1575         return 0;
1576 }
1577
1578 /**
1579  *      This function let the ug update connected peers
1580  *      @return   void
1581  *      @param[in] data the pointer to the main data structure
1582  */
1583 void wfd_ug_update_connected_peers(void *data)
1584 {
1585         __FUNC_ENTER__;
1586
1587         struct ug_data *ugd = (struct ug_data *) data;
1588         int i = 0 ;
1589         int res;
1590         bool is_group_owner = FALSE;
1591         Elm_Object_Item *item = NULL;
1592
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);
1596
1597         if (!ugd->conn_wfd_item)
1598                 _create_connected_dev_genlist(ugd);
1599
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);
1606                         }
1607
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);
1614                                 }
1615                         }
1616
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);
1621                         if (res != 0)
1622                                 break;
1623
1624                         ugd->gl_connected_peer_cnt++;
1625                 }
1626         }
1627
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);
1632
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;
1636                 }
1637         }
1638
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);
1643
1644                 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1645                 ugd->gl_busy_peers_start = NULL;
1646
1647         }
1648
1649         __FUNC_EXIT__;
1650 }
1651
1652 /**
1653  *      This function let the ug update the multi-connect peers
1654  *      @return   void
1655  *      @param[in] data the pointer to the main data structure
1656  */
1657 void wfd_ug_view_update_multiconn_peers(void *data)
1658 {
1659         __FUNC_ENTER__;
1660
1661         struct ug_data *ugd = (struct ug_data *) data;
1662         int i;
1663         int res;
1664         Elm_Object_Item *item = NULL;
1665
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);
1670                 }
1671
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);
1678                                 if (res != 0)
1679                                         break;
1680
1681                                 ugd->gl_multi_connect_peer_cnt++;
1682                         }
1683                 }
1684         }
1685
1686         __FUNC_EXIT__;
1687 }
1688
1689 /**
1690  *      This function let the ug update the available and busy peers
1691  */
1692 void wfd_ug_update_available_peers(void *data)
1693 {
1694         __FUNC_ENTER__;
1695
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;
1701         int res = 0;
1702         Elm_Object_Item *item = NULL;
1703         device_type_s *peer = NULL;
1704         GList *iterator = NULL;
1705
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;
1709
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;
1714         } else {
1715                 ugd->I_am_group_owner = is_group_owner;
1716         }
1717
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);
1722         }
1723
1724         if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1725                 if (ugd->avlbl_wfd_item == NULL)
1726                         _create_available_dev_genlist(ugd);
1727
1728
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))
1732                                 continue;
1733
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);
1741                                 }
1742
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);
1748                                 }
1749
1750                                 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL)
1751                                         continue;
1752
1753                                 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1754                                 if (peer == NULL) {
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);
1759                                         if (res != 0)
1760                                                 break;
1761
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);
1767                                 }
1768                         }
1769                 }
1770         }
1771
1772         wfd_check_gl_available_peers(ugd);
1773         wfd_check_gl_conn_peers(ugd);
1774
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);
1778
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))
1782                                 continue;
1783
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);
1791                                         }
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);
1796                                         if (res != 0)
1797                                                 break;
1798
1799                                         ugd->gl_busy_peer_cnt++;
1800                                 }
1801                         }
1802                 }
1803         }
1804
1805         wfd_check_gl_busy_peers(ugd);
1806
1807         __FUNC_EXIT__;
1808 }
1809
1810 /**
1811  *      This function let the ug update the failed peers
1812  *      @return   void
1813  *      @param[in] data the pointer to the main data structure
1814  */
1815 void wfd_ug_update_failed_peers(void *data)
1816 {
1817         __FUNC_ENTER__;
1818         struct ug_data *ugd = (struct ug_data *) data;
1819         int no_of_conn_failed_dev = 0;
1820         GList *iterator = NULL;
1821
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);
1824
1825         if (no_of_conn_failed_dev == 0)
1826                 return;
1827
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);
1832         }
1833
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);
1842                                 }
1843                         }
1844                 }
1845         }
1846
1847         __FUNC_EXIT__;
1848 }
1849
1850 #ifdef WFD_ON_OFF_GENLIST
1851 /**
1852  *      This function is called when user swipes on/off button
1853  *      @return   void
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
1857  */
1858 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1859 {
1860         __FUNC_ENTER__;
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);
1867
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;
1874         }
1875         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1876
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,
1882                                                                 EINA_FALSE);
1883                         wfd_client_switch_on(ugd);
1884                 }
1885         } else {
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,
1889                                                                 EINA_FALSE);
1890                         wfd_client_switch_off(ugd);
1891                 }
1892         }
1893
1894         __FUNC_EXIT__;
1895 }
1896
1897 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1898 {
1899         __FUNC_ENTER__;
1900         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1901         WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1902
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);
1907         else
1908                 elm_object_disabled_set(ugd->on_off_check, FALSE);
1909
1910         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
1911                 elm_check_state_set(ugd->on_off_check, TRUE);
1912         else
1913                 elm_check_state_set(ugd->on_off_check, FALSE);
1914
1915         __FUNC_EXIT__;
1916 }
1917
1918 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1919 {
1920         __FUNC_ENTER__;
1921         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1922         WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1923
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;
1933
1934         __FUNC_EXIT__;
1935 }
1936 #endif
1937
1938 /**
1939  *      This function let the ug create the main view
1940  *      @return   void
1941  *      @param[in] data the pointer to the main data structure
1942  */
1943 void create_wfd_ug_view(void *data)
1944 {
1945         __FUNC_ENTER__;
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;
1950 #endif
1951         Evas_Object *layout;
1952
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);
1958
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);
1963
1964         /* Create layout */
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;
1969
1970         ugd->genlist = _create_basic_genlist(ugd);
1971         if (ugd->genlist == NULL) {
1972                 DBG(LOG_ERROR, "Failed to create basic genlist");
1973                 return;
1974         }
1975         elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1976
1977         evas_object_show(ugd->base);
1978         elm_object_focus_set(ugd->base, EINA_TRUE);
1979
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);
1983
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",
1990                         more_btn);
1991 #endif
1992
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);
1997
1998         if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1999                 int ret = 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();
2008                 }
2009                 return;
2010         }
2011
2012         __FUNC_EXIT__;
2013 }
2014
2015 /**
2016  *      This function let the ug destroy the main view
2017  *      @return   void
2018  *      @param[in] data the pointer to the main data structure
2019  */
2020 void destroy_wfd_ug_view(void *data)
2021 {
2022         __FUNC_ENTER__;
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);
2027
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);
2035         __FUNC_EXIT__;
2036 }