Fix resource leak
[platform/core/appfw/pkgmgr-server.git] / src / pkgmgr-server.c
index d5b59ee..ea9a444 100644 (file)
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/signalfd.h>
 #include <signal.h>
 #include <grp.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <fnmatch.h>
 
 #include <glib.h>
 #include <gio/gio.h>
 #include <pkgmgr-info.h>
 #include <pkgmgr/pkgmgr_parser_db.h>
 #include <tzplatform_config.h>
-#include <drm-tizen-apps.h>
-#ifdef TIZEN_FEATURE_CSR
-#include <csr-content-screening.h>
-#endif
 
 #include "pkgmgr_installer.h"
 #include "pkgmgr-server.h"
 #include "queue.h"
 #include "package-manager.h"
 
+#define USRLIB "/usr/lib"
+
+#define PATH_LIBDRM_SVC_CORE \
+               "/usr/lib/libdrm-service-core-tizen.so.0"
+#define PATH_LIBCSR_CLIENT \
+               "/usr/lib/libcsr-client.so.2"
 #define OWNER_ROOT 0
 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
 #define APPFW_UID 301
@@ -59,6 +65,7 @@
 #define EXT_STORAGE_APPDATA_GROUP 10002
 #define MEDIA_STORAGE_GROUP 10502
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+#define MAX_LONGLONG_LENGTH 32
 
 typedef struct  {
        char **env;
@@ -79,24 +86,31 @@ is dynamically determined.
 */
 static char backend_busy = 0;
 extern int num_of_backends;
+bool is_drm_busy = false;
+static bool is_lock_set = false;
 
-struct signal_info_t {
-       pid_t pid;
-       int status;
-};
-
-static int pipe_sig[2];
-static GIOChannel *pipe_io;
-static guint pipe_wid;
+static GIOChannel *sio;
+static guint swid;
 static GHashTable *backend_info_table;
-static GMainLoop *mainloop = NULL;
+static GMainLoop *mainloop;
+static GDBusConnection *system_conn;
+
+static int (*_drm_tizen_register_license)
+               (const char *pRespBuf, unsigned int respBufLen);
+static int (*_drm_tizen_decrypt_package)(const char *pTADCFilepath,
+               int tadcFileLen, const char *pDecryptedFile,
+               int decryptedFileLen);
+static int (*_drm_tizen_generate_license_request)(const char *pRespBuf,
+               unsigned int respBufLen, char *pReqBuf,
+               unsigned int *pReqBufLen, char *pLicenseUrl,
+               unsigned int *pLicenseUrlLen);
+static void *drm_lib_handle;
 
 static int __check_backend_status_for_exit(void);
 static int __check_queue_status_for_exit(void);
 static int __is_backend_busy(int position);
 static void __set_backend_busy(int position);
 static void __set_backend_free(int position);
-static void sighandler(int signo);
 
 gboolean exit_server(void *data);
 
@@ -116,42 +130,226 @@ static void __set_backend_free(int position)
        backend_busy = backend_busy & ~(1 << position);
 }
 
