ebb5d32c80ce115f005d510a2788f918c6fa3a3e
[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         [APP_EVENT_UPDATE_REQUESTED] = APPCORE_BASE_EVENT_UPDATE_REQUESTED,
78 };
79
80 static int __ui_app_create(void *data)
81 {
82         appcore_efl_base_on_create();
83         if (__context.callback.create == NULL ||
84                         __context.callback.create(__context.data) == false)
85                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
86
87         return APP_ERROR_NONE;
88 }
89
90 static int __ui_app_terminate(void *data)
91 {
92         appcore_efl_base_on_terminate();
93
94         if (__context.callback.terminate)
95                 __context.callback.terminate(__context.data);
96
97         return APP_ERROR_NONE;
98 }
99
100 static int __ui_app_control(bundle *b, void *data)
101 {
102         app_control_h app_control = NULL;
103
104         appcore_efl_base_on_control(b);
105
106         if (b) {
107                 if (app_control_create_event(b, &app_control) != APP_ERROR_NONE)
108                         return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to create an app_control handle");
109         } else {
110                 if (app_control_create(&app_control) != APP_ERROR_NONE)
111                         return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "Failed to create an app_control handle");
112         }
113
114         if (__context.callback.app_control)
115                 __context.callback.app_control(app_control, __context.data);
116
117         app_control_destroy(app_control);
118
119         return APP_ERROR_NONE;
120 }
121
122 static int __ui_app_pause(void *data)
123 {
124         appcore_efl_base_on_pause();
125         if (__context.callback.pause)
126                 __context.callback.pause(__context.data);
127         return APP_ERROR_NONE;
128 }
129
130 static int __ui_app_resume(void *data)
131 {
132         appcore_efl_base_on_resume();
133         if (__context.callback.resume)
134                 __context.callback.resume(__context.data);
135         return APP_ERROR_NONE;
136 }
137
138 static int __app_init(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data, appcore_efl_base_ops ops)
139 {
140         int ret;
141
142         if (argc < 1 || argv == NULL || callback == NULL)
143                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
144
145         if (callback->create == NULL)
146                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
147
148         if (__app_state != APP_STATE_NOT_RUNNING)
149                 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
150
151         __context.callback = *callback;
152         __context.data = user_data;
153         __app_state = APP_STATE_CREATING;
154
155         ret = appcore_efl_base_init(ops, argc, argv, NULL,
156                         APPCORE_EFL_BASE_HINT_WINDOW_GROUP_CONTROL |
157                         APPCORE_EFL_BASE_HINT_WINDOW_STACK_CONTROL |
158                         APPCORE_EFL_BASE_HINT_BG_LAUNCH_CONTROL |
159                         APPCORE_EFL_BASE_HINT_HW_ACC_CONTROL |
160                         APPCORE_EFL_BASE_HINT_WINDOW_AUTO_CONTROL |
161                         APPCORE_EFL_BASE_HINT_LEGACY_CONTROL);
162
163         if (ret < 0) {
164                 __app_state = APP_STATE_NOT_RUNNING;
165                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
166         }
167
168         return APP_ERROR_NONE;
169 }
170
171 static void __app_fini(void)
172 {
173         appcore_efl_base_fini();
174         __app_state = APP_STATE_NOT_RUNNING;
175
176 }
177
178 int ui_app_init(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data, appcore_context_h *handle)
179 {
180         appcore_efl_base_ops ops = appcore_efl_base_get_default_ops();
181
182         /* override methods */
183         ops.ui_base.base.create = __ui_app_create;
184         ops.ui_base.base.control = __ui_app_control;
185         ops.ui_base.base.terminate = __ui_app_terminate;
186         ops.ui_base.pause = __ui_app_pause;
187         ops.ui_base.resume = __ui_app_resume;
188         ops.ui_base.base.run = NULL;
189         ops.ui_base.base.exit = NULL;
190
191         return __app_init(argc, argv, callback, user_data, ops);
192 }
193
194 void ui_app_fini(appcore_context_h handle)
195 {
196         __app_fini();
197 }
198
199 int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
200 {
201         int ret;
202         appcore_efl_base_ops ops = appcore_efl_base_get_default_ops();
203
204         /* override methods */
205         ops.ui_base.base.create = __ui_app_create;
206         ops.ui_base.base.control = __ui_app_control;
207         ops.ui_base.base.terminate = __ui_app_terminate;
208         ops.ui_base.pause = __ui_app_pause;
209         ops.ui_base.resume = __ui_app_resume;
210
211         ret = __app_init(argc, argv, callback, user_data, ops);
212         if (ret != APP_ERROR_NONE)
213                 return ret;
214
215          __app_fini();
216
217          return APP_ERROR_NONE;
218 }
219
220 void ui_app_exit(void)
221 {
222         appcore_efl_base_exit();
223 }
224
225 int __event_cb(void *event, void *data)
226 {
227         app_event_handler_h handler = data;
228
229         struct app_event_info app_event;
230
231         app_event.type = handler->type;
232         app_event.value = event;
233
234         if (handler->cb)
235                 handler->cb(&app_event, handler->data);
236
237         return 0;
238 }
239
240 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)
241 {
242         app_event_handler_h handler;
243
244         if (event_handler == NULL || callback == NULL)
245                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter");
246
247         if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_UPDATE_REQUESTED)
248                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid event type");
249
250         handler = calloc(1, sizeof(struct app_event_handler));
251         if (!handler)
252                 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler");
253
254         handler->type = event_type;
255         handler->cb = callback;
256         handler->data = user_data;
257         handler->raw = appcore_base_add_event(__app_event_converter[event_type], __event_cb, handler);
258
259         *event_handler = handler;
260
261         return APP_ERROR_NONE;
262 }
263
264 int ui_app_remove_event_handler(app_event_handler_h event_handler)
265 {
266         int ret;
267         app_event_type_e type;
268
269         if (event_handler == NULL)
270                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null");
271
272         type = event_handler->type;
273         if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_UPDATE_REQUESTED)
274                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid handler");
275
276
277         ret = appcore_base_remove_event(event_handler->raw);
278         if (ret < 0)
279                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid raw handler");
280
281         free(event_handler);
282
283         return APP_ERROR_NONE;
284 }
285