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