apply extended concept of package's attribute. 39/99039/9
authorjongmyeongko <jongmyeong.ko@samsung.com>
Mon, 21 Nov 2016 14:31:34 +0000 (23:31 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Thu, 24 Nov 2016 12:45:12 +0000 (21:45 +0900)
- preload-rw : located in /opt/usr/globalapps/ and preloaded.
- readonly : located in /usr/apps/ and preloaded. (== old preload_request)

some preload-rw package can be not-removable also like as readonly package.

Requires :
https://review.tizen.org/gerrit/#/c/99207/

Change-Id: I8ae7cfdb06467f4e27f1b23f2573d21ad54ee75d
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
37 files changed:
packaging/app-installers.spec
src/common/app_installer.cc
src/common/installer_context.cc
src/common/installer_context.h
src/common/pkgmgr_interface.cc
src/common/pkgmgr_interface.h
src/common/pkgmgr_query.cc
src/common/pkgmgr_query.h
src/common/pkgmgr_registration.cc
src/common/request.cc
src/common/request.h
src/common/security_registration.cc
src/common/security_registration.h
src/common/shared_dirs.cc
src/common/shared_dirs.h
src/common/step/backup/step_backup_icons.cc
src/common/step/configuration/step_configure.cc
src/common/step/configuration/step_configure.h
src/common/step/configuration/step_parse_manifest.cc
src/common/step/configuration/step_parse_preload.cc
src/common/step/filesystem/step_change_owner.cc
src/common/step/filesystem/step_create_globalapp_symlinks.cc
src/common/step/filesystem/step_create_icons.cc
src/common/step/filesystem/step_create_per_user_storage_directories.cc
src/common/step/filesystem/step_delta_patch.cc
src/common/step/filesystem/step_recover_change_owner.cc
src/common/step/filesystem/step_recover_icons.cc
src/common/step/filesystem/step_recover_manifest.cc
src/common/step/filesystem/step_remove_globalapp_symlinks.cc
src/common/step/filesystem/step_remove_icons.cc
src/common/step/pkgmgr/step_recover_application.cc
src/common/step/security/step_check_signature.cc
src/common/step/security/step_recover_security.cc
src/common/step/security/step_register_security.cc
src/common/step/security/step_rollback_deinstallation_security.cc
src/common/step/security/step_update_security.cc
src/common/utils/user_util.cc

index 863b50137bf49ed21c83bf7a86041e0dafa79b69..c531bc71dc12b25c387752a0f855fe56909eb694 100644 (file)
@@ -1,6 +1,6 @@
 Name:           app-installers
 Summary:        Application installers
-Version:        1.8
+Version:        1.9
 Release:        1
 Group:          Application Framework/Package Management
 License:        Apache-2.0
index ec7e9da043818a33e08d05c2105572e962692f57..79e59bfa314dfc382c5172a582e2be2e309e4af2 100644 (file)
@@ -129,9 +129,8 @@ AppInstaller::Result AppInstaller::Run() {
                       context_->pkgid.get());
   }
 
