appcore_ui_base: change version of tizen_policy from 1 to 7.
[platform/core/appfw/app-core.git] / src / ui_base / appcore_ui_base.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * 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 #define _GNU_SOURCE
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <linux/limits.h>
28
29 #include <Ecore_Wayland.h>
30 #include <wayland-client.h>
31 #include <wayland-tbm-client.h>
32 #include <tizen-extension-client-protocol.h>
33
34 #include <Ecore.h>
35 #include <glib-object.h>
36 #include <malloc.h>
37 #include <glib.h>
38 #include <gio/gio.h>
39 #include <stdbool.h>
40 #include <aul.h>
41 #include <aul_svc.h>
42 #include <bundle_internal.h>
43 #include <ttrace.h>
44
45 #include "appcore_base.h"
46 #include "appcore_ui_base.h"
47 #include "appcore_ui_base_private.h"
48 #include "appcore_ui_plugin.h"
49
50 enum app_state {
51         AS_NONE,
52         AS_CREATED,
53         AS_RUNNING,
54         AS_PAUSED,
55         AS_DYING,
56 };
57
58 typedef struct _appcore_ui_base_context {
59         appcore_ui_base_ops ops;
60         void *data;
61         int argc;
62         char **argv;
63         unsigned int hint;
64         char *below_app;
65         char *appid;
66         bool bg_state;
67
68         int state;
69         Ecore_Event_Handler *hshow;
70         Ecore_Event_Handler *hhide;
71         Ecore_Event_Handler *hvchange;
72         Ecore_Event_Handler *hlower;
73         Ecore_Event_Handler *hpvchange;
74 } appcore_ui_base_context;
75
76
77 static bool b_active = false;
78 static bool first_launch = true;
79
80 struct win_node {
81         unsigned int win;
82         unsigned int surf;
83         bool bfobscured;
84 };
85
86 static GSList *g_winnode_list;
87 static appcore_ui_base_context __context;
88 static struct wl_display *dsp;
89 static struct wl_registry *reg;
90 static struct tizen_policy *tz_policy;
91
92 static void _wl_cb_conformant(void *data,
93                 struct tizen_policy *tizen_policy,
94                 struct wl_surface *surface_resource,
95                 uint32_t is_conformant)
96 {
97         ; // nothing to do.
98 }
99
100 static void _wl_cb_conformant_area(void *data,
101                 struct tizen_policy *tizen_policy,
102                 struct wl_surface *surface_resource,
103                 uint32_t conformant_part,
104                 uint32_t state,
105                 int32_t x, int32_t y, int32_t w, int32_t h)
106 {
107         ; // nothing to do.
108 }
109
110 static void _wl_cb_notification_done(void *data,
111                 struct tizen_policy *tizen_policy,
112                 struct wl_surface *surface,
113                 int32_t level,
114                 uint32_t state)
115 {
116         ; // nothing to do.
117 }
118
119 static void _wl_cb_transient_for_done(void *data,
120                 struct tizen_policy *tizen_policy,
121                 uint32_t child_id)
122 {
123         ; // nothing to do.
124 }
125
126 static void _wl_cb_scr_mode_done(void *data,
127                 struct tizen_policy *tizen_policy,
128                 struct wl_surface *surface,
129                 uint32_t mode,
130                 uint32_t state)
131 {
132         ; // nothing to do.
133 }
134
135 static void _wl_cb_iconify_state_changed(void *data,
136                 struct tizen_policy *tizen_policy,
137                 struct wl_surface *surface_resource,
138                 uint32_t iconified,
139                 uint32_t force)
140 {
141         ; // nothing to do.
142 }
143
144 static void _wl_cb_supported_aux_hints(void *data,
145                 struct tizen_policy *tizen_policy,
146                 struct wl_surface *surface_resource,
147                 struct wl_array *hints,
148                 uint32_t num_hints)
149 {
150         ; // nothing to do.
151 }
152
153 static void _wl_cb_allowed_aux_hint(void *data,
154                 struct tizen_policy *tizen_policy,
155                 struct wl_surface *surface_resource,
156                 int id)
157 {
158         ; // nothing to do.
159 }
160
161 static void _wl_cb_aux_message(void *data,
162                 struct tizen_policy *tizen_policy,
163                 struct wl_surface *surface_resource,
164                 const char *key,
165                 const char *val,
166                 struct wl_array *options)
167 {
168         ; // nothing to do.
169 }
170
171 static void _wl_cb_conformant_region(void *data,
172                 struct tizen_policy *tizen_policy,
173                 struct wl_surface *surface,
174                 uint32_t conformant_part,
175                 uint32_t state,
176                 int32_t x, int32_t y, int32_t w, int32_t h,
177                 uint32_t serial)
178 {
179         ; // nothing to do.
180 }
181
182 static const struct tizen_policy_listener _tizen_policy_listener = {
183         _wl_cb_conformant,
184         _wl_cb_conformant_area,
185         _wl_cb_notification_done,
186         _wl_cb_transient_for_done,
187         _wl_cb_scr_mode_done,
188         _wl_cb_iconify_state_changed,
189         _wl_cb_supported_aux_hints,
190         _wl_cb_allowed_aux_hint,
191         _wl_cb_aux_message,
192         _wl_cb_conformant_region,
193 };
194
195 static void __wl_listener_cb(void *data, struct wl_registry *reg,
196                 uint32_t id, const char *interface, uint32_t ver)
197 {
198         if (interface && !strcmp(interface, "tizen_policy")) {
199                 if (!tz_policy)
200                         tz_policy = wl_registry_bind(reg, id,
201                                         &tizen_policy_interface, 7);
202                 if (tz_policy) {
203                         tizen_policy_add_listener(tz_policy, &_tizen_policy_listener, dsp);
204                 }
205         }
206 }
207
208 static void __wl_listener_remove_cb(void *data, struct wl_registry *reg,
209                 unsigned int id)
210 {
211         /* do nothing */
212 }
213
214 static const struct wl_registry_listener reg_listener = {
215         __wl_listener_cb,
216         __wl_listener_remove_cb
217 };
218
219 static Eina_Bool __stub_show_cb(void *data, int type, void *event)
220 {
221         if (__context.ops.window.show)
222                 __context.ops.window.show(type, event, __context.data);
223
224         return ECORE_CALLBACK_RENEW;
225 }
226
227 static Eina_Bool __stub_hide_cb(void *data, int type, void *event)
228 {
229         if (__context.ops.window.hide)
230                 __context.ops.window.hide(type, event, __context.data);
231
232         return ECORE_CALLBACK_RENEW;
233 }
234
235 static Eina_Bool __stub_visibility_cb(void *data, int type, void *event)
236 {
237         if (__context.ops.window.visibility)
238                 __context.ops.window.visibility(type, event, __context.data);
239
240         return ECORE_CALLBACK_RENEW;
241 }
242
243 static Eina_Bool __stub_lower_cb(void *data, int type, void *event)
244 {
245         if (__context.ops.window.lower)
246                 __context.ops.window.lower(type, event, __context.data);
247
248         return ECORE_CALLBACK_RENEW;
249 }
250
251 static Eina_Bool __stub_pre_visibility_cb(void *data, int type, void *event)
252 {
253         if (__context.ops.window.pre_visibility)
254                 __context.ops.window.pre_visibility(type, event, __context.data);
255
256         return ECORE_CALLBACK_RENEW;
257 }
258
259 static void __prepare_to_suspend(void)
260 {
261         int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
262
263         if (appcore_base_is_bg_allowed() && !appcore_base_is_suspended()) {
264                 appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
265                 appcore_base_toggle_suspended_state();
266         }
267 }
268
269 static void __exit_from_suspend(void)
270 {
271         int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
272
273         if (appcore_base_is_suspended()) {
274                 appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
275                 appcore_base_toggle_suspended_state();
276         }
277 }
278
279 static void __do_pause(void)
280 {
281         if (__context.state == AS_RUNNING) {
282                 if (__context.ops.pause) {
283                         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:PAUSE");
284                         __context.ops.pause(__context.data);
285                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
286                 }
287
288                 __context.state = AS_PAUSED;
289                 __prepare_to_suspend();
290         }
291         aul_status_update(STATUS_BG);
292 }
293
294 static void __do_resume(void)
295 {
296         if (__context.state == AS_PAUSED || __context.state == AS_CREATED) {
297                 __exit_from_suspend();
298                 if (__context.ops.resume) {
299                         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", __context.appid);
300                         traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESUME");
301                         __context.ops.resume(__context.data);
302                         traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
303                         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", __context.appid);
304                 }
305                 if ((__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) &&
306                                 __context.below_app) {
307                         aul_app_group_activate_below(__context.below_app);
308                         free(__context.below_app);
309                         __context.below_app = NULL;
310                 }
311                 __context.state = AS_RUNNING;
312         }
313
314         aul_status_update(STATUS_VISIBLE);
315 }
316
317 static GSList *__find_win(unsigned int win)
318 {
319         GSList *iter;
320         struct win_node *t;
321
322         for (iter = g_winnode_list; iter; iter = g_slist_next(iter)) {
323                 t = iter->data;
324                 if (t && t->win == win)
325                         return iter;
326         }
327
328         return NULL;
329 }
330
331 static int __get_main_window(void)
332 {
333         struct win_node *entry = NULL;
334
335         if (g_winnode_list != NULL) {
336                 entry = g_winnode_list->data;
337                 return (unsigned int) entry->win;
338         }
339
340         return 0;
341 }
342
343 static int __get_main_surface(void)
344 {
345         struct win_node *entry = NULL;
346
347         if (g_winnode_list != NULL) {
348                 entry = g_winnode_list->data;
349                 return (unsigned int) entry->surf;
350         }
351
352         return 0;
353 }
354
355 static bool __add_win(unsigned int win, unsigned int surf)
356 {
357         struct win_node *t;
358         GSList *f;
359
360         _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win);
361
362         f = __find_win(win);
363         if (f) {
364                 errno = ENOENT;
365                 _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win);
366                 return FALSE;
367         }
368
369         t = calloc(1, sizeof(struct win_node));
370         if (t == NULL)
371                 return FALSE;
372
373         t->win = win;
374         t->surf = surf;
375         t->bfobscured = FALSE;
376
377         g_winnode_list = g_slist_append(g_winnode_list, t);
378
379         return TRUE;
380 }
381
382 static bool __delete_win(unsigned int win)
383 {
384         GSList *f;
385
386         f = __find_win(win);
387         if (!f) {
388                 errno = ENOENT;
389                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n",
390                                 win);
391                 return FALSE;
392         }
393
394         free(f->data);
395         g_winnode_list = g_slist_delete_link(g_winnode_list, f);
396
397         return TRUE;
398 }
399
400 static bool __update_win(unsigned int win, unsigned int surf, bool bfobscured)
401 {
402         GSList *f;
403         struct win_node *t;
404
405         _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win,
406              bfobscured);
407
408         f = __find_win(win);
409         if (!f) {
410                 errno = ENOENT;
411                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win);
412                 return FALSE;
413         }
414
415         t = (struct win_node *)f->data;
416         t->win = win;
417         if (surf != 0)
418                 t->surf = surf;
419         t->bfobscured = bfobscured;
420
421         return TRUE;
422 }
423
424 static void __raise_win(void)
425 {
426         Ecore_Wl_Window *win;
427         unsigned int win_id;
428
429         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
430                 return;
431
432         win_id = __get_main_window();
433
434         _DBG("Raise window: %d", win_id);
435         win = ecore_wl_window_find(win_id);
436         ecore_wl_window_activate(win);
437 }
438
439 static void __pause_win(void)
440 {
441         Ecore_Wl_Window *win;
442         GSList *wlist = g_winnode_list;
443         struct win_node *entry = NULL;
444
445         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
446                 return;
447
448         _DBG("Pause window");
449
450         while (wlist) {
451                 entry = wlist->data;
452
453                 _DBG("Pause window: %d", entry->win);
454                 win = ecore_wl_window_find(entry->win);
455                 ecore_wl_window_iconified_set(win, EINA_TRUE);
456
457                 wlist = wlist->next;
458         }
459 }
460
461 static int __init_wl(void)
462 {
463         _DBG("initialize wayland");
464         dsp = wl_display_connect(NULL);
465         if (dsp == NULL) {
466                 _ERR("Failed to connect wl display");
467                 return -1;
468         }
469
470         reg = wl_display_get_registry(dsp);
471         if (reg == NULL) {
472                 _ERR("Failed to get registry");
473                 wl_display_disconnect(dsp);
474                 return -1;
475         }
476
477         wl_registry_add_listener(reg, &reg_listener, NULL);
478         wl_display_roundtrip(dsp);
479
480         if (!tz_policy) {
481                 _ERR("Failed to get tizen policy interface");
482                 wl_registry_destroy(reg);
483                 wl_display_disconnect(dsp);
484                 return -1;
485         }
486
487         return 0;
488 }
489
490 static void __finish_wl(void)
491 {
492         if (tz_policy) {
493                 tizen_policy_destroy(tz_policy);
494                 tz_policy = NULL;
495         }
496
497         if (reg) {
498                 wl_registry_destroy(reg);
499                 reg = NULL;
500         }
501
502         if (dsp) {
503                 wl_display_disconnect(dsp);
504                 dsp = NULL;
505         }
506 }
507
508 static void __set_bg_state(void)
509 {
510         if (!tz_policy && __init_wl() < 0)
511                 return;
512
513         tizen_policy_set_background_state(tz_policy, getpid());
514         wl_display_roundtrip(dsp);
515         __context.bg_state = true;
516         _DBG("bg state: %d", __context.bg_state);
517 }
518
519 static void __unset_bg_state(void)
520 {
521         if (!tz_policy)
522                 return;
523
524         tizen_policy_unset_background_state(tz_policy, getpid());
525         wl_display_roundtrip(dsp);
526         __context.bg_state = false;
527         _DBG("bg state: %d", __context.bg_state);
528 }
529
530 static void __do_start(bundle *b)
531 {
532         const char *bg_launch;
533         const char *below_app;
534
535         if (__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) {
536                 if (__context.below_app) {
537                         free(__context.below_app);
538                         __context.below_app = NULL;
539                 }
540
541                 below_app = bundle_get_val(b, AUL_SVC_K_RELOCATE_BELOW);
542                 if (below_app)
543                         __context.below_app = strdup(below_app);
544         }
545
546         if (first_launch) {
547                 first_launch = FALSE;
548                 return;
549         }
550
551         if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
552                 bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
553                 if (bg_launch && strcmp(bg_launch, "enable") == 0) {
554                         if (!__context.bg_state &&
555                                         __context.state != AS_RUNNING)
556                                 __set_bg_state();
557                 } else {
558                         if (__context.bg_state)
559                                 __unset_bg_state();
560                 }
561         }
562
563         if (__context.hint & APPCORE_UI_BASE_HINT_WINDOW_AUTO_CONTROL) {
564                 if (!__context.bg_state)
565                         __raise_win();
566         }
567 }
568
569 static int __is_legacy_lifecycle(void)
570 {
571         static int is_legacy = -1;
572         const char *api_version;
573
574         if (is_legacy != -1)
575                 return is_legacy;
576
577         api_version = getenv("TIZEN_API_VERSION");
578         if (api_version) {
579                 if (strverscmp("2.4", api_version) > 0 &&
580                                 strverscmp("2.2.1", api_version) < 0)
581                         is_legacy = 1;
582                 else
583                         is_legacy = 0;
584         } else {
585                 is_legacy = 0;
586         }
587
588         return is_legacy;
589 }
590
591 EXPORT_API int appcore_ui_base_on_receive(aul_type type, bundle *b)
592 {
593         if (__context.state == AS_DYING) {
594                 _ERR("Skip the event in dying state");
595                 return 0;
596         }
597
598         if (type == AUL_TERMINATE_BGAPP && __context.state != AS_PAUSED)
599                 return 0;
600
601         if (type == AUL_START)
602                 __exit_from_suspend();
603
604         appcore_base_on_receive(type, b);
605
606         switch (type) {
607         case AUL_START:
608                 __do_start(b);
609                 if (__context.hint & APPCORE_UI_BASE_HINT_LEGACY_CONTROL) {
610                         if (!__context.bg_state && __is_legacy_lifecycle()) {
611                                 _DBG("Legacy lifecycle");
612                                 __do_resume();
613                         }
614                 }
615                 break;
616         case AUL_RESUME:
617                 if (__context.bg_state)
618                         __unset_bg_state();
619                 __raise_win();
620                 break;
621         case AUL_TERMINATE:
622                 break;
623         case AUL_TERMINATE_BGAPP:
624                 _DBG("[APP %d] is paused. TERMINATE", getpid());
625                 __context.state = AS_DYING;
626                 aul_status_update(STATUS_DYING);
627                 if (__context.ops.base.exit)
628                         __context.ops.base.exit(__context.data);
629                 break;
630         case AUL_PAUSE:
631                 __pause_win();
632                 break;
633         default:
634                 break;
635         }
636
637         return 0;
638 }
639
640 static void __add_ecore_events(void)
641 {
642         __context.hshow = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW,
643                         __stub_show_cb, NULL);
644         if (!__context.hshow)
645                 _ERR("Failed to add ECORE_WL_EVENT_WINDOW_SHOW event");
646
647         __context.hhide = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE,
648                         __stub_hide_cb, NULL);
649         if (!__context.hhide)
650                 _ERR("Failed to add ECORE_WL_EVENT_WINDOW_HIDE event");
651
652         __context.hvchange = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
653                         __stub_visibility_cb, NULL);
654         if (!__context.hvchange)
655                 _ERR("Failed to add ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE event");
656
657         __context.hlower = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER,
658                         __stub_lower_cb, NULL);
659         if (!__context.hlower)
660                 _ERR("Failed to add ECORE_WL_EVENT_WINDOW_LOWER event");
661
662         __context.hpvchange = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_PRE_VISIBILITY_CHANGE,
663                         __stub_pre_visibility_cb, NULL);
664         if (!__context.hpvchange)
665                 _ERR("Failed to add ECORE_WL_EVENT_WINDOW_PRE_VISIBILITY_CHANGE event");
666 }
667
668 static void __del_ecore_events(void)
669 {
670         if (__context.hshow) {
671                 ecore_event_handler_del(__context.hshow);
672                 __context.hshow = NULL;
673         }
674
675         if (__context.hhide) {
676                 ecore_event_handler_del(__context.hhide);
677                 __context.hhide = NULL;
678         }
679
680         if (__context.hvchange) {
681                 ecore_event_handler_del(__context.hvchange);
682                 __context.hvchange = NULL;
683         }
684
685         if (__context.hlower) {
686                 ecore_event_handler_del(__context.hlower);
687                 __context.hlower = NULL;
688         }
689
690         if (__context.hpvchange) {
691                 ecore_event_handler_del(__context.hpvchange);
692                 __context.hpvchange = NULL;
693         }
694 }
695
696 EXPORT_API int appcore_ui_base_on_create(void)
697 {
698         __add_ecore_events();
699         appcore_base_on_create();
700         __context.state = AS_CREATED;
701         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]", __context.appid);
702
703         return 0;
704 }
705
706 EXPORT_API int appcore_ui_base_on_terminate(void)
707 {
708         if (__context.state == AS_RUNNING) {
709                 if (__context.ops.pause)
710                         __context.ops.pause(__context.data);
711         }
712
713         __context.state = AS_DYING;
714
715         appcore_base_on_terminate();
716
717         return 0;
718 }
719
720 EXPORT_API int appcore_ui_base_on_pause(void)
721 {
722         return 0;
723 }
724
725 EXPORT_API int appcore_ui_base_on_resume(void)
726 {
727         return 0;
728 }
729
730 EXPORT_API int appcore_ui_base_on_control(bundle *b)
731 {
732         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", __context.appid);
733         appcore_base_on_control(b);
734         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", __context.appid);
735
736         return 0;
737 }
738
739 static void __group_attach()
740 {
741         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
742                 return;
743
744         appcore_ui_base_group_add();
745 }
746
747 static void __group_lower()
748 {
749         if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
750                 return;
751         appcore_ui_base_group_remove();
752 }
753
754 EXPORT_API void appcore_ui_base_group_add()
755 {
756         static bool attached = false;
757
758         _DBG("__group_attach");
759         if (attached)
760                 return;
761
762         int wid = __get_main_surface();
763         if (wid == 0) {
764                 _ERR("window wasn't ready");
765                 return;
766         }
767
768         aul_app_group_set_window(wid);
769         attached = true;
770 }
771
772 EXPORT_API void appcore_ui_base_group_remove()
773 {
774         int exit = 0;
775
776         _DBG("__group_lower");
777         aul_app_group_lower(&exit);
778         if (exit) {
779                 _DBG("__group_lower : sub-app!");
780                 if (__context.ops.base.exit)
781                         __context.ops.base.exit(__context.data);
782         }
783 }
784
785 EXPORT_API void appcore_ui_base_window_on_show(int type, void *event)
786 {
787         Ecore_Wl_Event_Window_Show *ev;
788
789         ev = event;
790         if (ev->parent_win != 0) {
791                 /* This is child window. Skip!!! */
792                 return;
793         }
794
795         _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x, %d\n", ev->win, ev->data[0]);
796
797         if (!__find_win((unsigned int)ev->win))
798                 __add_win((unsigned int)ev->win, (unsigned int)ev->data[0]);
799         else
800                 __update_win((unsigned int)ev->win, (unsigned int)ev->data[0], FALSE);
801
802         if (ev->data[0] != 0)
803                 __group_attach();
804 }
805
806 static bool __check_visible(void)
807 {
808         GSList *iter = NULL;
809         struct win_node *entry = NULL;
810
811         _DBG("[EVENT_TEST][EVENT] __check_visible\n");
812
813         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
814                 entry = iter->data;
815                 _DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured);
816                 if (entry->bfobscured == FALSE)
817                         return true;
818         }
819
820         return false;
821 }
822
823 EXPORT_API void appcore_ui_base_window_on_hide(int type, void *event)
824 {
825         Ecore_Wl_Event_Window_Hide *ev;
826         int bvisibility;
827
828         ev = event;
829         _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win);
830
831         if (__find_win((unsigned int)ev->win)) {
832                 __delete_win((unsigned int)ev->win);
833                 bvisibility = __check_visible();
834                 if (!bvisibility && b_active == TRUE) {
835                         _DBG(" Go to Pasue state \n");
836                         b_active = FALSE;
837                         __do_pause();
838                 }
839         }
840 }
841
842 EXPORT_API void appcore_ui_base_window_on_lower(int type, void *event)
843 {
844         Ecore_Wl_Event_Window_Lower *ev;
845
846         ev = event;
847         if (!ev)
848                 return;
849         _DBG("ECORE_WL_EVENT_WINDOW_LOWER window id:%u\n", ev->win);
850         __group_lower();
851 }
852
853 EXPORT_API void appcore_ui_base_window_on_visibility(int type, void *event)
854 {
855         Ecore_Wl_Event_Window_Visibility_Change *ev;
856         int bvisibility;
857
858         ev = event;
859         __update_win((unsigned int)ev->win, 0, ev->fully_obscured);
860         bvisibility = __check_visible();
861
862         _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
863
864         if (bvisibility && b_active == FALSE) {
865                 _DBG(" Go to Resume state\n");
866                 b_active = TRUE;
867                 __do_resume();
868         } else if (!bvisibility && b_active == TRUE) {
869                 _DBG(" Go to Pasue state \n");
870                 b_active = FALSE;
871                 __do_pause();
872         } else {
873                 _DBG(" No change state \n");
874         }
875
876 }
877
878 EXPORT_API void appcore_ui_base_window_on_pre_visibility(int type, void *event)
879 {
880         Ecore_Wl_Event_Window_Pre_Visibility_Change *ev = event;
881         bool bvisibility;
882
883         if (ev && ev->type == ECORE_WL_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) {
884                 __update_win((unsigned int)ev->win, 0, false);
885                 bvisibility = __check_visible();
886
887                 _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
888                 if (bvisibility && b_active == FALSE) {
889                         _DBG(" Go to Resume state\n");
890                         b_active = TRUE;
891                         __do_resume();
892                 }
893         }
894 }
895
896 EXPORT_API int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
897                 void *data, unsigned int hint)
898 {
899         const char *bg_launch;
900         bundle *b;
901         char appid[PATH_MAX] = {0, };
902
903         ecore_wl_init(NULL);
904
905         appcore_ui_plugin_init(&ops, argc, argv, &hint);
906         aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
907         __context.ops = ops;
908         __context.data = data;
909         __context.argc = argc;
910         __context.argv = argv;
911         __context.hint = hint;
912         __context.state = AS_NONE;
913         __context.appid = strdup(appid);
914
915         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
916         if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
917                 b = bundle_import_from_argv(argc, argv);
918                 if (b) {
919                         bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
920                         if (bg_launch && strcmp(bg_launch, "enable") == 0)
921                                 __set_bg_state();
922
923                         bundle_free(b);
924                 }
925         }
926
927         return appcore_base_init(ops.base, argc, argv, data);
928 }
929
930 EXPORT_API void appcore_ui_base_fini(void)
931 {
932         __del_ecore_events();
933         __finish_wl();
934
935         free(__context.appid);
936         __context.appid = NULL;
937
938         appcore_base_fini();
939         appcore_ui_plugin_fini();
940         ecore_wl_shutdown();
941 }
942
943 EXPORT_API void appcore_ui_base_pause(void)
944 {
945         __do_pause();
946 }
947
948 EXPORT_API void appcore_ui_base_resume(void)
949 {
950         __do_resume();
951 }
952
953 EXPORT_API bool appcore_ui_base_is_resumed(void)
954 {
955         return __context.state == AS_RUNNING;
956 }
957
958 EXPORT_API void appcore_ui_base_exit(void)
959 {
960         if (__context.ops.base.exit)
961                 __context.ops.base.exit(__context.data);
962 }
963
964 EXPORT_API unsigned int appcore_ui_base_get_main_window(void)
965 {
966         return __get_main_window();
967 }
968
969 EXPORT_API unsigned int appcore_ui_base_get_main_surface(void)
970 {
971         return __get_main_surface();
972 }
973
974 EXPORT_API int appcore_ui_base_get_hint(void)
975 {
976         return __context.hint;
977 }
978
979 EXPORT_API bool appcore_ui_base_get_bg_state(void)
980 {
981         return __context.bg_state;
982 }
983
984 EXPORT_API void appcore_ui_base_set_bg_state(bool bg_state)
985 {
986         __context.bg_state = bg_state;
987 }
988
989 static int __on_receive(aul_type type, bundle *b, void *data)
990 {
991         return appcore_ui_base_on_receive(type, b);
992 }
993
994 static int __on_create(void *data)
995 {
996         return appcore_ui_base_on_create();
997 }
998
999 static int __on_terminate(void *data)
1000 {
1001         return appcore_ui_base_on_terminate();
1002 }
1003
1004 static int __on_pause(void *data)
1005 {
1006         return appcore_ui_base_on_pause();
1007 }
1008
1009 static int __on_resume(void *data)
1010 {
1011         return appcore_ui_base_on_resume();
1012 }
1013
1014 static void __window_on_show(int type, void *event, void *data)
1015 {
1016         appcore_ui_base_window_on_show(type, event);
1017 }
1018
1019 static void __window_on_hide(int type, void *event, void *data)
1020 {
1021         appcore_ui_base_window_on_hide(type, event);
1022 }
1023
1024 static void __window_on_lower(int type, void *event, void *data)
1025 {
1026         appcore_ui_base_window_on_lower(type, event);
1027 }
1028
1029 static void __window_on_visibility(int type, void *event, void *data)
1030 {
1031         appcore_ui_base_window_on_visibility(type, event);
1032 }
1033
1034 static void __window_on_pre_visibility(int type, void *event, void *data)
1035 {
1036         appcore_ui_base_window_on_pre_visibility(type, event);
1037 }
1038
1039 EXPORT_API appcore_ui_base_ops appcore_ui_base_get_default_ops(void)
1040 {
1041         appcore_ui_base_ops ops;
1042
1043         ops.base = appcore_base_get_default_ops();
1044
1045         /* override methods */
1046         ops.base.create = __on_create;
1047         ops.base.terminate = __on_terminate;
1048         ops.base.receive = __on_receive;
1049         ops.base.init = NULL;
1050         ops.base.finish = NULL;
1051         ops.base.run = NULL;
1052         ops.base.exit = NULL;
1053
1054         ops.pause = __on_pause;
1055         ops.resume = __on_resume;
1056         ops.window.show = __window_on_show;
1057         ops.window.hide = __window_on_hide;
1058         ops.window.lower = __window_on_lower;
1059         ops.window.visibility = __window_on_visibility;
1060         ops.window.pre_visibility = __window_on_pre_visibility;
1061
1062         return ops;
1063 }
1064
1065