Fix to not generate arg when length is 0
[platform/core/appfw/pkgmgr-server.git] / src / request.c
index 2e4fbc1..bb996a7 100644 (file)
@@ -4,15 +4,12 @@
 
 #include <glib.h>
 #include <gio/gio.h>
-#include <gum/gum-user.h>
-#include <gum/common/gum-user-types.h>
 
 #include "queue.h"
+#include "pkgmgr-info.h"
 #include "pkgmgr-server.h"
 #include "package-manager.h"
 
-#define RETRY_MAX 5
-#define RETRY_WAIT_USEC (1000000 / 2) /* 0.5 sec */
 #define PKGMGR_DBUS_SERVICE "org.tizen.pkgmgr"
 #define PKGMGR_DBUS_OBJECT_PATH "/org/tizen/pkgmgr"
 
@@ -66,6 +63,22 @@ static const char instropection_xml[] =
        "      <arg type='i' name='ret' direction='out'/>"
        "      <arg type='s' name='reqkey' direction='out'/>"
        "    </method>"
+       "    <method name='register_pkg_update_info'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='s' name='version' direction='in'/>"
+       "      <arg type='i' name='type' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='unregister_pkg_update_info'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='unregister_all_pkg_update_info'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
        "    <method name='enable_app'>"
        "      <arg type='u' name='uid' direction='in'/>"
        "      <arg type='s' name='appid' direction='in'/>"
@@ -78,6 +91,18 @@ static const char instropection_xml[] =
        "      <arg type='i' name='ret' direction='out'/>"
        "      <arg type='s' name='reqkey' direction='out'/>"
        "    </method>"
+       "    <method name='enable_apps'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='as' name='appids' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "      <arg type='s' name='reqkey' direction='out'/>"
+       "    </method>"
+       "    <method name='disable_apps'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='as' name='appids' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "      <arg type='s' name='reqkey' direction='out'/>"
+       "    </method>"
        "    <method name='enable_global_app_for_uid'>"
        "      <arg type='u' name='uid' direction='in'/>"
        "      <arg type='s' name='appid' direction='in'/>"
@@ -175,6 +200,17 @@ static const char instropection_xml[] =
        "      <arg type='s' name='label' direction='in'/>"
        "      <arg type='i' name='ret' direction='out'/>"
        "    </method>"
+       "    <method name='set_app_icon'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='appid' direction='in'/>"
+       "      <arg type='s' name='icon_path' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='migrate_external_image'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
        "  </interface>"
        "</node>";
 static GDBusNodeInfo *instropection_data;
@@ -197,7 +233,7 @@ static char *__generate_reqkey(const char *pkgid)
        size = strlen(pkgid) + strlen(timestr) + 2;
        str_req_key = (char *)calloc(size, sizeof(char));
        if (str_req_key == NULL) {
-               DBG("calloc failed");
+               ERR("calloc failed");
                return NULL;
        }
        snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
@@ -205,43 +241,6 @@ static char *__generate_reqkey(const char *pkgid)
        return str_req_key;
 }
 
-static int __is_admin_user(uid_t uid)
-{
-       GumUser *guser;
-       GumUserType ut = GUM_USERTYPE_NONE;
-       int retry_cnt = 0;
-
-       do {
-               guser = gum_user_get_sync(uid, FALSE);
-               if (guser == NULL) {
-                       ERR("cannot get user information from gumd, retry");
-                       retry_cnt++;
-                       usleep(RETRY_WAIT_USEC);
-                       continue;
-               }
-               break;
-       } while (retry_cnt <= RETRY_MAX);
-
-       if (guser == NULL) {
-               ERR("cannot get user information from gumd, failed");
-               return -1;
-       }
-
-       g_object_get(G_OBJECT(guser), "usertype", &ut, NULL);
-       if (ut == GUM_USERTYPE_NONE) {
-               ERR("cannot get user type");
-               g_object_unref(guser);
-               return -1;
-       } else if (ut != GUM_USERTYPE_ADMIN) {
-               g_object_unref(guser);
-               return 0;
-       }
-
-       g_object_unref(guser);
-
-       return 1;
-}
-
 static int __check_caller_permission(uid_t uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
@@ -288,7 +287,7 @@ static int __handle_request_install(uid_t caller_uid,
        uid_t target_uid = (uid_t)-1;
        char *arg_pkgtype = NULL;
        const char *pkgtype;
-       char *pkgpath = NULL;
+       const char *pkgpath = NULL;
        char *args = NULL;
        char *reqkey = NULL;
        gchar **tmp_args = NULL;
@@ -305,21 +304,22 @@ static int __handle_request_install(uid_t caller_uid,
        for (i = 0; i < args_count; i++)
                len = len + strlen(tmp_args[i]) + 1;
 
-       args = (char *)calloc(len, sizeof(char));
-       if (args == NULL) {
-               ERR("calloc failed");
-               g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
-               ret = -1;
-               goto catch;
-       }
-
-       for (i = 0; i < args_count; i++) {
-               strncat(args, tmp_args[i], strlen(tmp_args[i]));
-               if (i != args_count - 1)
-                       strncat(args, " ", strlen(" "));
+       if (len) {
+               args = (char *)calloc(len, sizeof(char));
+               if (args == NULL) {
+                       ERR("calloc failed");
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                                       PKGMGR_R_ENOMEM, ""));
+                       ret = -1;
+                       goto catch;
+               }
+               for (i = 0; i < args_count; i++) {
+                       strncat(args, tmp_args[i], len - strlen(args) - 1);
+                       if (i != args_count - 1)
+                               strncat(args, " ", len - strlen(args) - 1);
+               }
        }
-
        if (target_uid == (uid_t)-1 || pkgpath == NULL) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
@@ -347,7 +347,7 @@ static int __handle_request_install(uid_t caller_uid,
        }
 
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
-                               pkgtype, pkgpath, args)) {
+                               pkgtype, pkgpath, args, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -378,7 +378,7 @@ static int __handle_request_mount_install(uid_t caller_uid,
        uid_t target_uid = (uid_t)-1;
        char *arg_pkgtype = NULL;
        const char *pkgtype;
-       char *pkgpath = NULL;
+       const char *pkgpath = NULL;
        char *args = NULL;
        char *reqkey = NULL;
        gchar **tmp_args = NULL;
@@ -394,22 +394,22 @@ static int __handle_request_mount_install(uid_t caller_uid,
 
        for (i = 0; i < args_count; i++)
                len = len + strlen(tmp_args[i]) + 1;
-
-       args = (char *)calloc(len, sizeof(char));
-       if (args == NULL) {
-               ERR("calloc failed");
-               g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
-               ret = -1;
-               goto catch;
-       }
-
-       for (i = 0; i < args_count; i++) {
-               strncat(args, tmp_args[i], strlen(tmp_args[i]));
-               if (i != args_count - 1)
-                       strncat(args, " ", strlen(" "));
+       if (len) {
+               args = (char *)calloc(len, sizeof(char));
+               if (args == NULL) {
+                       ERR("calloc failed");
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                                       PKGMGR_R_ENOMEM, ""));
+                       ret = -1;
+                       goto catch;
+               }
+               for (i = 0; i < args_count; i++) {
+                       strncat(args, tmp_args[i], len - strlen(args) - 1);
+                       if (i != args_count - 1)
+                               strncat(args, " ", len - strlen(args) - 1);
+               }
        }
-
        if (target_uid == (uid_t)-1 || pkgpath == NULL) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
@@ -438,7 +438,7 @@ static int __handle_request_mount_install(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_MOUNT_INSTALL,
-                               pkgtype, pkgpath, args)) {
+                               pkgtype, pkgpath, args, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -492,7 +492,7 @@ static int __handle_request_reinstall(uid_t caller_uid,
                return -1;
        }
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
-                               pkgtype, pkgid, NULL)) {
+                               pkgtype, pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                free(reqkey);
@@ -538,7 +538,7 @@ static int __handle_request_uninstall(uid_t caller_uid,
                return -1;
        }
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
-                               pkgtype, pkgid, NULL)) {
+                               pkgtype, pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                free(reqkey);
@@ -588,7 +588,7 @@ static int __handle_request_move(uid_t caller_uid,
 
        snprintf(buf, sizeof(buf), "%d", move_type);
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
-                               pkgtype, pkgid, buf)) {
+                               pkgtype, pkgid, buf, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                free(reqkey);
@@ -638,7 +638,7 @@ static int __handle_request_enable_pkgs(uid_t caller_uid,
                }
                if (_push_queue(target_uid, caller_uid, reqkey,
                                        REQUEST_TYPE_ENABLE_PKG,
-                                       pkgtype, pkgid, NULL)) {
+                                       pkgtype, pkgid, NULL, NULL)) {
                        g_dbus_method_invocation_return_value(invocation,
                                        g_variant_new("(is)",
                                                PKGMGR_R_ESYSTEM, ""));
@@ -656,6 +656,204 @@ static int __handle_request_enable_pkgs(uid_t caller_uid,
        return 0;
 }
 
+static int __handle_request_register_pkg_update_info(
+               uid_t caller_uid, GDBusMethodInvocation *invocation,
+               GVariant *parameters)
+{
+       char *reqkey;
+       char buf[MAX_PKG_ARGS_LEN];
+       int ret;
+       pkgmgrinfo_pkginfo_h pkg_info;
+       bool is_global_pkg;
+       pkgmgrinfo_updateinfo_h update_info;
+       pkgmgrinfo_updateinfo_update_type converted_type;
+       uid_t target_uid = (uid_t)-1;
+       gchar *pkgid = NULL;
+       gchar *version = NULL;
+
+       g_variant_get(parameters, "(ussi)", &target_uid, &pkgid, &version, &converted_type);
+
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &pkg_info);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EIO));
+               return -1;
+       }
+       ret = pkgmgrinfo_pkginfo_is_global(pkg_info, &is_global_pkg);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EIO));
+               return -1;
+       }
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+
+       /* return error if given pkg is global pkg but caller is not admin */
+       if (caller_uid >= REGULAR_USER && is_global_pkg
+                       && !__is_admin_user(caller_uid)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EPRIV));
+               return -1;
+       }
+
+       ret = pkgmgrinfo_updateinfo_create(&update_info);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       ret = pkgmgrinfo_updateinfo_set_pkgid(update_info, (char *)pkgid);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               pkgmgrinfo_updateinfo_destroy(update_info);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_updateinfo_set_version(update_info, (char *)version);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               pkgmgrinfo_updateinfo_destroy(update_info);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_updateinfo_set_type(update_info, converted_type);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               pkgmgrinfo_updateinfo_destroy(update_info);
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("register_pkg_update_info");
+       if (reqkey == NULL) {
+               pkgmgrinfo_updateinfo_destroy(update_info);
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_push_queue(target_uid, caller_uid, reqkey,
+                       REQUEST_TYPE_REGISTER_PKG_UPDATE_INFO, "default",
+                       NULL, buf, update_info)) {
+               pkgmgrinfo_updateinfo_destroy(update_info);
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(reqkey);
+               return -1;
+       }
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
+static int __handle_request_unregister_pkg_update_info(
+               uid_t caller_uid, GDBusMethodInvocation *invocation,
+               GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *pkgid = NULL;
+       char *reqkey;
+       pkgmgrinfo_pkginfo_h pkg_info;
+       bool is_global_pkg;
+       int ret;
+
+       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &pkg_info);
+       if (ret != PMINFO_R_OK) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EIO));
+               return -1;
+       }
+       ret = pkgmgrinfo_pkginfo_is_global(pkg_info, &is_global_pkg);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EIO));
+               return -1;
+       }
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_info);
+
+       /* return error if given pkg is global pkg but caller is not admin */
+       if (caller_uid >= REGULAR_USER && is_global_pkg
+                       && !__is_admin_user(caller_uid)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_EPRIV));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("unregister_pkg_update_info");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_push_queue(target_uid, caller_uid, reqkey,
+                       REQUEST_TYPE_UNREGISTER_PKG_UPDATE_INFO, "default",
+                       pkgid, NULL, NULL)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(reqkey);
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+
+       return 0;
+
+}
+
+static int __handle_request_unregister_all_pkg_update_info(
+               uid_t caller_uid, GDBusMethodInvocation *invocation,
+               GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *reqkey;
+
+       g_variant_get(parameters, "(u)", &target_uid);
+       if (target_uid == (uid_t)-1) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("unregister_all_pkg_update_info");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
+               return -1;
+       }
+
+       if (_push_queue(target_uid, caller_uid, reqkey,
+                       REQUEST_TYPE_UNREGISTER_ALL_PKG_UPDATE_INFO, "default",
+                       NULL, NULL, NULL)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
+               free(reqkey);
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
 static int __handle_request_disable_pkgs(uid_t caller_uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
@@ -690,7 +888,7 @@ static int __handle_request_disable_pkgs(uid_t caller_uid,
                }
                if (_push_queue(target_uid, caller_uid, reqkey,
                                        REQUEST_TYPE_DISABLE_PKG,
-                                       pkgtype, pkgid, NULL)) {
+                                       pkgtype, pkgid, NULL, NULL)) {
                        g_dbus_method_invocation_return_value(invocation,
                                        g_variant_new("(is)",
                                                PKGMGR_R_ESYSTEM, ""));
@@ -708,6 +906,91 @@ static int __handle_request_disable_pkgs(uid_t caller_uid,
        return 0;
 }
 
+static int __handle_request_enable_apps(uid_t caller_uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *appid;
+       char *reqkey;
+       char buf[MAX_PKG_ARGS_LEN];
+       GVariantIter *iter;
+
+       g_variant_get(parameters, "(uas)", &target_uid, &iter);
+       if (target_uid == (uid_t)-1 || iter == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("enable_apps");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
+               return -1;
+       }
+
+       while (g_variant_iter_next(iter, "&s", &appid)) {
+               if (_push_queue(target_uid, caller_uid, reqkey,
+                                       REQUEST_TYPE_ENABLE_APP,
+                                       "default", appid, buf, NULL)) {
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                               PKGMGR_R_ESYSTEM, ""));
+                       free(reqkey);
+                       return -1;
+               }
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+               g_variant_new("(is)", PKGMGR_R_OK, reqkey));
+
+       free(reqkey);
+       return 0;
+}
+
+static int __handle_request_disable_apps(uid_t caller_uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *appid;
+       char *reqkey;
+       char buf[MAX_PKG_ARGS_LEN];
+       GVariantIter *iter;
+
+       g_variant_get(parameters, "(uas)", &target_uid, &iter);
+       if (target_uid == (uid_t)-1 || iter == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("disable_apps");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
+               return -1;
+       }
+
+       while (g_variant_iter_next(iter, "&s", &appid)) {
+               if (_push_queue(target_uid, caller_uid, reqkey,
+                                       REQUEST_TYPE_DISABLE_APP,
+                                       "default", appid, buf, NULL)) {
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                               PKGMGR_R_ESYSTEM, ""));
+                       free(reqkey);
+                       return -1;
+               }
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+               g_variant_new("(is)", PKGMGR_R_OK, reqkey));
+
+       free(reqkey);
+       return 0;
+
+}
+
 static int __handle_request_enable_app(uid_t caller_uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
@@ -733,7 +1016,7 @@ static int __handle_request_enable_app(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_ENABLE_APP, "default",
-                               appid, NULL)) {
+                               appid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -777,7 +1060,7 @@ static int __handle_request_disable_app(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_DISABLE_APP, "default",
-                               appid, NULL)) {
+                               appid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -821,7 +1104,7 @@ static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
-                               "default", appid, NULL)) {
+                               "default", appid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -865,7 +1148,7 @@ static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
-                               "default", appid, NULL)) {
+                               "default", appid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                ret = -1;
@@ -909,7 +1192,7 @@ static int __handle_request_getsize(uid_t caller_uid,
 
        snprintf(buf, sizeof(buf), "%d", get_type);
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
-                               "pkgtool", pkgid, buf)) {
+                               "pkgtool", pkgid, buf, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                free(reqkey);
@@ -948,7 +1231,7 @@ static int __handle_request_getsize_sync(uid_t caller_uid,
 
        snprintf(buf, sizeof(buf), "%d", get_type);
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE_SYNC,
-                               "pkgtool", pkgid, buf)) {
+                               "pkgtool", pkgid, buf, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
                free(reqkey);
@@ -966,9 +1249,8 @@ static int __handle_request_cleardata(uid_t caller_uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
        uid_t target_uid = (uid_t)-1;
-       char *pkgtype;
        char *pkgid = NULL;
-       char *reqkey = NULL;
+       char *pkgtype;
 
        g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
        if (target_uid == (uid_t)-1 || pkgid == NULL) {
@@ -980,31 +1262,20 @@ static int __handle_request_cleardata(uid_t caller_uid,
        pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
        if (pkgtype == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ENOPKG));
-               return -1;
-       }
-
-       reqkey = __generate_reqkey(pkgid);
-       if (reqkey == NULL) {
-               g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
-               free(pkgtype);
+                               g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
                return -1;
        }
 
-       if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
-                               pkgtype, pkgid, NULL)) {
+       if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARDATA,
+                               pkgtype, pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
-               free(reqkey);
                free(pkgtype);
                return -1;
        }
 
        g_dbus_method_invocation_return_value(invocation,
                        g_variant_new("(i)", PKGMGR_R_OK));