-static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond,
+static GDBusConnection *_get_system_conn(void)
+{
+       GError *err = NULL;
+
+       if (system_conn)
+               return system_conn;
+
+       system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (system_conn == NULL) {
+               ERR("Failed to get system bus: %s", err->message);
+               g_error_free(err);
+               return NULL;
+       }
+
+       return system_conn;
+}
+
+#define DEVICED_DBUS_PATH "org.tizen.system.deviced"
+#define DEVICED_DBUS_OBJECT_PATH "/Org/Tizen/System/DeviceD/Display"
+#define DEVICED_DBUS_INTERFACE_NAME "org.tizen.system.deviced.display"
+
+static void __set_power_lock(void)
+{
+       GDBusConnection *conn;
+       GDBusMessage *msg;
+       GError *err = NULL;
+       int ret = 0;
+
+       if (is_lock_set)
+               return;
+
+       conn = _get_system_conn();
+       if (conn == NULL)
+               return;
+
+       msg = g_dbus_message_new_method_call(DEVICED_DBUS_PATH,
+                       DEVICED_DBUS_OBJECT_PATH,
+                       DEVICED_DBUS_INTERFACE_NAME,
+                       "lockstate");
+       if (msg == NULL) {
+               ERR("g_dbus_message_new_method_call() has failed");
+               return;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(sssi)", "lcdoff",
+                       "staycurstate", "NULL", 0));
+       if (!g_dbus_connection_send_message(conn, msg,
+                               G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+               ERR("Unable to send dbus message for acquring lock as  %s",
+                               err->message);
+               ret = -1;
+       }
+
+       if (ret == 0)
+               is_lock_set = true;
+       g_object_unref(msg);
+       g_dbus_connection_flush_sync(conn, NULL, NULL);
+       g_clear_error(&err);
+}
+
+static void __release_power_lock(void)
+{
+       GError *err = NULL;
+       GDBusConnection *conn;
+       GDBusMessage *msg;
+       int ret = 0;
+
+       if (!is_lock_set)
+               return;
+
+       conn = _get_system_conn();
+       if (conn == NULL)
+               return;
+
+       msg = g_dbus_message_new_method_call(DEVICED_DBUS_PATH,
+                       DEVICED_DBUS_OBJECT_PATH,
+                       DEVICED_DBUS_INTERFACE_NAME,
+                       "unlockstate");
+       if (msg == NULL) {
+               ERR("g_dbus_message_new_method_call() is failed");
+               return;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(ss)", "lcdoff",
+                       "sleepmargin"));
+       if (!g_dbus_connection_send_message(conn, msg,
+                               G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+               ERR("Unable to send dbus message for releasing lock as  %s",
+                       err->message);
+               ret = -1;
+       }
+
+       if (ret == 0)
+               is_lock_set = false;
+       g_object_unref(msg);
+       g_dbus_connection_flush_sync(conn, NULL, NULL);
+       g_clear_error(&err);
+
+       return;
+}
+
+static gboolean getsize_io_handler(GIOChannel *io, GIOCondition cond,
                gpointer data)
 {
        GError *err = NULL;
        GIOStatus s;
        gsize len;
-       struct signal_info_t info;
-       struct backend_job *job;
+       char buf[MAX_LONGLONG_LENGTH];
+       long long result = 0;
+       struct backend_job *job = (struct backend_job *)data;
+       struct getsize_sync_extra_info *extra_getsize_info =
+                       (struct getsize_sync_extra_info *)job->extra_data;
 
-       s = g_io_channel_read_chars(io, (gchar *)&info,
-                       sizeof(struct signal_info_t), &len, &err);
+       s = g_io_channel_read_chars(io, (gchar *)buf, sizeof(buf), &len, &err);
        if (s != G_IO_STATUS_NORMAL) {
-               ERR("Signal pipe read failed: %s", err->message);
+               ERR("getsize fd read failed: %s", err->message);
                g_error_free(err);
-               return TRUE;
+               result = -1;
+       } else {
+               if (strlen(buf) == 0) {
+                       ERR("empty result");
+                       result = -1;
+               } else {
+                       result = atoll(buf);
+               }
        }
 
-       job = (struct backend_job *)g_hash_table_lookup(backend_info_table,
-                       (gconstpointer)info.pid);
-       if (job == NULL) {
-               ERR("Unknown child exit");
+       _return_value_to_caller(job->req_id, g_variant_new("(ix)",
+               (result < 0) ? PKGMGR_R_ERROR : PKGMGR_R_OK, result));
+
+       unlink(extra_getsize_info->getsize_fifo);
+       free(extra_getsize_info->getsize_fifo);
+       extra_getsize_info->getsize_fifo = NULL;
+
+       return FALSE;
+}
+
+static int __setup_size_info_io(struct backend_job *job)
+{
+       guint getsize_wid;
+       struct getsize_sync_extra_info *extra_getsize_info =
+                       (struct getsize_sync_extra_info *)job->extra_data;
+
+       extra_getsize_info->getsize_fd = open(extra_getsize_info->getsize_fifo,
+               O_RDONLY | O_NONBLOCK);
+       if (extra_getsize_info->getsize_fd < 0) {
+               ERR("failed to open the fifo(%s), errno(%d)",
+                               extra_getsize_info->getsize_fifo, errno);
                return -1;
        }
 
-       __set_backend_free(job->backend_slot);
-       if (WIFSIGNALED(info.status)) {
-               _send_fail_signal(job);
-               DBG("backend[%s] exit with signal[%d]", job->backend_type,
-                               WTERMSIG(info.status));
-       } else if (WEXITSTATUS(info.status)) {
-               DBG("backend[%s] exit with error", job->backend_type);
-       } else {
-               DBG("backend[%s] exit", job->backend_type);
+       extra_getsize_info->getsize_io =
+                       g_io_channel_unix_new(extra_getsize_info->getsize_fd);
+       if (!extra_getsize_info->getsize_io)
+               return -1;
+       g_io_channel_set_encoding(extra_getsize_info->getsize_io, NULL, NULL);
+       g_io_channel_set_buffered(extra_getsize_info->getsize_io, FALSE);
+       getsize_wid = g_io_add_watch_full(extra_getsize_info->getsize_io,
+               G_PRIORITY_HIGH, G_IO_IN, getsize_io_handler, job, NULL);
+       if (!getsize_wid) {
+               ERR("failed to add io watch");
+               return -1;
+       }
+
+       return 0;
+}
+
+static gboolean __signal_handler(GIOChannel *io, GIOCondition cond,
+               gpointer data)
+{
+       GError *err = NULL;
+       GIOStatus s;
+       gsize len;
+       struct signalfd_siginfo fdsi;
+       struct backend_job *job;
+       struct getsize_sync_extra_info *extra_getsize_info;
+       pid_t pid;
+       int status;
+
+       s = g_io_channel_read_chars(io, (gchar *)&fdsi,
+                       sizeof(struct signalfd_siginfo), &len, &err);
+       if (s != G_IO_STATUS_NORMAL || len != sizeof(struct signalfd_siginfo)) {
+               ERR("Signal read failed");
+               g_error_free(err);
+               return TRUE;
        }
 
-       g_hash_table_remove(backend_info_table, (gconstpointer)info.pid);
+       while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+               job = (struct backend_job *)g_hash_table_lookup(
+                       backend_info_table, (gconstpointer)pid);
+               if (job == NULL) {
+                       ERR("Unknown child exit");
+                       continue;
+               }
+
+               __set_backend_free(job->backend_slot);
+               if (WIFSIGNALED(status)) {
+                       _send_fail_signal(job);
+                       INFO("backend[%s][%d] exit with signal[%d]",
+                               job->backend_type, pid, WTERMSIG(status));
+               } else if (WEXITSTATUS(status)) {
+                       INFO("backend[%s][%d] exit with error",
+                               job->backend_type, pid);
+               } else {
+                       INFO("backend[%s][%d] exit", job->backend_type, pid);
+               }
+
+               if (job->req_type == REQUEST_TYPE_GETSIZE_SYNC &&
+                               job->extra_data) {
+                       extra_getsize_info =
+                                       (struct getsize_sync_extra_info *)job->extra_data;
+                       if (extra_getsize_info->getsize_fifo) {
+                               ERR("invalid backend close");
+                               _return_value_to_caller(job->req_id,
+                                       g_variant_new("(ix)",
+                                                       PKGMGR_R_ERROR, -1));
+                       }
+               }
+               g_hash_table_remove(backend_info_table, (gconstpointer)pid);
+       }
        g_idle_add(queue_job, NULL);
 
        return TRUE;
@@ -163,60 +361,42 @@ static int __init_backend_info(void)
                        g_direct_equal, NULL,
                        (GDestroyNotify)_free_backend_job);
 
-       if (pipe(pipe_sig)) {
-               ERR("create pipe failed");
-               return -1;
-       }
-
-       pipe_io = g_io_channel_unix_new(pipe_sig[0]);
-       g_io_channel_set_encoding(pipe_io, NULL, NULL);
-       g_io_channel_set_buffered(pipe_io, FALSE);
-       pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
-
        return 0;
 }
 
 static void __fini_backend_info(void)
 {
-       g_source_remove(pipe_wid);
-       g_io_channel_unref(pipe_io);
-       close(pipe_sig[0]);
-       close(pipe_sig[1]);
-
        /*Free backend info */
        g_hash_table_destroy(backend_info_table);
 }
 
-static void sighandler(int signo)
-{
-       struct signal_info_t info;
-       char buf[1024] = {0, };
-
-       info.pid = waitpid(-1, &info.status, WNOHANG);
-       if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
-               ERR("failed to write result: %s",
-                               strerror_r(errno, buf, sizeof(buf)));
-}
-
 static int __register_signal_handler(void)
 {
-       static int sig_reg = 0;
-       struct sigaction act;
+       sigset_t mask;
+       int sfd;
 
-       if (sig_reg)
-               return 0;
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGCHLD);
 
