dd81151b7483967d65aaa02c840d3a1a56b6c480
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_parse_manifest.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/configuration/step_parse_manifest.h"
6
7 #include <boost/tokenizer.hpp>
8
9 #include <pkgmgr/pkgmgr_parser.h>
10 #include <pkgmgr-info.h>
11
12 #include <tpk_manifest_handlers/account_handler.h>
13 #include <tpk_manifest_handlers/common/appdefined_privilege_handler.h>
14 #include <tpk_manifest_handlers/application_manifest_constants.h>
15 #include <tpk_manifest_handlers/author_handler.h>
16 #include <tpk_manifest_handlers/dependencies_handler.h>
17 #include <tpk_manifest_handlers/description_handler.h>
18 #include <tpk_manifest_handlers/feature_handler.h>
19 #include <tpk_manifest_handlers/package_handler.h>
20 #include <tpk_manifest_handlers/privileges_handler.h>
21 #include <tpk_manifest_handlers/profile_handler.h>
22 #include <tpk_manifest_handlers/provides_appdefined_privileges_handler.h>
23 #include <tpk_manifest_handlers/service_application_handler.h>
24 #include <tpk_manifest_handlers/shortcut_handler.h>
25 #include <tpk_manifest_handlers/trust_anchor_handler.h>
26 #include <tpk_manifest_handlers/ui_application_handler.h>
27 #include <tpk_manifest_handlers/watch_application_handler.h>
28 #include <tpk_manifest_handlers/widget_application_handler.h>
29
30 #include <chrono>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 #include <memory>
35 #include <set>
36 #include <type_traits>
37 #include <string>
38 #include <vector>
39
40 #include "common/app2ext_dynamic_service.h"
41 #include "common/app_installer.h"
42 #include "common/feature_validator.h"
43 #include "common/installer_context.h"
44 #include "common/paths.h"
45 #include "common/privileges.h"
46 #include "common/pkgmgr_registration.h"
47 #include "common/pkgmgr_query.h"
48 #include "common/step/step.h"
49 #include "common/utils/glist_range.h"
50
51 namespace app_keys = tpk::application_keys;
52 namespace bf = boost::filesystem;
53
54 namespace {
55
56 const char kManifestFileName[] = "tizen-manifest.xml";
57 const char kInstalledInternally[] = "installed_internal";
58 const char kInstalledExternally[] = "installed_external";
59 const char kPortraitOrientation[] = "portrait";
60 const char kLandscapeOrientation[] = "landscape";
61 const char kOperationEffectKey[] = "operation_effect";
62 const char kLaunchEffectKey[] = "launch_effect";
63 const char kPortraitEffectImageValue[] = "portrait-effectimage";
64 const char kLandscapeEffectImageValue[] = "landscape-effectimage";
65 const char kIndicatorDisplayValue[] = "indicatordisplay";
66
67 }  // namespace
68
69 namespace common_installer {
70 namespace configuration {
71
72 StepParseManifest::StepParseManifest(
73     InstallerContext* context, ManifestLocation manifest_location,
74     StoreLocation store_location)
75     : Step(context),
76       manifest_location_(manifest_location),
77       store_location_(store_location) {
78 }
79
80 Step::Status StepParseManifest::precheck() {
81   switch (manifest_location_) {
82     case ManifestLocation::RECOVERY:
83       if (context_->pkgid.get().empty())
84         return Status::RECOVERY_DONE;
85       break;
86     case ManifestLocation::INSTALLED:
87       if (context_->pkgid.get().empty()) {
88         LOG(ERROR) << "Package id is not set";
89         return Status::INVALID_VALUE;
90       }
91       break;
92     case ManifestLocation::PACKAGE:
93       if (context_->unpacked_dir_path.get().empty()) {
94         LOG(ERROR) << "Unpacked directory doesn't exist";
95         return Status::INVALID_VALUE;
96       }
97       break;
98     default:
99       LOG(ERROR) << "Unknown manifest location";
100       return Status::INVALID_VALUE;
101   }
102   return Status::OK;
103 }
104
105 bool StepParseManifest::LocateConfigFile() {
106   boost::filesystem::path manifest;
107   switch (manifest_location_) {
108     case ManifestLocation::RECOVERY: {
109       bf::path backup_path = common_installer::GetBackupPathForPackagePath(
110           context_->GetPkgPath()) / kManifestFileName;
111       bf::path in_package_path = context_->GetPkgPath() / kManifestFileName;
112       bf::path install_path =
113           bf::path(getUserManifestPath(context_->uid.get(),
114                       context_->is_readonly_package.get()))
115               / bf::path(context_->pkgid.get());
116       install_path += ".xml";
117       if (bf::exists(backup_path))
118         manifest = backup_path;
119       else if (bf::exists(in_package_path))
120         manifest = in_package_path;
121       else if (bf::exists(install_path))
122         manifest = install_path;
123       break;
124     }
125     case ManifestLocation::INSTALLED: {
126       uid_t uid;
127       bool is_readonly = context_->is_readonly_package.get();
128       PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
129       if (pkg_query.IsGlobalPackage())
130         uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
131       else
132         uid = context_->uid.get();
133       bf::path xml_path =
134           bf::path(getUserManifestPath(uid, is_readonly))
135           / bf::path(context_->pkgid.get());
136       xml_path += ".xml";
137       context_->xml_path.set(xml_path);
138       manifest = context_->xml_path.get();
139       if (!boost::filesystem::exists(manifest)) {
140         /* This routine has added for platform update */
141         manifest = context_->unpacked_dir_path.get();
142         manifest /= kManifestFileName;
143       }
144       break;
145     }
146     case ManifestLocation::PACKAGE: {
147       manifest = context_->unpacked_dir_path.get();
148       manifest /= kManifestFileName;
149       break;
150     }
151     default: {
152       LOG(ERROR) << "Unknown manifest location value";
153       return false;
154     }
155   }
156
157   LOG(DEBUG) << "manifest path: " << manifest;
158
159   if (!boost::filesystem::exists(manifest))
160     return false;
161
162   path_ = manifest;
163   return true;
164 }
165
166 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
167   int mode = 0;
168   std::size_t found = std::string::npos;
169
170   found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
171   if (found != std::string::npos)
172     mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
173
174   found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
175   if (found != std::string::npos)
176     mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
177
178   found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
179   if (found != std::string::npos)
180     mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
181
182   return mode;
183 }
184
185 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
186   manifest->root_path = strdup(
187       (context_->root_application_path.get() / manifest->package).c_str());
188   manifest->installed_time =
189       strdup(std::to_string(std::chrono::system_clock::to_time_t(
190           std::chrono::system_clock::now())).c_str());
191   return true;
192 }
193
194 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
195   std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
196       std::static_pointer_cast<const tpk::parse::PackageInfo>(
197           parser_->GetManifestData(app_keys::kManifestKey));
198   if (!pkg_info) {
199     LOG(ERROR) << "Package info manifest data has not been found.";
200     return false;
201   }
202
203   auto ui_application_list =
204       std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
205           parser_->GetManifestData(app_keys::kUIApplicationKey));
206   auto service_application_list =
207       std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
208           parser_->GetManifestData(app_keys::kServiceApplicationKey));
209   auto widget_application_list =
210       std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
211           parser_->GetManifestData(app_keys::kWidgetApplicationKey));
212   auto watch_application_list =
213       std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
214           parser_->GetManifestData(app_keys::kWatchApplicationKey));
215
216   // mandatory check
217   if (!ui_application_list && !service_application_list &&
218       !widget_application_list && !watch_application_list) {
219     LOG(ERROR) << "UI Application or Service Application or Widget Application "
220                   "or Watch Application are mandatory and has not been found.";
221     return false;
222   }
223
224   int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
225
226   manifest->ns = strdup(pkg_info->xmlns().c_str());
227   manifest->package = strdup(pkg_info->package().c_str());
228   manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
229   manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
230   manifest->appsetting = strdup("false");
231   manifest->support_disable = strdup(pkg_info->support_disable().c_str());
232   manifest->version = strdup(pkg_info->version().c_str());
233   manifest->installlocation = strdup(pkg_info->install_location().c_str());
234   manifest->api_version = strdup(pkg_info->api_version().c_str());
235   manifest->readonly = strdup(pkg_info->readonly().c_str());
236   manifest->preload = strdup(pkg_info->preload().c_str());
237   manifest->removable = strdup(pkg_info->removable().c_str());
238
239   common_installer::RequestType req_type = context_->request_type.get();
240   if (pkg_info->type().empty()) {
241     if ((req_type == RequestType::ManifestDirectInstall ||
242         req_type == RequestType::ManifestDirectUpdate) &&
243         context_->is_readonly_package.get())
244       manifest->type = strdup("rpm");
245     else
246       manifest->type = strdup("tpk");
247   } else {
248     manifest->type = strdup(pkg_info->type().c_str());
249   }
250
251   // Set external path if the package is installed at external storage.
252   if (req_type == RequestType::ManifestDirectInstall ||
253       req_type == RequestType::ManifestDirectUpdate ||
254       req_type == RequestType::ManifestPartialInstall ||
255       req_type == RequestType::ManifestPartialUpdate ||
256       req_type == RequestType::RecoverDB) {
257     App2ExtDynamicService service;
258     std::string image_path = service.GetExternalImagePath(
259         context_->pkgid.get().c_str(), context_->uid.get());
260     if (!image_path.empty()) {
261       manifest->external_path = strdup(image_path.c_str());
262       manifest->installed_storage = strdup(kInstalledExternally);
263     }
264   }
265
266   for (auto& pair : pkg_info->labels()) {
267     label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
268     if (!label) {
269       LOG(ERROR) << "Out of memory";
270       return false;
271     }
272     if (!pair.first.empty())
273       label->lang = strdup(pair.first.c_str());
274     else
275       label->lang = strdup(DEFAULT_LOCALE);
276     label->text = strdup(pair.second.c_str());
277     manifest->label = g_list_append(manifest->label, label);
278   }
279
280   std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
281       std::static_pointer_cast<const tpk::parse::ProfileInfo>(
282           parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
283   if (profile_info) {
284     for (auto& profile : profile_info->profiles()) {
285       manifest->deviceprofile = g_list_append(manifest->deviceprofile,
286                                               strdup(profile.c_str()));
287     }
288   }
289
290   // set installed_storage if package is installed
291   // this is internal field in package manager but after reading configuration
292   // we must know it
293   PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
294   if (!manifest->installed_storage) {
295     if (manifest_location_ == ManifestLocation::INSTALLED ||
296         manifest_location_ == ManifestLocation::RECOVERY) {
297       std::string storage = pkg_query.StorageForPkgId();
298       if (storage.empty()) {
299         // Failed to query installation storage, assign internal
300         manifest->installed_storage = strdup(kInstalledInternally);
301       } else {
302         manifest->installed_storage = strdup(storage.c_str());
303       }
304     } else {
305       manifest->installed_storage = strdup(kInstalledInternally);
306     }
307   }
308
309   // retrieve and set plugin execution info if exists
310   if (manifest_location_ == ManifestLocation::INSTALLED ||
311       manifest_location_ == ManifestLocation::RECOVERY) {
312     std::vector<PkgQueryInterface::PluginInfo> plugin_list;
313     pkg_query.PluginExecutionInfo(&plugin_list);
314
315     for (const auto& plugin_info : plugin_list) {
316       plugin_x* plugin =
317           reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
318       if (!plugin) {
319         LOG(ERROR) << "Out of memory";
320         return false;
321       }
322
323       plugin->pkgid = strdup(manifest->package);
324       plugin->appid = strdup(std::get<1>(plugin_info).c_str());
325       plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
326       plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
327       manifest->plugin = g_list_append(manifest->plugin, plugin);
328     }
329   }
330   return true;
331 }
332
333 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
334   std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
335       std::static_pointer_cast<const tpk::parse::AuthorInfo>(
336           parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
337
338   if (!author_info)
339     return true;
340
341   author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
342   if (!author) {
343     LOG(ERROR) << "Out of memory";
344     return false;
345   }
346   author->text = strdup(author_info->name().c_str());
347   author->email = strdup(author_info->email().c_str());
348   author->href = strdup(author_info->href().c_str());
349   author->lang = strdup(DEFAULT_LOCALE);
350   manifest->author = g_list_append(manifest->author, author);
351   return true;
352 }
353
354 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
355   std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
356       std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
357           parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
358
359   if (!description_info)
360     return true;
361
362   for (auto& desc : description_info->descriptions) {
363     description_x* description = reinterpret_cast<description_x*>
364         (calloc(1, sizeof(description_x)));
365     if (!description) {
366       LOG(ERROR) << "Out of memory";
367       return false;
368     }
369     description->text = strdup(desc.description().c_str());
370     description->lang = !desc.xml_lang().empty() ?
371         strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
372     manifest->description = g_list_append(manifest->description, description);
373   }
374   return true;
375 }
376
377 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
378   std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
379       std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
380           parser_->GetManifestData(app_keys::kPrivilegesKey));
381   if (!perm_info)
382     return true;
383
384   const auto& privileges = perm_info->GetPrivileges();
385   for (auto& priv : privileges) {
386     privilege_x* privilege =
387         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
388     if (!privilege) {
389       LOG(ERROR) << "Out of memory";
390       return false;
391     }
392     privilege->value = strdup(priv.first.c_str());
393     privilege->type = strdup(priv.second.c_str());
394     manifest->privileges = g_list_append(manifest->privileges, privilege);
395   }
396
397   const auto& appdef_privileges_list =
398       perm_info->GetAppDefinedPrivilegeInfoList();
399   for (auto& appdef_info : appdef_privileges_list) {
400     appdefined_privilege_x* privilege =
401         reinterpret_cast<appdefined_privilege_x*>(calloc(1,
402             sizeof(appdefined_privilege_x)));
403     if (privilege == nullptr) {
404       LOG(ERROR) << "Memory alloc failure";
405       return false;
406     }
407     auto& priv = appdef_info.GetAppDefinedPrivilege();
408     privilege->value = strdup(priv.privilege.c_str());
409     privilege->type = strdup(priv.type.c_str());
410     if (!priv.license.empty()) {
411       if (bf::path(priv.license).is_absolute())
412         privilege->license = strdup(priv.license.c_str());
413       else
414         privilege->license = strdup((context_->GetPkgPath()
415             / priv.license).c_str());
416     }
417     manifest->appdefined_privileges =
418         g_list_append(manifest->appdefined_privileges, privilege);
419   }
420
421   return true;
422 }
423
424 bool StepParseManifest::FillProvidesAppDefinedPrivileges(
425     manifest_x* manifest) {
426   std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
427       priv_info = std::static_pointer_cast<
428           const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
429               parser_->GetManifestData(
430                   app_keys::kProvidesAppDefinedPrivilegesKey));
431   if (!priv_info)
432     return true;
433
434   const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
435   for (auto& appdef_info : privileges_list) {
436     appdefined_privilege_x* privilege =
437         reinterpret_cast<appdefined_privilege_x*>(calloc(1,
438             sizeof(appdefined_privilege_x)));
439     if (privilege == nullptr) {
440       LOG(ERROR) << "Memory alloc failure";
441       return false;
442     }
443     auto& priv = appdef_info.GetAppDefinedPrivilege();
444     privilege->value = strdup(priv.privilege.c_str());
445     privilege->type = strdup(priv.type.c_str());
446     if (!priv.license.empty()) {
447       if (bf::path(priv.license).is_absolute())
448         privilege->license = strdup(priv.license.c_str());
449       else
450         privilege->license = strdup((context_->GetPkgPath()
451             / priv.license).c_str());
452     }
453     manifest->provides_appdefined_privileges =
454         g_list_append(manifest->provides_appdefined_privileges, privilege);
455   }
456
457   return true;
458 }
459
460 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
461   auto widget_application_list =
462       std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
463           parser_->GetManifestData(app_keys::kWidgetApplicationKey));
464   if (!widget_application_list)
465     return true;
466
467   for (const auto& application : widget_application_list->items) {
468     int package_support_mode_val = atoi(manifest->support_mode);
469     int app_support_mode_val = package_support_mode_val |
470         GetSupportModeVal(application.app_info.support_mode());
471
472     application_x* widget_app =
473         static_cast<application_x*>(calloc(1, sizeof(application_x)));
474     if (!widget_app) {
475       LOG(ERROR) << "Out of memory";
476       return false;
477     }
478     widget_app->appid = strdup(application.app_info.appid().c_str());
479     widget_app->launch_mode =
480         strdup(application.app_info.launch_mode().c_str());
481     widget_app->multiple = strdup("false");
482     widget_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
483     widget_app->support_mode =
484         strdup((std::to_string(app_support_mode_val)).c_str());
485     widget_app->taskmanage = strdup("false");
486     widget_app->indicatordisplay = strdup("false");
487     if (!application.app_info.type().empty())
488       widget_app->type = strdup(application.app_info.type().c_str());
489     else
490       widget_app->type = strdup("capp");
491     widget_app->component_type = strdup("widgetapp");
492     widget_app->hwacceleration =
493         strdup(application.app_info.hwacceleration().c_str());
494     widget_app->onboot = strdup("false");
495     widget_app->autorestart = strdup("false");
496     widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
497     widget_app->screenreader = strdup("use-system-setting");
498     widget_app->recentimage = strdup("false");
499     widget_app->launchcondition = strdup("false");
500     widget_app->guestmode_visibility = strdup("true");
501     widget_app->permission_type = strdup("normal");
502     widget_app->support_ambient = strdup("false");
503     widget_app->effectimage_type = strdup("image");
504     widget_app->submode = strdup("false");
505     widget_app->process_pool = strdup("false");
506     widget_app->package = strdup(manifest->package);
507     widget_app->support_disable = strdup(manifest->support_disable);
508     widget_app->launch_mode = strdup("single");
509     widget_app->api_version = strdup(manifest->api_version);
510     manifest->application = g_list_append(manifest->application, widget_app);
511     if (bf::path(application.app_info.exec().c_str()).is_absolute())
512       widget_app->exec = strdup(application.app_info.exec().c_str());
513     else
514       widget_app->exec = strdup((context_->root_application_path.get()
515                             / manifest->package / "bin"
516                             / application.app_info.exec()).c_str());
517
518     if (!FillApplicationIconPaths(widget_app, application.app_icons))
519       return false;
520     if (!FillLabel(widget_app, application.label))
521       return false;
522     if (!FillImage(widget_app, application.app_images))
523       return false;
524     if (!FillCategories(widget_app, application.categories))
525       return false;
526     if (!FillMetadata(widget_app, application.meta_data))
527       return false;
528   }
529   return true;
530 }
531
532 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
533   auto service_application_list =
534       std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
535           parser_->GetManifestData(app_keys::kServiceApplicationKey));
536   if (!service_application_list)
537     return true;
538
539   for (const auto& application : service_application_list->items) {
540     int package_support_mode_val = atoi(manifest->support_mode);
541     int app_support_mode_val = package_support_mode_val |
542         GetSupportModeVal(application.app_info.support_mode());
543
544     application_x* service_app =
545         static_cast<application_x*>(calloc(1, sizeof(application_x)));
546     if (!service_app) {
547       LOG(ERROR) << "Out of memory";
548       return false;
549     }
550     service_app->appid = strdup(application.app_info.appid().c_str());
551     service_app->multiple = strdup(application.app_info.multiple().c_str());
552     service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
553     service_app->support_mode =
554         strdup((std::to_string(app_support_mode_val)).c_str());
555     service_app->autorestart =
556         strdup(application.app_info.auto_restart().c_str());
557     service_app->onboot = strdup(application.app_info.on_boot().c_str());
558     if (!application.app_info.type().empty())
559       service_app->type = strdup(application.app_info.type().c_str());
560     else
561       service_app->type = strdup("capp");
562     service_app->process_pool =
563         strdup(application.app_info.process_pool().c_str());
564     service_app->component_type = strdup("svcapp");
565     service_app->mainapp = strdup(application.app_info.mainapp().c_str());
566     service_app->nodisplay = strdup("true");
567     service_app->hwacceleration = strdup("default");
568     service_app->screenreader = strdup("use-system-setting");
569     service_app->recentimage = strdup("false");
570     service_app->launchcondition = strdup("false");
571     service_app->indicatordisplay = strdup("true");
572     service_app->effectimage_type = strdup("image");
573     service_app->guestmode_visibility = strdup("true");
574     service_app->permission_type = strdup("normal");
575     service_app->submode = strdup("false");
576     service_app->process_pool = strdup("false");
577     service_app->support_ambient = strdup("false");
578     service_app->package = strdup(manifest->package);
579     service_app->support_disable = strdup(manifest->support_disable);
580     service_app->launch_mode = strdup("single");
581     service_app->api_version = strdup(manifest->api_version);
582     manifest->application = g_list_append(manifest->application, service_app);
583     if (bf::path(application.app_info.exec().c_str()).is_absolute())
584       service_app->exec = strdup(application.app_info.exec().c_str());
585     else
586       service_app->exec = strdup((context_->root_application_path.get()
587                             / manifest->package / "bin"
588                             / application.app_info.exec()).c_str());
589
590     if (!FillAppControl(service_app,  application.app_control))
591       return false;
592     if (!FillDataControl(service_app, application.data_control))
593       return false;
594     if (!FillApplicationIconPaths(service_app, application.app_icons))
595       return false;
596     if (!FillLabel(service_app, application.label))
597       return false;
598     if (!FillMetadata(service_app, application.meta_data))
599       return false;
600     if (!FillCategories(service_app, application.categories))
601       return false;
602     if (!FillBackgroundCategoryInfo(service_app,
603         application.background_category))
604       return false;
605   }
606   return true;
607 }
608
609 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
610   std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
611       std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
612           parser_->GetManifestData(app_keys::kUIApplicationKey));
613   if (!ui_application_list)
614     return true;
615
616   for (const auto& application : ui_application_list->items) {
617     int package_support_mode_val = atoi(manifest->support_mode);
618     int app_support_mode_val = package_support_mode_val |
619         GetSupportModeVal(application.app_info.support_mode());
620
621     application_x* ui_app =
622         static_cast<application_x*>(calloc(1, sizeof(application_x)));
623     if (!ui_app) {
624       LOG(ERROR) << "Out of memory";
625       return false;
626     }
627     ui_app->appid = strdup(application.app_info.appid().c_str());
628     ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
629     ui_app->multiple = strdup(application.app_info.multiple().c_str());
630     ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
631     ui_app->support_mode =
632         strdup((std::to_string(app_support_mode_val)).c_str());
633     ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
634     if (!application.app_info.type().empty())
635       ui_app->type = strdup(application.app_info.type().c_str());
636     else
637       ui_app->type = strdup("capp");
638     ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
639     ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
640     ui_app->submode = strdup(application.app_info.submode().c_str());
641     if (!application.app_info.indicator_display().empty())
642       ui_app->indicatordisplay =
643           strdup(application.app_info.indicator_display().c_str());
644     if (!application.app_info.effectimage_type().empty())
645       ui_app->effectimage_type =
646           strdup(application.app_info.effectimage_type().c_str());
647     if (!application.app_info.portrait_image().empty()) {
648       ui_app->portraitimg =
649           strdup(application.app_info.portrait_image().c_str());
650       AppendSplashScreen(ui_app, application.app_info.portrait_image(),
651           application.app_info.effectimage_type(), {}, kPortraitOrientation,
652           application.app_info.indicator_display(), {}, {});
653     }
654     if (!application.app_info.landscape_image().empty()) {
655       ui_app->landscapeimg =
656           strdup(application.app_info.landscape_image().c_str());
657       AppendSplashScreen(ui_app, application.app_info.landscape_image(),
658           application.app_info.effectimage_type(), {}, kLandscapeOrientation,
659           application.app_info.indicator_display(), {}, {});
660     }
661     ui_app->submode_mainid =
662         strdup(application.app_info.submode_mainid().c_str());
663     ui_app->hwacceleration =
664         strdup(application.app_info.hwacceleration().c_str());
665     ui_app->onboot = strdup("false");
666     ui_app->autorestart = strdup("false");
667     ui_app->component_type = strdup("uiapp");
668     ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
669     ui_app->screenreader = strdup("use-system-setting");
670     ui_app->recentimage = strdup("false");
671     ui_app->launchcondition = strdup("false");
672     ui_app->guestmode_visibility = strdup("true");
673     ui_app->permission_type = strdup("normal");
674     ui_app->support_ambient = strdup("false");
675     ui_app->package = strdup(manifest->package);
676     ui_app->support_disable = strdup(manifest->support_disable);
677     ui_app->splash_screen_display =
678         strdup(application.app_info.splash_screen_display().c_str());
679     ui_app->api_version = strdup(manifest->api_version);
680     manifest->application = g_list_append(manifest->application, ui_app);
681     if (bf::path(application.app_info.exec().c_str()).is_absolute())
682       ui_app->exec = strdup(application.app_info.exec().c_str());
683     else
684       ui_app->exec = strdup((context_->root_application_path.get()
685                             / manifest->package / "bin"
686                             / application.app_info.exec()).c_str());
687
688
689     if (!FillAppControl(ui_app, application.app_control))
690       return false;
691     if (!FillDataControl(ui_app, application.data_control))
692       return false;
693     if (!FillApplicationIconPaths(ui_app, application.app_icons))
694       return false;
695     if (!FillLabel(ui_app, application.label))
696       return false;
697     if (!FillImage(ui_app, application.app_images))
698       return false;
699     if (!FillMetadata(ui_app, application.meta_data))
700       return false;
701     if (!FillCategories(ui_app, application.categories))
702       return false;
703     if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
704       return false;
705     if (!FillSplashScreen(ui_app, application.app_splashscreens))
706       return false;
707   }
708   return true;
709 }
710
711 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
712   auto watch_application_list =
713         std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
714             parser_->GetManifestData(app_keys::kWatchApplicationKey));
715   if (!watch_application_list)
716     return true;
717
718   for (const auto& watch_application : watch_application_list->items) {
719     int package_support_mode_val = atoi(manifest->support_mode);
720     int app_support_mode_val = package_support_mode_val |
721         GetSupportModeVal(watch_application.app_info.support_mode());
722
723     application_x* watch_app =
724              static_cast<application_x*>(calloc(1, sizeof(application_x)));
725     if (!watch_app) {
726       LOG(ERROR) << "Out of memory";
727       return false;
728     }
729     watch_app->appid = strdup(watch_application.app_info.appid().c_str());
730
731     if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
732       watch_app->exec = strdup(watch_application.app_info.exec().c_str());
733     else
734       watch_app->exec = strdup(
735           (context_->root_application_path.get()
736                                / manifest->package / "bin" /
737                                watch_application.app_info.exec()).c_str());
738     watch_app->nodisplay = strdup("true");
739     watch_app->multiple = strdup("false");
740     if (!watch_application.app_info.type().empty())
741       watch_app->type = strdup(watch_application.app_info.type().c_str());
742     else
743       watch_app->type = strdup("capp");
744     watch_app->taskmanage = strdup("false");
745     watch_app->hwacceleration = strdup("default");
746     watch_app->screenreader = strdup("use-system-setting");
747     watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
748     watch_app->recentimage = strdup("false");
749     watch_app->launchcondition = strdup("false");
750     watch_app->indicatordisplay = strdup("true");
751     watch_app->effectimage_type = strdup("image");
752     watch_app->guestmode_visibility = strdup("true");
753     watch_app->permission_type = strdup("normal");
754     watch_app->component_type = strdup("watchapp");
755     watch_app->preload = strdup("false");
756     watch_app->submode = strdup("false");
757     watch_app->process_pool = strdup("false");
758     watch_app->autorestart = strdup("false");
759     watch_app->onboot = strdup("false");
760     watch_app->support_mode =
761         strdup((std::to_string(app_support_mode_val)).c_str());
762     watch_app->ui_gadget = strdup("false");
763     watch_app->launch_mode = strdup("single");
764     watch_app->api_version = strdup(manifest->api_version);
765     watch_app->support_ambient =
766         strdup(watch_application.app_info.ambient_support().c_str());
767     watch_app->package = strdup(manifest->package);
768     if (!watch_application.app_info.setup_appid().empty())
769       watch_app->setup_appid =
770           strdup(watch_application.app_info.setup_appid().c_str());
771
772     if (!FillLabel(watch_app, watch_application.label))
773       return false;
774     if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
775       return false;
776     if (!FillMetadata(watch_app, watch_application.meta_data))
777       return false;
778     if (!FillCategories(watch_app, watch_application.categories))
779       return false;
780     if (!FillBackgroundCategoryInfo(watch_app,
781         watch_application.background_category))
782       return false;
783     manifest->application = g_list_append(manifest->application, watch_app);
784   }
785   return true;
786 }
787
788 bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
789   std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
790       std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
791           parser_->GetManifestData(app_keys::kTrustAnchorKey));
792   if (!trust_anchor_info)
793     return true;
794
795   if (trust_anchor_info->get_use_system_certs().empty()) {
796     LOG(ERROR) << "Invalid trust anchor data";
797     return false;
798   }
799
800   manifest->use_system_certs =
801       strdup(trust_anchor_info->get_use_system_certs().c_str());
802
803   return true;
804 }
805
806 bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
807   std::shared_ptr<const tpk::parse::DependenciesInfo> dependencies_info =
808       std::static_pointer_cast<const tpk::parse::DependenciesInfo>(
809           parser_->GetManifestData(app_keys::kDependenciesKey));
810   if (!dependencies_info)
811     return true;
812
813   for (const auto& dependency : dependencies_info->dependencies()) {
814     dependency_x* dep =
815         static_cast<dependency_x*>(calloc(1, sizeof(dependency_x)));
816     if (!dep) {
817       LOG(ERROR) << "Out of memory";
818       return false;
819     }
820     dep->depends_on = strdup(dependency.pkgid().c_str());
821     dep->type = strdup(dependency.type().c_str());
822     if (!dependency.required_version().empty())
823       dep->required_version = strdup(dependency.required_version().c_str());
824     manifest->dependencies = g_list_append(manifest->dependencies, dep);
825   }
826
827   return true;
828 }
829
830 bool StepParseManifest::CheckFeatures() {
831   auto feature_info =
832         std::static_pointer_cast<const tpk::parse::FeatureInfo>(
833             parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
834   if (!feature_info)
835     return true;
836
837   std::string error;
838   FeatureValidator validator(feature_info->features());
839   if (!validator.Validate(&error)) {
840     LOG(ERROR) << "Feature validation error. " << error;
841     return false;
842   }
843
844   return true;
845 }
846
847 template <typename T>
848 bool StepParseManifest::FillAppControl(application_x* app,
849                                        const T& app_control_list) {
850   if (app_control_list.empty())
851     return true;
852
853   for (const auto& control : app_control_list) {
854     appcontrol_x* app_control =
855           static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
856     if (!app_control) {
857       LOG(ERROR) << "Out of memory";
858       return false;
859     }
860     app_control->operation = strdup(control.operation().c_str());
861     if (!control.mime().empty())
862       app_control->mime = strdup(control.mime().c_str());
863     if (!control.uri().empty())
864       app_control->uri = strdup(control.uri().c_str());
865     if (!control.visibility().empty())
866       app_control->visibility = strdup(control.visibility().c_str());
867     else
868       app_control->visibility = strdup("local-only");
869     if (!control.id().empty())
870       app_control->id = strdup(control.id().c_str());
871     else
872       app_control->id = strdup("no-name-app-control");
873     for (const auto& priv : control.privileges()) {
874       app_control->privileges = g_list_append(app_control->privileges,
875           strdup(priv.c_str()));
876     }
877     app->appcontrol = g_list_append(app->appcontrol, app_control);
878   }
879   return true;
880 }
881
882 template <typename T>
883 bool StepParseManifest::FillDataControl(application_x* app,
884                                 const T& data_control_list) {
885   if (data_control_list.empty())
886     return true;
887
888   for (const auto& control : data_control_list) {
889     datacontrol_x* data_control =
890           static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
891     if (!data_control) {
892       LOG(ERROR) << "Out of memory";
893       return false;
894     }
895     data_control->access = strdup(control.access().c_str());
896     data_control->providerid = strdup(control.providerid().c_str());
897     data_control->type = strdup(control.type().c_str());
898     if (!control.trusted().empty())
899       data_control->trusted = strdup(control.trusted().c_str());
900     else
901       data_control->trusted = strdup("false");
902     for (const auto& priv : control.privileges())
903       data_control->privileges = g_list_append(data_control->privileges,
904           strdup(priv.c_str()));
905
906     app->datacontrol = g_list_append(app->datacontrol, data_control);
907   }
908   return true;
909 }
910
911 template <typename T>
912 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
913                                          const T& icons_info) {
914   for (auto& application_icon : icons_info.icons()) {
915     icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
916     if (!icon) {
917       LOG(ERROR) << "Out of memory";
918       return false;
919     }
920     bf::path text;
921     if (bf::path(application_icon.path()).is_absolute()) {
922       text = application_icon.path();
923     } else {
924       text = context_->root_application_path.get()
925           / context_->pkgid.get() / "shared" / "res" / application_icon.path();
926     }
927     // NOTE: name is an attribute, but the xml writer uses it as text.
928     // This must be fixed in whole app-installer modules, including wgt.
929     // Current implementation is just for compatibility.
930     icon->text = strdup(text.c_str());
931     if (application_icon.lang().empty())
932       icon->lang = strdup(DEFAULT_LOCALE);
933     else
934       icon->lang = strdup(application_icon.lang().c_str());
935
936     if (!application_icon.dpi().empty())
937       icon->dpi = strdup(application_icon.dpi().c_str());
938     app->icon = g_list_append(app->icon, icon);
939   }
940   return true;
941 }
942
943 template <typename T>
944 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
945   if (label_list.empty())
946     return true;
947
948   for (const auto& control : label_list) {
949     label_x* label =
950           static_cast<label_x*>(calloc(1, sizeof(label_x)));
951     if (!label) {
952       LOG(ERROR) << "Out of memory";
953       return false;
954     }
955     // NOTE: name is an attribute, but the xml writer uses it as text.
956     // This must be fixed in whole app-installer modules, including wgt.
957     // Current implementation is just for compatibility.
958     label->text = strdup(control.text().c_str());
959     label->name = strdup(control.name().c_str());
960     label->lang = !control.xml_lang().empty() ?
961         strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
962     app->label = g_list_append(app->label, label);
963   }
964   return true;
965 }
966
967 template <typename T>
968 bool StepParseManifest::FillMetadata(application_x* app,
969                                      const T& meta_data_list) {
970   if (meta_data_list.empty())
971     return true;
972
973   for (auto& meta : meta_data_list) {
974     metadata_x* metadata =
975         static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
976     if (!metadata) {
977       LOG(ERROR) << "Out of memory";
978       return false;
979     }
980     metadata->key = strdup(meta.key().c_str());
981     metadata->value = strdup(meta.val().c_str());
982     app->metadata = g_list_append(app->metadata, metadata);
983
984     GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
985   }
986   return true;
987 }
988
989 template <typename T>
990 bool StepParseManifest::FillCategories(application_x* manifest,
991                                      const T& categories) {
992   for (auto& category : categories) {
993     manifest->category = g_list_append(manifest->category,
994                                        strdup(category.c_str()));
995   }
996   return true;
997 }
998
999 void StepParseManifest::AppendSplashScreen(application_x* app,
1000     const std::string& src, const std::string& type, const std::string& dpi,
1001     const std::string& orientation, const std::string& indicatordisplay,
1002     const std::string& operation, const std::string& color_depth) {
1003   splashscreen_x* splashscreen =
1004       static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
1005   if (!splashscreen) {
1006     LOG(ERROR) << "Out of memory";
1007     return;
1008   }
1009   if (bf::path(src).is_absolute()) {
1010     splashscreen->src = strdup(src.c_str());
1011   } else {
1012     bf::path full_path = context_->GetPkgPath() / src;
1013     splashscreen->src = strdup(full_path.string().c_str());
1014   }
1015   if (src.substr(src.find_last_of(".") + 1) == "edj")
1016     splashscreen->type = strdup("edj");
1017   else if (type == "edj")
1018     splashscreen->type = strdup("edj");
1019   else
1020     splashscreen->type = strdup("img");
1021   if (!dpi.empty())
1022     splashscreen->dpi = strdup(dpi.c_str());
1023   splashscreen->orientation = strdup(orientation.c_str());
1024   if (!indicatordisplay.empty())
1025     splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
1026   else
1027     splashscreen->indicatordisplay = strdup("true");
1028   if (operation == "launch_effect")
1029     splashscreen->operation = strdup("launch-effect");
1030   else if (!operation.empty())
1031     splashscreen->operation = strdup(operation.c_str());
1032   else
1033     splashscreen->operation = strdup("launch-effect");
1034   if (!color_depth.empty())
1035     splashscreen->color_depth = strdup(color_depth.c_str());
1036   else
1037     splashscreen->color_depth = strdup("24");
1038   app->splashscreens = g_list_append(app->splashscreens, splashscreen);
1039 }
1040
1041 template <typename T>
1042 bool StepParseManifest::FillSplashScreen(application_x* app,
1043                                      const T& splashscreens_info) {
1044   for (auto& splash_screen : splashscreens_info.splashscreens()) {
1045     std::string src;
1046     if (context_->is_readonly_package.get())
1047       src = splash_screen.src();
1048     else
1049       src = bf::path(context_->root_application_path.get()
1050         / app->package / "shared" / "res" / splash_screen.src()).string();
1051
1052     AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
1053         splash_screen.orientation(), splash_screen.indicatordisplay(),
1054         splash_screen.operation(), splash_screen.colordepth());
1055   }
1056   return true;
1057 }
1058
1059 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
1060     const std::string& key, const std::string& val) {
1061   std::string operation;
1062   if (key.find(kOperationEffectKey) != std::string::npos) {
1063     boost::char_separator<char> sep("=");
1064     boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
1065     auto iter = tokens.begin();
1066     iter++;
1067     operation = *iter;
1068   } else if (key.find(kLaunchEffectKey) != std::string::npos) {
1069     operation = std::string("launch-effect");
1070   } else {
1071     // not a metadata splashscreen
1072     return;
1073   }
1074
1075   boost::char_separator<char> sep("=|");
1076   boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
1077   auto iter = tokens.begin();
1078   std::string portrait_src;
1079   std::string landscape_src;
1080   std::string indicatordisplay;
1081   while (iter != tokens.end()) {
1082     if (!(*iter).compare(kPortraitEffectImageValue)) {
1083       iter++;
1084       portrait_src = *iter;
1085     } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
1086       iter++;
1087       landscape_src = *iter;
1088     } else if (!(*iter).compare(kIndicatorDisplayValue)) {
1089       iter++;
1090       indicatordisplay = *iter;
1091     }
1092     iter++;
1093   }
1094   if (!portrait_src.empty())
1095     AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
1096         indicatordisplay, operation, {});
1097   if (!landscape_src.empty())
1098     AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
1099         indicatordisplay, operation, {});
1100 }
1101
1102 bool StepParseManifest::FillImage(application_x* app,
1103                           const tpk::parse::ApplicationImagesInfo& image_list) {
1104   for (auto& app_image : image_list.images) {
1105     image_x* image =
1106         static_cast<image_x*>(calloc(1, sizeof(image_x)));
1107     if (!image) {
1108       LOG(ERROR) << "Out of memory";
1109       return false;
1110     }
1111     const std::string& lang = app_image.lang();
1112     if (!lang.empty())
1113       image->lang = strdup(lang.c_str());
1114     else
1115       image->lang = strdup(DEFAULT_LOCALE);
1116     if (!app_image.section().empty())
1117       image->section = strdup(app_image.section().c_str());
1118     app->image = g_list_append(app->image, image);
1119   }
1120   return true;
1121 }
1122
1123 template <typename T>
1124 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
1125     const T& background_category_data_list) {
1126   for (const auto& background_category : background_category_data_list) {
1127     app->background_category = g_list_append(
1128         app->background_category, strdup(background_category.value().c_str()));
1129   }
1130
1131   return true;
1132 }
1133
1134 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
1135   if (manifest_location_ == ManifestLocation::INSTALLED) {
1136     // recovery of tep value for installed package
1137     PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
1138     std::string old_tep = pkg_query.TepPath();
1139     if (!old_tep.empty())
1140       manifest->tep_name = strdup(old_tep.c_str());
1141
1142     // recovery of zip mount file for installed package
1143     std::string zip_mount_file = pkg_query.ZipMountFile();
1144     if (!zip_mount_file.empty())
1145       manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1146   }
1147
1148   // in case of hybrid package, main app is already set by wgt-backend
1149   application_x* mainapp = nullptr;
1150   if (!context_->cross_app_rules.get()) {
1151     // find mainapp
1152     for (const auto& app : GListRange<application_x*>(manifest->application)) {
1153       if (!strcmp(app->mainapp, "true")) {
1154         mainapp = app;
1155         break;
1156       }
1157     }
1158     if (mainapp == nullptr)
1159       mainapp = reinterpret_cast<application_x*>(
1160           g_list_first(manifest->application)->data);
1161     free(mainapp->mainapp);
1162     mainapp->mainapp = strdup("true");
1163     manifest->mainapp_id = strdup(mainapp->appid);
1164   }
1165
1166   // mark mainapp=false at other apps
1167   for (auto& app : GListRange<application_x*>(manifest->application)) {
1168     if (app == mainapp)
1169       continue;
1170     free(app->mainapp);
1171     app->mainapp = strdup("false");
1172   }
1173   return true;
1174 }
1175
1176 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
1177   if (!FillPackageInfo(manifest))
1178     return false;
1179   if (!FillInstallationInfo(manifest))
1180     return false;
1181   if (!FillUIApplication(manifest))
1182     return false;
1183   if (!FillServiceApplication(manifest))
1184     return false;
1185   if (!FillWidgetApplication(manifest))
1186     return false;
1187   if (!FillWatchApplication(manifest))
1188     return false;
1189   if (!FillPrivileges(manifest))
1190     return false;
1191   if (!FillProvidesAppDefinedPrivileges(manifest))
1192     return false;
1193   if (!FillAuthorInfo(manifest))
1194     return false;
1195   if (!FillDescriptionInfo(manifest))
1196     return false;
1197   if (!FillExtraInfo(manifest))
1198     return false;
1199   if (!FillTrustAnchorInfo(manifest))
1200     return false;
1201   if (!FillDependencyInfo(manifest))
1202     return false;
1203   return true;
1204 }
1205
1206 Step::Status StepParseManifest::process() {
1207   if (context_->force_clean_from_db.get())
1208     return Step::Status::OK;
1209   if (!LocateConfigFile()) {
1210     // continue if this is recovery, manifest file may never been created
1211     if (manifest_location_ == ManifestLocation::RECOVERY) {
1212       LOG(DEBUG) << "Manifest for recovery not found";
1213       return Step::Status::OK;
1214     }
1215     LOG(ERROR) << "No manifest file exists";
1216     return Step::Status::MANIFEST_NOT_FOUND;
1217   }
1218   parser_.reset(new tpk::parse::TPKConfigParser());
1219   if (!parser_->ParseManifest(path_)) {
1220     if (manifest_location_ == ManifestLocation::RECOVERY) {
1221       LOG(DEBUG) << "Manifest for recovery is invalid";
1222       bf::remove(path_);
1223       return Step::Status::OK;
1224     }
1225     LOG(ERROR) << "[Parse] Parse failed. " <<  parser_->GetErrorMessage();
1226     return Step::Status::PARSE_ERROR;
1227   }
1228
1229   // Copy data from ManifestData to InstallerContext
1230   std::shared_ptr<const tpk::parse::PackageInfo> info =
1231       std::static_pointer_cast<const tpk::parse::PackageInfo>(
1232           parser_->GetManifestData(app_keys::kManifestKey));
1233
1234   context_->pkgid.set(info->package());
1235
1236   manifest_x* manifest =
1237       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1238   if (!manifest) {
1239     LOG(ERROR) << "Out of memory";
1240     return Step::Status::ERROR;
1241   }
1242
1243   if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1244     LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1245                <<  parser_->GetErrorMessage();
1246     pkgmgr_parser_free_manifest_xml(manifest);
1247     return Step::Status::PARSE_ERROR;
1248   }
1249
1250   // write pkgid for recovery file
1251   if (context_->recovery_info.get().recovery_file) {
1252     context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1253     context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1254   }
1255
1256   LOG(DEBUG) << "Parsed package id: " << info->package();
1257
1258   switch (store_location_) {
1259     case StoreLocation::NORMAL:
1260       context_->manifest_data.set(manifest);
1261       break;
1262     case StoreLocation::BACKUP:
1263       context_->old_manifest_data.set(manifest);
1264       break;
1265     default:
1266       LOG(ERROR) << "Unknown store location for parsed data";
1267       return Step::Status::ERROR;
1268   }
1269   return Step::Status::OK;
1270 }
1271
1272 }  // namespace configuration
1273 }  // namespace common_installer