-  if (context_->installation_mode.get() == InstallationMode::OFFLINE &&
-      context_->is_preload_request.get() &&
-      process_status != Step::Status::OK) {
+  if ((context_->installation_mode.get() == InstallationMode::OFFLINE) &&
+      (process_status != Step::Status::OK)) {
     std::fstream info_file("/tmp/.preload_install_error",
         std::ios::out | std::ios::app);
     info_file << context_->pkgid.get() << std::endl;
index 73f9f75f8c22dd5a2cf16ba223650aed428f42df..1850bc5411ccb88c3e7bc1c6902552a4bae0c674 100644 (file)
@@ -36,7 +36,10 @@ InstallerContext::InstallerContext()
       uid(getuid()),
       backend_data(nullptr),
       privilege_level(PrivilegeLevel::UNTRUSTED),
-      is_preload_request(false),
+      is_readonly_package(false),
+      is_preload_rw_package(false),
+      force_remove(false),
+      no_remove(false),
       cross_app_rules(false) {}
 
 InstallerContext::~InstallerContext() {
index bdfbae58e7484b2289daf7e41a640d3825afbcce..6b537bc0dc6b737d2e647ec7ee453d08e86522cc 100644 (file)
@@ -286,15 +286,25 @@ class InstallerContext {
   Property<InstallationMode> installation_mode;
 
   /**
-   * \brief preload request received from pkgmgr_installer
+   * \brief readonly request received from pkgmgr_installer
    */
-  Property<bool> is_preload_request;
+  Property<bool> is_readonly_package;
+
+  /**
+   * \brief preload-rw request received from pkgmgr_installer
+   */
+  Property<bool> is_preload_rw_package;
 
   /**
    * \brief force-remove request received from pkgmgr_installer
    */
   Property<bool> force_remove;
 
+  /**
+   * \brief no-remove request received from pkgmgr_installer
+   */
+  Property<bool> no_remove;
+
   /**
    * \brief Describes behaviour for security manager. It set to true, this will
    *        force to generates n-to-n rules for package's apps.
index 27c5f6cfb6dd84ee0bfd4c9aea322f6c9a5f8e3a..8eebb54bbe8f79c07b97f0cedca6a9a7f4bb46be 100644 (file)
@@ -172,7 +172,7 @@ boost::filesystem::path PkgMgrInterface::GetTepPath() const {
 }
 
 bool PkgMgrInterface::GetIsTepMove() {
-  return (pkgmgr_installer_get_tep_move_type(pi_) == 1)?true:false;
+  return (pkgmgr_installer_get_tep_move_type(pi_) == 1);
 }
 
 bool PkgMgrInterface::GetIsMoveToExternal() {
@@ -180,9 +180,11 @@ bool PkgMgrInterface::GetIsMoveToExternal() {
 }
 
 bool PkgMgrInterface::GetIsPreloadRequest() {
-  return (pkgmgr_installer_get_is_preload(pi_) == 1)?
-      true:(install_mode_ == InstallationMode::OFFLINE)?
-      true:false;
+  return (pkgmgr_installer_get_is_preload(pi_) == 1);
+}
+
+bool PkgMgrInterface::GetIsPreloadRWRequest() {
+  return (pkgmgr_installer_get_is_preload_rw(pi_) == 1);
 }
 
 std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
@@ -192,8 +194,11 @@ std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
 }
 
 bool PkgMgrInterface::GetIsForceRemoval() {
-  // root only
-  return (getuid() == 0 && pkgmgr_installer_get_force_removal(pi_) == 1);
+  return (pkgmgr_installer_get_force_removal(pi_) == 1);
+}
+
+bool PkgMgrInterface::GetIsNoRemoval() {
+  return (pkgmgr_installer_get_no_removal(pi_) == 1);
 }
 
 }  // namespace common_installer
index 699974baf36d16423a042eb5d69faf4a642570e8..4ad28285122beba156f06f171e58d94de8c1d8cb 100644 (file)
@@ -127,6 +127,13 @@ class PkgMgrInterface {
   */
   bool GetIsPreloadRequest();
 
+  /**
+  * Returns True if the request is for preload-rw. Otherwise, return false
+  *
+  * \return True if the request is for preload-rw. Otherwise, return false
+  */
+  bool GetIsPreloadRWRequest();
+
   /**
   * Returns True if the request is for force-remove. Otherwise, return false
   *
@@ -134,6 +141,13 @@ class PkgMgrInterface {
   */
   bool GetIsForceRemoval();
 
+  /**
+  * Returns True if the request is for no-remove. Otherwise, return false
+  *
+  * \return True if the request is for no-remove. Otherwise, return false
+  */
+  bool GetIsNoRemoval();
+
   /**
    * Get Raw pointer to pkgmgr_installer object
    * NOTE: It should not be used (PkgMgrInterface can destroy it
index 691c343461b4a59e9dbdc250416fd189489a1519..4f63041f31d91c7308f6fcb17e78f9591ec3e475 100644 (file)
@@ -235,7 +235,7 @@ bool QueryIsGlobalPackage(const std::string& pkg_id, uid_t uid) {
   return is_global;
 }
 
-bool QueryIsPreloadPackage(const std::string& pkg_id, uid_t uid) {
+bool QueryIsReadonlyPackage(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) {
@@ -244,15 +244,15 @@ bool QueryIsPreloadPackage(const std::string& pkg_id, uid_t uid) {
     return false;
   }
 
-  bool is_preload = false;
-  if (pkgmgrinfo_pkginfo_is_preload(handle, &is_preload) != PMINFO_R_OK) {
-    LOG(ERROR) << "pkgmgrinfo_pkginfo_is_preload failed";
+  bool is_readonly = false;
+  if (pkgmgrinfo_pkginfo_is_readonly(handle, &is_readonly) != PMINFO_R_OK) {
+    LOG(ERROR) << "pkgmgrinfo_pkginfo_is_readonly failed";
     pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
     return false;
   }
 
   pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-  return is_preload;
+  return is_readonly;
 }
 
 }  // namespace common_installer
index b2b39e3d366b920befec18fa80064e06686384f5..a08a0de80ed4a7e8c77f2094828227c783b143a1 100644 (file)
@@ -120,14 +120,14 @@ bool QueryIsGlobalPackage(const std::string& pkg_id, uid_t uid);
 
 /**
  * \brief Adapter interface for external PkgMgr module used for checking
- *        if given package is preloaded package
+ *        if given package is readonly package
  *
  * \param pkg_id package id
  * \param uid user id
  *
- * \return true if package is preloaded
+ * \return true if package is readonly
  */
-bool QueryIsPreloadPackage(const std::string& pkg_id, uid_t uid);
+bool QueryIsReadonlyPackage(const std::string& pkg_id, uid_t uid);
 
 }  // namespace common_installer
 
index 593eb8669d971c02219009dc22e600eb8127ce31..dab584a57859f9112a9436d7df27bcf1f3063125 100644 (file)
@@ -74,26 +74,22 @@ bool RegisterCertificates(
   return true;
 }
 
-// "preload" : this package was installed at the binary creation.
+// "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" but is updated after first installation.
+// "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,
                        bool is_update) {
+  // preload, removalbe and readonly : in parse_preload step.
+  manifest->system = strdup("false");
+  manifest->update = strdup("false");
   if (!strcmp(manifest->preload, "true")) {
-    manifest->removable = strdup("false");
-    manifest->readonly = strdup("true");
-    manifest->system = strdup("true");
     if (is_update)
       manifest->update = strdup("true");
-    else
-      manifest->update = strdup("false");
-  } else {
-    manifest->removable = strdup("true");
-    manifest->readonly = strdup("false");
-    manifest->system = strdup("false");
-    manifest->update = strdup("false");
+    if (!strcmp(manifest->removable, "false"))
+      manifest->system = strdup("true");
   }
 
   return true;
index 0911a955849c06573756fc734c6dee31c8bef9d1..841e9977d9cd8d548b3c3154fc656c74a1dd02f3 100644 (file)
@@ -15,10 +15,10 @@ RequestMode GetRequestMode(uid_t uid) {
       RequestMode::GLOBAL : RequestMode::USER;
 }
 
-// Now, preload app is always installed RO location.
-const char* GetRootAppPath(bool is_preload, uid_t uid) {
+// Now, readonly app is always installed RO location.
+const char* GetRootAppPath(bool is_readonly, uid_t uid) {
   if (GetRequestMode(uid) == RequestMode::GLOBAL) {
-    return is_preload ?
+    return is_readonly ?
         tzplatform_getenv(TZ_SYS_RO_APP) : tzplatform_getenv(TZ_SYS_RW_APP);
   } else {
     tzplatform_set_user(uid);
index c320e9b21fb71a336cf2178038b03331ebe0aa20..2a49c07278680718710b5c34929d1da0ea7a6f1d 100644 (file)
@@ -48,7 +48,7 @@ RequestMode GetRequestMode(uid_t uid);
  *
  * \return root application path (eg. $HOME/apps_rw/)
  */
-const char* GetRootAppPath(bool is_preload, uid_t uid);
+const char* GetRootAppPath(bool is_readonly, uid_t uid);
 
 }  // namespace common_installer
 
index 61fa839948d51cc6cb02679811f5395ff87ddd5d..df29c180b53c8566275d9d225ab8e11c4766e5b9 100644 (file)
@@ -92,7 +92,8 @@ bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
     error = security_manager_app_inst_req_set_hybrid(req);
     if (error != SECURITY_MANAGER_SUCCESS) {
       std::string errnum = boost::str(boost::format("%d") % error);
-      *error_message = security_manager_strerror(static_cast<lib_retcode>(error));
+      *error_message =
+          security_manager_strerror(static_cast<lib_retcode>(error));
       *error_message += ":<" + errnum + ">";
       return false;
     }
@@ -154,7 +155,7 @@ bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
 
 bool PreparePathRequest(const std::string& pkg_id,
     const boost::filesystem::path& path, uid_t uid, path_req* req,
-    std::string* error_message) {
+    bool readonly, std::string* error_message) {
   if (pkg_id.empty() || path.empty()) {
     LOG(ERROR) << "Pkgid or path is empty. Both values must be set";
     return false;
@@ -189,7 +190,7 @@ bool PreparePathRequest(const std::string& pkg_id,
     return false;
   }
   // When registering skel dir on global installation mode
-  if (type == SM_APP_INSTALL_PRELOADED && getuid() != 0)
+  if (type == SM_APP_INSTALL_PRELOADED && !readonly)
     type = SM_APP_INSTALL_GLOBAL;
 
   error = security_manager_path_req_set_install_type(req, type);
@@ -364,7 +365,7 @@ bool UnregisterSecurityContextForPkgId(const std::string &pkg_id,
 
 bool RegisterSecurityContextForPath(const std::string &pkg_id,
     const boost::filesystem::path& path, uid_t uid,
-    std::string* error_message) {
+    bool readonly, std::string* error_message) {
   path_req* req;
   int error = security_manager_path_req_new(&req);
   if (error != SECURITY_MANAGER_SUCCESS) {
@@ -377,7 +378,7 @@ bool RegisterSecurityContextForPath(const std::string &pkg_id,
     return false;
   }
 
-  if (!PreparePathRequest(pkg_id, path, uid, req, error_message)) {
+  if (!PreparePathRequest(pkg_id, path, uid, req, readonly, error_message)) {
     LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
     security_manager_path_req_free(req);
     return false;
index c0b42b94a7bbbb6eef47c336810d430942adb616..0276984b46a2fe3b858e8a6b6f99209c270a3a85 100644 (file)
@@ -119,13 +119,14 @@ bool UnregisterSecurityContextForPkgId(const std::string& pkg_id, uid_t uid,
  * \param pkg_id pkgid of given package
  * \param path path for registering
  * \param uid uid
+ * \param readonly RO package flag
  * \param error_message extra/detailed error message
  *
  * \return true if success
  */
 bool RegisterSecurityContextForPath(const std::string &pkg_id,
     const boost::filesystem::path& path, uid_t uid,
-    std::string* error_message);
+    bool readonly, std::string* error_message);
 
 }  // namespace common_installer
 
index b4c56ddd63b78881984105a2c1b2532b650e2b1d..b83e35e9728946705120d56e315300cb9feb4855 100644 (file)
@@ -421,7 +421,7 @@ bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
 
 bool CreateSkelDirectories(const std::string& pkgid,
                            const std::string& api_version,
-                           bool trusted, bool shareddata, bool is_preload) {
+                           bool trusted, bool shareddata, bool is_readonly) {
   bf::path path = bf::path(kSkelAppDir) / pkgid;
   LOG(DEBUG) << "Creating directories in: " << path;
 
@@ -451,14 +451,14 @@ bool CreateSkelDirectories(const std::string& pkgid,
 
   std::string error_message;
   if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
-                                      &error_message)) {
+                                      is_readonly, &error_message)) {
     LOG(ERROR) << "Failed to register security context for path: " << path
                << ", error_message: " << error_message;
     return false;
   }
 
   bool result = true;
-  if (!is_preload) {
+  if (!is_readonly) {
     bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
     result = CreateSymlinkFiles(src_dir, path);
   }
@@ -530,7 +530,7 @@ bool CopyUserDirectories(const std::string& pkgid) {
     }
     std::string error_message;
     if (!RegisterSecurityContextForPath(pkgid, dst, std::get<0>(l),
-        &error_message)) {
+        false, &error_message)) {
       LOG(ERROR) << "Failed to register security context for path: " << dst
                  << ", error_message: " << error_message;
       return false;
index d99e6b9c79319c72f07923a047c2bcb34a9ada97..77e226034da4273b4b3ad32651073c1affe651a1 100644 (file)
@@ -70,14 +70,14 @@ bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid);
  * \param api_version package api version
  * \param trusted signed package flag
  * \param shareddata shared data privilege flag
- * \param is_preload preload flag
+ * \param is_readonly readonly flag
  *
  * \return bool true if succeed, false otherwise
  *
  */
 bool CreateSkelDirectories(const std::string& pkgid,
                            const std::string& api_version,
-                           bool trusted, bool shareddata, bool is_preload);
+                           bool trusted, bool shareddata, bool is_readonly);
 
 /**
  * \brief Performs deletion of directories
index 2bbaedf252d90ffd2640dd7a9bb631c1d2caaac5..df532ef41496605b6eaa602d678ee71598bd226f 100644 (file)
@@ -24,7 +24,7 @@ namespace backup {
 Step::Status StepBackupIcons::process() {
   // gather icon info
   const char* extra_icon_path = getIconPath(context_->uid.get(),
-      context_->is_preload_request.get());
+      context_->is_readonly_package.get());
   if (!extra_icon_path)
     return Status::OK;
 
index b736408437b765711192c7f3ea74ba45341b3936..4eb7e05ee8ba02d67e71b631943faae12826611f 100644 (file)
@@ -102,7 +102,7 @@ Step::Status StepConfigure::process() {
           context_->root_application_path.get() / context_->pkgid.get();
       bf::path xml_path =
           bf::path(getUserManifestPath(context_->uid.get(),
-              context_->is_preload_request.get()))
+              context_->is_readonly_package.get()))
           / bf::path(context_->pkgid.get());
       xml_path += ".xml";
       context_->unpacked_dir_path.set(package_directory);
@@ -148,22 +148,19 @@ Step::Status StepConfigure::process() {
 
 Step::Status StepConfigure::precheck() {
   SetupIsPreloadRequest();
+  SetupIsPreloadRWRequest();
+  SetupIsNoRemoval();
+
+  bool is_readonly = context_->is_readonly_package.get();
+  bool is_preload_rw = context_->is_preload_rw_package.get();
+  if (is_readonly && is_preload_rw) {
+    LOG(ERROR) << "Conflict of preload request!";
+    return Status::ERROR;
+  }
 
   context_->uid.set(pkgmgr_->GetUid());
-  if (getuid() == 0) {
-    if (pkgmgr_->GetRequestType() == RequestType::ManifestDirectInstall ||
-        pkgmgr_->GetRequestType() == RequestType::ManifestDirectUpdate ||
-        pkgmgr_->GetRequestType() == RequestType::DisablePkg ||
-        pkgmgr_->GetRequestType() == RequestType::EnablePkg) {
-      LOG(INFO) << "Allowing operation for root user";
-    } else if (context_->is_preload_request.get()) {
-      LOG(INFO) << "Allowing preload request mode for root user";
-    } else {
-      LOG(ERROR) << "App-installer should not run with superuser!";
-      return Status::OPERATION_NOT_ALLOWED;
-    }
+  if (getuid() == 0)
     return Status::OK;
-  }
 
   boost::optional<uid_t> appfw_uid = GetUidByUserName(kAppFWUser);
   if (!appfw_uid)
@@ -187,7 +184,8 @@ Step::Status StepConfigure::clean() {
 bool StepConfigure::SetupRootAppDirectory() {
   if (context_->root_application_path.get().empty()) {
     std::string root_app_path =
-        GetRootAppPath(context_->is_preload_request.get(), context_->uid.get());
+        GetRootAppPath(context_->is_readonly_package.get(),
+        context_->uid.get());
     if (root_app_path.empty())
       return false;
 
@@ -235,12 +233,20 @@ void StepConfigure::SetupFileCreationMask() {
 }
 
 void StepConfigure::SetupIsPreloadRequest() {
-  context_->is_preload_request.set(pkgmgr_->GetIsPreloadRequest());
+  context_->is_readonly_package.set(pkgmgr_->GetIsPreloadRequest());
+}
+
+void StepConfigure::SetupIsPreloadRWRequest() {
+  context_->is_preload_rw_package.set(pkgmgr_->GetIsPreloadRWRequest());
 }
 
 void StepConfigure::SetupIsForceRemoval() {
   context_->force_remove.set(pkgmgr_->GetIsForceRemoval());
 }
 
+void StepConfigure::SetupIsNoRemoval() {
+  context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
+}
+
 }  // namespace configuration
 }  // namespace common_installer
index 95e52db5c811acce517eb72cf064a51f3e327e17..8eaf122deae38aaaf0afee33169afed1576fda73 100644 (file)
@@ -60,7 +60,9 @@ class StepConfigure : public Step {
   void SetupRequestType();
   void SetupFileCreationMask();
   void SetupIsPreloadRequest();
+  void SetupIsPreloadRWRequest();
   void SetupIsForceRemoval();
+  void SetupIsNoRemoval();
 
   PkgMgrPtr pkgmgr_;
 
index 59279fd96912bd997df4ec0258d2270d5be35e97..0a986936d888f65bbd9cdb8239936350b45399ce 100644 (file)
@@ -107,17 +107,17 @@ bool StepParseManifest::LocateConfigFile() {
     }
     case ManifestLocation::INSTALLED: {
       uid_t uid;
-      bool is_preload;
+      bool is_readonly;
       if (QueryIsGlobalPackage(context_->pkgid.get(), context_->uid.get())) {
         uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
-        is_preload = QueryIsPreloadPackage(context_->pkgid.get(),
+        is_readonly = QueryIsReadonlyPackage(context_->pkgid.get(),
             context_->uid.get());
       } else {
         uid = context_->uid.get();
-        is_preload = context_->is_preload_request.get();
+        is_readonly = context_->is_readonly_package.get();
       }
       bf::path xml_path =
-          bf::path(getUserManifestPath(uid, is_preload))
+          bf::path(getUserManifestPath(uid, is_readonly))
           / bf::path(context_->pkgid.get());
       xml_path += ".xml";
       context_->xml_path.set(xml_path);
@@ -218,13 +218,15 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
   manifest->version = strdup(pkg_info->version().c_str());
   manifest->installlocation = strdup(pkg_info->install_location().c_str());
   manifest->api_version = strdup(pkg_info->api_version().c_str());
+  manifest->readonly = strdup(pkg_info->readonly().c_str());
   manifest->preload = strdup(pkg_info->preload().c_str());
+  manifest->removable = strdup(pkg_info->removable().c_str());
 
   if (pkg_info->type().empty()) {
     common_installer::RequestType req_type = context_->request_type.get();
     if ((req_type == RequestType::ManifestDirectInstall ||
         req_type == RequestType::ManifestDirectUpdate) &&
-        context_->is_preload_request.get())
+        context_->is_readonly_package.get())
       manifest->type = strdup("rpm");
     else
       manifest->type = strdup("tpk");
@@ -260,8 +262,7 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
     std::string storage = QueryStorageForPkgId(manifest->package,
                                               context_->uid.get());
     if (storage.empty()) {
-        // Failed to query installation storage, assign internal for preloaded
-        // applications
+        // Failed to query installation storage, assign internal
         manifest->installed_storage = strdup(kInstalledInternally);
     } else {
         manifest->installed_storage = strdup(storage.c_str());
@@ -793,7 +794,7 @@ bool StepParseManifest::FillSplashScreen(application_x* app,
   for (auto& splash_screen : splashscreens_info.splashscreens()) {
     splashscreen_x* splashscreen =
         static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
-    if (context_->is_preload_request.get())
+    if (context_->is_readonly_package.get())
       splashscreen->src = strdup(splash_screen.src().c_str());
     else
       splashscreen->src = strdup((context_->root_application_path.get()
index dbf4c41053c57c885666794e2575a46b6a1d1dd0..f8218d383b044a852f5e4c1ce51bec67b5af0a60 100644 (file)
@@ -23,25 +23,63 @@ namespace common_installer {
 namespace configuration {
 
 ci::Step::Status StepParsePreload::process() {
-  const char* preload_manifest_val = context_->manifest_data.get()->preload;
-
-  if (strcmp(preload_manifest_val, "true") != 0) {
-    bool is_preload = context_->is_preload_request.get();
-
-    LOG(INFO) << "is_preload : (" << is_preload << ")";
-    if (is_preload) {
-      context_->manifest_data.get()->preload = strdup("true");
+  const char* readonly_val = context_->manifest_data.get()->readonly;
+  if (!readonly_val || (readonly_val && strlen(readonly_val) == 0)) {
+    if (readonly_val)
+      free(context_->manifest_data.get()->readonly);
+    if (context_->is_readonly_package.get()) {
+      context_->manifest_data.get()->readonly = strdup("true");
 
       if (getuid() != 0) {
-        LOG(ERROR) << "You're not authorized to install preload app: "
+        LOG(ERROR) << "You're not authorized to install readonly app: "
             << context_->pkgid.get().c_str();
         return Status::OPERATION_NOT_ALLOWED;
       }
     } else {
-      context_->manifest_data.get()->preload = strdup("false");
+      context_->manifest_data.get()->readonly = strdup("false");
     }
   }
 
+  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);
+    if (context_->is_readonly_package.get() ||
+        context_->is_preload_rw_package.get())
+      context_->manifest_data.get()->preload = strdup("true");
+    else
+      context_->manifest_data.get()->preload = strdup("false");
+  }
+
+  const char* removable_val = context_->manifest_data.get()->removable;
+  if (!removable_val || (removable_val && strlen(removable_val) == 0)) {
+    if (removable_val)
+      free(context_->manifest_data.get()->removable);
+    if (context_->no_remove.get() ||
+        context_->is_readonly_package.get())
+      context_->manifest_data.get()->removable = strdup("false");
+    else
+      context_->manifest_data.get()->removable = strdup("true");
+  }
+
+  if ((strcmp(context_->manifest_data.get()->readonly, "true") == 0) &&
+      (strcmp(context_->manifest_data.get()->preload, "true") != 0)) {
+    LOG(ERROR) << "invalid preload attribute, readonly but not preload!";
+    return Status::MANIFEST_ERROR;
+  }
+
+  if ((strcmp(context_->manifest_data.get()->readonly, "true") == 0) &&
+      (strcmp(context_->manifest_data.get()->removable, "false") != 0)) {
+    LOG(ERROR) << "invalid preload attribute, readonly but removable!";
+    return Status::MANIFEST_ERROR;
+  }
+
+  if ((strcmp(context_->manifest_data.get()->preload, "false") == 0) &&
+      (strcmp(context_->manifest_data.get()->removable, "false") == 0)) {
+    LOG(ERROR) << "invalid preload attribute, no preload but not removable!";
+    return Status::MANIFEST_ERROR;
+  }
+
   return Status::OK;
 }
 
index df53592bcdcd83c52e52b8bdf984ad37274fe725..5c90ebfd3213571c9b279d607d6f61a7849f6ffb 100644 (file)
@@ -59,7 +59,7 @@ Step::Status StepChangeOwner::process() {
     return Status::ERROR;
 
   // For icon files
-  const char *iconpath = getIconPath(uid, context_->is_preload_request.get());
+  const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
   if (iconpath) {
     for (application_x* app :
         GListRange<application_x*>(
index 5c2ef61aaf62acd583483925e7e7e87602824df6..3b0253b28f1117fc0ee6c2fb3af88a7d2cdad75a 100644 (file)
@@ -23,7 +23,7 @@ namespace common_installer {
 namespace filesystem {
 
 common_installer::Step::Status StepCreateGlobalAppSymlinks::process() {
-  if (context_->is_preload_request.get())
+  if (context_->is_readonly_package.get())
     return Step::Status::OK;
   std::string package_id = context_->pkgid.get();
 
index b01585e93b4f99c15e8c610e37fa1d67804e90ae..2c5bdc22c6199d67df337f478c47e328d230cb87 100644 (file)
@@ -26,7 +26,7 @@ Step::Status StepCreateIcons::undo() {
 
 Step::Status StepCreateIcons::process() {
   const char* extra_icon_path = getIconPath(context_->uid.get(),
-      context_->is_preload_request.get());
+      context_->is_readonly_package.get());
   if (!extra_icon_path)
     return Status::OK;
 
index 83d4177f675a3df4cf3ddc51eb5310d9832579e8..9b7f9ef5c3943d601779166925a834d2ef3d07f7 100644 (file)
@@ -38,7 +38,7 @@ common_installer::Step::Status StepCreatePerUserStorageDirectories::process() {
     }
   }
   if (!common_installer::CreateSkelDirectories(package_id,
-      str_ver, trusted, shareddata, context_->is_preload_request.get())) {
+      str_ver, trusted, shareddata, context_->is_readonly_package.get())) {
     LOG(ERROR) << "Failed to create skel dirs";
     return Status::APP_DIR_ERROR;
   }
index 23d480f565ff9d8b1d1a7e68e833ea8864bef113..32ee3d56f3d43e8b7a83963216ee34dd1718bcff 100644 (file)
@@ -101,10 +101,11 @@ bool ApplyDeletedFiles(const delta::DeltaInfo& info, const bf::path& app_dir) {
 }
 
 bool ApplyModifiedFiles(const delta::DeltaInfo& info, const bf::path& app_dir,
-                        const bf::path& patch_dir, bool is_preload, uid_t uid) {
+                        const bf::path& patch_dir, bool is_readonly,
+                        uid_t uid) {
   for (auto& relative : info.modified()) {
     bf::path temp_file = ci::GenerateTemporaryPath(
-        bf::path(ci::GetRootAppPath(is_preload, uid)) / "tmp_file");
+        bf::path(ci::GetRootAppPath(is_readonly, uid)) / "tmp_file");
     bf::path patch_file = patch_dir / relative;
     bf::path input = app_dir / relative;
     if (!bf::is_regular_file(input)) {
@@ -184,10 +185,10 @@ bool ApplyAddedFiles(const delta::DeltaInfo& info, const bf::path& app_dir,
 }
 
 bool ApplyPatch(const delta::DeltaInfo& info, const bf::path& app_dir,
-                const bf::path& patch_dir, bool is_preload, uid_t uid) {
+                const bf::path& patch_dir, bool is_readonly, uid_t uid) {
   if (!ApplyDeletedFiles(info, app_dir))
     return false;
-  if (!ApplyModifiedFiles(info, app_dir, patch_dir, is_preload, uid))
+  if (!ApplyModifiedFiles(info, app_dir, patch_dir, is_readonly, uid))
     return false;
   if (!ApplyAddedFiles(info, app_dir, patch_dir))
     return false;
@@ -302,7 +303,7 @@ Step::Status StepDeltaPatch::process() {
 
   // apply changes mentioned in delta
   if (!ApplyPatch(*delta_info, context_->unpacked_dir_path.get(), patch_dir_,
-    context_->is_preload_request.get(), context_->uid.get()))
+    context_->is_readonly_package.get(), context_->uid.get()))
     return Status::DELTA_ERROR;
 
   bs::error_code error;
index 8cf8c044b5e2b3363ef95f272ca64a0a56aa3dad..5bf802da0ca0bff3dbfc779b2d65de1336c34a3b 100644 (file)
@@ -37,7 +37,7 @@ Step::Status StepRecoverChangeOwner::RecoveryUpdate() {
     return Step::Status::ERROR;
 
   // For icon files
-  const char *iconpath = getIconPath(uid, context_->is_preload_request.get());
+  const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
   if (iconpath) {
     for (application_x* app :
         GListRange<application_x*>(
index 30f86f7dbcab18f320149fa735c1d169e1b682b6..11962ed04b8e9bbd226e0f31c40467b826407184 100644 (file)
@@ -57,7 +57,7 @@ bool StepRecoverIcons::TryGatherIcons() {
 
   // gather icon info
   const char* extra_icon_path = getIconPath(context_->uid.get(),
-      context_->is_preload_request.get());
+      context_->is_readonly_package.get());
   if (!extra_icon_path)
     return true;
   for (auto iter = bf::directory_iterator(extra_icon_path);
index 8bc28fb1e8449bf983ff0cd1f4f843c63a7d8909..d8196fb3e634a0b3dd9fa737af4fcd91afd463bd 100644 (file)
@@ -56,7 +56,7 @@ bool StepRecoverManifest::SetXmlPaths() {
     return false;
   bf::path xml_path =
       bf::path(getUserManifestPath(context_->uid.get(),
-          context_->is_preload_request.get()))
+          context_->is_readonly_package.get()))
       / context_->pkgid.get();
   xml_path += ".xml";
   context_->xml_path.set(xml_path);
index 8fba186c266cad9ed5e886a0f86d6df97f314c2d..92acb13baeaaafc33d40b3e383d2077d835b2e2a 100644 (file)
@@ -23,7 +23,7 @@ namespace common_installer {
 namespace filesystem {
 
 Step::Status StepRemoveGlobalAppSymlinks::process() {
-  if (context_->is_preload_request.get())
+  if (context_->is_readonly_package.get())
     return Step::Status::OK;
 
   if (!QueryIsPackageInstalled(context_->pkgid.get(), kGlobalUserUid))
index a907c928a5869738a9f34682ff7a75e2f734146f..679604f09a1b001e69420334da3ff17920059a47 100644 (file)
@@ -31,7 +31,7 @@ Step::Status StepRemoveIcons::precheck() {
 
 Step::Status StepRemoveIcons::process() {
   const char* extra_icon_path = getIconPath(context_->uid.get(),
-      context_->is_preload_request.get());
+      context_->is_readonly_package.get());
   if (!extra_icon_path)
     return Status::OK;
   for (auto iter = bf::directory_iterator(extra_icon_path);
index 586a18b11726e62f9737ea027fd319180b0ad152..6640069ed08dd665beeb4825889f45fb419b50cd 100644 (file)
@@ -49,7 +49,7 @@ bool StepRecoverApplication::SetXmlPaths() {
     return false;
   bf::path xml_path =
       bf::path(getUserManifestPath(context_->uid.get(),
-          context_->is_preload_request.get()))
+          context_->is_readonly_package.get()))
       / context_->pkgid.get();
   xml_path += ".xml";
   context_->xml_path.set(xml_path);
index 2b754645094efc73fe1157a77ed04357a812ada0..fa8ea040661815d36925e07157f9370bce3d6f5c 100644 (file)
@@ -86,7 +86,7 @@ Step::Status StepCheckSignature::CheckSignatureMismatch() {
 
 Step::Status StepCheckSignature::CheckPrivilegeLevel(PrivilegeLevel level) {
   std::string error_message;
-  if (!context_->is_preload_request.get()) {
+  if (!context_->is_readonly_package.get()) {
     if (!ValidatePrivilegeLevel(level, context_->uid.get(),
         context_->manifest_data.get()->api_version,
         context_->manifest_data.get()->privileges, &error_message)) {
@@ -108,7 +108,6 @@ Step::Status StepCheckSignature::process() {
       (context_->request_type.get() == ci::RequestType::ManifestDirectInstall ||
       context_->request_type.get() == ci::RequestType::ManifestDirectUpdate)))
     check_reference = false;
-  bool is_preload = context_->is_preload_request.get();
   Status status = CheckSignatures(check_reference, &level);
   if (status != Status::OK)
     return status;
@@ -117,7 +116,7 @@ Step::Status StepCheckSignature::process() {
   if (status != Status::OK)
     return status;
 
-  if (is_preload)
+  if (context_->is_readonly_package.get())
     level = PrivilegeLevel::PLATFORM;
 
   /* for update of user apps in 2.4 */
index 566575f6cbcc0839843a939b391417aeef54127a..b60477e85e2c20f4ae58f23c1980a9e832357a79 100644 (file)
@@ -60,7 +60,7 @@ Step::Status StepRecoverSecurity::RecoveryUpdate() {
   }
   if (!RegisterSecurityContextForPath(
       context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
-      &error_message)) {
+      context_->is_readonly_package.get(), &error_message)) {
     if (!error_message.empty()) {
       LOG(ERROR) << "error_message: " << error_message;
       on_error(Status::SECURITY_ERROR, error_message);
index 61e6e852c712f5c51467e2be26347f7ed637d07f..b4e903909422e1941b85951e522a71100fcb46bd 100644 (file)
@@ -51,7 +51,7 @@ Step::Status StepRegisterSecurity::process() {
   }
   if (!RegisterSecurityContextForPath(
       context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
-      &error_message)) {
+      context_->is_readonly_package.get(), &error_message)) {
     if (!error_message.empty()) {
       LOG(ERROR) << "error_message: " << error_message;
       on_error(Status::SECURITY_ERROR, error_message);
index b7c0a4ccf737a251046fe685301612dbfe3b133c..8e2f21fc37f2f6e590b4dd5d29e4428ac63db68e 100644 (file)
@@ -40,7 +40,7 @@ Step::Status StepRollbackDeinstallationSecurity::undo() {
   }
   if (!RegisterSecurityContextForPath(
       context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
-      &error_message)) {
+      context_->is_readonly_package.get(), &error_message)) {
     if (!error_message.empty()) {
       LOG(ERROR) << "error_message: " << error_message;
       on_error(Status::SECURITY_ERROR, error_message);
index 361d7d48daf9e3019dc7141769972f4dcc64c0f3..95147c8bccbb522322ef34a5084f433170ea92f1 100644 (file)
@@ -25,7 +25,7 @@ Step::Status StepUpdateSecurity::process() {
   }
   if (!RegisterSecurityContextForPath(
       context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
-      &error_message)) {
+      context_->is_readonly_package.get(), &error_message)) {
     if (!error_message.empty()) {
       LOG(ERROR) << "error_message: " << error_message;
       on_error(Status::SECURITY_ERROR, error_message);
@@ -49,7 +49,7 @@ Step::Status StepUpdateSecurity::undo() {
   }
   if (!RegisterSecurityContextForPath(
       context_->pkgid.get(), context_->pkg_path.get(), context_->uid.get(),
-      &error_message)) {
+      context_->is_readonly_package.get(), &error_message)) {
     if (!error_message.empty()) {
       LOG(ERROR) << "error_message: " << error_message;
       on_error(Status::SECURITY_ERROR, error_message);
index 3296cf8216fa18d89d2d5f8a2081798d4416740a..d72f290a33094cc9f1fc81b9880efb4b203368f5 100644 (file)
@@ -62,7 +62,7 @@ UserList GetUserList() {
     } else {
       break;
     }
-  };
+  }
   UserList list;
   for (GumUser* guser : GListRange<GumUser*>(gum_user_list)) {
     uid_t uid;