-       act.sa_handler = sighandler;
-       sigemptyset(&act.sa_mask);
-       act.sa_flags = SA_NOCLDSTOP;
-       if (sigaction(SIGCHLD, &act, NULL) < 0) {
-               ERR("signal: SIGCHLD failed");
+       if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
+               ERR("sigprocmask failed");
                return -1;
        }
 
-       g_timeout_add_seconds(2, exit_server, NULL);
+       sfd = signalfd(-1, &mask, SFD_NONBLOCK);
+       if (sfd == -1) {
+               ERR("signalfd failed");
+               return -1;
+       }
+
+       sio = g_io_channel_unix_new(sfd);
+       g_io_channel_set_close_on_unref(sio, TRUE);
+       g_io_channel_set_encoding(sio, NULL, NULL);
+       g_io_channel_set_buffered(sio, FALSE);
+       swid = g_io_add_watch(sio, G_IO_IN, __signal_handler, NULL);
+
+       g_timeout_add_seconds_full(G_PRIORITY_LOW, 2, exit_server, NULL, NULL);
 
-       sig_reg = 1;
        return 0;
 }
 
@@ -244,40 +424,74 @@ gboolean exit_server(void *data)
 {
        DBG("exit_server Start");
        if (__check_backend_status_for_exit() &&
-                       __check_queue_status_for_exit()) {
+                       __check_queue_status_for_exit() && !is_drm_busy) {
                g_main_loop_quit(mainloop);
+               if (is_lock_set)
+                       __release_power_lock();
                return FALSE;
        }
        return TRUE;
 }
 
-#ifdef TIZEN_FEATURE_CSR
 static int __check_csr(const char *path)
 {
-       csr_cs_context_h context = NULL;
-       csr_cs_malware_h detected = NULL;
-       int ret = -1;
+       int ret;
+       void *context;
+       void *malware;
+       void *lib_handle;
+       int (*_csr_cs_context_create)(void **handle);
+       int (*_csr_cs_scan_file)(void *handle, const char *file_path, void **malware);
+       int (*_csr_cs_context_destroy)(void *handle);
+
+       lib_handle = dlopen(PATH_LIBCSR_CLIENT, RTLD_LAZY);
+       if (!lib_handle) {
+               DBG("Unable to open %s", PATH_LIBCSR_CLIENT);
+               return 0;
+       }
 
-       ret = csr_cs_context_create(&context);
-       if (ret != CSR_ERROR_NONE) {
-               ERR("Failed to create csr context");
-               return -1;
+       _csr_cs_context_create = dlsym(lib_handle, "csr_cs_context_create");
+       _csr_cs_scan_file = dlsym(lib_handle, "csr_cs_scan_file");
+       _csr_cs_context_destroy = dlsym(lib_handle, "csr_cs_context_destroy");
+
+       if (!_csr_cs_context_create || !_csr_cs_scan_file ||
+                       !_csr_cs_context_destroy) {
+               ERR("Failed to load CSR symbols");
+               ret = -1;
+               goto catch;
+       }
+
+       ret = _csr_cs_context_create(&context);
+       if (ret != 0) {
+               ERR("Failed to create context");
+               ret = -1;
+               goto catch;
        }
 
-       if (context) {
-               ret = csr_cs_scan_file(context, path, &detected);
+       ret = _csr_cs_scan_file(context, path, &malware);
+       if (ret != 0) {
                DBG("CSR result[%d]", ret);
+               ret = 0;
+               goto catch;
+       }
 
-               csr_cs_context_destroy(context);
-               if (detected != NULL) {
-                       ERR("CSR Denied[%s] Installation", path);
-                       return -1;
-               }
+       ret = _csr_cs_context_destroy(context);
+       if (ret != 0) {
+               ERR("Failed to destroy context");
+               ret = -1;
+               goto catch;
        }
 
-       return 0;
+       if (malware != NULL) {
+               ERR("CSR detected malware from [%s]", path);
+               ret = -1;
+       }
+
+catch:
+       if (lib_handle)
+               dlclose(lib_handle);
+
+       return ret;
 }
-#endif
 
 static int __kill_app(char *appid, uid_t uid)
 {
@@ -296,7 +510,7 @@ static int __kill_app(char *appid, uid_t uid)
 
        ret = aul_terminate_pid_for_uid(pid, uid);
        if (ret != AUL_R_OK) {
-               ERR("failed to terminate app(%d)", appid);
+               ERR("failed to terminate app(%s)", appid);
                return -1;
        }
 
@@ -356,7 +570,7 @@ static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
        return 0;
 }
 
-void free_user_context(user_ctxctx)
+void free_user_context(user_ctx *ctx)
 {
        char **env = NULL;
        int i = 0;
@@ -520,8 +734,8 @@ static char **__generate_argv(const char *args)
 
        ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
        if (FALSE == ret_parse) {
-               DBG("Failed to split args: %s", args);
-               DBG("messsage: %s", gerr->message);
+               ERR("Failed to split args: %s", args);
+               ERR("messsage: %s", gerr->message);
                exit(1);
        }
 
@@ -537,19 +751,19 @@ void __set_environment(gpointer user_data)
        user_ctx *ctx = (user_ctx *)user_data;
 
        if (set_environement(ctx))
-               DBG("Failed to set env for the user : %d", ctx->uid);
+               ERR("Failed to set env for the user : %d", ctx->uid);
 }
 
 static int __fork_and_exec_with_args(char **argv, uid_t uid)
 {
-       user_ctxuser_context;
+       user_ctx *user_context;
        GError *error = NULL;
        gboolean ret;
        int pid;
 
        user_context = get_user_context(uid);
        if (!user_context) {
-               DBG("Failed to getenv");
+               ERR("Failed to getenv");
                return -1;
        }
 
@@ -559,6 +773,8 @@ static int __fork_and_exec_with_args(char **argv, uid_t uid)
        if (ret != TRUE) {
                ERR("Failed to excute backend: %s", error->message);
                g_error_free(error);
+               free_user_context(user_context);
+               return -1;
        }
 
        free_user_context(user_context);
@@ -572,24 +788,15 @@ static int __change_job_info(struct backend_job *job, uid_t uid,
        int ret = 0;
        char *pkgid = NULL;
        pkgmgrinfo_appinfo_h handle = NULL;
-
-       switch (job->req_type) {
-       case REQUEST_TYPE_DISABLE_APP:
-       case REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
-       case REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
-       case REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
-               ret = pkgmgrinfo_appinfo_get_usr_appinfo(job->pkgid, uid,
-                               &handle);
-               break;
-       case REQUEST_TYPE_ENABLE_APP:
-       case REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
-               ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(job->pkgid,
-                               uid, &handle);
-               break;
-       default:
+       if (job->req_type != REQUEST_TYPE_DISABLE_APP &&
+                       job->req_type != REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID &&
+                       job->req_type != REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN &&
+                       job->req_type != REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN &&
+                       job->req_type != REQUEST_TYPE_ENABLE_APP &&
+                       job->req_type != REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID)
                return PMINFO_R_ERROR;
-       }
 
+       ret = pkgmgrinfo_appinfo_get_usr_all_appinfo(job->pkgid, uid, &handle);
        if (ret != PMINFO_R_OK)
                return PMINFO_R_ERROR;
 
@@ -597,14 +804,9 @@ static int __change_job_info(struct backend_job *job, uid_t uid,
        if (ret != PMINFO_R_OK)
                goto catch;
 
-       if ((job->req_type == REQUEST_TYPE_DISABLE_APP ||
-                               job->req_type == REQUEST_TYPE_ENABLE_APP) &&
-                       *is_global) {
-               ret = PMINFO_R_ERROR;
-               goto catch;
-       } else if ((job->req_type == REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID ||
-                               job->req_type ==
-                               REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID) &&
+       if ((job->req_type == REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID ||
+                       job->req_type ==
+                       REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID) &&
                        !*is_global) {
                ret = PMINFO_R_ERROR;
                goto catch;
@@ -630,19 +832,32 @@ static int __process_install(struct backend_job *job)
        char *backend_cmd;
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
+       gchar *req_id;
+       gchar *pkgid;
        int pid;
 
        backend_cmd = job->backend_path;
        if (backend_cmd == NULL)
                return -1;
 
+       req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
+       pkgid = g_shell_quote(job->pkgid);
+       if (!pkgid) {
+               g_free(req_id);
+               return -1;
+       }
+
        snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid, job->args);
+                       req_id, pkgid, (int)job->target_uid, job->args);
 
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
        g_strfreev(argv);
+       g_free(req_id);
+       g_free(pkgid);
 
        return pid;
 }
@@ -652,19 +867,31 @@ static int __process_mount_install(struct backend_job *job)
        char *backend_cmd;
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
+       gchar *req_id;
+       gchar *pkgid;
        int pid;
 
        backend_cmd = job->backend_path;
        if (backend_cmd == NULL)
                return -1;
 
+       req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
+       pkgid = g_shell_quote(job->pkgid);
+       if (!pkgid) {
+               g_free(req_id);
+               return -1;
+       }
        snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid, job->args);
+                       req_id, pkgid, (int)job->target_uid, job->args);
 
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
        g_strfreev(argv);
+       g_free(req_id);
+       g_free(pkgid);
 
        return pid;
 }
@@ -674,19 +901,32 @@ static int __process_reinstall(struct backend_job *job)
        char *backend_cmd;
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
+       gchar *req_id;
+       gchar *pkgid;
        int pid;
 
        backend_cmd = job->backend_path;
        if (backend_cmd == NULL)
                return -1;
 
+       req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
+       pkgid = g_shell_quote(job->pkgid);
+       if (!pkgid) {
+               g_free(req_id);
+               return -1;
+       }
+
        snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid);
+                       req_id, pkgid, (int)job->target_uid);
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
+       g_free(req_id);
+       g_free(pkgid);
 
        return pid;
 }
@@ -703,7 +943,7 @@ static int __process_uninstall(struct backend_job *job)
                return -1;
 
        snprintf(args, sizeof(args), "%s -k %s -d %s -u %d", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid);
+                       job->req_id, job->pkgid, (int)job->target_uid);
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
@@ -725,7 +965,7 @@ static int __process_move(struct backend_job *job)
                return -1;
 
        snprintf(args, sizeof(args), "%s -k %s -m %s -u %d -t %s", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid, job->args);
+                       job->req_id, job->pkgid, (int)job->target_uid, job->args);
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
@@ -740,19 +980,52 @@ static int __process_enable_pkg(struct backend_job *job)
        char *backend_cmd;
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
+       pkgmgrinfo_pkginfo_h pkginfo_h;
+       bool is_readonly;
+       bool is_global;
+       int ret;
        int pid;
 
        backend_cmd = job->backend_path;
        if (backend_cmd == NULL)
                return -1;
 
-       snprintf(args, sizeof(args), "%s -k %s -u %d -A %s", backend_cmd,
-                       job->req_id, (int)job->uid, job->pkgid);
-       argv = __generate_argv(args);
+       ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(
+                       job->pkgid, job->target_uid, &pkginfo_h);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get appinfo");
+               return -1;
+       }
 
+       ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get global value");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       if ((is_global && job->target_uid != GLOBAL_USER) ||
+                       (!is_global && job->target_uid == GLOBAL_USER)) {
+               ERR("Invalid attempt to enable pkg");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get readonly value");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       snprintf(args, sizeof(args), "%s -k %s -u %d -A %s %s",
+                       backend_cmd, job->req_id, (int)job->target_uid,
+                       job->pkgid, (is_readonly) ? "--preload" : "");
+       argv = __generate_argv(args);
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
 
        return pid;
 }
@@ -762,23 +1035,122 @@ static int __process_disable_pkg(struct backend_job *job)
        char *backend_cmd;
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
+       pkgmgrinfo_pkginfo_h pkginfo_h;
+       bool is_readonly;
+       bool is_global;
+       int ret;
        int pid;
 
        backend_cmd = job->backend_path;
        if (backend_cmd == NULL)
                return -1;
 
-       snprintf(args, sizeof(args), "%s -k %s -u %d -D %s", backend_cmd,
-                       job->req_id, (int)job->uid, job->pkgid);
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(
+                       job->pkgid, job->target_uid, &pkginfo_h);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get appinfo");
+               return -1;
+       }
+
+       ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get global value");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       if ((is_global && job->target_uid != GLOBAL_USER) ||
+                       (!is_global && job->target_uid == GLOBAL_USER)) {
+               ERR("Invalid attempt to disable pkg");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
+       if (ret != PMINFO_R_OK) {
+               ERR("Failed to get readonly value");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return -1;
+       }
+
+       snprintf(args, sizeof(args), "%s -k %s -u %d -D %s %s",
+                       backend_cmd, job->req_id, (int)job->target_uid,
+                       job->pkgid, (is_readonly) ? "--preload" : "");
        argv = __generate_argv(args);
 
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
 
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
        return pid;
 }
 
