Fix backup plugin execution information
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_parse_manifest.cc
index 3c18dec..39a3341 100644 (file)
@@ -9,14 +9,14 @@
 #include <pkgmgr/pkgmgr_parser.h>
 #include <pkgmgr-info.h>
 
-#include <tpk_manifest_handlers/account_handler.h>
-#include <tpk_manifest_handlers/common/appdefined_privilege_handler.h>
+#include <tpk_manifest_handlers/appdefined_privilege_handler.h>
 #include <tpk_manifest_handlers/application_manifest_constants.h>
 #include <tpk_manifest_handlers/author_handler.h>
 #include <tpk_manifest_handlers/component_based_application_handler.h>
 #include <tpk_manifest_handlers/dependencies_handler.h>
 #include <tpk_manifest_handlers/description_handler.h>
 #include <tpk_manifest_handlers/feature_handler.h>
+#include <tpk_manifest_handlers/light_user_handler.h>
 #include <tpk_manifest_handlers/package_handler.h>
 #include <tpk_manifest_handlers/privileges_handler.h>
 #include <tpk_manifest_handlers/profile_handler.h>
@@ -28,7 +28,6 @@
 #include <tpk_manifest_handlers/watch_application_handler.h>
 #include <tpk_manifest_handlers/widget_application_handler.h>
 
-#include <chrono>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <string>
 #include <vector>
 
-#include "common/app2ext_dynamic_service.h"
-#include "common/app_installer.h"
 #include "common/feature_validator.h"
 #include "common/installer_context.h"
-#include "common/paths.h"
+#include "common/utils/paths.h"
 #include "common/privileges.h"
 #include "common/pkgmgr_registration.h"
-#include "common/pkgmgr_query.h"
+#include "common/utils/pkgmgr_query.h"
 #include "common/step/step.h"
 #include "common/utils/glist_range.h"
+#include "common/utils/time_util.h"
 
 namespace app_keys = tpk::application_keys;
 namespace bf = boost::filesystem;
@@ -115,18 +113,23 @@ bool StepParseManifest::LocateConfigFile() {
                       context_->is_readonly_package.get()))
               / bf::path(context_->pkgid.get());
       install_path += ".xml";
-      if (bf::exists(backup_path))
+      bf::path backup_install_path =
+          common_installer::GetBackupPathForManifestFile(install_path);
+      if (bf::exists(backup_install_path))
+        manifest = backup_install_path;
+      else if (bf::exists(backup_path))
         manifest = backup_path;
-      else if (bf::exists(in_package_path))
-        manifest = in_package_path;
       else if (bf::exists(install_path))
         manifest = install_path;
+      else if (bf::exists(in_package_path))
+        manifest = in_package_path;
       break;
     }
     case ManifestLocation::INSTALLED: {
       uid_t uid;
       bool is_readonly = context_->is_readonly_package.get();
-      if (context_->pkg_query->IsGlobalPackage())
+      PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
+      if (pkg_query.IsGlobalPackage())
         uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
       else
         uid = context_->uid.get();
@@ -185,9 +188,7 @@ int StepParseManifest::GetSupportModeVal(std::string support_mode) {
 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
   manifest->root_path = strdup(
       (context_->root_application_path.get() / manifest->package).c_str());
-  manifest->installed_time =
-      strdup(std::to_string(std::chrono::system_clock::to_time_t(
-          std::chrono::system_clock::now())).c_str());
+  manifest->installed_time = strdup(GetCurrentTime().c_str());
   return true;
 }
 
@@ -200,44 +201,6 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
     return false;
   }
 
-  auto ui_application_list =
-      std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
-          parser_->GetManifestData(app_keys::kUIApplicationKey));
-  auto service_application_list =
-      std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
-          parser_->GetManifestData(app_keys::kServiceApplicationKey));
-  auto widget_application_list =
-      std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
-          parser_->GetManifestData(app_keys::kWidgetApplicationKey));
-  auto watch_application_list =
-      std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
-          parser_->GetManifestData(app_keys::kWatchApplicationKey));
-  auto component_based_application_list =
-      std::static_pointer_cast<
-          const tpk::parse::ComponentBasedApplicationInfoList>(
-              parser_->GetManifestData(
-                  app_keys::kComponentBasedApplicationKey));
-
-  // mandatory check
-  if (!ui_application_list && !service_application_list &&
-      !widget_application_list && !watch_application_list &&
-      !component_based_application_list) {
-    LOG(ERROR) << "UI Application or Service Application or Widget Application "
-                  "or Watch Application or Component-Based Application "
-                  "are mandatory and has not been found.";
-    return false;
-  }
-  if (component_based_application_list) {
-    for (const auto& app : component_based_application_list->items) {
-      if (app.components.components().empty()) {
-        LOG(ERROR) << "Frame-Component or Service-Component is mandatory and "
-                      "has not been found.";
-        return false;
-      }
-    }
-  }
-
-
   int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
 
   manifest->ns = strdup(pkg_info->xmlns().c_str());
