tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.034209 submit/tizen_2.4/20151028.063758 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:28:52 +0000 (16:28 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:28:52 +0000 (16:28 +0900)
13 files changed:
CMakeLists.txt
appcore-common.pc.in
include/appcore-common.h
include/appcore-internal.h
packaging/app-core.spec
src/appcore-X.c
src/appcore-efl.c
src/appcore-group.c [new file with mode: 0644]
src/appcore-i18n.c
src/appcore-measure.c
src/appcore-rotation.c
src/appcore.c
src/virtual_canvas.c

index fb908e8..8d18333 100755 (executable)
@@ -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)
index 233ccde..c735904 100644 (file)
@@ -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
index f0b5b44..760bd3d 100755 (executable)
@@ -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 <I>cb</I> 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 (<I>errno</I> set) 
+ * @return 0 on success, -1 on error (<I>errno</I> 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 (<I>errno</I> set) 
- * 
+ * @return 0 on success, -1 on error (<I>errno</I> set)
+ *
  * @par Errors:
  * EINVAL - <I>cb</I> 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 (<I>errno</I> set) 
- * 
+ * @return 0 on success, -1 on error (<I>errno</I> set)
+ *
  * @par Errors:
  * EINVAL - <I>curr</I> 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 (<I>errno</I> set) 
- * 
+ * @return 0 on success, -1 on error (<I>errno</I> set)
+ *
  * @par Errors:
  * EINVAL - <I>timeformat</I> 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 - <I>msgid</I> is NULL
+ *
+ * @pre None.
+ * @post None.
+ * @see None.
+ * @remarks None.
+ *
+ * @par Sample code:
+ * @code
+#include <appcore-common.h>
+
+...
+
+{
+       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 <I>dirname</I> 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 (<I>errno</I> set)
  *
- * @return 0 on success, -1 on error (<I>errno</I> set) 
- * 
  * @par Errors:
  * EINVAL - <I>domain</I> 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 <I>envnm</I> 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
index cca466b..03ed76e 100755 (executable)
@@ -27,7 +27,9 @@
 #define LOG_TAG "APP_CORE"
 
 #include <stdio.h>
+#include <stdbool.h>
 #include <dlog.h>
+#include <bundle.h>
 #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
index d71c1b0..a4850f8 100755 (executable)
@@ -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}
 
index 34b987f..2685cec 100755 (executable)
@@ -28,6 +28,7 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
+#include <Ecore.h>
 
 #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;
+}
index ea5eabf..d55dc4d 100755 (executable)
@@ -49,6 +49,7 @@
 #include <glib.h>
 #include <stdbool.h>
 #include <aul.h>
+#include <ttrace.h>
 #include "appcore-internal.h"
 #include "appcore-efl.h"
 #include "virtual_canvas.h"
@@ -56,6 +57,8 @@
 #include <vconf/vconf.h>
 #endif
 
+#include <bundle_internal.h>
+
 #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 (file)
index 0000000..2baf5c9
--- /dev/null
@@ -0,0 +1,42 @@
+#include <Elementary.h>
+#include <stdio.h>
+#include <glib.h>
+#include <aul.h>
+#include <aul_svc.h>
+#include <Ecore_X.h>
+#include <pkgmgr-info.h>
+#include <bundle_internal.h>
+#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();
+       }
+}
+
+
index 974f81f..29ec753 100755 (executable)
 #include <errno.h>
 
 #include <vconf.h>
+#include <iniparser.h>
 
 #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;
+}
index aa379fd..147efda 100755 (executable)
@@ -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;
 }
index d99dace..bc8bf86 100755 (executable)
 #include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
-
-#include <sensor_internal_deprecated.h>
-//#include <sensor_auto_rotation.h>
-
 #include <vconf.h>
 #include <Ecore_X.h>
 #include <Ecore.h>
@@ -34,6 +30,9 @@
 
 #include "appcore-internal.h"
 
+#ifdef _APPFW_FEATURE_SENSOR_AUTO_ROTATION
+#include <sensor_internal_deprecated.h>
+
 #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;
 }
index 2205330..98ac1ea 100755 (executable)
 #include <glib.h>
 #include <sys/time.h>
 #include <dlfcn.h>
+#include <stdbool.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <vconf.h>
 #include <aul.h>
+#include <bundle_internal.h>
+#include <launch/app_signal.h>
 #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;
+}
index 3b8308f..ea7a3a5 100755 (executable)
@@ -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;
        }