X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fappcore-efl.c;h=f0161b33d50e842e30e04c70103e13b4f67a59b5;hb=refs%2Ftags%2Faccepted%2Ftizen%2F3.0.m2%2Fwearable%2F20170104.122730;hp=8f3d9f3288629cddfdf660893f66ed1b461945ad;hpb=e5c06d1aa6bcb42993fcf05bd8fe7c1c30247bd4;p=platform%2Fcore%2Fappfw%2Fapp-core.git diff --git a/src/appcore-efl.c b/src/appcore-efl.c index 8f3d9f3..f0161b3 100644 --- a/src/appcore-efl.c +++ b/src/appcore-efl.c @@ -1,9 +1,5 @@ /* - * app-core - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Jayoun Lee , Sewook Park , Jaeho Lee + * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +12,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ #include @@ -29,7 +24,12 @@ #include #include -#ifndef WAYLAND +#if defined(WAYLAND) +#include +#include +#include +#include +#elif defined(X11) #include #include #include @@ -42,39 +42,20 @@ #include #include #include +#include #include #include +#include +#include +#include + #include "appcore-internal.h" #include "appcore-efl.h" -#define SYSMAN_MAXSTR 100 -#define SYSMAN_MAXARG 16 -#define SYSNOTI_SOCKET_PATH "/tmp/sn" -#define RETRY_READ_COUNT 10 - -#define PREDEF_BACKGRD "backgrd" -#define PREDEF_FOREGRD "foregrd" - -enum sysnoti_cmd { - ADD_SYSMAN_ACTION, - CALL_SYSMAN_ACTION -}; - -struct sysnoti { - int pid; - int cmd; - char *type; - char *path; - int argc; - char *argv[SYSMAN_MAXARG]; -}; - static pid_t _pid; - static bool resource_reclaiming = TRUE; static int tmp_val = 0; - struct ui_priv { const char *name; enum app_state state; @@ -82,19 +63,29 @@ struct ui_priv { Ecore_Event_Handler *hshow; Ecore_Event_Handler *hhide; Ecore_Event_Handler *hvchange; +#if defined(WAYLAND) + Ecore_Event_Handler *hlower; +#endif Ecore_Event_Handler *hcmsg; /* WM_ROTATE */ - Ecore_Timer *mftimer; /* Ecore Timer for memory flushing */ + Ecore_Timer *mftimer; /* Ecore Timer for memory flushing */ + struct appcore *app_core; +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + void (*prepare_to_suspend) (void *data); + void (*exit_from_suspend) (void *data); +#endif struct appcore_ops *ops; - void (*mfcb) (void); /* Memory Flushing Callback */ + void (*mfcb) (void); /* Memory Flushing Callback */ /* WM_ROTATE */ int wm_rot_supported; int rot_started; - int (*rot_cb) (enum appcore_rm, void *); + int (*rot_cb) (void *event_info, enum appcore_rm, void *); void *rot_cb_data; enum appcore_rm rot_mode; + bundle *pending_data; + char *below_app; }; static struct ui_priv priv; @@ -108,6 +99,7 @@ static const char *_ae_name[AE_MAX] = { [AE_RESET] = "RESET", [AE_LOWMEM_POST] = "LOWMEM_POST", [AE_MEM_FLUSH] = "MEM_FLUSH", + [AE_UPDATE_REQUESTED] = "UPDATE_REQUESTED", }; static const char *_as_name[] = { @@ -118,163 +110,166 @@ static const char *_as_name[] = { [AS_DYING] = "DYING", }; -static bool b_active = 0; +static bool b_active = FALSE; +static bool first_launch = TRUE; + struct win_node { unsigned int win; +#if defined(WAYLAND) + unsigned int surf; +#endif bool bfobscured; }; +#if defined(X11) static struct ui_wm_rotate wm_rotate; +#endif +static Eina_Bool __visibility_cb(void *data, int type, void *event); +static GSList *g_winnode_list; -static inline int send_int(int fd, int val) -{ - return write(fd, &val, sizeof(int)); -} +static struct wl_display *dsp; +static struct wl_registry *reg; +static struct tizen_policy *tz_policy; +static bool bg_state = false; -static inline int send_str(int fd, char *str) +static void __wl_listener_cb(void *data, struct wl_registry *reg, + uint32_t id, const char *interface, uint32_t ver) { - int len; - int ret; - if (str == NULL) { - len = 0; - ret = write(fd, &len, sizeof(int)); - } else { - len = strlen(str); - if (len > SYSMAN_MAXSTR) - len = SYSMAN_MAXSTR; - write(fd, &len, sizeof(int)); - ret = write(fd, str, len); + if (interface && !strcmp(interface, "tizen_policy")) { + if (!tz_policy) + tz_policy = wl_registry_bind(reg, id, + &tizen_policy_interface, 1); } - return ret; } -static int sysnoti_send(struct sysnoti *msg) +static void __wl_listener_remove_cb(void *data, struct wl_registry *reg, + unsigned int id) { - _ERR("--- %s: start", __FUNCTION__); - int client_len; - int client_sockfd; - int result; - int r; - int retry_count = 0; - struct sockaddr_un clientaddr; - int i; + /* do nothing */ +} + +static const struct wl_registry_listener reg_listener = { + __wl_listener_cb, + __wl_listener_remove_cb +}; - client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (client_sockfd == -1) { - _ERR("%s: socket create failed\n", __FUNCTION__); +static int __init_wl(void) +{ + _DBG("initialize wayland"); + dsp = wl_display_connect(NULL); + if (dsp == NULL) { + _ERR("Failed to connect wl display"); return -1; } - bzero(&clientaddr, sizeof(clientaddr)); - clientaddr.sun_family = AF_UNIX; - strncpy(clientaddr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1); - client_len = sizeof(clientaddr); - if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) < - 0) { - _ERR("%s: connect failed\n", __FUNCTION__); - close(client_sockfd); + reg = wl_display_get_registry(dsp); + if (reg == NULL) { + _ERR("Failed to get registry"); + wl_display_disconnect(dsp); return -1; } - send_int(client_sockfd, msg->pid); - send_int(client_sockfd, msg->cmd); - send_str(client_sockfd, msg->type); - send_str(client_sockfd, msg->path); - send_int(client_sockfd, msg->argc); - for (i = 0; i < msg->argc; i++) - send_str(client_sockfd, msg->argv[i]); + wl_registry_add_listener(reg, ®_listener, NULL); + wl_display_roundtrip(dsp); - _ERR("--- %s: read", __FUNCTION__); - while (retry_count < RETRY_READ_COUNT) { - r = read(client_sockfd, &result, sizeof(int)); - if (r < 0) { - if (errno == EINTR) { - _ERR("Re-read for error(EINTR)"); - retry_count++; - continue; - } - _ERR("Read fail for str length"); - result = -1; - break; - - } - break; - } - if (retry_count == RETRY_READ_COUNT) { - _ERR("Read retry failed"); + if (!tz_policy) { + _ERR("Failed to get tizen policy interface"); + wl_registry_destroy(reg); + wl_display_disconnect(dsp); + return -1; } - close(client_sockfd); - _ERR("--- %s: end", __FUNCTION__); - return result; + return 0; } -static int _call_predef_action(const char *type, int num, ...) +static void __finish_wl(void) { - _ERR("--- %s: start", __FUNCTION__); - struct sysnoti *msg; - int ret; - va_list argptr; - - int i; - char *args = NULL; - - if (type == NULL || num > SYSMAN_MAXARG) { - errno = EINVAL; - return -1; + if (tz_policy) { + tizen_policy_destroy(tz_policy); + tz_policy = NULL; } - msg = malloc(sizeof(struct sysnoti)); - - if (msg == NULL) { - /* Do something for not enought memory error */ - return -1; + if (reg) { + wl_registry_destroy(reg); + reg = NULL; } - msg->pid = getpid(); - msg->cmd = CALL_SYSMAN_ACTION; - msg->type = (char *)type; - msg->path = NULL; - - msg->argc = num; - va_start(argptr, num); - for (i = 0; i < num; i++) { - args = va_arg(argptr, char *); - msg->argv[i] = args; + if (dsp) { + wl_display_disconnect(dsp); + dsp = NULL; } - va_end(argptr); +} - _ERR("--- %s: send msg", __FUNCTION__); - ret = sysnoti_send(msg); - free(msg); +static void __set_bg_state(void) +{ + if (__init_wl() < 0) + return; - _ERR("--- %s: end", __FUNCTION__); - return ret; + tizen_policy_set_background_state(tz_policy, getpid()); + wl_display_roundtrip(dsp); + bg_state = true; + _DBG("bg state: %d", bg_state); } -static int _inform_foregrd(void) +static void __unset_bg_state(void) { - char buf[255]; - snprintf(buf, sizeof(buf), "%d", getpid()); - return _call_predef_action(PREDEF_FOREGRD, 1, buf); + if (!tz_policy) + return; + + tizen_policy_unset_background_state(tz_policy, getpid()); + wl_display_roundtrip(dsp); + bg_state = false; + _DBG("bg state: %d", bg_state); + __finish_wl(); } -static int _inform_backgrd(void) +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT +static void __appcore_efl_prepare_to_suspend(void *data) { - char buf[255]; - snprintf(buf, sizeof(buf), "%d", getpid()); - return _call_predef_action(PREDEF_BACKGRD, 1, buf); -} + struct ui_priv *ui = (struct ui_priv *)data; + struct sys_op *op = NULL; + int suspend = APPCORE_SUSPENDED_STATE_WILL_ENTER_SUSPEND; + if (ui->app_core && !ui->app_core->allowed_bg && !ui->app_core->suspended_state) { + op = &ui->app_core->sops[SE_SUSPENDED_STATE]; + if (op && op->func) + op->func((void *)&suspend, op->data); /* calls c-api handler */ + + ui->app_core->suspended_state = true; + } + _DBG("[__SUSPEND__]"); +} -static int WIN_COMP(gconstpointer data1, gconstpointer data2) +static void __appcore_efl_exit_from_suspend(void *data) { - struct win_node *a = (struct win_node *)data1; - struct win_node *b = (struct win_node *)data2; - return (int)((a->win)-(b->win)); + struct ui_priv *ui = (struct ui_priv *)data; + struct sys_op *op = NULL; + int suspend = APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND; + + if (ui->app_core && !ui->app_core->allowed_bg && ui->app_core->suspended_state) { + op = &ui->app_core->sops[SE_SUSPENDED_STATE]; + if (op && op->func) + op->func((void *)&suspend, op->data); /* calls c-api handler */ + + ui->app_core->suspended_state = false; + } + _DBG("[__SUSPEND__]"); } +#endif -GSList *g_winnode_list = NULL; +static void __appcore_efl_update_requested(void *data) +{ + struct ui_priv *ui = (struct ui_priv *)data; + struct sys_op *op; + int dummy = 0; + + if (ui->app_core) { + op = &ui->app_core->sops[SE_UPDATE_REQUESTED]; + if (op && op->func) + op->func((void *)&dummy, op->data); + } + _DBG("[__UPDATE_REQUESTED__]"); +} #if defined(MEMORY_FLUSH_ACTIVATE) static Eina_Bool __appcore_memory_flush_cb(void *data) @@ -282,18 +277,25 @@ static Eina_Bool __appcore_memory_flush_cb(void *data) struct ui_priv *ui = (struct ui_priv *)data; appcore_flush_memory(); - ui->mftimer = NULL; + if (ui) + ui->mftimer = NULL; + +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ui && ui->prepare_to_suspend) { + _DBG("[__SUSPEND__] flush case"); + ui->prepare_to_suspend(ui); + } +#endif return ECORE_CALLBACK_CANCEL; } static int __appcore_low_memory_post_cb(struct ui_priv *ui) { - if (ui->state == AS_PAUSED) { + if (ui->state == AS_PAUSED) appcore_flush_memory(); - } else { + else malloc_trim(0); - } return 0; } @@ -328,11 +330,44 @@ static void __appcore_efl_memory_flush_cb(void) _DBG("[APP %d] __appcore_efl_memory_flush_cb()", _pid); elm_cache_all_flush(); } +#if defined(WAYLAND) +static void wl_raise_win(void) +{ + Ecore_Wl_Window *win; + unsigned int win_id = appcore_get_main_window(); + + _DBG("Raise window: %d", win_id); + win = ecore_wl_window_find(win_id); + ecore_wl_window_activate(win); +} + +static void wl_pause_win(void) +{ + Ecore_Wl_Window *win; + GSList *wlist = g_winnode_list; + struct win_node *entry = NULL; + + _DBG("Pause window"); + + while (wlist) { + entry = wlist->data; + + _DBG("Pause window: %d", entry->win); + win = ecore_wl_window_find(entry->win); + ecore_wl_window_iconified_set(win, EINA_TRUE); + + wlist = wlist->next; + } +} + +#endif static void __do_app(enum app_event event, void *data, bundle * b) { int r = -1; struct ui_priv *ui = data; + const char *below_app; + const char *bg_launch; _DBG("[APP %d] Event: %d", _pid, event); _ret_if(ui == NULL || event >= AE_MAX); @@ -352,10 +387,33 @@ static void __do_app(enum app_event event, void *data, bundle * b) if (!(ui->state == AS_PAUSED && event == AE_PAUSE)) __appcore_timer_del(ui); + if (ui->state == AS_DYING) { + _ERR("Skip the event in dying state"); + return; + } + if (event == AE_TERMINATE) { _DBG("[APP %d] TERMINATE", _pid); - ui->state = AS_DYING; elm_exit(); + aul_status_update(STATUS_DYING); + return; + } + + if (event == AE_RAISE) { +#if defined(X11) + x_raise_win(getpid()); +#elif defined(WAYLAND) + wl_raise_win(); +#endif + return; + } + + if (event == AE_LOWER) { +#if defined(X11) + x_pause_win(getpid()); +#elif defined(WAYLAND) + wl_pause_win(); +#endif return; } @@ -364,46 +422,136 @@ static void __do_app(enum app_event event, void *data, bundle * b) switch (event) { case AE_RESET: _DBG("[APP %d] RESET", _pid); - LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", - ui->name); - if (ui->ops->reset) + if (ui->pending_data) + bundle_free(ui->pending_data); + ui->pending_data = bundle_dup(b); + LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", ui->name); + + if (ui->below_app) { + free(ui->below_app); + ui->below_app = NULL; + } + + below_app = bundle_get_val(b, AUL_SVC_K_RELOCATE_BELOW); + if (below_app) + ui->below_app = strdup(below_app); +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ui->exit_from_suspend) { + _DBG("[__SUSPEND__] reset case"); + ui->exit_from_suspend(ui); + } +#endif + + if (ui->ops->reset) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:RESET"); r = ui->ops->reset(b, ui->ops->data); - ui->state = AS_RUNNING; + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } + LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", ui->name); + + if (first_launch) { +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ui->app_core->allowed_bg) + __appcore_timer_add(ui); +#endif + first_launch = FALSE; + } else { + _INFO("[APP %d] App already running, raise the window", _pid); + if (bg_state) { + bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH); + if (!bg_launch || strcmp(bg_launch, "enable")) + __unset_bg_state(); + } +#ifdef X11 + x_raise_win(getpid()); +#else + wl_raise_win(); +#endif + } LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", ui->name); break; case AE_PAUSE: if (ui->state == AS_RUNNING) { _DBG("[APP %d] PAUSE", _pid); - if (ui->ops->pause) + if (ui->ops->pause) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:PAUSE"); r = ui->ops->pause(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } ui->state = AS_PAUSED; - if(r >= 0 && resource_reclaiming == TRUE) + if (r >= 0 && resource_reclaiming == TRUE) __appcore_timer_add(ui); +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + else if (r >= 0 && resource_reclaiming == FALSE + && ui->prepare_to_suspend) { + _DBG("[__SUSPEND__] pause case"); + ui->prepare_to_suspend(ui); + } +#endif } /* TODO : rotation stop */ - //r = appcore_pause_rotation_cb(); - - _inform_backgrd(); + /* r = appcore_pause_rotation_cb(); */ + aul_status_update(STATUS_BG); break; case AE_RESUME: LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", - ui->name); - if (ui->state == AS_PAUSED || tmp_val == 1) { + ui->name); +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ui->exit_from_suspend) { + _DBG("[__SUSPEND__] resume case"); + ui->exit_from_suspend(ui); + } + if (ui->app_core->allowed_bg) + __appcore_timer_del(ui); +#endif + + if (ui->state == AS_PAUSED || ui->state == AS_CREATED) { _DBG("[APP %d] RESUME", _pid); - if (ui->ops->resume) - r = ui->ops->resume(ui->ops->data); + + if (ui->state == AS_CREATED) { + bundle_free(ui->pending_data); + ui->pending_data = NULL; + } + + if (ui->ops->resume) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:RESUME"); + ui->ops->resume(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } ui->state = AS_RUNNING; - tmp_val = 0; + + if (ui->below_app) { + aul_app_group_activate_below(ui->below_app); + free(ui->below_app); + ui->below_app = NULL; + } } /*TODO : rotation start*/ - //r = appcore_resume_rotation_cb(); + /* r = appcore_resume_rotation_cb(); */ LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", ui->name); LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:Launching:done]", ui->name); - _inform_foregrd(); - + aul_status_update(STATUS_VISIBLE); + break; + case AE_TERMINATE_BGAPP: + if (ui->state == AS_PAUSED) { + _DBG("[APP %d] is paused. TERMINATE", _pid); + ui->state = AS_DYING; + aul_status_update(STATUS_DYING); + elm_exit(); + } else if (ui->state == AS_RUNNING) { + _DBG("[APP %d] is running.", _pid); + } else { + _DBG("[APP %d] is another state", _pid); + } + break; + case AE_UPDATE_REQUESTED: + __appcore_efl_update_requested(ui); break; default: /* do nothing */ @@ -416,44 +564,52 @@ static struct ui_ops efl_ops = { .cb_app = __do_app, }; - static bool __check_visible(void) { GSList *iter = NULL; struct win_node *entry = NULL; _DBG("[EVENT_TEST][EVENT] __check_visible\n"); - + for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; + entry = iter->data; _DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured); - if(entry->bfobscured == FALSE) - return TRUE; + if (entry->bfobscured == FALSE) + return TRUE; } + return FALSE; } -static bool __exist_win(unsigned int win) +static GSList *__find_win(unsigned int win) { - struct win_node temp; - GSList *f; - - temp.win = win; + GSList *iter; + struct win_node *t; - f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP); - if (f == NULL) { - return FALSE; - } else { - return TRUE; + for (iter = g_winnode_list; iter; iter = g_slist_next(iter)) { + t = iter->data; + if (t && t->win == win) + return iter; } + return NULL; } +#if defined(X11) static bool __add_win(unsigned int win) { struct win_node *t; GSList *f; + _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win); + + f = __find_win(win); + if (f) { + errno = ENOENT; + _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win); + return FALSE; + } + t = calloc(1, sizeof(struct win_node)); if (t == NULL) return FALSE; @@ -461,84 +617,107 @@ static bool __add_win(unsigned int win) t->win = win; t->bfobscured = FALSE; - _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win); + g_winnode_list = g_slist_append(g_winnode_list, t); - f = g_slist_find_custom(g_winnode_list, t, WIN_COMP); + return TRUE; +} +#elif defined(WAYLAND) +static bool __add_win(unsigned int win, unsigned int surf) +{ + struct win_node *t; + GSList *f; + + _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win); + f = __find_win(win); if (f) { errno = ENOENT; _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win); - free(t); - return 0; + return FALSE; } + t = calloc(1, sizeof(struct win_node)); + if (t == NULL) + return FALSE; + + t->win = win; + t->surf = surf; + t->bfobscured = FALSE; + g_winnode_list = g_slist_append(g_winnode_list, t); return TRUE; - } +#endif static bool __delete_win(unsigned int win) { - struct win_node temp; GSList *f; - temp.win = win; - - f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP); - if (f == NULL) { + f = __find_win(win); + if (!f) { errno = ENOENT; _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", - win); - return 0; + win); + return FALSE; } - g_winnode_list = g_slist_remove_link(g_winnode_list, f); - free(f->data); + g_winnode_list = g_slist_delete_link(g_winnode_list, f); return TRUE; } +#if defined(X11) static bool __update_win(unsigned int win, bool bfobscured) { - struct win_node temp; GSList *f; - struct win_node *t; _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win, bfobscured); - temp.win = win; - - f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP); - - if (f == NULL) { + f = __find_win(win); + if (!f) { errno = ENOENT; _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win); return FALSE; } - g_winnode_list = g_slist_remove_link(g_winnode_list, f); + t = (struct win_node *)f->data; + t->win = win; + t->bfobscured = bfobscured; - free(f->data); + return TRUE; +} +#elif defined(WAYLAND) +static bool __update_win(unsigned int win, unsigned int surf, bool bfobscured) +{ + GSList *f; + struct win_node *t; - t = calloc(1, sizeof(struct win_node)); - if (t == NULL) + _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win, + bfobscured); + + f = __find_win(win); + if (!f) { + errno = ENOENT; + _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win); return FALSE; + } + t = (struct win_node *)f->data; t->win = win; + if (surf != 0) + t->surf = surf; t->bfobscured = bfobscured; - g_winnode_list = g_slist_append(g_winnode_list, t); - return TRUE; - } +#endif /* WM_ROTATE */ -#ifndef WAYLAND +#ifdef X11 static Ecore_X_Atom _WM_WINDOW_ROTATION_SUPPORTED = 0; static Ecore_X_Atom _WM_WINDOW_ROTATION_CHANGE_REQUEST = 0; @@ -565,8 +744,7 @@ static int __check_wm_rotation_support(void) _WM_WINDOW_ROTATION_SUPPORTED, ECORE_X_ATOM_WINDOW, &win, 1); - if ((ret == 1) && (win)) - { + if ((ret == 1) && (win)) { ret = ecore_x_window_prop_xid_get(win, _WM_WINDOW_ROTATION_SUPPORTED, ECORE_X_ATOM_WINDOW, @@ -583,7 +761,7 @@ static void __set_wm_rotation_support(unsigned int win, unsigned int set) GSList *iter = NULL; struct win_node *entry = NULL; - if (0 == win) { + if (win == 0) { for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) { entry = iter->data; if (entry->win) { @@ -598,126 +776,163 @@ static void __set_wm_rotation_support(unsigned int win, unsigned int set) &set, 1); } } - -Ecore_X_Atom atom_parent; #endif static Eina_Bool __show_cb(void *data, int type, void *event) { -#ifndef WAYLAND - Ecore_X_Event_Window_Show *ev; - int ret; - Ecore_X_Window parent; +#if defined(WAYLAND) + Ecore_Wl_Event_Window_Show *ev; ev = event; - - ret = ecore_x_window_prop_window_get(ev->win, atom_parent, &parent, 1); - if (ret != 1) - { - // This is child window. Skip!!! + if (ev->parent_win != 0) { + /* This is child window. Skip!!! */ return ECORE_CALLBACK_PASS_ON; } + _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x, %d\n", ev->win, ev->data[0]); + + if (!__find_win((unsigned int)ev->win)) + __add_win((unsigned int)ev->win, (unsigned int)ev->data[0]); + else + __update_win((unsigned int)ev->win, (unsigned int)ev->data[0], FALSE); + +#elif defined(X11) + Ecore_X_Event_Window_Show *ev; + + ev = event; + _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x\n", ev->win); - if (!__exist_win((unsigned int)ev->win)) { + if (!__find_win((unsigned int)ev->win)) { /* WM_ROTATE */ - if ((priv.wm_rot_supported) && (1 == priv.rot_started)) { + if ((priv.wm_rot_supported) && (1 == priv.rot_started)) __set_wm_rotation_support(ev->win, 1); - } __add_win((unsigned int)ev->win); - } - else + } else { __update_win((unsigned int)ev->win, FALSE); + } #endif + appcore_group_attach(); return ECORE_CALLBACK_RENEW; } static Eina_Bool __hide_cb(void *data, int type, void *event) { -#ifndef WAYLAND +#if defined(WAYLAND) + Ecore_Wl_Event_Window_Hide *ev; +#elif defined(X11) Ecore_X_Event_Window_Hide *ev; +#endif int bvisibility = 0; ev = event; _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win); - if (__exist_win((unsigned int)ev->win)) { + if (__find_win((unsigned int)ev->win)) { __delete_win((unsigned int)ev->win); - bvisibility = __check_visible(); - if (!bvisibility && b_active == 1) { + if (!bvisibility && b_active == TRUE) { _DBG(" Go to Pasue state \n"); - b_active = 0; + b_active = FALSE; __do_app(AE_PAUSE, data, NULL); } } -#endif return ECORE_CALLBACK_RENEW; } +#if defined(WAYLAND) +static Eina_Bool __lower_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Lower *ev; + ev = event; + if (!ev) return ECORE_CALLBACK_RENEW; + _DBG("ECORE_WL_EVENT_WINDOW_LOWER window id:%u\n", ev->win); + appcore_group_lower(); + return ECORE_CALLBACK_RENEW; +} +#endif + static Eina_Bool __visibility_cb(void *data, int type, void *event) { -#ifndef WAYLAND +#if defined(WAYLAND) + Ecore_Wl_Event_Window_Visibility_Change *ev; + int bvisibility = 0; + ev = event; + __update_win((unsigned int)ev->win, 0, ev->fully_obscured); +#elif defined(X11) Ecore_X_Event_Window_Visibility_Change *ev; int bvisibility = 0; ev = event; __update_win((unsigned int)ev->win, ev->fully_obscured); +#endif bvisibility = __check_visible(); - if (bvisibility && b_active == 0) { + _DBG("bvisibility %d, b_active %d", bvisibility, b_active); + + if (bvisibility && b_active == FALSE) { _DBG(" Go to Resume state\n"); - b_active = 1; + b_active = TRUE; __do_app(AE_RESUME, data, NULL); - } else if (!bvisibility && b_active == 1) { + } else if (!bvisibility && b_active == TRUE) { _DBG(" Go to Pasue state \n"); - b_active = 0; + b_active = FALSE; __do_app(AE_PAUSE, data, NULL); } else _DBG(" No change state \n"); -#endif return ECORE_CALLBACK_RENEW; } -#ifndef WAYLAND +#if defined(X11) /* WM_ROTATE */ static Eina_Bool __cmsg_cb(void *data, int type, void *event) { struct ui_priv *ui = (struct ui_priv *)data; Ecore_X_Event_Client_Message *e = event; - if (!ui) return ECORE_CALLBACK_PASS_ON; - if (e->format != 32) return ECORE_CALLBACK_PASS_ON; + if (!ui) + return ECORE_CALLBACK_PASS_ON; + + if (e->format != 32) + return ECORE_CALLBACK_PASS_ON; + if (e->message_type == _WM_WINDOW_ROTATION_CHANGE_REQUEST) { - if ((0 == ui->wm_rot_supported) || - (0 == ui->rot_started) || - (NULL == ui->rot_cb)) { + if ((ui->wm_rot_supported == 0) + || (ui->rot_started == 0) + || (ui->rot_cb == NULL)) { return ECORE_CALLBACK_PASS_ON; } enum appcore_rm rm; - switch (e->data.l[1]) - { - case 0: rm = APPCORE_RM_PORTRAIT_NORMAL; break; - case 90: rm = APPCORE_RM_LANDSCAPE_REVERSE; break; - case 180: rm = APPCORE_RM_PORTRAIT_REVERSE; break; - case 270: rm = APPCORE_RM_LANDSCAPE_NORMAL; break; - default: rm = APPCORE_RM_UNKNOWN; break; + switch (e->data.l[1]) { + case 0: + rm = APPCORE_RM_PORTRAIT_NORMAL; + break; + case 90: + rm = APPCORE_RM_LANDSCAPE_REVERSE; + break; + case 180: + rm = APPCORE_RM_PORTRAIT_REVERSE; + break; + case 270: + rm = APPCORE_RM_LANDSCAPE_NORMAL; + break; + default: + rm = APPCORE_RM_UNKNOWN; + break; } ui->rot_mode = rm; - if (APPCORE_RM_UNKNOWN != rm) { - ui->rot_cb(rm, ui->rot_cb_data); - } + if (APPCORE_RM_UNKNOWN != rm) + ui->rot_cb((void *)&rm, rm, ui->rot_cb_data); } return ECORE_CALLBACK_PASS_ON; @@ -727,26 +942,30 @@ static Eina_Bool __cmsg_cb(void *data, int type, void *event) static void __add_climsg_cb(struct ui_priv *ui) { _ret_if(ui == NULL); -#ifndef WAYLAND - atom_parent = ecore_x_atom_get("_E_PARENT_BORDER_WINDOW"); - if (!atom_parent) - { - // Do Error Handling - } - +#if defined(WAYLAND) + ui->hshow = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __show_cb, ui); + ui->hhide = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __hide_cb, ui); + ui->hvchange = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, + __visibility_cb, ui); + ui->hlower = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, + __lower_cb, ui); +#elif defined(X11) ui->hshow = - ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, __show_cb, ui); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, __show_cb, ui); ui->hhide = - ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, __hide_cb, ui); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, __hide_cb, ui); ui->hvchange = - ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, - __visibility_cb, ui); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, + __visibility_cb, ui); /* Add client message callback for WM_ROTATE */ - if(!__check_wm_rotation_support()) - { - ui->hcmsg = - ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __cmsg_cb, ui); + if (!__check_wm_rotation_support()) { + ui->hcmsg = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + __cmsg_cb, ui); ui->wm_rot_supported = 1; appcore_set_wm_rotation(&wm_rotate); } @@ -757,6 +976,11 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv) { int r; char *hwacc = NULL; +#if _APPFW_FEATURE_BACKGROUND_MANAGEMENT + struct appcore *ac = NULL; +#endif + bundle *b; + const char *bg_launch; if (argc == NULL || argv == NULL) { _ERR("argc/argv is NULL"); @@ -764,42 +988,56 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv) return -1; } +#if !(GLIB_CHECK_VERSION(2, 36, 0)) g_type_init(); +#endif elm_init(*argc, *argv); hwacc = getenv("HWACC"); - - if(hwacc == NULL) { - _DBG("elm_config_preferred_engine_set is not called"); - } else if(strcmp(hwacc, "USE") == 0) { -#ifdef WAYLAND - elm_config_preferred_engine_set("wayland_egl"); - _DBG("elm_config_preferred_engine_set : wayland_egl"); -#else - elm_config_preferred_engine_set("opengl_x11"); - _DBG("elm_config_preferred_engine_set : opengl_x11"); -#endif - } else if(strcmp(hwacc, "NOT_USE") == 0) { -#ifdef WAYLAND - elm_config_preferred_engine_set("wayland_shm"); - _DBG("elm_config_preferred_engine_set : wayland_shm"); -#else - elm_config_preferred_engine_set("software_x11"); - _DBG("elm_config_preferred_engine_set : software_x11"); -#endif + if (hwacc == NULL) { + _DBG("elm_config_accel_preference_set is not called"); + } else if (strcmp(hwacc, "USE") == 0) { + elm_config_accel_preference_set("hw"); + _DBG("elm_config_accel_preference_set : hw"); + } else if (strcmp(hwacc, "NOT_USE") == 0) { + elm_config_accel_preference_set("none"); + _DBG("elm_config_accel_preference_set : none"); } else { - _DBG("elm_config_preferred_engine_set is not called"); + _DBG("elm_config_accel_preference_set is not called"); } r = appcore_init(ui->name, &efl_ops, *argc, *argv); _retv_if(r == -1, -1); +#if _APPFW_FEATURE_BACKGROUND_MANAGEMENT + appcore_get_app_core(&ac); + ui->app_core = ac; + SECURE_LOGD("[__SUSPEND__] appcore initialized, appcore addr: #%x", ac); +#endif + + b = bundle_import_from_argv(*argc, *argv); + if (b) { + bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH); + if (bg_launch && strcmp(bg_launch, "enable") == 0) + __set_bg_state(); + + bundle_free(b); + } + LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:appcore_init:done]", ui->name); if (ui->ops && ui->ops->create) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE"); r = ui->ops->create(ui->ops->data); - if (r == -1) { + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + if (r < 0) { _ERR("create() return error"); appcore_exit(); + if (ui->ops && ui->ops->terminate) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:TERMINATE"); + ui->ops->terminate(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } errno = ECANCELED; return -1; } @@ -818,8 +1056,23 @@ static void __after_loop(struct ui_priv *ui) appcore_unset_rotation_cb(); appcore_exit(); - if (ui->ops && ui->ops->terminate) + if (ui->state == AS_RUNNING) { + _DBG("[APP %d] PAUSE before termination", _pid); + if (ui->ops && ui->ops->pause) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:PAUSE"); + ui->ops->pause(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } + } + + if (ui->ops && ui->ops->terminate) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE"); ui->ops->terminate(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } + + ui->state = AS_DYING; if (ui->hshow) ecore_event_handler_del(ui->hshow); @@ -827,10 +1080,20 @@ static void __after_loop(struct ui_priv *ui) ecore_event_handler_del(ui->hhide); if (ui->hvchange) ecore_event_handler_del(ui->hvchange); +#if defined(WAYLAND) + if (ui->hlower) + ecore_event_handler_del(ui->hlower); +#endif __appcore_timer_del(ui); elm_shutdown(); + + /* Check loader case */ + if (getenv("AUL_LOADER_INIT")) { + unsetenv("AUL_LOADER_INIT"); + elm_shutdown(); + } } static int __set_data(struct ui_priv *ui, const char *name, @@ -858,9 +1121,7 @@ static int __set_data(struct ui_priv *ui, const char *name, _retv_if(ui->name == NULL, -1); ui->ops = ops; - ui->mfcb = __appcore_efl_memory_flush_cb; - _pid = getpid(); /* WM_ROTATE */ @@ -870,6 +1131,12 @@ static int __set_data(struct ui_priv *ui, const char *name, ui->rot_cb_data = NULL; ui->rot_mode = APPCORE_RM_UNKNOWN; +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + ui->app_core = NULL; + ui->prepare_to_suspend = __appcore_efl_prepare_to_suspend; + ui->exit_from_suspend = __appcore_efl_exit_from_suspend; +#endif + return 0; } @@ -881,17 +1148,17 @@ static void __unset_data(struct ui_priv *ui) memset(ui, 0, sizeof(struct ui_priv)); } +#if defined(X11) /* WM_ROTATE */ -static int __wm_set_rotation_cb(int (*cb) (enum appcore_rm, void *), void *data) +static int __wm_set_rotation_cb(int (*cb) (void *event_info, enum appcore_rm, void *), void *data) { if (cb == NULL) { errno = EINVAL; return -1; } - if ((priv.wm_rot_supported) && (0 == priv.rot_started)) { + if ((priv.wm_rot_supported) && (0 == priv.rot_started)) __set_wm_rotation_support(0, 1); - } priv.rot_cb = cb; priv.rot_cb_data = data; @@ -902,9 +1169,8 @@ static int __wm_set_rotation_cb(int (*cb) (enum appcore_rm, void *), void *data) static int __wm_unset_rotation_cb(void) { - if ((priv.wm_rot_supported) && (1 == priv.rot_started)) { + if ((priv.wm_rot_supported) && (1 == priv.rot_started)) __set_wm_rotation_support(0, 0); - } priv.rot_cb = NULL; priv.rot_cb_data = NULL; @@ -927,9 +1193,8 @@ static int __wm_get_rotation_state(enum appcore_rm *curr) static int __wm_pause_rotation_cb(void) { - if ((1 == priv.rot_started) && (priv.wm_rot_supported)) { + if ((priv.rot_started == 1) && (priv.wm_rot_supported)) __set_wm_rotation_support(0, 0); - } priv.rot_started = 0; @@ -938,9 +1203,8 @@ static int __wm_pause_rotation_cb(void) static int __wm_resume_rotation_cb(void) { - if ((0 == priv.rot_started) && (priv.wm_rot_supported)) { + if ((priv.rot_started == 0) && (priv.wm_rot_supported)) __set_wm_rotation_support(0, 1); - } priv.rot_started = 1; @@ -954,9 +1218,10 @@ static struct ui_wm_rotate wm_rotate = { __wm_pause_rotation_cb, __wm_resume_rotation_cb }; +#endif -EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, - struct appcore_ops *ops) +EXPORT_API int appcore_efl_init(const char *name, int *argc, char ***argv, + struct appcore_ops *ops) { int r; @@ -967,17 +1232,34 @@ EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, r = __before_loop(&priv, argc, argv); if (r == -1) { + aul_status_update(STATUS_DYING); __unset_data(&priv); return -1; } - elm_run(); + return 0; +} +EXPORT_API void appcore_efl_fini(void) +{ aul_status_update(STATUS_DYING); __after_loop(&priv); __unset_data(&priv); +} + +EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, + struct appcore_ops *ops) +{ + int r; + + r = appcore_efl_init(name, argc, argv, ops); + _retv_if(r == -1, -1); + + elm_run(); + + appcore_efl_fini(); return 0; } @@ -997,3 +1279,58 @@ EXPORT_API int appcore_set_app_state(int state) return 0; } + +EXPORT_API int appcore_set_preinit_window_name(const char *win_name) +{ + int ret = -1; + void *preinit_window = NULL; + const Evas *e = NULL; + + if (!win_name) { + _ERR("invalid parameter"); + return ret; + } + + preinit_window = elm_win_precreated_object_get(); + if (!preinit_window) { + _ERR("Failed to get preinit window"); + return ret; + } + + e = evas_object_evas_get((const Evas_Object *)preinit_window); + if (e) { + Ecore_Evas *ee = ecore_evas_ecore_evas_get(e); + if (ee) { + ecore_evas_name_class_set(ee, win_name, win_name); + ret = 0; + } + } + + return ret; +} + +EXPORT_API unsigned int appcore_get_main_window(void) +{ + struct win_node *entry = NULL; + + if (g_winnode_list != NULL) { + entry = g_winnode_list->data; + return (unsigned int) entry->win; + } + + return 0; +} + +#if defined(WAYLAND) +EXPORT_API unsigned int appcore_get_main_surface(void) +{ + struct win_node *entry = NULL; + + if (g_winnode_list != NULL) { + entry = g_winnode_list->data; + return (unsigned int) entry->surf; + } + + return 0; +} +#endif