Handle installing preload-ro and preload-rw pks with same pkgid 61/316761/3
authorSangyoon Jang <jeremy.jang@samsung.com>
Wed, 28 Aug 2024 00:50:27 +0000 (09:50 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Wed, 11 Sep 2024 06:33:57 +0000 (06:33 +0000)
Same pkgid in both ro and rw with version:
- RO = RW -> install RO only
- RO > RW -> install RO only
- RO < RW -> install RO and RW (RO-updated)

Change-Id: I87632def74d41e49bf13e8c8fe18474eb92933d0
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/install_preload_pkg/CMakeLists.txt
src/install_preload_pkg/install_preload_pkg.c

index 943f6c29d609639f7498ae6896f478b16c94070f..c208de3b7e7f6d525a947321fe5c7370a961c220 100644 (file)
@@ -10,6 +10,7 @@ ADD_EXECUTABLE(${TARGET_INSTALL_PRELOAD_PKG} ${SRCS})
 APPLY_PKG_CONFIG(${TARGET_INSTALL_PRELOAD_PKG} PUBLIC
   TZPLATFORM_DEPS
   PKGMGR_DEPS
+  PKGMGR_INFO_DEPS
   GLIB_DEPS
 )
 
index 32dbda50ef6b7733ab04b0436fd0734ad6cb0e9b..8ad3f5abb66ac401375d73f3525d63cb01e4356c 100644 (file)
@@ -31,6 +31,7 @@
 #include <glib.h>
 #include <getopt.h>
 
+#include <pkgmgr-info.h>
 #include <tzplatform_config.h>
 
 #include "package-manager.h"
@@ -85,6 +86,8 @@ struct pkginfo {
 
 typedef struct pkgfile_info {
        char *path;
+       char *pkgid;
+       char *version;
        char *backend_type;
        install_type install_type;
        bool skip_check_reference;
@@ -93,11 +96,14 @@ typedef struct pkgfile_info {
 
 GList *pkgfile_info_list;
 GList *rw_pkgfile_info_list;
+GList *duplicated_rw_pkgfile_info_list;
 
 static void __free_pkgfile_info_list(gpointer data)
 {
        pkgfile_info *info = (pkgfile_info *)data;
        free(info->path);
+       free(info->pkgid);
+       free(info->version);
        free(info->backend_type);
        free(info);
 }
@@ -151,6 +157,7 @@ static int _add_pkgfile_info(GList **list, const char *backend,
        pkgfile_info *pkgfile;
        int ret = 0;
        FILE *fp;
+       package_manager_pkg_detail_info_t *pkg_info;
 
        if (directory == NULL || type == INSTALL_TYPE_UNDEFINED)
                return -1;
@@ -212,6 +219,32 @@ static int _add_pkgfile_info(GList **list, const char *backend,
                pkgfile->pkg_size = ftell(fp);
                fclose(fp);
 
+               pkg_info = pkgmgr_client_check_pkginfo_from_file(pkgfile->path);
+               if (pkg_info == NULL) {
+                       _E("can not get pkg_info from [%s]\n", pkgfile->path);
+                       continue;
+               }
+
+               pkgfile->pkgid = strdup(pkg_info->pkgid);
+               if (pkgfile->pkgid == NULL) {
+                       _E("Out of memory\n");
+                       pkgmgr_client_free_pkginfo(pkg_info);
+                       __free_pkgfile_info_list((gpointer)pkgfile);
+                       closedir(dir);
+                       return -1;
+               }
+
+               pkgfile->version = strdup(pkg_info->version);
+               if (pkgfile->version == NULL) {
+                       _E("Out of memory\n");
+                       pkgmgr_client_free_pkginfo(pkg_info);
+                       __free_pkgfile_info_list((gpointer)pkgfile);
+                       closedir(dir);
+                       return -1;
+               }
+
+               pkgmgr_client_free_pkginfo(pkg_info);
+
                *list = g_list_prepend(*list, pkgfile);
        }
 
@@ -234,11 +267,68 @@ static gint __pkgfileinfo_compare(gconstpointer a, gconstpointer b)
                return 0;
 }
 
+static gint __compare_pkgid(gconstpointer data1, gconstpointer data2)
+{
+       struct pkgfile_info *info1 = (struct pkgfile_info *)data1;
+       struct pkgfile_info *info2 = (struct pkgfile_info *)data2;
+       return strcmp(info1->pkgid, info2->pkgid);
+}
+
+static int __should_install_rw_pkg(struct pkgfile_info *rw, pkgfile_info *ro)
+{
+       int ret;
+       pkgmgrinfo_version_compare_type result;
+
+       ret = pkgmgrinfo_compare_package_version(rw->version, ro->version,
+                       &result);
+       if (ret != PMINFO_R_OK) {
+               _E("Failed to compare package version [%s] and [%s]\n",
+                               rw->path, ro->path);
+               return -1;
+       }
+
+       if (result == PMINFO_VERSION_SAME)
+               return 0;
+       /* ro->version is higher than rw->version */
+       else if (result == PMINFO_VERSION_NEW)
+               return 0;
+       else
+               return 1;
+}
+
+static void _find_duplicated_rw_pkgfile_info(void)
+{
+       GList *iter = rw_pkgfile_info_list;
+       GList *next;
+       GList *ro_iter;
+
+       while (iter != NULL) {
+               next = iter->next;
+               ro_iter = g_list_find_custom(pkgfile_info_list, iter->data,
+                               __compare_pkgid);
+               /* found same pkgid in preload tpk(RO) */
+               if (ro_iter != NULL) {
+                       rw_pkgfile_info_list = g_list_remove_link(
+                                       rw_pkgfile_info_list, iter);
+                       if (__should_install_rw_pkg(iter->data, ro_iter->data))
+                               duplicated_rw_pkgfile_info_list = g_list_concat(
+                                               duplicated_rw_pkgfile_info_list,
+                                               iter);
+                       else
+                               g_list_free_full(iter, __free_pkginfo);
+               }
+               iter = next;
+       }
+}
+
 static void _sort_pkgfile_info_list() {
        pkgfile_info_list = g_list_sort(pkgfile_info_list, __pkgfileinfo_compare);
        rw_pkgfile_info_list = g_list_sort(rw_pkgfile_info_list, __pkgfileinfo_compare);
+       _find_duplicated_rw_pkgfile_info();
         pkgfile_info_list = g_list_concat(rw_pkgfile_info_list, pkgfile_info_list);
         rw_pkgfile_info_list = NULL;
+       pkgfile_info_list = g_list_concat(pkgfile_info_list, duplicated_rw_pkgfile_info_list);
+       duplicated_rw_pkgfile_info_list = NULL;
 }
 
 static int _install_pkg_with_pkginfo()
@@ -454,7 +544,9 @@ int main(int argc, char *argv[])
                        goto error;
 
                /* sort pkgfile_info_list and rw_pkgfile_info_list first,
-                * and concat rw_pkgfile_info_list to pkgfile_info_list
+                * and concat rw_pkgfile_info_list to pkgfile_info_list.
+                * if there are pkgs that has same pkgid and higer version
+                * in both list, rw one will be installed later.
                 */
                _sort_pkgfile_info_list();