Add new pkgmar_installer_info API
[platform/core/appfw/slp-pkgmgr.git] / installer / pkgmgr_installer.c
index cd08e19..e9a0aa7 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <glib.h>
 #include <gio/gio.h>
+#include <tzplatform_config.h>
 
 #include "pkgmgr_installer.h"
 #include "pkgmgr_installer_config.h"
 
 #define OPTVAL_PRELOAD 1000
 #define OPTVAL_FORCE_REMOVAL 1001
+#define OPTVAL_PRELOAD_RW 1002
+#define OPTVAL_NO_REMOVAL 1003
+#define OPTVAL_KEEP_RWDATA 1004
+#define OPTVAL_PARTIAL_RW 1005
+#define OPTVAL_MIGRATE_EXTIMG 1006
 
 /* Supported options */
-const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:q";
+const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qG";
 const struct option long_opts[] = {
        { "session-id", 1, NULL, 'k' },
        { "license-path", 1, NULL, 'l' },
@@ -73,8 +79,14 @@ const struct option long_opts[] = {
        { "direct-manifest-install", 1, NULL, 'y' },
        { "mount-install", 1, NULL, 'w' },
        { "recovery", 1, NULL, 'b' },
-       { "preload", 0, NULL, OPTVAL_PRELOAD },
-       { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL },
+       { "debug-mode", 0, NULL, 'G' },
+       { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
+       { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
+       { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
+       { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
+       { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
+       { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
+       { "migrate-extimg", 1, NULL, OPTVAL_MIGRATE_EXTIMG },
        { 0, 0, 0, 0 }  /* sentinel */
 };
 
@@ -92,12 +104,19 @@ struct pkgmgr_installer {
        int is_tep_included;
        int is_preload;
        int force_removal;
+       int is_preload_rw;
+       int no_removal;
+       int keep_rwdata;
+       int partial_rw;
+       int debug_mode;
        GDBusConnection *conn;
 };
 
 static uid_t g_target_uid;
+static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN;
 
-static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
+static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
+               const char *pkg_type)
 {
        if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
                return key;
@@ -105,13 +124,19 @@ static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
                return key;
        else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
                return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
+       else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
+               return pkg_type;
 
        switch (pi->request_type) {
        case PKGMGR_REQ_INSTALL:
        case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
        case PKGMGR_REQ_MOUNT_INSTALL:
+       case PKGMGR_REQ_REINSTALL:
+       case PKGMGR_REQ_ENABLE_PKG:
+       case PKGMGR_REQ_RECOVER:
                return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
        case PKGMGR_REQ_UNINSTALL:
+       case PKGMGR_REQ_DISABLE_PKG:
                return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
        case PKGMGR_REQ_UPGRADE:
                return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
@@ -125,6 +150,10 @@ static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
                return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
        case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
                return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
+       case PKGMGR_REQ_CLEAR:
+               return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
+       case PKGMGR_REQ_GETSIZE:
+               return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
        }
 
        ERR("cannot find type");
@@ -132,42 +161,9 @@ static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
        return NULL;
 }
 
-static int __send_signal_for_app_event(pkgmgr_installer *pi, const char *pkg_type,
-               const char *pkgid, const char *appid, const char *key, const char *val)
-{
-       char *sid;
-       const char *name;
-       GError *err = NULL;
-
-       if (!pi || pi->conn == NULL || appid == NULL)
-               return -1;
-
-       sid = pi->session_id;
-       if (!sid)
-               sid = "";
-
-       name = __get_signal_name(pi, key);
-       if (name == NULL) {
-               ERR("unknown signal type");
-               return -1;
-       }
-
-       if (g_dbus_connection_emit_signal(pi->conn, NULL,
-                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
-                               PKGMGR_INSTALLER_DBUS_INTERFACE, name,
-                               g_variant_new("(ussssss)", pi->target_uid, sid,
-                                       pkg_type, pkgid, appid, key, val), &err)
-                       != TRUE) {
-               ERR("failed to send dbus signal: %s", err->message);
-               g_error_free(err);
-               return -1;
-       }
-
-       return 0;
-}
-
 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
-               const char *pkgid, const char *key, const char *val)
+               const char *pkgid, const char *appid, const char *key,
+               const char *val)
 {
        char *sid;
        const char *name;
@@ -180,7 +176,7 @@ static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
        if (!sid)
                sid = "";
 
-       name = __get_signal_name(pi, key);
+       name = __get_signal_name(pi, key, pkg_type);
        if (name == NULL) {
                ERR("unknown signal type");
                return -1;
@@ -190,7 +186,8 @@ static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
                                PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
                                PKGMGR_INSTALLER_DBUS_INTERFACE, name,
                                g_variant_new("(ussssss)", pi->target_uid, sid,
-                                       pkg_type, pkgid, "", key, val), &err)
+                                       pkg_type, pkgid, appid ? appid : "",
+                                       key, val), &err)
                        != TRUE) {
                ERR("failed to send dbus signal: %s", err->message);
                g_error_free(err);
@@ -222,7 +219,7 @@ static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
                return -1;
        }
 
-       r = send(fd, data, len, 0);
+       r = send(fd, data, len, MSG_NOSIGNAL);
        if (r < 0) {
                ERR("failed to send data: %d", errno);
                close(fd);
@@ -234,8 +231,7 @@ static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
        return 0;
 }
 
-/* TODO: it should be refactored */
-static int __send_app_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
+static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
                const char *pkg_type, const char *pkgid, const char *appid,
                const char *key, const char *val)
 {
@@ -258,7 +254,7 @@ static int __send_app_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
 
        data_len = sizeof(size_t) + sizeof(gsize);
 
-       name = __get_signal_name(pi, key);
+       name = __get_signal_name(pi, key, pkg_type);
        if (name == NULL) {
                ERR("unknown signal type");
                return -1;
@@ -268,70 +264,11 @@ static int __send_app_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
        data_len += name_size;
 
        gv = g_variant_new("(ussssss)", pi->target_uid, sid,
-                       pkg_type, pkgid, appid, key, val);
-       gv_len = g_variant_get_size(gv);
-       gv_data = g_malloc(gv_len);
-       g_variant_store(gv, gv_data);
-       g_variant_unref(gv);
-       data_len += gv_len;
-
-       data = malloc(data_len);
-       ptr = data;
-       memcpy(ptr, &name_size, sizeof(size_t));
-       ptr += sizeof(size_t);
-       memcpy(ptr, &gv_len, sizeof(gsize));
-       ptr += sizeof(gsize);
-       memcpy(ptr, name, name_size);
-       ptr += name_size;
-       memcpy(ptr, gv_data, gv_len);
-
-       if (__send_signal_to_agent(uid, data, data_len)) {
-               ERR("failed to send signal to agent");
-               g_free(data);
+                       pkg_type, pkgid, appid ? appid : "", key, val);
+       if (gv == NULL) {
+               ERR("failed to create GVariant instance");
                return -1;
        }
-
-       g_free(gv_data);
-       free(data);
-
-       return 0;
-}
-
-/* TODO: it should be refactored */
-static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
-               const char *pkg_type, const char *pkgid,
-               const char *key, const char *val)
-{
-       char *sid;
-       const char *name;
-       size_t name_size;
-       GVariant *gv;
-       gsize gv_len;
-       gpointer gv_data;
-       void *data;
-       void *ptr;
-       size_t data_len;
-
-       if (!pi || pi->conn == NULL)
-               return -1;
-
-       sid = pi->session_id;
-       if (!sid)
-               sid = "";
-
-       data_len = sizeof(size_t) + sizeof(gsize);
-
-       name = __get_signal_name(pi, key);
-       if (name == NULL) {
-               ERR("unknown signal type");
-               return -1;
-       }
-       /* including null byte */
-       name_size = strlen(name) + 1;
-       data_len += name_size;
-
-       gv = g_variant_new("(ussssss)", pi->target_uid, sid,
-                       pkg_type, pkgid, "", key, val);
        gv_len = g_variant_get_size(gv);
        gv_data = g_malloc(gv_len);
        g_variant_store(gv, gv_data);
@@ -347,14 +284,14 @@ static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
        memcpy(ptr, name, name_size);
        ptr += name_size;
        memcpy(ptr, gv_data, gv_len);
+       g_free(gv_data);
 
        if (__send_signal_to_agent(uid, data, data_len)) {
                ERR("failed to send signal to agent");
-               g_free(data);
+               free(data);
                return -1;
        }
 
-       g_free(gv_data);
        free(data);
 
        return 0;
@@ -455,6 +392,35 @@ pkgmgr_installer_receive_request(pkgmgr_installer *pi,
                        pi->force_removal = 1;
                        DBG("force-remove request [%d]", pi->force_removal);
                        break;
+               case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
+                       pi->is_preload_rw = 1;
+                       DBG("preload-rw request [%d]", pi->is_preload_rw);
+                       break;
+               case OPTVAL_NO_REMOVAL: /* request for no-remove */
+                       pi->no_removal = 1;
+                       DBG("no-remove request [%d]", pi->no_removal);
+                       break;
+               case OPTVAL_KEEP_RWDATA:        /* request for keep-rwdata */
+                       pi->keep_rwdata = 1;
+                       DBG("keep-rwdata request [%d]", pi->keep_rwdata);
+                       break;
+               case OPTVAL_PARTIAL_RW: /* request for partial-rw */
+                       pi->partial_rw = 1;
+                       DBG("partial-rw request [%d]", pi->partial_rw);
+                       break;
+               case OPTVAL_MIGRATE_EXTIMG:
+                       /* request for legacy extimg migration */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = OPTVAL_MIGRATE_EXTIMG;
+                       pi->request_type = PKGMGR_REQ_MIGRATE_EXTIMG;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       DBG("legacy extimg migration requested");
+                       break;
                case 'k':       /* session id */
                        if (pi->session_id)
                                free(pi->session_id);
@@ -619,6 +585,10 @@ pkgmgr_installer_receive_request(pkgmgr_installer *pi,
                        pi->target_uid = (uid_t)atoi(optarg);
                        break;
 
+               case 'G': /* debug mode */
+                       pi->debug_mode = 1;
+                       break;
+
                        /* Otherwise */
                case '?':       /* Not an option */
                        break;
@@ -629,6 +599,11 @@ pkgmgr_installer_receive_request(pkgmgr_installer *pi,
                }
        }
 
+       /* if target user is not set, set as tizenglobalapp user */
+       if (pi->target_uid == 0) {
+               pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+               g_target_uid = pi->target_uid;
+       }
  RET:
        return r;
 }
@@ -710,13 +685,53 @@ API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
        return pi->force_removal;
 }
 
+API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->is_preload_rw;
+}
+
+API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->no_removal;
+}
+
+API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->keep_rwdata;
+}
+
+API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->partial_rw;
+}
+
+API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->debug_mode;
+}
+
 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
                             const char *pkg_type,
                             const char *pkgid,
                             const char *val)
 {
        int ret = 0;
-       ret = __send_signal_for_event(pi, pkg_type, pkgid,
+       ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
+                       PKGMGR_INSTALLER_APPID_KEY_STR, val);
+       return ret;
+}
+
+API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
+               pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
+               const char *pkgid, const char *val)
+{
+       int ret = 0;
+       ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
                        PKGMGR_INSTALLER_APPID_KEY_STR, val);
        return ret;
 }