-
-       free(reqkey);
        free(pkgtype);
 
        return 0;
@@ -1015,6 +1286,7 @@ static int __handle_request_clearcache(uid_t caller_uid,
 {
        uid_t target_uid = (uid_t)-1;
        char *pkgid = NULL;
+       char *pkgtype;
 
        g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
        if (target_uid == (uid_t)-1 || pkgid == NULL) {
@@ -1023,15 +1295,27 @@ static int __handle_request_clearcache(uid_t caller_uid,
                return -1;
        }
 
+       if (strcmp(PKG_CLEAR_ALL_CACHE, pkgid) == 0)
+               pkgtype = strdup("pkgtool");
+       else
+               pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
+       if (pkgtype == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
+               return -1;
+       }
+
        if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
-                               "pkgtool",  pkgid, NULL)) {
+                               pkgtype,  pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(pkgtype);
                return -1;
        }
 
        g_dbus_method_invocation_return_value(invocation,
                        g_variant_new("(i)", PKGMGR_R_OK));
+       free(pkgtype);
 
        return 0;
 }
@@ -1058,7 +1342,7 @@ static int __handle_request_kill(uid_t caller_uid,
        }
 
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
-                               "default", pkgid, NULL)) {
+                               "default", pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
                free(reqkey);
@@ -1094,7 +1378,7 @@ static int __handle_request_check(uid_t caller_uid,
        }
 
        if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
-                               "default", pkgid, NULL)) {
+                               "default", pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
                free(reqkey);
@@ -1131,7 +1415,7 @@ static int __handle_request_generate_license_request(uid_t caller_uid,
 
        if (_push_queue(caller_uid, caller_uid, reqkey,
                                REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
-                               "default", NULL, resp_data)) {
+                               "default", NULL, resp_data, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
                                        ""));
@@ -1168,7 +1452,7 @@ static int __handle_request_register_license(uid_t caller_uid,
 
        if (_push_queue(caller_uid, caller_uid, reqkey,
                                REQUEST_TYPE_REGISTER_LICENSE,
-                               "default", NULL, resp_data)) {
+                               "default", NULL, resp_data, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1207,7 +1491,7 @@ static int __handle_request_decrypt_package(uid_t caller_uid,
        if (_push_queue(caller_uid, caller_uid, reqkey,
                                REQUEST_TYPE_DECRYPT_PACKAGE,
                                "default", drm_file_path,
-                               decrypted_file_path)) {
+                               decrypted_file_path, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1246,7 +1530,7 @@ static int __update_app_splash_screen(uid_t caller_uid,
        }
 
        if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
-                               appid, NULL)) {
+                               appid, NULL, NULL)) {
                ERR("Failed to push request");
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
@@ -1303,7 +1587,7 @@ static int __handle_request_set_restriction_mode(uid_t caller_uid,
        snprintf(buf, sizeof(buf), "%d", mode);
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_SET_RESTRICTION_MODE,
-                               "default", pkgid, buf)) {
+                               "default", pkgid, buf, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1343,7 +1627,7 @@ static int __handle_request_unset_restriction_mode(uid_t caller_uid,
        snprintf(buf, sizeof(buf), "%d", mode);
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_UNSET_RESTRICTION_MODE,
-                               "default", pkgid, buf)) {
+                               "default", pkgid, buf, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1367,7 +1651,7 @@ static int __handle_request_get_restriction_mode(uid_t caller_uid,
        g_variant_get(parameters, "(us)", &target_uid, &pkgid);
        if (target_uid == (uid_t)-1 || pkgid == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+                               g_variant_new("(ii)", -1, PKGMGR_R_ECOMM));
                return -1;
        }
 
@@ -1380,7 +1664,7 @@ static int __handle_request_get_restriction_mode(uid_t caller_uid,
 
        if (_push_queue(target_uid, caller_uid, reqkey,
                                REQUEST_TYPE_GET_RESTRICTION_MODE,
-                               "default", pkgid, NULL)) {
+                               "default", pkgid, NULL, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1418,7 +1702,7 @@ static int __handle_request_set_app_label(uid_t uid,
 
        if (_push_queue(target_uid, uid, reqkey,
                                REQUEST_TYPE_SET_APP_LABEL,
-                               "default", appid, label)) {
+                               "default", appid, label, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
                free(reqkey);
@@ -1432,6 +1716,93 @@ static int __handle_request_set_app_label(uid_t uid,
        return 0;
 }
 
+static int __handle_request_set_app_icon(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *appid = NULL;
+       char *icon_path = NULL;
+       char *reqkey;
+
+       g_variant_get(parameters, "(uss)", &target_uid, &appid, &icon_path);
+       if (target_uid == (uid_t)-1 || appid == NULL || icon_path == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("app_icon");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               return -1;
+       }
+
+       if (_push_queue(target_uid, uid, reqkey,
+                               REQUEST_TYPE_SET_APP_ICON,
+                               "default", appid, icon_path, NULL)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(reqkey);
+               return -1;
+       }
+
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
+static int __handle_request_migrate_external_image(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *pkgid = NULL;
+       char *pkgtype;
+       char *reqkey;
+
+       g_variant_get(parameters, "(us)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
+       if (pkgtype == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOPKG));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey(pkgid);
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               free(pkgtype);
+               return -1;
+       }
+
+       if (_push_queue(target_uid, uid, reqkey,
+                               REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE,
+                               pkgtype, pkgid, NULL, NULL)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(reqkey);
+               free(pkgtype);
+               return -1;
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+                       g_variant_new("(i)", PKGMGR_R_OK));
+
+       free(reqkey);
+       free(pkgtype);
+
+       return 0;
+}
+
 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
 {
        GError *err = NULL;
@@ -1450,6 +1821,7 @@ static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
        }
 
        g_variant_get(result, "(u)", &uid);
+       g_variant_unref(result);
 
        return uid;
 }
@@ -1488,6 +1860,12 @@ static void __handle_method_call(GDBusConnection *connection,
                ret = __handle_request_enable_pkgs(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "disable_pkgs") == 0)
                ret = __handle_request_disable_pkgs(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "register_pkg_update_info") == 0)
+               ret = __handle_request_register_pkg_update_info(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "unregister_pkg_update_info") == 0)
+               ret = __handle_request_unregister_pkg_update_info(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "unregister_all_pkg_update_info") == 0)
+               ret = __handle_request_unregister_all_pkg_update_info(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "getsize") == 0)
                ret = __handle_request_getsize(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "getsize_sync") == 0)
@@ -1498,6 +1876,10 @@ static void __handle_method_call(GDBusConnection *connection,
                ret = __handle_request_enable_app(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "disable_app") == 0)
                ret = __handle_request_disable_app(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "enable_apps") == 0)
+               ret = __handle_request_enable_apps(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "disable_apps") == 0)
+               ret = __handle_request_disable_apps(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
                ret = __handle_request_enable_global_app_for_uid(uid,
                                invocation, parameters);
@@ -1534,6 +1916,11 @@ static void __handle_method_call(GDBusConnection *connection,
                                parameters);
        else if (g_strcmp0(method_name, "set_app_label") == 0)
                ret = __handle_request_set_app_label(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "set_app_icon") == 0)
+               ret = __handle_request_set_app_icon(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "migrate_external_image") == 0)
+               ret = __handle_request_migrate_external_image(uid, invocation,
+                               parameters);
        else
                ret = -1;