tizen 2.3 release
[framework/api/application.git] / src / app_main.c
1 /*
2  * Copyright (c) 2011 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
18 #include <stdlib.h>
19
20 #include <bundle.h>
21 #include <appcore-common.h>
22 #include <appcore-efl.h>
23 #include <dlog.h>
24 #include <vconf-internal-keys.h>
25
26 #include <Elementary.h>
27 #include <Eina.h>
28
29 #include <app_common.h>
30 #include <app_control_internal.h>
31 #include <app_internal.h>
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36
37 #define LOG_TAG "CAPI_APPFW_APPLICATION"
38
39 typedef enum {
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
43 } app_state_e;
44
45 typedef struct {
46         char *package;
47         char *app_name;
48         app_state_e state;
49         app_event_callback_s *callback;
50         void *data;
51 } app_context_s;
52
53 typedef app_context_s *app_context_h;
54
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);
60
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);
66
67 static void app_set_appcore_event_cb(app_context_h app_context);
68 static void app_unset_appcore_event_cb(void);
69
70 int app_main(int argc, char **argv, app_event_callback_s *callback, void *user_data)
71 {
72         return app_efl_main(&argc, &argv, callback, user_data);
73 }
74
75 int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data)
76 {
77         app_context_s app_context = {
78                 .package = NULL,
79                 .app_name = NULL,
80                 .state = APP_STATE_NOT_RUNNING,
81                 .callback = callback,
82                 .data = user_data
83         };
84
85         struct appcore_ops appcore_context = {
86                 .data = &app_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,
92         };
93
94         if (argc == NULL || argv == NULL || callback == NULL)
95         {
96                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
97         }
98
99         if (callback->create == NULL)
100         {
101                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
102         }
103
104         if (app_context.state != APP_STATE_NOT_RUNNING)
105         {
106                 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
107         }
108
109         if (app_get_id(&(app_context.package)) != APP_ERROR_NONE)
110         {
111                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
112         }
113
114         if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE)
115         {
116                 free(app_context.package);
117                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
118         }
119
120         app_context.state = APP_STATE_CREATING;
121
122         LOGI("app_efl_main");
123         appcore_efl_main(app_context.app_name, argc, argv, &appcore_context);
124
125         free(app_context.package);
126         free(app_context.app_name);
127
128         return APP_ERROR_NONE;
129 }
130
131 void app_exit(void)
132 {
133         app_efl_exit();
134 }
135
136 void app_efl_exit(void)
137 {
138         LOGI("app_efl_exit");
139         elm_exit();
140 }
141
142
143 int app_appcore_create(void *data)
144 {
145         LOGI("app_appcore_create");
146         app_context_h app_context = data;
147         app_create_cb create_cb;
148
149         if (app_context == NULL)
150         {
151                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
152         }
153
154         app_set_appcore_event_cb(app_context);
155
156         create_cb = app_context->callback->create;
157
158         if (create_cb == NULL || create_cb(app_context->data) == false)
159         {
160                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
161         }
162
163         app_context->state = APP_STATE_RUNNING;
164
165         return APP_ERROR_NONE;
166 }
167
168 int app_appcore_terminate(void *data)
169 {
170         LOGI("app_appcore_terminate");
171         app_context_h app_context = data;
172         app_terminate_cb terminate_cb;
173
174         if (app_context == NULL)
175         {
176                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
177         }
178
179         terminate_cb = app_context->callback->terminate;
180
181         if (terminate_cb != NULL)
182         {
183                 terminate_cb(app_context->data);
184         }
185
186         app_unset_appcore_event_cb();
187
188         app_finalizer_execute();
189
190         return APP_ERROR_NONE;
191 }
192
193 int app_appcore_pause(void *data)
194 {
195         LOGI("app_appcore_pause");
196         app_context_h app_context = data;
197         app_pause_cb pause_cb;
198
199         if (app_context == NULL)
200         {
201                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
202         }
203
204         pause_cb = app_context->callback->pause;
205
206         if (pause_cb != NULL)
207         {
208                 pause_cb(app_context->data);
209         }
210
211         return APP_ERROR_NONE;
212 }
213
214 int app_appcore_resume(void *data)
215 {
216         LOGI("app_appcore_resume");
217         app_context_h app_context = data;
218         app_resume_cb resume_cb;
219
220         if (app_context == NULL)
221         {
222                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
223         }
224
225         resume_cb = app_context->callback->resume;
226
227         if (resume_cb != NULL)
228         {
229                 resume_cb(app_context->data);
230         }
231
232         return APP_ERROR_NONE;
233 }
234
235
236 int app_appcore_reset(bundle *appcore_bundle, void *data)
237 {
238         LOGI("app_appcore_reset");
239         app_context_h app_context = data;
240         app_control_cb callback;
241         app_control_h app_control;
242
243         if (app_context == NULL)
244         {
245                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
246         }
247
248         if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE)
249         {
250                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a app_control handle from the bundle");
251         }
252
253         callback = app_context->callback->app_control;
254
255         if (callback != NULL)
256         {
257                 callback(app_control, app_context->data);
258         }
259
260         app_control_destroy(app_control);
261
262         return APP_ERROR_NONE;
263 }
264
265 int app_appcore_low_memory(void *event_info, void *data)
266 {
267         LOGI("app_appcore_low_memory");
268
269         app_context_h app_context = data;
270         app_low_memory_cb low_memory_cb;
271
272         if (app_context == NULL)
273         {
274                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
275         }
276
277         low_memory_cb = app_context->callback->low_memory;
278
279         if (low_memory_cb != NULL)
280         {
281                 low_memory_cb(app_context->data);
282         }
283
284         return APP_ERROR_NONE;
285 }
286
287 int app_appcore_low_battery(void *event_info, void *data)
288 {
289         app_context_h app_context = data;
290         app_low_battery_cb low_battery_cb;
291
292         LOGI("app_appcore_low_battery");
293
294         if (app_context == NULL)
295         {
296                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
297         }
298
299         low_battery_cb = app_context->callback->low_battery;
300
301         if (low_battery_cb != NULL)
302         {
303                 LOGI("app_appcore_low_memory: app_appcore_low_memory_cb() is called");
304                 low_battery_cb(app_context->data);
305         }
306
307         return APP_ERROR_NONE;
308 }
309
310 int app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
311 {
312         LOGI("app_appcore_rotation_event");
313         app_context_h app_context = data;
314         app_device_orientation_cb device_orientation_cb;
315
316         if (app_context == NULL)
317         {
318                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
319         }
320
321         device_orientation_cb = app_context->callback->device_orientation;
322
323         if (device_orientation_cb != NULL)
324         {
325                 app_device_orientation_e dev_orientation;
326
327                 dev_orientation = app_convert_appcore_rm(rm);
328
329                 device_orientation_cb(dev_orientation, app_context->data);
330         }
331
332         return APP_ERROR_NONE;
333 }
334
335 int app_appcore_lang_changed(void *event_info, void *data)
336 {
337         LOGI("app_appcore_lang_changed");
338         app_context_h app_context = data;
339         app_language_changed_cb lang_changed_cb;
340
341         if (app_context == NULL)
342         {
343                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
344         }
345
346         lang_changed_cb = app_context->callback->language_changed;
347
348         if (lang_changed_cb != NULL)
349         {
350                 lang_changed_cb(app_context->data);
351         }
352
353         return APP_ERROR_NONE;
354 }
355
356 int app_appcore_region_changed(void *event_info, void *data)
357 {
358         LOGI("app_appcore_region_changed");
359         app_context_h app_context = data;
360         app_region_format_changed_cb region_changed_cb;
361
362         if (app_context == NULL)
363         {
364                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
365         }
366
367         region_changed_cb = app_context->callback->region_format_changed;
368
369         if (region_changed_cb != NULL)
370         {
371                 region_changed_cb(app_context->data);
372         }
373
374         return APP_ERROR_NONE;
375 }
376
377
378 void app_set_appcore_event_cb(app_context_h app_context)
379 {
380         if (app_context->callback->low_memory != NULL)
381         {
382                 appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, app_appcore_low_memory, app_context);
383         }
384
385         if (app_context->callback->low_battery != NULL)
386         {
387                 appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, app_appcore_low_battery, app_context);
388         }
389
390         if (app_context->callback->device_orientation != NULL)
391         {
392                 appcore_set_rotation_cb(app_appcore_rotation_event, app_context);
393         }
394
395         if (app_context->callback->language_changed != NULL)
396         {
397                 appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, app_appcore_lang_changed, app_context);
398         }
399
400         if (app_context->callback->region_format_changed != NULL)
401         {
402                 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, app_appcore_region_changed, app_context);
403         }
404 }
405
406 void app_unset_appcore_event_cb(void)
407 {
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);
413 }
414
415 #define UI_APP_EVENT_MAX 5
416 static Eina_List *handler_list[UI_APP_EVENT_MAX] = {NULL, };
417 static int _initialized = 0;
418
419 struct ui_app_context {
420         char *package;
421         char *app_name;
422         app_state_e state;
423         ui_app_lifecycle_callback_s *callback;
424         void *data;
425 };
426
427 static void _free_handler_list(void)
428 {
429         int i;
430         app_event_handler_h handler;
431
432         for (i = 0; i < UI_APP_EVENT_MAX; i++) {
433                 EINA_LIST_FREE(handler_list[i], handler)
434                         free(handler);
435         }
436
437         eina_shutdown();
438 }
439
440 static int _ui_app_appcore_low_memory(void *event_info, void *data)
441 {
442         Eina_List *l;
443         app_event_handler_h handler;
444         struct app_event_info event;
445
446         LOGI("_app_appcore_low_memory");
447
448         event.type = APP_EVENT_LOW_MEMORY;
449         event.value = event_info;
450
451         EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) {
452                 handler->cb(&event, handler->data);
453         }
454
455         return APP_ERROR_NONE;
456 }
457
458 static int _ui_app_appcore_low_battery(void *event_info, void *data)
459 {
460         Eina_List *l;
461         app_event_handler_h handler;
462         struct app_event_info event;
463
464         LOGI("_ui_app_appcore_low_battery");
465
466         event.type = APP_EVENT_LOW_BATTERY;
467         event.value = event_info;
468
469         EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) {
470                 handler->cb(&event, handler->data);
471         }
472
473         return APP_ERROR_NONE;
474 }
475
476 static int _ui_app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data)
477 {
478         Eina_List *l;
479         app_event_handler_h handler;
480         struct app_event_info event;
481
482         LOGI("_ui_app_appcore_rotation_event");
483
484         event.type = APP_EVENT_DEVICE_ORIENTATION_CHANGED;
485         event.value = event_info;
486
487         EINA_LIST_FOREACH(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED], l, handler) {
488                 handler->cb(&event, handler->data);
489         }
490
491         return APP_ERROR_NONE;
492 }
493
494 static int _ui_app_appcore_lang_changed(void *event_info, void *data)
495 {
496         Eina_List *l;
497         app_event_handler_h handler;
498         struct app_event_info event;
499
500         LOGI("_ui_app_appcore_lang_changed");
501
502         event.type = APP_EVENT_LANGUAGE_CHANGED;
503         event.value = event_info;
504
505         EINA_LIST_FOREACH(handler_list[APP_EVENT_LANGUAGE_CHANGED], l, handler) {
506                 handler->cb(&event, handler->data);
507         }
508
509         return APP_ERROR_NONE;
510 }
511
512 static int _ui_app_appcore_region_changed(void *event_info, void *data)
513 {
514         Eina_List *l;
515         app_event_handler_h handler;
516         struct app_event_info event;
517
518         if (event_info == NULL) {
519                 LOGI("receive empty event, ignore it");
520                 return APP_ERROR_NONE;
521         }
522
523         LOGI("_ui_app_appcore_region_changed");
524
525         event.type = APP_EVENT_REGION_FORMAT_CHANGED;
526         event.value = event_info;
527
528         EINA_LIST_FOREACH(handler_list[APP_EVENT_REGION_FORMAT_CHANGED], l, handler) {
529                 handler->cb(&event, handler->data);
530         }
531
532         return APP_ERROR_NONE;
533 }
534
535
536 static void _ui_app_set_appcore_event_cb(void)
537 {
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);
543 }
544
545 static void _ui_app_unset_appcore_event_cb(void)
546 {
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);
552 }
553
554 static int _ui_app_appcore_create(void *data)
555 {
556         LOGI("app_appcore_create");
557         struct ui_app_context *app_context = data;
558         app_create_cb create_cb;
559
560         if (app_context == NULL)
561                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
562
563         _ui_app_set_appcore_event_cb();
564
565         create_cb = app_context->callback->create;
566
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");
569
570         app_context->state = APP_STATE_RUNNING;
571
572         return APP_ERROR_NONE;
573 }
574
575 static int _ui_app_appcore_terminate(void *data)
576 {
577         LOGI("app_appcore_terminate");
578         struct ui_app_context *app_context = data;
579         app_terminate_cb terminate_cb;
580
581         if (app_context == NULL)
582                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
583
584         terminate_cb = app_context->callback->terminate;
585
586         if (terminate_cb != NULL)
587                 terminate_cb(app_context->data);
588
589         _ui_app_unset_appcore_event_cb();
590
591         app_finalizer_execute();
592
593         if (_initialized) {
594                 _free_handler_list();
595                 _initialized = 0;
596         }
597
598         return APP_ERROR_NONE;
599 }
600
601 static int _ui_app_appcore_pause(void *data)
602 {
603         LOGI("app_appcore_pause");
604         struct ui_app_context *app_context = data;
605         app_pause_cb pause_cb;
606
607         if (app_context == NULL)
608                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
609
610         pause_cb = app_context->callback->pause;
611
612         if (pause_cb != NULL)
613                 pause_cb(app_context->data);
614
615         return APP_ERROR_NONE;
616 }
617
618 static int _ui_app_appcore_resume(void *data)
619 {
620         LOGI("app_appcore_resume");
621         struct ui_app_context *app_context = data;
622         app_resume_cb resume_cb;
623
624         if (app_context == NULL)
625                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
626
627         resume_cb = app_context->callback->resume;
628
629         if (resume_cb != NULL)
630                 resume_cb(app_context->data);
631
632         return APP_ERROR_NONE;
633 }
634
635
636 static int _ui_app_appcore_reset(bundle *appcore_bundle, void *data)
637 {
638         LOGI("app_appcore_reset");
639         struct ui_app_context *app_context = data;
640         app_control_cb callback;
641         app_control_h app_control;
642
643         if (app_context == NULL)
644                 return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
645
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");
648
649         callback = app_context->callback->app_control;
650
651         if (callback != NULL)
652                 callback(app_control, app_context->data);
653
654         app_control_destroy(app_control);
655
656         return APP_ERROR_NONE;
657 }
658
659 int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data)
660 {
661         struct ui_app_context app_context = {
662                 .package = NULL,
663                 .app_name = NULL,
664                 .state = APP_STATE_NOT_RUNNING,
665                 .callback = callback,
666                 .data = user_data
667         };
668
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,
676         };
677
678         if (argc < 1 || argv == NULL || callback == NULL)
679                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
680
681         if (callback->create == NULL)
682                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered");
683
684         if (app_context.state != APP_STATE_NOT_RUNNING)
685                 return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL);
686
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");
689
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");
693         }
694
695         app_context.state = APP_STATE_CREATING;
696
697         LOGI("app_efl_main");
698         appcore_efl_main(app_context.app_name, &argc, &argv, &appcore_context);
699
700         free(app_context.package);
701         free(app_context.app_name);
702
703         return APP_ERROR_NONE;
704 }
705
706 void ui_app_exit(void)
707 {
708         app_efl_exit();
709 }
710
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)
712 {
713         app_event_handler_h handler;
714         Eina_List *l_itr;
715
716         if (!_initialized) {
717                 eina_init();
718                 _initialized = 1;
719         }
720
721         if (event_handler == NULL || callback == NULL)
722                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter");
723
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");
726
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");
730         }
731
732         handler = calloc(1, sizeof(struct app_event_handler));
733         if (!handler)
734                 return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler");
735
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);
740
741         *event_handler = handler;
742
743         return APP_ERROR_NONE;
744 }
745
746 int ui_app_remove_event_handler(app_event_handler_h event_handler)
747 {
748         app_event_handler_h handler;
749         app_event_type_e type;
750         Eina_List *l_itr;
751         Eina_List *l_next;
752
753         if (event_handler == NULL)
754                 return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null");
755
756         if (!_initialized) {
757                 LOGI("handler list is not initialized");
758                 return APP_ERROR_NONE;
759         }
760
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");
764
765         EINA_LIST_FOREACH_SAFE(handler_list[type], l_itr, l_next, handler) {
766                 if (handler == event_handler) {
767                         free(handler);
768                         handler_list[type] = eina_list_remove_list(handler_list[type], l_itr);
769                         return APP_ERROR_NONE;
770                 }
771         }
772
773         return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler");
774 }