@@ -746,7 +761,7 @@ pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
                return -1;
        }
 
-       r = __send_signal_for_app_event(pi, pkg_type, pkgid, appid, key, val);
+       r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
 
        return r;
 }
@@ -768,7 +783,7 @@ pkgmgr_installer_send_signal(pkgmgr_installer *pi,
                        strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
                pi->request_type = PKGMGR_REQ_UPGRADE;
 
-       r = __send_signal_for_event(pi, pkg_type, pkgid, key, val);
+       r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
 
        return r;
 }
@@ -784,7 +799,8 @@ API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
                return -1;
        }
 
-       r = __send_app_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid, key, val);
+       r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
+                       key, val);
 
        return r;
 }
@@ -804,7 +820,8 @@ API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
                        strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
                pi->request_type = PKGMGR_REQ_UPGRADE;
 
-       r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, key, val);
+       r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
+                       key, val);
 
        return r;
 }
@@ -862,9 +879,23 @@ API int pkgmgr_installer_delete_certinfo(const char *pkgid)
        return ret;
 }
 
+API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level)
+{
+       g_privilege_level = level;
+
+       return 0;
+}
+
 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
 {
        *uid = g_target_uid;
 
        return 0;
 }
+
+API int pkgmgr_installer_info_get_privilege_level(pkgmgr_privilege_level *level)
+{
+       *level = g_privilege_level;
+
+       return 0;
+}