2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <appcore-common.h>
22 #include <appcore-efl.h>
24 #include <vconf-internal-keys.h>
26 #include <Elementary.h>
29 #include <app_common.h>
30 #include <app_control_internal.h>
31 #include <app_internal.h>
37 #define LOG_TAG "CAPI_APPFW_APPLICATION"
40 APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated
41 APP_STATE_CREATING, // The application is initializing the resources on app_create_cb callback
42 APP_STATE_RUNNING, // The application is running in the foreground and background
49 app_event_callback_s *callback;
53 typedef app_context_s *app_context_h;
55 static int app_appcore_create(void *data);
56 static int app_appcore_pause(void *data);
57 static int app_appcore_resume(void *data);
58 static int app_appcore_terminate(void *data);
59 static int app_appcore_reset(bundle *appcore_bundle, void *data);
61 static int app_appcore_low_memory(void *event, void *data);
62 static int app_appcore_low_battery(void *event, void *data);
63 static int app_appcore_rotation_event(void *event, enum appcore_rm rm, void *data);
64 static int app_appcore_lang_changed(void *event, void *data);
65 static int app_appcore_region_changed(void *event, void *data);
67 static void app_set_appcore_event_cb(app_context_h app_context);
68 static void app_unset_appcore_event_cb(void);
70 int app_main(int argc, char **argv, app_event_callback_s *callback, void *user_data)
72 return app_efl_main(&argc, &argv, callback, user_data);
75 int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data)
77 app_context_s app_context = {
80 .state = APP_STATE_NOT_RUNNING,
85 struct appcore_ops appcore_context = {
87 .create = app_appcore_create,
88 .terminate = app_appcore_terminate,
89 .pause = app_appcore_pause,
90 .resume = app_appcore_resume,
91 .reset = app_appcore_reset,
94 if (argc == NULL || argv == NULL || callback == NULL)
96 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
99 if (callback->create == NULL)
101 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
104 if (app_context.state != APP_STATE_NOT_RUNNING)
106 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
109 if (app_get_id(&(app_context.package)) != APP_ERROR_NONE)
111 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
114 if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE)
116 free(app_context.package);
117 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
120 app_context.state = APP_STATE_CREATING;
122 LOGI("app_efl_main");
123 appcore_efl_main(app_context.app_name, argc, argv, &appcore_context);
125 free(app_context.package);
126 free(app_context.app_name);
128 return APP_ERROR_NONE;
136 void app_efl_exit(void)
138 LOGI("app_efl_exit");
143 int app_appcore_create(void *data)
145 LOGI("app_appcore_create");
146 app_context_h app_context = data;
147 app_create_cb create_cb;
149 if (app_context == NULL)
151 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
154 app_set_appcore_event_cb(app_context);
156 create_cb = app_context->callback->create;
158 if (create_cb == NULL || create_cb(app_context->data) == false)
160 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
163 app_context->state = APP_STATE_RUNNING;
165 return APP_ERROR_NONE;
168 int app_appcore_terminate(void *data)
170 LOGI("app_appcore_terminate");
171 app_context_h app_context = data;
172 app_terminate_cb terminate_cb;
174 if (app_context == NULL)
176 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
179 terminate_cb = app_context->callback->terminate;
181 if (terminate_cb != NULL)
183 terminate_cb(app_context->data);
186 app_unset_appcore_event_cb();
188 app_finalizer_execute();
190 return APP_ERROR_NONE;
193 int app_appcore_pause(void *data)
195 LOGI("app_appcore_pause");
196 app_context_h app_context = data;
197 app_pause_cb pause_cb;
199 if (app_context == NULL)
201 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
204 pause_cb = app_context->callback->pause;
206 if (pause_cb != NULL)
208 pause_cb(app_context->data);
211 return APP_ERROR_NONE;
214 int app_appcore_resume(void *data)
216 LOGI("app_appcore_resume");
217 app_context_h app_context = data;
218 app_resume_cb resume_cb;
220 if (app_context == NULL)
222 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
225 resume_cb = app_context->callback->resume;
227 if (resume_cb != NULL)
229 resume_cb(app_context->data);
232 return APP_ERROR_NONE;
236 int app_appcore_reset(bundle *appcore_bundle, void *data)
238 LOGI("app_appcore_reset");
239 app_context_h app_context = data;
240 app_control_cb callback;
241 app_control_h app_control;
243 if (app_context == NULL)
245 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
248 if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE)
250 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a app_control handle from the bundle");
253 callback = app_context->callback->app_control;
255 if (callback != NULL)
257 callback(app_control, app_context->data);
260 app_control_destroy(app_control);
262 return APP_ERROR_NONE;
265 int app_appcore_low_memory(void *event_info, void *data)
267 LOGI("app_appcore_low_memory");
269 app_context_h app_context = data;
270 app_low_memory_cb low_memory_cb;
272 if (app_context == NULL)
274 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
277 low_memory_cb = app_context->callback->low_memory;
279 if (low_memory_cb != NULL)
281 low_memory_cb(app_context->data);
284 return APP_ERROR_NONE;
287 int app_appcore_low_battery(void *event_info, void *data)
289 app_context_h app_context = data;
290 app_low_battery_cb low_battery_cb;
292 LOGI("app_appcore_low_battery");
294 if (app_context == NULL)
296 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
299 low_battery_cb = app_context->callback->low_battery;
301 if (low_battery_cb != NULL)
303 LOGI("app_appcore_low_memory: app_appcore_low_memory_cb() is called");
304 low_battery_cb(app_context->data);
307 return APP_ERROR_NONE;
310 int app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
312 LOGI("app_appcore_rotation_event");
313 app_context_h app_context = data;
314 app_device_orientation_cb device_orientation_cb;
316 if (app_context == NULL)
318 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
321 device_orientation_cb = app_context->callback->device_orientation;
323 if (device_orientation_cb != NULL)
325 app_device_orientation_e dev_orientation;
327 dev_orientation = app_convert_appcore_rm(rm);
329 device_orientation_cb(dev_orientation, app_context->data);
332 return APP_ERROR_NONE;
335 int app_appcore_lang_changed(void *event_info, void *data)
337 LOGI("app_appcore_lang_changed");
338 app_context_h app_context = data;
339 app_language_changed_cb lang_changed_cb;
341 if (app_context == NULL)
343 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
346 lang_changed_cb = app_context->callback->language_changed;
348 if (lang_changed_cb != NULL)
350 lang_changed_cb(app_context->data);
353 return APP_ERROR_NONE;
356 int app_appcore_region_changed(void *event_info, void *data)
358 LOGI("app_appcore_region_changed");
359 app_context_h app_context = data;
360 app_region_format_changed_cb region_changed_cb;
362 if (app_context == NULL)
364 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
367 region_changed_cb = app_context->callback->region_format_changed;
369 if (region_changed_cb != NULL)
371 region_changed_cb(app_context->data);
374 return APP_ERROR_NONE;
378 void app_set_appcore_event_cb(app_context_h app_context)
380 if (app_context->callback->low_memory != NULL)
382 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, app_appcore_low_memory, app_context);
385 if (app_context->callback->low_battery != NULL)
387 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, app_appcore_low_battery, app_context);
390 if (app_context->callback->device_orientation != NULL)
392 appcore_set_rotation_cb(app_appcore_rotation_event, app_context);
395 if (app_context->callback->language_changed != NULL)
397 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, app_appcore_lang_changed, app_context);
400 if (app_context->callback->region_format_changed != NULL)
402 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, app_appcore_region_changed, app_context);
406 void app_unset_appcore_event_cb(void)
408 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL);
409 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
410 appcore_unset_rotation_cb();
411 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
412 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL);
415 #define UI_APP_EVENT_MAX 5
416 static Eina_List *handler_list[UI_APP_EVENT_MAX] = {NULL, };
417 static int _initialized = 0;
419 struct ui_app_context {
423 ui_app_lifecycle_callback_s *callback;
427 static void _free_handler_list(void)
430 app_event_handler_h handler;
432 for (i = 0; i < UI_APP_EVENT_MAX; i++) {
433 EINA_LIST_FREE(handler_list[i], handler)
440 static int _ui_app_appcore_low_memory(void *event_info, void *data)
443 app_event_handler_h handler;
444 struct app_event_info event;
446 LOGI("_app_appcore_low_memory");
448 event.type = APP_EVENT_LOW_MEMORY;
449 event.value = event_info;
451 EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) {
452 handler->cb(&event, handler->data);
455 return APP_ERROR_NONE;
458 static int _ui_app_appcore_low_battery(void *event_info, void *data)
461 app_event_handler_h handler;
462 struct app_event_info event;
464 LOGI("_ui_app_appcore_low_battery");
466 event.type = APP_EVENT_LOW_BATTERY;
467 event.value = event_info;
469 EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) {
470 handler->cb(&event, handler->data);
473 return APP_ERROR_NONE;
476 static int _ui_app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
479 app_event_handler_h handler;
480 struct app_event_info event;
482 LOGI("_ui_app_appcore_rotation_event");
484 event.type = APP_EVENT_DEVICE_ORIENTATION_CHANGED;
485 event.value = event_info;
487 EINA_LIST_FOREACH(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED], l, handler) {
488 handler->cb(&event, handler->data);
491 return APP_ERROR_NONE;
494 static int _ui_app_appcore_lang_changed(void *event_info, void *data)
497 app_event_handler_h handler;
498 struct app_event_info event;
500 LOGI("_ui_app_appcore_lang_changed");
502 event.type = APP_EVENT_LANGUAGE_CHANGED;
503 event.value = event_info;
505 EINA_LIST_FOREACH(handler_list[APP_EVENT_LANGUAGE_CHANGED], l, handler) {
506 handler->cb(&event, handler->data);
509 return APP_ERROR_NONE;
512 static int _ui_app_appcore_region_changed(void *event_info, void *data)
515 app_event_handler_h handler;
516 struct app_event_info event;
518 if (event_info == NULL) {
519 LOGI("receive empty event, ignore it");
520 return APP_ERROR_NONE;
523 LOGI("_ui_app_appcore_region_changed");
525 event.type = APP_EVENT_REGION_FORMAT_CHANGED;
526 event.value = event_info;
528 EINA_LIST_FOREACH(handler_list[APP_EVENT_REGION_FORMAT_CHANGED], l, handler) {
529 handler->cb(&event, handler->data);
532 return APP_ERROR_NONE;
536 static void _ui_app_set_appcore_event_cb(void)
538 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, _ui_app_appcore_low_memory, NULL);
539 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, _ui_app_appcore_low_battery, NULL);
540 appcore_set_rotation_cb(_ui_app_appcore_rotation_event, NULL);
541 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, _ui_app_appcore_lang_changed, NULL);
542 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, _ui_app_appcore_region_changed, NULL);
545 static void _ui_app_unset_appcore_event_cb(void)
547 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL);
548 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
549 appcore_unset_rotation_cb();
550 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
551 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL);
554 static int _ui_app_appcore_create(void *data)
556 LOGI("app_appcore_create");
557 struct ui_app_context *app_context = data;
558 app_create_cb create_cb;
560 if (app_context == NULL)
561 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
563 _ui_app_set_appcore_event_cb();
565 create_cb = app_context->callback->create;
567 if (create_cb == NULL || create_cb(app_context->data) == false)
568 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
570 app_context->state = APP_STATE_RUNNING;
572 return APP_ERROR_NONE;
575 static int _ui_app_appcore_terminate(void *data)
577 LOGI("app_appcore_terminate");
578 struct ui_app_context *app_context = data;
579 app_terminate_cb terminate_cb;
581 if (app_context == NULL)
582 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
584 terminate_cb = app_context->callback->terminate;
586 if (terminate_cb != NULL)
587 terminate_cb(app_context->data);
589 _ui_app_unset_appcore_event_cb();
591 app_finalizer_execute();
594 _free_handler_list();
598 return APP_ERROR_NONE;
601 static int _ui_app_appcore_pause(void *data)
603 LOGI("app_appcore_pause");
604 struct ui_app_context *app_context = data;
605 app_pause_cb pause_cb;
607 if (app_context == NULL)
608 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
610 pause_cb = app_context->callback->pause;
612 if (pause_cb != NULL)
613 pause_cb(app_context->data);
615 return APP_ERROR_NONE;
618 static int _ui_app_appcore_resume(void *data)
620 LOGI("app_appcore_resume");
621 struct ui_app_context *app_context = data;
622 app_resume_cb resume_cb;
624 if (app_context == NULL)
625 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
627 resume_cb = app_context->callback->resume;
629 if (resume_cb != NULL)
630 resume_cb(app_context->data);
632 return APP_ERROR_NONE;
636 static int _ui_app_appcore_reset(bundle *appcore_bundle, void *data)
638 LOGI("app_appcore_reset");
639 struct ui_app_context *app_context = data;
640 app_control_cb callback;
641 app_control_h app_control;
643 if (app_context == NULL)
644 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
646 if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE)
647 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a app_control handle from the bundle");
649 callback = app_context->callback->app_control;
651 if (callback != NULL)
652 callback(app_control, app_context->data);
654 app_control_destroy(app_control);
656 return APP_ERROR_NONE;
659 int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
661 struct ui_app_context app_context = {
664 .state = APP_STATE_NOT_RUNNING,
665 .callback = callback,
669 struct appcore_ops appcore_context = {
670 .data = &app_context,
671 .create = _ui_app_appcore_create,
672 .terminate = _ui_app_appcore_terminate,
673 .pause = _ui_app_appcore_pause,
674 .resume = _ui_app_appcore_resume,
675 .reset = _ui_app_appcore_reset,
678 if (argc < 1 || argv == NULL || callback == NULL)
679 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
681 if (callback->create == NULL)
682 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
684 if (app_context.state != APP_STATE_NOT_RUNNING)
685 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
687 if (app_get_id(&(app_context.package)) != APP_ERROR_NONE)
688 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
690 if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE) {
691 free(app_context.package);
692 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
695 app_context.state = APP_STATE_CREATING;
697 LOGI("app_efl_main");
698 appcore_efl_main(app_context.app_name, &argc, &argv, &appcore_context);
700 free(app_context.package);
701 free(app_context.app_name);
703 return APP_ERROR_NONE;
706 void ui_app_exit(void)
711 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)
713 app_event_handler_h handler;
721 if (event_handler == NULL || callback == NULL)
722 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter");
724 if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_REGION_FORMAT_CHANGED)
725 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid event type");
727 EINA_LIST_FOREACH(handler_list[event_type], l_itr, handler) {
728 if (handler->cb == callback)
729 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "already registered");
732 handler = calloc(1, sizeof(struct app_event_handler));
734 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler");
736 handler->type = event_type;
737 handler->cb = callback;
738 handler->data = user_data;
739 handler_list[event_type] = eina_list_append(handler_list[event_type], handler);
741 *event_handler = handler;
743 return APP_ERROR_NONE;
746 int ui_app_remove_event_handler(app_event_handler_h event_handler)
748 app_event_handler_h handler;
749 app_event_type_e type;
753 if (event_handler == NULL)
754 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null");
757 LOGI("handler list is not initialized");
758 return APP_ERROR_NONE;
761 type = event_handler->type;
762 if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_REGION_FORMAT_CHANGED)
763 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid handler");
765 EINA_LIST_FOREACH_SAFE(handler_list[type], l_itr, l_next, handler) {
766 if (handler == event_handler) {
768 handler_list[type] = eina_list_remove_list(handler_list[type], l_itr);
769 return APP_ERROR_NONE;
773 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler");