Parse icon for robotapp
[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 <pkgmgr/pkgmgr_parser.h>
8 #include <pkgmgr-info.h>
9
10 #include <tpk_manifest_handlers/appdefined_privilege_handler.h>
11 #include <tpk_manifest_handlers/application_manifest_constants.h>
12 #include <tpk_manifest_handlers/author_handler.h>
13 #include <tpk_manifest_handlers/component_based_application_handler.h>
14 #include <tpk_manifest_handlers/dependencies_handler.h>
15 #include <tpk_manifest_handlers/description_handler.h>
16 #include <tpk_manifest_handlers/feature_handler.h>
17 #include <tpk_manifest_handlers/light_user_handler.h>
18 #include <tpk_manifest_handlers/package_handler.h>
19 #include <tpk_manifest_handlers/privileges_handler.h>
20 #include <tpk_manifest_handlers/profile_handler.h>
21 #include <tpk_manifest_handlers/provides_appdefined_privileges_handler.h>
22 #include <tpk_manifest_handlers/robot_application_handler.h>
23 #include <tpk_manifest_handlers/service_application_handler.h>
24 #include <tpk_manifest_handlers/shortcut_handler.h>
25 #include <tpk_manifest_handlers/trust_anchor_handler.h>
26 #include <tpk_manifest_handlers/ui_application_handler.h>
27 #include <tpk_manifest_handlers/watch_application_handler.h>
28 #include <tpk_manifest_handlers/widget_application_handler.h>
29
30 #include <cstdio>
31 #include <cstdlib>
32 #include <cstring>
33 #include <filesystem>
34 #include <memory>
35 #include <regex>
36 #include <set>
37 #include <type_traits>
38 #include <string>
39 #include <vector>
40
41 #include "common/feature_validator.h"
42 #include "common/installer_context.h"
43 #include "common/utils/paths.h"
44 #include "common/privileges.h"
45 #include "common/pkgmgr_registration.h"
46 #include "common/utils/pkgmgr_query.h"
47 #include "common/step/step.h"
48 #include "common/utils/glist_range.h"
49 #include "common/utils/time_util.h"
50
51 namespace app_keys = tpk::application_keys;
52 namespace fs = std::filesystem;
53
54 namespace {
55
56 const char kManifestFileName[] = "tizen-manifest.xml";
57 const char kInstalledInternally[] = "installed_internal";
58 const char kInstalledExternally[] = "installed_external";
59 const char kPortraitOrientation[] = "portrait";
60 const char kLandscapeOrientation[] = "landscape";
61 const char kOperationEffectKey[] = "operation_effect";
62 const char kLaunchEffectKey[] = "launch_effect";
63 const char kPortraitEffectImageValue[] = "portrait-effectimage";
64 const char kLandscapeEffectImageValue[] = "landscape-effectimage";
65 const char kIndicatorDisplayValue[] = "indicatordisplay";
66
67 }  // namespace
68
69 namespace common_installer {
70 namespace configuration {
71
72 StepParseManifest::StepParseManifest(
73     InstallerContext* context, ManifestLocation manifest_location,
74     StoreLocation store_location)
75     : Step(context),
76       manifest_location_(manifest_location),
77       store_location_(store_location) {
78 }
79
80 Step::Status StepParseManifest::precheck() {
81   switch (manifest_location_) {
82     case ManifestLocation::RECOVERY:
83       if (context_->pkgid.get().empty())
84         return Status::RECOVERY_DONE;
85       break;
86     case ManifestLocation::INSTALLED:
87       if (context_->pkgid.get().empty()) {
88         LOG(ERROR) << "Package id is not set";
89         return Status::INVALID_VALUE;
90       }
91       break;
92     case ManifestLocation::PACKAGE:
93       if (context_->unpacked_dir_path.get().empty()) {
94         LOG(ERROR) << "Unpacked directory doesn't exist";
95         return Status::INVALID_VALUE;
96       }
97       break;
98     default:
99       LOG(ERROR) << "Unknown manifest location";
100       return Status::INVALID_VALUE;
101   }
102   return Status::OK;
103 }
104
105 bool StepParseManifest::LocateConfigFile() {
106   std::filesystem::path manifest;
107   switch (manifest_location_) {
108     case ManifestLocation::RECOVERY: {
109       fs::path backup_path = common_installer::GetBackupPathForPackagePath(
110           context_->GetPkgPath()) / kManifestFileName;
111       fs::path in_package_path = context_->GetPkgPath() / kManifestFileName;
112       fs::path install_path =
113           fs::path(getUserManifestPath(context_->uid.get(),
114                       context_->is_readonly_package.get()))
115               / fs::path(context_->pkgid.get());
116       install_path += ".xml";
117       fs::path backup_install_path =
118           common_installer::GetBackupPathForManifestFile(install_path);
119       if (fs::exists(backup_install_path))
120         manifest = backup_install_path;
121       else if (fs::exists(backup_path))
122         manifest = backup_path;
123       else if (fs::exists(install_path))
124         manifest = install_path;
125       else if (fs::exists(in_package_path))
126         manifest = in_package_path;
127       break;
128     }
129     case ManifestLocation::INSTALLED: {
130       uid_t uid;
131       bool is_readonly = context_->is_readonly_package.get();
132       PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
133       if (pkg_query.IsGlobalPackage())
134         uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
135       else
136         uid = context_->uid.get();
137       fs::path xml_path =
138           fs::path(getUserManifestPath(uid, is_readonly))
139           / fs::path(context_->pkgid.get());
140       xml_path += ".xml";
141       context_->xml_path.set(xml_path);
142       manifest = context_->xml_path.get();
143       if (!std::filesystem::exists(manifest)) {
144         /* This routine has added for platform update */
145         manifest = context_->unpacked_dir_path.get();
146         manifest /= kManifestFileName;
147       }
148       break;
149     }
150     case ManifestLocation::PACKAGE: {
151       manifest = context_->unpacked_dir_path.get();
152       manifest /= kManifestFileName;
153       break;
154     }
155     default: {
156       LOG(ERROR) << "Unknown manifest location value";
157       return false;
158     }
159   }
160
161   LOG(DEBUG) << "manifest path: " << manifest;
162
163   if (!std::filesystem::exists(manifest))
164     return false;
165
166   path_ = manifest;
167   return true;
168 }
169
170 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
171   int mode = 0;
172   std::size_t found = std::string::npos;
173
174   found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
175   if (found != std::string::npos)
176     mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
177
178   found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
179   if (found != std::string::npos)
180     mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
181
182   found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
183   if (found != std::string::npos)
184     mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
185
186   return mode;
187 }
188
189 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
190   manifest->root_path = strdup(
191       (context_->root_application_path.get() / manifest->package).c_str());
192   manifest->installed_time = strdup(GetCurrentTime().c_str());
193   return true;
194 }
195
196 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
197   std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
198       std::static_pointer_cast<const tpk::parse::PackageInfo>(
199           parser_->GetManifestData(app_keys::kManifestKey));
200   if (!pkg_info) {
201     LOG(ERROR) << "Package info manifest data has not been found.";
202     return false;
203   }
204
205   int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
206
207   manifest->ns = strdup(pkg_info->xmlns().c_str());
208   manifest->package = strdup(pkg_info->package().c_str());
209   manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
210   manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
211   manifest->appsetting = strdup("false");
212   manifest->support_disable = strdup(pkg_info->support_disable().c_str());
213   manifest->version = strdup(pkg_info->version().c_str());
214   manifest->installlocation = strdup(pkg_info->install_location().c_str());
215   manifest->api_version = strdup(pkg_info->api_version().c_str());
216   manifest->readonly = strdup(pkg_info->readonly().c_str());
217   manifest->preload = strdup(pkg_info->preload().c_str());
218   manifest->removable = strdup(pkg_info->removable().c_str());
219
220   common_installer::RequestType req_type = context_->request_type.get();
221   if (pkg_info->type().empty()) {
222     if ((req_type == RequestType::ManifestDirectInstall ||
223         req_type == RequestType::ManifestDirectUpdate) &&
224         context_->is_readonly_package.get())
225       manifest->type = strdup("rpm");
226     else
227       manifest->type = strdup("tpk");
228   } else {
229     manifest->type = strdup(pkg_info->type().c_str());
230   }
231
232   for (auto& pair : pkg_info->labels()) {
233     label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
234     if (!label) {
235       LOG(ERROR) << "Out of memory";
236       return false;
237     }
238     if (!pair.first.empty())
239       label->lang = strdup(pair.first.c_str());
240     else
241       label->lang = strdup(DEFAULT_LOCALE);
242     label->text = strdup(pair.second.c_str());
243     manifest->label = g_list_append(manifest->label, label);
244   }
245
246   std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
247       std::static_pointer_cast<const tpk::parse::ProfileInfo>(
248           parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
249   if (profile_info) {
250     for (auto& profile : profile_info->profiles()) {
251       manifest->deviceprofile = g_list_append(manifest->deviceprofile,
252                                               strdup(profile.c_str()));
253     }
254   }
255
256   // set installed_storage if package is installed
257   // this is internal field in package manager but after reading configuration
258   // we must know it
259   PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
260   if (!manifest->installed_storage) {
261     if (manifest_location_ == ManifestLocation::INSTALLED ||
262         manifest_location_ == ManifestLocation::RECOVERY) {
263       std::string storage = pkg_query.StorageForPkgId();
264       if (storage.empty()) {
265         // Failed to query installation storage, assign internal
266         manifest->installed_storage = strdup(kInstalledInternally);
267       } else {
268         manifest->installed_storage = strdup(storage.c_str());
269       }
270     } else {
271       manifest->installed_storage = strdup(kInstalledInternally);
272     }
273   }
274
275   // retrieve and set plugin execution info if exists
276   if (store_location_ == StoreLocation::BACKUP && (
277       manifest_location_ == ManifestLocation::INSTALLED ||
278       manifest_location_ == ManifestLocation::RECOVERY)) {
279     std::vector<PkgQueryInterface::PluginInfo> plugin_list;
280     pkg_query.PluginExecutionInfo(&plugin_list);
281
282     for (const auto& plugin_info : plugin_list) {
283       plugin_x* plugin =
284           reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
285       if (!plugin) {
286         LOG(ERROR) << "Out of memory";
287         return false;
288       }
289
290       plugin->pkgid = strdup(manifest->package);
291       plugin->appid = strdup(std::get<1>(plugin_info).c_str());
292       plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
293       plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
294       manifest->plugin = g_list_append(manifest->plugin, plugin);
295     }
296   }
297   return true;
298 }
299
300 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
301   std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
302       std::static_pointer_cast<const tpk::parse::AuthorInfo>(
303           parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
304
305   if (!author_info)
306     return true;
307
308   author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
309   if (!author) {
310     LOG(ERROR) << "Out of memory";
311     return false;
312   }
313   author->text = strdup(author_info->name().c_str());
314   author->email = strdup(author_info->email().c_str());
315   author->href = strdup(author_info->href().c_str());
316   author->lang = strdup(DEFAULT_LOCALE);
317   manifest->author = g_list_append(manifest->author, author);
318   return true;
319 }
320
321 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
322   std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
323       std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
324           parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
325
326   if (!description_info)
327     return true;
328
329   for (auto& desc : description_info->descriptions) {
330     description_x* description = reinterpret_cast<description_x*>
331         (calloc(1, sizeof(description_x)));
332     if (!description) {
333       LOG(ERROR) << "Out of memory";
334       return false;
335     }
336     description->text = strdup(desc.description().c_str());
337     description->lang = !desc.xml_lang().empty() ?
338         strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
339     manifest->description = g_list_append(manifest->description, description);
340   }
341   return true;
342 }
343
344 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
345   std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
346       std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
347           parser_->GetManifestData(app_keys::kPrivilegesKey));
348   if (!perm_info)
349     return true;
350
351   const auto& privileges = perm_info->GetPrivileges();
352   for (auto& priv : privileges) {
353     privilege_x* privilege =
354         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
355     if (!privilege) {
356       LOG(ERROR) << "Out of memory";
357       return false;
358     }
359     privilege->value = strdup(priv.first.c_str());
360     privilege->type = strdup(priv.second.c_str());
361     manifest->privileges = g_list_append(manifest->privileges, privilege);
362   }
363
364   const auto& appdef_privileges_list =
365       perm_info->GetAppDefinedPrivilegeInfoList();
366   for (auto& appdef_info : appdef_privileges_list) {
367     appdefined_privilege_x* privilege =
368         reinterpret_cast<appdefined_privilege_x*>(calloc(1,
369             sizeof(appdefined_privilege_x)));
370     if (privilege == nullptr) {
371       LOG(ERROR) << "Memory alloc failure";
372       return false;
373     }
374     auto& priv = appdef_info.GetAppDefinedPrivilege();
375     privilege->value = strdup(priv.privilege.c_str());
376     privilege->type = strdup(priv.type.c_str());
377     if (!priv.license.empty()) {
378       if (fs::path(priv.license).is_absolute())
379         privilege->license = strdup(priv.license.c_str());
380       else
381         privilege->license = strdup((context_->GetPkgPath()
382             / priv.license).c_str());
383     }
384     manifest->appdefined_privileges =
385         g_list_append(manifest->appdefined_privileges, privilege);
386   }
387
388   return true;
389 }
390
391 bool StepParseManifest::FillProvidesAppDefinedPrivileges(
392     manifest_x* manifest) {
393   std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
394       priv_info = std::static_pointer_cast<
395           const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
396               parser_->GetManifestData(
397                   app_keys::kProvidesAppDefinedPrivilegesKey));
398   if (!priv_info)
399     return true;
400
401   const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
402   for (auto& appdef_info : privileges_list) {
403     appdefined_privilege_x* privilege =
404         reinterpret_cast<appdefined_privilege_x*>(calloc(1,
405             sizeof(appdefined_privilege_x)));
406     if (privilege == nullptr) {
407       LOG(ERROR) << "Memory alloc failure";
408       return false;
409     }
410     auto& priv = appdef_info.GetAppDefinedPrivilege();
411     privilege->value = strdup(priv.privilege.c_str());
412     privilege->type = strdup(priv.type.c_str());
413     if (!priv.license.empty()) {
414       if (fs::path(priv.license).is_absolute())
415         privilege->license = strdup(priv.license.c_str());
416       else
417         privilege->license = strdup((context_->GetPkgPath()
418             / priv.license).c_str());
419     }
420     manifest->provides_appdefined_privileges =
421         g_list_append(manifest->provides_appdefined_privileges, privilege);
422   }
423
424   return true;
425 }
426
427 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
428   auto widget_application_list =
429       std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
430           parser_->GetManifestData(app_keys::kWidgetApplicationKey));
431   if (!widget_application_list)
432     return true;
433
434   for (const auto& application : widget_application_list->items) {
435     int package_support_mode_val = atoi(manifest->support_mode);
436     int app_support_mode_val = package_support_mode_val |
437         GetSupportModeVal(application.app_info.support_mode());
438
439     application_x* widget_app =
440         static_cast<application_x*>(calloc(1, sizeof(application_x)));
441     if (!widget_app) {
442       LOG(ERROR) << "Out of memory";
443       return false;
444     }
445     widget_app->appid = strdup(application.app_info.appid().c_str());
446     widget_app->launch_mode =
447         strdup(application.app_info.launch_mode().c_str());
448     widget_app->multiple = strdup("false");
449     widget_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
450     widget_app->support_mode =
451         strdup((std::to_string(app_support_mode_val)).c_str());
452     widget_app->taskmanage = strdup("false");
453     widget_app->indicatordisplay = strdup("false");
454     if (!application.app_info.type().empty())
455       widget_app->type = strdup(application.app_info.type().c_str());
456     else
457       widget_app->type = strdup("capp");
458     widget_app->component_type = strdup("widgetapp");
459     widget_app->hwacceleration =
460         strdup(application.app_info.hwacceleration().c_str());
461     widget_app->onboot = strdup("false");
462     widget_app->autorestart = strdup("false");
463     widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
464     widget_app->screenreader = strdup("use-system-setting");
465     widget_app->recentimage = strdup("false");
466     widget_app->launchcondition = strdup("false");
467     widget_app->guestmode_visibility = strdup("true");
468     widget_app->permission_type = strdup("normal");
469     widget_app->support_ambient = strdup("false");
470     widget_app->effectimage_type = strdup("image");
471     widget_app->submode = strdup("false");
472     widget_app->process_pool = strdup("false");
473     widget_app->package = strdup(manifest->package);
474     widget_app->support_disable = strdup(manifest->support_disable);
475     widget_app->launch_mode = strdup("single");
476     if (!application.app_info.api_version().empty())
477       widget_app->api_version =
478           strdup(application.app_info.api_version().c_str());
479     else
480       widget_app->api_version = strdup(manifest->api_version);
481     manifest->application = g_list_append(manifest->application, widget_app);
482     if (fs::path(application.app_info.exec().c_str()).is_absolute())
483       widget_app->exec = strdup(application.app_info.exec().c_str());
484     else
485       widget_app->exec = strdup((context_->root_application_path.get()
486                             / manifest->package / "bin"
487                             / application.app_info.exec()).c_str());
488
489     if (!FillApplicationIconPaths(widget_app, application.app_icons))
490       return false;
491     if (!FillLabel(widget_app, application.label))
492       return false;
493     if (!FillImage(widget_app, application.app_images))
494       return false;
495     if (!FillCategories(widget_app, application.categories))
496       return false;
497     if (!FillMetadata(widget_app, application.meta_data))
498       return false;
499     if (!FillResControl(widget_app, application.res_controls))
500       return false;
501   }
502   return true;
503 }
504
505 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
506   auto service_application_list =
507       std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
508           parser_->GetManifestData(app_keys::kServiceApplicationKey));
509   if (!service_application_list)
510     return true;
511
512   for (const auto& application : service_application_list->items) {
513     int package_support_mode_val = atoi(manifest->support_mode);
514     int app_support_mode_val = package_support_mode_val |
515         GetSupportModeVal(application.app_info.support_mode());
516
517     application_x* service_app =
518         static_cast<application_x*>(calloc(1, sizeof(application_x)));
519     if (!service_app) {
520       LOG(ERROR) << "Out of memory";
521       return false;
522     }
523     service_app->appid = strdup(application.app_info.appid().c_str());
524     service_app->multiple = strdup(application.app_info.multiple().c_str());
525     service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
526     service_app->support_mode =
527         strdup((std::to_string(app_support_mode_val)).c_str());
528     service_app->autorestart =
529         strdup(application.app_info.auto_restart().c_str());
530     service_app->onboot = strdup(application.app_info.on_boot().c_str());
531     if (!application.app_info.type().empty())
532       service_app->type = strdup(application.app_info.type().c_str());
533     else
534       service_app->type = strdup("capp");
535     service_app->component_type = strdup("svcapp");
536     service_app->mainapp = strdup(application.app_info.mainapp().c_str());
537     service_app->nodisplay = strdup("true");
538     service_app->hwacceleration = strdup("default");
539     service_app->screenreader = strdup("use-system-setting");
540     service_app->recentimage = strdup("false");
541     service_app->launchcondition = strdup("false");
542     service_app->indicatordisplay = strdup("true");
543     service_app->effectimage_type = strdup("image");
544     service_app->guestmode_visibility = strdup("true");
545     service_app->permission_type = strdup("normal");
546     service_app->submode = strdup("false");
547     service_app->process_pool = strdup("false");
548     service_app->support_ambient = strdup("false");
549     service_app->package = strdup(manifest->package);
550     service_app->support_disable = strdup(manifest->support_disable);
551     service_app->launch_mode = strdup("single");
552     if (!application.app_info.api_version().empty())
553       service_app->api_version =
554           strdup(application.app_info.api_version().c_str());
555     else
556       service_app->api_version = strdup(manifest->api_version);
557     manifest->application = g_list_append(manifest->application, service_app);
558     if (fs::path(application.app_info.exec().c_str()).is_absolute())
559       service_app->exec = strdup(application.app_info.exec().c_str());
560     else
561       service_app->exec = strdup((context_->root_application_path.get()
562                             / manifest->package / "bin"
563                             / application.app_info.exec()).c_str());
564
565     if (!FillAppControl(service_app,  application.app_control))
566       return false;
567     if (!FillDataControl(service_app, application.data_control))
568       return false;
569     if (!FillApplicationIconPaths(service_app, application.app_icons))
570       return false;
571     if (!FillLabel(service_app, application.label))
572       return false;
573     if (!FillMetadata(service_app, application.meta_data))
574       return false;
575     if (!FillCategories(service_app, application.categories))
576       return false;
577     if (!FillBackgroundCategoryInfo(service_app,
578         application.background_category))
579       return false;
580     if (!FillResControl(service_app, application.res_controls))
581       return false;
582   }
583   return true;
584 }
585
586 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
587   std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
588       std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
589           parser_->GetManifestData(app_keys::kUIApplicationKey));
590   if (!ui_application_list)
591     return true;
592
593   for (const auto& application : ui_application_list->items) {
594     int package_support_mode_val = atoi(manifest->support_mode);
595     int app_support_mode_val = package_support_mode_val |
596         GetSupportModeVal(application.app_info.support_mode());
597
598     application_x* ui_app =
599         static_cast<application_x*>(calloc(1, sizeof(application_x)));
600     if (!ui_app) {
601       LOG(ERROR) << "Out of memory";
602       return false;
603     }
604     ui_app->appid = strdup(application.app_info.appid().c_str());
605     ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
606     ui_app->multiple = strdup(application.app_info.multiple().c_str());
607     ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
608     ui_app->support_mode =
609         strdup((std::to_string(app_support_mode_val)).c_str());
610     ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
611     if (!application.app_info.type().empty())
612       ui_app->type = strdup(application.app_info.type().c_str());
613     else
614       ui_app->type = strdup("capp");
615     ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
616     ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
617     ui_app->submode = strdup(application.app_info.submode().c_str());
618     if (!application.app_info.indicator_display().empty())
619       ui_app->indicatordisplay =
620           strdup(application.app_info.indicator_display().c_str());
621     if (!application.app_info.effectimage_type().empty())
622       ui_app->effectimage_type =
623           strdup(application.app_info.effectimage_type().c_str());
624     if (!application.app_info.portrait_image().empty()) {
625       ui_app->portraitimg =
626           strdup(application.app_info.portrait_image().c_str());
627       AppendSplashScreen(ui_app, application.app_info.portrait_image(),
628           application.app_info.effectimage_type(), {}, kPortraitOrientation,
629           application.app_info.indicator_display(), {}, {});
630     }
631     if (!application.app_info.landscape_image().empty()) {
632       ui_app->landscapeimg =
633           strdup(application.app_info.landscape_image().c_str());
634       AppendSplashScreen(ui_app, application.app_info.landscape_image(),
635           application.app_info.effectimage_type(), {}, kLandscapeOrientation,
636           application.app_info.indicator_display(), {}, {});
637     }
638     ui_app->submode_mainid =
639         strdup(application.app_info.submode_mainid().c_str());
640     ui_app->hwacceleration =
641         strdup(application.app_info.hwacceleration().c_str());
642     ui_app->onboot = strdup("false");
643     ui_app->autorestart = strdup("false");
644     ui_app->component_type = strdup("uiapp");
645     ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
646     ui_app->screenreader = strdup("use-system-setting");
647     ui_app->recentimage = strdup("false");
648     ui_app->launchcondition = strdup("false");
649     ui_app->guestmode_visibility = strdup("true");
650     ui_app->permission_type = strdup("normal");
651     ui_app->support_ambient = strdup("false");
652     ui_app->package = strdup(manifest->package);
653     ui_app->support_disable = strdup(manifest->support_disable);
654     ui_app->splash_screen_display =
655         strdup(application.app_info.splash_screen_display().c_str());
656     if (!application.app_info.api_version().empty())
657       ui_app->api_version = strdup(application.app_info.api_version().c_str());
658     else
659       ui_app->api_version = strdup(manifest->api_version);
660     manifest->application = g_list_append(manifest->application, ui_app);
661     if (fs::path(application.app_info.exec().c_str()).is_absolute())
662       ui_app->exec = strdup(application.app_info.exec().c_str());
663     else
664       ui_app->exec = strdup((context_->root_application_path.get()
665                             / manifest->package / "bin"
666                             / application.app_info.exec()).c_str());
667
668
669     if (!FillAppControl(ui_app, application.app_control))
670       return false;
671     if (!FillDataControl(ui_app, application.data_control))
672       return false;
673     if (!FillApplicationIconPaths(ui_app, application.app_icons))
674       return false;
675     if (!FillLabel(ui_app, application.label))
676       return false;
677     if (!FillImage(ui_app, application.app_images))
678       return false;
679     if (!FillMetadata(ui_app, application.meta_data))
680       return false;
681     if (!FillCategories(ui_app, application.categories))
682       return false;
683     if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
684       return false;
685     if (!FillSplashScreen(ui_app, application.app_splashscreens))
686       return false;
687     if (!FillResControl(ui_app, application.res_controls))
688       return false;
689   }
690   return true;
691 }
692
693 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
694   auto watch_application_list =
695         std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
696             parser_->GetManifestData(app_keys::kWatchApplicationKey));
697   if (!watch_application_list)
698     return true;
699
700   for (const auto& watch_application : watch_application_list->items) {
701     int package_support_mode_val = atoi(manifest->support_mode);
702     int app_support_mode_val = package_support_mode_val |
703         GetSupportModeVal(watch_application.app_info.support_mode());
704
705     application_x* watch_app =
706              static_cast<application_x*>(calloc(1, sizeof(application_x)));
707     if (!watch_app) {
708       LOG(ERROR) << "Out of memory";
709       return false;
710     }
711     watch_app->appid = strdup(watch_application.app_info.appid().c_str());
712
713     if (fs::path(watch_application.app_info.exec().c_str()).is_absolute())
714       watch_app->exec = strdup(watch_application.app_info.exec().c_str());
715     else
716       watch_app->exec = strdup(
717           (context_->root_application_path.get()
718                                / manifest->package / "bin" /
719                                watch_application.app_info.exec()).c_str());
720     watch_app->nodisplay = strdup("true");
721     watch_app->multiple = strdup("false");
722     if (!watch_application.app_info.type().empty())
723       watch_app->type = strdup(watch_application.app_info.type().c_str());
724     else
725       watch_app->type = strdup("capp");
726     watch_app->taskmanage = strdup("false");
727     watch_app->hwacceleration = strdup("default");
728     watch_app->screenreader = strdup("use-system-setting");
729     watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
730     watch_app->recentimage = strdup("false");
731     watch_app->launchcondition = strdup("false");
732     watch_app->indicatordisplay = strdup("true");
733     watch_app->effectimage_type = strdup("image");
734     watch_app->guestmode_visibility = strdup("true");
735     watch_app->permission_type = strdup("normal");
736     watch_app->component_type = strdup("watchapp");
737     watch_app->preload = strdup("false");
738     watch_app->submode = strdup("false");
739     watch_app->process_pool = strdup("false");
740     watch_app->autorestart = strdup("false");
741     watch_app->onboot = strdup("false");
742     watch_app->support_mode =
743         strdup((std::to_string(app_support_mode_val)).c_str());
744     watch_app->ui_gadget = strdup("false");
745     watch_app->launch_mode = strdup("single");
746     if (!watch_application.app_info.api_version().empty())
747       watch_app->api_version =
748           strdup(watch_application.app_info.api_version().c_str());
749     else
750       watch_app->api_version = strdup(manifest->api_version);
751     watch_app->support_ambient =
752         strdup(watch_application.app_info.ambient_support().c_str());
753     watch_app->package = strdup(manifest->package);
754     if (!watch_application.app_info.setup_appid().empty())
755       watch_app->setup_appid =
756           strdup(watch_application.app_info.setup_appid().c_str());
757     manifest->application = g_list_append(manifest->application, watch_app);
758
759     if (!FillLabel(watch_app, watch_application.label))
760       return false;
761     if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
762       return false;
763     if (!FillMetadata(watch_app, watch_application.meta_data))
764       return false;
765     if (!FillCategories(watch_app, watch_application.categories))
766       return false;
767     if (!FillBackgroundCategoryInfo(watch_app,
768         watch_application.background_category))
769       return false;
770     if (!FillResControl(watch_app, watch_application.res_controls))
771       return false;
772   }
773   return true;
774 }
775
776 bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
777   std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
778       std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
779           parser_->GetManifestData(app_keys::kTrustAnchorKey));
780   if (!trust_anchor_info)
781     return true;
782
783   if (trust_anchor_info->get_use_system_certs().empty()) {
784     LOG(ERROR) << "Invalid trust anchor data";
785     return false;
786   }
787
788   manifest->use_system_certs =
789       strdup(trust_anchor_info->get_use_system_certs().c_str());
790
791   return true;
792 }
793
794 bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
795   std::shared_ptr<const tpk::parse::DependenciesInfo> dependencies_info =
796       std::static_pointer_cast<const tpk::parse::DependenciesInfo>(
797           parser_->GetManifestData(app_keys::kDependenciesKey));
798   if (!dependencies_info)
799     return true;
800
801   for (const auto& dependency : dependencies_info->dependencies()) {
802     dependency_x* dep =
803         static_cast<dependency_x*>(calloc(1, sizeof(dependency_x)));
804     if (!dep) {
805       LOG(ERROR) << "Out of memory";
806       return false;
807     }
808     dep->depends_on = strdup(dependency.pkgid().c_str());
809     dep->type = strdup(dependency.type().c_str());
810     if (!dependency.required_version().empty())
811       dep->required_version = strdup(dependency.required_version().c_str());
812     manifest->dependencies = g_list_append(manifest->dependencies, dep);
813   }
814
815   return true;
816 }
817
818 bool StepParseManifest::FillLightUserInfo(manifest_x* manifest) {
819   std::shared_ptr<const tpk::parse::LightUserInfo> light_user_info =
820       std::static_pointer_cast<const tpk::parse::LightUserInfo>(
821           parser_->GetManifestData(tpk::parse::LightUserInfo::Key()));
822   if (!light_user_info) {
823     manifest->light_user_switch_mode = strdup("default");
824     return true;
825   }
826
827   if (light_user_info->switch_mode().empty()) {
828     LOG(ERROR) << "Invalid switch mode";
829     return false;
830   }
831
832   manifest->light_user_switch_mode =
833       strdup(light_user_info->switch_mode().c_str());
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     fs::path text;
929     if (fs::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 (fs::path(src).is_absolute()) {
1018     splashscreen->src = strdup(src.c_str());
1019   } else {
1020     fs::path full_path = context_->GetPkgPath() / src;
1021     splashscreen->src = strdup(full_path.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 = fs::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 template <typename T>
1068 bool StepParseManifest::FillResControl(application_x* app,
1069     const T& res_control_list) {
1070   for (auto& res_control : res_control_list) {
1071     if (res_control.resource_type().empty())
1072       continue;
1073
1074     res_control_x* rc =
1075         static_cast<res_control_x*>(calloc(1, sizeof(res_control_x)));
1076     if (!rc) {
1077       LOG(ERROR) << "Out of memory";
1078       return false;
1079     }
1080
1081     rc->res_type = strdup(res_control.resource_type().c_str());
1082     if (!res_control.min_res_version().empty())
1083       rc->min_res_version = strdup(res_control.min_res_version().c_str());
1084     if (!res_control.max_res_version().empty())
1085       rc->max_res_version = strdup(res_control.max_res_version().c_str());
1086     if (!res_control.auto_close().empty())
1087       rc->auto_close = strdup(res_control.auto_close().c_str());
1088
1089     app->res_control = g_list_prepend(app->res_control, rc);
1090   }
1091   return true;
1092 }
1093
1094 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
1095     const std::string& key, const std::string& val) {
1096   std::string operation;
1097   auto pos = key.find(kOperationEffectKey);
1098   if (pos != std::string::npos) {
1099     operation = key.substr(pos + 1, key.size());
1100   } else if (key.find(kLaunchEffectKey) != std::string::npos) {
1101     operation = std::string("launch-effect");
1102   } else {
1103     // not a metadata splashscreen
1104     return;
1105   }
1106
1107   std::string portrait_src;
1108   std::string landscape_src;
1109   std::string indicatordisplay;
1110
1111   std::regex re("[=|]");
1112   std::sregex_token_iterator first(val.begin(), val.end(), re, -1);
1113   std::sregex_token_iterator last;
1114   std::vector<std::string> tokens(first, last);
1115   for (const auto& t : tokens) {
1116     if (t.compare(kPortraitEffectImageValue))
1117       portrait_src = t;
1118     else if (t.compare(kLandscapeEffectImageValue))
1119       landscape_src = t;
1120     else if (t.compare(kIndicatorDisplayValue))
1121       indicatordisplay = t;
1122   }
1123
1124   if (!portrait_src.empty())
1125     AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
1126         indicatordisplay, operation, {});
1127   if (!landscape_src.empty())
1128     AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
1129         indicatordisplay, operation, {});
1130 }
1131
1132 bool StepParseManifest::FillImage(application_x* app,
1133                           const tpk::parse::ApplicationImagesInfo& image_list) {
1134   for (auto& app_image : image_list.images) {
1135     image_x* image =
1136         static_cast<image_x*>(calloc(1, sizeof(image_x)));
1137     if (!image) {
1138       LOG(ERROR) << "Out of memory";
1139       return false;
1140     }
1141     const std::string& lang = app_image.lang();
1142     if (!lang.empty())
1143       image->lang = strdup(lang.c_str());
1144     else
1145       image->lang = strdup(DEFAULT_LOCALE);
1146     if (!app_image.section().empty())
1147       image->section = strdup(app_image.section().c_str());
1148     app->image = g_list_append(app->image, image);
1149   }
1150   return true;
1151 }
1152
1153 template <typename T>
1154 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
1155     const T& background_category_data_list) {
1156   for (const auto& background_category : background_category_data_list) {
1157     app->background_category = g_list_append(
1158         app->background_category, strdup(background_category.value().c_str()));
1159   }
1160
1161   return true;
1162 }
1163
1164 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
1165   if (manifest_location_ == ManifestLocation::INSTALLED) {
1166     // recovery of tep value for installed package
1167     PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
1168     std::string old_tep = pkg_query.TepPath();
1169     if (!old_tep.empty())
1170       manifest->tep_name = strdup(old_tep.c_str());
1171
1172     // recovery of zip mount file for installed package
1173     std::string zip_mount_file = pkg_query.ZipMountFile();
1174     if (!zip_mount_file.empty())
1175       manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1176   }
1177
1178   if (manifest->application == nullptr)
1179     return true;
1180
1181   // in case of hybrid package, main app is already set by wgt-backend
1182   application_x* mainapp = nullptr;
1183   if (!context_->cross_app_rules.get()) {
1184     // find mainapp
1185     for (const auto& app : GListRange<application_x*>(manifest->application)) {
1186       if (!strcmp(app->mainapp, "true")) {
1187         mainapp = app;
1188         break;
1189       }
1190     }
1191     if (mainapp == nullptr)
1192       mainapp = reinterpret_cast<application_x*>(
1193           g_list_first(manifest->application)->data);
1194     free(mainapp->mainapp);
1195     mainapp->mainapp = strdup("true");
1196     manifest->mainapp_id = strdup(mainapp->appid);
1197   }
1198
1199   // mark mainapp=false at other apps
1200   for (auto& app : GListRange<application_x*>(manifest->application)) {
1201     if (app == mainapp)
1202       continue;
1203     free(app->mainapp);
1204     app->mainapp = strdup("false");
1205   }
1206   return true;
1207 }
1208
1209 bool StepParseManifest::FillComponentBasedApplicationInfo(
1210     manifest_x* manifest) {
1211   std::shared_ptr<const tpk::parse::ComponentBasedApplicationInfoList>
1212       component_based_application_list = std::static_pointer_cast<
1213           const tpk::parse::ComponentBasedApplicationInfoList>(
1214               parser_->GetManifestData(
1215                   app_keys::kComponentBasedApplicationKey));
1216   if (!component_based_application_list)
1217     return true;
1218
1219   for (const auto& application : component_based_application_list->items) {
1220     int package_support_mode_val = atoi(manifest->support_mode);
1221     int app_support_mode_val = package_support_mode_val |
1222         GetSupportModeVal(application.app_info.support_mode());
1223
1224     application_x* app =
1225         static_cast<application_x*>(calloc(1, sizeof(application_x)));
1226     if (!app) {
1227       LOG(ERROR) << "Out of memory";
1228       return false;
1229     }
1230
1231     app->appid = strdup(application.app_info.appid().c_str());
1232     app->launch_mode = strdup(application.app_info.launch_mode().c_str());
1233     app->multiple = strdup(application.app_info.multiple().c_str());
1234     app->nodisplay = strdup(application.app_info.nodisplay().c_str());
1235     app->support_mode = strdup((std::to_string(app_support_mode_val)).c_str());
1236     app->taskmanage = strdup(application.app_info.taskmanage().c_str());
1237     if (!application.app_info.type().empty())
1238       app->type = strdup(application.app_info.type().c_str());
1239     else
1240       app->type = strdup("c++app");
1241     app->indicatordisplay =
1242         strdup(application.app_info.indicator_display().c_str());
1243     app->component_type = strdup("componentbasedapp");
1244     app->hwacceleration = strdup(application.app_info.hwacceleration().c_str());
1245     app->onboot = strdup("false");
1246     app->autorestart = strdup("false");
1247     app->mainapp = strdup(application.app_info.mainapp().c_str());
1248     app->screenreader = strdup("use-system-setting");
1249     app->recentimage = strdup("false");
1250     app->launchcondition = strdup("false");
1251     app->guestmode_visibility = strdup("true");
1252     app->permission_type = strdup("normal");
1253     app->support_ambient = strdup("false");
1254     app->effectimage_type = strdup("image");
1255     app->submode = strdup("false");
1256     app->process_pool = strdup("false");
1257     app->package = strdup(manifest->package);
1258     app->support_disable = strdup(manifest->support_disable);
1259     app->launch_mode = strdup("single");
1260     if (!application.app_info.api_version().empty())
1261       app->api_version = strdup(application.app_info.api_version().c_str());
1262     else
1263       app->api_version = strdup(manifest->api_version);
1264     app->splash_screen_display =
1265         strdup(application.app_info.splash_screen_display().c_str());
1266     manifest->application = g_list_append(manifest->application, app);
1267     if (fs::path(application.app_info.exec().c_str()).is_absolute()) {
1268       app->exec = strdup(application.app_info.exec().c_str());
1269     } else {
1270       app->exec = strdup((context_->root_application_path.get()
1271                           / manifest->package / "bin"
1272                           / application.app_info.exec()).c_str());
1273     }
1274     if (!FillLabel(app, application.label))
1275       return false;
1276     if (!FillImage(app, application.app_images))
1277       return false;
1278     if (!FillBackgroundCategoryInfo(app, application.background_category))
1279       return false;
1280     if (!FillAppControl(app, application.app_control))
1281       return false;
1282     if (!FillDataControl(app, application.data_control))
1283       return false;
1284     if (!FillMetadata(app, application.meta_data))
1285       return false;
1286     if (!FillCategories(app, application.categories))
1287       return false;
1288     if (!FillSplashScreen(app, application.app_splashscreens))
1289       return false;
1290     if (!FillResControl(app, application.res_controls))
1291       return false;
1292   }
1293
1294   return true;
1295 }
1296
1297 bool StepParseManifest::FillRobotApplicationInfo(
1298     manifest_x* manifest) {
1299   std::shared_ptr<const tpk::parse::RobotApplicationInfoList>
1300       robot_application_list = std::static_pointer_cast<
1301           const tpk::parse::RobotApplicationInfoList>(
1302               parser_->GetManifestData(
1303                   app_keys::kRobotApplicationKey));
1304   if (!robot_application_list)
1305     return true;
1306
1307   for (const auto& application : robot_application_list->items) {
1308     int package_support_mode_val = atoi(manifest->support_mode);
1309     int app_support_mode_val = package_support_mode_val |
1310         GetSupportModeVal(application.app_info.support_mode());
1311
1312     application_x* app =
1313         static_cast<application_x*>(calloc(1, sizeof(application_x)));
1314     if (!app) {
1315       LOG(ERROR) << "Out of memory";
1316       return false;
1317     }
1318
1319     app->appid = strdup(application.app_info.appid().c_str());
1320     app->multiple = strdup("false");
1321     app->nodisplay = strdup("false");
1322     app->support_mode = strdup((std::to_string(app_support_mode_val)).c_str());
1323     app->taskmanage = strdup("false");
1324     if (!application.app_info.type().empty())
1325       app->type = strdup(application.app_info.type().c_str());
1326     else
1327       app->type = strdup("robotapp");
1328     app->indicatordisplay = strdup("false");
1329     app->component_type = strdup("robotapp");
1330     app->hwacceleration = strdup("default");
1331     app->onboot = strdup("false");
1332     app->autorestart = strdup("false");
1333     app->mainapp = strdup(application.app_info.mainapp().c_str());
1334     app->screenreader = strdup("use-system-setting");
1335     app->recentimage = strdup("false");
1336     app->launchcondition = strdup("false");
1337     app->guestmode_visibility = strdup("true");
1338     app->permission_type = strdup("normal");
1339     app->support_ambient = strdup("false");
1340     app->effectimage_type = strdup("image");
1341     app->submode = strdup("false");
1342     app->process_pool = strdup("false");
1343     app->package = strdup(manifest->package);
1344     app->support_disable = strdup(manifest->support_disable);
1345     app->launch_mode = strdup("single");
1346     if (!application.app_info.api_version().empty())
1347       app->api_version = strdup(application.app_info.api_version().c_str());
1348     else
1349       app->api_version = strdup(manifest->api_version);
1350     manifest->application = g_list_append(manifest->application, app);
1351     if (fs::path(application.app_info.exec().c_str()).is_absolute()) {
1352       app->exec = strdup(application.app_info.exec().c_str());
1353     } else {
1354       app->exec = strdup((context_->root_application_path.get()
1355                           / manifest->package / "bin"
1356                           / application.app_info.exec()).c_str());
1357     }
1358     if (!FillApplicationIconPaths(app, application.app_icons))
1359       return false;
1360     if (!FillLabel(app, application.label))
1361       return false;
1362     if (!FillMetadata(app, application.meta_data))
1363       return false;
1364     if (!FillResControl(app, application.res_controls))
1365       return false;
1366   }
1367
1368   return true;
1369 }
1370
1371 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
1372   if (!FillPackageInfo(manifest))
1373     return false;
1374   if (!FillInstallationInfo(manifest))
1375     return false;
1376   if (!FillUIApplication(manifest))
1377     return false;
1378   if (!FillServiceApplication(manifest))
1379     return false;
1380   if (!FillWidgetApplication(manifest))
1381     return false;
1382   if (!FillWatchApplication(manifest))
1383     return false;
1384   if (!FillComponentBasedApplicationInfo(manifest))
1385     return false;
1386   if (!FillRobotApplicationInfo(manifest))
1387     return false;
1388   if (!FillPrivileges(manifest))
1389     return false;
1390   if (!FillProvidesAppDefinedPrivileges(manifest))
1391     return false;
1392   if (!FillAuthorInfo(manifest))
1393     return false;
1394   if (!FillDescriptionInfo(manifest))
1395     return false;
1396   if (!FillExtraInfo(manifest))
1397     return false;
1398   if (!FillTrustAnchorInfo(manifest))
1399     return false;
1400   if (!FillDependencyInfo(manifest))
1401     return false;
1402   if (!FillLightUserInfo(manifest))
1403     return false;
1404   return true;
1405 }
1406
1407 Step::Status StepParseManifest::process() {
1408   if (context_->force_clean_from_db.get())
1409     return Step::Status::OK;
1410   if (!LocateConfigFile()) {
1411     // continue if this is recovery, manifest file may never been created
1412     if (manifest_location_ == ManifestLocation::RECOVERY) {
1413       LOG(DEBUG) << "Manifest for recovery not found";
1414       return Step::Status::OK;
1415     }
1416     LOG(ERROR) << "No manifest file exists";
1417     return Step::Status::MANIFEST_NOT_FOUND;
1418   }
1419   parser_.reset(new tpk::parse::TPKConfigParser());
1420   if (!parser_->ParseManifest(path_)) {
1421     if (manifest_location_ == ManifestLocation::RECOVERY) {
1422       LOG(DEBUG) << "Manifest for recovery is invalid";
1423       fs::remove(path_);
1424       return Step::Status::OK;
1425     }
1426     LOG(ERROR) << "[Parse] Parse failed. " <<  parser_->GetErrorMessage();
1427     return Step::Status::PARSE_ERROR;
1428   }
1429
1430   // Copy data from ManifestData to InstallerContext
1431   std::shared_ptr<const tpk::parse::PackageInfo> info =
1432       std::static_pointer_cast<const tpk::parse::PackageInfo>(
1433           parser_->GetManifestData(app_keys::kManifestKey));
1434
1435   context_->pkgid.set(info->package());
1436
1437   manifest_x* manifest =
1438       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1439   if (!manifest) {
1440     LOG(ERROR) << "Out of memory";
1441     return Step::Status::ERROR;
1442   }
1443
1444   if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1445     LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1446                <<  parser_->GetErrorMessage();
1447     pkgmgr_parser_free_manifest_xml(manifest);
1448     return Step::Status::PARSE_ERROR;
1449   }
1450
1451   // write pkgid for recovery file
1452   if (context_->recovery_info.get().recovery_file) {
1453     context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1454     context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1455   }
1456
1457   LOG(INFO) << "Parsed package id: " << info->package();
1458
1459   switch (store_location_) {
1460     case StoreLocation::NORMAL:
1461       context_->manifest_data.set(manifest);
1462       break;
1463     case StoreLocation::BACKUP:
1464       context_->old_manifest_data.set(manifest);
1465       break;
1466     default:
1467       LOG(ERROR) << "Unknown store location for parsed data";
1468       return Step::Status::ERROR;
1469   }
1470   return Step::Status::OK;
1471 }
1472
1473 }  // namespace configuration
1474 }  // namespace common_installer