Fix a bug on processing system packages 18/136418/12
authorSangyoon Jang <jeremy.jang@samsung.com>
Thu, 29 Jun 2017 10:15:06 +0000 (19:15 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Fri, 7 Jul 2017 07:12:32 +0000 (07:12 +0000)
- ReadonlyUpdateUninstall will be triggered when the package is 'system'
  and 'update' package.
- Non-removable preload package will be a non-system package after updated.

Change-Id: I6266cc8894a85bedd4e870e02357d55ad4428150
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/common/pkgmgr_interface.cc
src/common/pkgmgr_query.cc
src/common/pkgmgr_query.h
src/common/pkgmgr_registration.cc
src/common/step/configuration/step_parse_manifest.cc
src/common/step/configuration/step_parse_preload.cc

index bce8829..a001fb6 100644 (file)
@@ -169,8 +169,9 @@ RequestType PkgMgrInterface::GetRequestType() const {
     case PKGMGR_REQ_UNINSTALL: {
       std::string pkgid = GetRequestInfo();
       uid_t uid = GetUid();
-      if (QueryIsReadonlyPackage(pkgid, uid) &&
-          QueryIsUpdatedPackage(pkgid, uid))
+      if (QueryIsSystemPackage(pkgid, uid) &&
+          QueryIsUpdatedPackage(pkgid, uid) &&
+          QueryIsRemovablePackage(pkgid, uid))
         return RequestType::ReadonlyUpdateUninstall;
       else if (GetIsPreloadRequest() && GetIsPartialRW())
         return RequestType::PartialUninstall;
index 124d699..3d46480 100644 (file)
@@ -315,4 +315,44 @@ bool QueryIsPreloadPackage(const std::string& pkg_id, uid_t uid) {
   return is_preload;
 }
 
+bool QueryIsSystemPackage(const std::string& pkg_id, uid_t uid) {
+  pkgmgrinfo_pkginfo_h handle;
+  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &handle);
+  if (ret != PMINFO_R_OK) {
+    if (ret != PMINFO_R_ENOENT)
+      LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_pkginfo";
+    return false;
+  }
+
+  bool is_system = false;
+  if (pkgmgrinfo_pkginfo_is_system(handle, &is_system) != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_is_system failed";
+    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+    return false;
+  }
+
+  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+  return is_system;
+}
+
+bool QueryIsRemovablePackage(const std::string& pkg_id, uid_t uid) {
+  pkgmgrinfo_pkginfo_h handle;
+  int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid, &handle);
+  if (ret != PMINFO_R_OK) {
+    if (ret != PMINFO_R_ENOENT)
+      LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_pkginfo";
+    return false;
+  }
+
+  bool is_removable = false;
+  if (pkgmgrinfo_pkginfo_is_removable(handle, &is_removable) != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_is_removable failed";
+    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+    return false;
+  }
+
+  pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+  return is_removable;
+}
+
 }  // namespace common_installer
index 4038b46..c3d8ccc 100644 (file)
@@ -162,6 +162,28 @@ bool QueryIsUpdatedPackage(const std::string& pkg_id, uid_t uid);
  */
 bool QueryIsPreloadPackage(const std::string& pkg_id, uid_t uid);
 
+/**
+ * \brief Adapter interface for external PkgMgr module used for checking
+ *        if given package is system package
+ *
+ * \param pkg_id package id
+ * \param uid user id
+ *
+ * \return true if package is system package
+ */
+bool QueryIsSystemPackage(const std::string& pkg_id, uid_t uid);
+
+/**
+ * \brief Adapter interface for external PkgMgr module used for checking
+ *        if given package is removable package
+ *
+ * \param pkg_id package id
+ * \param uid user id
+ *
+ * \return true if package is removable package
+ */
+bool QueryIsRemovablePackage(const std::string& pkg_id, uid_t uid);
+
 }  // namespace common_installer
 
 #endif  // COMMON_PKGMGR_QUERY_H_
index 827c9ee..0287969 100644 (file)
@@ -76,29 +76,6 @@ bool RegisterCertificates(
   return true;
 }
 
