Modified flushing memory logic
[platform/core/appfw/app-core.git] / src / multiwindow_base / appcore_multiwindow_base.c
1 /*
2  * Copyright (c) 2017 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 #include <sys/types.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <linux/limits.h>
24
25 #include <Ecore_Wl2.h>
26 #include <glib-object.h>
27 #include <malloc.h>
28 #include <glib.h>
29 #include <gio/gio.h>
30 #include <stdbool.h>
31 #include <aul.h>
32 #include <aul_svc.h>
33 #include <bundle_internal.h>
34
35 #include "appcore_base.h"
36 #include "appcore_multiwindow_base.h"
37 #include "appcore_multiwindow_base_private.h"
38
39 appcore_multiwindow_base_context _appcore_mw_context;
40 static guint __flush_timer = 0;
41
42 static gboolean __flush_memory(gpointer data)
43 {
44         _DBG("Flush memory");
45         if (_appcore_mw_context.ops.base.trim_memory)
46                 _appcore_mw_context.ops.base.trim_memory(_appcore_mw_context.data);
47         __flush_timer = 0;
48         return G_SOURCE_REMOVE;
49 }
50
51 static void __add_flush_timer(void)
52 {
53         if (__flush_timer)
54                 return;
55
56         __flush_timer = g_timeout_add(5000, __flush_memory, NULL);
57 }
58
59 static void __remove_flush_timer(void)
60 {
61         if (!__flush_timer)
62                 return;
63
64         g_source_remove(__flush_timer);
65         __flush_timer = 0;
66 }
67
68 static Eina_Bool __stub_show_cb(void *data, int type, void *event)
69 {
70         if (_appcore_mw_context.ops.window.show)
71                 _appcore_mw_context.ops.window.show(type, event, _appcore_mw_context.data);
72
73         return ECORE_CALLBACK_RENEW;
74 }
75
76 static Eina_Bool __stub_hide_cb(void *data, int type, void *event)
77 {
78         if (_appcore_mw_context.ops.window.hide)
79                 _appcore_mw_context.ops.window.hide(type, event, _appcore_mw_context.data);
80
81         return ECORE_CALLBACK_RENEW;
82 }
83
84 static Eina_Bool __stub_visibility_cb(void *data, int type, void *event)
85 {
86         Ecore_Wl2_Event_Window_Visibility_Change *ev = event;
87
88         if (_appcore_mw_context.ops.window.visibility)
89                 _appcore_mw_context.ops.window.visibility(type, event, _appcore_mw_context.data);
90
91         if (ev && ev->fully_obscured) {
92                 if (!appcore_multiwindow_base_window_is_resumed())
93                         __add_flush_timer();
94         } else {
95                 __remove_flush_timer();
96         }
97
98         return ECORE_CALLBACK_RENEW;
99 }
100
101 static Eina_Bool __stub_lower_cb(void *data, int type, void *event)
102 {
103         if (_appcore_mw_context.ops.window.lower)
104                 _appcore_mw_context.ops.window.lower(type, event, _appcore_mw_context.data);
105
106         return ECORE_CALLBACK_RENEW;
107 }
108
109 static Eina_Bool __stub_pre_visibility_cb(void *data, int type, void *event)
110 {
111         Ecore_Wl2_Event_Window_Pre_Visibility_Change *ev = event;
112
113         if (_appcore_mw_context.ops.window.pre_visibility)
114                 _appcore_mw_context.ops.window.pre_visibility(type, event, _appcore_mw_context.data);
115
116         if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED)
117                 __remove_flush_timer();
118
119         return ECORE_CALLBACK_RENEW;
120 }
121
122 EXPORT_API int appcore_multiwindow_base_init(appcore_multiwindow_base_ops ops, int argc, char **argv, void *data)
123 {
124         _appcore_mw_context.ops = ops;
125         _appcore_mw_context.data = data;
126         _appcore_mw_context.argc = argc;
127         _appcore_mw_context.argv = argv;
128
129         return appcore_base_init(ops.base, argc, argv, data);
130 }
131
132 static void __destroy_iter(gpointer data, gpointer user_data)
133 {
134         appcore_multiwindow_base_instance *inst = data;
135
136         if (!inst)
137                 return;
138
139         appcore_multiwindow_base_instance_exit(inst);
140 }
141
142 static void __destroy_all(void)
143 {
144         g_list_foreach(_appcore_mw_context.instances, __destroy_iter, NULL);
145 }
146
147 static void __free_class(gpointer data)
148 {
149         appcore_multiwindow_base_class *cls = data;
150
151         free(cls->id);
152         free(cls);
153 }
154
155 EXPORT_API void appcore_multiwindow_base_fini(void)
156 {
157         __destroy_all();
158         g_list_free_full(_appcore_mw_context.classes, __free_class);
159         _appcore_mw_context.classes = NULL;
160
161         if (_appcore_mw_context.hshow) {
162                 ecore_event_handler_del(_appcore_mw_context.hshow);
163                 _appcore_mw_context.hshow = NULL;
164         }
165
166         if (_appcore_mw_context.hhide) {
167                 ecore_event_handler_del(_appcore_mw_context.hhide);
168                 _appcore_mw_context.hhide = NULL;
169         }
170
171         if (_appcore_mw_context.hvchange) {
172                 ecore_event_handler_del(_appcore_mw_context.hvchange);
173                 _appcore_mw_context.hvchange = NULL;
174         }
175
176         if (_appcore_mw_context.hlower) {
177                 ecore_event_handler_del(_appcore_mw_context.hlower);
178                 _appcore_mw_context.hlower = NULL;
179         }
180
181         if (_appcore_mw_context.hpvchange) {
182                 ecore_event_handler_del(_appcore_mw_context.hpvchange);
183                 _appcore_mw_context.hpvchange = NULL;
184         }
185
186         appcore_base_fini();
187 }
188
189 EXPORT_API void appcore_multiwindow_base_exit(void)
190 {
191         if (_appcore_mw_context.ops.base.exit)
192                 _appcore_mw_context.ops.base.exit(_appcore_mw_context.data);
193 }
194
195 static int __on_receive(aul_type type, bundle *b, void *data)
196 {
197         return appcore_multiwindow_base_on_receive(type, b);
198 }
199
200 static int __on_create(void *data)
201 {
202         return appcore_multiwindow_base_on_create();
203 }
204
205 static int __on_terminate(void *data)
206 {
207         return appcore_multiwindow_base_on_terminate();
208 }
209
210 static void __on_trim_memory(void *data)
211 {
212         appcore_multiwindow_base_on_trim_memory();
213 }
214
215 static void __window_on_show(int type, void *event, void *data)
216 {
217         appcore_multiwindow_base_window_on_show(type, event);
218 }
219
220 static void __window_on_hide(int type, void *event, void *data)
221 {
222         appcore_multiwindow_base_window_on_hide(type, event);
223 }
224
225 static void __window_on_lower(int type, void *event, void *data)
226 {
227         appcore_multiwindow_base_window_on_lower(type, event);
228 }
229
230 static void __window_on_visibility(int type, void *event, void *data)
231 {
232         appcore_multiwindow_base_window_on_visibility(type, event);
233 }
234
235 static void __window_on_pre_visibility(int type, void *event, void *data)
236 {
237         appcore_multiwindow_base_window_on_pre_visibility(type, event);
238 }
239
240 EXPORT_API appcore_multiwindow_base_ops appcore_multiwindow_base_get_default_ops(void)
241 {
242         appcore_multiwindow_base_ops ops;
243
244         ops.base = appcore_base_get_default_ops();
245
246         /* override methods */
247         ops.base.create = __on_create;
248         ops.base.terminate = __on_terminate;
249         ops.base.receive = __on_receive;
250         ops.base.init = NULL;
251         ops.base.finish = NULL;
252         ops.base.run = NULL;
253         ops.base.exit = NULL;
254         ops.base.trim_memory = __on_trim_memory;
255
256         ops.window.show = __window_on_show;
257         ops.window.hide = __window_on_hide;
258         ops.window.lower = __window_on_lower;
259         ops.window.visibility = __window_on_visibility;
260         ops.window.pre_visibility = __window_on_pre_visibility;
261
262         return ops;
263 }
264
265 EXPORT_API int appcore_multiwindow_base_on_receive(aul_type type, bundle *b)
266 {
267         appcore_base_on_receive(type, b);
268
269         return 0;
270 }
271
272 EXPORT_API int appcore_multiwindow_base_on_create(void)
273 {
274         appcore_base_on_create();
275
276         _appcore_mw_context.hshow = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW, __stub_show_cb, NULL);
277         _appcore_mw_context.hhide = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_HIDE, __stub_hide_cb, NULL);
278         _appcore_mw_context.hvchange = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE,
279                         __stub_visibility_cb, NULL);
280         _appcore_mw_context.hlower = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_LOWER, __stub_lower_cb, NULL);
281         _appcore_mw_context.hpvchange = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE,
282                         __stub_pre_visibility_cb, NULL);
283
284         return 0;
285 }
286
287 EXPORT_API int appcore_multiwindow_base_on_terminate(void)
288 {
289         appcore_base_on_terminate();
290
291         return 0;
292 }
293
294 EXPORT_API int appcore_multiwindow_base_on_control(bundle *b)
295 {
296         appcore_base_on_control(b);
297
298         return 0;
299 }
300
301 EXPORT_API int appcore_multiwindow_base_on_trim_memory(void)
302 {
303         return appcore_base_on_trim_memory();
304 }