#include <vconf.h>
#include <aul.h>
#include <bundle_internal.h>
+#include <sensor_internal.h>
+#include <ttrace.h>
+#include <system_info.h>
+
#include "appcore_base.h"
#include "appcore_base_private.h"
+#include "appcore_watchdog.h"
+#include "appcore_base_control.h"
#define PATH_LOCALE "locale"
-#define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
+#define RESOURCED_FREEZER_PATH "/Org/Tizen/ResourceD/Freezer"
#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
#define RESOURCED_FREEZER_SIGNAL "FreezerState"
+#define SQLITE_FLUSH_MAX (1024 * 1024)
typedef struct _appcore_base_context {
appcore_base_ops ops;
unsigned int tid;
bool suspended_state;
bool allowed_bg;
+ bool dirty;
+ guint sid;
+ int display_state;
} appcore_base_context;
typedef struct _appcore_base_event_node {
int type;
appcore_base_event_cb cb;
void *data;
+ void *prev_event;
} appcore_base_event_node;
+typedef struct _appcore_base_rotation {
+ int conn;
+ int lock;
+ int ref;
+ enum appcore_base_rm rm;
+ int charger_status;
+ bool initialized;
+} appcore_base_rotation;
+
+struct lang_info_s {
+ char *parent;
+ GList *list;
+};
+
static appcore_base_context __context;
static GList *__events;
static GDBusConnection *__bus;
static guint __suspend_dbus_handler_initialized;
static char *__locale_dir;
+static appcore_base_rotation __rotation;
+
+appcore_base_tizen_profile_t appcore_base_get_tizen_profile(void)
+{
+ static appcore_base_tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
+ char *profile_name = NULL;
+
+ if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
+ return profile;
+
+ system_info_get_platform_string("http://tizen.org/feature/profile",
+ &profile_name);
+ if (profile_name == NULL)
+ return profile;
+
+ switch (*profile_name) {
+ case 'm':
+ case 'M':
+ profile = TIZEN_PROFILE_MOBILE;
+ break;
+ case 'w':
+ case 'W':
+ profile = TIZEN_PROFILE_WEARABLE;
+ break;
+ case 't':
+ case 'T':
+ profile = TIZEN_PROFILE_TV;
+ break;
+ case 'i':
+ case 'I':
+ profile = TIZEN_PROFILE_IVI;
+ break;
+ default:
+ profile = TIZEN_PROFILE_COMMON;
+ break;
+ }
+ free(profile_name);
+
+ return profile;
+}
+
+static int __compare_event(void *prev_event, void *curr_event, int type)
+{
+ char *curr_strval;
+ char *prev_strval;
+ int curr_intval;
+ int prev_intval;
+ int ret = -1;
+
+ switch (type) {
+ case APPCORE_BASE_EVENT_LOW_MEMORY:
+ case APPCORE_BASE_EVENT_LOW_BATTERY:
+ case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
+ case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
+ prev_intval = GPOINTER_TO_INT(prev_event);
+ curr_intval = *(int *)curr_event;
+ if (prev_intval == curr_intval)
+ ret = 0;
+ break;
+ case APPCORE_BASE_EVENT_LANG_CHANGE:
+ case APPCORE_BASE_EVENT_REGION_CHANGE:
+ prev_strval = prev_event;
+ curr_strval = curr_event;
+ if (prev_strval && curr_strval &&
+ !strcmp(prev_strval, curr_strval))
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static void __unset_prev_event(void **prev_event, int type)
+{
+ if (type == APPCORE_BASE_EVENT_LANG_CHANGE ||
+ type == APPCORE_BASE_EVENT_REGION_CHANGE)
+ free(*prev_event);
+ *prev_event = NULL;
+}
+
+static void __set_prev_event(void **prev_event, void *curr_event, int type)
+{
+ int curr_intval;
+ char *curr_strval;
+
+ switch (type) {
+ case APPCORE_BASE_EVENT_LOW_MEMORY:
+ case APPCORE_BASE_EVENT_LOW_BATTERY:
+ case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
+ case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
+ curr_intval = *(int *)curr_event;
+ *prev_event = GINT_TO_POINTER(curr_intval);
+ break;
+ case APPCORE_BASE_EVENT_LANG_CHANGE:
+ case APPCORE_BASE_EVENT_REGION_CHANGE:
+ curr_strval = curr_event;
+ if (curr_strval)
+ *prev_event = strdup(curr_strval);
+ break;
+ default:
+ break;
+ }
+}
static void __invoke_callback(void *event, int type)
{
while (iter) {
appcore_base_event_node *node = iter->data;
+ iter = g_list_next(iter);
- if (node->type == type)
+ if (node->type != type)
+ continue;
+
+ if (__compare_event(node->prev_event, event, type)) {
node->cb(event, node->data);
- iter = g_list_next(iter);
+ __unset_prev_event(&node->prev_event, type);
+ __set_prev_event(&node->prev_event, event, type);
+ }
}
}
return false;
}
+static enum appcore_base_rm __get_rm(sensor_data_t data)
+{
+ int event;
+ enum appcore_base_rm rm;
+
+ if (data.value_count <= 0) {
+ _ERR("Failed to get sensor data");
+ return APPCORE_BASE_RM_UNKNOWN;
+ }
+
+ event = data.values[0];
+ switch (event) {
+ case AUTO_ROTATION_DEGREE_0:
+ rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
+ break;
+ case AUTO_ROTATION_DEGREE_90:
+ rm = APPCORE_BASE_RM_LANDSCAPE_NORMAL;
+ break;
+ case AUTO_ROTATION_DEGREE_180:
+ rm = APPCORE_BASE_RM_PORTRAIT_REVERSE;
+ break;
+ case AUTO_ROTATION_DEGREE_270:
+ rm = APPCORE_BASE_RM_LANDSCAPE_REVERSE;
+ break;
+ default:
+ rm = APPCORE_BASE_RM_UNKNOWN;
+ break;
+ }
+
+ return rm;
+}
+
+static void __lock_cb(keynode_t *node, void *user_data)
+{
+ bool r;
+ sensor_data_t data;
+ enum appcore_base_rm rm;
+
+ __rotation.lock = !vconf_keynode_get_bool(node);
+ if (__rotation.lock) {
+ _DBG("Rotation locked");
+ rm = APPCORE_BASE_RM_PORTRAIT_NORMAL;
+ } else {
+ _DBG("Rotation unlocked");
+ r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data);
+ if (!r) {
+ _ERR("Failed to get sensor data");
+ return;
+ }
+
+ rm = __get_rm(data);
+ if (rm == APPCORE_BASE_RM_UNKNOWN) {
+ _ERR("Unknown mode");
+ return;
+ }
+ }
+
+ if (__rotation.rm == rm)
+ return;
+
+ _DBG("Rotation: %d -> %d", __rotation.rm, rm);
+ __rotation.rm = rm;
+ __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
+}
+
+static void __auto_rotation_changed_cb(sensor_t sensor, unsigned int event_type,
+ sensor_data_t *data, void *user_data)
+{
+ enum appcore_base_rm rm;
+
+ if (data == NULL)
+ return;
+
+ if (__rotation.lock)
+ return;
+
+ if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
+ return;
+
+ rm = __get_rm(*data);
+ if (rm == APPCORE_BASE_RM_UNKNOWN) {
+ _ERR("Unknown mode");
+ return;
+ }
+
+ _DBG("Rotation: %d -> %d", __rotation.rm, rm);
+ __rotation.rm = rm;
+ __invoke_callback((void *)&__rotation.rm, APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED);
+}
+
+static void __fini_rotation(void)
+{
+ if (!__rotation.initialized)
+ return;
+
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb);
+ sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
+ sensord_stop(__rotation.conn);
+ sensord_disconnect(__rotation.conn);
+
+ __rotation.lock = 0;
+ __rotation.initialized = false;
+}
+
+static void __init_rotation(void)
+{
+ sensor_t sensor;
+ int lock;
+ bool r;
+
+ if (__rotation.initialized)
+ return;
+
+ sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
+ __rotation.conn = sensord_connect(sensor);
+ if (__rotation.conn < 0) {
+ _ERR("Failed to connect sensord");
+ return;
+ }
+
+ r = sensord_register_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT,
+ SENSOR_INTERVAL_NORMAL, 0, __auto_rotation_changed_cb, NULL);
+ if (!r) {
+ _ERR("Failed to register auto rotation change event");
+ sensord_disconnect(__rotation.conn);
+ return;
+ }
+
+ r = sensord_start(__rotation.conn, 0);
+ if (!r) {
+ _ERR("Failed to start sensord");
+ sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
+ sensord_disconnect(__rotation.conn);
+ return;
+ }
+
+ lock = 0;
+ vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb, NULL);
+
+ __rotation.lock = !lock;
+ __rotation.initialized = true;
+}
+
+static void __charger_status_changed_cb(keynode_t *keynode, void *user_data)
+{
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ __rotation.charger_status = vconf_keynode_get_int(keynode);
+ if (__rotation.charger_status) {
+ if (__rotation.ref)
+ __init_rotation();
+ } else {
+ if (__rotation.ref)
+ __fini_rotation();
+ }
+ _DBG("charger status(%d)", __rotation.charger_status);
+ }
+}
+
+static void __unregister_rotation_changed_event(void)
+{
+ if (!__rotation.ref)
+ return;
+
+ __rotation.ref--;
+ if (__rotation.ref > 1)
+ return;
+
+ __fini_rotation();
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ __charger_status_changed_cb);
+ }
+
+ __rotation.ref = 0;
+}
+
+static void __register_rotation_changed_event(void)
+{
+ if (__rotation.ref) {
+ __rotation.ref++;
+ return;
+ }
+
+ if (TIZEN_FEATURE_CHARGER_STATUS) {
+ vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ &__rotation.charger_status);
+ vconf_notify_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ __charger_status_changed_cb, NULL);
+ if (__rotation.charger_status)
+ __init_rotation();
+ } else {
+ __init_rotation();
+ }
+
+ __rotation.ref++;
+}
+
static void __on_low_memory(keynode_t *key, void *data)
{
int val;
val = vconf_keynode_get_int(key);
if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
- __invoke_callback(key, APPCORE_BASE_EVENT_LOW_MEMORY);
+ __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_MEMORY);
malloc_trim(0);
}
}
val = vconf_keynode_get_int(key);
if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
- __invoke_callback(key, APPCORE_BASE_EVENT_LOW_BATTERY);
+ __invoke_callback(&val, APPCORE_BASE_EVENT_LOW_BATTERY);
}
-static void __free_children_langs(gpointer data)
+static void __destroy_lang_info(gpointer data)
{
- GList *list = (GList *)data;
+ struct lang_info_s *info = (struct lang_info_s *)data;
- if (list == NULL)
+ if (info == NULL)
return;
- g_list_free_full(list, (GDestroyNotify)free);
+ if (info->list)
+ g_list_free_full(info->list, free);
+ if (info->parent)
+ free(info->parent);
+ free(info);
+}
+
+static struct lang_info_s *__create_lang_info(const char *lang)
+{
+ struct lang_info_s *info;
+
+ info = calloc(1, sizeof(struct lang_info_s));
+ if (info == NULL) {
+ _ERR("Out of memory");
+ return NULL;
+ }
+
+ info->parent = strdup(lang);
+ if (info->parent == NULL) {
+ _ERR("Out of memory");
+ free(info);
+ return NULL;
+ }
+
+ return info;
}
static gint __compare_langs(gconstpointer a, gconstpointer b)
{
+ if (!a || !b)
+ return -1;
+
return strcmp(a, b);
}
+static char *__get_string_before(const char *str, const char *delim)
+{
+ char *new_str;
+ char *dup_str;
+ char *token;
+
+ dup_str = strdup(str);
+ if (dup_str == NULL)
+ return NULL;
+
+ token = strtok(dup_str, delim);
+ if (token == NULL) {
+ free(dup_str);
+ return NULL;
+ }
+
+ new_str = strdup(token);
+ free(dup_str);
+
+ return new_str;
+}
+
static GHashTable *__get_lang_table(void)
{
GHashTable *table;
char buf[PATH_MAX];
struct stat stat_buf;
int ret;
- char *dup_lang;
- char *token;
- GList *list;
+ char *parent_lang;
+ struct lang_info_s *info;
if (__locale_dir == NULL || __locale_dir[0] == '\0')
return NULL;
table = g_hash_table_new_full(g_str_hash, g_str_equal,
- free, __free_children_langs);
+ NULL, __destroy_lang_info);
if (table == NULL) {
_ERR("Out of memory");
return NULL;
if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
continue;
- dup_lang = strdup(dentry->d_name);
- if (dup_lang == NULL) {
+ parent_lang = __get_string_before(dentry->d_name, "_");
+ if (parent_lang == NULL) {
_ERR("Out of memory");
break;
}
- token = strtok(dup_lang, "_");
- if (token == NULL) {
- free(dup_lang);
- continue;
- }
-
- list = (GList *)g_hash_table_lookup(table, token);
- if (list == NULL) {
- list = g_list_append(list, strdup(dentry->d_name));
- g_hash_table_insert(table, strdup(token), list);
- } else {
- list = g_list_append(list, strdup(dentry->d_name));
+ info = g_hash_table_lookup(table, parent_lang);
+ if (info == NULL) {
+ info = __create_lang_info(parent_lang);
+ if (info == NULL) {
+ free(parent_lang);
+ break;
+ }
+ g_hash_table_insert(table, info->parent, info);
}
- free(dup_lang);
+ info->list = g_list_append(info->list, strdup(dentry->d_name));
+ free(parent_lang);
}
closedir(dp);
return table;
}
-static char *__get_string_before(const char *str, const char *delim)
-{
- char *new_str;
- char *dup_str;
- char *token;
-
- dup_str = strdup(str);
- if (dup_str == NULL)
- return NULL;
-
- token = strtok(dup_str, delim);
- if (token == NULL) {
- free(dup_str);
- return NULL;
- }
-
- new_str = strdup(token);
- free(dup_str);
-
- return new_str;
-}
-
static GList *__append_langs(const char *lang, GList *list, GHashTable *table)
{
- GList *child_list;
- GList *child_iter;
+ struct lang_info_s *info;
GList *found;
- char *child_lang;
- char *parent_lang;
+ char *parent_lang = NULL;
char *extract_lang;
- char *tmp;
if (lang == NULL)
return list;
- found = g_list_find_custom(g_list_first(list), lang,
- __compare_langs);
- if (found) {
- tmp = (char *)found->data;
- list = g_list_remove(list, tmp);
- list = g_list_append(list, tmp);
- return list;
- }
+ list = g_list_append(list, strdup(lang));
extract_lang = __get_string_before(lang, ".");
if (extract_lang == NULL)
return list;
- parent_lang = __get_string_before(extract_lang, "_");
- if (parent_lang == NULL) {
- free(extract_lang);
- return list;
+ found = g_list_find_custom(list, extract_lang, __compare_langs);
+ if (found) {
+ list = g_list_remove_link(list, found);
+ list = g_list_concat(list, found);
+ goto end;
}
- child_list = g_hash_table_lookup(table, parent_lang);
- if (child_list == NULL) {
- free(parent_lang);
- free(extract_lang);
- return list;
- }
+ parent_lang = __get_string_before(extract_lang, "_");
+ if (parent_lang == NULL)
+ goto end;
- found = g_list_find_custom(g_list_first(child_list),
- extract_lang, __compare_langs);
+ info = g_hash_table_lookup(table, parent_lang);
+ if (info == NULL)
+ goto end;
+
+ found = g_list_find_custom(info->list, extract_lang, __compare_langs);
if (found) {
- tmp = (char *)found->data;
- child_list = g_list_remove(child_list, tmp);
- list = g_list_append(list, tmp);
- free(parent_lang);
- free(extract_lang);
- return list;
+ info->list = g_list_remove_link(info->list, found);
+ list = g_list_concat(list, found);
+ goto end;
}
- free(extract_lang);
- found = g_list_find_custom(g_list_first(child_list),
- parent_lang, __compare_langs);
+ found = g_list_find_custom(info->list, parent_lang, __compare_langs);
if (found) {
- tmp = (char *)found->data;
- child_list = g_list_remove(child_list, tmp);
- list = g_list_append(list, tmp);
- free(parent_lang);
- return list;
+ info->list = g_list_remove_link(info->list, found);
+ list = g_list_concat(list, found);
+ goto end;
}
- free(parent_lang);
- child_iter = g_list_first(child_list);
- while (child_iter) {
- child_lang = (char *)child_iter->data;
- child_iter = g_list_next(child_iter);
- if (child_lang) {
- list = g_list_append(list, strdup(child_lang));
- child_list = g_list_remove(child_list, child_lang);
- free(child_lang);
- break;
- }
+ found = g_list_first(info->list);
+ if (found) {
+ info->list = g_list_remove_link(info->list, found);
+ list = g_list_concat(list, found);
}
+end:
+ if (extract_lang)
+ free(extract_lang);
+ if (parent_lang)
+ free(parent_lang);
+
return list;
}
GList *found;
for (i = 0; i < (sizeof(langs) / sizeof(langs[0])); i++) {
- found = g_list_find_custom(g_list_first(list), langs[i],
- __compare_langs);
+ found = g_list_find_custom(list, langs[i], __compare_langs);
if (found == NULL)
list = g_list_append(list, strdup(langs[i]));
}
}
setenv("LANG", lang, 1);
setenv("LC_MESSAGES", lang, 1);
+ setenv("LC_ALL", lang, 1);
r = setlocale(LC_ALL, "");
if (r == NULL) {
- r = setlocale(LC_ALL, lang);
- if (r != NULL)
+ r = setlocale(LC_ALL, "en_US.UTF-8");
+ if (r != NULL) {
_DBG("*****appcore setlocale=%s\n", r);
+ } else {
+ _DBG("*****appcore setlocale=\"C\"");
+ setenv("LC_ALL", "C", 1);
+ r = setlocale(LC_ALL, "");
+ if (r == NULL)
+ _ERR("failed to setlocale");
+ }
}
free(lang);
}
setenv("LC_MEASUREMENT", region, 1);
setenv("LC_IDENTIFICATION", region, 1);
r = setlocale(LC_ALL, "");
- if (r != NULL)
+ if (r != NULL) {
_DBG("*****appcore setlocale=%s\n", r);
+ } else {
+ _DBG("*****appcore setlocale=\"C\"");
+ setenv("LC_ALL", "C", 1);
+ r = setlocale(LC_ALL, "");
+ if (r == NULL)
+ _ERR("failed to setlocale");
+ }
free(region);
}
{
char *val;
+ if (__context.sid) {
+ g_source_remove(__context.sid);
+ __context.sid = 0;
+ }
+
val = vconf_keynode_get_str(key);
__update_lang();
static void __on_region_change(keynode_t *key, void *data)
{
- char *val = NULL;
+ char *val;
const char *name;
name = vconf_keynode_get_name(key);
- if (!strcmp(name, VCONFKEY_REGIONFORMAT))
- val = vconf_keynode_get_str(key);
+ if (name == NULL)
+ return;
+
+ if (strcmp(name, VCONFKEY_REGIONFORMAT) &&
+ strcmp(name, VCONFKEY_REGIONFORMAT_TIME1224))
+ return;
+
+ val = vconf_get_str(VCONFKEY_REGIONFORMAT);
__update_region();
__invoke_callback((void *)val, APPCORE_BASE_EVENT_REGION_CHANGE);
+ free(val);
+}
+
+static gboolean __invoke_lang_change(gpointer data)
+{
+ const char *lang;
+
+ __context.sid = 0;
+
+ lang = getenv("LANG");
+ if (!lang)
+ return G_SOURCE_REMOVE;
+
+ __invoke_callback((void *)lang, APPCORE_BASE_EVENT_LANG_CHANGE);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void __verify_language(void)
+{
+ char *lang;
+ const char *env_lang;
+
+ env_lang = getenv("LANG");
+ if (!env_lang)
+ return;
+
+ lang = vconf_get_str(VCONFKEY_LANGSET);
+ if (!lang)
+ return;
+
+ if (strcmp(env_lang, lang) != 0) {
+ _INFO("LANG(%s), LANGSET(%s)", env_lang, lang);
+ __context.sid = g_idle_add(__invoke_lang_change, NULL);
+ }
+
+ free(lang);
}
static gboolean __flush_memory(gpointer data)
{
int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
- appcore_base_flush_memory();
+ if (__context.ops.trim_memory)
+ __context.ops.trim_memory(__context.data);
+
__context.tid = 0;
if (!__context.allowed_bg && !__context.suspended_state) {
__bus = NULL;
}
+static gboolean __init_suspend(gpointer data)
+{
+ __init_suspend_dbus_handler();
+ return G_SOURCE_REMOVE;
+}
+
static int __get_locale_resource_dir(char *locale_dir, int size)
{
const char *res_path;
snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
if (access(locale_dir, R_OK) != 0)
- return -1;
+ _DBG("%s does not exist", locale_dir);
return 0;
}
static int __set_i18n(const char *domain, const char *dir)
{
char *r;
- char *lan;
if (domain == NULL) {
errno = EINVAL;
__update_region();
r = setlocale(LC_ALL, "");
- /* if locale is not set properly, try again to set as language base */
+ /* if locale is not set properly, try to set "en_US" again */
if (r == NULL) {
- lan = vconf_get_str(VCONFKEY_LANGSET);
- if (lan != NULL) {
- r = setlocale(LC_ALL, lan);
+ r = setlocale(LC_ALL, "en_US.UTF-8");
+ if (r != NULL)
_DBG("*****appcore setlocale=%s\n", r);
- free(lan);
- }
}
- if (r == NULL)
+ if (r == NULL) {
_ERR("appcore: setlocale() error");
+ _DBG("*****appcore setlocale=\"C\"");
+ setenv("LC_ALL", "C", 1);
+ r = setlocale(LC_ALL, "");
+ if (r == NULL)
+ _ERR("failed to setlocale");
+ }
r = bindtextdomain(domain, dir);
if (r == NULL)
char *name = NULL;
r = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
- if (r < 0)
+ if (r < 0) {
+ _ERR("Failed to get application ID - pid(%d)", getpid());
return -1;
+ }
r = __get_app_name(appid, &name);
if (r < 0)
return 0;
}
+EXPORT_API int appcore_base_set_i18n(const char *domain_name, const char *dir_name)
+{
+ return __set_i18n(domain_name, dir_name);
+}
+
+static void __set_default_events(void)
+{
+ int r;
+
+ vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
+ r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
+ if (r == 0)
+ vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
+ vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
+}
+
+static void __unset_default_events(void)
+{
+ int r;
+
+ vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
+ r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
+ if (r == 0)
+ vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
+}
+
EXPORT_API int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data)
{
+ int i;
+ int r;
+
__context.ops = ops;
__context.argc = argc;
__context.argv = argv;
__context.suspended_state = false;
__context.allowed_bg = false;
+ if (__context.ops.init)
+ __context.ops.init(argc, argv, data);
+
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
+ g_idle_add(__init_suspend, NULL);
+
+ if (!__context.dirty) {
+ __context.dirty = true;
+
+ for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
+ if (__exist_callback(i)) {
+ if (__context.ops.set_event)
+ __context.ops.set_event(i, __context.data);
+ }
+ }
+ }
+
+ __verify_language();
+ __set_default_events();
if (__context.ops.set_i18n)
__context.ops.set_i18n(__context.data);
- __init_suspend_dbus_handler();
-
- if (__context.ops.create && __context.ops.create(__context.data) < 0) {
- aul_status_update(STATUS_DYING);
- return 0;
+ if (__context.ops.create) {
+ traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
+ r = __context.ops.create(__context.data);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+ if (r < 0) {
+ aul_status_update(STATUS_DYING);
+ return 0;
+ }
}
if (__context.ops.run)
{
int i;
+ aul_status_update(STATUS_DYING);
+ appcore_watchdog_disable();
+ if (__context.ops.terminate) {
+ traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE");
+ __context.ops.terminate(__context.data);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+ }
+
for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
if (__exist_callback(i)) {
if (__context.ops.unset_event)
}
}
+ appcore_base_control_fini();
+ __unset_default_events();
+
+ if (__context.sid) {
+ g_source_remove(__context.sid);
+ __context.sid = 0;
+ }
+
g_list_free_full(__events, free);
__events = NULL;
- __fini_suspend_dbus_handler();
- aul_status_update(STATUS_DYING);
- if (__context.ops.terminate)
- __context.ops.terminate(__context.data);
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT)
+ __fini_suspend_dbus_handler();
if (__locale_dir) {
free(__locale_dir);
__locale_dir = NULL;
}
+
+ __context.dirty = false;
+
+ if (__context.ops.finish)
+ __context.ops.finish();
}
EXPORT_API int appcore_base_flush_memory(void)
{
- malloc_trim(0);
+ if (__context.ops.trim_memory)
+ __context.ops.trim_memory(__context.data);
+
return 0;
}
EXPORT_API int appcore_base_on_receive(aul_type type, bundle *b)
{
- int ret;
- const char **tep_path;
- int len = 0;
- int i;
const char *bg;
int dummy = 0;
switch (type) {
case AUL_START:
_DBG("[APP %d] AUL event: AUL_START", getpid());
- tep_path = bundle_get_str_array(b, AUL_TEP_PATH, &len);
- if (tep_path) {
- for (i = 0; i < len; i++) {
- ret = aul_check_tep_mount(tep_path[i]);
- if (ret == -1) {
- _ERR("mount request not completed within 1 sec");
- exit(-1);
- }
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
+ bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
+ if (bg && !strcmp(bg, "ALLOWED_BG")) {
+ _DBG("[__SUSPEND__] allowed background");
+ __context.allowed_bg = true;
+ __remove_suspend_timer();
}
}
- bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
- if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
- _DBG("[__SUSPEND__] allowed background");
- __context.allowed_bg = true;
- __remove_suspend_timer();
+ if (__context.ops.control) {
+ traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESET");
+ __context.ops.control(b, __context.data);
+ traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
}
-
- if (__context.ops.control)
- __context.ops.control(b, __context.data);
break;
case AUL_RESUME:
_DBG("[APP %d] AUL event: AUL_RESUME", getpid());
- bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
- if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
- _DBG("[__SUSPEND__] allowed background");
- __context.allowed_bg = true;
- __remove_suspend_timer();
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
+ bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
+ if (bg && !strcmp(bg, "ALLOWED_BG")) {
+ _DBG("[__SUSPEND__] allowed background");
+ __context.allowed_bg = true;
+ __remove_suspend_timer();
+ }
}
break;
case AUL_TERMINATE:
if (__context.ops.exit)
__context.ops.exit(__context.data);
break;
+ case AUL_TERMINATE_INST:
+ case AUL_TERMINATE_BG_INST:
case AUL_TERMINATE_BGAPP:
- _DBG("[APP %d] AUL event: AUL_TERMINATE_BGAPP", getpid());
+ _DBG("[APP %d] AUL event: %d", getpid(), type);
if (!__context.allowed_bg)
__remove_suspend_timer();
break;
case AUL_WAKE:
_DBG("[APP %d] AUL event: AUL_WAKE", getpid());
- if (!__context.allowed_bg && __context.suspended_state) {
- int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
- __remove_suspend_timer();
- __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
- __context.suspended_state = false;
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
+ if (!__context.allowed_bg &&
+ __context.suspended_state) {
+ int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+ __remove_suspend_timer();
+ __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+ __context.suspended_state = false;
+ }
}
break;
case AUL_SUSPEND:
_DBG("[APP %d] AUL event: AUL_SUSPEND", getpid());
- if (!__context.allowed_bg && !__context.suspended_state) {
- __remove_suspend_timer();
- __flush_memory(NULL);
+ if (TIZEN_FEATURE_BACKGROUND_MANAGEMENT) {
+ if (!__context.allowed_bg &&
+ !__context.suspended_state) {
+ __remove_suspend_timer();
+ __flush_memory(NULL);
+ }
}
break;
case AUL_UPDATE_REQUESTED:
EXPORT_API int appcore_base_on_create(void)
{
int r;
- r = aul_launch_init(__context.ops.receive, NULL);
+
+ r = aul_launch_init(__context.ops.receive, __context.data);
if (r < 0) {
_ERR("Aul init failed: %d", r);
return -1;
EXPORT_API int appcore_base_on_control(bundle *b)
{
+ appcore_base_control_invoke(b);
+
return 0;
}
EXPORT_API int appcore_base_on_terminate()
{
aul_finalize();
- if (__context.ops.exit)
- __context.ops.exit(__context.data);
return 0;
}
EXPORT_API void appcore_base_on_set_event(enum appcore_base_event event)
{
- int r;
-
switch (event) {
- case APPCORE_BASE_EVENT_LOW_MEMORY:
- vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
- break;
case APPCORE_BASE_EVENT_LOW_BATTERY:
vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL);
break;
- case APPCORE_BASE_EVENT_LANG_CHANGE:
- vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
- break;
- case APPCORE_BASE_EVENT_REGION_CHANGE:
- r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
- if (r < 0)
- break;
-
- vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
+ case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
+ __register_rotation_changed_event();
break;
case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
break;
EXPORT_API void appcore_base_on_unset_event(enum appcore_base_event event)
{
- int r;
-
switch (event) {
- case APPCORE_BASE_EVENT_LOW_MEMORY:
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
- break;
case APPCORE_BASE_EVENT_LOW_BATTERY:
vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
break;
- case APPCORE_BASE_EVENT_LANG_CHANGE:
- vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
- break;
- case APPCORE_BASE_EVENT_REGION_CHANGE:
- r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
- if (r < 0)
- break;
- vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
+ case APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED:
+ __unregister_rotation_changed_event();
break;
case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
break;
}
}
+EXPORT_API int appcore_base_on_trim_memory(void)
+{
+ int (*sqlite3_free_heap_memory)(int);
+
+ sqlite3_free_heap_memory = dlsym(RTLD_DEFAULT,
+ "sqlite3_release_memory");
+ if (sqlite3_free_heap_memory)
+ sqlite3_free_heap_memory(SQLITE_FLUSH_MAX);
+
+ malloc_trim(0);
+
+ return 0;
+}
+
EXPORT_API appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
appcore_base_event_cb cb, void *data)
{
appcore_base_event_node *node;
- if (!__exist_callback(event)) {
+ if (__context.dirty && !__exist_callback(event)) {
if (__context.ops.set_event)
__context.ops.set_event(event, __context.data);
}
node->cb = cb;
node->type = event;
node->data = data;
+ node->prev_event = NULL;
__events = g_list_append(__events, node);
return node;
appcore_base_event_node *node = handle;
enum appcore_base_event event;
+ if (!node || !g_list_find(__events, node))
+ return -1;
+
event = node->type;
__events = g_list_remove(__events, node);
+ __unset_prev_event(&node->prev_event, event);
free(node);
- if (!__exist_callback(event)) {
+ if (__context.dirty && !__exist_callback(event)) {
if (__context.ops.unset_event)
__context.ops.unset_event(event, __context.data);
}
EXPORT_API int appcore_base_get_rotation_state(enum appcore_base_rm *curr)
{
+ if (curr == NULL)
+ return -1;
+
+ if (!__rotation.ref)
+ return -1;
+
+ *curr = __rotation.rm;
return 0;
}
__context.suspended_state ^= __context.suspended_state;
}
+EXPORT_API void appcore_base_exit(void)
+{
+ if (__context.ops.exit)
+ __context.ops.exit(__context.data);
+}
+
+EXPORT_API void appcore_base_add_suspend_timer(void)
+{
+ __add_suspend_timer();
+}
+
+EXPORT_API void appcore_base_remove_suspend_timer(void)
+{
+ __remove_suspend_timer();
+}
+
+EXPORT_API void appcore_base_set_display_state(int display_state)
+{
+ __context.display_state = display_state;
+}
+
+EXPORT_API int appcore_base_get_display_state(void)
+{
+ return __context.display_state;
+}
+
static int __on_receive(aul_type type, bundle *b, void *data)
{
return appcore_base_on_receive(type, b);
static void __on_set_event(enum appcore_base_event event, void *data)
{
- return appcore_base_on_set_event(event);
+ appcore_base_on_set_event(event);
}
static void __on_unset_event(enum appcore_base_event event, void *data)
{
- return appcore_base_on_unset_event(event);
+ appcore_base_on_unset_event(event);
+}
+
+static void __on_trim_memory(void *data)
+{
+ appcore_base_on_trim_memory();
}
EXPORT_API appcore_base_ops appcore_base_get_default_ops(void)
ops.terminate = __on_terminate;
ops.receive = __on_receive;
ops.set_i18n = __on_set_i18n;
+ ops.init = NULL;
+ ops.finish = NULL;
ops.run = NULL;
ops.exit = NULL;
ops.set_event = __on_set_event;
ops.unset_event = __on_unset_event;
+ ops.trim_memory = __on_trim_memory;
return ops;
}
-
-