Fix backup plugin execution information
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_parse_manifest.cc
index 8f119ea..39a3341 100644 (file)
@@ -4,23 +4,30 @@
 
 #include "common/step/configuration/step_parse_manifest.h"
 
+#include <boost/tokenizer.hpp>
+
 #include <pkgmgr/pkgmgr_parser.h>
 #include <pkgmgr-info.h>
 
-#include <tpk_manifest_handlers/account_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>
+#include <tpk_manifest_handlers/provides_appdefined_privileges_handler.h>
 #include <tpk_manifest_handlers/service_application_handler.h>
 #include <tpk_manifest_handlers/shortcut_handler.h>
+#include <tpk_manifest_handlers/trust_anchor_handler.h>
 #include <tpk_manifest_handlers/ui_application_handler.h>
 #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/app_installer.h"
-#include "common/backup_paths.h"
+#include "common/feature_validator.h"
 #include "common/installer_context.h"
+#include "common/utils/paths.h"
+#include "common/privileges.h"
+#include "common/pkgmgr_registration.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;
@@ -42,8 +53,17 @@ namespace bf = boost::filesystem;
 namespace {
 
 const char kManifestFileName[] = "tizen-manifest.xml";
-
-}  // namepsace
+const char kInstalledInternally[] = "installed_internal";
+const char kInstalledExternally[] = "installed_external";
+const char kPortraitOrientation[] = "portrait";
+const char kLandscapeOrientation[] = "landscape";
+const char kOperationEffectKey[] = "operation_effect";
+const char kLaunchEffectKey[] = "launch_effect";
+const char kPortraitEffectImageValue[] = "portrait-effectimage";
+const char kLandscapeEffectImageValue[] = "landscape-effectimage";
+const char kIndicatorDisplayValue[] = "indicatordisplay";
+
+}  // namespace
 
 namespace common_installer {
 namespace configuration {
@@ -59,6 +79,9 @@ StepParseManifest::StepParseManifest(
 Step::Status StepParseManifest::precheck() {
   switch (manifest_location_) {
     case ManifestLocation::RECOVERY:
+      if (context_->pkgid.get().empty())
+        return Status::RECOVERY_DONE;
+      break;
     case ManifestLocation::INSTALLED:
       if (context_->pkgid.get().empty()) {
         LOG(ERROR) << "Package id is not set";
@@ -82,25 +105,45 @@ bool StepParseManifest::LocateConfigFile() {
   boost::filesystem::path manifest;
   switch (manifest_location_) {
     case ManifestLocation::RECOVERY: {
-      context_->pkg_path.set(
-          context_->root_application_path.get() / context_->pkgid.get());
       bf::path backup_path = common_installer::GetBackupPathForPackagePath(
-          context_->pkg_path.get()) / kManifestFileName;
-      bf::path in_package_path = context_->pkg_path.get() / kManifestFileName;
-      if (bf::exists(backup_path))
+          context_->GetPkgPath()) / kManifestFileName;
+      bf::path in_package_path = context_->GetPkgPath() / kManifestFileName;
+      bf::path install_path =
+          bf::path(getUserManifestPath(context_->uid.get(),
+                      context_->is_readonly_package.get()))
+              / bf::path(context_->pkgid.get());
+      install_path += ".xml";
+      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(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();
+      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();
       bf::path xml_path =
-          bf::path(getUserManifestPath(context_->uid.get(),
-              context_->is_preload_request.get()))
+          bf::path(getUserManifestPath(uid, is_readonly))
           / bf::path(context_->pkgid.get());
       xml_path += ".xml";
       context_->xml_path.set(xml_path);
       manifest = context_->xml_path.get();
+      if (!boost::filesystem::exists(manifest)) {
+        /* This routine has added for platform update */
+        manifest = context_->unpacked_dir_path.get();
+        manifest /= kManifestFileName;
+      }
       break;
     }
     case ManifestLocation::PACKAGE: {
@@ -123,12 +166,29 @@ bool StepParseManifest::LocateConfigFile() {
   return true;
 }
 
+int StepParseManifest::GetSupportModeVal(std::string support_mode) {
+  int mode = 0;
+  std::size_t found = std::string::npos;
+
+  found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
+  if (found != std::string::npos)
+    mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
+
+  found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
+  if (found != std::string::npos)
+    mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
+
+  found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
+  if (found != std::string::npos)
+    mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
+
+  return 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;
 }
 
@@ -141,41 +201,26 @@ 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));
-
-  // mandatory check
-  if (!ui_application_list && !service_application_list &&
-      !widget_application_list && !watch_application_list) {
-    LOG(ERROR) << "UI Application or Service Application or Widget Application "
-                  "or Watch Application are 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());
   manifest->package = strdup(pkg_info->package().c_str());
   manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
+  manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
   manifest->appsetting = strdup("false");
-  manifest->support_disable = strdup("false");
+  manifest->support_disable = strdup(pkg_info->support_disable().c_str());
   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());
 
+  common_installer::RequestType req_type = context_->request_type.get();
   if (pkg_info->type().empty()) {
-    common_installer::RequestType req_type = context_->request_type.get();
-    if (req_type == RequestType::ManifestDirectInstall ||
-        req_type == RequestType::ManifestDirectUpdate)
+    if ((req_type == RequestType::ManifestDirectInstall ||
+        req_type == RequestType::ManifestDirectUpdate) &&
+        context_->is_readonly_package.get())
       manifest->type = strdup("rpm");
     else
       manifest->type = strdup("tpk");
@@ -185,11 +230,15 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
 
   for (auto& pair : pkg_info->labels()) {
     label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
+    if (!label) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     if (!pair.first.empty())
       label->lang = strdup(pair.first.c_str());
     else
       label->lang = strdup(DEFAULT_LOCALE);
-    label->name = strdup(pair.second.c_str());
+    label->text = strdup(pair.second.c_str());
     manifest->label = g_list_append(manifest->label, label);
   }
 
@@ -203,18 +252,46 @@ bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
     }
   }
 
-  if (ui_application_list) {
-    manifest->mainapp_id =
-        strdup(ui_application_list->items[0].app_info.appid().c_str());
-  } else if (service_application_list) {
-    manifest->mainapp_id =
-        strdup(service_application_list->items[0].app_info.appid().c_str());
-  } else if (widget_application_list) {
-    manifest->mainapp_id =
-        strdup(widget_application_list->items[0].app_info.appid().c_str());
-  } else if (watch_application_list) {
-    manifest->mainapp_id =
-        strdup(watch_application_list->items[0].app_info.appid().c_str());
+  // 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 = pkg_query.StorageForPkgId();
+      if (storage.empty()) {
+        // Failed to query installation storage, assign internal
+        manifest->installed_storage = strdup(kInstalledInternally);
+      } else {
+        manifest->installed_storage = strdup(storage.c_str());
+      }
+    } else {
+      manifest->installed_storage = strdup(kInstalledInternally);
+    }
+  }
+
+  // retrieve and set plugin execution info if exists
+  if (store_location_ == StoreLocation::BACKUP && (
+      manifest_location_ == ManifestLocation::INSTALLED ||
+      manifest_location_ == ManifestLocation::RECOVERY)) {
+    std::vector<PkgQueryInterface::PluginInfo> plugin_list;
+    pkg_query.PluginExecutionInfo(&plugin_list);
+
+    for (const auto& plugin_info : plugin_list) {
+      plugin_x* plugin =
+          reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
+      if (!plugin) {
+        LOG(ERROR) << "Out of memory";
+        return false;
+      }
+
+      plugin->pkgid = strdup(manifest->package);
+      plugin->appid = strdup(std::get<1>(plugin_info).c_str());
+      plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
+      plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
+      manifest->plugin = g_list_append(manifest->plugin, plugin);
+    }
   }
   return true;
 }
@@ -228,6 +305,10 @@ bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
     return true;
 
   author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
+  if (!author) {
+    LOG(ERROR) << "Out of memory";
+    return false;
+  }
   author->text = strdup(author_info->name().c_str());
   author->email = strdup(author_info->email().c_str());
   author->href = strdup(author_info->href().c_str());
@@ -247,6 +328,10 @@ bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
   for (auto& desc : description_info->descriptions) {
     description_x* description = reinterpret_cast<description_x*>
         (calloc(1, sizeof(description_x)));
+    if (!description) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     description->text = strdup(desc.description().c_str());
     description->lang = !desc.xml_lang().empty() ?
         strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
@@ -262,11 +347,79 @@ bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
   if (!perm_info)
     return true;
 
-  std::set<std::string> privileges = perm_info->GetPrivileges();
+  const auto& privileges = perm_info->GetPrivileges();
   for (auto& priv : privileges) {
-    manifest->privileges = g_list_append(manifest->privileges,
-                                         strdup(priv.c_str()));
+    privilege_x* privilege =
+        reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
+    if (!privilege) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
+    privilege->value = strdup(priv.first.c_str());
+    privilege->type = strdup(priv.second.c_str());
+    manifest->privileges = g_list_append(manifest->privileges, privilege);
+  }
+
+  const auto& appdef_privileges_list =
+      perm_info->GetAppDefinedPrivilegeInfoList();
+  for (auto& appdef_info : appdef_privileges_list) {
+    appdefined_privilege_x* privilege =
+        reinterpret_cast<appdefined_privilege_x*>(calloc(1,
+            sizeof(appdefined_privilege_x)));
+    if (privilege == nullptr) {
+      LOG(ERROR) << "Memory alloc failure";
+      return false;
+    }
+    auto& priv = appdef_info.GetAppDefinedPrivilege();
+    privilege->value = strdup(priv.privilege.c_str());
+    privilege->type = strdup(priv.type.c_str());
+    if (!priv.license.empty()) {
+      if (bf::path(priv.license).is_absolute())
+        privilege->license = strdup(priv.license.c_str());
+      else
+        privilege->license = strdup((context_->GetPkgPath()
+            / priv.license).c_str());
+    }
+    manifest->appdefined_privileges =
+        g_list_append(manifest->appdefined_privileges, privilege);
+  }
+
+  return true;
+}
+
+bool StepParseManifest::FillProvidesAppDefinedPrivileges(
+    manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
+      priv_info = std::static_pointer_cast<
+          const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
+              parser_->GetManifestData(
+                  app_keys::kProvidesAppDefinedPrivilegesKey));
+  if (!priv_info)
+    return true;
+
+  const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
+  for (auto& appdef_info : privileges_list) {
+    appdefined_privilege_x* privilege =
+        reinterpret_cast<appdefined_privilege_x*>(calloc(1,
+            sizeof(appdefined_privilege_x)));
+    if (privilege == nullptr) {
+      LOG(ERROR) << "Memory alloc failure";
+      return false;
+    }
+    auto& priv = appdef_info.GetAppDefinedPrivilege();
+    privilege->value = strdup(priv.privilege.c_str());
+    privilege->type = strdup(priv.type.c_str());
+    if (!priv.license.empty()) {
+      if (bf::path(priv.license).is_absolute())
+        privilege->license = strdup(priv.license.c_str());
+      else
+        privilege->license = strdup((context_->GetPkgPath()
+            / priv.license).c_str());
+    }
+    manifest->provides_appdefined_privileges =
+        g_list_append(manifest->provides_appdefined_privileges, privilege);
   }
+
   return true;
 }
 
@@ -278,37 +431,52 @@ bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
     return true;
 
   for (const auto& application : widget_application_list->items) {
-    // if there is no app yet, set this app as mainapp
-    bool main_app = manifest->application == nullptr;
+    int package_support_mode_val = atoi(manifest->support_mode);
+    int app_support_mode_val = package_support_mode_val |
+        GetSupportModeVal(application.app_info.support_mode());
 
     application_x* widget_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!widget_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     widget_app->appid = strdup(application.app_info.appid().c_str());
     widget_app->launch_mode =
         strdup(application.app_info.launch_mode().c_str());
     widget_app->multiple = strdup("false");
-    widget_app->nodisplay = strdup("true");
+    widget_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
+    widget_app->support_mode =
+        strdup((std::to_string(app_support_mode_val)).c_str());
     widget_app->taskmanage = strdup("false");
     widget_app->indicatordisplay = strdup("false");
-    widget_app->type = strdup("capp");
+    if (!application.app_info.type().empty())
+      widget_app->type = strdup(application.app_info.type().c_str());
+    else
+      widget_app->type = strdup("capp");
     widget_app->component_type = strdup("widgetapp");
     widget_app->hwacceleration =
         strdup(application.app_info.hwacceleration().c_str());
     widget_app->onboot = strdup("false");
     widget_app->autorestart = strdup("false");
-    widget_app->mainapp = main_app ? strdup("true") : strdup("false");
-    widget_app->enabled = strdup("true");
+    widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
     widget_app->screenreader = strdup("use-system-setting");
     widget_app->recentimage = strdup("false");
     widget_app->launchcondition = strdup("false");
     widget_app->guestmode_visibility = strdup("true");
     widget_app->permission_type = strdup("normal");
-    widget_app->ambient_support = strdup("false");
+    widget_app->support_ambient = strdup("false");
     widget_app->effectimage_type = strdup("image");
     widget_app->submode = strdup("false");
     widget_app->process_pool = strdup("false");
     widget_app->package = strdup(manifest->package);
     widget_app->support_disable = strdup(manifest->support_disable);
+    widget_app->launch_mode = strdup("single");
+    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());
@@ -327,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;
 }
@@ -339,23 +509,30 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
     return true;
 
   for (const auto& application : service_application_list->items) {
-    // if there is no app yet, set this app as mainapp
-    bool main_app = manifest->application == nullptr;
+    int package_support_mode_val = atoi(manifest->support_mode);
+    int app_support_mode_val = package_support_mode_val |
+        GetSupportModeVal(application.app_info.support_mode());
 
     application_x* service_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!service_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     service_app->appid = strdup(application.app_info.appid().c_str());
     service_app->multiple = strdup(application.app_info.multiple().c_str());
     service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
+    service_app->support_mode =
+        strdup((std::to_string(app_support_mode_val)).c_str());
     service_app->autorestart =
         strdup(application.app_info.auto_restart().c_str());
     service_app->onboot = strdup(application.app_info.on_boot().c_str());
-    service_app->type = strdup(application.app_info.type().c_str());
-    service_app->process_pool =
-        strdup(application.app_info.process_pool().c_str());
+    if (!application.app_info.type().empty())
+      service_app->type = strdup(application.app_info.type().c_str());
+    else
+      service_app->type = strdup("capp");
     service_app->component_type = strdup("svcapp");
-    service_app->mainapp = main_app ? strdup("true") : strdup("false");
-    service_app->enabled = strdup("true");
+    service_app->mainapp = strdup(application.app_info.mainapp().c_str());
     service_app->nodisplay = strdup("true");
     service_app->hwacceleration = strdup("default");
     service_app->screenreader = strdup("use-system-setting");
@@ -367,9 +544,15 @@ bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
     service_app->permission_type = strdup("normal");
     service_app->submode = strdup("false");
     service_app->process_pool = strdup("false");
-    service_app->ambient_support = strdup("false");
+    service_app->support_ambient = strdup("false");
     service_app->package = strdup(manifest->package);
     service_app->support_disable = strdup(manifest->support_disable);
+    service_app->launch_mode = strdup("single");
+    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());
@@ -393,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;
 }
@@ -405,17 +590,27 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
     return true;
 
   for (const auto& application : ui_application_list->items) {
-    // if there is no app yet, set this app as mainapp
-    bool main_app = manifest->application == nullptr;
+    int package_support_mode_val = atoi(manifest->support_mode);
+    int app_support_mode_val = package_support_mode_val |
+        GetSupportModeVal(application.app_info.support_mode());
 
     application_x* ui_app =
         static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!ui_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     ui_app->appid = strdup(application.app_info.appid().c_str());
     ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
     ui_app->multiple = strdup(application.app_info.multiple().c_str());
     ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
+    ui_app->support_mode =
+        strdup((std::to_string(app_support_mode_val)).c_str());
     ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
-    ui_app->type = strdup(application.app_info.type().c_str());
+    if (!application.app_info.type().empty())
+      ui_app->type = strdup(application.app_info.type().c_str());
+    else
+      ui_app->type = strdup("capp");
     ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
     ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
     ui_app->submode = strdup(application.app_info.submode().c_str());
@@ -425,12 +620,20 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
     if (!application.app_info.effectimage_type().empty())
       ui_app->effectimage_type =
           strdup(application.app_info.effectimage_type().c_str());
-    if (!application.app_info.portrait_image().empty())
+    if (!application.app_info.portrait_image().empty()) {
       ui_app->portraitimg =
           strdup(application.app_info.portrait_image().c_str());
-    if (!application.app_info.landscape_image().empty())
+      AppendSplashScreen(ui_app, application.app_info.portrait_image(),
+          application.app_info.effectimage_type(), {}, kPortraitOrientation,
+          application.app_info.indicator_display(), {}, {});
+    }
+    if (!application.app_info.landscape_image().empty()) {
       ui_app->landscapeimg =
           strdup(application.app_info.landscape_image().c_str());
+      AppendSplashScreen(ui_app, application.app_info.landscape_image(),
+          application.app_info.effectimage_type(), {}, kLandscapeOrientation,
+          application.app_info.indicator_display(), {}, {});
+    }
     ui_app->submode_mainid =
         strdup(application.app_info.submode_mainid().c_str());
     ui_app->hwacceleration =
@@ -438,18 +641,21 @@ bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
     ui_app->onboot = strdup("false");
     ui_app->autorestart = strdup("false");
     ui_app->component_type = strdup("uiapp");
-    ui_app->mainapp = main_app ? strdup("true") : strdup("false");
-    ui_app->enabled = strdup("true");
+    ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
     ui_app->screenreader = strdup("use-system-setting");
     ui_app->recentimage = strdup("false");
     ui_app->launchcondition = strdup("false");
     ui_app->guestmode_visibility = strdup("true");
     ui_app->permission_type = strdup("normal");
-    ui_app->ambient_support = strdup("false");
+    ui_app->support_ambient = strdup("false");
     ui_app->package = strdup(manifest->package);
     ui_app->support_disable = strdup(manifest->support_disable);
     ui_app->splash_screen_display =
         strdup(application.app_info.splash_screen_display().c_str());
+    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());
@@ -477,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;
 }
