fix pkg move behavior 46/78446/4 accepted/tizen/common/20160706.141859 accepted/tizen/ivi/20160706.014245 accepted/tizen/mobile/20160706.014207 accepted/tizen/tv/20160706.014221 accepted/tizen/wearable/20160706.014233 submit/tizen/20160705.114429
authorjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 5 Jul 2016 12:57:43 +0000 (21:57 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 5 Jul 2016 13:53:32 +0000 (22:53 +0900)
kill apps and umount image when sdcard is removed

Change-Id: I120edd133e3c349ae1e4dfce512975436e6c48ad
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
inc/app2ext_interface.h
packaging/app2sd.spec
plugin/app2sd/CMakeLists.txt
plugin/app2sd/inc/app2sd_internals.h
plugin/app2sd/src/app2sd_client_interface.c
plugin/app2sd/src/app2sd_interface.c
plugin/app2sd/src/app2sd_internals.c
plugin/app2sd/src/app2sd_internals_registry.c
src/app2ext_interface.c

index 45743ce..7bcf819 100644 (file)
@@ -156,6 +156,7 @@ typedef enum app2ext_error_t {
        APP2EXT_ERROR_OPERATION_NOT_PERMITTED,
        APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS,
        APP2EXT_ERROR_PKGMGR_ERROR,
+       APP2EXT_ERROR_KILLAPP_ERROR,
 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
        APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE,
        APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE,
index 61e8bde..6d7826e 100644 (file)
@@ -15,6 +15,7 @@ BuildRequires:  pkgconfig(minizip)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(aul)
 BuildRequires:  cmake
 
 %description
index 1545c32..0adce49 100644 (file)
@@ -3,7 +3,7 @@ PROJECT(app2sd C)
 
 ### Required packages
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED libssl dlog openssl pkgmgr-info libtzplatform-config gio-2.0 glib-2.0 minizip)
+pkg_check_modules(pkgs REQUIRED libssl dlog openssl pkgmgr-info libtzplatform-config gio-2.0 glib-2.0 minizip aul)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index 9da353c..7fbf09f 100644 (file)
@@ -171,6 +171,10 @@ int _app2sd_set_info_in_db(const char *pkgid, const char *passwd,
 
 int _app2sd_get_info_from_db(const char *filename, char **pkgid, uid_t *uid);
 
+typedef int (*app2sd_info_cb)(const char *pkgid, uid_t uid);
+
+int _app2sd_get_foreach_info_from_db(app2sd_info_cb cb_func);
+
 int _app2sd_force_clean(const char *pkgid, const char *application_path,
                const char *loopback_device, uid_t uid);
 
index 852e6fe..c861215 100644 (file)
@@ -27,6 +27,8 @@
 #include <sys/wait.h>
 #include <gio/gio.h>
 
+#include <pkgmgr-info.h>
+
 #include "app2sd_client_interface.h"
 #include "app2ext_utils.h"
 
@@ -503,6 +505,8 @@ int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list,
        GVariantBuilder *builder = NULL;
        GVariant *param = NULL;
        app2sd_cmd cmd = APP2SD_MOVE_APP_TO_PHONE;
+       pkgmgrinfo_pkginfo_h info_handle = NULL;
+       pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
 
        /* validate the function parameter recieved */
        if (pkgid == NULL || dir_list == NULL
@@ -512,6 +516,30 @@ int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list,
                return APP2EXT_ERROR_INVALID_ARGUMENTS;
        }
 
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
+       if (ret < 0) {
+               _E("failed to get pkginfo for pkg(%s), uid(%d), ret(%d)",
+                       pkgid, uid, ret);
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+       ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
+       if (ret < 0) {
+               _E("failed to get installed storage for pkg(%s) of uid(%d), ret(%d)",
+                       pkgid, uid, ret);
+               pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+
+       if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
+               || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
+                       _E("PKG_EXISTS in [%d] STORAGE", storage);
+                       pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
+                       return APP2EXT_ERROR_PKG_EXISTS;
+       } else {
+               _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
+       }
+       pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
+
        if (move_type == APP2EXT_MOVE_TO_EXT)
                cmd = APP2SD_MOVE_APP_TO_MMC;
 
index d7144fd..2991b8b 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <pkgmgr-info.h>
+#include <aul.h>
 
 #include "app2sd_internals.h"
 
@@ -449,6 +450,67 @@ int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
        return ret;
 }
 
+static int _app2sd_application_handler(const pkgmgrinfo_appinfo_h handle, void *data)
+{
+       int ret = 0;
+       int pid = 0;
+       char *appid = NULL;
+       uid_t uid = *(uid_t *)data;
+
+       ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+       if (ret < 0) {
+               _E("failed to get appid");
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+
+       _D("appid(%s), uid(%d)", appid, uid);
+
+       ret = aul_app_is_running_for_uid(appid, uid);
+       if (ret == 0)
+               return APP2EXT_SUCCESS;
+
+       pid = aul_app_get_pid_for_uid(appid, uid);
+       if (pid < 0) {
+               _E("failed to get pid");
+               return APP2EXT_ERROR_KILLAPP_ERROR;
+       }
+
+       ret = aul_terminate_pid_sync_for_uid(pid, uid);
+       if (ret != AUL_R_OK) {
+               _E("failed to kill app");
+               return APP2EXT_ERROR_KILLAPP_ERROR;
+       }
+
+       return APP2EXT_SUCCESS;
+}
+
+static int _app2sd_kill_running_app(const char *pkgid, uid_t uid)
+{
+       int ret = 0;
+       pkgmgrinfo_pkginfo_h handle;
+
+       ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
+       if (ret < 0) {
+               _E("failed to get pkginfo");
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+
+       ret = pkgmgrinfo_appinfo_get_usr_list(handle,
+               PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid);
+       if (ret < 0) {
+               _E("failed to get appinfo");
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+
+       ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+       if (ret < 0) {
+               _E("failed to destroy pkginfo");
+               return APP2EXT_ERROR_PKGMGR_ERROR;
+       }
+
+       return APP2EXT_SUCCESS;
+}
+
 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
 {
        int ret = APP2EXT_SUCCESS;
@@ -456,6 +518,7 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
        char loopback_device[FILENAME_MAX] = { 0, };
        char *encoded_id = NULL;
        FILE *fp = NULL;
+       int mmc_present = 1;
 
        /* validate the function parameter recieved */
        if (pkgid == NULL) {
@@ -463,11 +526,13 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
                return APP2EXT_ERROR_INVALID_ARGUMENTS;
        }
 
+       _app2sd_kill_running_app(pkgid, uid);
+
        /* check whether MMC is present or not */
        ret = _app2sd_check_mmc_status();
        if (ret) {
-               _E("MMC not preset OR Not ready (%d)", ret);
-               return APP2EXT_ERROR_MMC_STATUS;
+               _W("MMC not preset OR Not ready (%d)", ret);
+               mmc_present = 0;
        }
 
        encoded_id = _app2sd_get_encoded_name(pkgid, uid);
@@ -490,12 +555,14 @@ int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
        }
        free(encoded_id);
 
-       fp = fopen(loopback_device, "r+");
-       if (fp == NULL) {
-               _E("app entry is not present in SD Card");
-               return APP2EXT_ERROR_INVALID_PACKAGE;
+       if (mmc_present) {
+               fp = fopen(loopback_device, "r+");
+               if (fp == NULL) {
+                       _E("app entry is not present in SD Card");
+                       return APP2EXT_ERROR_INVALID_PACKAGE;
+               }
+               fclose(fp);
        }
-       fclose(fp);
 
        ret = _app2sd_unmount_app_content(application_path);
        if (ret) {
@@ -748,32 +815,6 @@ int app2sd_usr_pre_move_installed_app(const char *pkgid,
                return APP2EXT_ERROR_INVALID_ARGUMENTS;
        }
 
-       pkgmgrinfo_pkginfo_h info_handle = NULL;
-       pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
-       pkgmgr_ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
-       if (pkgmgr_ret < 0) {
-               _E("failed to get pkginfo for pkg(%s), uid(%d), pkgmgr_ret(%d)",
-                       pkgid, uid, pkgmgr_ret);
-               return APP2EXT_ERROR_PKGMGR_ERROR;
-       }
-       pkgmgr_ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
-       if (pkgmgr_ret < 0) {
-               _E("failed to get installed storage for pkg(%s) of uid(%d), pkgmgr_ret(%d)",
-                       pkgid, uid, pkgmgr_ret);
-               pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
-               return APP2EXT_ERROR_PKGMGR_ERROR;
-       }
-
-       if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
-               || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
-                       _E("PKG_EXISTS in [%d] STORAGE", storage);
-                       pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
-                       return APP2EXT_ERROR_PKG_EXISTS;
-       } else {
-               _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
-       }
-       pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
-
        ret = __app2sd_create_app2sd_directories(uid);
        if (ret) {
                _E("failed to create app2sd dirs");
@@ -1230,8 +1271,8 @@ int app2sd_enable_full_pkg(void)
 
        dir = opendir(APP2SD_PATH);
        if (!dir) {
-               if (strerror_r(errno, buf, sizeof(buf)) == 0)
-                       _E("failed to opendir (%s)", buf);
+               strerror_r(errno, buf, sizeof(buf));
+               _E("failed to opendir (%s)", buf);
                return APP2EXT_ERROR_OPEN_DIR;
        }
 
@@ -1256,15 +1297,13 @@ int app2sd_enable_full_pkg(void)
                        _E("failed to get info from db");
                        break;;
                }
-               if (pkgid && uid > 0) {
+               if (pkgid) {
                        _D("pkgid(%s), uid(%d)", pkgid, uid);
                        ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
                        if (ret) {
                                _E("error(%d)", ret);
                                break;
                        }
-               }
-               if (pkgid) {
                        free(pkgid);
                        pkgid = NULL;
                }
@@ -1279,65 +1318,33 @@ int app2sd_enable_full_pkg(void)
        return ret;
 }
 
-int app2sd_disable_full_pkg(void)
+static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
 {
        int ret = APP2EXT_SUCCESS;
-       int rc = 0;
-       char buf[FILENAME_MAX] = { 0, };
-       char loopback_device[FILENAME_MAX] = { 0, };
-       DIR *dir = NULL;
-       struct dirent entry;
-       struct dirent *result = NULL;
-       char *pkgid = NULL;
-       uid_t uid = 0;
 
-       dir = opendir(APP2SD_PATH);
-       if (!dir) {
-               if (strerror_r(errno, buf, sizeof(buf)) == 0)
-                       _E("failed to opendir (%s)", buf);
-               return APP2EXT_ERROR_OPEN_DIR;
+       if (pkgid) {
+               _D("pkgid(%s), uid(%d)", pkgid, uid);
+               ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
+               if (ret)
+                       _E("error(%d)", ret);
        }
 
+       return ret;
+}
+
+int app2sd_disable_full_pkg(void)
+{
+       int ret = APP2EXT_SUCCESS;
+
        ret = _app2sd_initialize_db();
        if (ret) {
                _E("app2sd db initialize failed");
-               closedir(dir);
                return APP2EXT_ERROR_SQLITE_REGISTRY;
        }
 
-       for (rc = readdir_r(dir, &entry, &result);
-               rc == 0 && result != NULL;
-               rc = readdir_r(dir, &entry, &result)) {
-               if (strcmp(entry.d_name, ".") == 0 ||
-                       strcmp(entry.d_name, "..") == 0)
-                       continue;
-               snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
-                       APP2SD_PATH, entry.d_name);
-               ret = _app2sd_get_info_from_db(loopback_device,
-                       &pkgid, &uid);
-               if (ret) {
-                       _E("failed to get info from db");
-                       break;
-               }
-               if (pkgid && uid > 0) {
-                       _D("pkgid(%s), uid(%d)", pkgid, uid);
-                       ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
-                       if (ret) {
-                               _E("error(%d)", ret);
-                               break;
-                       }
-               }
-               if (pkgid) {
-                       free(pkgid);
-                       pkgid = NULL;
-               }
-       }
-
-       if (pkgid) {
-               free(pkgid);
-               pkgid = NULL;
-       }
-       closedir(dir);
+       ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
+       if (ret)
+               _E("disable full pkg error(%d)", ret);
 
        return ret;
 }
index 58f6f67..9b336cc 100644 (file)
@@ -789,24 +789,21 @@ int _app2sd_mount_app_content(const char *application_path, const char *pkgid,
                break;
        }
 
-       if (cmd == APP2SD_PRE_UNINSTALL || cmd == APP2SD_MOVE_APP_TO_PHONE ||
-               cmd == APP2SD_PRE_UPGRADE) {
-               /* delete lost+found dir */
-               snprintf(temp_path, FILENAME_MAX - 1, "%s/lost+found",
-                       application_mmc_path);
-               ret = _app2sd_delete_directory(temp_path);
-               if (ret) {
-                       _E("unable to delete (%s)", temp_path);
-                       return APP2EXT_ERROR_DELETE_DIRECTORY;
-               }
-       }
-
        if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC ||
                cmd == APP2SD_PRE_UPGRADE) {
                ret = _app2sd_create_directory_entry(application_path,
                        pkgid, dir_list, uid);
        }
 
+       /* change lost+found permission */
+       snprintf(temp_path, FILENAME_MAX - 1, "%s/lost+found",
+                       application_mmc_path);
+       ret = _app2sd_make_directory(temp_path, uid);
+       if (ret) {
+               _E("create directory(%s) failed", temp_path);
+               return APP2EXT_ERROR_CREATE_DIRECTORY;
+       }
+
        return ret;
 }
 
@@ -910,6 +907,15 @@ int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list, uid_t uid)
        snprintf(application_archive_path, FILENAME_MAX - 1, "%s/.archive",
                application_path);
 
+       ret = mkdir(application_mmc_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       _E("unable to create directory for archiving," \
+                               " error(%d)", errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+
        ret = mkdir(application_archive_path, mode);
        if (ret) {
                if (errno != EEXIST) {
index 14e1c02..c235889 100644 (file)
@@ -236,6 +236,48 @@ FINISH_OFF:
        return ret;
 }
 
+int _app2sd_get_foreach_info_from_db(app2sd_info_cb cb_func)
+{
+       char *query = NULL;
+       sqlite3_stmt *stmt = NULL;
+       const char *pkgid = NULL;
+       int uid = 0;
+       int ret = 0;
+
+       query = sqlite3_mprintf("select * from app2sd_info");
+       if (query == NULL) {
+               _E("failed to make a query");
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+
+       ret = sqlite3_prepare_v2(app2sd_db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _E("prepare failed (%s)", sqlite3_errmsg(app2sd_db));
+               sqlite3_free(query);
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+
+       ret = APP2EXT_SUCCESS;
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               pkgid = (const char *)sqlite3_column_text(stmt, 0);
+               uid = sqlite3_column_int(stmt, 3);
+
+               ret = cb_func(pkgid, (uid_t)uid);
+               if (ret) {
+                       _E("app2sd info callback error");
+                       break;
+               }
+       }
+
+       if (SQLITE_OK != sqlite3_finalize(stmt)) {
+               _E("error : sqlite3_finalize");
+               ret = APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       sqlite3_free(query);
+
+       return ret;
+}
+
 char *_app2sd_get_password_from_db(const char *pkgid, uid_t uid)
 {
        char *query = NULL;
index e16289a..4776f87 100644 (file)
@@ -105,6 +105,9 @@ int app2ext_deinit(app2ext_handle *handle)
        return 0;
 }
 
+/* use this api only to check external related file existing,
+ * such as .mmc directory and image file under /sdcard/app2sd.
+ */
 int app2ext_usr_get_app_location(const char *pkgid, uid_t uid)
 {
        FILE *fp = NULL;