+static int __process_register_pkg_update_info(struct backend_job *job)
+{
+       int ret;
+
+       if (!job->extra_data) {
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               return -1;
+       }
+
+       ret = pkgmgr_parser_register_pkg_update_info_in_usr_db(
+                       (pkgmgrinfo_updateinfo_h)job->extra_data, job->target_uid);
+       if (ret == PMINFO_R_OK)
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_OK));
+       else
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+
+       pkgmgrinfo_updateinfo_destroy(job->extra_data);
+       job->extra_data = NULL;
+
+       return ret;
+}
+
+static int __process_unregister_pkg_update_info(struct backend_job *job)
+{
+       int ret = pkgmgr_parser_unregister_pkg_update_info_in_usr_db
+                       (job->pkgid, job->target_uid);
+
+       if (ret == PMINFO_R_OK)
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_OK));
+       else
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+       return ret;
+}
+
+static int __process_unregister_all_pkg_update_info(struct backend_job *job)
+{
+       int ret = pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
+                       job->target_uid);
+
+       if (ret != PMINFO_R_OK) {
+               _return_value_to_caller(job->req_id,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               return ret;
+       }
+
+       if (__is_admin_user(job->caller_uid)) {
+               ret = pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
+                               GLOBAL_USER);
+               if (ret != PMINFO_R_OK) {
+                       _return_value_to_caller(job->req_id,
+                                       g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+                       return ret;
+               }
+       }
+       _return_value_to_caller(job->req_id,
+                       g_variant_new("(i)", PKGMGR_R_OK));
+
+       return ret;
+}
+
 static int __process_enable_app(struct backend_job *job)
 {
        int ret = -1;
@@ -787,32 +1159,32 @@ static int __process_enable_app(struct backend_job *job)
        /* get actual pkgid and replace it to appid which is currently stored
         * at pkgid variable
         */
-       ret = __change_job_info(job, job->uid, &is_global);
+       ret = __change_job_info(job, job->target_uid, &is_global);
        if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_START_KEY_STR,
                                PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
                                job->req_type);
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
                return ret;
        }
 
-       _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+       _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                        PKGMGR_INSTALLER_START_KEY_STR,
                        PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, job->req_type);
 
        ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
-                       job->uid, 0);
+                       job->target_uid, 0);
        if (ret != PMINFO_R_OK)
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        else
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_OK_EVENT_STR,
                                job->req_type);
@@ -828,40 +1200,40 @@ static int __process_disable_app(struct backend_job *job)
        /* get actual pkgid and replace it to appid which is currently stored
         * at pkgid variable
         */
-       ret = __change_job_info(job, job->uid, &is_global);
+       ret = __change_job_info(job, job->target_uid, &is_global);
        if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_START_KEY_STR,
                                PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
                                job->req_type);
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
                return ret;
        }
 
-       _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+       _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                        PKGMGR_INSTALLER_START_KEY_STR,
                        PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, job->req_type);
 
-       ret = __kill_app(job->appid, job->uid);
+       ret = __kill_app(job->appid, job->target_uid);
        if (ret != 0) {
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        }
 
        ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
-                       job->uid, 1);
+                       job->target_uid, 1);
        if (ret != PMINFO_R_OK)
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        else
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_OK_EVENT_STR,
                                job->req_type);
@@ -877,33 +1249,33 @@ static int __process_enable_global_app_for_uid(struct backend_job *job)
        /* get actual pkgid and replace it to appid which is currently stored
         * at pkgid variable
         */
-       ret = __change_job_info(job, job->uid, &is_global);
+       ret = __change_job_info(job, job->target_uid, &is_global);
        if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_START_KEY_STR,
-                               PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID,
+                               PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
                                job->req_type);
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
                return ret;
        }
 
-       _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+       _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                        PKGMGR_INSTALLER_START_KEY_STR,
-                       PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID,
+                       PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
                        job->req_type);
 
        ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
-                       job->appid, job->uid, 0);
+                       job->appid, job->target_uid, 0);
        if (ret != PMINFO_R_OK)
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        else
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_OK_EVENT_STR,
                                job->req_type);
@@ -921,35 +1293,35 @@ static int __process_disable_global_app_for_uid(struct backend_job *job)
         */
        ret = __change_job_info(job, GLOBAL_USER, &is_global);
        if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
-               _send_app_signal(job->uid, job->req_id,
+               _send_app_signal(job->target_uid, job->req_id,
                                job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_START_KEY_STR,
-                               PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID,
+                               PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
                                job->req_type);
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
                return ret;
        }
 
-       _send_app_signal(job->uid, job->req_id,
+       _send_app_signal(job->target_uid, job->req_id,
                        job->pkgid, job->appid,
                        PKGMGR_INSTALLER_START_KEY_STR,
-                       PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID,
+                       PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
                        job->req_type);
 
-       ret = __kill_app(job->appid, job->uid);
+       ret = __kill_app(job->appid, job->target_uid);
        ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
-                       job->appid, job->uid, 1);
+                       job->appid, job->target_uid, 1);
 
        if (ret != PMINFO_R_OK)
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        else
-               _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                                PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_OK_EVENT_STR,
                                job->req_type);
@@ -959,57 +1331,113 @@ static int __process_disable_global_app_for_uid(struct backend_job *job)
 
 static int __process_getsize(struct backend_job *job)
 {
-       static const char *backend_cmd = "/usr/bin/pkg_getsize";
+       static const char backend_cmd[] = "/usr/bin/pkg_getsize";
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
        int pid;
 
-       snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, job->pkgid,
-                       job->args, job->req_id);
+       snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d",
+                       backend_cmd, job->pkgid, job->args, job->caller_uid,
+                       job->req_id, job->target_uid);
        argv = __generate_argv(args);
-       pid = __fork_and_exec_with_args(argv, job->uid);
+       pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
 
        return pid;
 }
 
