Tizen 2.1 base
[apps/native/ug-bluetooth-efl.git] / src / ui / bt-main-ug.c
1 /*
2  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <aul.h>
18 #include <vconf.h>
19 #include <vconf-internal-setting-keys.h>
20 #include <Evas.h>
21 #include <Edje.h>
22 #include <dbus/dbus.h>
23 #include <dbus/dbus-glib-bindings.h>
24
25 #include "bt-main-ug.h"
26 #include "bt-util.h"
27 #include "bt-widget.h"
28 #include "bt-main-view.h"
29 #include "bt-ipc-handler.h"
30 #include "bt-debug.h"
31 #include "bt-resource.h"
32 #include "bt-callback.h"
33 #include "bt-string-define.h"
34 #include "bt-net-connection.h"
35
36 static void __on_destroy(ui_gadget_h ug, service_h service, void *priv);
37
38
39 /**********************************************************************
40 *                                               Static Functions
41 ***********************************************************************/
42
43 static void bt_ug_change_language(bt_ug_data *ugd)
44 {
45         FN_START;
46
47         ret_if(ugd == NULL);
48
49         if (ugd->profile_vd) {
50                 if (ugd->profile_vd->genlist)
51                         elm_genlist_realized_items_update(
52                                         ugd->profile_vd->genlist);
53
54                 if (ugd->profile_vd->navi_it)
55                         elm_object_item_text_set(ugd->profile_vd->navi_it,
56                                         BT_STR_DETAILS);
57         }
58
59         if (ugd->main_genlist)
60                 elm_genlist_realized_items_update(ugd->main_genlist);
61
62         if (ugd->navi_it)
63                 elm_object_item_text_set(ugd->navi_it, BT_STR_BLUETOOTH);
64
65         FN_END;
66 }
67
68 static Evas_Object *__bt_create_fullview(Evas_Object * parent, bt_ug_data *ugd)
69 {
70         FN_START;
71
72         Evas_Object *base = NULL;
73
74         base = elm_layout_add(parent);
75         if (!base)
76                 return NULL;
77
78         elm_layout_theme_set(base, "layout", "application", "default");
79         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
80                                          EVAS_HINT_EXPAND);
81         evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL);
82
83         FN_END;
84         return base;
85 }
86
87 static Evas_Object *__bt_create_frameview(Evas_Object * parent,
88                                           bt_ug_data *ugd)
89 {
90         FN_START;
91
92         Evas_Object *base = NULL;
93
94         base = elm_layout_add(parent);
95         if (!base)
96                 return NULL;
97
98         elm_layout_theme_set(base, "layout", "application", "default");
99         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
100                                          EVAS_HINT_EXPAND);
101         evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL);
102
103         FN_END;
104         return base;
105 }
106
107 static void __bt_ug_release_memory(bt_ug_data *ugd)
108 {
109         FN_START;
110
111         bt_dev_t *dev = NULL;
112         Eina_List *l = NULL;
113         Eina_List *l_next = NULL;
114
115         ret_if(ugd == NULL);
116
117         /* Release profile view data */
118         if (ugd->profile_vd) {
119                 if (ugd->profile_vd->genlist)
120                         elm_genlist_clear(ugd->profile_vd->genlist);
121
122                 if (ugd->profile_vd->name_itc) {
123                         elm_genlist_item_class_free(ugd->profile_vd->name_itc);
124                         ugd->profile_vd->name_itc = NULL;
125                 }
126
127                 if (ugd->profile_vd->unpair_itc) {
128                         elm_genlist_item_class_free(ugd->profile_vd->unpair_itc);
129                         ugd->profile_vd->unpair_itc = NULL;
130                 }
131
132                 if (ugd->profile_vd->title_itc) {
133                         elm_genlist_item_class_free(ugd->profile_vd->title_itc);
134                         ugd->profile_vd->title_itc = NULL;
135                 }
136
137                 if (ugd->profile_vd->call_itc) {
138                         elm_genlist_item_class_free(ugd->profile_vd->call_itc);
139                         ugd->profile_vd->call_itc = NULL;
140                 }
141
142                 if (ugd->profile_vd->media_itc) {
143                         elm_genlist_item_class_free(ugd->profile_vd->media_itc);
144                         ugd->profile_vd->media_itc = NULL;
145                 }
146
147                 if (ugd->profile_vd->hid_itc) {
148                         elm_genlist_item_class_free(ugd->profile_vd->hid_itc);
149                         ugd->profile_vd->hid_itc = NULL;
150                 }
151
152                 free(ugd->profile_vd);
153                 ugd->profile_vd = NULL;
154         }
155
156         /* Release paired device items */
157         EINA_LIST_FOREACH_SAFE(ugd->paired_device, l, l_next, dev) {
158                 ugd->paired_device =
159                     eina_list_remove_list(ugd->paired_device, l);
160                 _bt_util_free_device_item(dev);
161         }
162
163         /* Release searched device items */
164         EINA_LIST_FOREACH_SAFE(ugd->searched_device, l, l_next, dev) {
165                 ugd->searched_device =
166                     eina_list_remove_list(ugd->searched_device, l);
167                 _bt_util_free_device_item(dev);
168         }
169
170         /* Release genlist item class */
171         if (ugd->sp_itc) {
172                 elm_genlist_item_class_free(ugd->sp_itc);
173                 ugd->sp_itc = NULL;
174         }
175
176         if (ugd->status_itc) {
177                 elm_genlist_item_class_free(ugd->status_itc);
178                 ugd->status_itc = NULL;
179         }
180
181         if (ugd->visible_itc) {
182                 elm_genlist_item_class_free(ugd->visible_itc);
183                 ugd->visible_itc = NULL;
184         }
185
186         if (ugd->timeout_value_itc) {
187                 elm_genlist_item_class_free(ugd->timeout_value_itc);
188                 ugd->timeout_value_itc = NULL;
189         }
190
191         if (ugd->paired_title_itc) {
192                 elm_genlist_item_class_free(ugd->paired_title_itc);
193                 ugd->paired_title_itc = NULL;
194         }
195
196         if (ugd->searched_title_itc) {
197                 elm_genlist_item_class_free(ugd->searched_title_itc);
198                 ugd->searched_title_itc = NULL;
199         }
200
201         if (ugd->device_itc) {
202                 elm_genlist_item_class_free(ugd->device_itc);
203                 ugd->device_itc = NULL;
204         }
205
206         if (ugd->searched_itc) {
207                 elm_genlist_item_class_free(ugd->searched_itc);
208                 ugd->searched_itc = NULL;
209         }
210
211         if (ugd->no_device_itc) {
212                 elm_genlist_item_class_free(ugd->no_device_itc);
213                 ugd->no_device_itc = NULL;
214         }
215
216         if (ugd->main_genlist)
217                 elm_genlist_clear(ugd->main_genlist);
218
219         /* Unref the Dbus connections */
220         if (ugd->conn)
221                 dbus_g_connection_unref(ugd->conn);
222
223         if (ugd->popup_bundle) {
224                 free(ugd->popup_bundle);
225                 ugd->popup_bundle = NULL;
226         }
227
228         if (ugd->popup_timer) {
229                 g_source_remove(ugd->popup_timer);
230                 ugd->popup_timer = 0;
231         }
232
233         FN_END;
234 }
235
236 static void *__on_create(ui_gadget_h ug, enum ug_mode mode, service_h service,
237                          void *priv)
238 {
239         FN_START;
240
241         bt_ug_data *ugd = NULL;
242         Evas_Object *bg = NULL;
243
244         if (!ug || !priv)
245                 return NULL;
246
247         ugd = (bt_ug_data *)priv;
248         ugd->ug = ug;
249
250         bindtextdomain(PKGNAME, LOCALEDIR);
251
252         ugd->win_main = ug_get_parent_layout(ug);
253
254         if (!ugd->win_main)
255                 return NULL;
256
257         if (mode == UG_MODE_FULLVIEW) {
258                 ugd->base = __bt_create_fullview(ugd->win_main, ugd);
259                 bg = _bt_create_bg(ugd->win_main, "group_list");
260                 elm_object_part_content_set(ugd->base, "elm.swallow.bg", bg);
261         } else {
262                 ugd->base = __bt_create_frameview(ugd->win_main, ugd);
263                 bg = _bt_create_bg(ugd->win_main, "transparent");
264                 elm_object_part_content_set(ugd->base, "elm.swallow.bg", bg);
265         }
266
267         _bt_main_init_status(ugd, service);
268         _bt_ipc_init_event_signal((void *)ugd);
269
270         ugd->service = service;
271
272         if (ugd->bt_launch_mode != BT_LAUNCH_VISIBILITY) {
273                 _bt_main_draw_list_view(ugd);
274         } else {
275                 _bt_main_draw_visibility_view(ugd);
276         }
277
278         evas_object_show(ugd->base);
279
280         ugd->ug_status = BT_UG_CREATE;
281
282         FN_END;
283         return ugd->base;
284 }
285
286 static void __on_start(ui_gadget_h ug, service_h service, void *priv)
287 {
288         FN_START;
289
290         int g_angle = 0;
291         bt_ug_data *ugd = NULL;
292
293         retm_if(priv == NULL, "Invalid argument: priv is NULL\n");
294
295         ugd = priv;
296
297         g_angle = elm_win_rotation_get(ugd->win_main);
298         ugd->rotation = (int)(g_angle / 90);
299
300         BT_DBG("rotation: %d", ugd->rotation);
301
302         ugd->ug_status = BT_UG_START;
303
304         FN_END;
305 }
306
307 static void __on_pause(ui_gadget_h ug, service_h service, void *priv)
308 {
309         FN_START;
310         bt_ug_data *ugd = NULL;
311
312         retm_if(priv == NULL, "Invalid argument: priv is NULL\n");
313
314         ugd = (bt_ug_data *)priv;
315
316         if (ugd->op_status == BT_SEARCHING)
317                 bt_adapter_stop_device_discovery();
318
319         ugd->ug_status = BT_UG_PAUSE;
320
321         FN_END;
322 }
323
324 static void __on_resume(ui_gadget_h ug, service_h service, void *priv)
325 {
326         FN_START;
327
328         bt_ug_data *ugd = NULL;
329
330         retm_if(priv == NULL, "Invalid argument: priv is NULL\n");
331
332         ugd = (bt_ug_data *)priv;
333
334         ugd->ug_status = BT_UG_RESUME;
335
336         if (ugd->visible_item)
337                 elm_genlist_item_update(ugd->visible_item);
338
339         FN_END;
340 }
341
342 static void __on_destroy(ui_gadget_h ug, service_h service, void *priv)
343 {
344         FN_START;
345
346         bt_ug_data *ugd = NULL;
347         int state;
348
349         if (!ug || !priv)
350                 return;
351
352         ugd = priv;
353
354         ugd->ug_status = BT_UG_DESTORY;
355
356         if (ugd->request_timer) {
357                 ecore_timer_del(ugd->request_timer);
358                 ugd->request_timer = NULL;
359         }
360
361         if (ugd->timeout_id) {
362                 g_source_remove(ugd->timeout_id);
363                 ugd->timeout_id = 0;
364         }
365
366         if (ugd->op_status == BT_SEARCHING)
367                 bt_adapter_stop_device_discovery();
368
369         if (ugd->selectioninfo) {
370                 evas_object_del(ugd->selectioninfo);
371                 ugd->selectioninfo = NULL;
372         }
373
374         bt_adapter_unset_state_changed_cb();
375         bt_adapter_unset_device_discovery_state_changed_cb();
376         bt_device_unset_bond_created_cb();
377         bt_device_unset_bond_destroyed_cb();
378         bt_device_unset_service_searched_cb();
379         bt_audio_unset_connection_state_changed_cb();
380         bt_hid_host_deinitialize();
381         bt_audio_deinitialize();
382
383         bt_deinitialize();
384
385         _bt_destroy_net_connection(ugd->connection);
386
387         _bt_ipc_unregister_popup_event_signal(ugd->EDBusHandle, (void *)ugd);
388         _bt_ipc_deinit_event_signal((void *)ugd);
389
390         __bt_ug_release_memory(ugd);
391
392         if (ugd->base) {
393                 evas_object_del(ugd->base);
394                 ugd->base = NULL;
395         }
396
397         FN_END;
398 }
399
400 static void __on_message(ui_gadget_h ug, service_h msg, service_h service,
401                          void *priv)
402 {
403         FN_START;
404         FN_END;
405 }
406
407 static void __on_event(ui_gadget_h ug, enum ug_event event, service_h service,
408                        void *priv)
409 {
410         FN_START;
411
412         bt_ug_data *ugd = NULL;
413
414         ret_if(priv == NULL);
415
416         ugd = (bt_ug_data *)priv;
417
418         BT_DBG("event: %d", event);
419
420         switch (event) {
421         case UG_EVENT_LOW_MEMORY:
422                 break;
423         case UG_EVENT_LOW_BATTERY:
424                 if (_bt_util_is_battery_low() == FALSE)
425                         return;
426
427                 if (ugd->op_status == BT_SEARCHING)
428                         bt_adapter_stop_device_discovery();
429
430                 _bt_main_create_information_popup(ugd, BT_STR_LOW_BATTERY);
431                 break;
432         case UG_EVENT_LANG_CHANGE:
433                 bt_ug_change_language(ugd);
434                 break;
435         case UG_EVENT_ROTATE_PORTRAIT:
436                 ugd->rotation = BT_ROTATE_PORTRAIT;
437                 break;
438         case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
439                 ugd->rotation = BT_ROTATE_PORTRAIT_UPSIDEDOWN;
440                 break;
441         case UG_EVENT_ROTATE_LANDSCAPE:
442                 ugd->rotation = BT_ROTATE_LANDSCAPE;
443                 break;
444         case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
445                 ugd->rotation = BT_ROTATE_LANDSCAPE_UPSIDEDOWN;
446                 break;
447         default:
448                 break;
449         }
450
451         if (event == UG_EVENT_ROTATE_PORTRAIT ||
452              event == UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN ||
453               event == UG_EVENT_ROTATE_LANDSCAPE ||
454                event == UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN) {
455                 _bt_rotate_selectioninfo(ugd->selectioninfo, ugd->rotation);
456                 _bt_main_change_rotate_mode((void *)ugd);
457         }
458
459         FN_END;
460 }
461
462 static void __on_key_event(ui_gadget_h ug, enum ug_key_event event,
463                            service_h service, void *priv)
464 {
465         FN_START;
466
467         bt_ug_data *ugd = NULL;
468
469         BT_DBG("event: %d\n", event);
470
471         ugd = (bt_ug_data *)priv;
472
473         switch (event) {
474         case UG_KEY_EVENT_END:
475                 _bt_ug_destroy(ugd, NULL);
476                 break;
477         default:
478                 break;
479         }
480         FN_END;
481 }
482
483 /**********************************************************************
484 *                                             Common Functions
485 ***********************************************************************/
486
487 UG_MODULE_API int UG_MODULE_INIT(struct ug_module_ops *ops)
488 {
489         FN_START;
490
491         bt_ug_data *ugd = NULL;
492
493         if (!ops)
494                 return BT_UG_FAIL;
495
496         ugd = calloc(1, sizeof(bt_ug_data));
497         if (!ugd)
498                 return BT_UG_FAIL;
499
500         ops->create = __on_create;
501         ops->start = __on_start;
502         ops->pause = __on_pause;
503         ops->resume = __on_resume;
504         ops->destroy = __on_destroy;
505         ops->message = __on_message;
506         ops->event = __on_event;
507         ops->key_event = __on_key_event;
508         ops->priv = ugd;
509         ops->opt = UG_OPT_INDICATOR_ENABLE;
510
511         FN_END;
512         return BT_UG_ERROR_NONE;
513 }
514
515 UG_MODULE_API void UG_MODULE_EXIT(struct ug_module_ops *ops)
516 {
517         FN_START;
518
519         bt_ug_data *ugd;
520
521         if (!ops)
522                 return;
523
524         ugd = ops->priv;
525         if (ugd)
526                 free(ugd);
527
528         FN_END;
529 }
530
531 UG_MODULE_API int setting_plugin_reset(service_h service, void *priv)
532 {
533         FN_START;
534
535         _bt_reset_environment();
536
537         FN_END;
538         return 0;
539 }
540
541 void _bt_ug_destroy(void *data, void *result)
542 {
543         FN_START;
544         int ret = 0;
545         bt_ug_data *ugd = NULL;
546
547         ret_if(data == NULL);
548
549         ugd = (bt_ug_data *)data;
550
551         if (result != NULL) {
552                 ug_send_result(ugd->ug, result);
553         }
554
555         if (ugd->ug)
556                 ret = ug_destroy_me(ugd->ug);
557
558         if (ret < 0)
559                 BT_DBG("Fail to destroy me");
560
561         FN_END;
562 }