2 * Copyright (c) 2016 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.
24 #include <sys/types.h>
30 #include <linux/limits.h>
37 #include <bundle_internal.h>
38 #include <sensor_internal.h>
40 #include "appcore_base.h"
41 #include "appcore_base_private.h"
43 #define PATH_LOCALE "locale"
44 #define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
45 #define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
46 #define RESOURCED_FREEZER_SIGNAL "FreezerState"
48 typedef struct _appcore_base_context {
57 } appcore_base_context;
59 typedef struct _appcore_base_event_node {
61 appcore_base_event_cb cb;
63 } appcore_base_event_node;
65 typedef struct _appcore_base_rotation {
69 enum appcore_base_rm rm;
70 } appcore_base_rotation;
77 static appcore_base_context __context;
78 static GList *__events;
79 static GDBusConnection *__bus;
80 static guint __suspend_dbus_handler_initialized;
81 static char *__locale_dir;
82 static appcore_base_rotation __rotation;
84 static void __invoke_callback(void *event, int type)
86 GList *iter = __events;
89 appcore_base_event_node *node = iter->data;
91 if (node->type == type)
92 node->cb(event, node->data);
93 iter = g_list_next(iter);
97 static bool __exist_callback(int type)
99 GList *iter = __events;
102 appcore_base_event_node *node = iter->data;
104 if (node->type == type)
107 iter = g_list_next(iter);
113 static enum appcore_base_rm __get_rm(sensor_data_t data)
116 enum appcore_base_rm rm;
118 if (data.value_count <= 0) {
119 _ERR("Failed to get sensor data");
120 return APPCORE_BASE_RM_UNKNOWN;
123 event = data.values[0];
125 case AUTO_ROTATION_DEGREE_0:
126 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
128 case AUTO_ROTATION_DEGREE_90:
129 rm = APPCORE_BASE_RM_LANDSCAPE_NORMAL;
131 case AUTO_ROTATION_DEGREE_180:
132 rm = APPCORE_BASE_RM_PORTRAIT_REVERSE;
134 case AUTO_ROTATION_DEGREE_270:
135 rm = APPCORE_BASE_RM_LANDSCAPE_REVERSE;
138 rm = APPCORE_BASE_RM_UNKNOWN;
145 static void __lock_cb(keynode_t *node, void *user_data)
149 enum appcore_base_rm rm;
151 __rotation.lock = !vconf_keynode_get_bool(node);
152 if (__rotation.lock) {
153 _DBG("Rotation locked");
154 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
156 _DBG("Rotation unlocked");
157 r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data);
159 _ERR("Failed to get sensor data");
164 if (rm == APPCORE_BASE_RM_UNKNOWN) {
165 _ERR("Unknown mode");
170 if (__rotation.rm == rm)
173 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
175 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
178 static void __auto_rotation_changed_cb(sensor_t sensor, unsigned int event_type,
179 sensor_data_t *data, void *user_data)
181 enum appcore_base_rm rm;
189 if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
192 rm = __get_rm(*data);
193 if (rm == APPCORE_BASE_RM_UNKNOWN) {
194 _ERR("Unknown mode");
198 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
200 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
203 static void __unregister_rotation_changed_event(void)
209 if (__rotation.ref > 1)
212 vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb);
213 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
214 sensord_stop(__rotation.conn);
215 sensord_disconnect(__rotation.conn);
221 static void __register_rotation_changed_event(void)
227 if (__rotation.ref) {
232 sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
233 __rotation.conn = sensord_connect(sensor);
234 if (__rotation.conn < 0) {
235 _ERR("Failed to connect sensord");
239 r = sensord_register_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT,
240 SENSOR_INTERVAL_NORMAL, 0, __auto_rotation_changed_cb, NULL);
242 _ERR("Failed to register auto rotation change event");
243 sensord_disconnect(__rotation.conn);
247 r = sensord_start(__rotation.conn, 0);
249 _ERR("Failed to start sensord");
250 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
251 sensord_disconnect(__rotation.conn);
256 vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
257 vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb, NULL);
259 __rotation.lock = !lock;
263 static void __on_low_memory(keynode_t *key, void *data)
267 val = vconf_keynode_get_int(key);
269 if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
270 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_MEMORY);
275 static void __on_low_battery(keynode_t *key, void *data)
279 val = vconf_keynode_get_int(key);
281 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
282 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_BATTERY);
285 static void __destroy_lang_info(gpointer data)
287 struct lang_info_s *info = (struct lang_info_s *)data;
293 g_list_free_full(info->list, free);
299 static struct lang_info_s *__create_lang_info(const char *lang)
301 struct lang_info_s *info;
303 info = calloc(1, sizeof(struct lang_info_s));
305 _ERR("Out of memory");
309 info->parent = strdup(lang);
310 if (info->parent == NULL) {
311 _ERR("Out of memory");
319 static gint __compare_langs(gconstpointer a, gconstpointer b)
327 static char *__get_string_before(const char *str, const char *delim)
333 dup_str = strdup(str);
337 token = strtok(dup_str, delim);
343 new_str = strdup(token);
349 static GHashTable *__get_lang_table(void)
353 struct dirent *dentry;
355 struct stat stat_buf;
358 struct lang_info_s *info;
360 if (__locale_dir == NULL || __locale_dir[0] == '\0')
363 table = g_hash_table_new_full(g_str_hash, g_str_equal,
364 NULL, __destroy_lang_info);
366 _ERR("Out of memory");
370 dp = opendir(__locale_dir);
372 g_hash_table_destroy(table);
376 while ((dentry = readdir(dp)) != NULL) {
377 if (!strcmp(dentry->d_name, ".") ||
378 !strcmp(dentry->d_name, ".."))
381 snprintf(buf, sizeof(buf), "%s/%s",
382 __locale_dir, dentry->d_name);
383 ret = stat(buf, &stat_buf);
384 if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
387 parent_lang = __get_string_before(dentry->d_name, "_");
388 if (parent_lang == NULL) {
389 _ERR("Out of memory");
393 info = g_hash_table_lookup(table, parent_lang);
395 info = __create_lang_info(parent_lang);
400 g_hash_table_insert(table, info->parent, info);
402 info->list = g_list_append(info->list, strdup(dentry->d_name));
410 static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
412 struct lang_info_s *info;
414 char *parent_lang = NULL;
420 list = g_list_append(list, strdup(lang));
422 extract_lang = __get_string_before(lang, ".");
423 if (extract_lang == NULL)
426 found = g_list_find_custom(list, extract_lang, __compare_langs);
428 list = g_list_remove_link(list, found);
429 list = g_list_concat(list, found);
433 parent_lang = __get_string_before(extract_lang, "_");
434 if (parent_lang == NULL)
437 info = g_hash_table_lookup(table, parent_lang);
441 found = g_list_find_custom(info->list, extract_lang, __compare_langs);
443 info->list = g_list_remove_link(info->list, found);
444 list = g_list_concat(list, found);
448 found = g_list_find_custom(info->list, parent_lang, __compare_langs);
450 info->list = g_list_remove_link(info->list, found);
451 list = g_list_concat(list, found);
455 found = g_list_first(info->list);
457 info->list = g_list_remove_link(info->list, found);
458 list = g_list_concat(list, found);
470 static GList *__split_language(const char *lang)
476 dup_lang = strdup(lang);
477 if (dup_lang == NULL) {
478 _ERR("Out of memory");
482 token = strtok(dup_lang, ":");
483 while (token != NULL) {
484 list = g_list_append(list, strdup(token));
485 token = strtok(NULL, ":");
492 static GList *__append_default_langs(GList *list)
494 const char *langs[] = {"en_US", "en_GB", "en"};
498 for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
499 found = g_list_find_custom(list, langs[i], __compare_langs);
501 list = g_list_append(list, strdup(langs[i]));
507 static char *__get_language(const char *lang)
511 GList *lang_list = NULL;
514 char buf[LINE_MAX] = {'\0'};
517 list = __split_language(lang);
521 table = __get_lang_table();
523 g_list_free_full(list, free);
527 iter = g_list_first(list);
529 language = (char *)iter->data;
530 lang_list = __append_langs(language, lang_list, table);
531 iter = g_list_next(iter);
533 g_list_free_full(list, free);
534 g_hash_table_destroy(table);
536 lang_list = __append_default_langs(lang_list);
537 iter = g_list_first(lang_list);
539 language = (char *)iter->data;
541 if (buf[0] == '\0') {
542 snprintf(buf, sizeof(buf), "%s", language);
544 n = sizeof(buf) - strlen(buf) - 1;
545 strncat(buf, ":", n);
546 n = sizeof(buf) - strlen(buf) - 1;
547 strncat(buf, language, n);
550 iter = g_list_next(iter);
552 g_list_free_full(lang_list, free);
557 static void __update_lang(void)
563 lang = vconf_get_str(VCONFKEY_LANGSET);
565 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
566 language = __get_language(lang);
568 _DBG("*****language(%s)", language);
569 setenv("LANGUAGE", language, 1);
572 setenv("LANGUAGE", lang, 1);
574 setenv("LANG", lang, 1);
575 setenv("LC_MESSAGES", lang, 1);
576 r = setlocale(LC_ALL, "");
578 r = setlocale(LC_ALL, lang);
580 _DBG("*****appcore setlocale=%s\n", r);
586 static void __update_region(void)
591 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
593 setenv("LC_CTYPE", region, 1);
594 setenv("LC_NUMERIC", region, 1);
595 setenv("LC_TIME", region, 1);
596 setenv("LC_COLLATE", region, 1);
597 setenv("LC_MONETARY", region, 1);
598 setenv("LC_PAPER", region, 1);
599 setenv("LC_NAME", region, 1);
600 setenv("LC_ADDRESS", region, 1);
601 setenv("LC_TELEPHONE", region, 1);
602 setenv("LC_MEASUREMENT", region, 1);
603 setenv("LC_IDENTIFICATION", region, 1);
604 r = setlocale(LC_ALL, "");
606 _DBG("*****appcore setlocale=%s\n", r);
612 static void __on_language_change(keynode_t *key, void *data)
616 val = vconf_keynode_get_str(key);
619 __invoke_callback((void *)val, APPCORE_BASE_EVENT_LANG_CHANGE);
622 static void __on_region_change(keynode_t *key, void *data)
627 name = vconf_keynode_get_name(key);
628 if (name && !strcmp(name, VCONFKEY_REGIONFORMAT))
629 val = vconf_keynode_get_str(key);
632 __invoke_callback((void *)val, APPCORE_BASE_EVENT_REGION_CHANGE);
635 static gboolean __flush_memory(gpointer data)
637 int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
639 appcore_base_flush_memory();
642 if (!__context.allowed_bg && !__context.suspended_state) {
643 _DBG("[__SUSPEND__] flush case");
644 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
645 __context.suspended_state = true;
651 static void __add_suspend_timer(void)
653 __context.tid = g_timeout_add_seconds(5, __flush_memory, NULL);
656 static void __remove_suspend_timer(void)
658 if (__context.tid > 0) {
659 g_source_remove(__context.tid);
664 static void __on_receive_suspend_signal(GDBusConnection *connection,
665 const gchar *sender_name,
666 const gchar *object_path,
667 const gchar *interface_name,
668 const gchar *signal_name,
669 GVariant *parameters,
672 gint suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
676 if (g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL) == 0) {
677 g_variant_get(parameters, "(ii)", &status, &pid);
678 if (pid == getpid() && status == 0) {
679 if (!__context.allowed_bg && __context.suspended_state) {
680 __remove_suspend_timer();
681 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
682 __context.suspended_state = false;
683 __add_suspend_timer();
689 static int __init_suspend_dbus_handler(void)
693 if (__suspend_dbus_handler_initialized)
697 __bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
699 _ERR("Failed to connect to the D-BUS daemon: %s",
706 __suspend_dbus_handler_initialized = g_dbus_connection_signal_subscribe(
709 RESOURCED_FREEZER_INTERFACE,
710 RESOURCED_FREEZER_SIGNAL,
711 RESOURCED_FREEZER_PATH,
713 G_DBUS_SIGNAL_FLAGS_NONE,
714 __on_receive_suspend_signal,
717 if (__suspend_dbus_handler_initialized == 0) {
718 _ERR("g_dbus_connection_signal_subscribe() is failed.");
722 _DBG("[__SUSPEND__] suspend signal initialized");
727 static void __fini_suspend_dbus_handler(void)
732 if (__suspend_dbus_handler_initialized) {
733 g_dbus_connection_signal_unsubscribe(__bus,
734 __suspend_dbus_handler_initialized);
735 __suspend_dbus_handler_initialized = 0;
738 g_object_unref(__bus);
742 static int __get_locale_resource_dir(char *locale_dir, int size)
744 const char *res_path;
746 res_path = aul_get_app_resource_path();
747 if (res_path == NULL) {
748 _ERR("Failed to get resource path");
752 snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
753 if (access(locale_dir, R_OK) != 0)
754 _DBG("%s does not exist", locale_dir);
759 static int __get_app_name(const char *appid, char **name)
761 char *name_token = NULL;
766 /* com.vendor.name -> name */
767 name_token = strrchr(appid, '.');
768 if (name_token == NULL)
773 *name = strdup(name_token);
780 static int __set_i18n(const char *domain, const char *dir)
785 if (domain == NULL) {
793 __locale_dir = strdup(dir);
799 r = setlocale(LC_ALL, "");
800 /* if locale is not set properly, try again to set as language base */
802 lan = vconf_get_str(VCONFKEY_LANGSET);
804 r = setlocale(LC_ALL, lan);
805 _DBG("*****appcore setlocale=%s\n", r);
810 _ERR("appcore: setlocale() error");
812 r = bindtextdomain(domain, dir);
814 _ERR("appcore: bindtextdomain() error");
816 r = textdomain(domain);
818 _ERR("appcore: textdomain() error");
823 EXPORT_API int appcore_base_on_set_i18n(void)
826 char locale_dir[PATH_MAX];
827 char appid[PATH_MAX];
830 r = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
832 _ERR("Failed to get application ID - pid(%d)", getpid());
836 r = __get_app_name(appid, &name);
840 r = __get_locale_resource_dir(locale_dir, sizeof(locale_dir));
846 r = __set_i18n(name, locale_dir);
857 EXPORT_API int appcore_base_set_i18n(const char *domain_name, const char *dir_name)
859 return __set_i18n(domain_name, dir_name);
862 EXPORT_API int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data)
868 __context.argc = argc;
869 __context.argv = argv;
870 __context.data = data;
872 __context.suspended_state = false;
873 __context.allowed_bg = false;
875 if (__context.ops.init)
876 __context.ops.init(argc, argv, data);
878 if (__context.ops.set_i18n)
879 __context.ops.set_i18n(__context.data);
881 __init_suspend_dbus_handler();
883 if (!__context.dirty) {
884 __context.dirty = true;
886 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
887 if (__exist_callback(i)) {
888 if (__context.ops.set_event)
889 __context.ops.set_event(i, __context.data);
894 if (__context.ops.create) {
895 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
896 r = __context.ops.create(__context.data);
897 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
899 aul_status_update(STATUS_DYING);
904 if (__context.ops.run)
905 __context.ops.run(__context.data);
910 EXPORT_API void appcore_base_fini(void)
914 aul_status_update(STATUS_DYING);
915 if (__context.ops.terminate) {
916 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE");
917 __context.ops.terminate(__context.data);
918 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
921 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
922 if (__exist_callback(i)) {
923 if (__context.ops.unset_event)
924 __context.ops.unset_event(i, __context.data);
928 g_list_free_full(__events, free);
930 __fini_suspend_dbus_handler();
937 __context.dirty = false;
939 if (__context.ops.finish)
940 __context.ops.finish();
943 EXPORT_API int appcore_base_flush_memory(void)
949 EXPORT_API int appcore_base_on_receive(aul_type type, bundle *b)
952 const char **tep_path;
960 _DBG("[APP %d] AUL event: AUL_START", getpid());
961 tep_path = bundle_get_str_array(b, AUL_TEP_PATH, &len);
963 for (i = 0; i < len; i++) {
964 ret = aul_check_tep_mount(tep_path[i]);
966 _ERR("mount request not completed within 1 sec");
972 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
973 if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
974 _DBG("[__SUSPEND__] allowed background");
975 __context.allowed_bg = true;
976 __remove_suspend_timer();
979 if (__context.ops.control) {
980 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESET");
981 __context.ops.control(b, __context.data);
982 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
986 _DBG("[APP %d] AUL event: AUL_RESUME", getpid());
987 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
988 if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
989 _DBG("[__SUSPEND__] allowed background");
990 __context.allowed_bg = true;
991 __remove_suspend_timer();
995 _DBG("[APP %d] AUL event: AUL_TERMINATE", getpid());
996 aul_status_update(STATUS_DYING);
997 if (!__context.allowed_bg)
998 __remove_suspend_timer();
1000 if (__context.ops.exit)
1001 __context.ops.exit(__context.data);
1003 case AUL_TERMINATE_BGAPP:
1004 _DBG("[APP %d] AUL event: AUL_TERMINATE_BGAPP", getpid());
1005 if (!__context.allowed_bg)
1006 __remove_suspend_timer();
1009 _DBG("[APP %d] AUL event: AUL_WAKE", getpid());
1010 if (!__context.allowed_bg && __context.suspended_state) {
1011 int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
1012 __remove_suspend_timer();
1013 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
1014 __context.suspended_state = false;
1018 _DBG("[APP %d] AUL event: AUL_SUSPEND", getpid());
1019 if (!__context.allowed_bg && !__context.suspended_state) {
1020 __remove_suspend_timer();
1021 __flush_memory(NULL);
1024 case AUL_UPDATE_REQUESTED:
1025 _DBG("[APP %d] AUL event: AUL_UPDATE_REQUESTED", getpid());
1026 __invoke_callback((void *)&dummy, APPCORE_BASE_EVENT_UPDATE_REQUESTED);
1029 _DBG("[APP %d] AUL event: %d", getpid(), type);
1037 EXPORT_API int appcore_base_on_create(void)
1040 r = aul_launch_init(__context.ops.receive, NULL);
1042 _ERR("Aul init failed: %d", r);
1046 r = aul_launch_argv_handler(__context.argc, __context.argv);
1048 _ERR("Aul argv handler failed: %d", r);
1055 EXPORT_API int appcore_base_on_control(bundle *b)
1060 EXPORT_API int appcore_base_on_terminate()
1067 EXPORT_API void appcore_base_on_set_event(enum appcore_base_event event)
1072 case APPCORE_BASE_EVENT_LOW_MEMORY:
1073 vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
1075 case APPCORE_BASE_EVENT_LOW_BATTERY:
1076 vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL);
1078 case APPCORE_BASE_EVENT_LANG_CHANGE:
1079 vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
1081 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1082 __register_rotation_changed_event();
1084 case APPCORE_BASE_EVENT_REGION_CHANGE:
1085 r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
1089 vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
1091 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1100 EXPORT_API void appcore_base_on_unset_event(enum appcore_base_event event)
1105 case APPCORE_BASE_EVENT_LOW_MEMORY:
1106 vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
1108 case APPCORE_BASE_EVENT_LOW_BATTERY:
1109 vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
1111 case APPCORE_BASE_EVENT_LANG_CHANGE:
1112 vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
1114 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1115 __unregister_rotation_changed_event();
1117 case APPCORE_BASE_EVENT_REGION_CHANGE:
1118 r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
1121 vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
1123 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1130 EXPORT_API appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
1131 appcore_base_event_cb cb, void *data)
1133 appcore_base_event_node *node;
1135 if (__context.dirty && !__exist_callback(event)) {
1136 if (__context.ops.set_event)
1137 __context.ops.set_event(event, __context.data);
1140 node = malloc(sizeof(appcore_base_event_node));
1148 __events = g_list_append(__events, node);
1153 EXPORT_API int appcore_base_remove_event(appcore_base_event_h handle)
1155 appcore_base_event_node *node = handle;
1156 enum appcore_base_event event;
1158 if (!node || !g_list_find(__events, node))
1162 __events = g_list_remove(__events, node);
1164 if (__context.dirty && !__exist_callback(event)) {
1165 if (__context.ops.unset_event)
1166 __context.ops.unset_event(event, __context.data);
1172 EXPORT_API int appcore_base_raise_event(void *event, enum appcore_base_event type)
1174 __invoke_callback(event, type);
1178 EXPORT_API int appcore_base_get_rotation_state(enum appcore_base_rm *curr)
1183 if (!__rotation.ref)
1186 *curr = __rotation.rm;
1190 EXPORT_API bool appcore_base_is_bg_allowed(void)
1192 return __context.allowed_bg;
1195 EXPORT_API bool appcore_base_is_suspended(void)
1197 return __context.suspended_state;
1200 EXPORT_API void appcore_base_toggle_suspended_state(void)
1202 __context.suspended_state ^= __context.suspended_state;
1205 EXPORT_API void appcore_base_exit(void)
1207 if (__context.ops.exit)
1208 __context.ops.exit(__context.data);
1211 static int __on_receive(aul_type type, bundle *b, void *data)
1213 return appcore_base_on_receive(type, b);
1216 static int __on_create(void *data)
1218 return appcore_base_on_create();
1221 static int __on_control(bundle *b, void *data)
1223 return appcore_base_on_control(b);
1226 static int __on_terminate(void *data)
1228 return appcore_base_on_terminate();
1231 static int __on_set_i18n(void *data)
1233 return appcore_base_on_set_i18n();
1236 static void __on_set_event(enum appcore_base_event event, void *data)
1238 return appcore_base_on_set_event(event);
1241 static void __on_unset_event(enum appcore_base_event event, void *data)
1243 return appcore_base_on_unset_event(event);
1246 EXPORT_API appcore_base_ops appcore_base_get_default_ops(void)
1248 appcore_base_ops ops;
1250 ops.create = __on_create;
1251 ops.control = __on_control;
1252 ops.terminate = __on_terminate;
1253 ops.receive = __on_receive;
1254 ops.set_i18n = __on_set_i18n;
1259 ops.set_event = __on_set_event;
1260 ops.unset_event = __on_unset_event;