@@ -489,10 +697,16 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
     return true;
 
   for (const auto& watch_application : watch_application_list->items) {
-    bool main_app = manifest->application == nullptr;
+    int package_support_mode_val = atoi(manifest->support_mode);
+    int app_support_mode_val = package_support_mode_val |
+        GetSupportModeVal(watch_application.app_info.support_mode());
 
     application_x* watch_app =
              static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!watch_app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     watch_app->appid = strdup(watch_application.app_info.appid().c_str());
 
     if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
@@ -504,12 +718,14 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
                                watch_application.app_info.exec()).c_str());
     watch_app->nodisplay = strdup("true");
     watch_app->multiple = strdup("false");
-    watch_app->type = strdup(watch_application.app_info.type().c_str());
+    if (!watch_application.app_info.type().empty())
+      watch_app->type = strdup(watch_application.app_info.type().c_str());
+    else
+      watch_app->type = strdup("capp");
     watch_app->taskmanage = strdup("false");
-    watch_app->enabled = strdup("true");
     watch_app->hwacceleration = strdup("default");
     watch_app->screenreader = strdup("use-system-setting");
-    watch_app->mainapp = main_app ? strdup("true") : strdup("false");
+    watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
     watch_app->recentimage = strdup("false");
     watch_app->launchcondition = strdup("false");
     watch_app->indicatordisplay = strdup("true");
