4d9c7b94d225aebf4848a2effe2be335856010cc
[platform/core/api/application.git] / src / app_main.c
1 /*
2  * Copyright (c) 2011 - 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 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24
25 #include <bundle.h>
26 #include <appcore_efl_base.h>
27 #include <dlog.h>
28
29 #include <app_internal.h>
30 #include <app_control_internal.h>
31 #include <app_common_internal.h>
32 #include <tizen_error.h>
33
34 #include "app_extension.h"
35
36 #ifdef LOG_TAG
37 #undef LOG_TAG
38 #endif
39
40 #define LOG_TAG "CAPI_APPFW_APPLICATION"
41
42 #define UI_APP_EVENT_MAX 7
43
44 typedef enum {
45         APP_STATE_NOT_RUNNING, /* The application has been launched or was running but was terminated */
46         APP_STATE_CREATING, /* The application is initializing the resources on app_create_cb callback */
47         APP_STATE_RUNNING, /* The application is running in the foreground and background */
48 } app_state_e;
49
50 struct app_event_handler {
51         app_event_type_e type;
52         app_event_cb cb;
53         void *data;
54         void *raw;
55 };
56
57 struct app_event_info {
58         app_event_type_e type;
59         void *value;
60 };
61
62 struct ui_app_context {
63         ui_app_lifecycle_callback_s callback;
64         void *data;
65 };
66
67 static struct ui_app_context __context;
68 static app_state_e __app_state = APP_STATE_NOT_RUNNING;
69
70 static int __app_event_converter[APPCORE_BASE_EVENT_MAX] = {
71         [APP_EVENT_LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
72         [APP_EVENT_LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
73         [APP_EVENT_LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
74         [APP_EVENT_DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
75         [APP_EVENT_REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE,
76         [APP_EVENT_SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
77 };
78
79 static int __ui_app_create(void *data)
80 {
81         appcore_efl_base_on_create();
82         if (__context.callback.create == NULL ||
83                         __context.callback.create(__context.data) == false)
84                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
85
86         return APP_ERROR_NONE;
87 }
88
89 static int __ui_app_terminate(void *data)
90 {
91         appcore_efl_base_on_terminate();
92
93         if (__context.callback.terminate)
94                 __context.callback.terminate(__context.data);
95
96         return APP_ERROR_NONE;
97 }
98
99 static int __ui_app_control(bundle *b, void *data)
100 {
101         app_control_h app_control = NULL;
102
103         appcore_efl_base_on_control(b);
104
105         if (b) {
106                 if (app_control_create_event(b, &app_control) != APP_ERROR_NONE)
107                         return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to create an app_control handle");
108         } else {
109                 if (app_control_create(&app_control) != APP_ERROR_NONE)
110                         return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Failed to create an app_control handle");
111         }
112
113         if (__context.callback.app_control)
114                 __context.callback.app_control(app_control, __context.data);
115
116         app_control_destroy(app_control);
117
118         return APP_ERROR_NONE;
119 }
120
121 static int __ui_app_pause(void *data)
122 {
123         appcore_efl_base_on_pause();
124         if (__context.callback.pause)
125                 __context.callback.pause(__context.data);
126         return APP_ERROR_NONE;
127 }
128
129 static int __ui_app_resume(void *data)
130 {
131         appcore_efl_base_on_resume();
132         if (__context.callback.resume)
133                 __context.callback.resume(__context.data);
134         return APP_ERROR_NONE;
135 }
136
137 static int __app_init(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data, appcore_efl_base_ops ops)
138 {
139         int ret;
140
141         if (argc < 1 || argv == NULL || callback == NULL)
142                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
143
144         if (callback->create == NULL)
145                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
146
147         if (__app_state != APP_STATE_NOT_RUNNING)
148                 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
149
150         __context.callback = *callback;
151         __context.data = user_data;
152         __app_state = APP_STATE_CREATING;
153
154         ret = appcore_efl_base_init(ops, argc, argv, NULL,
155                         APPCORE_EFL_BASE_HINT_WINDOW_GROUP_CONTROL |
156                         APPCORE_EFL_BASE_HINT_WINDOW_STACK_CONTROL |
157                         APPCORE_EFL_BASE_HINT_BG_LAUNCH_CONTROL |
158                         APPCORE_EFL_BASE_HINT_HW_ACC_CONTROL |
159                         APPCORE_EFL_BASE_HINT_WINDOW_AUTO_CONTROL |
160                         APPCORE_EFL_BASE_HINT_LEGACY_CONTROL);
161
162         if (ret < 0) {
163                 __app_state = APP_STATE_NOT_RUNNING;
164                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
165         }
166
167         return APP_ERROR_NONE;
168 }
169
170 static void __app_fini(void)
171 {
172         appcore_efl_base_fini();
173         __app_state = APP_STATE_NOT_RUNNING;
174
175 }
176
177 int ui_app_init(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data, appcore_context_h *handle)
178 {
179         appcore_efl_base_ops ops = appcore_efl_base_get_default_ops();
180
181         /* override methods */
182         ops.ui_base.base.create = __ui_app_create;
183         ops.ui_base.base.control = __ui_app_control;
184         ops.ui_base.base.terminate = __ui_app_terminate;
185         ops.ui_base.pause = __ui_app_pause;
186         ops.ui_base.resume = __ui_app_resume;
187         ops.ui_base.base.run = NULL;
188         ops.ui_base.base.exit = NULL;
189
190         return __app_init(argc, argv, callback, user_data, ops);
191 }
192
193 void ui_app_fini(appcore_context_h handle)
194 {
195         __app_fini();
196 }
197
198 int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
199 {
200         int ret;
201         appcore_efl_base_ops ops = appcore_efl_base_get_default_ops();
202
203         /* override methods */
204         ops.ui_base.base.create = __ui_app_create;
205         ops.ui_base.base.control = __ui_app_control;
206         ops.ui_base.base.terminate = __ui_app_terminate;
207         ops.ui_base.pause = __ui_app_pause;
208         ops.ui_base.resume = __ui_app_resume;
209
210         ret = __app_init(argc, argv, callback, user_data, ops);
211         if (ret != APP_ERROR_NONE)
212                 return ret;
213
214          __app_fini();
215
216          return APP_ERROR_NONE;
217 }
218
219 void ui_app_exit(void)
220 {
221         appcore_efl_base_exit();
222 }
223
224 int __event_cb(void *event, void *data)
225 {
226         app_event_handler_h handler = data;
227
228         struct app_event_info app_event;
229
230         app_event.type = handler->type;
231         app_event.value = event;
232
233         if (handler->cb)
234                 handler->cb(&app_event, handler->data);
235
236         return 0;
237 }
238
239 int ui_app_add_event_handler(app_event_handler_h *event_handler, app_event_type_e event_type, app_event_cb callback, void *user_data)
240 {
241         app_event_handler_h handler;
242
243         if (event_handler == NULL || callback == NULL)
244                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter");
245
246         if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_UPDATE_REQUESTED)
247                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid event type");
248
249         handler = calloc(1, sizeof(struct app_event_handler));
250         if (!handler)
251                 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler");
252
253         handler->type = event_type;
254         handler->cb = callback;
255         handler->data = user_data;
256         handler->raw = appcore_base_add_event(__app_event_converter[event_type], __event_cb, handler);
257
258         *event_handler = handler;
259
260         return APP_ERROR_NONE;
261 }
262
263 int ui_app_remove_event_handler(app_event_handler_h event_handler)
264 {
265         int ret;
266         app_event_type_e type;
267
268         if (event_handler == NULL)
269                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null");
270
271         type = event_handler->type;
272         if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_UPDATE_REQUESTED)
273                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid handler");
274
275
276         ret = appcore_base_remove_event(event_handler->raw);
277         if (ret < 0)
278                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid raw handler");
279
280         free(event_handler);
281
282         return APP_ERROR_NONE;
283 }
284