Merge branch 'master' into tizen_2.1
[apps/native/ug-wifi-direct.git] / ug-wifidirect / src / wfd_ug.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://floralicense.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 #ifndef UG_MODULE_API
22 #define UG_MODULE_API __attribute__ ((visibility("default")))
23 #endif
24
25
26 #include <sys/time.h>
27 #include <libintl.h>
28 #include <sys/utsname.h>
29
30 #include <vconf.h>
31 #include <Elementary.h>
32 #include <ui-gadget-module.h>
33 #include <wifi-direct.h>
34
35 #include "wfd_ug.h"
36 #include "wfd_ug_view.h"
37 #include "wfd_client.h"
38
39 void initialize_gen_item_class();
40
41 struct ug_data *global_ugd = NULL;
42
43 struct ug_data *wfd_get_ug_data()
44 {
45         return global_ugd;
46 }
47
48 /**
49  *      This function let the ug create backgroud
50  *      @return  backgroud
51  *      @param[in] ugd the pointer to the parent object
52  *      @param[in] ugd the pointer to the main data structure
53  */
54 static Evas_Object *_create_bg(Evas_Object *parent, char *style)
55 {
56         __WDUG_LOG_FUNC_ENTER__;
57         Evas_Object *bg;
58
59         bg = elm_bg_add(parent);
60         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
61         elm_object_style_set(bg, style);
62         elm_win_resize_object_add(parent, bg);
63         evas_object_show(bg);
64
65         __WDUG_LOG_FUNC_EXIT__;
66         return bg;
67 }
68
69 /**
70  *      This function let the ug create full view
71  *      @return  full view
72  *      @param[in] ugd the pointer to the parent object
73  *      @param[in] ugd the pointer to the main data structure
74  */
75 static Evas_Object *_create_fullview(Evas_Object *parent, struct ug_data *ugd)
76 {
77         __WDUG_LOG_FUNC_ENTER__;
78         Evas_Object *base;
79
80         if (parent == NULL) {
81                 WDUG_LOGE( "Incorrenct parameter");
82                 return NULL;
83         }
84
85         /* Create Full view */
86         base = elm_layout_add(parent);
87         if (!base) {
88                 WDUG_LOGE( "Failed to add layout");
89                 return NULL;
90         }
91
92         elm_layout_theme_set(base, "layout", "application", "default");
93         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
94         evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL);
95
96         __WDUG_LOG_FUNC_EXIT__;
97         return base;
98 }
99
100 /**
101  *      This function let the ug create frame view
102  *      @return  frame view
103  *      @param[in] ugd the pointer to the parent object
104  *      @param[in] ugd the pointer to the main data structure
105  */
106 static Evas_Object *_create_frameview(Evas_Object *parent, struct ug_data *ugd)
107 {
108         __WDUG_LOG_FUNC_ENTER__;
109         Evas_Object *base;
110
111         if (parent == NULL) {
112                 WDUG_LOGE( "Incorrenct parameter");
113                 return NULL;
114         }
115
116         /* Create Frame view */
117         base = elm_layout_add(parent);
118         if (!base) {
119                 WDUG_LOGE( "Failed to add layout");
120                 return NULL;
121         }
122
123         elm_layout_theme_set(base, "layout", "application", "default");
124         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
125         evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL);
126
127         __WDUG_LOG_FUNC_EXIT__;
128         return base;
129 }
130
131 /**
132  *      This function let the ug destroy the main view
133  *      @return   void
134  *      @param[in] data the pointer to the main data structure
135  */
136 void destroy_wfd_ug_view(void *data)
137 {
138         __WDUG_LOG_FUNC_ENTER__;
139         struct ug_data *ugd = (struct ug_data *) data;
140
141         if (ugd->genlist) {
142                 evas_object_del(ugd->genlist);
143                 ugd->genlist = NULL;
144         }
145
146         if (ugd->naviframe) {
147                 evas_object_del(ugd->naviframe);
148                 ugd->naviframe = NULL;
149         }
150
151         __WDUG_LOG_FUNC_EXIT__;
152 }
153
154 /**
155  *      This function let the ug initialize wfd when timeout
156  *      @return   if stop the timer, return false, else return true
157  *      @param[in] data the pointer to the main data structure
158  */
159 gboolean _wfd_init_cb(void *data)
160 {
161         __WDUG_LOG_FUNC_ENTER__;
162         int res = -1;
163         struct ug_data *ugd = (struct ug_data *) data;
164
165         if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATED) {
166                 res = init_wfd_client(ugd);
167                 if (res != 0) {
168                         WDUG_LOGE( "Failed to initialize WFD client library\n");
169                         return true;
170                 }
171         }
172
173         __WDUG_LOG_FUNC_EXIT__;
174         return false;
175 }
176
177 static void *on_create(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv)
178 {
179         __WDUG_LOG_FUNC_ENTER__;
180         struct ug_data *ugd;
181         int res = 0;
182
183         if (!ug || !priv) {
184                 return NULL;
185         }
186
187         ugd = priv;
188         ugd->ug = ug;
189
190         bindtextdomain(PACKAGE, LOCALEDIR);
191
192         ugd->win = ug_get_window();
193         if (!ugd->win) {
194                 return NULL;
195         }
196
197         if (mode == UG_MODE_FULLVIEW) {
198                 ugd->base = _create_fullview(ugd->win, ugd);
199         } else {
200                 ugd->base = _create_frameview(ugd->win, ugd);
201         }
202
203         if (ugd->base) {
204                 ugd->bg = _create_bg(ugd->win, "group_list");
205                 elm_object_part_content_set(ugd->base, "elm.swallow.bg", ugd->bg);
206         } else {
207                 WDUG_LOGE( "Failed to create base layout\n");
208                 return NULL;
209         }
210
211         /* check status of wifi-direct from vconf */
212         wfd_get_vconf_status(ugd);
213
214         /*
215         * if not deactivated, do initialization at once;
216         * otherwise, do initialization later
217         */
218         if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATED || service) {
219                 res = init_wfd_client(ugd);
220                 if (res != 0) {
221                         WDUG_LOGE( "Failed to initialize WFD client library\n");
222                 }
223
224                 if (service) {
225                         int status = 0;
226                         char *data = NULL;
227
228                         /* get the status from appsvc */
229                         service_get_extra_data(service, "status", &data);
230                         if (data) {
231                                 status = atoi(data);
232                         }
233
234                         /*
235                         * status -
236                         * 0 : No operation,
237                         * 1 : Activate ,
238                         * 2 : Deactivate
239                         */
240                         if (status == 0x01) {
241                                 wfd_client_switch_on(ugd);
242                         } else if (status == 0x02) {
243                                 wfd_client_switch_off(ugd);
244                         }
245                 }
246         } else {
247                 g_timeout_add(100, _wfd_init_cb, ugd);
248         }
249
250         if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) {
251                 wfd_ug_get_discovered_peers(ugd);
252         }
253
254         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
255                 wfd_ug_get_connected_peers(ugd);
256         }
257
258         if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED) {
259                 /* start discovery */
260                 res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
261                 if (res != WIFI_DIRECT_ERROR_NONE) {
262                         WDUG_LOGE( "Failed to start discovery. [%d]\n", res);
263                         ugd->is_re_discover = TRUE;
264                         wifi_direct_cancel_discovery();
265                 } else {
266                         WDUG_LOGI("Discovery is started\n");
267                         ugd->is_re_discover = FALSE;
268                 }
269         }
270
271         /* draw UI */
272         initialize_gen_item_class();
273         create_wfd_ug_view(ugd);
274         wfd_ug_view_update_peers(ugd);
275
276         evas_object_show(ugd->base);
277
278         __WDUG_LOG_FUNC_EXIT__;
279         return ugd->base;
280 }
281
282 static void on_start(ui_gadget_h ug, service_h service, void *priv)
283 {
284         __WDUG_LOG_FUNC_ENTER__;
285         struct ug_data *ugd;
286         int res;
287
288         if (!ug || !priv) {
289                 return;
290         }
291
292         ugd = priv;
293
294         struct utsname kernel_info;
295         res = uname(&kernel_info);
296         if (res != 0) {
297                 WDUG_LOGE( "Failed to detect target type\n");
298         } else {
299                 WDUG_LOGI("HW ID of this device [%s]\n", kernel_info.machine);
300                 if (strncmp(kernel_info.machine, "arm", 3) != 0) {
301                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_NOT_SUPPORTED_DEVICE"), POPUP_TYPE_TERMINATE);
302                         return;
303                 }
304         }
305
306         __WDUG_LOG_FUNC_EXIT__;
307 }
308
309 static void on_pause(ui_gadget_h ug, service_h service, void *priv)
310 {
311         __WDUG_LOG_FUNC_ENTER__;
312         __WDUG_LOG_FUNC_EXIT__;
313 }
314
315 static void on_resume(ui_gadget_h ug, service_h service, void *priv)
316 {
317         __WDUG_LOG_FUNC_ENTER__;
318         __WDUG_LOG_FUNC_EXIT__;
319 }
320
321 static void on_destroy(ui_gadget_h ug, service_h service, void *priv)
322 {
323         __WDUG_LOG_FUNC_ENTER__;
324
325         if (!ug || !priv) {
326                 WDUG_LOGE( "The param is NULL\n");
327                 return;
328         }
329
330         struct ug_data *ugd = priv;
331         if (ugd == NULL || ugd->base == NULL) {
332                 WDUG_LOGE( "The param is NULL\n");
333                 return;
334         }
335
336         deinit_wfd_client(ugd);
337         WDUG_LOGI("WFD client deregistered");
338
339         destroy_wfd_ug_view(ugd);
340         WDUG_LOGI("Destroying About item");
341
342         wfd_ug_view_free_peers(ugd);
343
344         WDUG_LOGI("WFD client deregistered");
345         if (ugd->bg) {
346                 evas_object_del(ugd->bg);
347                 ugd->bg = NULL;
348         }
349         WDUG_LOGI("WFD client deregistered");
350
351         if (ugd->base) {
352                 evas_object_del(ugd->base);
353                 ugd->base = NULL;
354         }
355
356         __WDUG_LOG_FUNC_EXIT__;
357         return;
358 }
359
360 static void on_message(ui_gadget_h ug, service_h msg, service_h service, void *priv)
361 {
362         __WDUG_LOG_FUNC_ENTER__;
363         __WDUG_LOG_FUNC_EXIT__;
364 }
365
366 static void on_event(ui_gadget_h ug, enum ug_event event, service_h service, void *priv)
367 {
368         __WDUG_LOG_FUNC_ENTER__;
369
370         if (!ug || !priv) {
371                 WDUG_LOGE( "The param is NULL\n");
372                 return;
373         }
374
375         switch (event) {
376         case UG_EVENT_LOW_MEMORY:
377                 WDUG_LOGI("UG_EVENT_LOW_MEMORY\n");
378                 break;
379         case UG_EVENT_LOW_BATTERY:
380                 WDUG_LOGI("UG_EVENT_LOW_BATTERY\n");
381                 break;
382         case UG_EVENT_LANG_CHANGE:
383                 WDUG_LOGI("UG_EVENT_LANG_CHANGE\n");
384                 break;
385         case UG_EVENT_ROTATE_PORTRAIT:
386                 WDUG_LOGI("UG_EVENT_ROTATE_PORTRAIT\n");
387                 break;
388         case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
389                 WDUG_LOGI("UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN\n");
390                 break;
391         case UG_EVENT_ROTATE_LANDSCAPE:
392                 WDUG_LOGI("UG_EVENT_ROTATE_LANDSCAPE\n");
393                 break;
394         case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
395                 WDUG_LOGI("UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN\n");
396                 break;
397         default:
398                 WDUG_LOGI("default\n");
399                 break;
400         }
401
402         __WDUG_LOG_FUNC_EXIT__;
403 }
404
405 static void on_key_event(ui_gadget_h ug, enum ug_key_event event, service_h service, void *priv)
406 {
407         __WDUG_LOG_FUNC_ENTER__;
408
409         if (!ug || !priv) {
410                 WDUG_LOGE( "The param is NULL\n");
411                 return;
412         }
413
414         switch (event) {
415         case UG_KEY_EVENT_END:
416                 WDUG_LOGI("UG_KEY_EVENT_END\n");
417                 break;
418         default:
419                 break;
420         }
421
422         __WDUG_LOG_FUNC_EXIT__;
423 }
424
425 UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops)
426 {
427         __WDUG_LOG_FUNC_ENTER__;
428         struct ug_data *ugd;
429
430         if (!ops) {
431                 WDUG_LOGE( "The param is NULL\n");
432                 return -1;
433         }
434
435         ugd = calloc(1, sizeof(struct ug_data));
436         if (ugd == NULL) {
437                 WDUG_LOGE( "Failed to allocate memory for UG data\n");
438                 return -1;
439         }
440
441         global_ugd = ugd;
442
443         ops->create = on_create;
444         ops->start = on_start;
445         ops->pause = on_pause;
446         ops->resume = on_resume;
447         ops->destroy = on_destroy;
448         ops->message = on_message;
449         ops->event = on_event;
450         ops->key_event = on_key_event;
451         ops->priv = ugd;
452         ops->opt = UG_OPT_INDICATOR_ENABLE;
453
454         __WDUG_LOG_FUNC_EXIT__;
455         return 0;
456 }
457
458 UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops)
459 {
460         __WDUG_LOG_FUNC_ENTER__;
461
462         struct ug_data *ugd;
463
464         if (!ops) {
465                 WDUG_LOGE( "The param is NULL\n");
466                 return;
467         }
468
469         ugd = ops->priv;
470
471         if (ugd) {
472                 free(ugd);
473         }
474
475         __WDUG_LOG_FUNC_EXIT__;
476 }
477
478 UG_MODULE_API int setting_plugin_reset(service_h service, void *priv)
479 {
480         __WDUG_LOG_FUNC_ENTER__;
481         int res = -1;
482         wifi_direct_state_e state;
483
484         res = wifi_direct_initialize();
485         if (res != WIFI_DIRECT_ERROR_NONE) {
486                 WDUG_LOGE( "Failed to initialize wifi direct. [%d]\n", res);
487                 return -1;
488         }
489
490         res = wifi_direct_get_state(&state);
491         if (res != WIFI_DIRECT_ERROR_NONE) {
492                 WDUG_LOGE( "Failed to get link status. [%d]\n", res);
493                 return -1;
494         }
495
496         if (state < WIFI_DIRECT_STATE_ACTIVATING) {
497                 WDUG_LOGI("No need to reset Wi-Fi Direct.\n");
498         } else {
499                 /*if connected, disconnect all devices*/
500                 if (WIFI_DIRECT_STATE_CONNECTED == state) {
501                         res = wifi_direct_disconnect_all();
502                         if (res != WIFI_DIRECT_ERROR_NONE) {
503                                 WDUG_LOGE( "Failed to send disconnection request to all. [%d]\n", res);
504                                 return -1;
505                         }
506                 }
507
508                 res = wifi_direct_deactivate();
509                 if (res != WIFI_DIRECT_ERROR_NONE) {
510                         WDUG_LOGE( "Failed to reset Wi-Fi Direct. [%d]\n", res);
511                         return -1;
512                 }
513         }
514
515         res = wifi_direct_deinitialize();
516         if (res != WIFI_DIRECT_ERROR_NONE) {
517                 WDUG_LOGE( "Failed to deinitialize wifi direct. [%d]\n", res);
518                 return -1;
519         }
520
521         __WDUG_LOG_FUNC_EXIT__;
522         return 0;
523 }
524