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