@@ -265,21 +228,6 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
     manifest->type = strdup(pkg_info->type().c_str());
   }
 
-  // Set external path if the package is installed at external storage.
-  if (req_type == RequestType::ManifestDirectInstall ||
-      req_type == RequestType::ManifestDirectUpdate ||
-      req_type == RequestType::ManifestPartialInstall ||
-      req_type == RequestType::ManifestPartialUpdate ||
-      req_type == RequestType::RecoverDB) {
-    App2ExtDynamicService service;
-    std::string image_path = service.GetExternalImagePath(
-        context_->pkgid.get().c_str(), context_->uid.get());
-    if (!image_path.empty()) {
-      manifest->external_path = strdup(image_path.c_str());
-      manifest->installed_storage = strdup(kInstalledExternally);
-    }
-  }
-
   for (auto& pair : pkg_info->labels()) {
     label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
     if (!label) {
@@ -307,10 +255,11 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
   // set installed_storage if package is installed
   // this is internal field in package manager but after reading configuration
   // we must know it
+  PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
   if (!manifest->installed_storage) {
     if (manifest_location_ == ManifestLocation::INSTALLED ||
         manifest_location_ == ManifestLocation::RECOVERY) {
-      std::string storage = context_->pkg_query->StorageForPkgId();
+      std::string storage = pkg_query.StorageForPkgId();
       if (storage.empty()) {
         // Failed to query installation storage, assign internal
         manifest->installed_storage = strdup(kInstalledInternally);
@@ -323,10 +272,11 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
   }
 
   // retrieve and set plugin execution info if exists
-  if (manifest_location_ == ManifestLocation::INSTALLED ||
-      manifest_location_ == ManifestLocation::RECOVERY) {
+  if (store_location_ == StoreLocation::BACKUP && (
+      manifest_location_ == ManifestLocation::INSTALLED ||
+      manifest_location_ == ManifestLocation::RECOVERY)) {
     std::vector<PkgQueryInterface::PluginInfo> plugin_list;
-    context_->pkg_query->PluginExecutionInfo(&plugin_list);
+    pkg_query.PluginExecutionInfo(&plugin_list);
 
     for (const auto& plugin_info : plugin_list) {
       plugin_x* plugin =
@@ -522,7 +472,11 @@ bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
     widget_app->package = strdup(manifest->package);
     widget_app->support_disable = strdup(manifest->support_disable);
     widget_app->launch_mode = strdup("single");
-    widget_app->api_version = strdup(manifest->api_version);
+    if (!application.app_info.api_version().empty())
+      widget_app->api_version =
+          strdup(application.app_info.api_version().c_str());
+    else
+      widget_app->api_version = strdup(manifest->api_version);
     manifest->application = g_list_append(manifest->application, widget_app);
     if (bf::path(application.app_info.exec().c_str()).is_absolute())
       widget_app->exec = strdup(application.app_info.exec().c_str());
@@ -541,6 +495,8 @@ bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
       return false;
     if (!FillMetadata(widget_app, application.meta_data))
       return false;
+    if (!FillResControl(widget_app, application.res_controls))
+      return false;
   }
   return true;
 }
@@ -575,8 +531,6 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
       service_app->type = strdup(application.app_info.type().c_str());
     else
       service_app->type = strdup("capp");
-    service_app->process_pool =
-        strdup(application.app_info.process_pool().c_str());
     service_app->component_type = strdup("svcapp");
     service_app->mainapp = strdup(application.app_info.mainapp().c_str());
     service_app->nodisplay = strdup("true");
@@ -594,7 +548,11 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
     service_app->package = strdup(manifest->package);
     service_app->support_disable = strdup(manifest->support_disable);
     service_app->launch_mode = strdup("single");
-    service_app->api_version = strdup(manifest->api_version);
+    if (!application.app_info.api_version().empty())
+      service_app->api_version =
+          strdup(application.app_info.api_version().c_str());
+    else
+      service_app->api_version = strdup(manifest->api_version);
     manifest->application = g_list_append(manifest->application, service_app);
     if (bf::path(application.app_info.exec().c_str()).is_absolute())
       service_app->exec = strdup(application.app_info.exec().c_str());
@@ -618,6 +576,8 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
     if (!FillBackgroundCategoryInfo(service_app,
         application.background_category))
       return false;
+    if (!FillResControl(service_app, application.res_controls))
+      return false;
   }
   return true;
 }
@@ -692,7 +652,10 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
     ui_app->support_disable = strdup(manifest->support_disable);
     ui_app->splash_screen_display =
         strdup(application.app_info.splash_screen_display().c_str());
-    ui_app->api_version = strdup(manifest->api_version);
+    if (!application.app_info.api_version().empty())
+      ui_app->api_version = strdup(application.app_info.api_version().c_str());
+    else
+      ui_app->api_version = strdup(manifest->api_version);
     manifest->application = g_list_append(manifest->application, ui_app);
     if (bf::path(application.app_info.exec().c_str()).is_absolute())
       ui_app->exec = strdup(application.app_info.exec().c_str());
@@ -720,6 +683,8 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
       return false;
     if (!FillSplashScreen(ui_app, application.app_splashscreens))
       return false;
+    if (!FillResControl(ui_app, application.res_controls))
+      return false;
   }
   return true;
 }
@@ -777,13 +742,18 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
         strdup((std::to_string(app_support_mode_val)).c_str());
     watch_app->ui_gadget = strdup("false");
     watch_app->launch_mode = strdup("single");
-    watch_app->api_version = strdup(manifest->api_version);
+    if (!watch_application.app_info.api_version().empty())
+      watch_app->api_version =
+          strdup(watch_application.app_info.api_version().c_str());
+    else
+      watch_app->api_version = strdup(manifest->api_version);
     watch_app->support_ambient =
         strdup(watch_application.app_info.ambient_support().c_str());
     watch_app->package = strdup(manifest->package);
     if (!watch_application.app_info.setup_appid().empty())
       watch_app->setup_appid =
           strdup(watch_application.app_info.setup_appid().c_str());
+    manifest->application = g_list_append(manifest->application, watch_app);
 
     if (!FillLabel(watch_app, watch_application.label))
       return false;
@@ -796,7 +766,8 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
     if (!FillBackgroundCategoryInfo(watch_app,
         watch_application.background_category))
       return false;
-    manifest->application = g_list_append(manifest->application, watch_app);
+    if (!FillResControl(watch_app, watch_application.res_controls))
+      return false;
   }
   return true;
 }
@@ -843,6 +814,26 @@ bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
   return true;
 }
 
+bool StepParseManifest::FillLightUserInfo(manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::LightUserInfo> light_user_info =
+      std::static_pointer_cast<const tpk::parse::LightUserInfo>(
+          parser_->GetManifestData(tpk::parse::LightUserInfo::Key()));
+  if (!light_user_info) {
+    manifest->light_user_switch_mode = strdup("default");
+    return true;
+  }
+
+  if (light_user_info->switch_mode().empty()) {
+    LOG(ERROR) << "Invalid switch mode";
+    return false;
+  }
+
+  manifest->light_user_switch_mode =
+      strdup(light_user_info->switch_mode().c_str());
+
+  return true;
+}
+
 bool StepParseManifest::CheckFeatures() {
   auto feature_info =
         std::static_pointer_cast<const tpk::parse::FeatureInfo>(
@@ -1072,6 +1063,33 @@ bool StepParseManifest::FillSplashScreen(application_x* app,
   return true;
 }
 
+template <typename T>
+bool StepParseManifest::FillResControl(application_x* app,
+    const T& res_control_list) {
+  for (auto& res_control : res_control_list) {
+    if (res_control.resource_type().empty())
+      continue;
+
+    res_control_x* rc =
+        static_cast<res_control_x*>(calloc(1, sizeof(res_control_x)));
+    if (!rc) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
+
+    rc->res_type = strdup(res_control.resource_type().c_str());
+    if (!res_control.min_res_version().empty())
+      rc->min_res_version = strdup(res_control.min_res_version().c_str());
+    if (!res_control.max_res_version().empty())
+      rc->max_res_version = strdup(res_control.max_res_version().c_str());
+    if (!res_control.auto_close().empty())
+      rc->auto_close = strdup(res_control.auto_close().c_str());
+
+    app->res_control = g_list_prepend(app->res_control, rc);
+  }
+  return true;
+}
+
 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
     const std::string& key, const std::string& val) {
   std::string operation;
@@ -1150,16 +1168,20 @@ bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
   if (manifest_location_ == ManifestLocation::INSTALLED) {
     // recovery of tep value for installed package
-    std::string old_tep = context_->pkg_query->TepPath();
+    PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
+    std::string old_tep = pkg_query.TepPath();
     if (!old_tep.empty())
       manifest->tep_name = strdup(old_tep.c_str());
 
     // recovery of zip mount file for installed package
-    std::string zip_mount_file = context_->pkg_query->ZipMountFile();
+    std::string zip_mount_file = pkg_query.ZipMountFile();
     if (!zip_mount_file.empty())
       manifest->zip_mount_file = strdup(zip_mount_file.c_str());
   }
 
+  if (manifest->application == nullptr)
+    return true;
+
   // in case of hybrid package, main app is already set by wgt-backend
   application_x* mainapp = nullptr;
   if (!context_->cross_app_rules.get()) {
@@ -1188,27 +1210,6 @@ bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
   return true;
 }
 
-template <typename T>
-bool StepParseManifest::FillComponentInfo(application_x* app,
-                                          const T& component_list) {
-  for (auto& component : component_list.components()) {
-    component_x* comp =
-        static_cast<component_x*>(calloc(1, sizeof(component_x)));
-    if (!comp) {
-      LOG(ERROR) << "Out of memory";
-      return false;
-    }
-
-    comp->id = strdup(component.id().c_str());
-    comp->type = strdup(component.type().c_str());
-    comp->launch_mode = strdup(component.launch_mode().c_str());
-
-    app->components = g_list_append(app->components, comp);
-  }
-
-  return true;
-}
-
 bool StepParseManifest::FillComponentBasedApplicationInfo(
     manifest_x* manifest) {
   std::shared_ptr<const tpk::parse::ComponentBasedApplicationInfoList>
@@ -1260,7 +1261,12 @@ bool StepParseManifest::FillComponentBasedApplicationInfo(
     app->package = strdup(manifest->package);
     app->support_disable = strdup(manifest->support_disable);
     app->launch_mode = strdup("single");
-    app->api_version = strdup(manifest->api_version);
+    if (!application.app_info.api_version().empty())
+      app->api_version = strdup(application.app_info.api_version().c_str());
+    else
+      app->api_version = strdup(manifest->api_version);
+    app->splash_screen_display =
+        strdup(application.app_info.splash_screen_display().c_str());
     manifest->application = g_list_append(manifest->application, app);
     if (bf::path(application.app_info.exec().c_str()).is_absolute()) {
       app->exec = strdup(application.app_info.exec().c_str());
@@ -1275,7 +1281,17 @@ bool StepParseManifest::FillComponentBasedApplicationInfo(
       return false;
     if (!FillBackgroundCategoryInfo(app, application.background_category))
       return false;
-    if (!FillComponentInfo(app, application.components))
+    if (!FillAppControl(app, application.app_control))
+      return false;
+    if (!FillDataControl(app, application.data_control))
+      return false;
+    if (!FillMetadata(app, application.meta_data))
+      return false;
+    if (!FillCategories(app, application.categories))
+      return false;
+    if (!FillSplashScreen(app, application.app_splashscreens))
+      return false;
+    if (!FillResControl(app, application.res_controls))
       return false;
   }
 
@@ -1311,6 +1327,8 @@ bool StepParseManifest::FillManifestX(manifest_x* manifest) {
     return false;
   if (!FillDependencyInfo(manifest))
     return false;
+  if (!FillLightUserInfo(manifest))
+    return false;
   return true;
 }
 
@@ -1343,12 +1361,6 @@ Step::Status StepParseManifest::process() {
           parser_->GetManifestData(app_keys::kManifestKey));
 
   context_->pkgid.set(info->package());
-  if (!context_->pkg_query) {
-    std::unique_ptr<PkgQueryInterface> pkgquery(
-        new PkgQueryInterface(context_->pkgid.get(),
-                              context_->uid.get()));
-    context_->pkg_query = std::move(pkgquery);
-  }
 
   manifest_x* manifest =
       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));