+static int __process_getsize_sync(struct backend_job *job)
+{
+       static const char backend_cmd[] = "/usr/bin/pkg_getsize";
+       char **argv;
+       char args[MAX_PKG_ARGS_LEN];
+       char fifo_path[PATH_MAX];
+       struct getsize_sync_extra_info *extra_getsize_info;
+       int pid;
+
+       snprintf(fifo_path, sizeof(fifo_path), "/tmp/pkgmgr/%s",
+                       job->req_id);
+
+       extra_getsize_info = calloc(1, sizeof(struct getsize_sync_extra_info));
+       if (!extra_getsize_info) {
+               ERR("memory alloc failed");
+               goto error;
+       }
+
+       extra_getsize_info->getsize_fifo = strdup(fifo_path);
+       if (!extra_getsize_info->getsize_fifo) {
+               ERR("out of memory");
+               goto error;
+       }
+
+       job->extra_data = extra_getsize_info;
+
+       if (mkfifo(extra_getsize_info->getsize_fifo, 0600) < 0) {
+               ERR("failed to mkfifo");
+               goto error;
+       }
+
+       snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d --sync",
+                       backend_cmd, job->pkgid, job->args, job->caller_uid,
+                       job->req_id, job->target_uid);
+       argv = __generate_argv(args);
+       pid = __fork_and_exec_with_args(argv, APPFW_UID);
+
+       g_strfreev(argv);
+
+       if (pid < 0) {
+               ERR("failed to execute backend");
+               goto error;
+       }
+       if (__setup_size_info_io(job) < 0) {
+               ERR("failed to setup io handler");
+               goto error;
+       }
+
+       return pid;
+
+error:
+       _return_value_to_caller(job->req_id,
+               g_variant_new("(ix)", PKGMGR_R_ERROR, -1));
+       return -1;
+}
+
 static int __process_cleardata(struct backend_job *job)
 {
-       char *backend_cmd;
+       static const char *backend_cmd = "/usr/bin/pkg_cleardata";
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
        int pid;
 
-       backend_cmd = job->backend_path;
-       if (backend_cmd == NULL)
+       if ((int)job->target_uid < REGULAR_USER)
                return -1;
 
-       /* TODO: set movetype */
-       snprintf(args, sizeof(args), "%s -k %s -c %s -u %d", backend_cmd,
-                       job->req_id, job->pkgid, (int)job->uid);
+       snprintf(args, sizeof(args), "%s -d -n %s -u %d",
+                       backend_cmd, job->pkgid, job->target_uid);
        argv = __generate_argv(args);
-
        pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
-
        return pid;
 }
 
 static int __process_clearcache(struct backend_job *job)
 {
-       static const char *backend_cmd = "/usr/bin/pkg_clearcache";
+       static const char *backend_cmd = "/usr/bin/pkg_cleardata";
        char **argv;
        char args[MAX_PKG_ARGS_LEN];
        int pid;
 
-       snprintf(args, sizeof(args), "%s %s", backend_cmd, job->pkgid);
+       if ((int)job->target_uid < REGULAR_USER)
+               return -1;
+
+       snprintf(args, sizeof(args), "%s -c -n %s -u %d",
+                       backend_cmd, job->pkgid, job->target_uid);
        argv = __generate_argv(args);
-       pid = __fork_and_exec_with_args(argv, job->uid);
+       pid = __fork_and_exec_with_args(argv, APPFW_UID);
 
        g_strfreev(argv);
-
        return pid;
 }
 
@@ -1019,7 +1447,7 @@ static int __process_kill(struct backend_job *job)
        pkgmgrinfo_pkginfo_h handle;
        pkgcmd_data *pdata;
 
-       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->uid,
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
                        &handle);
        if (ret < 0) {
                ERR("Failed to get handle");
@@ -1043,9 +1471,9 @@ static int __process_kill(struct backend_job *job)
                free(pdata);
                return -1;
        }
-       pdata->uid = job->uid;
+       pdata->uid = job->target_uid;
        ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
-                       __pkgcmd_app_cb, pdata, job->uid);
+                       __pkgcmd_app_cb, pdata, job->target_uid);
 
        _return_value_to_caller(job->req_id,
                        g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
@@ -1067,7 +1495,7 @@ static int __process_check(struct backend_job *job)
        pkgmgrinfo_pkginfo_h handle;
        pkgcmd_data *pdata;
 
-       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->uid,
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
                        &handle);
        if (ret < 0) {
                ERR("Failed to get handle");
@@ -1091,9 +1519,9 @@ static int __process_check(struct backend_job *job)
                free(pdata);
                return -1;
        }
-       pdata->uid = job->uid;
+       pdata->uid = job->target_uid;
        ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
-                       __pkgcmd_app_cb, pdata, job->uid);
+                       __pkgcmd_app_cb, pdata, job->target_uid);
 
        _return_value_to_caller(job->req_id,
                        g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
@@ -1109,54 +1537,120 @@ static int __process_check(struct backend_job *job)
        return 0;
 }
 
+static int __load_drm_library(void)
+{
+       if (drm_lib_handle)
+               return 0;
+
+       drm_lib_handle = dlopen(PATH_LIBDRM_SVC_CORE, RTLD_LAZY);
+       if (!drm_lib_handle) {
+               DBG("Unable to open %s", PATH_LIBDRM_SVC_CORE);
+               return -1;
+       }
+
+       _drm_tizen_generate_license_request =
+                       dlsym(drm_lib_handle, "drm_tizen_generate_license_request");
+       if (_drm_tizen_generate_license_request == NULL) {
+               ERR("_drm_tizen_generate_license_request() failed");
+               goto catch;
+       }
+
+       _drm_tizen_register_license =
+                               dlsym(drm_lib_handle, "drm_tizen_register_license");
+       if (_drm_tizen_register_license == NULL) {
+               ERR("_register_license() failed");
+               goto catch;
+       }
+
+       _drm_tizen_decrypt_package =
+                       dlsym(drm_lib_handle, "drm_tizen_decrypt_package");
+       if (_drm_tizen_decrypt_package == NULL) {
+               ERR("_drm_tizen_decrypt_package() failed");
+               goto catch;
+       }
+
+       return 0;
+catch:
+       if (drm_lib_handle) {
+               dlclose(drm_lib_handle);
+               drm_lib_handle = NULL;
+       }
+       return -1;
+}
+
+static void __unload_drm_library(void)
+{
+       if (drm_lib_handle) {
+               dlclose(drm_lib_handle);
+               drm_lib_handle = NULL;
+       }
+}
+
 static int __process_generate_license_request(struct backend_job *job)
 {
-       int ret;
        char *resp_data;
        char req_data[MAX_PKG_ARGS_LEN];
        unsigned int req_data_len;
        char license_url[MAX_PKG_ARGS_LEN];
        unsigned int license_url_len;
+       int ret;
 
        resp_data = job->args;
        req_data_len = sizeof(req_data);
        license_url_len = sizeof(license_url);
 
-       ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
-                       req_data, &req_data_len, license_url, &license_url_len);
-       if (ret != TADC_SUCCESS) {
-               ERR("drm_tizen_generate_license_request failed: %d", ret);
-               _return_value_to_caller(job->req_id, g_variant_new("(iss)",
-                                       PKGMGR_R_ESYSTEM, "", ""));
-               return -1;
+       if (__load_drm_library() != 0) {
+               ERR("Failed to load library");
+               goto catch;
        }
 
+       ret = _drm_tizen_generate_license_request(resp_data, strlen(resp_data),
+                       req_data, &req_data_len,
+                       license_url, &license_url_len);
+       if (ret != 1) {
+               ERR("drm_tizen_generate_license_request failed");
+               goto catch;
+       }
        _return_value_to_caller(job->req_id,
                        g_variant_new("(iss)", PKGMGR_R_OK, req_data,
                                license_url));
-
+       is_drm_busy = true;
        return 0;
+
+catch:
+       _return_value_to_caller(job->req_id, g_variant_new("(iss)",
+                               PKGMGR_R_ESYSTEM, "", ""));
+       is_drm_busy = false;
+       __unload_drm_library();
+       return -1;
 }
 
 static int __process_register_license(struct backend_job *job)
 {
-       int ret;
        char *resp_data;
+       int ret;
 
        resp_data = job->args;
-
-       ret = drm_tizen_register_license(resp_data, strlen(resp_data));
-       if (ret != TADC_SUCCESS) {
+       if (!_drm_tizen_register_license) {
+               ERR("_drm_tizen_register_license is not loaded");
+               goto catch;
+       }
+       ret = _drm_tizen_register_license(resp_data, strlen(resp_data));
+       if (ret != 1) {
                ERR("drm_tizen_register_license failed: %d", ret);
-               _return_value_to_caller(job->req_id,
-                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
-               return -1;
+               goto catch;
        }
-
        _return_value_to_caller(job->req_id,
                        g_variant_new("(i)", PKGMGR_R_OK));
-
        return 0;
+
+catch:
+       _return_value_to_caller(job->req_id,
+                       g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+       is_drm_busy = false;
+       __unload_drm_library();
+
+       return -1;
 }
 
 static int __process_decrypt_package(struct backend_job *job)
@@ -1169,19 +1663,28 @@ static int __process_decrypt_package(struct backend_job *job)
        decrypted_file_path = job->args;
 
        /* TODO: check ownership of decrypted file */
-       ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
+       if (!_drm_tizen_decrypt_package) {
+               ERR("drm_tizen_decrypt_package is not loaded");
+
+               goto catch;
+       }
+       ret = _drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
                        decrypted_file_path, strlen(decrypted_file_path));
-       if (ret != TADC_SUCCESS) {
-               ERR("drm_tizen_register_license failed: %d", ret);
-               _return_value_to_caller(job->req_id,
-                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
-               return -1;
+       if (ret != 1) {
+               ERR("drm_tizen_decrypt_package failed: %d", ret);
+               goto catch;
        }
-
        _return_value_to_caller(job->req_id,
                        g_variant_new("(i)", PKGMGR_R_OK));
-
        return 0;
+
+catch:
+       _return_value_to_caller(job->req_id,
+               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+       is_drm_busy = false;
+       __unload_drm_library();
+
+       return -1;
 }
 
 static int __process_update_app_splash_screen(struct backend_job *job, int flag)
@@ -1190,27 +1693,27 @@ static int __process_update_app_splash_screen(struct backend_job *job, int flag)
        bool is_global = false;
        const char *val;
 
-       ret = __change_job_info(job, job->uid, &is_global);
+       ret = __change_job_info(job, job->target_uid, &is_global);
        if (ret != PMINFO_R_OK || strlen(job->appid) == 0)
                return -1;
 
        val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
                PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
-       _send_app_signal(job->uid, job->req_id, job->pkgid, job->appid,
+       _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
                        PKGMGR_INSTALLER_START_KEY_STR, val, job->req_type);
 
        if (is_global)
-               ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(job->appid, job->uid, flag);
+               ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(job->appid, job->target_uid, flag);
        else
                ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
-                       job->appid, job->uid, flag);
+                       job->appid, job->target_uid, flag);
        if (ret != PMINFO_R_OK)
-               _send_app_signal(job->uid, job->req_id, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid,
                                job->appid, PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_FAIL_EVENT_STR,
                                job->req_type);
        else
-               _send_app_signal(job->uid, job->req_id, job->pkgid,
+               _send_app_signal(job->target_uid, job->req_id, job->pkgid,
                                job->appid, PKGMGR_INSTALLER_END_KEY_STR,
                                PKGMGR_INSTALLER_OK_EVENT_STR,
                                job->req_type);
@@ -1224,7 +1727,7 @@ static int __process_set_restriction_mode(struct backend_job *job)
        int mode;
 
        mode = atoi(job->args);
-       ret = _set_restriction_mode(job->uid, job->pkgid, mode);
+       ret = _set_restriction_mode(job->target_uid, job->pkgid, mode);
 
        _return_value_to_caller(job->req_id,
                        g_variant_new("(i)", ret));
@@ -1238,7 +1741,7 @@ static int __process_unset_restriction_mode(struct backend_job *job)
        int mode;
 
        mode = atoi(job->args);
-       ret = _unset_restriction_mode(job->uid, job->pkgid, mode);
+       ret = _unset_restriction_mode(job->target_uid, job->pkgid, mode);
 
        _return_value_to_caller(job->req_id,
                        g_variant_new("(i)", ret));
@@ -1251,7 +1754,7 @@ static int __process_get_restriction_mode(struct backend_job *job)
        int ret;
        int mode = -1;
 
-       ret = _get_restriction_mode(job->uid, job->pkgid, &mode);
+       ret = _get_restriction_mode(job->target_uid, job->pkgid, &mode);
 
        _return_value_to_caller(job->req_id,
                        g_variant_new("(ii)", mode, ret));
@@ -1259,6 +1762,63 @@ static int __process_get_restriction_mode(struct backend_job *job)
        return ret;
 }
 
+static int __process_set_app_label(struct backend_job *job)
+{
+       int ret;
+
+       ret = pkgmgr_parser_update_app_label_info_in_usr_db(job->pkgid,
+                       job->target_uid, job->args);
+       _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+
+       return ret;
+}
+
+static int __process_set_app_icon(struct backend_job *job)
+{
+       int ret;
+
+       ret = pkgmgr_parser_update_app_icon_info_in_usr_db(job->pkgid,
+                       job->target_uid, job->args);
+       _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+
+       return ret;
+}
+
+static int __process_migrate_external_image(struct backend_job *job)
+{
+       char *backend_cmd;
+       char **argv;
+       char args[MAX_PKG_ARGS_LEN];
+       int pid;
+
+       backend_cmd = job->backend_path;
+       if (backend_cmd == NULL)
+               return -1;
+
+       snprintf(args, sizeof(args), "%s -k %s --migrate-extimg %s -u %d %s",
+                       backend_cmd, job->req_id, job->pkgid,
+                       (int)job->target_uid, job->args);
+
+       argv = __generate_argv(args);
+
+       pid = __fork_and_exec_with_args(argv, APPFW_UID);
+       g_strfreev(argv);
+
+       return pid;
+}
+
+static int __post_process(int ret, int x, struct backend_job *job)
+{
+       if (ret < 0) {
+               __set_backend_free(x);
+               _free_backend_job(job);
+       } else {
+               g_hash_table_insert(backend_info_table, (gpointer)ret,
+                               (gpointer)job);
+       }
+       return 0;
+}
+
 gboolean queue_job(void *data)
 {
        struct backend_job *job = NULL;
@@ -1277,14 +1837,13 @@ gboolean queue_job(void *data)
 
        /* all backend messages queue are empty or busy */
        if (x == num_of_backends || job == NULL) {
-               DBG("no job left");
+               DBG("no job available");
                return FALSE;
        }
 
        /* set current backend job */
        DBG("handle request type [%d]", job->req_type);
 
-#ifdef TIZEN_FEATURE_CSR
        if (job->req_type == REQUEST_TYPE_INSTALL ||
                        job->req_type == REQUEST_TYPE_MOUNT_INSTALL ||
                        job->req_type == REQUEST_TYPE_REINSTALL) {
@@ -1293,53 +1852,69 @@ gboolean queue_job(void *data)
                        ret = -1;
                        _send_fail_signal(job);
                        _free_backend_job(job);
-                       return FALSE;
+                       return TRUE;
                }
        }
-#endif
 
        switch (job->req_type) {
        case REQUEST_TYPE_INSTALL:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_install(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_MOUNT_INSTALL:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_mount_install(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_REINSTALL:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_reinstall(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_UNINSTALL:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_uninstall(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_MOVE:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_move(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_ENABLE_PKG:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_enable_pkg(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               if (ret < 0)
+                       _send_fail_signal(job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_DISABLE_PKG:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_disable_pkg(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               if (ret < 0)
+                       _send_fail_signal(job);
+               __post_process(ret, x, job);
+               break;
+       case REQUEST_TYPE_REGISTER_PKG_UPDATE_INFO:
+               ret = __process_register_pkg_update_info(job);
+               __free_extra_info(job);
+               _free_backend_job(job);
+               break;
+       case REQUEST_TYPE_UNREGISTER_PKG_UPDATE_INFO:
+               ret = __process_unregister_pkg_update_info(job);
+               _free_backend_job(job);
+               break;
+       case REQUEST_TYPE_UNREGISTER_ALL_PKG_UPDATE_INFO:
+               ret = __process_unregister_all_pkg_update_info(job);
+               _free_backend_job(job);
                break;
        case REQUEST_TYPE_ENABLE_APP:
                ret = __process_enable_app(job);
@@ -1352,20 +1927,26 @@ gboolean queue_job(void *data)
        case REQUEST_TYPE_GETSIZE:
                __set_backend_busy(x);
                ret = __process_getsize(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
+               break;
+       case REQUEST_TYPE_GETSIZE_SYNC:
+               __set_backend_busy(x);
+               ret = __process_getsize_sync(job);
+               if (ret < 0)
+                       __free_extra_info(job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_CLEARDATA:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_cleardata(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_CLEARCACHE:
                __set_backend_busy(x);
+               __set_power_lock();
                ret = __process_clearcache(job);
-               g_hash_table_insert(backend_info_table, (gpointer)ret,
-                               (gpointer)job);
+               __post_process(ret, x, job);
                break;
        case REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
                ret = __process_enable_global_app_for_uid(job);
@@ -1415,12 +1996,26 @@ gboolean queue_job(void *data)
                ret = __process_get_restriction_mode(job);
                _free_backend_job(job);
                break;
+       case REQUEST_TYPE_SET_APP_LABEL:
+               ret = __process_set_app_label(job);
+               _free_backend_job(job);
+               break;
+       case REQUEST_TYPE_SET_APP_ICON:
+               ret = __process_set_app_icon(job);
+               _free_backend_job(job);
+               break;
+       case REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE:
+               __set_backend_busy(x);
+               __set_power_lock();
+               ret = __process_migrate_external_image(job);
+               __post_process(ret, x, job);
+               break;
        default:
                ret = -1;
                break;
        }
 
-       return FALSE;
+       return TRUE;
 }
 
 int main(int argc, char *argv[])
@@ -1429,15 +2024,20 @@ int main(int argc, char *argv[])
 
        DBG("server start");
 
+       if (__register_signal_handler()) {
+               ERR("failed to register signal handler");
+               return -1;
+       }
+
        r = _init_backend_queue();
        if (r) {
-               DBG("Queue Initialization Failed");
+               ERR("Queue Initialization Failed");
                return -1;
        }
 
        r = __init_backend_info();
        if (r) {
-               DBG("backend info init failed");
+               ERR("backend info init failed");
                return -1;
        }
 
@@ -1447,11 +2047,6 @@ int main(int argc, char *argv[])
                return -1;
        }
 
-       if (__register_signal_handler()) {
-               ERR("failed to register signal handler");
-               return -1;
-       }
-
 #if !GLIB_CHECK_VERSION(2, 35, 0)
        g_type_init();
 #endif
@@ -1470,6 +2065,9 @@ int main(int argc, char *argv[])
        __fini_backend_info();
        _fini_backend_queue();
 
+       g_source_remove(swid);
+       g_io_channel_unref(sio);
+
        DBG("package manager server terminated.");
 
        return 0;