47b3fb1938bc1324ae867b1f7ff6bb472f77b865
[platform/core/system/system-popup.git] / src / common / core.c
1 /*
2  * system-popup
3  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "popup-common.h"
19
20 #define SYSPOPUP_CONTENT "_SYSPOPUP_CONTENT_"
21
22 static syspopup_handler handler;
23 static GList *popup_list = NULL;
24
25 extern int reset_window_priority(int priority);
26
27 GList *get_popup_list(void)
28 {
29         return popup_list;
30 }
31
32 void register_popup(const struct popup_ops *ops)
33 {
34         struct object_ops *obj;
35
36         if (!ops) {
37                 _E("Invalid parameter");
38                 return;
39         }
40
41         obj = (struct object_ops *)calloc(1, sizeof(struct object_ops));
42         if (!obj) {
43                 _E("calloc() fialed");
44                 return;
45         }
46
47         obj->ops = ops;
48
49         popup_list = g_list_append(popup_list, obj);
50 }
51
52 static void free_obj(gpointer data)
53 {
54         struct object_ops *obj = data;
55         FREE(obj);
56 }
57
58 void unregister_all_popup(void)
59 {
60         if (popup_list)
61                 g_list_free_full(popup_list, free_obj);
62 }
63
64 void terminate_if_no_popup(void)
65 {
66         GList *l;
67         struct object_ops *obj;
68
69         for (l = popup_list ; l ; l = g_list_next(l)) {
70                 obj = (struct object_ops *)(l->data);
71                 if (obj->popup) {
72                         _I("popup exists(%s)", obj->ops->name);
73                         return;
74                 }
75         }
76         window_terminate();
77 }
78
79 static int load_popup_by_type(bundle *b)
80 {
81         char *type;
82         GList *l;
83         struct object_ops *obj;
84         int ret;
85
86         if (!b)
87                 return -EINVAL;
88
89         type = (char *)bundle_get_val(b, SYSPOPUP_CONTENT);
90         if (!type) {
91                 _E("FAIL: bundle_get_val()");
92                 return -ENOMEM;
93         }
94
95         for (l = popup_list ; l ; l = g_list_next(l)) {
96                 obj = (struct object_ops *)(l->data);
97                 if (!obj || !(obj->ops) || !(obj->ops->name) || !(obj->ops->show))
98                         continue;
99                 if (strncmp(type, obj->ops->name, strlen(type) + 1))
100                         continue;
101
102                 if (obj->ops->skip && obj->ops->skip(b, obj->ops)) {
103                         terminate_if_no_popup();
104                         return 0;
105                 }
106
107                 if (obj->ops->change)
108                         obj->ops->change(b, obj->ops);
109
110                 if (obj->ops->pre)
111                         obj->ops->pre(b, obj->ops);
112
113                 ret = obj->ops->show(b, obj->ops);
114
115                 if (obj->ops->post)
116                         obj->ops->post(b, obj->ops);
117
118                 return ret;
119         }
120         return -EINVAL;
121 }
122
123 static int release_all_handlers(void *data)
124 {
125         GList *l;
126         struct object_ops *obj;
127         static bool already = false;
128
129         if (already)
130                 return 0;
131         already = true;
132
133         for (l = popup_list ; l ; l = g_list_next(l)) {
134                 obj = (struct object_ops *)(l->data);
135                 if (obj && obj->popup) {
136                         if (obj->ops->terminate)
137                                 obj->ops->terminate(obj->ops);
138                         release_evas_object(&(obj->popup));
139                 }
140         }
141
142         unset_dbus_connection();
143         remove_window();
144         unregister_all_popup();
145         return 0;
146 }
147
148 static int terminate_by_syspopup(bundle *b, void *data)
149 {
150         return release_all_handlers(data);
151 }
152
153 static int app_create(void *data)
154 {
155         int ret;
156
157         handler.def_term_fn = terminate_by_syspopup;
158         handler.def_timeout_fn = NULL;
159
160         /* create window */
161         ret = create_window(PACKAGE);
162         if (ret < 0)
163                 return ret;
164
165         if (appcore_set_i18n(LANG_DOMAIN, LOCALE_DIR) != 0)
166                 _E("FAIL: appcore_set_i18n()");
167
168         ret = set_dbus_connection();
169         if (ret < 0)
170                 _E("Failed to set dbus connection (%d)", ret);
171
172         return 0;
173 }
174
175 static int app_terminate(void *data)
176 {
177         return release_all_handlers(data);
178 }
179
180 static int app_pause(void *data)
181 {
182         GList *l;
183         struct object_ops *obj;
184
185         for (l = popup_list ; l ; l = g_list_next(l)) {
186                 obj = (struct object_ops *)(l->data);
187                 if (obj && obj->ops) {
188                         if (obj->ops->term_pause == NULL
189                                         || obj->ops->term_pause(obj->ops)) {
190                                 unload_simple_popup(obj->ops);
191                         }
192                 }
193         }
194         terminate_if_no_popup();
195         return 0;
196 }
197
198 static int app_resume(void *data)
199 {
200         return 0;
201 }
202
203 static int app_reset(bundle *b, void *data)
204 {
205         int ret;
206         Evas_Object *win;
207
208         if (!b) {
209                 ret = -EINVAL;
210                 goto out;
211         }
212
213         if (syspopup_has_popup(b)) {
214                 syspopup_reset(b);
215         } else {
216                 win = get_window();
217                 if (!win)
218                         return -ENOMEM;
219
220                 ret = syspopup_create(b, &handler, win, NULL);
221                 if (ret < 0) {
222                         _E("FAIL: syspopup_create(): %d", ret);
223                         goto out;
224                 }
225
226                 /* change window priority to normal */
227                 (void)reset_window_priority(WIN_PRIORITY_HIGH);
228         }
229
230         ret = load_popup_by_type(b);
231         if (ret < 0)
232                 goto out;
233
234         return 0;
235
236 out:
237         window_terminate();
238         return ret;
239 }
240
241 int main(int argc, char *argv[])
242 {
243         struct appcore_ops ops = {
244                 .create = app_create,
245                 .terminate = app_terminate,
246                 .pause = app_pause,
247                 .resume = app_resume,
248                 .reset = app_reset,
249         };
250
251         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
252 }