Add abstract app core APIs 55/82655/22
authorJunghoon Park <jh9216.park@samsung.com>
Fri, 5 Aug 2016 02:23:11 +0000 (11:23 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Mon, 20 Feb 2017 02:10:29 +0000 (11:10 +0900)
Change-Id: I5ad5e5c9717002e3d91cbaf638bad7a910817c6d
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
16 files changed:
CMakeLists.txt
include/SLP_Appcore_PG.h [deleted file]
include/appcore-internal.h
include/appcore_base.h [new file with mode: 0644]
include/appcore_ui_base.h [new file with mode: 0644]
include/image/SLP_Appcore_PG_events.png [deleted file]
include/image/SLP_Appcore_PG_lifecycle.png [deleted file]
include/image/SLP_Appcore_PG_overview.png [deleted file]
include/image/SLP_Appcore_PG_rotation.png [deleted file]
packaging/app-core.changes [deleted file]
packaging/app-core.spec
src/appcore-noti.c [deleted file]
src/base/appcore_base.c [new file with mode: 0644]
src/base/appcore_base_private.h [new file with mode: 0644]
src/ui_base/appcore_ui_base.c [new file with mode: 0644]
src/ui_base/appcore_ui_base_private.h [new file with mode: 0644]

index 3ec39fe..01e2963 100644 (file)
@@ -23,10 +23,10 @@ SET(CMAKE_SKIP_BUILD_RPATH TRUE)
 # Build appcore-common Library
 # ------------------------------
 SET(APPCORE_COMMON "appcore-common")
-SET(SRCS_common src/appcore.c src/appcore-i18n.c src/appcore-measure.c src/appcore-rotation.c)
+SET(SRCS_common src/appcore.c src/appcore-i18n.c src/appcore-measure.c src/appcore-rotation.c src/base/appcore_base.c)
 
 
-SET(HEADERS_common appcore-common.h)
+SET(HEADERS_common appcore-common.h appcore_base.h)
 
 INCLUDE(FindPkgConfig)
 SET(APPCORE_PKG_CHECK_MODULES "gio-2.0 vconf sensor aul dlog ecore capi-system-info")
@@ -51,14 +51,13 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_COMMON}.pc DESTINATION ${LIB
 FOREACH(hfile ${HEADERS_common})
        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
 ENDFOREACH(hfile)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/SLP_Appcore_PG.h DESTINATION include)
 
 #################################################################
 # Build appcore-efl Library
 # ------------------------------
 SET(APPCORE_EFL "appcore-efl")
-SET(SRCS_efl src/appcore-efl.c src/appcore-group.c)
-SET(HEADERS_efl appcore-efl.h)
+SET(SRCS_efl src/appcore-efl.c src/appcore-group.c src/ui_base/appcore_ui_base.c)
+SET(HEADERS_efl appcore-efl.h appcore_ui_base.h)
 
 INCLUDE(FindPkgConfig)
 SET(APPCORE_PKG_CHECK_MODULES2 "elementary dlog ecore gobject-2.0 glib-2.0 aul pkgmgr-info ttrace capi-system-info")
diff --git a/include/SLP_Appcore_PG.h b/include/SLP_Appcore_PG.h
deleted file mode 100644 (file)
index df4823a..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/**
- @ingroup SLP_PG
- @defgroup SLP_PG_APPCORE Application Model and Appcore
- @{
-
-<h1 class="pg">Introduction</h1>
-
-<h2 class="pg">Purpose of this document</h2>
- This document demonstrates the basic steps needed to develop application(EFL or GTK) using appcore module in the SLP(Samsung Linux Platform). The document provides a brief introduction to the appcore architecture and explains application life-cycle of appcore. Programmers should develop their applications(EFL or GTK) based on the appcore module. The sample applications can be studied and can be used to develop other applications.
-
-<h2 class="pg">Features</h2>
-- Support EFL and GTK(including STK) application's basic function
-- Support internalization
-- Support rotation function
-- Support power state function
-
-
-
-<h1 class="pg">Components of Appcore</h3>
-@image html SLP_Appcore_PG_overview.png
-
-- Appcore EFL(libappcore-efl.so)
-  - It provides appcore_efl_main() which includes elm_init(), elm_run(), and other initializations for EFL application
-  - Refer to appcore-efl.h
-- Appcore common(libappcore-common.so)
-  - It provides useful rotation function to control sensor’s rotation operation in application
-  - It provides useful function to process internalization based on GNU gettext
-  - It provides useful function to control power-state in application
-  - Refer to appcore-common.h
-- Libraries used by Appcore
-  - EFL and GTK(STK) is a graphic widget library
-  - Sensor for supporting rotation
-  - AUL for application's life-cycle
-  - RUA for task manager
-  - Vconf for system events (such as low battery, low memory).
-@}
- @defgroup SLP_PG_APPCORE1 1.Application's life-cycle
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Application's life-cycle</h2>
-Appcore provides basic life-cycle like the following to manage application in SLP
-<table>
-  <tr>
-    <td> @image html SLP_Appcore_PG_lifecycle.png </td>
-    <td>
-      <table>
-        <tr>
-         <th>Operation</th>
-         <th>Description</th>
-       </tr>
-       <tr>
-         <td>CREATE</td>
-         <td>Called once before the main loop. Initialize the application such as window creation, data structure allocation, and etc.</td>
-       </tr>
-       <tr>
-         <td>RESET</td>
-         <td>Called at the first idler and every "relaunch" message. Reset the application states and data structures.</td>
-       </tr>
-       <tr>
-         <td>PAUSE</td>
-         <td>Called when the entire window in this application are invisible. Recommend to suspend the actions related to the visibility.</td>
-       </tr>
-       <tr>
-         <td>RESUME</td>
-         <td>Called when one of the windows in this application is visible. Resume the paused actions.</td>
-       </tr>
-       <tr>
-         <td>TERMINATE</td>
-         <td>Called once after the main loop. Release the resources.</td>
-       </tr>
-      </table> 
-    </td>
-  </tr>
-</table>
-Call the main function (appcore_efl_main() with struct appcore_ops filled with the proper function pointers. The functions are called by Appcore at the proper situation.
-@code
-struct appcore_ops {
-        void *data; // Callback data
-        int (*create)(void *); // Called before main loop 
-        int (*terminate)(void *); // Called after main loop 
-        int (*pause)(void *); // Called when every window goes back
-        int (*resume)(void *); // Called when any window comes on top
-        int (*reset)(bundle *, void *); // Called at the first idler and every relaunching
-};
-@endcode
-
-@}
- @defgroup SLP_PG_APPCORE2 2.Appcore event handling
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Appcore event handling</h2>
-An Application should perform an action when a system change occurs, such as the battery level goes low. Appcore provides APIs to handle the system changes notified by other frameworks and managers. The following figure shows the relationship between events and callback functions.
-
-@image html SLP_Appcore_PG_events.png 
-
-Appcore provides appcore_set_event_callback() to handle events from the system. If you set the callback function, it will be called when the event received. Otherwise, Appcore does default behavior which is defined as following.
-<table>
-  <tr>
-    <th>Event</th>
-    <th>Description</th>
-    <th>Default behavior</th>
-  </tr>
-  <tr>
-    <td>APPCORE_EVENT_LOW_MEMORY</td>
-    <td>A system memory goes low</td>
-    <td>call malloc_trim() to enforce giving back the freed memory</td>
-  </tr>
-  <tr>
-    <td>APPCORE_EVENT_LOW_BATTERY</td>
-    <td>A system is out of battery</td>
-    <td>Quit the main loop</td>
-  </tr>
-  <tr>
-    <td>APPCORE_EVENT_LANG_CHANGE</td>
-    <td>A system's language setting is changed</td>
-    <td>Reset the environment variable "LANG". This has influence on the function related to internationalization</td>
-  </tr>
-</table>
-
-
-@}
- @defgroup SLP_PG_APPCORE3 3.Internationalization
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Internationalization</h3>
-SLP platform uses GNU gettext for Internationalization.
-The process of using gettext is as follows:
--# Marking any phrases to be translated using gettext(“phrase”) or gettext_noop(“phrase”)
--# Generating a <I>po</I> file by extracting marked phrases using a <I>xgettext</I> command.
--# Modifying the <I>po</I> file and entering a translated phrase for the corresponding phrase.
--# Compiling a <I>po</I> file into a <I>mo</I>  file using a <I>msgfmt</I> command.
--# Installing <I>mo</I> files into proper locale directories.
--# gettext() returns a properly translated phrase while an application is running.
-
-For example, we have the following source code
-@code
-printf(“%s\n”, gettext(“Hello”));
-@endcode
-
-Then, as you can see, we can have the following po file using xgettext,
-@code
-#: hello.c:41
-msgid "Hello"
-msgstr ""
-@endcode
-
-And we can enter a translated phrase as the following,
-@code
-#: hello.c:41
-msgid "Hello"
-msgstr "안녕하세요" // Hello in Korean
-@endcode
-
-Finally we generate and install a mo file. In doing so, an application will print out "안녕하세요" instead of "Hello", if the applied language is Korean.
-
-appcore_set_i18n() has been introduced to achieve an internationalization which requires information on a mo file's name and its installed directory.
-@code
-int appcore_set_i18n(const char *domainname, const char *dirname)
-@endcode
-
-The first parameter, <I>domainname</I>, a mo file’s name and the second one, <I>dirname</I>, is the directory.<br>
-In general, a mo file will be installed in the following fashion, <I>dirname/locale/category/domainname.mo</I>. <I>locale</I> is a locale’s name, such as ‘ko’ and ‘ja’, and category is LC_MESSAGES. For instance, a mo file has been installed in /usr/share/locale/ko/LC_MESSAGES/example.mo, and then <I>dirname</I> becomes /usr/share/locale.<br>
-Typically, mo files will be installed in ${prefix}/share/locale.
-
-Generally the following macros are defined for easy to use gettext()
-@code
-#define _(str) gettext(str)
-#define gettext_noop(str) (str)
-#define N_(str) gettext_noop(str)
-@endcode
-
-N_() macro only extracts any marked phrases using xgettext command, it will not do anything in the action. This macro is used to handle an array of phrases. Since gettext() cannot be called in declaration of an array, we let N_() macro extract phrases and then call gettext(). Let’s look at the following example.
-
-@code
-static const char *messages[] = {
-       N_(“Hello”),
-       N_(“World”)
-};
-…
-printf(“Message: %s\n”, _(messages[0]);
-…
-@endcode
-
-In doing so, we now can handle phrases in an array as same as we do for the following.
-
-@code
-printf(“Message: %s\n”, _(“Hello”);
-@endcode
-
-For more details, refer to GNU gettext manual (http://www.gnu.org/software/gettext/manual/gettext.html)
-
-@}
- @defgroup SLP_PG_APPCORE4 4.Rotation
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Rotation</h3>
-An Application can display its UI in either landscape or portrait mode. The application registers to receive rotation events from the system with the appcore_set_rotation_cb() API. The system automatically calls the registered user's callback whenever the sensor framework detects that the current rotation status has changed. This continues until appcore_unset_rotation_cb() is called.
-
-@code
-enum appcore_rm {
-        APPCORE_RM_UNKNOWN,
-        APPCORE_RM_PORTRAIT_NORMAL , // Portrait mode
-        APPCORE_RM_PORTRAIT_REVERSE , // Portrait upside down mode 
-        APPCORE_RM_LANDSCAPE_NORMAL , // Left handed landscape mode
-        APPCORE_RM_LANDSCAPE_REVERSE ,  // Right handed landscape mode 
-};
-
-int appcore_set_rotation_cb(int (*cb)(enum appcore_rm, void *), void *data);
-int appcore_unset_rotation_cb(void);
-int appcore_get_rotation_state(enum appcore_rm *curr);
-@endcode
-
-<I>enum appcore_rm</I> has portrait, portrait upside down, left handed landscape, and right handed landscape mode. The following is an each mode.
-@image html SLP_Appcore_PG_rotation.png
-
-When the registered callback is called, it receives the current mode state as the first argument. According to the received mode state, the application should rotate the window, resize window to changed screen size and composite the screen.
-
-@}
- @defgroup SLP_PG_APPCORE5 5.Using code template
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Using code template</h1>
-We provide a code template for reference and convenience. You can generate a code template using the script "app-gen.sh" which is included in the <I>app-template</I> package.
-
-The usage as follow:
-@code
-# app-gen.sh
-Usage) app-gen.sh dest app_name [EFL|GTK] 
-       app_name does not support _ string because of debian usage."
-
-ex) 
- EFL application: 
-  # app-gen.sh ~/efl_app MyApp
-
- GTK application: 
-  # app-gen.sh /home/app/gtk_app TestApp GTK
-
-@endcode
-
-Let's make a simple application using template
--# Install <I>app-template</I> package
-@code
-# apt-get install app-template
-@endcode
--# Generate a code template
-@code
-# app-gen.sh ~/apps/simple simple EFL
-@endcode
--# Build a package
-@code
-# cd ~/apps/simple
-# dpkg-buildpackage -sa -rfakeroot
-@endcode
-@}
- @defgroup SLP_PG_APPCORE6 6.Example: EFL Apps
- @ingroup SLP_PG_APPCORE
- @{
-
-<h1 class="pg">Example: EFL application</h1>
-
-Header example
-@code
-12 #ifndef __APP_COMMON_H__
-13 #define __APP_COMMON_H__
-14 
-15 #include <Elementary.h>
-16 
-17 #if !defined(PACKAGE)
-18 #  define PACKAGE "example"  // for appcore_set_i18n()
-19 #endif
-20 
-21 #if !defined(LOCALEDIR)
-22 #  define LOCALEDIR "/opt/apps/com.slp.example/share/locale" // for appcore_set_i18n()
-23 #endif
-24 
-25 #if !defined(EDJDIR)
-26 #  define EDJDIR "/opt/apps/com.slp.example/share/edje"
-27 #endif
-28 
-29 #define EDJ_FILE EDJDIR "/" PACKAGE ".edj"
-30 #define GRP_MAIN "main"
-31 
-32 struct appdata
-33 {
-34         Evas_Object *win;
-35         Evas_Object *ly_main;
-36 
-37         // add more variables here
-38 };
-39 
-40 #endif // __APP_COMMON_H__ 
-@endcode
-
-Source example
-@code
-12 #include <stdio.h>
-13 #include <appcore-efl.h>
-14 #include <Ecore_X.h>
-15 
-16 #include "example.h"
-17 
-18 struct text_part {   // this for internationalization
-19         char *part;
-20         char *msgid;
-21 };
-22 
-23 static struct text_part main_txt[] = {
-24         { "txt_title", N_("Application template"), },
-25         { "txt_mesg", N_("Click to exit"), },  // N_() is do nothing. Only for extracting the string
-26 };
-27
-28
-29 static void win_del(void *data, Evas_Object *obj, void *event)
-30 {
-31         elm_exit();
-32 }
-33 
-34 static void main_quit_cb(void *data, Evas_Object *obj,
-35                 const char *emission, const char *source)
-36 {
-37         elm_exit();
-38 }
-39 
-40 static void update_ts(Evas_Object *eo, struct text_part *tp, int size)
-41 {
-42         int i;
-43 
-44         if (eo == NULL || tp == NULL || size < 0)
-45                 return;
-46 
-47         for (i = 0; i < size; i++) {
-48                 if (tp[i].part && tp[i].msgid)
-49                         edje_object_part_text_set(eo,
-50                                         tp[i].part, _(tp[i].msgid)); // _() return translated string
-51         }
-52 }
-53 
-54 static int lang_changed(void *data) // language changed callback
-55 {
-56         struct appdata *ad = data;
-57 
-58         if (ad->ly_main == NULL)
-59                 return 0;
-60 
-61         update_ts(elm_layout_edje_get(ad->ly_main), main_txt,
-62                         sizeof(main_txt)/sizeof(main_txt[0]));
-63 
-64         return 0;
-65 }
-66 
-67 static int rotate(enum appcore_rm m, void *data) // rotation callback
-68 {
-69         struct appdata *ad = data;
-70         int r;
-71 
-72         if (ad == NULL || ad->win == NULL)
-73                 return 0;
-74 
-75         switch(m) {
-76         case APPCORE_RM_PORTRAIT_NORMAL:
-77                 r = 0;
-78                 break;
-79         case APPCORE_RM_PORTRAIT_REVERSE:
-80                 r = 180;
-81                 break;
-82         case APPCORE_RM_LANDSCAPE_NORMAL:
-83                 r = 270;
-84                 break;
-85         case APPCORE_RM_LANDSCAPE_REVERSE:
-86                 r = 90;
-87                 break;
-88         default:
-89                 r = -1;
-90                 break;
-91         }
-92 
-93         if (r >= 0) // Using this API, you can implement the rotation mode easily
-94                 elm_win_rotation_with_resize_set(ad->win, r);
-95 
-96         return 0;
-97 }
-98 
-99 static Evas_Object* create_win(const char *name)
-100 {
-101         Evas_Object *eo;
-102         int w, h;
-103 
-104         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
-105         if (eo) {
-106                 elm_win_title_set(eo, name);
-107                 elm_win_borderless_set(eo, EINA_TRUE);
-108                 evas_object_smart_callback_add(eo, "delete,request",
-109                                 win_del, NULL);
-110                 ecore_x_window_size_get(ecore_x_window_root_first_get(), // get root window(screen) size
-111                                 &w, &h);
-112                 evas_object_resize(eo, w, h);
-113         }
-114 
-115         return eo;
-116 }
-117 
-118 static Evas_Object* load_edj(Evas_Object *parent, const char *file,
-119                 const char *group)
-120 {
-121         Evas_Object *eo;
-122         int r;
-123 
-124         eo = elm_layout_add(parent);
-125         if (eo) {
-126                 r = elm_layout_file_set(eo, file, group);
-127                 if (!r) {
-128                         evas_object_del(eo);
-129                         return NULL;
-130                 }
-131 
-132                 evas_object_size_hint_weight_set(eo,
-133                                 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-134         }
-135 
-136         return eo;
-137 }
-138 
-139 static int app_create(void *data)
-140 {
-141         struct appdata *ad = data;
-142         Evas_Object *win;
-143         Evas_Object *ly;
-144         int r;
-145 
-146         // create window 
-147         win = create_win(PACKAGE);
-148         if (win == NULL)
-149                 return -1;
-150         ad->win = win;
-151 
-152         // load edje 
-153         ly = load_edj(win, EDJ_FILE, GRP_MAIN);
-154         if (ly == NULL)
-155                 return -1;
-156         elm_win_resize_object_add(win, ly); // This can make the EDJE object fitted in window size
-157         edje_object_signal_callback_add(elm_layout_edje_get(ly),
-158                         "EXIT", "*", main_quit_cb, NULL);
-159         ad->ly_main = ly;
-160         evas_object_show(ly);
-161 
-166         lang_changed(ad); // call the language changed callback to update strings
-167 
-168         evas_object_show(win);
-169 
-170         // add system event callback 
-171         appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE,
-172                         lang_changed, ad);
-173 
-174         appcore_set_rotation_cb(rotate, ad); // set rotation callback
-175 
-176         // appcore measure time example 
-177         printf("from AUL to %s(): %d msec\n", __func__,
-178                         appcore_measure_time_from("APP_START_TIME"));
-179 
-180         appcore_measure_start();
-181         return 0;
-182 }
-183 
-184 static int app_terminate(void *data) // terminate callback
-185 {
-186         struct appdata *ad = data;
-187 
-188         if (ad->ly_main)
-189                 evas_object_del(ad->ly_main);
-190 
-191         if (ad->win)
-192                 evas_object_del(ad->win);
-193 
-194         return 0;
-195 }
-196 
-197 static int app_pause(void *data) // pause callback
-198 {
-199         struct appdata *ad = data;
-200 
-201         return 0;
-202 }
-203 
-204 static int app_resume(void *data) // resume callback
-205 {
-206         struct appdata *ad = data;
-207 
-208         return 0;
-209 }
-210 
-211 static int app_reset(bundle *b, void *data) // reset callback
-212 {
-213         struct appdata *ad = data;
-214 
-215         // appcore measure time example 
-216         printf("from AUL to %s(): %d msec\n", __func__,
-217                         appcore_measure_time_from("APP_START_TIME"));
-218         printf("from create to %s(): %d msec\n", __func__,
-219                         appcore_measure_time());
-220 
-221         if (ad->win)
-222                 elm_win_activate(ad->win); // You should make one of the window on top
-223 
-224         return 0;
-225 }
-226 
-227 int main(int argc, char *argv[])
-228 {
-229         struct appdata ad;
-230         struct appcore_ops ops = {  // fill the appcore_ops with callback functions
-231                 .create = app_create,
-232                 .terminate = app_terminate,
-233                 .pause = app_pause,
-234                 .resume = app_resume,
-235                 .reset = app_reset,
-236         };
-237 
-238         // appcore measure time example 
-239         printf("from AUL to %s(): %d msec\n", __func__,
-240                         appcore_measure_time_from("APP_START_TIME"));
-241 
-242         memset(&ad, 0x0, sizeof(struct appdata));
-243         ops.data = &ad;
-244 
-245         return appcore_efl_main(PACKAGE, &argc, &argv, &ops); // start mainloop
-246 }
-@endcode
-
- @}
-**/
index ff6ced3..4253acb 100644 (file)
@@ -161,11 +161,6 @@ extern void update_lang(void);
 extern int set_i18n(const char *domainname, const char *dirname);
 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);*/
 
diff --git a/include/appcore_base.h b/include/appcore_base.h
new file mode 100644 (file)
index 0000000..bd8b758
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <libintl.h>
+#include <bundle.h>
+#include <aul.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum appcore_base_rm {
+       APPCORE_BASE_RM_UNKNOWN,
+       APPCORE_BASE_RM_PORTRAIT_NORMAL,
+       APPCORE_BASE_RM_PORTRAIT_REVERSE,
+       APPCORE_BASE_RM_LANDSCAPE_NORMAL,
+       APPCORE_BASE_RM_LANDSCAPE_REVERSE,
+};
+
+enum appcore_base_event {
+       APPCORE_BASE_EVENT_START,
+       APPCORE_BASE_EVENT_LOW_MEMORY,
+       APPCORE_BASE_EVENT_LOW_BATTERY,
+       APPCORE_BASE_EVENT_LANG_CHANGE,
+       APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
+       APPCORE_BASE_EVENT_REGION_CHANGE,
+       APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
+       APPCORE_BASE_EVENT_UPDATE_REQUESTED,
+       APPCORE_BASE_EVENT_MAX,
+};
+
+enum appcore_base_suspended_state {
+       APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND = 0,
+       APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND
+};
+
+
+typedef int (*appcore_base_event_cb)(void *event, void *data);
+typedef void *appcore_base_event_h;
+
+typedef struct _appcore_base_ops {
+       int (*create) (void *data);
+       int (*terminate) (void *data);
+       int (*control) (bundle *b, void *data);
+       int (*receive)(aul_type type, bundle *b, void *data);
+       int (*set_i18n)(void *data);
+       void (*run)(void *data);
+       void (*exit)(void *data);
+       void (*set_event)(enum appcore_base_event event, void *data);
+       void (*unset_event)(enum appcore_base_event event, void *data);
+} appcore_base_ops;
+
+int appcore_base_on_receive(aul_type type, bundle *b);
+int appcore_base_on_create(void);
+int appcore_base_on_control(bundle *b);
+int appcore_base_on_terminate(void);
+int appcore_base_on_set_i18n(void);
+void appcore_base_on_set_event(enum appcore_base_event event);
+void appcore_base_on_unset_event(enum appcore_base_event event);
+int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data);
+void appcore_base_fini(void);
+appcore_base_ops appcore_base_get_default_ops(void);
+appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
+               appcore_base_event_cb cb, void *data);
+int appcore_base_remove_event(appcore_base_event_h handle);
+int appcore_base_raise_event(void *event, enum appcore_base_event type);
+int appcore_base_flush_memory(void);
+int appcore_base_get_rotation_state(enum appcore_base_rm *curr);
+bool appcore_base_is_bg_allowed(void);
+bool appcore_base_is_suspended(void);
+void appcore_base_toggle_suspended_state(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/include/appcore_ui_base.h b/include/appcore_ui_base.h
new file mode 100644 (file)
index 0000000..dc9d615
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <libintl.h>
+#include <bundle.h>
+#include <aul.h>
+#include <appcore_base.h>
+
+typedef struct _appcore_ui_base_window_ops {
+       void (*show)(int type, void *event, void *data);
+       void (*hide)(int type, void *event, void *data);
+       void (*lower)(int type, void *event, void *data);
+       void (*visibility)(int type, void *event, void *data);
+} appcore_ui_base_window_ops;
+
+typedef struct _appcore_ui_base_ops {
+       int (*pause) (void *data);
+       int (*resume) (void *data);
+       appcore_base_ops base;
+       appcore_ui_base_window_ops window;
+} appcore_ui_base_ops;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum appcore_ui_base_hint {
+       APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL = 0x1,
+       APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL = 0x2,
+       APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL = 0x4,
+       APPCORE_UI_BASE_HINT_HW_ACC_CONTROL = 0x8,
+};
+
+int appcore_ui_base_on_receive(aul_type type, bundle *b);
+int appcore_ui_base_on_create(void);
+int appcore_ui_base_on_terminate(void);
+int appcore_ui_base_on_pause(void);
+int appcore_ui_base_on_resume(void);
+int appcore_ui_base_on_control(bundle *b);
+void appcore_ui_base_window_on_show(int type, void *event);
+void appcore_ui_base_window_on_hide(int type, void *event);
+void appcore_ui_base_window_on_lower(int type, void *event);
+void appcore_ui_base_window_on_visibility(int type, void *event);
+int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
+               void *data, unsigned int hint);
+void appcore_ui_base_fini(void);
+appcore_ui_base_ops appcore_ui_base_get_default_ops(void);
+void appcore_ui_base_pause(void);
+void appcore_ui_base_resume(void);
+bool appcore_ui_base_is_resumed(void);
+void appcore_ui_base_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/include/image/SLP_Appcore_PG_events.png b/include/image/SLP_Appcore_PG_events.png
deleted file mode 100644 (file)
index 03a1547..0000000
Binary files a/include/image/SLP_Appcore_PG_events.png and /dev/null differ
diff --git a/include/image/SLP_Appcore_PG_lifecycle.png b/include/image/SLP_Appcore_PG_lifecycle.png
deleted file mode 100644 (file)
index 0b12db4..0000000
Binary files a/include/image/SLP_Appcore_PG_lifecycle.png and /dev/null differ
diff --git a/include/image/SLP_Appcore_PG_overview.png b/include/image/SLP_Appcore_PG_overview.png
deleted file mode 100644 (file)
index ce3fbc9..0000000
Binary files a/include/image/SLP_Appcore_PG_overview.png and /dev/null differ
diff --git a/include/image/SLP_Appcore_PG_rotation.png b/include/image/SLP_Appcore_PG_rotation.png
deleted file mode 100644 (file)
index 444d7ba..0000000
Binary files a/include/image/SLP_Appcore_PG_rotation.png and /dev/null differ
diff --git a/packaging/app-core.changes b/packaging/app-core.changes
deleted file mode 100644 (file)
index a9e9ec7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-* Tue May 28 2013 Xavier Roche <xavrock.os@gmail.com> accepted/tizen/20130520.100903@8c0d950
-- Fix X86_64 build-install compliance
-
index 1abb475..cea659c 100644 (file)
@@ -115,6 +115,7 @@ rm -rf %{buildroot}
 %files efl-devel
 %manifest %{name}.manifest
 %{_includedir}/appcore/appcore-efl.h
+%{_includedir}/appcore/appcore_ui_base.h
 %{_libdir}/libappcore-efl.so
 %{_libdir}/pkgconfig/appcore-efl.pc
 
@@ -128,4 +129,5 @@ rm -rf %{buildroot}
 %{_libdir}/libappcore-common.so
 %{_libdir}/pkgconfig/appcore-common.pc
 %{_includedir}/appcore/appcore-common.h
-%{_includedir}/SLP_Appcore_PG.h
+%{_includedir}/appcore/appcore_base.h
+
diff --git a/src/appcore-noti.c b/src/appcore-noti.c
deleted file mode 100644 (file)
index c3af2aa..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <heynoti.h>
-
-#include "appcore-internal.h"
-
-#define NOTI_COMP(a, b) (strcmp(a->name, b->name))
-
-struct noti_s {
-       const char *name;
-       void *data;
-       int (*cb_pre) (void *);
-       int (*cb) (void *);
-       int (*cb_post) (void *);
-
-       struct noti_s *next;
-};
-typedef struct noti_s notis;
-
-
-SGLIB_DEFINE_LIST_PROTOTYPES(notis, NOTI_COMP, next);
-SGLIB_DEFINE_LIST_FUNCTIONS(notis, NOTI_COMP, next);
-
-static struct noti_s *noti_h;
-
-static void __main_handle(void *data)
-{
-       struct noti_s *n = data;
-
-       _ret_if(n == NULL || n->name == NULL);
-
-       _DBG("[APP %d] noti: %s", getpid(), n->name);
-
-       if (n->cb_pre)
-               n->cb_pre(n->data);
-
-       if (n->cb)
-               n->cb(n->data);
-
-       if (n->cb_post)
-               n->cb_post(n->data);
-}
-
-static int __del_noti(int fd, struct noti_s *t)
-{
-       int r;
-
-       r = heynoti_unsubscribe(fd, t->name, __main_handle);
-       if (r == 0) {
-               sglib_notis_delete(&noti_h, t);
-               free((void *)t->name);
-               free(t);
-       }
-
-       return r;
-}
-
-static int __del_notis(int fd)
-{
-       struct sglib_notis_iterator it;
-       struct noti_s *t;
-
-       t = sglib_notis_it_init(&it, noti_h);
-       while (t) {
-               __del_noti(fd, t);
-               t = sglib_notis_it_next(&it);
-       }
-
-       return 0;
-}
-
-int add_noti(int fd, const char *name, int (*cb_pre) (void *),
-            int (*cb) (void *), int (*cb_post) (void *), void *data)
-{
-       int r;
-       struct noti_s *t;
-
-       if (fd < 0) {
-               errno = EBADF;
-               return -1;
-       }
-
-       if (name == NULL || name[0] == '\0') {
-               errno = EINVAL;
-               return -1;
-       }
-
-       t = calloc(1, sizeof(struct noti_s));
-       if (t == NULL)
-               return -1;
-
-       t->name = strdup(name);
-       if (t->name == NULL) {
-               free(t);
-               return -1;
-       }
-
-       t->cb_pre = cb_pre;
-       t->cb = cb;
-       t->cb_post = cb_post;
-       t->data = data;
-
-       r = heynoti_subscribe(fd, name, __main_handle, t);
-       if (r != 0) {
-               free((void *)t->name);
-               free(t);
-               return -1;
-       }
-
-       sglib_notis_add(&noti_h, t);
-
-       return r;
-}
-
-int del_noti(int fd, const char *name)
-{
-       struct noti_s t;
-       struct noti_s *f;
-
-       if (fd < 0) {
-               errno = EBADF;
-               return -1;
-       }
-
-       t.name = name;
-       f = sglib_notis_find_member(noti_h, &t);
-       if (f == NULL) {
-               errno = ENOENT;
-               return -1;
-       }
-
-       return __del_noti(fd, f);
-}
-
-int noti_start(int fd)
-{
-       return heynoti_attach_handler(fd);
-}
-
-int noti_init(void)
-{
-       return heynoti_init();
-}
-
-void noti_exit(int *fd)
-{
-       _ret_if(fd == NULL || *fd < 0);
-
-       __del_notis(*fd);
-
-       heynoti_close(*fd);
-
-       *fd = -1;
-}
diff --git a/src/base/appcore_base.c b/src/base/appcore_base.c
new file mode 100644 (file)
index 0000000..7c1b826
--- /dev/null
@@ -0,0 +1,746 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <locale.h>
+#include <libintl.h>
+#include <linux/limits.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+#include <vconf.h>
+#include <aul.h>
+#include <bundle_internal.h>
+#include "appcore_base.h"
+#include "appcore_base_private.h"
+
+#define PATH_LOCALE "locale"
+#define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
+#define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
+#define RESOURCED_FREEZER_SIGNAL "FreezerState"
+
+typedef struct _appcore_base_context {
+       appcore_base_ops ops;
+       void *data;
+       int argc;
+       char **argv;
+       unsigned int tid;
+       bool suspended_state;
+       bool allowed_bg;
+} appcore_base_context;
+
+typedef struct _appcore_base_event_node {
+       int type;
+       appcore_base_event_cb cb;
+       void *data;
+} appcore_base_event_node;
+
+static appcore_base_context __context;
+static GList *__events;
+static GDBusConnection *__bus;
+static guint __suspend_dbus_handler_initialized;
+
+static void __invoke_callback(void *event, int type)
+{
+       GList *iter = __events;
+
+       while (iter) {
+               appcore_base_event_node *node = iter->data;
+
+               if (node->type == type)
+                       node->cb(event, node->data);
+               iter = g_list_next(iter);
+       }
+}
+
+static bool __exist_callback(int type)
+{
+       GList *iter = __events;
+
+       while (iter) {
+               appcore_base_event_node *node = iter->data;
+
+               if (node->type == type)
+                       return true;
+
+               iter = g_list_next(iter);
+       }
+
+       return false;
+}
+
+static void __on_low_memory(keynode_t *key, void *data)
+{
+       int val;
+
+       val = vconf_keynode_get_int(key);
+
+       if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
+               __invoke_callback(key, APPCORE_BASE_EVENT_LOW_MEMORY);
+               malloc_trim(0);
+       }
+}
+
+static void __on_low_battery(keynode_t *key, void *data)
+{
+       int val;
+
+       val = vconf_keynode_get_int(key);
+
+       if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
+               __invoke_callback(key, APPCORE_BASE_EVENT_LOW_BATTERY);
+}
+
+static void __update_lang(void)
+{
+       char language[32];
+       char *lang;
+       char *r;
+
+       lang = vconf_get_str(VCONFKEY_LANGSET);
+       if (lang) {
+               snprintf(language, sizeof(language), "%s:en_US:en_GB:en", lang);
+               setenv("LANGUAGE", language, 1);
+               setenv("LANG", lang, 1);
+               setenv("LC_MESSAGES", lang, 1);
+               r = setlocale(LC_ALL, "");
+               if (r == NULL) {
+                       r = setlocale(LC_ALL, lang);
+                       if (r != NULL)
+                               _DBG("*****appcore setlocale=%s\n", r);
+               }
+               free(lang);
+       }
+}
+
+static void __update_region(void)
+{
+       char *region;
+       char *r;
+
+       region = vconf_get_str(VCONFKEY_REGIONFORMAT);
+       if (region) {
+               setenv("LC_CTYPE", region, 1);
+               setenv("LC_NUMERIC", region, 1);
+               setenv("LC_TIME", region, 1);
+               setenv("LC_COLLATE", region, 1);
+               setenv("LC_MONETARY", region, 1);
+               setenv("LC_PAPER", region, 1);
+               setenv("LC_NAME", region, 1);
+               setenv("LC_ADDRESS", region, 1);
+               setenv("LC_TELEPHONE", region, 1);
+               setenv("LC_MEASUREMENT", region, 1);
+               setenv("LC_IDENTIFICATION", region, 1);
+               r = setlocale(LC_ALL, "");
+               if (r != NULL)
+                       _DBG("*****appcore setlocale=%s\n", r);
+
+               free(region);
+       }
+}
+
+static void __on_language_change(keynode_t *key, void *data)
+{
+       char *val;
+
+       val = vconf_keynode_get_str(key);
+
+       __update_lang();
+       __invoke_callback((void *)val, APPCORE_BASE_EVENT_LANG_CHANGE);
+}
+
+static void __on_region_change(keynode_t *key, void *data)
+{
+       char *val = NULL;
+       const char *name;
+
+       name = vconf_keynode_get_name(key);
+       if (!strcmp(name, VCONFKEY_REGIONFORMAT))
+               val = vconf_keynode_get_str(key);
+
+       __update_region();
+       __invoke_callback((void *)val, APPCORE_BASE_EVENT_REGION_CHANGE);
+}
+
+static gboolean __flush_memory(gpointer data)
+{
+       int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
+
+       appcore_base_flush_memory();
+       __context.tid = 0;
+
+       if (!__context.allowed_bg && !__context.suspended_state) {
+               _DBG("[__SUSPEND__] flush case");
+               __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+               __context.suspended_state = true;
+       }
+
+       return FALSE;
+}
+
+static void __add_suspend_timer(void)
+{
+       __context.tid = g_timeout_add_seconds(5, __flush_memory, NULL);
+}
+
+static void __remove_suspend_timer(void)
+{
+       if (__context.tid > 0) {
+               g_source_remove(__context.tid);
+               __context.tid = 0;
+       }
+}
+
+static void __on_receive_suspend_signal(GDBusConnection *connection,
+                                       const gchar *sender_name,
+                                       const gchar *object_path,
+                                       const gchar *interface_name,
+                                       const gchar *signal_name,
+                                       GVariant *parameters,
+                                       gpointer user_data)
+{
+       gint suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+       gint pid;
+       gint status;
+
+       if (g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL) == 0) {
+               g_variant_get(parameters, "(ii)", &status, &pid);
+               if (pid == getpid() && status == 0) {
+                       if (!__context.allowed_bg && __context.suspended_state) {
+                               __remove_suspend_timer();
+                               __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+                               __context.suspended_state = false;
+                               __add_suspend_timer();
+                       }
+               }
+       }
+}
+
+static int __init_suspend_dbus_handler(void)
+{
+       GError *err = NULL;
+
+       if (__suspend_dbus_handler_initialized)
+               return 0;
+
+       if (!__bus) {
+               __bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+               if (!__bus) {
+                       _ERR("Failed to connect to the D-BUS daemon: %s",
+                                               err->message);
+                       g_error_free(err);
+                       return -1;
+               }
+       }
+
+       __suspend_dbus_handler_initialized = g_dbus_connection_signal_subscribe(
+                                               __bus,
+                                               NULL,
+                                               RESOURCED_FREEZER_INTERFACE,
+                                               RESOURCED_FREEZER_SIGNAL,
+                                               RESOURCED_FREEZER_PATH,
+                                               NULL,
+                                               G_DBUS_SIGNAL_FLAGS_NONE,
+                                               __on_receive_suspend_signal,
+                                               NULL,
+                                               NULL);
+       if (__suspend_dbus_handler_initialized == 0) {
+               _ERR("g_dbus_connection_signal_subscribe() is failed.");
+               return -1;
+       }
+
+       _DBG("[__SUSPEND__] suspend signal initialized");
+
+       return 0;
+}
+
+static void __fini_suspend_dbus_handler(void)
+{
+       if (__bus == NULL)
+               return;
+
+       if (__suspend_dbus_handler_initialized) {
+               g_dbus_connection_signal_unsubscribe(__bus,
+                               __suspend_dbus_handler_initialized);
+               __suspend_dbus_handler_initialized = 0;
+       }
+
+       g_object_unref(__bus);
+       __bus = NULL;
+}
+
+static int __get_locale_resource_dir(char *locale_dir, int size)
+{
+       const char *res_path;
+
+       res_path = aul_get_app_resource_path();
+       if (res_path == NULL) {
+               _ERR("Failed to get resource path");
+               return -1;
+       }
+
+       snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
+       if (access(locale_dir, R_OK) != 0)
+               return -1;
+
+       return 0;
+}
+
+static int __get_app_name(const char *appid, char **name)
+{
+       char *name_token = NULL;
+
+       if (appid == NULL)
+               return -1;
+
+       /* com.vendor.name -> name */
+       name_token = strrchr(appid, '.');
+       if (name_token == NULL)
+               return -1;
+
+       name_token++;
+
+       *name = strdup(name_token);
+       if (*name == NULL)
+               return -1;
+
+       return 0;
+}
+
+static int __set_i18n(const char *domain, const char *dir)
+{
+       char *r;
+       char *lan;
+
+       if (domain == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       __update_lang();
+       __update_region();
+
+       r = setlocale(LC_ALL, "");
+       /* if locale is not set properly, try again to set as language base */
+       if (r == NULL) {
+               lan = vconf_get_str(VCONFKEY_LANGSET);
+               if (lan != NULL) {
+                       r = setlocale(LC_ALL, lan);
+                       _DBG("*****appcore setlocale=%s\n", r);
+                       free(lan);
+               }
+       }
+       if (r == NULL)
+               _ERR("appcore: setlocale() error");
+
+       r = bindtextdomain(domain, dir);
+       if (r == NULL)
+               _ERR("appcore: bindtextdomain() error");
+
+       r = textdomain(domain);
+       if (r == NULL)
+               _ERR("appcore: textdomain() error");
+
+       return 0;
+}
+
+EXPORT_API int appcore_base_on_set_i18n(void)
+{
+       int r;
+       char locale_dir[PATH_MAX];
+       char appid[PATH_MAX];
+       char *name = NULL;
+
+       r = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
+       if (r < 0)
+               return -1;
+
+       r = __get_app_name(appid, &name);
+       if (r < 0)
+               return -1;
+
+       r = __get_locale_resource_dir(locale_dir, sizeof(locale_dir));
+       if (r < 0) {
+               free(name);
+               return -1;
+       }
+
+       r = __set_i18n(name, locale_dir);
+       if (r < 0) {
+               free(name);
+               return -1;
+       }
+
+       free(name);
+
+       return 0;
+}
+
+EXPORT_API int appcore_base_init(appcore_base_ops ops, int argc, char **argv, void *data)
+{
+       __context.ops = ops;
+       __context.argc = argc;
+       __context.argv = argv;
+       __context.data = data;
+       __context.tid = 0;
+       __context.suspended_state = false;
+       __context.allowed_bg = false;
+
+       if (__context.ops.set_i18n)
+               __context.ops.set_i18n(__context.data);
+
+       __init_suspend_dbus_handler();
+
+       if (__context.ops.create && __context.ops.create(__context.data) < 0) {
+               aul_status_update(STATUS_DYING);
+               return 0;
+       }
+
+       if (__context.ops.run)
+               __context.ops.run(__context.data);
+
+       return 0;
+}
+
+EXPORT_API void appcore_base_fini(void)
+{
+       int i;
+
+       for (i = APPCORE_BASE_EVENT_START + 1; i < APPCORE_BASE_EVENT_MAX; i++) {
+               if (__exist_callback(i)) {
+                       if (__context.ops.unset_event)
+                               __context.ops.unset_event(i, __context.data);
+               }
+       }
+
+       g_list_free_full(__events, free);
+       __events = NULL;
+       __fini_suspend_dbus_handler();
+
+       aul_status_update(STATUS_DYING);
+       if (__context.ops.terminate)
+               __context.ops.terminate(__context.data);
+
+}
+
+EXPORT_API int appcore_base_flush_memory(void)
+{
+       malloc_trim(0);
+       return 0;
+}
+
+EXPORT_API int appcore_base_on_receive(aul_type type, bundle *b)
+{
+       int ret;
+       const char **tep_path;
+       int len = 0;
+       int i;
+       const char *bg;
+       int dummy = 0;
+
+       switch (type) {
+       case AUL_START:
+               _DBG("[APP %d]     AUL event: AUL_START", getpid());
+               tep_path = bundle_get_str_array(b, AUL_TEP_PATH, &len);
+               if (tep_path) {
+                       for (i = 0; i < len; i++) {
+                               ret = aul_check_tep_mount(tep_path[i]);
+                               if (ret == -1) {
+                                       _ERR("mount request not completed within 1 sec");
+                                       exit(-1);
+                               }
+                       }
+               }
+
+               bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
+               if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
+                       _DBG("[__SUSPEND__] allowed background");
+                       __context.allowed_bg = true;
+                       __remove_suspend_timer();
+               }
+
+               if (__context.ops.control)
+                      __context.ops.control(b, __context.data);
+               break;
+       case AUL_RESUME:
+               _DBG("[APP %d]     AUL event: AUL_RESUME", getpid());
+               bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
+               if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
+                       _DBG("[__SUSPEND__] allowed background");
+                       __context.allowed_bg = true;
+                       __remove_suspend_timer();
+               }
+               break;
+       case AUL_TERMINATE:
+               _DBG("[APP %d]     AUL event: AUL_TERMINATE", getpid());
+               aul_status_update(STATUS_DYING);
+               if (!__context.allowed_bg)
+                       __remove_suspend_timer();
+
+               if (__context.ops.exit)
+                       __context.ops.exit(__context.data);
+               break;
+       case AUL_TERMINATE_BGAPP:
+               _DBG("[APP %d]     AUL event: AUL_TERMINATE_BGAPP", getpid());
+               if (!__context.allowed_bg)
+                       __remove_suspend_timer();
+               break;
+       case AUL_WAKE:
+               _DBG("[APP %d]     AUL event: AUL_WAKE", getpid());
+               if (!__context.allowed_bg && __context.suspended_state) {
+                       int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+                       __remove_suspend_timer();
+                       __invoke_callback((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+                       __context.suspended_state = false;
+               }
+               break;
+       case AUL_SUSPEND:
+               _DBG("[APP %d]     AUL event: AUL_SUSPEND", getpid());
+               if (!__context.allowed_bg && !__context.suspended_state) {
+                       __remove_suspend_timer();
+                       __flush_memory(NULL);
+               }
+               break;
+       case AUL_UPDATE_REQUESTED:
+               _DBG("[APP %d]     AUL event: AUL_UPDATE_REQUESTED", getpid());
+               __invoke_callback((void *)&dummy, APPCORE_BASE_EVENT_UPDATE_REQUESTED);
+               break;
+       default:
+               _DBG("[APP %d]     AUL event: %d", getpid(), type);
+               /* do nothing */
+               break;
+       }
+
+       return 0;
+}
+
+EXPORT_API int appcore_base_on_create(void)
+{
+       int r;
+       r = aul_launch_init(__context.ops.receive, NULL);
+       if (r < 0) {
+               _ERR("Aul init failed: %d", r);
+               return -1;
+       }
+
+       r = aul_launch_argv_handler(__context.argc, __context.argv);
+       if (r < 0) {
+               _ERR("Aul argv handler failed: %d", r);
+               return -1;
+       }
+
+       return 0;
+}
+
+EXPORT_API int appcore_base_on_control(bundle *b)
+{
+       return 0;
+}
+
+EXPORT_API int appcore_base_on_terminate()
+{
+       aul_finalize();
+       if (__context.ops.exit)
+               __context.ops.exit(__context.data);
+
+       return 0;
+}
+
+EXPORT_API void appcore_base_on_set_event(enum appcore_base_event event)
+{
+       int r;
+
+       switch (event) {
+       case APPCORE_BASE_EVENT_LOW_MEMORY:
+               vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
+               break;
+       case APPCORE_BASE_EVENT_LOW_BATTERY:
+               vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL);
+               break;
+       case APPCORE_BASE_EVENT_LANG_CHANGE:
+               vconf_notify_key_changed(VCONFKEY_LANGSET, __on_language_change, NULL);
+               break;
+       case APPCORE_BASE_EVENT_REGION_CHANGE:
+               r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change, NULL);
+               if (r < 0)
+                       break;
+
+               vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change, NULL);
+               break;
+       case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
+               break;
+
+       default:
+               break;
+       }
+
+}
+
+EXPORT_API void appcore_base_on_unset_event(enum appcore_base_event event)
+{
+       int r;
+
+       switch (event) {
+       case APPCORE_BASE_EVENT_LOW_MEMORY:
+               vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
+               break;
+       case APPCORE_BASE_EVENT_LOW_BATTERY:
+               vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
+               break;
+       case APPCORE_BASE_EVENT_LANG_CHANGE:
+               vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_language_change);
+               break;
+       case APPCORE_BASE_EVENT_REGION_CHANGE:
+               r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_change);
+               if (r < 0)
+                       break;
+               vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, __on_region_change);
+               break;
+       case APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE:
+               break;
+       default:
+               break;
+       }
+}
+
+EXPORT_API appcore_base_event_h appcore_base_add_event(enum appcore_base_event event,
+               appcore_base_event_cb cb, void *data)
+{
+       appcore_base_event_node *node;
+
+       if (!__exist_callback(event)) {
+               if (__context.ops.set_event)
+                       __context.ops.set_event(event, __context.data);
+       }
+
+       node = malloc(sizeof(appcore_base_event_node));
+
+       if (node == NULL)
+               return NULL;
+
+       node->cb = cb;
+       node->type = event;
+       node->data = data;
+       __events = g_list_append(__events, node);
+
+       return node;
+}
+
+EXPORT_API int appcore_base_remove_event(appcore_base_event_h handle)
+{
+       appcore_base_event_node *node = handle;
+       enum appcore_base_event event;
+
+       event = node->type;
+       __events = g_list_remove(__events, node);
+       free(node);
+       if (!__exist_callback(event)) {
+               if (__context.ops.unset_event)
+                       __context.ops.unset_event(event, __context.data);
+       }
+
+       return 0;
+}
+
+EXPORT_API int appcore_base_raise_event(void *event, enum appcore_base_event type)
+{
+       __invoke_callback(event, type);
+       return 0;
+}
+
+EXPORT_API int appcore_base_get_rotation_state(enum appcore_base_rm *curr)
+{
+       return 0;
+}
+
+EXPORT_API bool appcore_base_is_bg_allowed(void)
+{
+       return __context.allowed_bg;
+}
+
+EXPORT_API bool appcore_base_is_suspended(void)
+{
+       return __context.suspended_state;
+}
+
+EXPORT_API void appcore_base_toggle_suspended_state(void)
+{
+       __context.suspended_state ^= __context.suspended_state;
+}
+
+static int __on_receive(aul_type type, bundle *b, void *data)
+{
+       return appcore_base_on_receive(type, b);
+}
+
+static int __on_create(void *data)
+{
+       return appcore_base_on_create();
+}
+
+static int __on_control(bundle *b, void *data)
+{
+       return appcore_base_on_control(b);
+}
+
+static int __on_terminate(void *data)
+{
+       return appcore_base_on_terminate();
+}
+
+static int __on_set_i18n(void *data)
+{
+       return appcore_base_on_set_i18n();
+}
+
+static void __on_set_event(enum appcore_base_event event, void *data)
+{
+       return appcore_base_on_set_event(event);
+}
+
+static void __on_unset_event(enum appcore_base_event event, void *data)
+{
+       return appcore_base_on_unset_event(event);
+}
+
+EXPORT_API appcore_base_ops appcore_base_get_default_ops(void)
+{
+       appcore_base_ops ops;
+
+       ops.create = __on_create;
+       ops.control = __on_control;
+       ops.terminate = __on_terminate;
+       ops.receive = __on_receive;
+       ops.set_i18n = __on_set_i18n;
+       ops.run = NULL;
+       ops.exit = NULL;
+       ops.set_event = __on_set_event;
+       ops.unset_event = __on_unset_event;
+
+       return ops;
+}
+
+
diff --git a/src/base/appcore_base_private.h b/src/base/appcore_base_private.h
new file mode 100644 (file)
index 0000000..9e596fe
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#define LOG_TAG "APP_CORE_BASE"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <dlog.h>
+
+#ifndef EXPORT_API
+#  define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef _DLOG_H_
+#  define _ERR(fmt, arg...) \
+       do { fprintf(stderr, "appcore: "fmt"\n", ##arg); } while (0)
+
+#  define _INFO(fmt, arg...) \
+       do { fprintf(stdout, fmt"\n", ##arg); } while (0)
+
+#  define _DBG(fmt, arg...) \
+       do { \
+               if (getenv("APPCORE_DEBUG")) { \
+                       fprintf(stdout, fmt"\n", ##arg); \
+               } \
+       } while (0)
+#else
+#  define _ERR(fmt, arg...) \
+       do { \
+               fprintf(stderr, "appcore: "fmt"\n", ##arg); \
+               LOGE(fmt, ##arg); \
+       } while (0)
+#  define _INFO(...) LOGI(__VA_ARGS__)
+#  define _DBG(...) LOGD(__VA_ARGS__)
+#endif
+
+#define _warn_if(expr, fmt, arg...) do { \
+               if (expr) { \
+                       _ERR(fmt, ##arg); \
+               } \
+       } while (0)
+
+#define _ret_if(expr) do { \
+               if (expr) { \
+                       return; \
+               } \
+       } while (0)
+
+#define _retv_if(expr, val) do { \
+               if (expr) { \
+                       return (val); \
+               } \
+       } while (0)
+
+#define _retm_if(expr, fmt, arg...) do { \
+               if (expr) { \
+                       _ERR(fmt, ##arg); \
+                       return; \
+               } \
+       } while (0)
+
+#define _retvm_if(expr, val, fmt, arg...) do { \
+               if (expr) { \
+                       _ERR(fmt, ##arg); \
+                       return (val); \
+               } \
+       } while (0)
+
+
+extern void aul_finalize();
+
diff --git a/src/ui_base/appcore_ui_base.c b/src/ui_base/appcore_ui_base.c
new file mode 100644 (file)
index 0000000..baf80cd
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <linux/limits.h>
+
+#include <Ecore_Wayland.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tizen-extension-client-protocol.h>
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Input_Evas.h>
+#include <Elementary.h>
+#include <glib-object.h>
+#include <malloc.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <stdbool.h>
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+#include <ttrace.h>
+
+#include "appcore_base.h"
+#include "appcore_ui_base.h"
+#include "appcore_ui_base_private.h"
+
+enum app_state {
+       AS_NONE,
+       AS_CREATED,
+       AS_RUNNING,
+       AS_PAUSED,
+       AS_DYING,
+};
+
+typedef struct _appcore_ui_base_context {
+       appcore_ui_base_ops ops;
+       void *data;
+       int argc;
+       char **argv;
+       unsigned int hint;
+       char *below_app;
+       char *appid;
+
+       int state;
+       Ecore_Event_Handler *hshow;
+       Ecore_Event_Handler *hhide;
+       Ecore_Event_Handler *hvchange;
+       Ecore_Event_Handler *hlower;
+} appcore_ui_base_context;
+
+
+static bool b_active = false;
+static bool first_launch = true;
+
+struct win_node {
+       unsigned int win;
+       unsigned int surf;
+       bool bfobscured;
+};
+
+static GSList *g_winnode_list;
+static appcore_ui_base_context __context;
+static struct wl_display *dsp;
+static struct wl_registry *reg;
+static struct tizen_policy *tz_policy;
+static bool bg_state = false;
+
+static void __wl_listener_cb(void *data, struct wl_registry *reg,
+               uint32_t id, const char *interface, uint32_t ver)
+{
+       if (interface && !strcmp(interface, "tizen_policy")) {
+               if (!tz_policy)
+                       tz_policy = wl_registry_bind(reg, id,
+                                       &tizen_policy_interface, 1);
+       }
+}
+
+static void __wl_listener_remove_cb(void *data, struct wl_registry *reg,
+               unsigned int id)
+{
+       /* do nothing */
+}
+
+static const struct wl_registry_listener reg_listener = {
+       __wl_listener_cb,
+       __wl_listener_remove_cb
+};
+
+static Eina_Bool __stub_show_cb(void *data, int type, void *event)
+{
+       if (__context.ops.window.show)
+               __context.ops.window.show(type, event, __context.data);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool __stub_hide_cb(void *data, int type, void *event)
+{
+       if (__context.ops.window.hide)
+               __context.ops.window.hide(type, event, __context.data);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool __stub_visibility_cb(void *data, int type, void *event)
+{
+       if (__context.ops.window.visibility)
+               __context.ops.window.visibility(type, event, __context.data);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool __stub_lower_cb(void *data, int type, void *event)
+{
+       if (__context.ops.window.lower)
+               __context.ops.window.lower(type, event, __context.data);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+static void __prepare_to_suspend(void)
+{
+       int suspend = APPCORE_BASE_SUSPENDED_STATE_WILL_ENTER_SUSPEND;
+
+       if (appcore_base_is_bg_allowed() && !appcore_base_is_suspended()) {
+               appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+               appcore_base_toggle_suspended_state();
+       }
+}
+
+static void __exit_from_suspend(void)
+{
+       int suspend = APPCORE_BASE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+
+       if (appcore_base_is_suspended()) {
+               appcore_base_raise_event((void *)&suspend, APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE);
+               appcore_base_toggle_suspended_state();
+       }
+}
+
+static void __do_pause(void)
+{
+       if (__context.state == AS_RUNNING) {
+               if (__context.ops.pause)
+                       __context.ops.pause(__context.data);
+
+               __context.state = AS_PAUSED;
+               __prepare_to_suspend();
+       }
+       aul_status_update(STATUS_BG);
+}
+
+static void __do_resume(void)
+{
+       if (__context.state == AS_PAUSED || __context.state == AS_CREATED) {
+               __exit_from_suspend();
+               if (__context.ops.resume) {
+                       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", __context.appid);
+                       __context.ops.resume(__context.data);
+                       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", __context.appid);
+                       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:Launching:done]", __context.appid);
+               }
+               if ((__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) &&
+                               __context.below_app) {
+                       aul_app_group_activate_below(__context.below_app);
+                       free(__context.below_app);
+                       __context.below_app = NULL;
+               }
+               __context.state = AS_RUNNING;
+       }
+
+       aul_status_update(STATUS_VISIBLE);
+}
+
+static GSList *__find_win(unsigned int win)
+{
+       GSList *iter;
+       struct win_node *t;
+
+       for (iter = g_winnode_list; iter; iter = g_slist_next(iter)) {
+               t = iter->data;
+               if (t && t->win == win)
+                       return iter;
+       }
+
+       return NULL;
+}
+
+static int __get_main_window(void)
+{
+       struct win_node *entry = NULL;
+
+       if (g_winnode_list != NULL) {
+               entry = g_winnode_list->data;
+               return (unsigned int) entry->win;
+       }
+
+       return 0;
+}
+
+static int __get_main_surface(void)
+{
+       struct win_node *entry = NULL;
+
+       if (g_winnode_list != NULL) {
+               entry = g_winnode_list->data;
+               return (unsigned int) entry->surf;
+       }
+
+       return 0;
+}
+
+static bool __add_win(unsigned int win, unsigned int surf)
+{
+       struct win_node *t;
+       GSList *f;
+
+       _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win);
+
+       f = __find_win(win);
+       if (f) {
+               errno = ENOENT;
+               _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win);
+               return FALSE;
+       }
+
+       t = calloc(1, sizeof(struct win_node));
+       if (t == NULL)
+               return FALSE;
+
+       t->win = win;
+       t->surf = surf;
+       t->bfobscured = FALSE;
+
+       g_winnode_list = g_slist_append(g_winnode_list, t);
+
+       return TRUE;
+}
+
+static bool __delete_win(unsigned int win)
+{
+       GSList *f;
+
+       f = __find_win(win);
+       if (!f) {
+               errno = ENOENT;
+               _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n",
+                               win);
+               return FALSE;
+       }
+
+       free(f->data);
+       g_winnode_list = g_slist_delete_link(g_winnode_list, f);
+
+       return TRUE;
+}
+
+static bool __update_win(unsigned int win, unsigned int surf, bool bfobscured)
+{
+       GSList *f;
+       struct win_node *t;
+
+       _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win,
+            bfobscured);
+
+       f = __find_win(win);
+       if (!f) {
+               errno = ENOENT;
+               _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win);
+               return FALSE;
+       }
+
+       t = (struct win_node *)f->data;
+       t->win = win;
+       if (surf != 0)
+               t->surf = surf;
+       t->bfobscured = bfobscured;
+
+       return TRUE;
+}
+
+static void __raise_win(void)
+{
+       Ecore_Wl_Window *win;
+       unsigned int win_id;
+
+       if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
+               return;
+
+       win_id = __get_main_window();
+
+       _DBG("Raise window: %d", win_id);
+       win = ecore_wl_window_find(win_id);
+       ecore_wl_window_activate(win);
+}
+
+static void __pause_win(void)
+{
+       Ecore_Wl_Window *win;
+       GSList *wlist = g_winnode_list;
+       struct win_node *entry = NULL;
+
+       if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL))
+               return;
+
+       _DBG("Pause window");
+
+       while (wlist) {
+               entry = wlist->data;
+
+               _DBG("Pause window: %d", entry->win);
+               win = ecore_wl_window_find(entry->win);
+               ecore_wl_window_iconified_set(win, EINA_TRUE);
+
+               wlist = wlist->next;
+       }
+}
+
+static int __init_wl(void)
+{
+       _DBG("initialize wayland");
+       dsp = wl_display_connect(NULL);
+       if (dsp == NULL) {
+               _ERR("Failed to connect wl display");
+               return -1;
+       }
+
+       reg = wl_display_get_registry(dsp);
+       if (reg == NULL) {
+               _ERR("Failed to get registry");
+               wl_display_disconnect(dsp);
+               return -1;
+       }
+
+       wl_registry_add_listener(reg, &reg_listener, NULL);
+       wl_display_roundtrip(dsp);
+
+       if (!tz_policy) {
+               _ERR("Failed to get tizen policy interface");
+               wl_registry_destroy(reg);
+               wl_display_disconnect(dsp);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void __finish_wl(void)
+{
+       if (tz_policy) {
+               tizen_policy_destroy(tz_policy);
+               tz_policy = NULL;
+       }
+
+       if (reg) {
+               wl_registry_destroy(reg);
+               reg = NULL;
+       }
+
+       if (dsp) {
+               wl_display_disconnect(dsp);
+               dsp = NULL;
+       }
+}
+
+static void __set_bg_state(void)
+{
+       if (__init_wl() < 0)
+               return;
+
+       tizen_policy_set_background_state(tz_policy, getpid());
+       wl_display_roundtrip(dsp);
+       bg_state = true;
+       _DBG("bg state: %d", bg_state);
+}
+
+static void __unset_bg_state(void)
+{
+       if (!tz_policy)
+               return;
+
+       tizen_policy_unset_background_state(tz_policy, getpid());
+       wl_display_roundtrip(dsp);
+       bg_state = false;
+       _DBG("bg state: %d", bg_state);
+       __finish_wl();
+}
+
+static void __do_start(bundle *b)
+{
+       const char *bg_launch;
+       const char *below_app;
+
+       if (__context.hint & APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL) {
+               if (__context.below_app) {
+                       free(__context.below_app);
+                       __context.below_app = NULL;
+               }
+
+               below_app = bundle_get_val(b, AUL_SVC_K_RELOCATE_BELOW);
+               if (below_app)
+                       __context.below_app = strdup(below_app);
+       }
+
+       if (first_launch) {
+               first_launch = FALSE;
+               return;
+       }
+
+       if ((__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) &&
+               bg_state) {
+               bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
+               if (!bg_launch || strcmp(bg_launch, "enable"))
+                       __unset_bg_state();
+       }
+
+       __raise_win();
+}
+
+EXPORT_API int appcore_ui_base_on_receive(aul_type type, bundle *b)
+{
+       if (__context.state == AS_DYING) {
+               _ERR("Skip the event in dying state");
+               return 0;
+       }
+
+       if (type == AUL_TERMINATE_BGAPP && __context.state != AS_PAUSED)
+               return 0;
+
+       if (type == AUL_START)
+               __exit_from_suspend();
+
+       appcore_base_on_receive(type, b);
+
+       switch (type) {
+       case AUL_START:
+               __do_start(b);
+               break;
+       case AUL_RESUME:
+               __do_resume();
+               break;
+       case AUL_TERMINATE:
+               break;
+       case AUL_TERMINATE_BGAPP:
+               _DBG("[APP %d] is paused. TERMINATE", getpid());
+               __context.state = AS_DYING;
+               aul_status_update(STATUS_DYING);
+               if (__context.ops.base.exit)
+                       __context.ops.base.exit(__context.data);
+               break;
+       case AUL_PAUSE:
+               __pause_win();
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+EXPORT_API int appcore_ui_base_on_create(void)
+{
+       appcore_base_on_create();
+
+       __context.hshow = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __stub_show_cb, NULL);
+       __context.hhide = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __stub_hide_cb, NULL);
+       __context.hvchange = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE,
+                               __stub_visibility_cb, NULL);
+       __context.hlower = ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, __stub_lower_cb, NULL);
+       __context.state = AS_CREATED;
+       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]", __context.appid);
+
+       return 0;
+}
+
+EXPORT_API int appcore_ui_base_on_terminate(void)
+{
+       if (__context.state == AS_RUNNING) {
+               if (__context.ops.pause)
+                       __context.ops.pause(__context.data);
+       }
+
+       __context.state = AS_DYING;
+       if (__context.hshow)
+               ecore_event_handler_del(__context.hshow);
+       if (__context.hhide)
+               ecore_event_handler_del(__context.hhide);
+       if (__context.hvchange)
+               ecore_event_handler_del(__context.hvchange);
+       if (__context.hlower)
+               ecore_event_handler_del(__context.hlower);
+
+       elm_shutdown();
+
+       /* Check loader case */
+       if (getenv("AUL_LOADER_INIT")) {
+               unsetenv("AUL_LOADER_INIT");
+               elm_shutdown();
+       }
+
+       appcore_base_on_terminate();
+
+       return 0;
+}
+
+EXPORT_API int appcore_ui_base_on_pause(void)
+{
+       return 0;
+}
+
+EXPORT_API int appcore_ui_base_on_resume(void)
+{
+       return 0;
+}
+
+EXPORT_API int appcore_ui_base_on_control(bundle *b)
+{
+       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", __context.appid);
+       appcore_base_on_control(b);
+       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", __context.appid);
+
+       return 0;
+}
+
+static void __group_attach()
+{
+       static bool attached = false;
+
+       if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
+               return;
+
+       _DBG("__group_attach");
+       if (attached)
+               return;
+
+       int wid = __get_main_surface();
+       if (wid == 0) {
+               _ERR("window wasn't ready");
+               return;
+       }
+
+       aul_app_group_set_window(wid);
+       attached = true;
+}
+
+static void __group_lower()
+{
+       int exit = 0;
+
+       if (!(__context.hint & APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL))
+               return;
+
+       _DBG("__group_lower");
+       aul_app_group_lower(&exit);
+       if (exit) {
+               _DBG("__group_lower : sub-app!");
+               if (__context.ops.base.exit)
+                       __context.ops.base.exit(__context.data);
+       }
+}
+
+EXPORT_API void appcore_ui_base_window_on_show(int type, void *event)
+{
+       Ecore_Wl_Event_Window_Show *ev;
+
+       ev = event;
+       if (ev->parent_win != 0) {
+               /* This is child window. Skip!!! */
+               return;
+       }
+
+       _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x, %d\n", ev->win, ev->data[0]);
+
+       if (!__find_win((unsigned int)ev->win))
+               __add_win((unsigned int)ev->win, (unsigned int)ev->data[0]);
+       else
+               __update_win((unsigned int)ev->win, (unsigned int)ev->data[0], FALSE);
+       __group_attach();
+}
+
+static bool __check_visible(void)
+{
+       GSList *iter = NULL;
+       struct win_node *entry = NULL;
+
+       _DBG("[EVENT_TEST][EVENT] __check_visible\n");
+
+       for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
+               entry = iter->data;
+               _DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured);
+               if (entry->bfobscured == FALSE)
+                       return true;
+       }
+
+       return false;
+}
+
+EXPORT_API void appcore_ui_base_window_on_hide(int type, void *event)
+{
+       Ecore_Wl_Event_Window_Hide *ev;
+       int bvisibility;
+
+       ev = event;
+       _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win);
+
+       if (__find_win((unsigned int)ev->win)) {
+               __delete_win((unsigned int)ev->win);
+               bvisibility = __check_visible();
+               if (!bvisibility && b_active == TRUE) {
+                       _DBG(" Go to Pasue state \n");
+                       b_active = FALSE;
+                       __do_pause();
+               }
+       }
+}
+
+EXPORT_API void appcore_ui_base_window_on_lower(int type, void *event)
+{
+       Ecore_Wl_Event_Window_Lower *ev;
+
+       ev = event;
+       if (!ev)
+               return;
+       _DBG("ECORE_WL_EVENT_WINDOW_LOWER window id:%u\n", ev->win);
+       __group_lower();
+}
+
+EXPORT_API void appcore_ui_base_window_on_visibility(int type, void *event)
+{
+       Ecore_Wl_Event_Window_Visibility_Change *ev;
+       int bvisibility;
+
+       ev = event;
+       __update_win((unsigned int)ev->win, 0, ev->fully_obscured);
+       bvisibility = __check_visible();
+
+       _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
+
+       if (bvisibility && b_active == FALSE) {
+               _DBG(" Go to Resume state\n");
+               b_active = TRUE;
+               __do_resume();
+       } else if (!bvisibility && b_active == TRUE) {
+               _DBG(" Go to Pasue state \n");
+               b_active = FALSE;
+               __do_pause();
+       } else {
+               _DBG(" No change state \n");
+       }
+
+}
+
+EXPORT_API int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
+               void *data, unsigned int hint)
+{
+       char *hwacc;
+       const char *bg_launch;
+       bundle *b;
+       char appid[PATH_MAX] = {0, };
+
+       aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+       __context.ops = ops;
+       __context.data = data;
+       __context.argc = argc;
+       __context.argv = argv;
+       __context.hint = hint;
+       __context.state = AS_NONE;
+       __context.appid = strdup(appid);
+
+       LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
+       elm_init(argc, argv);
+
+       if (__context.hint & APPCORE_UI_BASE_HINT_HW_ACC_CONTROL) {
+               hwacc = getenv("HWACC");
+
+               if (hwacc == NULL) {
+                       _DBG("elm_config_accel_preference_set is not called");
+               } else if (strcmp(hwacc, "USE") == 0) {
+                       elm_config_accel_preference_set("hw");
+                       _DBG("elm_config_accel_preference_set : hw");
+               } else if (strcmp(hwacc, "NOT_USE") == 0) {
+                       elm_config_accel_preference_set("none");
+                       _DBG("elm_config_accel_preference_set : none");
+               } else {
+                       _DBG("elm_config_accel_preference_set is not called");
+               }
+       }
+
+       if (__context.hint & APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL) {
+               b = bundle_import_from_argv(argc, argv);
+               if (b) {
+                       bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
+                       if (bg_launch && strcmp(bg_launch, "enable") == 0)
+                               __set_bg_state();
+
+                       bundle_free(b);
+               }
+       }
+
+       return appcore_base_init(ops.base, argc, argv, data);
+}
+
+EXPORT_API void appcore_ui_base_fini(void)
+{
+       appcore_base_fini();
+       free(__context.appid);
+       __context.appid = NULL;
+}
+
+EXPORT_API void appcore_ui_base_pause(void)
+{
+       __do_pause();
+}
+
+EXPORT_API void appcore_ui_base_resume(void)
+{
+       __do_resume();
+}
+
+EXPORT_API bool appcore_ui_base_is_resumed(void)
+{
+       return __context.state == AS_RUNNING;
+}
+
+EXPORT_API void appcore_ui_base_exit(void)
+{
+       if (__context.ops.base.exit)
+               __context.ops.base.exit(__context.data);
+}
+
+static int __on_receive(aul_type type, bundle *b, void *data)
+{
+       return appcore_ui_base_on_receive(type, b);
+}
+
+static int __on_create(void *data)
+{
+       return appcore_ui_base_on_create();
+}
+
+static int __on_terminate(void *data)
+{
+       return appcore_ui_base_on_terminate();
+}
+
+static int __on_pause(void *data)
+{
+       return appcore_ui_base_on_pause();
+}
+
+static int __on_resume(void *data)
+{
+       return appcore_ui_base_on_resume();
+}
+
+static void __window_on_show(int type, void *event, void *data)
+{
+       appcore_ui_base_window_on_show(type, event);
+}
+
+static void __window_on_hide(int type, void *event, void *data)
+{
+       appcore_ui_base_window_on_hide(type, event);
+}
+
+static void __window_on_lower(int type, void *event, void *data)
+{
+       appcore_ui_base_window_on_lower(type, event);
+}
+
+static void __window_on_visibility(int type, void *event, void *data)
+{
+       appcore_ui_base_window_on_visibility(type, event);
+}
+
+static void __run(void *data)
+{
+       elm_run();
+}
+
+static void __exit(void *data)
+{
+       elm_exit();
+}
+
+EXPORT_API appcore_ui_base_ops appcore_ui_base_get_default_ops(void)
+{
+       appcore_ui_base_ops ops;
+
+       ops.base = appcore_base_get_default_ops();
+
+       /* override methods */
+       ops.base.create = __on_create;
+       ops.base.terminate = __on_terminate;
+       ops.base.receive = __on_receive;
+       ops.base.run = __run;
+       ops.base.exit = __exit;
+
+       ops.pause = __on_pause;
+       ops.resume = __on_resume;
+       ops.window.show = __window_on_show;
+       ops.window.hide = __window_on_hide;
+       ops.window.lower = __window_on_lower;
+       ops.window.visibility = __window_on_visibility;
+
+       return ops;
+}
+
+
diff --git a/src/ui_base/appcore_ui_base_private.h b/src/ui_base/appcore_ui_base_private.h
new file mode 100644 (file)
index 0000000..cfa0c28
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#define LOG_TAG "APP_CORE_UI_BASE"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <dlog.h>
+
+#ifndef EXPORT_API
+#  define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef _DLOG_H_
+#  define _ERR(fmt, arg...) \
+       do { fprintf(stderr, "appcore: "fmt"\n", ##arg); } while (0)
+
+#  define _INFO(fmt, arg...) \
+       do { fprintf(stdout, fmt"\n", ##arg); } while (0)
+
+#  define _DBG(fmt, arg...) \
+       do { \
+               if (getenv("APPCORE_DEBUG")) { \
+                       fprintf(stdout, fmt"\n", ##arg); \
+               } \
+       } while (0)
+#else
+#  define _ERR(fmt, arg...) \
+       do { \
+               fprintf(stderr, "appcore: "fmt"\n", ##arg); \
+               LOGE(fmt, ##arg); \
+       } while (0)
+#  define _INFO(...) LOGI(__VA_ARGS__)
+#  define _DBG(...) LOGD(__VA_ARGS__)
+#endif
+
+
+