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