4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
28 #include <sys/types.h>
32 #include <linux/limits.h>
38 #include "appcore-internal.h"
40 #define SQLITE_FLUSH_MAX (1024*1024)
42 #define PKGNAME_MAX 256
43 #define PATH_APP_ROOT "/opt/usr/apps"
44 #define PATH_RO_APP_ROOT "/usr/apps"
45 #define PATH_RES "/res"
46 #define PATH_LOCALE "/locale"
48 static struct appcore core;
50 char caller_appid[APPID_MAX];
52 static enum appcore_event to_ae[SE_MAX] = {
53 APPCORE_EVENT_UNKNOWN, /* SE_UNKNOWN */
54 APPCORE_EVENT_LOW_MEMORY, /* SE_LOWMEM */
55 APPCORE_EVENT_LOW_BATTERY, /* SE_LOWBAT */
56 APPCORE_EVENT_LANG_CHANGE, /* SE_LANGCGH */
57 APPCORE_EVENT_REGION_CHANGE,
61 enum cb_type { /* callback */
71 enum appcore_event sys;
76 int (*cb_pre) (void *);
78 int (*cb_post) (void *);
80 int (*vcb_pre) (void *, void *);
81 int (*vcb) (void *, void *);
82 int (*vcb_post) (void *, void *);
86 int (*callback) (void *);
90 static struct open_s open;
92 static int __app_terminate(void *data);
93 static int __app_resume(void *data);
94 static int __app_reset(void *data, bundle *k);
95 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
96 static int __app_resume_lcd_on(void *data);
97 static int __app_pause_lcd_off(void *data);
100 static int __sys_lowmem_post(void *data, void *evt);
101 static int __sys_lowmem(void *data, void *evt);
102 static int __sys_lowbatt(void *data, void *evt);
103 static int __sys_langchg_pre(void *data, void *evt);
104 static int __sys_langchg(void *data, void *evt);
105 static int __sys_regionchg_pre(void *data, void *evt);
106 static int __sys_regionchg(void *data, void *evt);
107 extern void aul_finalize();
110 static struct evt_ops evtops[] = {
113 .key.vkey = VCONFKEY_SYSMAN_LOW_MEMORY,
114 .vcb_post = __sys_lowmem_post,
119 .key.vkey = VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
120 .vcb = __sys_lowbatt,
124 .key.vkey = VCONFKEY_LANGSET,
125 .vcb_pre = __sys_langchg_pre,
126 .vcb = __sys_langchg,
130 .key.vkey = VCONFKEY_REGIONFORMAT,
131 .vcb_pre = __sys_regionchg_pre,
132 .vcb = __sys_regionchg,
136 .key.vkey = VCONFKEY_REGIONFORMAT_TIME1224,
137 .vcb = __sys_regionchg,
141 static int __get_dir_name(char *dirname)
143 char pkgid[PKGNAME_MAX];
151 if (aul_app_get_pkgid_bypid(pid, pkgid, PKGNAME_MAX) != AUL_R_OK)
154 r = snprintf(dirname, PATH_MAX, PATH_APP_ROOT "/%s" PATH_RES PATH_LOCALE,pkgid);
157 if (access(dirname, R_OK) == 0) return 0;
158 r = snprintf(dirname, PATH_MAX, PATH_RO_APP_ROOT "/%s" PATH_RES PATH_LOCALE,pkgid);
165 static int __app_terminate(void *data)
167 struct appcore *ac = data;
169 _retv_if(ac == NULL || ac->ops == NULL, -1);
170 _retv_if(ac->ops->cb_app == NULL, 0);
172 ac->ops->cb_app(AE_TERMINATE, ac->ops->data, NULL);
177 static gboolean __prt_ltime(gpointer data)
181 msec = appcore_measure_time_from(NULL);
183 _DBG("[APP %d] first idle after reset: %d msec", _pid, msec);
188 static int __app_reset(void *data, bundle * k)
190 struct appcore *ac = data;
191 _retv_if(ac == NULL || ac->ops == NULL, -1);
192 _retv_if(ac->ops->cb_app == NULL, 0);
194 g_idle_add(__prt_ltime, ac);
196 ac->ops->cb_app(AE_RESET, ac->ops->data, k);
201 static int __app_resume(void *data)
203 x_raise_win(getpid());
207 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
208 static int __app_resume_lcd_on(void *data)
210 struct appcore *ac = data;
211 ac->ops->cb_app(AE_RESUME, ac->ops->data, NULL);
215 static int __app_pause_lcd_off(void *data)
217 struct appcore *ac = data;
218 ac->ops->cb_app(AE_PAUSE, ac->ops->data, NULL);
223 static int __sys_do_default(struct appcore *ac, enum sys_event event)
229 /*r = __def_lowbatt(ac);*/
240 static int __sys_do(struct appcore *ac, void *event_info, enum sys_event event)
244 _retv_if(ac == NULL || event >= SE_MAX, -1);
246 op = &ac->sops[event];
248 if (op->func == NULL)
249 return __sys_do_default(ac, event);
251 return op->func(event_info, op->data);
254 static int __sys_lowmem_post(void *data, void *evt)
256 keynode_t *key = evt;
259 val = vconf_keynode_get_int(key);
261 if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
262 #if defined(MEMORY_FLUSH_ACTIVATE)
263 struct appcore *ac = data;
264 ac->ops->cb_app(AE_LOWMEM_POST, ac->ops->data, NULL);
272 static int __sys_lowmem(void *data, void *evt)
274 keynode_t *key = evt;
277 val = vconf_keynode_get_int(key);
279 if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING)
280 return __sys_do(data, (void *)&val, SE_LOWMEM);
285 static int __sys_lowbatt(void *data, void *evt)
287 keynode_t *key = evt;
290 val = vconf_keynode_get_int(key);
292 /* VCONFKEY_SYSMAN_BAT_CRITICAL_LOW or VCONFKEY_SYSMAN_POWER_OFF */
293 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
294 return __sys_do(data, (void *)&val, SE_LOWBAT);
299 static int __sys_langchg_pre(void *data, void *evt)
305 static int __sys_langchg(void *data, void *evt)
307 keynode_t *key = evt;
310 val = vconf_keynode_get_str(key);
312 return __sys_do(data, (void *)val, SE_LANGCHG);
315 static int __sys_regionchg_pre(void *data, void *evt)
321 static int __sys_regionchg(void *data, void *evt)
323 keynode_t *key = evt;
327 name = vconf_keynode_get_name(key);
328 if (!strcmp(name, VCONFKEY_REGIONFORMAT))
329 val = vconf_keynode_get_str(key);
331 return __sys_do(data, (void *)val, SE_REGIONCHG);
334 static void __vconf_do(struct evt_ops *eo, keynode_t * key, void *data)
339 eo->vcb_pre(data, key);
345 eo->vcb_post(data, key);
348 static void __vconf_cb(keynode_t *key, void *data)
353 name = vconf_keynode_get_name(key);
354 _ret_if(name == NULL);
356 _DBG("[APP %d] vconf changed: %s", _pid, name);
358 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
359 struct evt_ops *eo = &evtops[i];
363 if (!strcmp(name, eo->key.vkey))
364 __vconf_do(eo, key, data);
373 static int __add_vconf(struct appcore *ac)
378 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
379 struct evt_ops *eo = &evtops[i];
383 r = vconf_notify_key_changed(eo->key.vkey, __vconf_cb,
395 static int __del_vconf(void)
400 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
401 struct evt_ops *eo = &evtops[i];
405 r = vconf_ignore_key_changed(eo->key.vkey, __vconf_cb);
416 static int __aul_handler(aul_type type, bundle *b, void *data)
419 const char *str = NULL;
423 _DBG("[APP %d] AUL event: AUL_START", _pid);
424 __app_reset(data, b);
425 str = bundle_get_val(b, AUL_K_CALLER_APPID);
426 SECURE_LOGD("caller_appid : %s", str);
428 strncpy(caller_appid, str, APPID_MAX-1);
429 caller_appid[APPID_MAX-1] = '\0';
433 _DBG("[APP %d] AUL event: AUL_RESUME", _pid);
435 ret = open.callback(open.cbdata);
443 _DBG("[APP %d] AUL event: AUL_TERMINATE", _pid);
444 __app_terminate(data);
446 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
447 case AUL_RESUME_LCD_ON:
448 _DBG("[APP %d] AUL event: AUL_RESUME_LCD_ON", _pid);
449 __app_resume_lcd_on(data);
451 case AUL_PAUSE_LCD_OFF:
452 _DBG("[APP %d] AUL event: AUL_PAUSE_LCD_OFF", _pid);
453 __app_pause_lcd_off(data);
457 _DBG("[APP %d] AUL event: %d", _pid, type);
466 static void __clear(struct appcore *ac)
468 memset(ac, 0, sizeof(struct appcore));
471 EXPORT_API char *appcore_get_caller_appid()
476 EXPORT_API int appcore_set_open_cb(int (*cb) (void *),
485 EXPORT_API int appcore_set_event_callback(enum appcore_event event,
486 int (*cb) (void *, void *), void *data)
488 struct appcore *ac = &core;
492 for (se = SE_UNKNOWN; se < SE_MAX; se++) {
493 if (event == to_ae[se])
497 if (se == SE_UNKNOWN || se >= SE_MAX) {
498 _ERR("Unregistered event");
513 EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops,
514 int argc, char **argv)
517 char dirname[PATH_MAX];
519 if (core.state != 0) {
520 _ERR("Already in use");
525 if (ops == NULL || ops->cb_app == NULL) {
526 _ERR("ops or callback function is null");
531 r = __get_dir_name(dirname);
532 SECURE_LOGD("dir : %s", dirname);
533 r = set_i18n(name, dirname);
534 _retv_if(r == -1, -1);
536 r = __add_vconf(&core);
538 _ERR("Add vconf callback failed");
542 r = aul_launch_init(__aul_handler, &core);
544 _ERR("Aul init failed: %d", r);
548 r = aul_launch_argv_handler(argc, argv);
550 _ERR("Aul argv handler failed: %d", r);
555 core.state = 1; /* TODO: use enum value */
566 EXPORT_API void appcore_exit(void)
575 EXPORT_API int appcore_flush_memory(void)
577 int (*flush_fn) (int);
580 struct appcore *ac = &core;
583 _ERR("Appcore not initialized");
587 //_DBG("[APP %d] Flushing memory ...", _pid);
589 if (ac->ops->cb_app) {
590 ac->ops->cb_app(AE_MEM_FLUSH, ac->ops->data, NULL);
593 flush_fn = dlsym(RTLD_DEFAULT, "sqlite3_release_memory");
595 size = flush_fn(SQLITE_FLUSH_MAX);
600 *Disabled - the impact of stack_trim() is unclear
604 //_DBG("[APP %d] Flushing memory DONE", _pid);