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 <sys/types.h>
26 #include <appcore-common.h>
27 #include <appcore-efl.h>
31 #include <Elementary.h>
33 #include <app_internal.h>
34 #include <app_control_internal.h>
35 #include <tizen_error.h>
37 #include "app_extension.h"
43 #define LOG_TAG "CAPI_APPFW_APPLICATION"
46 APP_STATE_NOT_RUNNING, /* The application has been launched or was running but was terminated */
47 APP_STATE_CREATING, /* The application is initializing the resources on app_create_cb callback */
48 APP_STATE_RUNNING, /* The application is running in the foreground and background */
55 app_event_callback_s *callback;
59 typedef app_context_s *app_context_h;
61 static int app_appcore_create(void *data);
62 static int app_appcore_pause(void *data);
63 static int app_appcore_resume(void *data);
64 static int app_appcore_terminate(void *data);
65 static int app_appcore_reset(bundle *appcore_bundle, void *data);
67 static int app_appcore_low_memory(void *event, void *data);
68 static int app_appcore_low_battery(void *event, void *data);
69 static int app_appcore_rotation_event(void *event, enum appcore_rm rm, void *data);
70 static int app_appcore_lang_changed(void *event, void *data);
71 static int app_appcore_region_changed(void *event, void *data);
73 static void app_set_appcore_event_cb(app_context_h app_context);
74 static void app_unset_appcore_event_cb(void);
76 int app_main(int argc, char **argv, app_event_callback_s *callback, void *user_data)
78 return app_efl_main(&argc, &argv, callback, user_data);
81 int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data)
83 app_context_s app_context = {
86 .state = APP_STATE_NOT_RUNNING,
91 struct appcore_ops appcore_context = {
93 .create = app_appcore_create,
94 .terminate = app_appcore_terminate,
95 .pause = app_appcore_pause,
96 .resume = app_appcore_resume,
97 .reset = app_appcore_reset,
100 if (argc == NULL || argv == NULL || callback == NULL)
101 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
103 if (callback->create == NULL)
104 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
106 if (app_context.state != APP_STATE_NOT_RUNNING)
107 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
109 if (app_get_id(&(app_context.package)) != APP_ERROR_NONE)
110 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
112 if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE) {
113 free(app_context.package);
114 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
117 app_context.state = APP_STATE_CREATING;
119 appcore_efl_main(app_context.app_name, argc, argv, &appcore_context);
121 free(app_context.package);
122 free(app_context.app_name);
124 return APP_ERROR_NONE;
132 void app_efl_exit(void)
137 int app_appcore_create(void *data)
139 app_context_h app_context = data;
140 app_create_cb create_cb;
141 char locale_dir[TIZEN_PATH_MAX] = {0, };
143 if (app_context == NULL)
144 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
146 app_set_appcore_event_cb(app_context);
148 snprintf(locale_dir, TIZEN_PATH_MAX, "%s/%s" PATH_FMT_RES_DIR
149 PATH_FMT_LOCALE_DIR, PATH_FMT_APP_ROOT, app_context->package);
150 if (access(locale_dir, R_OK) != 0) {
151 snprintf(locale_dir, TIZEN_PATH_MAX, "%s/%s" PATH_FMT_RO_RES_DIR
152 PATH_FMT_RO_LOCALE_DIR, PATH_FMT_RO_APP_ROOT, app_context->package);
154 appcore_set_i18n(app_context->app_name, locale_dir);
156 create_cb = app_context->callback->create;
157 if (create_cb == NULL || create_cb(app_context->data) == false)
158 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
160 app_context->state = APP_STATE_RUNNING;
162 return APP_ERROR_NONE;
165 int app_appcore_terminate(void *data)
167 app_context_h app_context = data;
168 app_terminate_cb terminate_cb;
170 if (app_context == NULL)
171 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
173 terminate_cb = app_context->callback->terminate;
175 if (terminate_cb != NULL)
176 terminate_cb(app_context->data);
178 app_unset_appcore_event_cb();
180 app_finalizer_execute();
182 return APP_ERROR_NONE;
185 int app_appcore_pause(void *data)
187 app_context_h app_context = data;
188 app_pause_cb pause_cb;
190 if (app_context == NULL)
191 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
193 pause_cb = app_context->callback->pause;
194 if (pause_cb != NULL)
195 pause_cb(app_context->data);
197 return APP_ERROR_NONE;
200 int app_appcore_resume(void *data)
202 app_context_h app_context = data;
203 app_resume_cb resume_cb;
205 if (app_context == NULL)
206 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
208 resume_cb = app_context->callback->resume;
209 if (resume_cb != NULL)
210 resume_cb(app_context->data);
212 return APP_ERROR_NONE;
215 int app_appcore_reset(bundle *appcore_bundle, void *data)
217 app_context_h app_context = data;
218 app_control_cb callback;
219 app_control_h app_control;
221 if (app_context == NULL)
222 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
224 if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE)
225 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a service handle from the bundle");
227 callback = app_context->callback->app_control;
228 if (callback != NULL)
229 callback(app_control, app_context->data);
231 app_control_destroy(app_control);
233 return APP_ERROR_NONE;
236 int app_appcore_low_memory(void *event_info, void *data)
238 app_context_h app_context = data;
239 app_low_memory_cb low_memory_cb;
241 if (app_context == NULL)
242 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
244 low_memory_cb = app_context->callback->low_memory;
245 if (low_memory_cb != NULL)
246 low_memory_cb(app_context->data);
248 return APP_ERROR_NONE;
251 int app_appcore_low_battery(void *event_info, void *data)
253 app_context_h app_context = data;
254 app_low_battery_cb low_battery_cb;
256 if (app_context == NULL)
257 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
259 low_battery_cb = app_context->callback->low_battery;
260 if (low_battery_cb != NULL)
261 low_battery_cb(app_context->data);
263 return APP_ERROR_NONE;
266 int app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
268 app_context_h app_context = data;
269 app_device_orientation_cb device_orientation_cb;
271 if (app_context == NULL)
272 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
274 device_orientation_cb = app_context->callback->device_orientation;
275 if (device_orientation_cb != NULL) {
276 app_device_orientation_e dev_orientation;
278 dev_orientation = app_convert_appcore_rm(rm);
280 device_orientation_cb(dev_orientation, app_context->data);
283 return APP_ERROR_NONE;
286 int app_appcore_lang_changed(void *event_info, void *data)
288 app_context_h app_context = data;
289 app_language_changed_cb lang_changed_cb;
291 if (app_context == NULL)
292 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
294 lang_changed_cb = app_context->callback->language_changed;
295 if (lang_changed_cb != NULL)
296 lang_changed_cb(app_context->data);
298 return APP_ERROR_NONE;
301 int app_appcore_region_changed(void *event_info, void *data)
303 app_context_h app_context = data;
304 app_region_format_changed_cb region_changed_cb;
306 if (app_context == NULL)
307 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
309 region_changed_cb = app_context->callback->region_format_changed;
310 if (region_changed_cb != NULL)
311 region_changed_cb(app_context->data);
313 return APP_ERROR_NONE;
316 void app_set_appcore_event_cb(app_context_h app_context)
318 if (app_context->callback->low_memory != NULL)
319 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, app_appcore_low_memory, app_context);
321 if (app_context->callback->low_battery != NULL)
322 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, app_appcore_low_battery, app_context);
324 if (app_context->callback->device_orientation != NULL)
325 appcore_set_rotation_cb(app_appcore_rotation_event, app_context);
327 if (app_context->callback->language_changed != NULL)
328 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, app_appcore_lang_changed, app_context);
330 if (app_context->callback->region_format_changed != NULL)
331 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, app_appcore_region_changed, app_context);
334 void app_unset_appcore_event_cb(void)
336 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL);
337 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
338 appcore_unset_rotation_cb();
339 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
340 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL);
343 #define UI_APP_EVENT_MAX 6
344 static Eina_List *handler_list[UI_APP_EVENT_MAX] = {NULL, };
345 static int handler_initialized = 0;
346 static int appcore_initialized = 0;
348 struct ui_app_context {
352 ui_app_lifecycle_callback_s *callback;
356 static void _free_handler_list(void)
359 app_event_handler_h handler;
361 for (i = 0; i < UI_APP_EVENT_MAX; i++) {
362 EINA_LIST_FREE(handler_list[i], handler)
370 static int _ui_app_appcore_low_memory(void *event_info, void *data)
373 app_event_handler_h handler;
374 struct app_event_info event;
376 LOGI("_app_appcore_low_memory");
378 event.type = APP_EVENT_LOW_MEMORY;
379 event.value = event_info;
381 EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) {
382 handler->cb(&event, handler->data);
385 return APP_ERROR_NONE;
388 static int _ui_app_appcore_low_battery(void *event_info, void *data)
391 app_event_handler_h handler;
392 struct app_event_info event;
394 LOGI("_ui_app_appcore_low_battery");
396 event.type = APP_EVENT_LOW_BATTERY;
397 event.value = event_info;
399 EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) {
400 handler->cb(&event, handler->data);
403 return APP_ERROR_NONE;
406 static int _ui_app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
409 app_event_handler_h handler;
410 struct app_event_info event;
412 LOGI("_ui_app_appcore_rotation_event");
414 event.type = APP_EVENT_DEVICE_ORIENTATION_CHANGED;
415 event.value = event_info;
417 EINA_LIST_FOREACH(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED], l, handler) {
418 handler->cb(&event, handler->data);
421 return APP_ERROR_NONE;
424 static int _ui_app_appcore_lang_changed(void *event_info, void *data)
427 app_event_handler_h handler;
428 struct app_event_info event;
430 LOGI("_ui_app_appcore_lang_changed");
432 event.type = APP_EVENT_LANGUAGE_CHANGED;
433 event.value = event_info;
435 EINA_LIST_FOREACH(handler_list[APP_EVENT_LANGUAGE_CHANGED], l, handler) {
436 handler->cb(&event, handler->data);
439 return APP_ERROR_NONE;
442 static int _ui_app_appcore_region_changed(void *event_info, void *data)
445 app_event_handler_h handler;
446 struct app_event_info event;
448 if (event_info == NULL) {
449 LOGI("receive empty event, ignore it");
450 return APP_ERROR_NONE;
453 LOGI("_ui_app_appcore_region_changed");
455 event.type = APP_EVENT_REGION_FORMAT_CHANGED;
456 event.value = event_info;
458 EINA_LIST_FOREACH(handler_list[APP_EVENT_REGION_FORMAT_CHANGED], l, handler) {
459 handler->cb(&event, handler->data);
462 return APP_ERROR_NONE;
465 static int _ui_app_appcore_suspended_state_changed(void *event_info, void *data)
468 app_event_handler_h handler;
469 struct app_event_info event;
471 LOGI("_ui_app_appcore_suspended_state_changed");
472 LOGI("[__SUSPEND__] suspended state: %d (0: suspend, 1: wake)", *(int*)event_info);
474 event.type = APP_EVENT_SUSPENDED_STATE_CHANGED;
475 event.value = event_info;
477 EINA_LIST_FOREACH(handler_list[APP_EVENT_SUSPENDED_STATE_CHANGED], l, handler) {
478 handler->cb(&event, handler->data);
481 return APP_ERROR_NONE;
484 static void _ui_app_appcore_set_event_cb(app_event_type_e event_type)
486 switch (event_type) {
487 case APP_EVENT_LOW_MEMORY:
488 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, _ui_app_appcore_low_memory, NULL);
490 case APP_EVENT_LOW_BATTERY:
491 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, _ui_app_appcore_low_battery, NULL);
493 case APP_EVENT_LANGUAGE_CHANGED:
494 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, _ui_app_appcore_lang_changed, NULL);
496 case APP_EVENT_DEVICE_ORIENTATION_CHANGED:
497 appcore_set_rotation_cb(_ui_app_appcore_rotation_event, NULL);
499 case APP_EVENT_REGION_FORMAT_CHANGED:
500 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, _ui_app_appcore_region_changed, NULL);
502 case APP_EVENT_SUSPENDED_STATE_CHANGED:
503 LOGI("[__SUSPEND__]");
504 appcore_set_event_callback(APPCORE_EVENT_SUSPENDED_STATE_CHANGE, _ui_app_appcore_suspended_state_changed, NULL);
511 static void _ui_app_appcore_unset_event_cb(app_event_type_e event_type)
513 switch (event_type) {
514 case APP_EVENT_LOW_MEMORY:
515 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL);
517 case APP_EVENT_LOW_BATTERY:
518 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL);
520 case APP_EVENT_LANGUAGE_CHANGED:
521 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
523 case APP_EVENT_DEVICE_ORIENTATION_CHANGED:
524 appcore_unset_rotation_cb();
526 case APP_EVENT_REGION_FORMAT_CHANGED:
527 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL);
529 case APP_EVENT_SUSPENDED_STATE_CHANGED:
530 LOGI("[__SUSPEND__]");
531 appcore_set_event_callback(APPCORE_EVENT_SUSPENDED_STATE_CHANGE, NULL, NULL);
538 static void _ui_app_set_appcore_event_cb(void)
540 _ui_app_appcore_set_event_cb(APP_EVENT_LOW_MEMORY);
541 _ui_app_appcore_set_event_cb(APP_EVENT_LANGUAGE_CHANGED);
542 _ui_app_appcore_set_event_cb(APP_EVENT_REGION_FORMAT_CHANGED);
544 if (eina_list_count(handler_list[APP_EVENT_LOW_BATTERY]) > 0)
545 _ui_app_appcore_set_event_cb(APP_EVENT_LOW_BATTERY);
546 if (eina_list_count(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED]) > 0)
547 _ui_app_appcore_set_event_cb(APP_EVENT_DEVICE_ORIENTATION_CHANGED);
548 if (eina_list_count(handler_list[APP_EVENT_SUSPENDED_STATE_CHANGED]) > 0)
549 _ui_app_appcore_set_event_cb(APP_EVENT_SUSPENDED_STATE_CHANGED);
552 static void _ui_app_unset_appcore_event_cb(void)
554 _ui_app_appcore_unset_event_cb(APP_EVENT_LOW_MEMORY);
555 _ui_app_appcore_unset_event_cb(APP_EVENT_LANGUAGE_CHANGED);
556 _ui_app_appcore_unset_event_cb(APP_EVENT_REGION_FORMAT_CHANGED);
558 if (eina_list_count(handler_list[APP_EVENT_LOW_BATTERY]) > 0)
559 _ui_app_appcore_unset_event_cb(APP_EVENT_LOW_BATTERY);
560 if (eina_list_count(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED]) > 0)
561 _ui_app_appcore_unset_event_cb(APP_EVENT_DEVICE_ORIENTATION_CHANGED);
562 if (eina_list_count(handler_list[APP_EVENT_SUSPENDED_STATE_CHANGED]) > 0)
563 _ui_app_appcore_unset_event_cb(APP_EVENT_SUSPENDED_STATE_CHANGED);
566 static int _ui_app_appcore_create(void *data)
568 LOGI("app_appcore_create");
569 struct ui_app_context *app_context = data;
570 app_create_cb create_cb;
572 if (app_context == NULL)
573 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
575 appcore_initialized = 1;
576 _ui_app_set_appcore_event_cb();
578 create_cb = app_context->callback->create;
580 if (create_cb == NULL || create_cb(app_context->data) == false)
581 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
583 app_context->state = APP_STATE_RUNNING;
585 return APP_ERROR_NONE;
588 static int _ui_app_appcore_terminate(void *data)
590 LOGI("app_appcore_terminate");
591 struct ui_app_context *app_context = data;
592 app_terminate_cb terminate_cb;
594 if (app_context == NULL)
595 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
597 terminate_cb = app_context->callback->terminate;
599 if (terminate_cb != NULL)
600 terminate_cb(app_context->data);
602 _ui_app_unset_appcore_event_cb();
604 app_finalizer_execute();
606 if (handler_initialized) {
607 _free_handler_list();
608 handler_initialized = 0;
611 return APP_ERROR_NONE;
614 static int _ui_app_appcore_pause(void *data)
616 LOGI("app_appcore_pause");
617 struct ui_app_context *app_context = data;
618 app_pause_cb pause_cb;
620 if (app_context == NULL)
621 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
623 pause_cb = app_context->callback->pause;
625 if (pause_cb != NULL)
626 pause_cb(app_context->data);
628 return APP_ERROR_NONE;
631 static int _ui_app_appcore_resume(void *data)
633 LOGI("app_appcore_resume");
634 struct ui_app_context *app_context = data;
635 app_resume_cb resume_cb;
637 if (app_context == NULL)
638 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
640 resume_cb = app_context->callback->resume;
642 if (resume_cb != NULL)
643 resume_cb(app_context->data);
645 return APP_ERROR_NONE;
649 static int _ui_app_appcore_reset(bundle *appcore_bundle, void *data)
651 LOGI("app_appcore_reset");
652 struct ui_app_context *app_context = data;
653 app_control_cb callback;
654 app_control_h app_control;
657 if (app_context == NULL)
658 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
660 if (appcore_bundle) {
661 if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE)
662 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create an app_control handle from the bundle");
664 ret = app_control_create(&app_control);
665 if (ret != APP_ERROR_NONE)
666 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create an app_control");
669 callback = app_context->callback->app_control;
671 if (callback != NULL)
672 callback(app_control, app_context->data);
674 app_control_destroy(app_control);
676 return APP_ERROR_NONE;
679 int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
681 struct ui_app_context app_context = {
684 .state = APP_STATE_NOT_RUNNING,
685 .callback = callback,
689 struct appcore_ops appcore_context = {
690 .data = &app_context,
691 .create = _ui_app_appcore_create,
692 .terminate = _ui_app_appcore_terminate,
693 .pause = _ui_app_appcore_pause,
694 .resume = _ui_app_appcore_resume,
695 .reset = _ui_app_appcore_reset,
698 if (argc < 1 || argv == NULL || callback == NULL)
699 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
701 if (callback->create == NULL)
702 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
704 if (app_context.state != APP_STATE_NOT_RUNNING)
705 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
707 if (app_get_id(&(app_context.package)) != APP_ERROR_NONE)
708 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
710 if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE) {
711 free(app_context.package);
712 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
715 app_context.state = APP_STATE_CREATING;
717 LOGI("app_efl_main");
718 appcore_efl_main(app_context.app_name, &argc, &argv, &appcore_context);
720 free(app_context.package);
721 free(app_context.app_name);
723 return APP_ERROR_NONE;
726 void ui_app_exit(void)
731 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)
733 app_event_handler_h handler;
736 if (!handler_initialized) {
738 handler_initialized = 1;
741 if (event_handler == NULL || callback == NULL)
742 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter");
744 if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_SUSPENDED_STATE_CHANGED)
745 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid event type");
747 EINA_LIST_FOREACH(handler_list[event_type], l_itr, handler) {
748 if (handler->cb == callback)
749 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "already registered");
752 handler = calloc(1, sizeof(struct app_event_handler));
754 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler");
756 handler->type = event_type;
757 handler->cb = callback;
758 handler->data = user_data;
760 if (appcore_initialized && eina_list_count(handler_list[event_type]) == 0)
761 _ui_app_appcore_set_event_cb(event_type);
763 handler_list[event_type] = eina_list_append(handler_list[event_type], handler);
765 *event_handler = handler;
767 return APP_ERROR_NONE;
770 int ui_app_remove_event_handler(app_event_handler_h event_handler)
772 app_event_handler_h handler;
773 app_event_type_e type;
777 if (event_handler == NULL)
778 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null");
780 if (!handler_initialized) {
781 LOGI("handler list is not initialized");
782 return APP_ERROR_NONE;
785 type = event_handler->type;
786 if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_SUSPENDED_STATE_CHANGED)
787 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid handler");
789 EINA_LIST_FOREACH_SAFE(handler_list[type], l_itr, l_next, handler) {
790 if (handler == event_handler) {
792 handler_list[type] = eina_list_remove_list(handler_list[type], l_itr);
794 if (appcore_initialized && eina_list_count(handler_list[type]) == 0)
795 _ui_app_appcore_unset_event_cb(type);
797 return APP_ERROR_NONE;
801 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler");