Add appcore event
[platform/core/appfw/app-core.git] / src / appcore-efl.c
index b9454f0..1378463 100644 (file)
@@ -26,6 +26,9 @@
 
 #if defined(WAYLAND)
 #include <Ecore_Wayland.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tizen-extension-client-protocol.h>
 #elif defined(X11)
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
@@ -42,6 +45,8 @@
 #include <gio/gio.h>
 #include <stdbool.h>
 #include <aul.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
 #include <ttrace.h>
 
 #include "appcore-internal.h"
@@ -65,8 +70,8 @@ struct ui_priv {
 
        Ecore_Timer *mftimer; /* Ecore Timer for memory flushing */
 
-#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
        struct appcore *app_core;
+#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
        void (*prepare_to_suspend) (void *data);
        void (*exit_from_suspend) (void *data);
 #endif
@@ -80,6 +85,7 @@ struct ui_priv {
        void *rot_cb_data;
        enum appcore_rm rot_mode;
        bundle *pending_data;
+       char *below_app;
 };
 
 static struct ui_priv priv;
@@ -93,6 +99,7 @@ static const char *_ae_name[AE_MAX] = {
        [AE_RESET] = "RESET",
        [AE_LOWMEM_POST] = "LOWMEM_POST",
        [AE_MEM_FLUSH] = "MEM_FLUSH",
+       [AE_UPDATE_REQUESTED] = "UPDATE_REQUESTED",
 };
 
 static const char *_as_name[] = {
@@ -120,6 +127,102 @@ static struct ui_wm_rotate wm_rotate;
 static Eina_Bool __visibility_cb(void *data, int type, void *event);
 static GSList *g_winnode_list;
 
+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 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();
+}
+
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
 static void __appcore_efl_prepare_to_suspend(void *data)
 {
@@ -154,6 +257,20 @@ static void __appcore_efl_exit_from_suspend(void *data)
 }
 #endif
 
+static void __appcore_efl_update_requested(void *data)
+{
+       struct ui_priv *ui = (struct ui_priv *)data;
+       struct sys_op *op;
+       int dummy = 0;
+
+       if (ui->app_core) {
+               op = &ui->app_core->sops[SE_UPDATE_REQUESTED];
+               if (op && op->func)
+                       op->func((void *)&dummy, op->data);
+       }
+       _DBG("[__UPDATE_REQUESTED__]");
+}
+
 #if defined(MEMORY_FLUSH_ACTIVATE)
 static Eina_Bool __appcore_memory_flush_cb(void *data)
 {
@@ -249,6 +366,8 @@ static void __do_app(enum app_event event, void *data, bundle * b)
 {
        int r = -1;
        struct ui_priv *ui = data;
+       const char *below_app;
+       const char *bg_launch;
 
        _DBG("[APP %d] Event: %d", _pid, event);
        _ret_if(ui == NULL || event >= AE_MAX);
@@ -306,6 +425,14 @@ static void __do_app(enum app_event event, void *data, bundle * b)
                ui->pending_data = bundle_dup(b);
                LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]", ui->name);
 
+               if (ui->below_app) {
+                       free(ui->below_app);
+                       ui->below_app = NULL;
+               }
+
+               below_app = bundle_get_val(b, AUL_SVC_K_RELOCATE_BELOW);
+               if (below_app)
+                       ui->below_app = strdup(below_app);
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
                if (ui->exit_from_suspend) {
                        _DBG("[__SUSPEND__] reset case");
@@ -322,9 +449,18 @@ static void __do_app(enum app_event event, void *data, bundle * b)
                LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", ui->name);
 
                if (first_launch) {
+#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
+                       if (ui->app_core->allowed_bg)
+                               __appcore_timer_add(ui);
+#endif
                        first_launch = FALSE;
                } else {
                        _INFO("[APP %d] App already running, raise the window", _pid);
+                       if (bg_state) {
+                               bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
+                               if (!bg_launch || strcmp(bg_launch, "enable"))
+                                       __unset_bg_state();
+                       }
 #ifdef X11
                        x_raise_win(getpid());
 #else
@@ -366,6 +502,8 @@ static void __do_app(enum app_event event, void *data, bundle * b)
                        _DBG("[__SUSPEND__] resume case");
                        ui->exit_from_suspend(ui);
                }
+               if (ui->app_core->allowed_bg)
+                       __appcore_timer_del(ui);
 #endif
 
                if (ui->state == AS_PAUSED || ui->state == AS_CREATED) {
@@ -383,6 +521,12 @@ static void __do_app(enum app_event event, void *data, bundle * b)
                                traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
                        }
                        ui->state = AS_RUNNING;
+
+                       if (ui->below_app) {
+                               aul_app_group_activate_below(ui->below_app);
+                               free(ui->below_app);
+                               ui->below_app = NULL;
+                       }
                }
                /*TODO : rotation start*/
                /* r = appcore_resume_rotation_cb(); */
@@ -404,6 +548,9 @@ static void __do_app(enum app_event event, void *data, bundle * b)
                        _DBG("[APP %d] is another state", _pid);
                }
                break;
+       case AE_UPDATE_REQUESTED:
+               __appcore_efl_update_requested(ui);
+               break;
        default:
                /* do nothing */
                break;
@@ -835,6 +982,11 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv)
 {
        int r;
        char *hwacc = NULL;
+#if _APPFW_FEATURE_BACKGROUND_MANAGEMENT
+       struct appcore *ac = NULL;
+#endif
+       bundle *b;
+       const char *bg_launch;
 
        if (argc == NULL || argv == NULL) {
                _ERR("argc/argv is NULL");
@@ -866,9 +1018,18 @@ static int __before_loop(struct ui_priv *ui, int *argc, char ***argv)
 #if _APPFW_FEATURE_BACKGROUND_MANAGEMENT
        appcore_get_app_core(&ac);
        ui->app_core = ac;
-       SECURE_LOGD("[__SUSPEND__] appcore initialized, appcore addr: 0x%x", ac);
+       SECURE_LOGD("[__SUSPEND__] appcore initialized, appcore addr: #%x", ac);
 #endif
 
+       b = bundle_import_from_argv(*argc, *argv);
+       if (b) {
+               bg_launch = bundle_get_val(b, AUL_SVC_K_BG_LAUNCH);
+               if (bg_launch && strcmp(bg_launch, "enable") == 0)
+                       __set_bg_state();
+
+               bundle_free(b);
+       }
+
        LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:appcore_init:done]", ui->name);
        if (ui->ops && ui->ops->create) {
                traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
@@ -1130,7 +1291,7 @@ EXPORT_API int appcore_set_preinit_window_name(const char *win_name)
                return ret;
        }
 
-       preinit_window = aul_get_preinit_window(win_name);
+       preinit_window = elm_win_precreated_object_get();
        if (!preinit_window) {
                _ERR("Failed to get preinit window");
                return ret;