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