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 <system_info.h>
42 #include "appcore_base.h"
43 #include "appcore_base_private.h"
44 #include "appcore_watchdog.h"
46 #define PATH_LOCALE "locale"
47 #define RESOURCED_FREEZER_PATH "/Org/Tizen/ResourceD/Freezer"
48 #define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
49 #define RESOURCED_FREEZER_SIGNAL "FreezerState"
50 #define SQLITE_FLUSH_MAX (1024 * 1024)
52 typedef struct _appcore_base_context {
63 } appcore_base_context;
65 typedef struct _appcore_base_event_node {
67 appcore_base_event_cb cb;
69 } appcore_base_event_node;
71 typedef struct _appcore_base_rotation {
75 enum appcore_base_rm rm;
78 } appcore_base_rotation;
85 static appcore_base_context __context;
86 static GList *__events;
87 static GDBusConnection *__bus;
88 static guint __suspend_dbus_handler_initialized;
89 static char *__locale_dir;
90 static appcore_base_rotation __rotation;
92 appcore_base_tizen_profile_t appcore_base_get_tizen_profile(void)
94 static appcore_base_tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
95 char *profile_name = NULL;
97 if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
100 system_info_get_platform_string("http://tizen.org/feature/profile",
102 if (profile_name == NULL)
105 switch (*profile_name) {
108 profile = TIZEN_PROFILE_MOBILE;
112 profile = TIZEN_PROFILE_WEARABLE;
116 profile = TIZEN_PROFILE_TV;
120 profile = TIZEN_PROFILE_IVI;
123 profile = TIZEN_PROFILE_COMMON;
132 static void __invoke_callback(void *event, int type)
134 GList *iter = __events;
137 appcore_base_event_node *node = iter->data;
139 if (node->type == type)
140 node->cb(event, node->data);
141 iter = g_list_next(iter);
145 static bool __exist_callback(int type)
147 GList *iter = __events;
150 appcore_base_event_node *node = iter->data;
152 if (node->type == type)
155 iter = g_list_next(iter);
161 static enum appcore_base_rm __get_rm(sensor_data_t data)
164 enum appcore_base_rm rm;
166 if (data.value_count <= 0) {
167 _ERR("Failed to get sensor data");
168 return APPCORE_BASE_RM_UNKNOWN;
171 event = data.values[0];
173 case AUTO_ROTATION_DEGREE_0:
174 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
176 case AUTO_ROTATION_DEGREE_90:
177 rm = APPCORE_BASE_RM_LANDSCAPE_NORMAL;
179 case AUTO_ROTATION_DEGREE_180:
180 rm = APPCORE_BASE_RM_PORTRAIT_REVERSE;
182 case AUTO_ROTATION_DEGREE_270:
183 rm = APPCORE_BASE_RM_LANDSCAPE_REVERSE;
186 rm = APPCORE_BASE_RM_UNKNOWN;
193 static void __lock_cb(keynode_t *node, void *user_data)
197 enum appcore_base_rm rm;
199 __rotation.lock = !vconf_keynode_get_bool(node);
200 if (__rotation.lock) {
201 _DBG("Rotation locked");
202 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
204 _DBG("Rotation unlocked");
205 r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data);
207 _ERR("Failed to get sensor data");
212 if (rm == APPCORE_BASE_RM_UNKNOWN) {
213 _ERR("Unknown mode");
218 if (__rotation.rm == rm)
221 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
223 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
226 static void __auto_rotation_changed_cb(sensor_t sensor, unsigned int event_type,
227 sensor_data_t *data, void *user_data)
229 enum appcore_base_rm rm;
237 if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
240 rm = __get_rm(*data);
241 if (rm == APPCORE_BASE_RM_UNKNOWN) {
242 _ERR("Unknown mode");
246 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
248 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
251 static void __fini_rotation(void)
253 if (!__rotation.initialized)
256 vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb);
257 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
258 sensord_stop(__rotation.conn);
259 sensord_disconnect(__rotation.conn);
262 __rotation.initialized = false;
265 static void __init_rotation(void)
271 if (__rotation.initialized)
274 sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
275 __rotation.conn = sensord_connect(sensor);
276 if (__rotation.conn < 0) {
277 _ERR("Failed to connect sensord");
281 r = sensord_register_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT,
282 SENSOR_INTERVAL_NORMAL, 0, __auto_rotation_changed_cb, NULL);
284 _ERR("Failed to register auto rotation change event");
285 sensord_disconnect(__rotation.conn);
289 r = sensord_start(__rotation.conn, 0);
291 _ERR("Failed to start sensord");
292 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
293 sensord_disconnect(__rotation.conn);
298 vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
299 vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb, NULL);
301 __rotation.lock = !lock;
302 __rotation.initialized = true;
305 static void __charger_status_changed_cb(keynode_t *keynode, void *user_data)
307 if (TIZEN_FEATURE_CHARGER_STATUS) {
308 __rotation.charger_status = vconf_keynode_get_int(keynode);
309 if (__rotation.charger_status) {
316 _DBG("charger status(%d)", __rotation.charger_status);
320 static void __unregister_rotation_changed_event(void)
326 if (__rotation.ref > 1)
330 if (TIZEN_FEATURE_CHARGER_STATUS) {
331 vconf_ignore_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
332 __charger_status_changed_cb);
338 static void __register_rotation_changed_event(void)
340 if (__rotation.ref) {
345 if (TIZEN_FEATURE_CHARGER_STATUS) {
346 vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
347 &__rotation.charger_status);
348 vconf_notify_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
349 __charger_status_changed_cb, NULL);
350 if (__rotation.charger_status)
359 static void __on_low_memory(keynode_t *key, void *data)
363 val = vconf_keynode_get_int(key);
365 if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
366 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_MEMORY);
371 static void __on_low_battery(keynode_t *key, void *data)
375 val = vconf_keynode_get_int(key);
377 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
378 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_BATTERY);
381 static void __destroy_lang_info(gpointer data)
383 struct lang_info_s *info = (struct lang_info_s *)data;
389 g_list_free_full(info->list, free);
395 static struct lang_info_s *__create_lang_info(const char *lang)
397 struct lang_info_s *info;
399 info = calloc(1, sizeof(struct lang_info_s));
401 _ERR("Out of memory");
405 info->parent = strdup(lang);
406 if (info->parent == NULL) {
407 _ERR("Out of memory");
415 static gint __compare_langs(gconstpointer a, gconstpointer b)
423 static char *__get_string_before(const char *str, const char *delim)
429 dup_str = strdup(str);
433 token = strtok(dup_str, delim);
439 new_str = strdup(token);
445 static GHashTable *__get_lang_table(void)
449 struct dirent *dentry;
451 struct stat stat_buf;
454 struct lang_info_s *info;
456 if (__locale_dir == NULL || __locale_dir[0] == '\0')
459 table = g_hash_table_new_full(g_str_hash, g_str_equal,
460 NULL, __destroy_lang_info);
462 _ERR("Out of memory");
466 dp = opendir(__locale_dir);
468 g_hash_table_destroy(table);
472 while ((dentry = readdir(dp)) != NULL) {
473 if (!strcmp(dentry->d_name, ".") ||
474 !strcmp(dentry->d_name, ".."))
477 snprintf(buf, sizeof(buf), "%s/%s",
478 __locale_dir, dentry->d_name);
479 ret = stat(buf, &stat_buf);
480 if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
483 parent_lang = __get_string_before(dentry->d_name, "_");
484 if (parent_lang == NULL) {
485 _ERR("Out of memory");
489 info = g_hash_table_lookup(table, parent_lang);
491 info = __create_lang_info(parent_lang);
496 g_hash_table_insert(table, info->parent, info);
498 info->list = g_list_append(info->list, strdup(dentry->d_name));
506 static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
508 struct lang_info_s *info;
510 char *parent_lang = NULL;
516 list = g_list_append(list, strdup(lang));
518 extract_lang = __get_string_before(lang, ".");
519 if (extract_lang == NULL)
522 found = g_list_find_custom(list, extract_lang, __compare_langs);
524 list = g_list_remove_link(list, found);
525 list = g_list_concat(list, found);
529 parent_lang = __get_string_before(extract_lang, "_");
530 if (parent_lang == NULL)
533 info = g_hash_table_lookup(table, parent_lang);
537 found = g_list_find_custom(info->list, extract_lang, __compare_langs);
539 info->list = g_list_remove_link(info->list, found);
540 list = g_list_concat(list, found);
544 found = g_list_find_custom(info->list, parent_lang, __compare_langs);
546 info->list = g_list_remove_link(info->list, found);
547 list = g_list_concat(list, found);
551 found = g_list_first(info->list);
553 info->list = g_list_remove_link(info->list, found);
554 list = g_list_concat(list, found);
566 static GList *__split_language(const char *lang)
572 dup_lang = strdup(lang);
573 if (dup_lang == NULL) {
574 _ERR("Out of memory");
578 token = strtok(dup_lang, ":");
579 while (token != NULL) {
580 list = g_list_append(list, strdup(token));
581 token = strtok(NULL, ":");
588 static GList *__append_default_langs(GList *list)
590 const char *langs[] = {"en_US", "en_GB", "en"};
594 for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
595 found = g_list_find_custom(list, langs[i], __compare_langs);
597 list = g_list_append(list, strdup(langs[i]));
603 static char *__get_language(const char *lang)
607 GList *lang_list = NULL;
610 char buf[LINE_MAX] = {'\0'};
613 list = __split_language(lang);
617 table = __get_lang_table();
619 g_list_free_full(list, free);
623 iter = g_list_first(list);
625 language = (char *)iter->data;
626 lang_list = __append_langs(language, lang_list, table);
627 iter = g_list_next(iter);
629 g_list_free_full(list, free);
630 g_hash_table_destroy(table);
632 lang_list = __append_default_langs(lang_list);
633 iter = g_list_first(lang_list);
635 language = (char *)iter->data;
637 if (buf[0] == '\0') {
638 snprintf(buf, sizeof(buf), "%s", language);
640 n = sizeof(buf) - strlen(buf) - 1;
641 strncat(buf, ":", n);
642 n = sizeof(buf) - strlen(buf) - 1;
643 strncat(buf, language, n);
646 iter = g_list_next(iter);
648 g_list_free_full(lang_list, free);
653 static void __update_lang(void)
659 lang = vconf_get_str(VCONFKEY_LANGSET);
661 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
662 language = __get_language(lang);
664 _DBG("*****language(%s)", language);
665 setenv("LANGUAGE", language, 1);
668 setenv("LANGUAGE", lang, 1);
670 setenv("LANG", lang, 1);
671 setenv("LC_MESSAGES", lang, 1);
672 r = setlocale(LC_ALL, "");
674 r = setlocale(LC_ALL, "en_US.UTF-8");
676 _DBG("*****appcore setlocale=%s\n", r);
678 _DBG("*****appcore setlocale=\"C\"");
679 setenv("LC_ALL", "C", 1);
680 r = setlocale(LC_ALL, "");
682 _ERR("failed to setlocale");
689 static void __update_region(void)
694 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
696 setenv("LC_CTYPE", region, 1);
697 setenv("LC_NUMERIC", region, 1);
698 setenv("LC_TIME", region, 1);
699 setenv("LC_COLLATE", region, 1);
700 setenv("LC_MONETARY", region, 1);
701 setenv("LC_PAPER", region, 1);
702 setenv("LC_NAME", region, 1);
703 setenv("LC_ADDRESS", region, 1);
704 setenv("LC_TELEPHONE", region, 1);
705 setenv("LC_MEASUREMENT", region, 1);
706 setenv("LC_IDENTIFICATION", region, 1);
707 r = setlocale(LC_ALL, "");
709 _DBG("*****appcore setlocale=%s\n", r);
711 _DBG("*****appcore setlocale=\"C\"");
712 setenv("LC_ALL", "C", 1);
713 r = setlocale(LC_ALL, "");
715 _ERR("failed to setlocale");
722 static void __on_language_change(keynode_t *key, void *data)
727 g_source_remove(__context.sid);
731 val = vconf_keynode_get_str(key);
734 __invoke_callback((void *)val, APPCORE_BASE_EVENT_LANG_CHANGE);
737 static void __on_region_change(keynode_t *key, void *data)
742 name = vconf_keynode_get_name(key);
746 if (strcmp(name, VCONFKEY_REGIONFORMAT) &&
747 strcmp(name, VCONFKEY_REGIONFORMAT_TIME1224))
750 val = vconf_get_str(VCONFKEY_REGIONFORMAT);
753 __invoke_callback((void *)val, APPCORE_BASE_EVENT_REGION_CHANGE);
757 static gboolean __invoke_lang_change(gpointer data)
763 lang = getenv("LANG");
765 return G_SOURCE_REMOVE;
767 __invoke_callback((void *)lang, APPCORE_BASE_EVENT_LANG_CHANGE);
769 return G_SOURCE_REMOVE;
772 static void __verify_language(void)
775 const char *env_lang;
777 env_lang = getenv("LANG");
781 lang = vconf_get_str(VCONFKEY_LANGSET);
785 if (strcmp(env_lang, lang) != 0) {
786 _INFO("LANG(%s), LANGSET(%s)", env_lang, lang);
787 __context.sid = g_idle_add(__invoke_lang_change, NULL);
793 static gboolean __flush_memory(gpointer data)
795 int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
797 if (__context.ops.trim_memory)
798 __context.ops.trim_memory(__context.data);
802 if (!__context.allowed_bg && !__context.suspended_state) {
803 _DBG("[__SUSPEND__] flush case");
804 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
805 __context.suspended_state = true;
811 static void __add_suspend_timer(void)
813 __context.tid = g_timeout_add_seconds(5, __flush_memory, NULL);
816 static void __remove_suspend_timer(void)
818 if (__context.tid > 0) {
819 g_source_remove(__context.tid);
824 static void __on_receive_suspend_signal(GDBusConnection *connection,
825 const gchar *sender_name,
826 const gchar *object_path,
827 const gchar *interface_name,
828 const gchar *signal_name,
829 GVariant *parameters,
832 gint suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
836 if (g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL) == 0) {
837 g_variant_get(parameters, "(ii)", &status, &pid);
838 if (pid == getpid() && status == 0) {
839 if (!__context.allowed_bg && __context.suspended_state) {
840 __remove_suspend_timer();
841 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
842 __context.suspended_state = false;
843 __add_suspend_timer();
849 static int __init_suspend_dbus_handler(void)
853 if (__suspend_dbus_handler_initialized)
857 __bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
859 _ERR("Failed to connect to the D-BUS daemon: %s",
866 __suspend_dbus_handler_initialized = g_dbus_connection_signal_subscribe(
869 RESOURCED_FREEZER_INTERFACE,
870 RESOURCED_FREEZER_SIGNAL,
871 RESOURCED_FREEZER_PATH,
873 G_DBUS_SIGNAL_FLAGS_NONE,
874 __on_receive_suspend_signal,
877 if (__suspend_dbus_handler_initialized == 0) {
878 _ERR("g_dbus_connection_signal_subscribe() is failed.");
882 _DBG("[__SUSPEND__] suspend signal initialized");
887 static void __fini_suspend_dbus_handler(void)
892 if (__suspend_dbus_handler_initialized) {
893 g_dbus_connection_signal_unsubscribe(__bus,
894 __suspend_dbus_handler_initialized);
895 __suspend_dbus_handler_initialized = 0;
898 g_object_unref(__bus);
902 static gboolean __init_suspend(gpointer data)
904 __init_suspend_dbus_handler();
905 return G_SOURCE_REMOVE;
908 static int __get_locale_resource_dir(char *locale_dir, int size)
910 const char *res_path;
912 res_path = aul_get_app_resource_path();
913 if (res_path == NULL) {
914 _ERR("Failed to get resource path");
918 snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
919 if (access(locale_dir, R_OK) != 0)
920 _DBG("%s does not exist", locale_dir);
925 static int __get_app_name(const char *appid, char **name)
927 char *name_token = NULL;
932 /* com.vendor.name -> name */
933 name_token = strrchr(appid, '.');
934 if (name_token == NULL)
939 *name = strdup(name_token);
946 static int __set_i18n(const char *domain, const char *dir)
950 if (domain == NULL) {
958 __locale_dir = strdup(dir);
964 r = setlocale(LC_ALL, "");
965 /* if locale is not set properly, try to set "en_US" again */
967 r = setlocale(LC_ALL, "en_US.UTF-8");
969 _DBG("*****appcore setlocale=%s\n", r);
972 _ERR("appcore: setlocale() error");
973 _DBG("*****appcore setlocale=\"C\"");
974 setenv("LC_ALL", "C", 1);
975 r = setlocale(LC_ALL, "");
977 _ERR("failed to setlocale");
980 r = bindtextdomain(domain, dir);
982 _ERR("appcore: bindtextdomain() error");
984 r = textdomain(domain);
986 _ERR("appcore: textdomain() error");
991 EXPORT_API int appcore_base_on_set_i18n(void)
994 char locale_dir[PATH_MAX];
995 char appid[PATH_MAX];
998 r = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
1000 _ERR("Failed to get application ID - pid(%d)", getpid());
1004 r = __get_app_name(appid, &name);
1008 r = __get_locale_resource_dir(locale_dir, sizeof(locale_dir));
1014 r = __set_i18n(name, locale_dir);
1025 EXPORT_API int appcore_base_set_i18n(const char *domain_name, const char *dir_name)
1027 return __set_i18n(domain_name, dir_name);
1030 static void __set_default_events(void)
1034 vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
1035 r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
1037 vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
1038 vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
1041 static void __unset_default_events(void)
1045 vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
1046 r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
1048 vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
1049 vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
1052 EXPORT_API int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data)
1057 __context.ops = ops;
1058 __context.argc = argc;
1059 __context.argv = argv;
1060 __context.data = data;
1062 __context.suspended_state = false;
1063 __context.allowed_bg = false;
1065 if (__context.ops.init)
1066 __context.ops.init(argc, argv, data);
1068 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
1069 g_idle_add(__init_suspend, NULL);
1071 if (!__context.dirty) {
1072 __context.dirty = true;
1074 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
1075 if (__exist_callback(i)) {
1076 if (__context.ops.set_event)
1077 __context.ops.set_event(i, __context.data);
1082 __verify_language();
1083 __set_default_events();
1084 if (__context.ops.set_i18n)
1085 __context.ops.set_i18n(__context.data);
1087 if (__context.ops.create) {
1088 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
1089 r = __context.ops.create(__context.data);
1090 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1092 aul_status_update(STATUS_DYING);
1097 if (__context.ops.run)
1098 __context.ops.run(__context.data);
1103 EXPORT_API void appcore_base_fini(void)
1107 aul_status_update(STATUS_DYING);
1108 appcore_watchdog_disable();
1109 if (__context.ops.terminate) {
1110 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE");
1111 __context.ops.terminate(__context.data);
1112 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1115 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
1116 if (__exist_callback(i)) {
1117 if (__context.ops.unset_event)
1118 __context.ops.unset_event(i, __context.data);
1122 __unset_default_events();
1124 if (__context.sid) {
1125 g_source_remove(__context.sid);
1129 g_list_free_full(__events, free);
1132 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
1133 __fini_suspend_dbus_handler();
1137 __locale_dir = NULL;
1140 __context.dirty = false;
1142 if (__context.ops.finish)
1143 __context.ops.finish();
1146 EXPORT_API int appcore_base_flush_memory(void)
1148 if (__context.ops.trim_memory)
1149 __context.ops.trim_memory(__context.data);
1154 EXPORT_API int appcore_base_on_receive(aul_type type, bundle *b)
1161 _DBG("[APP %d] AUL event: AUL_START", getpid());
1162 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1163 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
1164 if (bg && !strcmp(bg, "ALLOWED_BG")) {
1165 _DBG("[__SUSPEND__] allowed background");
1166 __context.allowed_bg = true;
1167 __remove_suspend_timer();
1171 if (__context.ops.control) {
1172 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESET");
1173 __context.ops.control(b, __context.data);
1174 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1178 _DBG("[APP %d] AUL event: AUL_RESUME", getpid());
1179 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1180 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
1181 if (bg && !strcmp(bg, "ALLOWED_BG")) {
1182 _DBG("[__SUSPEND__] allowed background");
1183 __context.allowed_bg = true;
1184 __remove_suspend_timer();
1189 _DBG("[APP %d] AUL event: AUL_TERMINATE", getpid());
1190 aul_status_update(STATUS_DYING);
1191 if (!__context.allowed_bg)
1192 __remove_suspend_timer();
1194 if (__context.ops.exit)
1195 __context.ops.exit(__context.data);
1197 case AUL_TERMINATE_BGAPP:
1198 _DBG("[APP %d] AUL event: AUL_TERMINATE_BGAPP", getpid());
1199 if (!__context.allowed_bg)
1200 __remove_suspend_timer();
1203 _DBG("[APP %d] AUL event: AUL_WAKE", getpid());
1204 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1205 if (!__context.allowed_bg &&
1206 __context.suspended_state) {
1207 int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
1208 __remove_suspend_timer();
1209 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
1210 __context.suspended_state = false;
1215 _DBG("[APP %d] AUL event: AUL_SUSPEND", getpid());
1216 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1217 if (!__context.allowed_bg &&
1218 !__context.suspended_state) {
1219 __remove_suspend_timer();
1220 __flush_memory(NULL);
1224 case AUL_UPDATE_REQUESTED:
1225 _DBG("[APP %d] AUL event: AUL_UPDATE_REQUESTED", getpid());
1226 __invoke_callback((void *)&dummy, APPCORE_BASE_EVENT_UPDATE_REQUESTED);
1229 _DBG("[APP %d] AUL event: %d", getpid(), type);
1237 EXPORT_API int appcore_base_on_create(void)
1241 r = aul_launch_init(__context.ops.receive, NULL);
1243 _ERR("Aul init failed: %d", r);
1247 r = aul_launch_argv_handler(__context.argc, __context.argv);
1249 _ERR("Aul argv handler failed: %d", r);
1256 EXPORT_API int appcore_base_on_control(bundle *b)
1261 EXPORT_API int appcore_base_on_terminate()
1268 EXPORT_API void appcore_base_on_set_event(enum appcore_base_event event)
1271 case APPCORE_BASE_EVENT_LOW_BATTERY:
1272 vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL);
1274 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1275 __register_rotation_changed_event();
1277 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1286 EXPORT_API void appcore_base_on_unset_event(enum appcore_base_event event)
1289 case APPCORE_BASE_EVENT_LOW_BATTERY:
1290 vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
1292 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1293 __unregister_rotation_changed_event();
1295 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1302 EXPORT_API int appcore_base_on_trim_memory(void)
1304 int (*sqlite3_free_heap_memory)(int);
1306 sqlite3_free_heap_memory = dlsym(RTLD_DEFAULT,
1307 "sqlite3_release_memory");
1308 if (sqlite3_free_heap_memory)
1309 sqlite3_free_heap_memory(SQLITE_FLUSH_MAX);
1316 EXPORT_API appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
1317 appcore_base_event_cb cb, void *data)
1319 appcore_base_event_node *node;
1321 if (__context.dirty && !__exist_callback(event)) {
1322 if (__context.ops.set_event)
1323 __context.ops.set_event(event, __context.data);
1326 node = malloc(sizeof(appcore_base_event_node));
1334 __events = g_list_append(__events, node);
1339 EXPORT_API int appcore_base_remove_event(appcore_base_event_h handle)
1341 appcore_base_event_node *node = handle;
1342 enum appcore_base_event event;
1344 if (!node || !g_list_find(__events, node))
1348 __events = g_list_remove(__events, node);
1350 if (__context.dirty && !__exist_callback(event)) {
1351 if (__context.ops.unset_event)
1352 __context.ops.unset_event(event, __context.data);
1358 EXPORT_API int appcore_base_raise_event(void *event, enum appcore_base_event type)
1360 __invoke_callback(event, type);
1364 EXPORT_API int appcore_base_get_rotation_state(enum appcore_base_rm *curr)
1369 if (!__rotation.ref)
1372 *curr = __rotation.rm;
1376 EXPORT_API bool appcore_base_is_bg_allowed(void)
1378 return __context.allowed_bg;
1381 EXPORT_API bool appcore_base_is_suspended(void)
1383 return __context.suspended_state;
1386 EXPORT_API void appcore_base_toggle_suspended_state(void)
1388 __context.suspended_state ^= __context.suspended_state;
1391 EXPORT_API void appcore_base_exit(void)
1393 if (__context.ops.exit)
1394 __context.ops.exit(__context.data);
1397 EXPORT_API void appcore_base_add_suspend_timer(void)
1399 __add_suspend_timer();
1402 EXPORT_API void appcore_base_remove_suspend_timer(void)
1404 __remove_suspend_timer();
1407 EXPORT_API void appcore_base_set_display_state(int display_state)
1409 __context.display_state = display_state;
1412 EXPORT_API int appcore_base_get_display_state(void)
1414 return __context.display_state;
1417 static int __on_receive(aul_type type, bundle *b, void *data)
1419 return appcore_base_on_receive(type, b);
1422 static int __on_create(void *data)
1424 return appcore_base_on_create();
1427 static int __on_control(bundle *b, void *data)
1429 return appcore_base_on_control(b);
1432 static int __on_terminate(void *data)
1434 return appcore_base_on_terminate();
1437 static int __on_set_i18n(void *data)
1439 return appcore_base_on_set_i18n();
1442 static void __on_set_event(enum appcore_base_event event, void *data)
1444 appcore_base_on_set_event(event);
1447 static void __on_unset_event(enum appcore_base_event event, void *data)
1449 appcore_base_on_unset_event(event);
1452 static void __on_trim_memory(void *data)
1454 appcore_base_on_trim_memory();
1457 EXPORT_API appcore_base_ops appcore_base_get_default_ops(void)
1459 appcore_base_ops ops;
1461 ops.create = __on_create;
1462 ops.control = __on_control;
1463 ops.terminate = __on_terminate;
1464 ops.receive = __on_receive;
1465 ops.set_i18n = __on_set_i18n;
1470 ops.set_event = __on_set_event;
1471 ops.unset_event = __on_unset_event;
1472 ops.trim_memory = __on_trim_memory;