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>
41 #include "appcore_base.h"
42 #include "appcore_base_private.h"
44 #define PATH_LOCALE "locale"
45 #define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
46 #define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
47 #define RESOURCED_FREEZER_SIGNAL "FreezerState"
48 #define SQLITE_FLUSH_MAX (1024 * 1024)
50 typedef struct _appcore_base_context {
60 } appcore_base_context;
62 typedef struct _appcore_base_event_node {
64 appcore_base_event_cb cb;
66 } appcore_base_event_node;
68 typedef struct _appcore_base_rotation {
72 enum appcore_base_rm rm;
73 } appcore_base_rotation;
80 static appcore_base_context __context;
81 static GList *__events;
82 static GDBusConnection *__bus;
83 static guint __suspend_dbus_handler_initialized;
84 static char *__locale_dir;
85 static appcore_base_rotation __rotation;
87 appcore_base_tizen_profile_t appcore_base_get_tizen_profile(void)
89 static appcore_base_tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
90 char *profile_name = NULL;
92 if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
95 system_info_get_platform_string("http://tizen.org/feature/profile",
97 if (profile_name == NULL)
100 switch (*profile_name) {
103 profile = TIZEN_PROFILE_MOBILE;
107 profile = TIZEN_PROFILE_WEARABLE;
111 profile = TIZEN_PROFILE_TV;
115 profile = TIZEN_PROFILE_IVI;
118 profile = TIZEN_PROFILE_COMMON;
127 static void __invoke_callback(void *event, int type)
129 GList *iter = __events;
132 appcore_base_event_node *node = iter->data;
134 if (node->type == type)
135 node->cb(event, node->data);
136 iter = g_list_next(iter);
140 static bool __exist_callback(int type)
142 GList *iter = __events;
145 appcore_base_event_node *node = iter->data;
147 if (node->type == type)
150 iter = g_list_next(iter);
156 static enum appcore_base_rm __get_rm(sensor_data_t data)
159 enum appcore_base_rm rm;
161 if (data.value_count <= 0) {
162 _ERR("Failed to get sensor data");
163 return APPCORE_BASE_RM_UNKNOWN;
166 event = data.values[0];
168 case AUTO_ROTATION_DEGREE_0:
169 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
171 case AUTO_ROTATION_DEGREE_90:
172 rm = APPCORE_BASE_RM_LANDSCAPE_NORMAL;
174 case AUTO_ROTATION_DEGREE_180:
175 rm = APPCORE_BASE_RM_PORTRAIT_REVERSE;
177 case AUTO_ROTATION_DEGREE_270:
178 rm = APPCORE_BASE_RM_LANDSCAPE_REVERSE;
181 rm = APPCORE_BASE_RM_UNKNOWN;
188 static void __lock_cb(keynode_t *node, void *user_data)
192 enum appcore_base_rm rm;
194 __rotation.lock = !vconf_keynode_get_bool(node);
195 if (__rotation.lock) {
196 _DBG("Rotation locked");
197 rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
199 _DBG("Rotation unlocked");
200 r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data);
202 _ERR("Failed to get sensor data");
207 if (rm == APPCORE_BASE_RM_UNKNOWN) {
208 _ERR("Unknown mode");
213 if (__rotation.rm == rm)
216 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
218 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
221 static void __auto_rotation_changed_cb(sensor_t sensor, unsigned int event_type,
222 sensor_data_t *data, void *user_data)
224 enum appcore_base_rm rm;
232 if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
235 rm = __get_rm(*data);
236 if (rm == APPCORE_BASE_RM_UNKNOWN) {
237 _ERR("Unknown mode");
241 _DBG("Rotation: %d -> %d", __rotation.rm, rm);
243 __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
246 static void __unregister_rotation_changed_event(void)
252 if (__rotation.ref > 1)
255 vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb);
256 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
257 sensord_stop(__rotation.conn);
258 sensord_disconnect(__rotation.conn);
264 static void __register_rotation_changed_event(void)
270 if (__rotation.ref) {
275 sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
276 __rotation.conn = sensord_connect(sensor);
277 if (__rotation.conn < 0) {
278 _ERR("Failed to connect sensord");
282 r = sensord_register_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT,
283 SENSOR_INTERVAL_NORMAL, 0, __auto_rotation_changed_cb, NULL);
285 _ERR("Failed to register auto rotation change event");
286 sensord_disconnect(__rotation.conn);
290 r = sensord_start(__rotation.conn, 0);
292 _ERR("Failed to start sensord");
293 sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
294 sensord_disconnect(__rotation.conn);
299 vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
300 vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb, NULL);
302 __rotation.lock = !lock;
306 static void __on_low_memory(keynode_t *key, void *data)
310 val = vconf_keynode_get_int(key);
312 if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
313 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_MEMORY);
318 static void __on_low_battery(keynode_t *key, void *data)
322 val = vconf_keynode_get_int(key);
324 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
325 __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_BATTERY);
328 static void __destroy_lang_info(gpointer data)
330 struct lang_info_s *info = (struct lang_info_s *)data;
336 g_list_free_full(info->list, free);
342 static struct lang_info_s *__create_lang_info(const char *lang)
344 struct lang_info_s *info;
346 info = calloc(1, sizeof(struct lang_info_s));
348 _ERR("Out of memory");
352 info->parent = strdup(lang);
353 if (info->parent == NULL) {
354 _ERR("Out of memory");
362 static gint __compare_langs(gconstpointer a, gconstpointer b)
370 static char *__get_string_before(const char *str, const char *delim)
376 dup_str = strdup(str);
380 token = strtok(dup_str, delim);
386 new_str = strdup(token);
392 static GHashTable *__get_lang_table(void)
396 struct dirent *dentry;
398 struct stat stat_buf;
401 struct lang_info_s *info;
403 if (__locale_dir == NULL || __locale_dir[0] == '\0')
406 table = g_hash_table_new_full(g_str_hash, g_str_equal,
407 NULL, __destroy_lang_info);
409 _ERR("Out of memory");
413 dp = opendir(__locale_dir);
415 g_hash_table_destroy(table);
419 while ((dentry = readdir(dp)) != NULL) {
420 if (!strcmp(dentry->d_name, ".") ||
421 !strcmp(dentry->d_name, ".."))
424 snprintf(buf, sizeof(buf), "%s/%s",
425 __locale_dir, dentry->d_name);
426 ret = stat(buf, &stat_buf);
427 if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
430 parent_lang = __get_string_before(dentry->d_name, "_");
431 if (parent_lang == NULL) {
432 _ERR("Out of memory");
436 info = g_hash_table_lookup(table, parent_lang);
438 info = __create_lang_info(parent_lang);
443 g_hash_table_insert(table, info->parent, info);
445 info->list = g_list_append(info->list, strdup(dentry->d_name));
453 static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
455 struct lang_info_s *info;
457 char *parent_lang = NULL;
463 list = g_list_append(list, strdup(lang));
465 extract_lang = __get_string_before(lang, ".");
466 if (extract_lang == NULL)
469 found = g_list_find_custom(list, extract_lang, __compare_langs);
471 list = g_list_remove_link(list, found);
472 list = g_list_concat(list, found);
476 parent_lang = __get_string_before(extract_lang, "_");
477 if (parent_lang == NULL)
480 info = g_hash_table_lookup(table, parent_lang);
484 found = g_list_find_custom(info->list, extract_lang, __compare_langs);
486 info->list = g_list_remove_link(info->list, found);
487 list = g_list_concat(list, found);
491 found = g_list_find_custom(info->list, parent_lang, __compare_langs);
493 info->list = g_list_remove_link(info->list, found);
494 list = g_list_concat(list, found);
498 found = g_list_first(info->list);
500 info->list = g_list_remove_link(info->list, found);
501 list = g_list_concat(list, found);
513 static GList *__split_language(const char *lang)
519 dup_lang = strdup(lang);
520 if (dup_lang == NULL) {
521 _ERR("Out of memory");
525 token = strtok(dup_lang, ":");
526 while (token != NULL) {
527 list = g_list_append(list, strdup(token));
528 token = strtok(NULL, ":");
535 static GList *__append_default_langs(GList *list)
537 const char *langs[] = {"en_US", "en_GB", "en"};
541 for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
542 found = g_list_find_custom(list, langs[i], __compare_langs);
544 list = g_list_append(list, strdup(langs[i]));
550 static char *__get_language(const char *lang)
554 GList *lang_list = NULL;
557 char buf[LINE_MAX] = {'\0'};
560 list = __split_language(lang);
564 table = __get_lang_table();
566 g_list_free_full(list, free);
570 iter = g_list_first(list);
572 language = (char *)iter->data;
573 lang_list = __append_langs(language, lang_list, table);
574 iter = g_list_next(iter);
576 g_list_free_full(list, free);
577 g_hash_table_destroy(table);
579 lang_list = __append_default_langs(lang_list);
580 iter = g_list_first(lang_list);
582 language = (char *)iter->data;
584 if (buf[0] == '\0') {
585 snprintf(buf, sizeof(buf), "%s", language);
587 n = sizeof(buf) - strlen(buf) - 1;
588 strncat(buf, ":", n);
589 n = sizeof(buf) - strlen(buf) - 1;
590 strncat(buf, language, n);
593 iter = g_list_next(iter);
595 g_list_free_full(lang_list, free);
600 static void __update_lang(void)
606 lang = vconf_get_str(VCONFKEY_LANGSET);
608 /* TODO: Use VCONFKEY_SETAPPL_LANGUAGES key */
609 language = __get_language(lang);
611 _DBG("*****language(%s)", language);
612 setenv("LANGUAGE", language, 1);
615 setenv("LANGUAGE", lang, 1);
617 setenv("LANG", lang, 1);
618 setenv("LC_MESSAGES", lang, 1);
619 r = setlocale(LC_ALL, "");
621 r = setlocale(LC_ALL, "en_US.UTF-8");
623 _DBG("*****appcore setlocale=%s\n", r);
625 _DBG("*****appcore setlocale=\"C\"");
626 setenv("LC_ALL", "C", 1);
627 r = setlocale(LC_ALL, "");
629 _ERR("failed to setlocale");
636 static void __update_region(void)
641 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
643 setenv("LC_CTYPE", region, 1);
644 setenv("LC_NUMERIC", region, 1);
645 setenv("LC_TIME", region, 1);
646 setenv("LC_COLLATE", region, 1);
647 setenv("LC_MONETARY", region, 1);
648 setenv("LC_PAPER", region, 1);
649 setenv("LC_NAME", region, 1);
650 setenv("LC_ADDRESS", region, 1);
651 setenv("LC_TELEPHONE", region, 1);
652 setenv("LC_MEASUREMENT", region, 1);
653 setenv("LC_IDENTIFICATION", region, 1);
654 r = setlocale(LC_ALL, "");
656 _DBG("*****appcore setlocale=%s\n", r);
658 _DBG("*****appcore setlocale=\"C\"");
659 setenv("LC_ALL", "C", 1);
660 r = setlocale(LC_ALL, "");
662 _ERR("failed to setlocale");
669 static void __on_language_change(keynode_t *key, void *data)
674 g_source_remove(__context.sid);
678 val = vconf_keynode_get_str(key);
681 __invoke_callback((void *)val, APPCORE_BASE_EVENT_LANG_CHANGE);
684 static void __on_region_change(keynode_t *key, void *data)
689 name = vconf_keynode_get_name(key);
693 if (strcmp(name, VCONFKEY_REGIONFORMAT) &&
694 strcmp(name, VCONFKEY_REGIONFORMAT_TIME1224))
697 val = vconf_get_str(VCONFKEY_REGIONFORMAT);
700 __invoke_callback((void *)val, APPCORE_BASE_EVENT_REGION_CHANGE);
704 static gboolean __invoke_lang_change(gpointer data)
710 lang = getenv("LANG");
712 return G_SOURCE_REMOVE;
714 __invoke_callback((void *)lang, APPCORE_BASE_EVENT_LANG_CHANGE);
716 return G_SOURCE_REMOVE;
719 static void __verify_language(void)
722 const char *env_lang;
724 env_lang = getenv("LANG");
728 lang = vconf_get_str(VCONFKEY_LANGSET);
732 if (strcmp(env_lang, lang) != 0) {
733 _INFO("LANG(%s), LANGSET(%s)", env_lang, lang);
734 __context.sid = g_idle_add(__invoke_lang_change, NULL);
740 static gboolean __flush_memory(gpointer data)
742 int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
744 appcore_base_flush_memory();
747 if (!__context.allowed_bg && !__context.suspended_state) {
748 _DBG("[__SUSPEND__] flush case");
749 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
750 __context.suspended_state = true;
756 static void __add_suspend_timer(void)
758 __context.tid = g_timeout_add_seconds(5, __flush_memory, NULL);
761 static void __remove_suspend_timer(void)
763 if (__context.tid > 0) {
764 g_source_remove(__context.tid);
769 static void __on_receive_suspend_signal(GDBusConnection *connection,
770 const gchar *sender_name,
771 const gchar *object_path,
772 const gchar *interface_name,
773 const gchar *signal_name,
774 GVariant *parameters,
777 gint suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
781 if (g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL) == 0) {
782 g_variant_get(parameters, "(ii)", &status, &pid);
783 if (pid == getpid() && status == 0) {
784 if (!__context.allowed_bg && __context.suspended_state) {
785 __remove_suspend_timer();
786 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
787 __context.suspended_state = false;
788 __add_suspend_timer();
794 static int __init_suspend_dbus_handler(void)
798 if (__suspend_dbus_handler_initialized)
802 __bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
804 _ERR("Failed to connect to the D-BUS daemon: %s",
811 __suspend_dbus_handler_initialized = g_dbus_connection_signal_subscribe(
814 RESOURCED_FREEZER_INTERFACE,
815 RESOURCED_FREEZER_SIGNAL,
816 RESOURCED_FREEZER_PATH,
818 G_DBUS_SIGNAL_FLAGS_NONE,
819 __on_receive_suspend_signal,
822 if (__suspend_dbus_handler_initialized == 0) {
823 _ERR("g_dbus_connection_signal_subscribe() is failed.");
827 _DBG("[__SUSPEND__] suspend signal initialized");
832 static void __fini_suspend_dbus_handler(void)
837 if (__suspend_dbus_handler_initialized) {
838 g_dbus_connection_signal_unsubscribe(__bus,
839 __suspend_dbus_handler_initialized);
840 __suspend_dbus_handler_initialized = 0;
843 g_object_unref(__bus);
847 static gboolean __init_suspend(gpointer data)
849 __init_suspend_dbus_handler();
850 return G_SOURCE_REMOVE;
853 static int __get_locale_resource_dir(char *locale_dir, int size)
855 const char *res_path;
857 res_path = aul_get_app_resource_path();
858 if (res_path == NULL) {
859 _ERR("Failed to get resource path");
863 snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
864 if (access(locale_dir, R_OK) != 0)
865 _DBG("%s does not exist", locale_dir);
870 static int __get_app_name(const char *appid, char **name)
872 char *name_token = NULL;
877 /* com.vendor.name -> name */
878 name_token = strrchr(appid, '.');
879 if (name_token == NULL)
884 *name = strdup(name_token);
891 static int __set_i18n(const char *domain, const char *dir)
895 if (domain == NULL) {
903 __locale_dir = strdup(dir);
909 r = setlocale(LC_ALL, "");
910 /* if locale is not set properly, try to set "en_US" again */
912 r = setlocale(LC_ALL, "en_US.UTF-8");
914 _DBG("*****appcore setlocale=%s\n", r);
917 _ERR("appcore: setlocale() error");
918 _DBG("*****appcore setlocale=\"C\"");
919 setenv("LC_ALL", "C", 1);
920 r = setlocale(LC_ALL, "");
922 _ERR("failed to setlocale");
925 r = bindtextdomain(domain, dir);
927 _ERR("appcore: bindtextdomain() error");
929 r = textdomain(domain);
931 _ERR("appcore: textdomain() error");
936 EXPORT_API int appcore_base_on_set_i18n(void)
939 char locale_dir[PATH_MAX];
940 char appid[PATH_MAX];
943 r = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
945 _ERR("Failed to get application ID - pid(%d)", getpid());
949 r = __get_app_name(appid, &name);
953 r = __get_locale_resource_dir(locale_dir, sizeof(locale_dir));
959 r = __set_i18n(name, locale_dir);
970 EXPORT_API int appcore_base_set_i18n(const char *domain_name, const char *dir_name)
972 return __set_i18n(domain_name, dir_name);
975 static void __set_default_events(void)
979 vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
980 r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
982 vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
983 vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
986 static void __unset_default_events(void)
990 vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
991 r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
993 vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
994 vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
997 EXPORT_API int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data)
1002 __context.ops = ops;
1003 __context.argc = argc;
1004 __context.argv = argv;
1005 __context.data = data;
1007 __context.suspended_state = false;
1008 __context.allowed_bg = false;
1010 if (__context.ops.init)
1011 __context.ops.init(argc, argv, data);
1013 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
1014 g_idle_add(__init_suspend, NULL);
1016 if (!__context.dirty) {
1017 __context.dirty = true;
1019 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
1020 if (__exist_callback(i)) {
1021 if (__context.ops.set_event)
1022 __context.ops.set_event(i, __context.data);
1027 __verify_language();
1028 __set_default_events();
1029 if (__context.ops.set_i18n)
1030 __context.ops.set_i18n(__context.data);
1032 if (__context.ops.create) {
1033 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
1034 r = __context.ops.create(__context.data);
1035 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1037 aul_status_update(STATUS_DYING);
1042 if (__context.ops.run)
1043 __context.ops.run(__context.data);
1048 EXPORT_API void appcore_base_fini(void)
1052 aul_status_update(STATUS_DYING);
1053 if (__context.ops.terminate) {
1054 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE");
1055 __context.ops.terminate(__context.data);
1056 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1059 for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
1060 if (__exist_callback(i)) {
1061 if (__context.ops.unset_event)
1062 __context.ops.unset_event(i, __context.data);
1066 __unset_default_events();
1068 if (__context.sid) {
1069 g_source_remove(__context.sid);
1073 g_list_free_full(__events, free);
1076 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
1077 __fini_suspend_dbus_handler();
1081 __locale_dir = NULL;
1084 __context.dirty = false;
1086 if (__context.ops.finish)
1087 __context.ops.finish();
1090 EXPORT_API int appcore_base_flush_memory(void)
1092 int (*sqlite3_free_heap_memory)(int);
1094 sqlite3_free_heap_memory = dlsym(RTLD_DEFAULT,
1095 "sqlite3_release_memory");
1096 if (sqlite3_free_heap_memory)
1097 sqlite3_free_heap_memory(SQLITE_FLUSH_MAX);
1103 EXPORT_API int appcore_base_on_receive(aul_type type, bundle *b)
1110 _DBG("[APP %d] AUL event: AUL_START", getpid());
1111 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1112 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
1113 if (bg && !strcmp(bg, "ALLOWED_BG")) {
1114 _DBG("[__SUSPEND__] allowed background");
1115 __context.allowed_bg = true;
1116 __remove_suspend_timer();
1120 if (__context.ops.control) {
1121 traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESET");
1122 __context.ops.control(b, __context.data);
1123 traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
1127 _DBG("[APP %d] AUL event: AUL_RESUME", getpid());
1128 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1129 bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
1130 if (bg && !strcmp(bg, "ALLOWED_BG")) {
1131 _DBG("[__SUSPEND__] allowed background");
1132 __context.allowed_bg = true;
1133 __remove_suspend_timer();
1138 _DBG("[APP %d] AUL event: AUL_TERMINATE", getpid());
1139 aul_status_update(STATUS_DYING);
1140 if (!__context.allowed_bg)
1141 __remove_suspend_timer();
1143 if (__context.ops.exit)
1144 __context.ops.exit(__context.data);
1146 case AUL_TERMINATE_BGAPP:
1147 _DBG("[APP %d] AUL event: AUL_TERMINATE_BGAPP", getpid());
1148 if (!__context.allowed_bg)
1149 __remove_suspend_timer();
1152 _DBG("[APP %d] AUL event: AUL_WAKE", getpid());
1153 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1154 if (!__context.allowed_bg &&
1155 __context.suspended_state) {
1156 int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
1157 __remove_suspend_timer();
1158 __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
1159 __context.suspended_state = false;
1164 _DBG("[APP %d] AUL event: AUL_SUSPEND", getpid());
1165 if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
1166 if (!__context.allowed_bg &&
1167 !__context.suspended_state) {
1168 __remove_suspend_timer();
1169 __flush_memory(NULL);
1173 case AUL_UPDATE_REQUESTED:
1174 _DBG("[APP %d] AUL event: AUL_UPDATE_REQUESTED", getpid());
1175 __invoke_callback((void *)&dummy, APPCORE_BASE_EVENT_UPDATE_REQUESTED);
1178 _DBG("[APP %d] AUL event: %d", getpid(), type);
1186 EXPORT_API int appcore_base_on_create(void)
1190 r = aul_launch_init(__context.ops.receive, NULL);
1192 _ERR("Aul init failed: %d", r);
1196 r = aul_launch_argv_handler(__context.argc, __context.argv);
1198 _ERR("Aul argv handler failed: %d", r);
1205 EXPORT_API int appcore_base_on_control(bundle *b)
1210 EXPORT_API int appcore_base_on_terminate()
1217 EXPORT_API void appcore_base_on_set_event(enum appcore_base_event event)
1220 case APPCORE_BASE_EVENT_LOW_BATTERY:
1221 vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL);
1223 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1224 __register_rotation_changed_event();
1226 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1235 EXPORT_API void appcore_base_on_unset_event(enum appcore_base_event event)
1238 case APPCORE_BASE_EVENT_LOW_BATTERY:
1239 vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
1241 case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
1242 __unregister_rotation_changed_event();
1244 case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
1251 EXPORT_API appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
1252 appcore_base_event_cb cb, void *data)
1254 appcore_base_event_node *node;
1256 if (__context.dirty && !__exist_callback(event)) {
1257 if (__context.ops.set_event)
1258 __context.ops.set_event(event, __context.data);
1261 node = malloc(sizeof(appcore_base_event_node));
1269 __events = g_list_append(__events, node);
1274 EXPORT_API int appcore_base_remove_event(appcore_base_event_h handle)
1276 appcore_base_event_node *node = handle;
1277 enum appcore_base_event event;
1279 if (!node || !g_list_find(__events, node))
1283 __events = g_list_remove(__events, node);
1285 if (__context.dirty && !__exist_callback(event)) {
1286 if (__context.ops.unset_event)
1287 __context.ops.unset_event(event, __context.data);
1293 EXPORT_API int appcore_base_raise_event(void *event, enum appcore_base_event type)
1295 __invoke_callback(event, type);
1299 EXPORT_API int appcore_base_get_rotation_state(enum appcore_base_rm *curr)
1304 if (!__rotation.ref)
1307 *curr = __rotation.rm;
1311 EXPORT_API bool appcore_base_is_bg_allowed(void)
1313 return __context.allowed_bg;
1316 EXPORT_API bool appcore_base_is_suspended(void)
1318 return __context.suspended_state;
1321 EXPORT_API void appcore_base_toggle_suspended_state(void)
1323 __context.suspended_state ^= __context.suspended_state;
1326 EXPORT_API void appcore_base_exit(void)
1328 if (__context.ops.exit)
1329 __context.ops.exit(__context.data);
1332 EXPORT_API void appcore_base_add_suspend_timer(void)
1334 __add_suspend_timer();
1337 EXPORT_API void appcore_base_remove_suspend_timer(void)
1339 __remove_suspend_timer();
1342 static int __on_receive(aul_type type, bundle *b, void *data)
1344 return appcore_base_on_receive(type, b);
1347 static int __on_create(void *data)
1349 return appcore_base_on_create();
1352 static int __on_control(bundle *b, void *data)
1354 return appcore_base_on_control(b);
1357 static int __on_terminate(void *data)
1359 return appcore_base_on_terminate();
1362 static int __on_set_i18n(void *data)
1364 return appcore_base_on_set_i18n();
1367 static void __on_set_event(enum appcore_base_event event, void *data)
1369 return appcore_base_on_set_event(event);
1372 static void __on_unset_event(enum appcore_base_event event, void *data)
1374 return appcore_base_on_unset_event(event);
1377 EXPORT_API appcore_base_ops appcore_base_get_default_ops(void)
1379 appcore_base_ops ops;
1381 ops.create = __on_create;
1382 ops.control = __on_control;
1383 ops.terminate = __on_terminate;
1384 ops.receive = __on_receive;
1385 ops.set_i18n = __on_set_i18n;
1390 ops.set_event = __on_set_event;
1391 ops.unset_event = __on_unset_event;