Merge branch 'tizen_3.0' into tizen
[platform/core/appfw/app-core.git] / src / appcore.c
index 82473d5..20fb3c4 100644 (file)
@@ -1,9 +1,5 @@
 /*
- *  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>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +12,6 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
 
 #include <dlfcn.h>
 #include <vconf.h>
 #include <aul.h>
-#include <tzplatform_config.h>
+#include <bundle_internal.h>
 #include "appcore-internal.h"
 
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
 
 #define RESOURCED_FREEZER_PATH "/Org/Tizen/Resourced/Freezer"
 #define RESOURCED_FREEZER_INTERFACE "org.tizen.resourced.freezer"
 #define RESOURCED_FREEZER_SIGNAL "FreezerState"
+
+int __appcore_init_suspend_dbus_handler(void *data);
+void __appcore_fini_suspend_dbus_handler(void);
 #endif
 
 #define SQLITE_FLUSH_MAX               (1024*1024)
 
-#define PKGNAME_MAX 256
-#define PATH_APP_ROOT tzplatform_getenv(TZ_USER_APP)
-#define PATH_RO_APP_ROOT tzplatform_getenv(TZ_SYS_RO_APP)
-#define PATH_RES "/res"
-#define PATH_LOCALE "/locale"
+#define PATH_LOCALE "locale"
 
 static struct appcore core;
 static pid_t _pid;
@@ -65,6 +58,7 @@ static enum appcore_event to_ae[SE_MAX] = {
        APPCORE_EVENT_LANG_CHANGE,      /* SE_LANGCGH */
        APPCORE_EVENT_REGION_CHANGE,
        APPCORE_EVENT_SUSPENDED_STATE_CHANGE,
+       APPCORE_EVENT_UPDATE_REQUESTED,
 };
 
 static int appcore_event_initialized[SE_MAX] = {0,};
@@ -146,31 +140,22 @@ static struct evt_ops evtops[] = {
 };
 
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
-static DBusConnection *bus = NULL;
-static int __suspend_dbus_handler_initialized = 0;
+static GDBusConnection *bus;
+static guint __suspend_dbus_handler_initialized;
 #endif
 
-static int __get_dir_name(char *dirname)
+static int __get_locale_resource_dir(char *locale_dir, int size)
 {
-       char pkg_name[PKGNAME_MAX];
-       int r;
-       int pid;
-
-       pid = getpid();
-       if (pid < 0)
-               return -1;
+       const char *res_path;
 
-       if (aul_app_get_pkgname_bypid(pid, pkg_name, PKGNAME_MAX) != AUL_R_OK)
+       res_path = aul_get_app_resource_path();
+       if (res_path == NULL) {
+               _ERR("Failed to get resource path");
                return -1;
+       }
 
-       r = snprintf(dirname, PATH_MAX, "%s/%s" PATH_RES PATH_LOCALE,
-                       PATH_APP_ROOT, pkg_name);
-       if (r < 0)
-               return -1;
-       if (access(dirname, R_OK) == 0) return 0;
-       r = snprintf(dirname, PATH_MAX, "%s/%s" PATH_RES PATH_LOCALE,
-                       PATH_RO_APP_ROOT, pkg_name);
-       if (r < 0)
+       snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path);
+       if (access(locale_dir, R_OK) != 0)
                return -1;
 
        return 0;
@@ -244,6 +229,17 @@ static int __app_pause(void *data)
        return 0;
 }
 
+static int __app_update_requested(void *data)
+{
+       struct appcore *ac = data;
+
+       _retv_if(ac == NULL || ac->ops == NULL, -1);
+       _retv_if(ac->ops->cb_app == NULL, 0);
+       ac->ops->cb_app(AE_UPDATE_REQUESTED, ac->ops->data, NULL);
+
+       return 0;
+}
+
 static int __sys_do_default(struct appcore *ac, enum sys_event event)
 {
        int r;
@@ -509,17 +505,32 @@ static void __remove_suspend_timer(struct appcore *ac)
 static int __aul_handler(aul_type type, bundle *b, void *data)
 {
        int ret;
+       const char **tep_path = NULL;
+       int len = 0;
+       int i;
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
        const char *bg = NULL;
        struct appcore *ac = data;
+       int suspend = APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
 #endif
 
        switch (type) {
        case AUL_START:
                _DBG("[APP %d]     AUL event: AUL_START", _pid);
+               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);
+                               }
+                       }
+               }
+
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
                bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
-               if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWGED_BG")) == 0) {
+               if (bg && strncmp(bg, "ALLOWED_BG", strlen("ALLOWED_BG")) == 0) {
                        _DBG("[__SUSPEND__] allowed background");
                        ac->allowed_bg = true;
                        __remove_suspend_timer(data);
@@ -573,20 +584,32 @@ static int __aul_handler(aul_type type, bundle *b, void *data)
        case AUL_WAKE:
                _DBG("[APP %d]     AUL event: AUL_WAKE", _pid);
                if (!ac->allowed_bg && ac->suspended_state) {
-                       int suspend = APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
                        __remove_suspend_timer(data);
                        __sys_do(ac, &suspend, SE_SUSPENDED_STATE);
                        ac->suspended_state = false;
                }
+
+               if (b) {
+                       bg = bundle_get_val(b, AUL_K_ALLOWED_BG);
+                       if (bg && strcmp(bg, "ALLOWED_BG") == 0) {
+                               _DBG("[__SUSPEND__] allowed background");
+                               ac->allowed_bg = true;
+                       }
+               }
                break;
        case AUL_SUSPEND:
                _DBG("[APP %d]     AUL event: AUL_SUSPEND", _pid);
-               if (!ac->allowed_bg && !ac->suspended_state) {
+               ac->allowed_bg = false;
+               if (!ac->suspended_state) {
                        __remove_suspend_timer(data);
                        __flush_memory((gpointer)ac);
                }
                break;
 #endif
+       case AUL_UPDATE_REQUESTED:
+               _DBG("[APP %d]     AUL event: AUL_UPDATE_REQUESTED", _pid);
+               __app_update_requested(data);
+               break;
        default:
                _DBG("[APP %d]     AUL event: %d", _pid, type);
                /* do nothing */
@@ -602,7 +625,7 @@ static void __clear(struct appcore *ac)
        memset(ac, 0, sizeof(struct appcore));
 }
 
-void appcore_get_app_core(struct appcore **ac)
+EXPORT_API void appcore_get_app_core(struct appcore **ac)
 {
        *ac = &core;
 }
@@ -657,11 +680,25 @@ EXPORT_API int appcore_set_event_callback(enum appcore_event event,
        return 0;
 }
 
+#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
+static gboolean __init_suspend(gpointer data)
+{
+       int r;
+
+       r = __appcore_init_suspend_dbus_handler(&core);
+       if (r == -1) {
+               _ERR("Initailzing suspended state handler failed");
+       }
+
+       return FALSE;
+}
+#endif
+
 EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops,
                            int argc, char **argv)
 {
        int r;
-       char dirname[PATH_MAX];
+       char locale_dir[PATH_MAX];
 
        if (core.state != 0) {
                _ERR("Already in use");
@@ -675,18 +712,10 @@ EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops,
                return -1;
        }
 
-       r = __get_dir_name(dirname);
-       r = set_i18n(name, dirname);
+       r = __get_locale_resource_dir(locale_dir, sizeof(locale_dir));
+       r = set_i18n(name, locale_dir);
        _retv_if(r == -1, -1);
 
-#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
-       r = _appcore_init_suspend_dbus_handler(&core);
-       if (r == -1) {
-               _ERR("Initailzing suspended state handler failed");
-               goto err;
-       }
-#endif
-
        r = aul_launch_init(__aul_handler, &core);
        if (r < 0) {
                _ERR("Aul init failed: %d", r);
@@ -707,6 +736,10 @@ EXPORT_API int appcore_init(const char *name, const struct ui_ops *ops,
 
        _pid = getpid();
 
+#ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
+       g_idle_add(__init_suspend, NULL);
+#endif
+
        return 0;
  err:
        __del_vconf_list();
@@ -721,6 +754,7 @@ EXPORT_API void appcore_exit(void)
                __clear(&core);
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
                __remove_suspend_timer(&core);
+               __appcore_fini_suspend_dbus_handler();
 #endif
        }
        aul_finalize();
@@ -758,90 +792,83 @@ EXPORT_API int appcore_flush_memory(void)
 }
 
 #ifdef _APPFW_FEATURE_BACKGROUND_MANAGEMENT
-static DBusHandlerResult __suspend_dbus_signal_filter(DBusConnection *conn,
-                                       DBusMessage *message, void *user_data)
-{
-       const char *sender;
-       const char *interface;
-       int pid;
-       int state;
-       int suspend;
-
-       DBusError error;
-       dbus_error_init(&error);
-
-       sender = dbus_message_get_sender(message);
-       if (sender == NULL)
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-       interface = dbus_message_get_interface(message);
-       if (interface == NULL) {
-               _ERR("reject by security issue - no interface\n");
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-       }
-
-       if (dbus_message_is_signal(message, interface, RESOURCED_FREEZER_SIGNAL)) {
-               if (dbus_message_get_args(message, &error, DBUS_TYPE_INT32, &state,
-                                       DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID) == FALSE) {
-                       _ERR("Failed to get data: %s", error.message);
-                       dbus_error_free(&error);
-                       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-               }
-
-               if (pid == getpid() && state == 0) { /* thawed */
-                       suspend = APPCORE_SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
-                       SECURE_LOGD("[__SUSPEND__] state: %d (0: thawed, 1: frozen), pid: %d", state, pid);
-
-                       struct appcore *ac = (struct appcore *)user_data;
-                       if (!ac->allowed_bg && ac->suspended_state) {
+static void __suspend_dbus_signal_handler(GDBusConnection *connection,
+                                       const gchar *sender_name,
+                                       const gchar *object_path,
+                                       const gchar *interface_name,
+                                       const gchar *signal_name,
+                                       GVariant *parameters,
+                                       gpointer user_data)
+{
+       struct appcore *ac = (struct appcore *)user_data;
+       gint suspend = APPCORE_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) { /* thawed */
+                       if (ac && !ac->allowed_bg && ac->suspended_state) {
                                __remove_suspend_timer(ac);
-                               __sys_do(user_data, &suspend, SE_SUSPENDED_STATE);
+                               __sys_do(ac, &suspend, SE_SUSPENDED_STATE);
                                ac->suspended_state = false;
                                __add_suspend_timer(ac);
                        }
                }
        }
-
-       return DBUS_HANDLER_RESULT_HANDLED;
 }
 
-int _appcore_init_suspend_dbus_handler(void *data)
+int __appcore_init_suspend_dbus_handler(void *data)
 {
-       DBusError error;
-       char rule[MAX_LOCAL_BUFSZ];
+       GError *err = NULL;
 
        if (__suspend_dbus_handler_initialized)
                return 0;
 
-       dbus_error_init(&error);
        if (!bus) {
-               bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+               bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
                if (!bus) {
-                       _ERR("Failed to connect to the D-BUS daemon: %s", error.message);
-                       dbus_error_free(&error);
+                       _ERR("Failed to connect to the D-BUS daemon: %s",
+                                               err->message);
+                       g_error_free(err);
                        return -1;
                }
        }
-       dbus_connection_setup_with_g_main(bus, NULL);
-
-       snprintf(rule, MAX_LOCAL_BUFSZ,
-                       "path='%s',type='signal',interface='%s'", RESOURCED_FREEZER_PATH, RESOURCED_FREEZER_INTERFACE);
-       /* listening to messages */
-       dbus_bus_add_match(bus, rule, &error);
-       if (dbus_error_is_set(&error)) {
-               _ERR("Fail to rule set: %s", error.message);
-               dbus_error_free(&error);
-               return -1;
-       }
 
-       if (dbus_connection_add_filter(bus, __suspend_dbus_signal_filter, data, NULL) == FALSE) {
-               _ERR("add filter fail");
+       __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,
+                                               __suspend_dbus_signal_handler,
+                                               data,
+                                               NULL);
+       if (__suspend_dbus_handler_initialized == 0) {
+               _ERR("g_dbus_connection_signal_subscribe() is failed.");
                return -1;
        }
 
-       __suspend_dbus_handler_initialized = 1;
        _DBG("[__SUSPEND__] suspend signal initialized");
 
        return 0;
 }
+
+void __appcore_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;
+}
 #endif
+