From: jk7744.park Date: Sat, 24 Oct 2015 07:28:52 +0000 (+0900) Subject: tizen 2.4 release X-Git-Tag: accepted/tizen/2.4/mobile/20151029.034209^0 X-Git-Url: http://review.tizen.org/git/?p=framework%2Fappfw%2Fapp-core.git;a=commitdiff_plain;h=d0109a92dbe5182fbd0656e222860809a0a52bb2 tizen 2.4 release --- diff --git a/CMakeLists.txt b/CMakeLists.txt index fb908e8..8d18333 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,8 +30,16 @@ SET(SRCS_common src/appcore.c src/appcore-i18n.c src/appcore-measure.c SET(HEADERS_common appcore-common.h) INCLUDE(FindPkgConfig) -#pkg_check_modules(pkg_common REQUIRED pmapi vconf sensor aul rua dlog x11) -pkg_check_modules(pkg_common REQUIRED vconf sensor aul dlog x11 ecore-x ) +SET(pkg_common_requires "vconf aul dlog x11 ecore-x ttrace iniparser dbus-1") +SET(pc_requires "vconf aul dlog x11") + +IF(_APPFW_FEATURE_SENSOR_AUTO_ROTATION) + SET(pkg_common_requires "${pkg_common_requires} sensor") + SET(pc_requires "${pc_requires} sensor") + ADD_DEFINITIONS("-D_APPFW_FEATURE_SENSOR_AUTO_ROTATION") +ENDIF(_APPFW_FEATURE_SENSOR_AUTO_ROTATION) + +pkg_check_modules(pkg_common REQUIRED ${pkg_common_requires}) FOREACH(flag ${pkg_common_CFLAGS}) SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} ${flag}") ENDFOREACH(flag) @@ -44,12 +52,21 @@ IF(_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS) ADD_DEFINITIONS("-D_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS") ENDIF(_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS) +IF(_APPFW_FEATURE_EXPANSION_PKG_INSTALL) + ADD_DEFINITIONS("-D_APPFW_FEATURE_EXPANSION_PKG_INSTALL") +ENDIF(_APPFW_FEATURE_EXPANSION_PKG_INSTALL) + +IF(_APPFW_FEATURE_BACKGROUND_MANAGEMENT) + ADD_DEFINITIONS("-D_APPFW_FEATURE_BACKGROUND_MANAGEMENT") +ENDIF(_APPFW_FEATURE_BACKGROUND_MANAGEMENT) + ADD_LIBRARY(${APPCORE_COMMON} SHARED ${SRCS_common}) SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES SOVERSION ${VERSION_MAJOR}) SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES VERSION ${VERSION}) SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_common}) TARGET_LINK_LIBRARIES(${APPCORE_COMMON} ${pkg_common_LDFLAGS} "-ldl") +SET(PC_REQUIRED ${pc_requires}) CONFIGURE_FILE(${APPCORE_COMMON}.pc.in ${APPCORE_COMMON}.pc @ONLY) INSTALL(TARGETS ${APPCORE_COMMON} DESTINATION lib COMPONENT RuntimeLibraries) @@ -63,12 +80,12 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/SLP_Appcore_PG.h DESTINATION i # Build appcore-efl Library # ------------------------------ SET(APPCORE_EFL "appcore-efl") -SET(SRCS_efl src/appcore-efl.c src/virtual_canvas.c) +SET(SRCS_efl src/appcore-efl.c src/appcore-group.c src/virtual_canvas.c) SET(HEADERS_efl appcore-efl.h) INCLUDE(FindPkgConfig) -pkg_check_modules(pkg_efl REQUIRED elementary dlog ecore ecore-x gobject-2.0 glib-2.0 x11 xcomposite ecore-evas ecore-input aul evas vconf) +pkg_check_modules(pkg_efl REQUIRED elementary dlog ecore ecore-x gobject-2.0 glib-2.0 x11 xcomposite ecore-evas ecore-input aul evas vconf pkgmgr-info ttrace dbus-glib-1) FOREACH(flag ${pkg_efl_CFLAGS}) SET(EXTRA_CFLAGS_efl "${EXTRA_CFLAGS_efl} ${flag}") ENDFOREACH(flag) diff --git a/appcore-common.pc.in b/appcore-common.pc.in index 233ccde..c735904 100644 --- a/appcore-common.pc.in +++ b/appcore-common.pc.in @@ -8,6 +8,6 @@ includedir=@INCLUDEDIR@ Name: app-core-common Description: SAMSUNG Linux platform application library Version: @VERSION@ -Requires: sensor vconf aul dlog x11 +Requires: @PC_REQUIRED@ Libs: -L${libdir} -lappcore-common Cflags: -I${includedir} -I${includedir}/appcore diff --git a/include/appcore-common.h b/include/appcore-common.h index f0b5b44..760bd3d 100755 --- a/include/appcore-common.h +++ b/include/appcore-common.h @@ -65,15 +65,17 @@ extern "C" { */ enum appcore_event { APPCORE_EVENT_UNKNOWN, - /**< Unknown event */ + /**< Unknown event */ APPCORE_EVENT_LOW_MEMORY, - /**< Low memory */ + /**< Low memory */ APPCORE_EVENT_LOW_BATTERY, - /**< Low battery */ + /**< Low battery */ APPCORE_EVENT_LANG_CHANGE, - /**< Language setting is changed */ + /**< Language setting is changed */ APPCORE_EVENT_REGION_CHANGE, - /**< Region setting is changed */ + /**< Region setting is changed */ + APPCORE_EVENT_SUSPENDED_STATE_CHANGE, + /**< The suspended state is changed */ }; /** @@ -103,6 +105,12 @@ enum appcore_time_format { APPCORE_TIME_FORMAT_24, }; + +enum appcore_suspended_state { + APPCORE_SUSPENDED_STATE_WILL_ENTER_SUSPEND = 0, + APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND +}; + /** * Appcore operations which are called during the application life-cycle * @see appcore_efl_main() @@ -136,10 +144,10 @@ struct appcore_ops { * * @par Typical use case: * To do something when predefined events (enum appcore_event) occur, use this API - * + * * @par Method of function operation: * Using Heynoti subscription, Vconf changed callback, and AUL, Appcore invokes the registered callback function. - * + * * @par Important notes: * Only one callback function can be set. If cb is NULL, unset the callback function about the event.\n * Default behavior is performed when the specified event callback doesn't have registered. @@ -148,7 +156,7 @@ struct appcore_ops { * @param[in] cb callback function * @param[in] data callback function data * - * @return 0 on success, -1 on error (errno set) + * @return 0 on success, -1 on error (errno set) * * @par Errors: * EINVAL - Invalid event type @@ -214,18 +222,18 @@ int appcore_set_event_callback(enum appcore_event event, * * @par Typical use case: * To do something when the rotation mode is changed, use this API - * + * * @par Method of function operation: * Appcore receives rotation change from Sensor framework. When Appcore receive the change, it invokes the registered callback function. - * + * * @par Important notes: * Locks the rotation mode, the registered callback is not invoked. * * @param[in] cb callback function * @param[in] data callback function data * - * @return 0 on success, -1 on error (errno set) - * + * @return 0 on success, -1 on error (errno set) + * * @par Errors: * EINVAL - cb is NULL * EALREADY - rotation callback function already registered @@ -268,7 +276,7 @@ int appcore_set_rotation_cb(int (*cb) (void *event_info, enum appcore_rm, void * * This function unsets a callback function for rotation events. * * @return 0 on success, -1 on error - * + * * @pre Callback is set by appcore_set_rotation_cb(). * @post None. * @see appcore_set_rotation_cb(), appcore_get_rotation_state() @@ -305,12 +313,12 @@ int appcore_unset_rotation_cb(void); * * @par Method of function operation: * This function gets the current rotation mode from Sensor framework. - * + * * @param[out] curr current rotation mode\n * If Sensor framework is not working, curr is set to APPCORE_RM_UNKNOWN. * - * @return 0 on success, -1 on error (errno set) - * + * @return 0 on success, -1 on error (errno set) + * * @par Errors: * EINVAL - curr is NULL * @@ -330,7 +338,7 @@ int appcore_unset_rotation_cb(void); enum appcore_rm curr; ... - + r = appcore_get_rotation_state(&curr); if (r == -1) { // add exception handling @@ -351,12 +359,12 @@ int appcore_get_rotation_state(enum appcore_rm *curr); * * @par Method of function operation: * This function gets the current time format from vconf. - * + * * @param[out] timeformat current time format\n * If vconf is not working, timeformat is set to APPCORE_TIME_FORMAT_UNKNOWN. * - * @return 0 on success, -1 on error (errno set) - * + * @return 0 on success, -1 on error (errno set) + * * @par Errors: * EINVAL - timeformat is NULL * @@ -376,7 +384,7 @@ int appcore_get_rotation_state(enum appcore_rm *curr); enum appcore_time_format timeformat; ... - + r = appcore_get_timeformat(&timeformat); if (r == -1) { // add exception handling @@ -390,6 +398,51 @@ int appcore_get_timeformat(enum appcore_time_format *timeformat); /** * @par Description: + * Gets the localized translation. + * + * @par Purpose: + * To get the localized translation string, use this API. + * + * @par Method of function operation: + * This function gets the translation string from localization file(.po file). + * + * @param[in] message id for string to be translated\n + * + * @return The localized translation for the given message on success, + * otherwise the given message + * The resulting string is statically allocated and must not be modified or freed. + * @par Errors: + * EINVAL - msgid is NULL + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include + +... + +{ + char *str; + + ... + + str = appcore_get_i18n_text("IDS_STRING"); + if (str == "IDS_STRING") { + // add exception handling + } + ... +} + * @endcode + * + */ +char *appcore_get_i18n_text(const char *msgid); + +/** + * @par Description: * Set the information for the internationalization. * * @par Purpose: @@ -397,18 +450,18 @@ int appcore_get_timeformat(enum appcore_time_format *timeformat); * * @par Typical use case: * This function provides convenience for using gettext. - * + * * @par Method of function operation: * Calls setlocale(), bindtextdomain() and textdomain() internally. - * + * * @par Corner cases/exceptions: * If dirname is NULL, the previously set base directory is used. Typically, it is /usr/share/locale. * * @param[in] domainname a message domain name(text domain name) \n Must be a non-empty string. - * @param[in] dirname the base directory for message catalogs belonging to the specified domain \n + * @param[in] dirname the base directory for message catalogs belonging to the specified domain \n + * + * @return 0 on success, -1 on error (errno set) * - * @return 0 on success, -1 on error (errno set) - * * @par Errors: * EINVAL - domain is NULL * @@ -430,7 +483,7 @@ int appcore_get_timeformat(enum appcore_time_format *timeformat); r = appcore_set_i18n("i18n_example", NULL); if (r == -1) { - // add exception handling + // add exception handling } ... } @@ -441,18 +494,18 @@ int appcore_set_i18n(const char *domainname, const char *dirname); /** * @par Description: - * Set the measuring start time + * Set the measuring start time * * @par Purpose: * To measure the time, the start time should be set. This function set the start point. * * @par Typical use case: * It is used to measure the time for doing something. \n - * This function set the start point. And, appcore_measure_time() returns + * This function set the start point. And, appcore_measure_time() returns * the elapsed time from the start point. * * @see appcore_measure_time() - * + * * @par Method of function operation: * Store the current time to the internal variable. * @@ -492,7 +545,7 @@ void appcore_measure_start(void); * This function returns the elapsed time from the start point set by appcore_measure_start(). * * @see appcore_measure_start() - * + * * @par Method of function operation: * This function subtracts the current time from the start point. * @@ -537,7 +590,7 @@ int appcore_measure_time(void); * This function returns the elapsed time from a time specified in environment variable. * * @see appcore_measure_start() - * + * * @par Method of function operation: * This function subtracts the current time from a time specified in environment variable. * @@ -545,7 +598,7 @@ int appcore_measure_time(void); * If envnm is NULL, "APP_START_TIME" set by launcher is used. * If the environment variable is not set or invalid format, returns 0. * - * @param[in] envnm environment variable name which has + * @param[in] envnm environment variable name which has * the start time (format: "%u %u", seconds, micro seconds) * * @return Milliseconds from a time specified in environment variable @@ -563,9 +616,9 @@ int appcore_measure_time(void); { ... - // do something + // do something - printf("it takes %d msec from APP_START\n", + printf("it takes %d msec from APP_START\n", appcore_measure_time_from("APP_START_TIME")); ... } @@ -582,7 +635,7 @@ struct ui_ops; /** * @par Description: * Appcore init. Internal use only - * + * * @par Important notes: * Except special case, NEVER use this. Use the appcore EFL or GTK instead of this. * @@ -606,10 +659,13 @@ struct ui_ops; int appcore_init(const char *name, const struct ui_ops *ops, int argc, char **argv); +struct appcore; +void appcore_get_app_core(struct appcore **ac); + /** * @par Description: * Appcore exit. Internal use only. - * + * * @par Important notes: * Except special case, NEVER use this. * @@ -634,9 +690,9 @@ void appcore_exit(void); * sqlite3_release_memory() if sqlite3 is used, and malloc_trim(). Also, trims native stack. * * @par Important notes: - * Currently, this function is automatically called in the following 2 cases:\n + * Currently, this function is automatically called in the following 2 cases:\n * (1) when the application enters into the pause state and\n - * (2) when low memory event is invoked and the application is on pause.\n + * (2) when low memory event is invoked and the application is on pause.\n * Developers can use this function when they want extra memory flush utility. * * @return 0 on success, -1 on error @@ -671,8 +727,8 @@ int appcore_flush_memory(void); /** * @par Description: * Set a open callback - * Only when application is running, if aul_open api is called, then this callback function is called. - * If your open_cb function return -1, then appcore doesn't raise window. + * Only when application is running, if aul_open api is called, then this callback function is called. + * If your open_cb function return -1, then appcore doesn't raise window. * * @param[in] cb callback function * @param[in] data callback function data diff --git a/include/appcore-internal.h b/include/appcore-internal.h index cca466b..03ed76e 100755 --- a/include/appcore-internal.h +++ b/include/appcore-internal.h @@ -27,7 +27,9 @@ #define LOG_TAG "APP_CORE" #include +#include #include +#include #include "appcore-common.h" @@ -36,6 +38,7 @@ #endif # define _ERR(fmt, arg...) LOGE(fmt, ##arg) +# define _WARN(fmt, arg...) LOGW(fmt, ##arg) # define _INFO(...) LOGI(__VA_ARGS__) # define _DBG(...) LOGD(__VA_ARGS__) @@ -110,6 +113,7 @@ enum app_event { AE_UNKNOWN, AE_CREATE, AE_TERMINATE, + AE_TERMINATE_BGAPP, AE_PAUSE, AE_RESUME, AE_RESET, @@ -127,6 +131,7 @@ enum sys_event { SE_LOWBAT, SE_LANGCHG, SE_REGIONCHG, + SE_SUSPENDED_STATE, SE_MAX }; @@ -143,6 +148,9 @@ struct sys_op { */ struct appcore { int state; + unsigned int tid; + bool suspended_state; + bool allowed_bg; const struct ui_ops *ops; struct sys_op sops[SE_MAX]; @@ -164,6 +172,7 @@ void update_region(void); /* appcore-X.c */ extern int x_raise_win(pid_t pid); +extern int x_pause_win(pid_t pid); /* appcore-util.c */ /* extern void stack_trim(void);*/ @@ -180,6 +189,15 @@ struct ui_wm_rotate { }; int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate); +void appcore_group_reset(bundle *b); +void appcore_group_attach(); +void appcore_group_lower(); +unsigned int appcore_get_main_window(); + +int _appcore_request_to_suspend(int pid); +int _appcore_init_suspend_dbus_handler(void *data); +int _appcore_fini_suspend_dbus_handler(void *data); + #define ENV_START "APP_START_TIME" #define MEMORY_FLUSH_ACTIVATE diff --git a/packaging/app-core.spec b/packaging/app-core.spec index d71c1b0..a4850f8 100755 --- a/packaging/app-core.spec +++ b/packaging/app-core.spec @@ -24,15 +24,17 @@ BuildRequires: pkgconfig(eet) BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(gobject-2.0) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(ttrace) +BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: cmake -%if "%{?tizen_profile_name}" == "wearable" -BuildRequires: pkgconfig(system-resource) -%endif %description SLP common application basic - +%define appfw_feature_process_pool 1 +%define appfw_feature_capture_snapshot 0 %package efl Summary: App basic EFL @@ -81,8 +83,26 @@ Group: Development/Libraries %description template Application basics template - +%if "%{?tizen_profile_name}" == "wearable" %define appfw_feature_visibility_check_by_lcd_status 1 +%define appfw_feature_sensor_auto_rotation 1 +%define appfw_feature_background_management 1 +%else +%if "%{?tizen_profile_name}" == "mobile" +%define appfw_feature_visibility_check_by_lcd_status 1 +%define appfw_feature_sensor_auto_rotation 1 +%define appfw_feature_background_management 1 +%else +%if "%{?tizen_profile_name}" == "tv" +%define appfw_feature_visibility_check_by_lcd_status 0 +%define appfw_feature_sensor_auto_rotation 0 +%define appfw_feature_background_management 0 +%endif +%endif +%endif + +%define appfw_feature_expansion_pkg_install 1 + %prep %setup -q @@ -91,21 +111,41 @@ export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %if 0%{?appfw_feature_visibility_check_by_lcd_status} -export CFLAGS="$CFLAGS -D_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS" -#_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS=ON +_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS=ON +%endif +%if 0%{?appfw_feature_process_pool} +_APPFW_FEATURE_PROCESS_POOL=ON +%endif +%if 0%{?appfw_feature_capture_snapshot} +_APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER=ON +%endif +%if 0%{?appfw_feature_expansion_pkg_install} +_APPFW_FEATURE_EXPANSION_PKG_INSTALL=ON +%endif +%if 0%{?appfw_feature_sensor_auto_rotation} +_APPFW_FEATURE_SENSOR_AUTO_ROTATION=ON +%endif +%if 0%{?appfw_feature_background_management} +_APPFW_FEATURE_BACKGROUND_MANAGEMENT=ON %endif #export CFLAGS="$CFLAGS -Wall -Werror -Wno-unused-function" cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DENABLE_GTK=OFF \ - -D_APPFW_FEATURE_PROCESS_POOL:BOOL=ON \ + -D_APPFW_FEATURE_PROCESS_POOL:BOOL=${_APPFW_FEATURE_PROCESS_POOL} \ + -D_APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER:BOOL=${_APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER} \ + -D_APPFW_FEATURE_EXPANSION_PKG_INSTALL:BOOL=${_APPFW_FEATURE_EXPANSION_PKG_INSTALL} \ -D_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS:BOOL=${_APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS} \ + -D_APPFW_FEATURE_SENSOR_AUTO_ROTATION:BOOL=${_APPFW_FEATURE_SENSOR_AUTO_ROTATION} \ + -D_APPFW_FEATURE_BACKGROUND_MANAGEMENT:BOOL=${_APPFW_FEATURE_BACKGROUND_MANAGEMENT} \ . %if "%{?tizen_profile_name}" == "wearable" export CFLAGS="$CFLAGS -DWEARABLE" -%elseif "%{?tizen_profile_name}" == "mobile" +%else +%if "%{?tizen_profile_name}" == "mobile" export CFLAGS="$CFLAGS -DMOBILE" %endif +%endif make %{?jobs:-j%jobs} diff --git a/src/appcore-X.c b/src/appcore-X.c index 34b987f..2685cec 100755 --- a/src/appcore-X.c +++ b/src/appcore-X.c @@ -28,6 +28,7 @@ #include #include +#include #include "appcore-internal.h" @@ -103,6 +104,58 @@ static int __find_win(Display *d, Window *win, pid_t pid) return 0; } +static void __add_win_list(Eina_List **list, Window *win) +{ + void *w; + Eina_List *l; + + if (!list || !win) + return; + + EINA_LIST_FOREACH(*list, l, w) { + if ((Window)w == *win) + return; + } + + *list = eina_list_append(*list, (void *)*win); +} + +static void __foreach_win(Eina_List **list, Display *d, Window *win, pid_t pid) +{ + int i; + int r; + pid_t p; + unsigned int n; + Window root, parent, *child; + + p = __get_win_pid(d, *win); + if (p == pid) + __add_win_list(list, win); + + r = XQueryTree(d, *win, &root, &parent, &child, &n); + if (r) { + for (i = 0; i < n; i++) { + __foreach_win(list, d, &child[i], pid); + } + XFree(child); + } +} + +static int __iconify_win(Eina_List *list, Display *d) +{ + void *w; + Eina_List *l; + + if (!list || !d) + return -1; + + EINA_LIST_FOREACH(list, l, w) { + XIconifyWindow(d, (Window)w, 0); + } + + return 0; +} + static int __raise_win(Display *d, Window win) { XEvent xev; @@ -168,3 +221,39 @@ EXPORT_API int x_raise_win(pid_t pid) return r; } + +int x_pause_win(pid_t pid) +{ + int r; + Display *d; + Window win; + Eina_List *list_win = NULL; + + if (pid < 1) { + errno = EINVAL; + return -1; + } + + r = kill(pid, 0); + if (r == -1) { + errno = ESRCH; + return -1; + } + + d = XOpenDisplay(NULL); + _retv_if(d == NULL, -1); + + win = XDefaultRootWindow(d); + if (!a_pid) + a_pid = XInternAtom(d, "_NET_WM_PID", True); + + __foreach_win(&list_win, d, &win, pid); + r = __iconify_win(list_win, d); + + XCloseDisplay(d); + + if (list_win) + eina_list_free(list_win); + + return r; +} diff --git a/src/appcore-efl.c b/src/appcore-efl.c index ea5eabf..d55dc4d 100755 --- a/src/appcore-efl.c +++ b/src/appcore-efl.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "appcore-internal.h" #include "appcore-efl.h" #include "virtual_canvas.h" @@ -56,6 +57,8 @@ #include #endif +#include + #define SYSMAN_MAXSTR 100 #define SYSMAN_MAXARG 16 #define SYSNOTI_SOCKET_PATH "/tmp/sn" @@ -97,8 +100,12 @@ struct ui_priv { Ecore_Timer *mftimer; /* Ecore Timer for memory flushing */ + struct appcore *app_core; struct appcore_ops *ops; + void (*mfcb) (void); /* Memory Flushing Callback */ + void (*prepare_to_suspend) (void *data); + void (*exit_from_suspend) (void *data); /* WM_ROTATE */ int wm_rot_supported; @@ -162,6 +169,7 @@ static inline int send_str(int fd, char *str) return ret; } +#if 0 static int sysnoti_send(struct sysnoti *msg) { int client_len; @@ -219,93 +227,51 @@ static int sysnoti_send(struct sysnoti *msg) close(client_sockfd); return result; } +#endif void __trm_app_info_send_socket(char *write_buf) { - const char trm_socket_for_app_info[] = "/dev/socket/app_info"; - int socket_fd = 0; - int ret = 0; - struct sockaddr_un addr; - - _DBG("__trm_app_info_send_socket"); - - if (access(trm_socket_for_app_info, F_OK) != 0) { - _ERR("access"); - goto trm_end; - } - - socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0); - if (socket_fd < 0) { - _ERR("socket"); - goto trm_end; - } - - memset(&addr, 0, sizeof(addr)); - sprintf(addr.sun_path, "%s", trm_socket_for_app_info); - addr.sun_family = AF_LOCAL; - - ret = connect(socket_fd, (struct sockaddr *) &addr ,sizeof(sa_family_t) + strlen(trm_socket_for_app_info) ); - if (ret != 0) { - close(socket_fd); - goto trm_end; - } - - send(socket_fd, write_buf, strlen(write_buf), MSG_DONTWAIT | MSG_NOSIGNAL); - _DBG("send"); - - close(socket_fd); -trm_end: - return; -} - -#ifdef _APPFW_FEATURE_CPU_BOOST -static void __stop_cpu_boost(void) -{ - const char trm_sock_for_cpu_boost[] = "/dev/socket/scenario_info"; - int sock_fd = 0; + const char trm_socket_for_app_info[] = "/dev/socket/app_info"; + int socket_fd = 0; int ret = 0; struct sockaddr_un addr; - const char command[] = "AppLaunchUnlock"; - _DBG("__stop_cpu_boost enter"); + _DBG("__trm_app_info_send_socket"); - if (access(trm_sock_for_cpu_boost, F_OK) != 0) { - _ERR("access() failed, errno: %d (%s)", errno, strerror(errno)); - goto error; + if (access(trm_socket_for_app_info, F_OK) != 0) { + _ERR("access"); + goto trm_end; } - sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0); - if (sock_fd < 0) { - _ERR("socket() failed, errno: %d (%s)", errno, strerror(errno)); - goto error; + socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0); + if (socket_fd < 0) { + _ERR("socket"); + goto trm_end; } memset(&addr, 0, sizeof(addr)); - sprintf(addr.sun_path, "%s", trm_sock_for_cpu_boost); + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", trm_socket_for_app_info); addr.sun_family = AF_LOCAL; - ret = connect(sock_fd, (struct sockaddr *) &addr, sizeof(sa_family_t) + strlen(trm_sock_for_cpu_boost)); + ret = connect(socket_fd, (struct sockaddr *) &addr ,sizeof(sa_family_t) + strlen(trm_socket_for_app_info) ); if (ret != 0) { - _ERR("connect() failed, errno: %d (%s)", errno, strerror(errno)); - close(sock_fd); - goto error; + close(socket_fd); + goto trm_end; } - ret = send(sock_fd, command, strlen(command), MSG_DONTWAIT | MSG_NOSIGNAL); + ret = send(socket_fd, write_buf, strlen(write_buf), MSG_DONTWAIT | MSG_NOSIGNAL); if (ret < 0) { _ERR("send() failed, errno: %d (%s)", errno, strerror(errno)); - close(sock_fd); - goto error; + } else { + _DBG("send"); } - close(sock_fd); - _DBG("__stop_cpu_boost ok"); - -error: + close(socket_fd); +trm_end: return; } -#endif +#if 0 static int _call_predef_action(const char *type, int num, ...) { struct sysnoti *msg; @@ -359,18 +325,15 @@ static int _inform_backgrd(void) snprintf(buf, sizeof(buf), "%d", getpid()); return _call_predef_action(PREDEF_BACKGRD, 1, buf); } - - +#endif char appid[APPID_MAX]; #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER bool taskmanage; static void _capture_and_make_file(Ecore_X_Window win, int pid, const char *package); -#endif - static bool __check_skip(Ecore_X_Window xwin); - +#endif static int WIN_COMP(gconstpointer data1, gconstpointer data2) { @@ -381,13 +344,59 @@ static int WIN_COMP(gconstpointer data1, gconstpointer data2) GSList *g_winnode_list = NULL; +static void __appcore_efl_prepare_to_suspend(void *data) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + 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 + } + _appcore_request_to_suspend(getpid()); //send dbus signal to resourced + ui->app_core->suspended_state = true; + } + _DBG("[__SUSPEND__]"); +#endif +} + +static void __appcore_efl_exit_from_suspend(void *data) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + 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 +} + #if defined(MEMORY_FLUSH_ACTIVATE) static Eina_Bool __appcore_memory_flush_cb(void *data) { + _DBG("[__SUSPEND__]"); 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; } @@ -435,6 +444,20 @@ static void __appcore_efl_memory_flush_cb(void) } #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER +static int __is_sub_app() +{ + static int lpid = -1; + int cpid = getpid(); + + if (lpid == -1) + lpid = aul_app_group_get_leader_pid(cpid); + + if (lpid == cpid) + return 0; + + return 1; +} + static Eina_Bool __appcore_mimiapp_capture_cb(void *data) { GSList *iter = NULL; @@ -447,7 +470,7 @@ static Eina_Bool __appcore_mimiapp_capture_cb(void *data) } if(iter) { entry = iter->data; - if(taskmanage) { + if (taskmanage || __is_sub_app()) { _capture_and_make_file(entry->win, getpid(), appid); } } @@ -465,66 +488,70 @@ static void __do_app(enum app_event event, void *data, bundle * b) const char *miniapp = NULL; #endif - _ret_if(ui == NULL || event >= AE_MAX); - _DBG("[APP %d] Event: %s State: %s", _pid, _ae_name[event], - _as_name[ui->state]); + if (ui == NULL || event >= AE_MAX) { + return; + } + + _INFO("[APP %d] Event: %s State: %s", _pid, _ae_name[event], + _as_name[ui->state]); if (event == AE_MEM_FLUSH) { ui->mfcb(); return; } - if (event == AE_LOWMEM_POST) { - if (__appcore_low_memory_post_cb(ui) == 0) + if ((event == AE_LOWMEM_POST) && + (__appcore_low_memory_post_cb(ui) == 0)) { return; } 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; } - _ret_if(ui->ops == NULL); + /* _ret_if(ui->ops == NULL); */ switch (event) { case AE_RESET: _DBG("[APP %d] RESET", _pid); LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", ui->name); - if (ui->ops->reset) - r = ui->ops->reset(b, ui->ops->data); + +#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"); + ui->ops->reset(b, ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", ui->name); - if(first_launch) { - first_launch = 0; + if (!first_launch) { is_legacy_lifecycle = aul_get_support_legacy_lifecycle(); - - _INFO("Legacy lifecycle: %d", is_legacy_lifecycle); - if (!is_legacy_lifecycle) { - _INFO("[APP %d] Initial Launching, call the resume_cb", _pid); - if (ui->ops->resume) - r = ui->ops->resume(ui->ops->data); - } - } else { _INFO("Legacy lifecycle: %d", is_legacy_lifecycle); if (!is_legacy_lifecycle) { _INFO("[APP %d] App already running, raise the window", _pid); x_raise_win(getpid()); - - if (ui->state == AS_PAUSED) { - _INFO("[APP %d] Call the resume_cb", _pid); - if (ui->ops->resume) - r = ui->ops->resume(ui->ops->data); - } } } - - ui->state = AS_RUNNING; + first_launch = 0; #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER miniapp = bundle_get_val(b, "http://tizen.org/appcontrol/data/miniapp"); @@ -536,11 +563,23 @@ static void __do_app(enum app_event event, void *data, bundle * b) 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) - __appcore_timer_add(ui); + if (r >= 0) { + if (resource_reclaiming == TRUE) + __appcore_timer_add(ui); +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + else if (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(); @@ -550,16 +589,46 @@ static void __do_app(enum app_event event, void *data, bundle * b) #ifdef WEARABLE proc_group_change_status(PROC_CGROUP_SET_BACKGRD, getpid(), NULL); #endif + aul_invoke_status_local_cb(STATUS_BG); //_inform_backgrd(); break; case AE_RESUME: LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", - ui->name); - if (ui->state == AS_PAUSED) { + ui->name); + +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ui->exit_from_suspend) { + _DBG("[__SUSPEND__] resume case"); + ui->exit_from_suspend(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) { + is_legacy_lifecycle = aul_get_support_legacy_lifecycle(); + + _INFO("Legacy lifecycle: %d", is_legacy_lifecycle); + if (!is_legacy_lifecycle) { + _INFO("[APP %d] Initial Launching, call the resume_cb", _pid); + if (ui->ops->resume) { + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, + "APPCORE:RESUME"); + ui->ops->resume(ui->ops->data); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + } + } + } else { + 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; + } /*TODO : rotation start*/ //r = appcore_resume_rotation_cb(); @@ -579,11 +648,21 @@ static void __do_app(enum app_event event, void *data, bundle * b) #endif snprintf(trm_buf, MAX_PACKAGE_STR_SIZE,"appinfo_resume:[PID]%d", getpid()); __trm_app_info_send_socket(trm_buf); -#ifdef _APPFW_FEATURE_CPU_BOOST - __stop_cpu_boost(); -#endif //_inform_foregrd(); + aul_invoke_status_local_cb(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; default: /* do nothing */ @@ -611,6 +690,7 @@ static bool __check_visible(void) return FALSE; } +#ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER static bool __check_skip(Ecore_X_Window xwin) { unsigned int i, num; @@ -640,6 +720,7 @@ static bool __check_skip(Ecore_X_Window xwin) free(state); return FALSE; } +#endif static bool __exist_win(unsigned int win) { @@ -745,7 +826,9 @@ static bool __update_win(unsigned int win, bool bfobscured) /* WM_ROTATE */ static Ecore_X_Atom _WM_WINDOW_ROTATION_SUPPORTED = 0; +#if 0 static Ecore_X_Atom _WM_WINDOW_ROTATION_CHANGE_REQUEST = 0; +#endif static int __check_wm_rotation_support(void) { @@ -807,6 +890,10 @@ static void __set_wm_rotation_support(unsigned int win, unsigned int set) Ecore_X_Atom atom_parent; Ecore_X_Atom xsend_Atom; +Ecore_X_Atom win_req_lower; +#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS +Ecore_X_Atom lcd_Atom; +#endif static Eina_Bool __show_cb(void *data, int type, void *event) { @@ -820,10 +907,11 @@ static Eina_Bool __show_cb(void *data, int type, void *event) if (ret != 1) { // This is child window. Skip!!! + _ERR(" This is child window. Skip!!! WIN:%x\n", ev->win); return ECORE_CALLBACK_PASS_ON; } - _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x\n", ev->win); + _WARN("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x\n", ev->win); if (!__exist_win((unsigned int)ev->win)) { /* WM_ROTATE */ @@ -833,8 +921,9 @@ static Eina_Bool __show_cb(void *data, int type, void *event) __add_win((unsigned int)ev->win); } else - __update_win((unsigned int)ev->win, FALSE); + __update_win((unsigned int)ev->win, TRUE); + appcore_group_attach(); return ECORE_CALLBACK_RENEW; } @@ -845,7 +934,7 @@ static Eina_Bool __hide_cb(void *data, int type, void *event) ev = event; - _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win); + _WARN("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win); if (__exist_win((unsigned int)ev->win)) { __delete_win((unsigned int)ev->win); @@ -856,7 +945,7 @@ static Eina_Bool __hide_cb(void *data, int type, void *event) b_active = 0; __do_app(AE_PAUSE, data, NULL); #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER - if(taskmanage) { + if (taskmanage || __is_sub_app()) { _capture_and_make_file(ev->win, getpid(), appid); } else if ( aul_is_subapp() ) { _capture_and_make_file(ev->win, getpid(), appcore_get_caller_appid()); @@ -874,6 +963,7 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) int bvisibility = 0; #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS int lcd_status = 0; + int r = -1; #endif ev = event; @@ -888,8 +978,9 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) b_active = 1; #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS - vconf_get_int(VCONFKEY_PM_STATE, &lcd_status); - if(lcd_status == VCONFKEY_PM_STATE_LCDOFF) { + r = vconf_get_int(VCONFKEY_PM_STATE, &lcd_status); + if (r == VCONF_OK && lcd_status == VCONFKEY_PM_STATE_LCDOFF) { + _WARN("LCD status is off, skip the AE_RESUME event"); return ECORE_CALLBACK_RENEW; } #endif @@ -899,7 +990,7 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) b_active = 0; __do_app(AE_PAUSE, data, NULL); #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER - if(taskmanage) { + if (taskmanage || __is_sub_app()) { _capture_and_make_file(ev->win, getpid(), appid); } else if ( aul_is_subapp() ) { _capture_and_make_file(ev->win, getpid(), appcore_get_caller_appid()); @@ -912,12 +1003,17 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) } -/* 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 (e->message_type == win_req_lower) { + _DBG("win_req_lower"); + + appcore_group_lower(); + return ECORE_CALLBACK_PASS_ON; + } + #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER if (e->message_type == xsend_Atom) { _DBG("_E_ILLUME_ATOM_APPCORE_RECAPTURE_REQUEST win(%x)", e->win); @@ -925,33 +1021,22 @@ static Eina_Bool __cmsg_cb(void *data, int type, void *event) return ECORE_CALLBACK_PASS_ON; } #endif - - 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)) { - return ECORE_CALLBACK_PASS_ON; +#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS + if (e->message_type == lcd_Atom) { + if (e->data.l[0] == 1) { + _WARN("LCD On. Resume the topmost app"); + __do_app(AE_RESUME, data, NULL); } - - 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; + else if (e->data.l[0] == 0) { + _WARN("LCD Off. Pause the topmost app"); + __do_app(AE_PAUSE, data, NULL); } - - ui->rot_mode = rm; - - if (APPCORE_RM_UNKNOWN != rm) { - ui->rot_cb((void *)&rm, rm, ui->rot_cb_data); + else { + _ERR("Invalid value."); } + return ECORE_CALLBACK_PASS_ON; } - +#endif return ECORE_CALLBACK_PASS_ON; } @@ -971,19 +1056,31 @@ static void __add_climsg_cb(struct ui_priv *ui) // Do Error Handling _ERR("xsend_Atom is NULL"); } +#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS + lcd_Atom = ecore_x_atom_get("_SEND_EVENT_TO_WINDOW_BY_LCD_ON_OFF_"); + if (!lcd_Atom) + { + // Do Error Handling + _ERR("lcd_Atom is NULL"); + } +#endif + + win_req_lower = ecore_x_atom_get("_E_ILLUME_ATOM_WIN_REQ_LOWER"); + if (!win_req_lower) + { + // Do Error Handling + _ERR("win_req_lower is NULL"); + + } ui->hshow = 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); ui->hvchange = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, ui); - -#ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER ui->hcmsg = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __cmsg_cb, ui); -#endif /* 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); ui->wm_rot_supported = 1; appcore_set_wm_rotation(&wm_rotate); } @@ -993,7 +1090,7 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv) { int r; char *hwacc = NULL; - char *tm_tmp = NULL; + struct appcore *ac = NULL; if (argc == NULL || argv == NULL) { _ERR("argc/argv is NULL"); @@ -1001,27 +1098,26 @@ 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) { - elm_config_preferred_engine_set("opengl_x11"); - _DBG("elm_config_preferred_engine_set : opengl_x11"); - } else if(strcmp(hwacc, "NOT_USE") == 0) { - elm_config_preferred_engine_set("software_x11"); - _DBG("elm_config_preferred_engine_set : software_x11"); + if(hwacc && strcmp(hwacc, "USE") == 0) { + elm_config_accel_preference_set("hw"); + _DBG("elm_config_accel_preference_set : hw"); + } else if(hwacc && 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"); } #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER + char *tm_tmp = NULL; + tm_tmp = getenv("TASKMANAGE"); - if(tm_tmp == NULL) { - _DBG("taskmanage is null"); - taskmanage = 1; - } else if(strcmp(tm_tmp, "false") == 0) { + if(tm_tmp && strcmp(tm_tmp, "false") == 0) { _DBG("taskmanage is false"); taskmanage = 0; } else { @@ -1029,17 +1125,28 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv) taskmanage = 1; } #endif + r = appcore_init(ui->name, &efl_ops, *argc, *argv); _retv_if(r == -1, -1); + appcore_get_app_core(&ac); + ui->app_core = ac; + SECURE_LOGD("[__SUSPEND__] appcore initialized, appcore addr: 0x%x", ac); + 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); + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); if (r < 0) { _ERR("create() return error"); appcore_exit(); - if (ui->ops && ui->ops->terminate) + 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; } @@ -1060,12 +1167,21 @@ static void __after_loop(struct ui_priv *ui) if (ui->state == AS_RUNNING) { _DBG("[APP %d] PAUSE before termination", _pid); - if (ui->ops && ui->ops->pause) + 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) + 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); @@ -1076,7 +1192,9 @@ static void __after_loop(struct ui_priv *ui) __appcore_timer_del(ui); - elm_shutdown(); + // Check the process-pool case + if (elm_shutdown() > 0) + elm_shutdown(); #ifdef _GATE_TEST_ENABLE if((ui->name) && (strncmp(ui->name, "wrt-client", 10) != 0)) { @@ -1122,6 +1240,10 @@ static int __set_data(struct ui_priv *ui, const char *name, ui->rot_cb_data = NULL; ui->rot_mode = APPCORE_RM_UNKNOWN; + ui->app_core = NULL; + ui->prepare_to_suspend = __appcore_efl_prepare_to_suspend; + ui->exit_from_suspend = __appcore_efl_exit_from_suspend; + return 0; } @@ -1331,11 +1453,9 @@ static char *_capture_window(Window id, Visual *visual, int width, int height, i } #define _WND_REQUEST_ANGLE_IDX 0 -#define _WND_CURR_ANGLE_IDX 1 int _get_angle(Ecore_X_Window win) { int after = -1; - int before = -1; do { int ret, count; @@ -1359,7 +1479,6 @@ int _get_angle(Ecore_X_Window win) } after= angle[_WND_REQUEST_ANGLE_IDX]; - before = angle[_WND_CURR_ANGLE_IDX]; } while (0); if (-1 == after) after = 0; @@ -1397,13 +1516,19 @@ bool _make_capture_file(const char *package, int width, int height, char *img, i int cx = 0, cy = 0; int mx = 0; int r = 0; + char idbuf[APPID_MAX] = { 0, }; _retv_if(NULL == package, false); + int lpid = aul_app_group_get_leader_pid(getpid()); + + _retv_if(lpid < 0, false); + if ( AUL_R_OK != aul_app_get_appid_bypid(lpid, idbuf, APPID_MAX - 1)) + return false; - len = strlen(package) + EXTENSION_LEN; + len = strlen(idbuf) + EXTENSION_LEN; filename = malloc(len); _retv_if(NULL == filename, false); - snprintf(filename, len, CAPTURE_FILE_PATH"/%s.jpg", package); + snprintf(filename, len, CAPTURE_FILE_PATH"/%s.jpg", idbuf); if (90 == angle || 270 == angle) { canvas_width = height; @@ -1558,14 +1683,10 @@ static void _capture_and_make_file(Ecore_X_Window win, int pid, const char *pack } #endif -extern int aul_status_update(int status); - EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, struct appcore_ops *ops) { int r; - GSList *iter = NULL; - struct win_node *entry = NULL; int pid; LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", name); @@ -1590,14 +1711,17 @@ EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv, aul_status_update(STATUS_DYING); #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER + GSList *iter = NULL; + struct win_node *entry = NULL; + for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) { entry = iter->data; if(__check_skip(entry->win) == FALSE) break; } - if(iter) { + if (iter) { entry = iter->data; - if(taskmanage) { + if (taskmanage || __is_sub_app()) { _capture_and_make_file(entry->win, pid, appid); } } @@ -1670,3 +1794,14 @@ EXPORT_API int appcore_set_preinit_window_name(const char* win_name) return ret; } #endif + +EXPORT_API unsigned int appcore_get_main_window() +{ + struct win_node *entry = NULL; + + if (g_winnode_list != NULL) { + entry = g_winnode_list->data; + return (unsigned int) entry->win; + } + return 0; +} diff --git a/src/appcore-group.c b/src/appcore-group.c new file mode 100644 index 0000000..2baf5c9 --- /dev/null +++ b/src/appcore-group.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "appcore-internal.h" + +void appcore_group_attach() +{ + _DBG("appcore_group_attach"); + static bool attached = false; + + if (attached) + return; + + int wid = appcore_get_main_window(); + + if (wid == 0) { + _ERR("window wasn't ready"); + return; + } + + aul_app_group_set_window(wid); + attached = true; +} + +void appcore_group_lower() +{ + _DBG("appcore_group_lower"); + int exit = 0; + + aul_app_group_lower(&exit); + if (exit) { + _DBG("appcore_group_lower : sub-app!"); + elm_exit(); + } +} + + diff --git a/src/appcore-i18n.c b/src/appcore-i18n.c index 974f81f..29ec753 100755 --- a/src/appcore-i18n.c +++ b/src/appcore-i18n.c @@ -26,10 +26,28 @@ #include #include +#include #include "appcore-internal.h" static int _set; +static char* current_lang = NULL; + +static void __load_lang_info_for_fallback_translated_msg(char *lang) +{ + if(!lang) { + _ERR("lang value is null"); + return; + } + + if(current_lang) { + free(current_lang); + current_lang = NULL; + } + current_lang = strdup(lang); + + return; +} void update_lang(void) { @@ -44,7 +62,12 @@ void update_lang(void) _DBG("*****appcore setlocale=%s\n", r); } } + + __load_lang_info_for_fallback_translated_msg(lang); + free(lang); + } else { + _ERR("failed to get current language for set lang env"); } } @@ -71,6 +94,8 @@ void update_region(void) _DBG("*****appcore setlocale=%s\n", r); } free(region); + } else { + _ERR("failed to get current region format for set region env"); } } @@ -145,6 +170,7 @@ EXPORT_API int appcore_get_timeformat(enum appcore_time_format *timeformat) int r; if (timeformat == NULL) { + _ERR("timeformat is null"); errno = EINVAL; return -1; } @@ -157,3 +183,44 @@ EXPORT_API int appcore_get_timeformat(enum appcore_time_format *timeformat) } else return 0; } + +EXPORT_API char *appcore_get_i18n_text(const char *msgid) +{ + char *cur_env = NULL; + char *get_env = NULL; + char *translated_msg = NULL; + + if(!msgid) { + _ERR("msgid is null"); + errno = EINVAL; + return NULL; + } + + // get msg based on current locale env + translated_msg = gettext(msgid); + if(strncmp(msgid, translated_msg, strlen(msgid)) != 0) { + goto func_out; + } + + // backup current LC_MESSAGES locale value + get_env = setlocale(LC_MESSAGES, NULL); + if(get_env) { + cur_env = strdup(get_env); + } + + // Fallback #1 - get msg based on current language setting value + if(current_lang) { + setlocale(LC_MESSAGES, current_lang); + translated_msg = gettext(msgid); + if(strncmp(msgid, translated_msg, strlen(msgid)) != 0) { + goto func_out; + } + } + +func_out : + if(cur_env) { + setlocale(LC_MESSAGES, cur_env); + free(cur_env); + } + return translated_msg; +} diff --git a/src/appcore-measure.c b/src/appcore-measure.c index aa379fd..147efda 100755 --- a/src/appcore-measure.c +++ b/src/appcore-measure.c @@ -50,15 +50,18 @@ static int __get_envtime(const char *name, struct timeval *t) int r; char *s; - s = getenv(name ? : ENV_START); - /*_retvm_if(s == NULL, -1, "%s is not set", name);*/ - _retv_if(s == NULL, -1); + s = getenv(name ? name : ENV_START); + if (s == NULL) { + return -1; + } - r = sscanf(s, "%u/%u", (int *)&t->tv_sec, (int *)&t->tv_usec); + r = sscanf((const char *)s, "%u/%u", (int *)&t->tv_sec, (int *)&t->tv_usec); if (r != 2) - r = sscanf(s, "%u %u", (int *)&t->tv_sec, (int *)&t->tv_usec); + r = sscanf((const char *)s, "%u %u", (int *)&t->tv_sec, (int *)&t->tv_usec); - _retv_if(r != 2, -1); + if (r != 2) { + return -1; + } return 0; } diff --git a/src/appcore-rotation.c b/src/appcore-rotation.c index d99dace..bc8bf86 100755 --- a/src/appcore-rotation.c +++ b/src/appcore-rotation.c @@ -23,10 +23,6 @@ #include #include #include - -#include -//#include - #include #include #include @@ -34,6 +30,9 @@ #include "appcore-internal.h" +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION +#include + #define _MAKE_ATOM(a, s) \ do { \ a = ecore_x_atom_get(s); \ @@ -106,7 +105,6 @@ static void __changed_cb(unsigned int event_type, sensor_event_data_t *event, { int *cb_event_data; enum appcore_rm m; - int ret; if (rot.lock) return; @@ -184,10 +182,12 @@ static void __del_rotlock(void) vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __lock_cb); rot.lock = 0; } +#endif EXPORT_API int appcore_set_rotation_cb(int (*cb) (void *event_info, enum appcore_rm, void *), void *data) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (rot.wm_rotate) { return rot.wm_rotate->set_rotation_cb(cb, data); } else { @@ -245,11 +245,13 @@ EXPORT_API int appcore_set_rotation_cb(int (*cb) (void *event_info, enum appcore root = ecore_x_window_root_first_get(); XSelectInput(ecore_x_display_get(), root, PropertyChangeMask); } +#endif return 0; } EXPORT_API int appcore_unset_rotation_cb(void) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (rot.wm_rotate) { return rot.wm_rotate->unset_rotation_cb(); } @@ -288,11 +290,13 @@ EXPORT_API int appcore_unset_rotation_cb(void) } rot.handle = -1; } +#endif return 0; } EXPORT_API int appcore_get_rotation_state(enum appcore_rm *curr) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (rot.wm_rotate) { return rot.wm_rotate->get_rotation_state(curr); } @@ -317,11 +321,13 @@ EXPORT_API int appcore_get_rotation_state(enum appcore_rm *curr) *curr = __get_mode(event); } +#endif return 0; } EXPORT_API int appcore_pause_rotation_cb(void) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (rot.wm_rotate) { return rot.wm_rotate->pause_rotation_cb(); } @@ -353,12 +359,13 @@ EXPORT_API int appcore_pause_rotation_cb(void) rot.sf_started = 0; } } - +#endif return 0; } EXPORT_API int appcore_resume_rotation_cb(void) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (rot.wm_rotate) { return rot.wm_rotate->resume_rotation_cb(); } @@ -404,11 +411,13 @@ EXPORT_API int appcore_resume_rotation_cb(void) rot.mode = m; } } +#endif return 0; } EXPORT_API int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate) { +#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION if (!wm_rotate) return -1; if (rot.callback) { @@ -417,5 +426,6 @@ EXPORT_API int appcore_set_wm_rotation(struct ui_wm_rotate* wm_rotate) } rot.wm_rotate = wm_rotate; _DBG("[APP %d] Support wm rotate:%p", getpid(), wm_rotate); +#endif return 0; } diff --git a/src/appcore.c b/src/appcore.c index 2205330..98ac1ea 100755 --- a/src/appcore.c +++ b/src/appcore.c @@ -33,11 +33,17 @@ #include #include #include +#include +#include +#include #include #include +#include +#include #include "appcore-internal.h" #define SQLITE_FLUSH_MAX (1024*1024) +#define MAX_LOCAL_BUFSZ 128 #define PKGNAME_MAX 256 #define PATH_APP_ROOT "/opt/usr/apps" @@ -55,8 +61,10 @@ static enum appcore_event to_ae[SE_MAX] = { APPCORE_EVENT_LOW_BATTERY, /* SE_LOWBAT */ APPCORE_EVENT_LANG_CHANGE, /* SE_LANGCGH */ APPCORE_EVENT_REGION_CHANGE, + APPCORE_EVENT_SUSPENDED_STATE_CHANGE, }; +static int appcore_event_initialized[SE_MAX] = {0}; enum cb_type { /* callback */ _CB_NONE, @@ -92,10 +100,6 @@ static struct open_s open; static int __app_terminate(void *data); static int __app_resume(void *data); static int __app_reset(void *data, bundle *k); -#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS -static int __app_resume_lcd_on(void *data); -static int __app_pause_lcd_off(void *data); -#endif static int __sys_lowmem_post(void *data, void *evt); static int __sys_lowmem(void *data, void *evt); @@ -138,26 +142,63 @@ static struct evt_ops evtops[] = { }, }; +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT +static DBusConnection *bus = NULL; +static int __suspend_dbus_handler_initialized = 0; +#endif + static int __get_dir_name(char *dirname) { char pkgid[PKGNAME_MAX]; int r; int pid; + char *cmdline = NULL; + char *name = NULL; + int len = 0; pid = getpid(); if (pid < 0) return -1; - if (aul_app_get_pkgid_bypid(pid, pkgid, PKGNAME_MAX) != AUL_R_OK) + cmdline = aul_get_cmdline_bypid(pid); + if (cmdline == NULL) { + _ERR("cmdline is null"); return -1; + } - r = snprintf(dirname, PATH_MAX, PATH_APP_ROOT "/%s" PATH_RES PATH_LOCALE,pkgid); - if (r < 0) - return -1; - if (access(dirname, R_OK) == 0) return 0; - r = snprintf(dirname, PATH_MAX, PATH_RO_APP_ROOT "/%s" PATH_RES PATH_LOCALE,pkgid); - if (r < 0) - return -1; + //for handling wrt case + if (strncmp(cmdline, PATH_APP_ROOT, strlen(PATH_APP_ROOT)) != 0 + && strncmp(cmdline, PATH_RO_APP_ROOT, strlen(PATH_RO_APP_ROOT)) != 0) { + free(cmdline); + + if (aul_app_get_pkgid_bypid(pid, pkgid, PKGNAME_MAX) != AUL_R_OK) + return -1; + + r = snprintf(dirname, PATH_MAX, PATH_APP_ROOT "/%s" PATH_RES PATH_LOCALE, pkgid); + if (r < 0) + return -1; + + if (access(dirname, R_OK) == 0) + return 0; + + r = snprintf(dirname, PATH_MAX, PATH_RO_APP_ROOT "/%s" PATH_RES PATH_LOCALE, pkgid); + if (r < 0) + return -1; + } + else { + name = (char *)g_strrstr(cmdline, "/"); + name[0] = '\0'; + name = (char *)g_strrstr(cmdline, "/"); + name[0] = '\0'; + + len = strlen(cmdline); + strncpy(dirname, cmdline, len); + dirname[len] = '\0'; + + len = strlen(dirname); + strncat(dirname, "/res/locale", PATH_MAX - len); + free(cmdline); + } return 0; } @@ -174,6 +215,18 @@ static int __app_terminate(void *data) return 0; } +static int __bgapp_terminate(void *data) +{ + struct appcore *ac = data; + + _retv_if(ac == NULL || ac->ops == NULL, -1); + _retv_if(ac->ops->cb_app == NULL, 0); + + ac->ops->cb_app(AE_TERMINATE_BGAPP, ac->ops->data, NULL); + + return 0; +} + static gboolean __prt_ltime(gpointer data) { int msec; @@ -204,22 +257,12 @@ static int __app_resume(void *data) return 0; } -#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS -static int __app_resume_lcd_on(void *data) +static int __app_pause(void *data) { - struct appcore *ac = data; - ac->ops->cb_app(AE_RESUME, ac->ops->data, NULL); + x_pause_win(getpid()); return 0; } -static int __app_pause_lcd_off(void *data) -{ - struct appcore *ac = data; - ac->ops->cb_app(AE_PAUSE, ac->ops->data, NULL); - return 0; -} -#endif - static int __sys_do_default(struct appcore *ac, enum sys_event event) { int r; @@ -261,6 +304,10 @@ static int __sys_lowmem_post(void *data, void *evt) if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) { #if defined(MEMORY_FLUSH_ACTIVATE) struct appcore *ac = data; + + _retv_if(ac == NULL || ac->ops == NULL, -1); + _retv_if(ac->ops->cb_app == NULL, 0); + ac->ops->cb_app(AE_LOWMEM_POST, ac->ops->data, NULL); #else malloc_trim(0); @@ -370,57 +417,192 @@ static void __vconf_cb(keynode_t *key, void *data) } } -static int __add_vconf(struct appcore *ac) +static int __add_vconf(struct appcore *ac, enum sys_event se) { - int i; int r; - for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) { - struct evt_ops *eo = &evtops[i]; - - switch (eo->type) { - case _CB_VCONF: - r = vconf_notify_key_changed(eo->key.vkey, __vconf_cb, - ac); + switch (se) { + case SE_LOWMEM: + r = vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __vconf_cb, ac); + break; + case SE_LOWBAT: + r = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __vconf_cb, ac); + break; + case SE_LANGCHG: + r = vconf_notify_key_changed(VCONFKEY_LANGSET, __vconf_cb, ac); + break; + case SE_REGIONCHG: + r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __vconf_cb, ac); + if (r < 0) break; - default: - /* do nothing */ + + r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __vconf_cb, ac); + break; + default: + r = -1; + break; + } + + return r; +} + +static int __del_vconf(enum sys_event se) +{ + int r; + + switch (se) { + case SE_LOWMEM: + r = vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __vconf_cb); + break; + case SE_LOWBAT: + r = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __vconf_cb); + break; + case SE_LANGCHG: + r = vconf_ignore_key_changed(VCONFKEY_LANGSET, __vconf_cb); + break; + case SE_REGIONCHG: + r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __vconf_cb); + if (r < 0) break; - } + + r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __vconf_cb); + break; + default: + r = -1; + break; } - return 0; + return r; } -static int __del_vconf(void) +static int __del_vconf_list(void) { - int i; int r; + enum sys_event se; - for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) { - struct evt_ops *eo = &evtops[i]; + for (se = SE_LOWMEM; se < SE_MAX; se++) { + if (appcore_event_initialized[se]) { + r = __del_vconf(se); + if (r < 0) + _ERR("Delete vconf callback failed"); + else + appcore_event_initialized[se] = 0; + } + } - switch (eo->type) { - case _CB_VCONF: - r = vconf_ignore_key_changed(eo->key.vkey, __vconf_cb); - break; - default: - /* do nothing */ - break; + return 0; +} + +EXPORT_API int _appcore_request_to_suspend(int pid) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + static DBusConnection* conn = NULL; + DBusMessage *message; + DBusError err; + + dbus_error_init(&err); + + if (conn == NULL) { + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + if (!conn) { + _ERR("Fail to dbus_bus_get : %s", err.message); + return -1; } } + message = dbus_message_new_signal(APPFW_SUSPEND_HINT_PATH, + APPFW_SUSPEND_HINT_INTERFACE, + APPFW_SUSPEND_HINT_SIGNAL); + + if (dbus_message_append_args(message, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID) == FALSE) { + _ERR("Failed to load data error"); + return -1; + } + + if (dbus_connection_send(conn, message, NULL) == FALSE) { + _ERR("dbus send error"); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(message); + + SECURE_LOGD("[__SUSPEND__] Send suspend hint, pid: %d", pid); +#endif return 0; } +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT +static gboolean __flush_memory(gpointer data) +{ + int suspend = APPCORE_SUSPENDED_STATE_WILL_ENTER_SUSPEND; + struct appcore *ac = (struct appcore *)data; + + appcore_flush_memory(); + + if (!ac) { + return FALSE; + } + ac->tid = 0; + + if (!ac->allowed_bg && !ac->suspended_state) { + _DBG("[__SUSPEND__] flush case"); + __sys_do(ac, &suspend, SE_SUSPENDED_STATE); + _appcore_request_to_suspend(getpid()); //send dbus signal to resourced + ac->suspended_state = true; + } + + return FALSE; +} +#endif + +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT +static void __add_suspend_timer(struct appcore *ac) +{ + ac->tid = g_timeout_add_seconds(5, __flush_memory, ac); +} +#endif + +static void __remove_suspend_timer(struct appcore *ac) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + if (ac->tid > 0) { + g_source_remove(ac->tid); + ac->tid = 0; + } +#endif +} + static int __aul_handler(aul_type type, bundle *b, void *data) { int ret; const char *str = NULL; + const char *bg = NULL; + struct appcore *ac = data; switch (type) { case AUL_START: _DBG("[APP %d] AUL event: AUL_START", _pid); +#ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL + const char *tep_path = NULL; + tep_path = bundle_get_val(b, AUL_TEP_PATH); + if (tep_path) { + ret = aul_check_tep_mount(tep_path); + if (ret == -1) { + _ERR("mount request not completed within 1 sec"); + exit(-1); + } + } +#endif + bg = bundle_get_val(b, AUL_K_ALLOWED_BG); + if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) { + _DBG("[__SUSPEND__] allowed background"); + ac->allowed_bg = true; + __remove_suspend_timer(data); + } + __app_reset(data, b); str = bundle_get_val(b, AUL_K_CALLER_APPID); SECURE_LOGD("caller_appid : %s", str); @@ -431,6 +613,13 @@ static int __aul_handler(aul_type type, bundle *b, void *data) break; case AUL_RESUME: _DBG("[APP %d] AUL event: AUL_RESUME", _pid); + bg = bundle_get_val(b, AUL_K_ALLOWED_BG); + if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) { + _DBG("[__SUSPEND__] allowed background"); + ac->allowed_bg = true; + __remove_suspend_timer(data); + } + if(open.callback) { ret = open.callback(open.cbdata); if (ret == 0) @@ -441,18 +630,22 @@ static int __aul_handler(aul_type type, bundle *b, void *data) break; case AUL_TERMINATE: _DBG("[APP %d] AUL event: AUL_TERMINATE", _pid); + if (!ac->allowed_bg) { + __remove_suspend_timer(data); + } __app_terminate(data); break; -#ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS - case AUL_RESUME_LCD_ON: - _DBG("[APP %d] AUL event: AUL_RESUME_LCD_ON", _pid); - __app_resume_lcd_on(data); + case AUL_TERMINATE_BGAPP: + _DBG("[APP %d] AUL event: AUL_TERMINATE_BGAPP", _pid); + if (!ac->allowed_bg) { + __remove_suspend_timer(data); + } + __bgapp_terminate(data); break; - case AUL_PAUSE_LCD_OFF: - _DBG("[APP %d] AUL event: AUL_PAUSE_LCD_OFF", _pid); - __app_pause_lcd_off(data); + case AUL_PAUSE: + _DBG("[APP %d] AUL event: AUL_PAUSE", _pid); + __app_pause(data); break; -#endif default: _DBG("[APP %d] AUL event: %d", _pid, type); /* do nothing */ @@ -488,6 +681,7 @@ EXPORT_API int appcore_set_event_callback(enum appcore_event event, struct appcore *ac = &core; struct sys_op *op; enum sys_event se; + int r = 0; for (se = SE_UNKNOWN; se < SE_MAX; se++) { if (event == to_ae[se]) @@ -505,13 +699,25 @@ EXPORT_API int appcore_set_event_callback(enum appcore_event event, op->func = cb; op->data = data; - return 0; -} - + if (op->func && !appcore_event_initialized[se]) { + r = __add_vconf(ac, se); + if (r < 0) + _ERR("Add vconf callback failed"); + else + appcore_event_initialized[se] = 1; + } else if (!op->func && appcore_event_initialized[se]) { + r = __del_vconf(se); + if (r < 0) + _ERR("Delete vconf callback failed"); + else + appcore_event_initialized[se] = 0; + } + return r; +} EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops, - int argc, char **argv) + int argc, char **argv) { int r; char dirname[PATH_MAX]; @@ -533,9 +739,9 @@ EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops, r = set_i18n(name, dirname); _retv_if(r == -1, -1); - r = __add_vconf(&core); + r = _appcore_init_suspend_dbus_handler(&core); if (r == -1) { - _ERR("Add vconf callback failed"); + _ERR("Initailzing suspended state handler failed"); goto err; } @@ -553,30 +759,39 @@ EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops, core.ops = ops; core.state = 1; /* TODO: use enum value */ + core.tid = 0; + core.suspended_state = false; + core.allowed_bg = false; _pid = getpid(); return 0; err: - __del_vconf(); + __del_vconf_list(); __clear(&core); + _appcore_fini_suspend_dbus_handler(&core); return -1; } EXPORT_API void appcore_exit(void) { if (core.state) { - __del_vconf(); + __del_vconf_list(); __clear(&core); + _appcore_fini_suspend_dbus_handler(&core); + __remove_suspend_timer(&core); } aul_finalize(); } +EXPORT_API void appcore_get_app_core(struct appcore **ac) +{ + *ac = &core; +} + EXPORT_API int appcore_flush_memory(void) { int (*flush_fn) (int); - int size = 0; - struct appcore *ac = &core; if (!core.state) { @@ -585,6 +800,7 @@ EXPORT_API int appcore_flush_memory(void) } //_DBG("[APP %d] Flushing memory ...", _pid); + _retv_if(ac == NULL || ac->ops == NULL, -1); if (ac->ops->cb_app) { ac->ops->cb_app(AE_MEM_FLUSH, ac->ops->data, NULL); @@ -592,7 +808,7 @@ EXPORT_API int appcore_flush_memory(void) flush_fn = dlsym(RTLD_DEFAULT, "sqlite3_release_memory"); if (flush_fn) { - size = flush_fn(SQLITE_FLUSH_MAX); + flush_fn(SQLITE_FLUSH_MAX); } malloc_trim(0); @@ -605,3 +821,128 @@ EXPORT_API int appcore_flush_memory(void) return 0; } + +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT +static DBusHandlerResult +__suspend_dbus_signal_filter(DBusConnection *conn, DBusMessage *message, void *user_data) +{ + const char *sender; + const char *interface; + int pid; + int state; + int suspend; + + DBusError error; + dbus_error_init(&error); + + sender = dbus_message_get_sender(message); + if (sender == NULL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + interface = dbus_message_get_interface(message); + if (interface == NULL) { + _ERR("reject by security issue - no interface\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (dbus_message_is_signal(message, interface, RESOURCED_FREEZER_SIGNAL)) { + if (dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &state, + DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID) == FALSE) { + _ERR("Failed to get data: %s", error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (pid == getpid() && state == 0) { //thawed + suspend = APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND; + SECURE_LOGD("[__SUSPEND__] state: %d (0: thawed, 1: frozen), pid: %d", state, pid); + + struct appcore *ac = (struct appcore *)user_data; + if (!ac->allowed_bg && ac->suspended_state) { + __remove_suspend_timer(ac); + __sys_do(user_data, &suspend, SE_SUSPENDED_STATE); + ac->suspended_state = false; + __add_suspend_timer(ac); + } + } + } + + return DBUS_HANDLER_RESULT_HANDLED; +} +#endif + +int _appcore_init_suspend_dbus_handler(void *data) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + DBusError error; + char rule[MAX_LOCAL_BUFSZ]; + + if (__suspend_dbus_handler_initialized) + return 0; + + dbus_error_init(&error); + if (!bus) { + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + _ERR("Failed to connect to the D-BUS daemon: %s", error.message); + dbus_error_free(&error); + return -1; + } + } + dbus_connection_setup_with_g_main(bus, NULL); + + snprintf(rule, MAX_LOCAL_BUFSZ, + "path='%s',type='signal',interface='%s'", RESOURCED_FREEZER_PATH, RESOURCED_FREEZER_INTERFACE); + /* listening to messages */ + dbus_bus_add_match(bus, rule, &error); + if (dbus_error_is_set(&error)) { + _ERR("Fail to rule set: %s", error.message); + dbus_error_free(&error); + return -1; + } + + if (dbus_connection_add_filter(bus, __suspend_dbus_signal_filter, data, NULL) == FALSE) { + _ERR("add filter fail"); + return -1; + } + + __suspend_dbus_handler_initialized = 1; + _DBG("[__SUSPEND__] suspend signal initialized"); +#endif + + return 0; +} + +int _appcore_fini_suspend_dbus_handler(void* data) +{ +#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT + DBusError error; + char rule[MAX_LOCAL_BUFSZ]; + + if (!__suspend_dbus_handler_initialized) + return 0; + + dbus_error_init(&error); + + dbus_connection_remove_filter(bus, __suspend_dbus_signal_filter, data); + + snprintf(rule, MAX_LOCAL_BUFSZ, + "path='%s',type='signal',interface='%s'", RESOURCED_FREEZER_PATH, RESOURCED_FREEZER_INTERFACE); + dbus_bus_remove_match(bus, rule, &error); + if (dbus_error_is_set(&error)) { + _ERR("Fail to rule unset: %s", error.message); + dbus_error_free(&error); + return -1; + } + + dbus_connection_close(bus); + dbus_connection_unref(bus); + + bus = NULL; + + __suspend_dbus_handler_initialized = 0; + _DBG("[__SUSPEND__] suspend signal finalized"); +#endif + + return 0; +} diff --git a/src/virtual_canvas.c b/src/virtual_canvas.c index 3b8308f..ea7a3a5 100755 --- a/src/virtual_canvas.c +++ b/src/virtual_canvas.c @@ -79,14 +79,14 @@ static bool _flush_data_to_file(Evas *e, char *data, const char *filename, int w if (evas_object_image_save(output, filename, NULL, QUALITY_N_COMPRESS) == EINA_FALSE) { evas_object_del(output); - _DBG("Faild to save a captured image (%s)\n", filename); + SECURE_LOGD("Faild to save a captured image (%s)\n", filename); return false; } evas_object_del(output); if (access(filename, F_OK) != 0) { - _DBG("File %s is not found\n", filename); + SECURE_LOGD("File %s is not found\n", filename); return false; }