@@ -522,17 +738,116 @@ bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
     watch_app->process_pool = strdup("false");
     watch_app->autorestart = strdup("false");
     watch_app->onboot = strdup("false");
-    watch_app->support_disable = strdup(manifest->support_disable);
+    watch_app->support_mode =
+        strdup((std::to_string(app_support_mode_val)).c_str());
     watch_app->ui_gadget = strdup("false");
     watch_app->launch_mode = strdup("single");
-    watch_app->ambient_support =
+    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;
     if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
       return false;
-    manifest->application = g_list_append(manifest->application, watch_app);
+    if (!FillMetadata(watch_app, watch_application.meta_data))
+      return false;
+    if (!FillCategories(watch_app, watch_application.categories))
+      return false;
+    if (!FillBackgroundCategoryInfo(watch_app,
+        watch_application.background_category))
+      return false;
+    if (!FillResControl(watch_app, watch_application.res_controls))
+      return false;
+  }
+  return true;
+}
+
+bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
+      std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
+          parser_->GetManifestData(app_keys::kTrustAnchorKey));
+  if (!trust_anchor_info)
+    return true;
+
+  if (trust_anchor_info->get_use_system_certs().empty()) {
+    LOG(ERROR) << "Invalid trust anchor data";
+    return false;
+  }
+
+  manifest->use_system_certs =
+      strdup(trust_anchor_info->get_use_system_certs().c_str());
+
+  return true;
+}
+
+bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::DependenciesInfo> dependencies_info =
+      std::static_pointer_cast<const tpk::parse::DependenciesInfo>(
+          parser_->GetManifestData(app_keys::kDependenciesKey));
+  if (!dependencies_info)
+    return true;
+
+  for (const auto& dependency : dependencies_info->dependencies()) {
+    dependency_x* dep =
+        static_cast<dependency_x*>(calloc(1, sizeof(dependency_x)));
+    if (!dep) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
+    dep->depends_on = strdup(dependency.pkgid().c_str());
+    dep->type = strdup(dependency.type().c_str());
+    if (!dependency.required_version().empty())
+      dep->required_version = strdup(dependency.required_version().c_str());
+    manifest->dependencies = g_list_append(manifest->dependencies, dep);
   }