-// "preload" : pre-installed package at the first boot state.
-//             this package exists in both readonly and readwrite.
-// "system" : this package is "preload" and is not removable.
-// "update" : this package is "preload" and is updated by downloadable update.
-// "removable" : this package can be removed.
-// "readonly" : this package exists in readonly location.
-bool AssignPackageTags(manifest_x* manifest) {
-  if (!manifest)
-    return false;
-
-  // preload, removalbe and readonly : in parse_preload step.
-  if (manifest->preload && !strcmp(manifest->preload, "true")) {
-    if (manifest->removable && !strcmp(manifest->removable, "false"))
-      manifest->system = strdup("true");
-    else
-      manifest->system = strdup("false");
-  } else {
-    manifest->system = strdup("false");
-  }
-
-  return true;
-}
-
 }  // namespace
 
 namespace common_installer {
@@ -113,9 +90,6 @@ bool RegisterAppInPkgmgr(manifest_x* manifest,
   if (!tep_path.empty())
     manifest->tep_name = strdup(tep_path.c_str());
 
-  if (!AssignPackageTags(manifest))
-    return false;
-
   int ret = request_mode != RequestMode::GLOBAL ?
       pkgmgr_parser_process_usr_manifest_x_for_installation(manifest, uid) :
       pkgmgr_parser_process_manifest_x_for_installation(manifest);
@@ -137,9 +111,6 @@ bool UpgradeAppInPkgmgr(manifest_x* manifest,
                         const CertificateInfo& cert_info,
                         uid_t uid,
                         RequestMode request_mode) {
-  if (!AssignPackageTags(manifest))
-    return false;
-
   int ret = request_mode != RequestMode::GLOBAL ?
        pkgmgr_parser_process_usr_manifest_x_for_upgrade(manifest, uid) :
        pkgmgr_parser_process_manifest_x_for_upgrade(manifest);
index 57ecf42..1269848 100644 (file)
@@ -232,22 +232,6 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
   manifest->removable = strdup(pkg_info->removable().c_str());
 
   common_installer::RequestType req_type = context_->request_type.get();
-  // set update false when ReadonlyUpdateUninstall
-  if (req_type == RequestType::ReadonlyUpdateUninstall)
-    manifest->update = strdup("false");
-  // set update true if package is updated preload package
-  else if (QueryIsUpdatedPackage(pkg_info->package(), context_->uid.get()))
-    manifest->update = strdup("true");
-  // set update true when update non-removable preload package
-  else if (QueryIsPreloadPackage(pkg_info->package(), context_->uid.get()) &&
-      (req_type == RequestType::Update ||
-       req_type == RequestType::Delta ||
-       req_type == RequestType::MountUpdate ||
-       req_type == RequestType::ReadonlyUpdateInstall))
-    manifest->update = strdup("true");
-  else
-    manifest->update = strdup("false");
-
   if (pkg_info->type().empty()) {
     if ((req_type == RequestType::ManifestDirectInstall ||
         req_type == RequestType::ManifestDirectUpdate) &&
index 4209521..7500b37 100644 (file)
@@ -41,11 +41,11 @@ ci::Step::Status StepParsePreload::process() {
     }
   }
 
+  RequestType req_type = context_->request_type.get();
   const char* preload_val = context_->manifest_data.get()->preload;
   if (!preload_val || (preload_val && strlen(preload_val) == 0)) {
     if (preload_val)
       free(context_->manifest_data.get()->preload);
-    RequestType req_type = context_->request_type.get();
     if (req_type == RequestType::Update ||
         req_type == RequestType::Delta ||
         req_type == RequestType::MountUpdate ||
@@ -93,6 +93,47 @@ ci::Step::Status StepParsePreload::process() {
     return Status::MANIFEST_ERROR;
   }
 
+  manifest_x* manifest = context_->manifest_data.get();
+  // set update false when ReadonlyUpdateUninstall
+  if (req_type == RequestType::ReadonlyUpdateUninstall)
+    manifest->update = strdup("false");
+  // set update true if package is updated preload package
+  else if (QueryIsUpdatedPackage(context_->pkgid.get(), context_->uid.get()))
+    manifest->update = strdup("true");
+  // set update true when update non-removable preload package
+  else if (QueryIsPreloadPackage(context_->pkgid.get(), context_->uid.get()) &&
+      (req_type == RequestType::Update ||
+       req_type == RequestType::Delta ||
+       req_type == RequestType::MountUpdate ||
+       req_type == RequestType::ReadonlyUpdateInstall))
+    manifest->update = strdup("true");
+  else
+    manifest->update = strdup("false");
+
+  // set system true when install RO preload package
+  if (context_->is_readonly_package.get() ||
+      (manifest->readonly && !strcmp(manifest->readonly, "true")))
+    manifest->system = strdup("true");
+  // set system true when install non-removable RW preload package
+  else if (
+      (context_->is_preload_rw_package.get() ||
+          (manifest->preload && !strcmp(manifest->preload, "true"))) &&
+      (context_->no_remove.get() ||
+          (manifest->removable && !strcmp(manifest->removable, "false"))))
+    manifest->system = strdup("true");
+  // set system false when update non-removable RW preload package
+  else if (QueryIsSystemPackage(context_->pkgid.get(), context_->uid.get()) &&
+      !QueryIsReadonlyPackage(context_->pkgid.get(), context_->uid.get()) &&
+      !QueryIsUpdatedPackage(context_->pkgid.get(), context_->uid.get()))
+    manifest->system = strdup("false");
+  // set system true when update RO preload package
+  else if (req_type == RequestType::ReadonlyUpdateInstall ||
+      req_type == RequestType::ReadonlyUpdateUninstall ||
+      QueryIsSystemPackage(context_->pkgid.get(), context_->uid.get()))
+    manifest->system = strdup("true");
+  else
+    manifest->system = strdup("false");
+
   return Status::OK;
 }