+
+  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>(
+            parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
+  if (!feature_info)
+    return true;
+
+  std::string error;
+  FeatureValidator validator(feature_info->features());
+  if (!validator.Validate(&error)) {
+    LOG(ERROR) << "Feature validation error. " << error;
+    return false;
+  }
+
   return true;
 }
 
@@ -545,11 +860,27 @@ bool StepParseManifest::FillAppControl(application_x* app,
   for (const auto& control : app_control_list) {
     appcontrol_x* app_control =
           static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
+    if (!app_control) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     app_control->operation = strdup(control.operation().c_str());
     if (!control.mime().empty())
       app_control->mime = strdup(control.mime().c_str());
     if (!control.uri().empty())
       app_control->uri = strdup(control.uri().c_str());
+    if (!control.visibility().empty())
+      app_control->visibility = strdup(control.visibility().c_str());
+    else
+      app_control->visibility = strdup("local-only");
+    if (!control.id().empty())
+      app_control->id = strdup(control.id().c_str());
+    else
+      app_control->id = strdup("no-name-app-control");
+    for (const auto& priv : control.privileges()) {
+      app_control->privileges = g_list_append(app_control->privileges,
+          strdup(priv.c_str()));
+    }
     app->appcontrol = g_list_append(app->appcontrol, app_control);
   }
   return true;
@@ -564,9 +895,21 @@ bool StepParseManifest::FillDataControl(application_x* app,
   for (const auto& control : data_control_list) {
     datacontrol_x* data_control =
           static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
+    if (!data_control) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     data_control->access = strdup(control.access().c_str());
     data_control->providerid = strdup(control.providerid().c_str());
     data_control->type = strdup(control.type().c_str());
+    if (!control.trusted().empty())
+      data_control->trusted = strdup(control.trusted().c_str());
+    else
+      data_control->trusted = strdup("false");
+    for (const auto& priv : control.privileges())
+      data_control->privileges = g_list_append(data_control->privileges,
+          strdup(priv.c_str()));
+
     app->datacontrol = g_list_append(app->datacontrol, data_control);
   }
   return true;
@@ -576,7 +919,11 @@ template <typename T>
 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
                                          const T& icons_info) {
   for (auto& application_icon : icons_info.icons()) {
-    icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
+    icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
+    if (!icon) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     bf::path text;
     if (bf::path(application_icon.path()).is_absolute()) {
       text = application_icon.path();
@@ -608,6 +955,10 @@ bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
   for (const auto& control : label_list) {
     label_x* label =
           static_cast<label_x*>(calloc(1, sizeof(label_x)));
+    if (!label) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     // NOTE: name is an attribute, but the xml writer uses it as text.
     // This must be fixed in whole app-installer modules, including wgt.
     // Current implementation is just for compatibility.
@@ -629,9 +980,15 @@ bool StepParseManifest::FillMetadata(application_x* app,
   for (auto& meta : meta_data_list) {
     metadata_x* metadata =
         static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
+    if (!metadata) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     metadata->key = strdup(meta.key().c_str());
     metadata->value = strdup(meta.val().c_str());
     app->metadata = g_list_append(app->metadata, metadata);
+
+    GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
   }
   return true;
 }
@@ -646,39 +1003,145 @@ bool StepParseManifest::FillCategories(application_x* manifest,
   return true;
 }
 
+void StepParseManifest::AppendSplashScreen(application_x* app,
+    const std::string& src, const std::string& type, const std::string& dpi,
+    const std::string& orientation, const std::string& indicatordisplay,
+    const std::string& operation, const std::string& color_depth) {
+  splashscreen_x* splashscreen =
+      static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
+  if (!splashscreen) {
+    LOG(ERROR) << "Out of memory";
+    return;
+  }
+  if (bf::path(src).is_absolute()) {
+    splashscreen->src = strdup(src.c_str());
+  } else {
+    bf::path full_path = context_->GetPkgPath() / src;
+    splashscreen->src = strdup(full_path.string().c_str());
+  }
+  if (src.substr(src.find_last_of(".") + 1) == "edj")
+    splashscreen->type = strdup("edj");
+  else if (type == "edj")
+    splashscreen->type = strdup("edj");
+  else
+    splashscreen->type = strdup("img");
+  if (!dpi.empty())
+    splashscreen->dpi = strdup(dpi.c_str());
+  splashscreen->orientation = strdup(orientation.c_str());
+  if (!indicatordisplay.empty())
+    splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
+  else
+    splashscreen->indicatordisplay = strdup("true");
+  if (operation == "launch_effect")
+    splashscreen->operation = strdup("launch-effect");
+  else if (!operation.empty())
+    splashscreen->operation = strdup(operation.c_str());
+  else
+    splashscreen->operation = strdup("launch-effect");
+  if (!color_depth.empty())
+    splashscreen->color_depth = strdup(color_depth.c_str());
+  else
+    splashscreen->color_depth = strdup("24");
+  app->splashscreens = g_list_append(app->splashscreens, splashscreen);
+}
+
 template <typename T>
 bool StepParseManifest::FillSplashScreen(application_x* app,
                                      const T& splashscreens_info) {
   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() == true)
-      splashscreen->src = strdup(splash_screen.src().c_str());
+    std::string src;
+    if (context_->is_readonly_package.get())
+      src = splash_screen.src();
     else
-      splashscreen->src = strdup((context_->root_application_path.get()
-        / app->package / "shared" / "res" / splash_screen.src()).c_str());
-
-    splashscreen->type = strdup(splash_screen.type().c_str());
-    if (!splash_screen.dpi().empty())
-      splashscreen->dpi = strdup(splash_screen.dpi().c_str());
-    splashscreen->orientation = strdup(splash_screen.orientation().c_str());
-    if (!splash_screen.indicatordisplay().empty())
-      splashscreen->indicatordisplay = strdup(
-          splash_screen.indicatordisplay().c_str());
-    else
-      splashscreen->indicatordisplay = strdup("true");
-    if (!splash_screen.operation().empty())
-      splashscreen->operation = strdup(splash_screen.operation().c_str());
-    app->splashscreens = g_list_append(app->splashscreens, splashscreen);
+      src = bf::path(context_->root_application_path.get()
+        / app->package / "shared" / "res" / splash_screen.src()).string();
+
+    AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
+        splash_screen.orientation(), splash_screen.indicatordisplay(),
+        splash_screen.operation(), splash_screen.colordepth());
+  }
+  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;
+  if (key.find(kOperationEffectKey) != std::string::npos) {
+    boost::char_separator<char> sep("=");
+    boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
+    auto iter = tokens.begin();
+    iter++;
+    operation = *iter;
+  } else if (key.find(kLaunchEffectKey) != std::string::npos) {
+    operation = std::string("launch-effect");
+  } else {
+    // not a metadata splashscreen
+    return;
+  }
+
+  boost::char_separator<char> sep("=|");
+  boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
+  auto iter = tokens.begin();
+  std::string portrait_src;
+  std::string landscape_src;
+  std::string indicatordisplay;
+  while (iter != tokens.end()) {
+    if (!(*iter).compare(kPortraitEffectImageValue)) {
+      iter++;
+      portrait_src = *iter;
+    } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
+      iter++;
+      landscape_src = *iter;
+    } else if (!(*iter).compare(kIndicatorDisplayValue)) {
+      iter++;
+      indicatordisplay = *iter;
+    }
+    iter++;
+  }
+  if (!portrait_src.empty())
+    AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
+        indicatordisplay, operation, {});
+  if (!landscape_src.empty())
+    AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
+        indicatordisplay, operation, {});
+}
+
 bool StepParseManifest::FillImage(application_x* app,
                           const tpk::parse::ApplicationImagesInfo& image_list) {
   for (auto& app_image : image_list.images) {
     image_x* image =
         static_cast<image_x*>(calloc(1, sizeof(image_x)));
+    if (!image) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
     const std::string& lang = app_image.lang();
     if (!lang.empty())
       image->lang = strdup(lang.c_str());
@@ -691,56 +1154,145 @@ bool StepParseManifest::FillImage(application_x* app,
   return true;
 }
 
-bool StepParseManifest::FillAccounts() {
-  std::shared_ptr<const tpk::parse::AccountInfo> account_info =
-      std::static_pointer_cast<const tpk::parse::AccountInfo>(
-        parser_->GetManifestData(app_keys::kAccountKey));
-  if (!account_info)
-    return true;
+template <typename T>
+bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
+    const T& background_category_data_list) {
+  for (const auto& background_category : background_category_data_list) {
+    app->background_category = g_list_append(
+        app->background_category, strdup(background_category.value().c_str()));
+  }
 
-  AccountInfo info;
-  for (auto& account : account_info->accounts()) {
-    SingleAccountInfo single_info;
-    single_info.capabilities = account.capabilities;
-    single_info.icon_paths = account.icon_paths;
-    single_info.multiple_account_support = account.multiple_account_support;
-    single_info.names = account.labels;
-    // appid has the same value as package
-    single_info.appid =  account.app_id;
-    single_info.providerid = account.provider_id;
-    info.set_account(single_info);
-  }
-  context_->manifest_plugins_data.get().account_info.set(info);
   return true;
 }
 
-bool StepParseManifest::FillShortcuts() {
-  std::shared_ptr<const tpk::parse::ShortcutListInfo> shortcut_info =
-      std::static_pointer_cast<const tpk::parse::ShortcutListInfo>(
-        parser_->GetManifestData(app_keys::kShortcutListKey));
-  if (!shortcut_info)
+bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
+  if (manifest_location_ == ManifestLocation::INSTALLED) {
+    // recovery of tep value for installed package
+    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 = pkg_query.ZipMountFile();
+    if (!zip_mount_file.empty())
+      manifest->zip_mount_file = strdup(zip_mount_file.c_str());
+  }
+
+  if (manifest->application == nullptr)
     return true;
 
-  ShortcutListInfo list;
-  for (auto& shortcut : shortcut_info->shortcuts) {
-    ShortcutInfo single_info;
-    single_info.app_id = shortcut.app_id;
-    single_info.extra_data = shortcut.extra_data;
-    single_info.extra_key = shortcut.extra_key;
-    single_info.icon = shortcut.icon;
-    single_info.labels =  shortcut.labels;
-    list.push_back(single_info);
-  }
-  context_->manifest_plugins_data.get().shortcut_info.set(list);
+  // in case of hybrid package, main app is already set by wgt-backend
+  application_x* mainapp = nullptr;
+  if (!context_->cross_app_rules.get()) {
+    // find mainapp
+    for (const auto& app : GListRange<application_x*>(manifest->application)) {
+      if (!strcmp(app->mainapp, "true")) {
+        mainapp = app;
+        break;
+      }
+    }
+    if (mainapp == nullptr)
+      mainapp = reinterpret_cast<application_x*>(
+          g_list_first(manifest->application)->data);
+    free(mainapp->mainapp);
+    mainapp->mainapp = strdup("true");
+    manifest->mainapp_id = strdup(mainapp->appid);
+  }
+
+  // mark mainapp=false at other apps
+  for (auto& app : GListRange<application_x*>(manifest->application)) {
+    if (app == mainapp)
+      continue;
+    free(app->mainapp);
+    app->mainapp = strdup("false");
+  }
   return true;
 }
 
-template <typename T>
-bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
-    const T& background_category_data_list) {
-  for (const auto& background_category : background_category_data_list) {
-    app->background_category = g_list_append(
-        app->background_category, strdup(background_category.value().c_str()));
+bool StepParseManifest::FillComponentBasedApplicationInfo(
+    manifest_x* manifest) {
+  std::shared_ptr<const tpk::parse::ComponentBasedApplicationInfoList>
+      component_based_application_list = std::static_pointer_cast<
+          const tpk::parse::ComponentBasedApplicationInfoList>(
+              parser_->GetManifestData(
+                  app_keys::kComponentBasedApplicationKey));
+  if (!component_based_application_list)
+    return true;
+
+  for (const auto& application : component_based_application_list->items) {
+    int package_support_mode_val = atoi(manifest->support_mode);
+    int app_support_mode_val = package_support_mode_val |
+        GetSupportModeVal(application.app_info.support_mode());
+
+    application_x* app =
+        static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (!app) {
+      LOG(ERROR) << "Out of memory";
+      return false;
+    }
+
+    app->appid = strdup(application.app_info.appid().c_str());
+    app->launch_mode = strdup(application.app_info.launch_mode().c_str());
+    app->multiple = strdup(application.app_info.multiple().c_str());
+    app->nodisplay = strdup(application.app_info.nodisplay().c_str());
+    app->support_mode = strdup((std::to_string(app_support_mode_val)).c_str());
+    app->taskmanage = strdup(application.app_info.taskmanage().c_str());
+    if (!application.app_info.type().empty())
+      app->type = strdup(application.app_info.type().c_str());
+    else
+      app->type = strdup("c++app");
+    app->indicatordisplay =
+        strdup(application.app_info.indicator_display().c_str());
+    app->component_type = strdup("componentbasedapp");
+    app->hwacceleration = strdup(application.app_info.hwacceleration().c_str());
+    app->onboot = strdup("false");
+    app->autorestart = strdup("false");
+    app->mainapp = strdup(application.app_info.mainapp().c_str());
+    app->screenreader = strdup("use-system-setting");
+    app->recentimage = strdup("false");
+    app->launchcondition = strdup("false");
+    app->guestmode_visibility = strdup("true");
+    app->permission_type = strdup("normal");
+    app->support_ambient = strdup("false");
+    app->effectimage_type = strdup("image");
+    app->submode = strdup("false");
+    app->process_pool = strdup("false");
+    app->package = strdup(manifest->package);
+    app->support_disable = strdup(manifest->support_disable);
+    app->launch_mode = strdup("single");
+    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());
+    } else {
+      app->exec = strdup((context_->root_application_path.get()
+                          / manifest->package / "bin"
+                          / application.app_info.exec()).c_str());
+    }
+    if (!FillLabel(app, application.label))
+      return false;
+    if (!FillImage(app, application.app_images))
+      return false;
+    if (!FillBackgroundCategoryInfo(app, application.background_category))
+      return false;
+    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;
   }
 
   return true;
@@ -759,20 +1311,30 @@ bool StepParseManifest::FillManifestX(manifest_x* manifest) {
     return false;
   if (!FillWatchApplication(manifest))
     return false;
+  if (!FillComponentBasedApplicationInfo(manifest))
+    return false;
   if (!FillPrivileges(manifest))
     return false;
+  if (!FillProvidesAppDefinedPrivileges(manifest))
+    return false;
   if (!FillAuthorInfo(manifest))
     return false;
   if (!FillDescriptionInfo(manifest))
     return false;
-  if (!FillAccounts())
+  if (!FillExtraInfo(manifest))
+    return false;
+  if (!FillTrustAnchorInfo(manifest))
     return false;
-  if (!FillShortcuts())
+  if (!FillDependencyInfo(manifest))
+    return false;
+  if (!FillLightUserInfo(manifest))
     return false;
   return true;
 }
 
 Step::Status StepParseManifest::process() {
+  if (context_->force_clean_from_db.get())
+    return Step::Status::OK;
   if (!LocateConfigFile()) {
     // continue if this is recovery, manifest file may never been created
     if (manifest_location_ == ManifestLocation::RECOVERY) {
@@ -784,6 +1346,11 @@ Step::Status StepParseManifest::process() {
   }
   parser_.reset(new tpk::parse::TPKConfigParser());
   if (!parser_->ParseManifest(path_)) {
+    if (manifest_location_ == ManifestLocation::RECOVERY) {
+      LOG(DEBUG) << "Manifest for recovery is invalid";
+      bf::remove(path_);
+      return Step::Status::OK;
+    }
     LOG(ERROR) << "[Parse] Parse failed. " <<  parser_->GetErrorMessage();
     return Step::Status::PARSE_ERROR;
   }
@@ -794,28 +1361,28 @@ Step::Status StepParseManifest::process() {
           parser_->GetManifestData(app_keys::kManifestKey));
 
   context_->pkgid.set(info->package());
-  context_->pkg_path.set(
-      context_->root_application_path.get() / context_->pkgid.get());
 
   manifest_x* manifest =
       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
+  if (!manifest) {
+    LOG(ERROR) << "Out of memory";
+    return Step::Status::ERROR;
+  }
 
   if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
     LOG(ERROR) << "[Parse] Storing manifest_x failed. "
                <<  parser_->GetErrorMessage();
+    pkgmgr_parser_free_manifest_xml(manifest);
     return Step::Status::PARSE_ERROR;
   }
 
-  if (!context_->tep_path.get().empty())
-    manifest->tep_name = strdup(context_->tep_path.get().c_str());
-
   // write pkgid for recovery file
   if (context_->recovery_info.get().recovery_file) {
     context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
     context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
   }
 
-  LOG(DEBUG) << "Parsed package id: " << info->package();
+  LOG(INFO) << "Parsed package id: " << info->package();
 
   switch (store_location_) {
     case StoreLocation::NORMAL: