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.
5 #include "common/step/configuration/step_parse_manifest.h"
7 #include <boost/tokenizer.hpp>
9 #include <pkgmgr/pkgmgr_parser.h>
10 #include <pkgmgr-info.h>
12 #include <tpk_manifest_handlers/account_handler.h>
13 #include <tpk_manifest_handlers/common/appdefined_privilege_handler.h>
14 #include <tpk_manifest_handlers/application_manifest_constants.h>
15 #include <tpk_manifest_handlers/author_handler.h>
16 #include <tpk_manifest_handlers/description_handler.h>
17 #include <tpk_manifest_handlers/feature_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>
35 #include <type_traits>
39 #include "common/app2ext_dynamic_service.h"
40 #include "common/app_installer.h"
41 #include "common/feature_validator.h"
42 #include "common/installer_context.h"
43 #include "common/paths.h"
44 #include "common/privileges.h"
45 #include "common/pkgmgr_registration.h"
46 #include "common/pkgmgr_query.h"
47 #include "common/step/step.h"
48 #include "common/utils/glist_range.h"
50 namespace app_keys = tpk::application_keys;
51 namespace bf = boost::filesystem;
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";
68 namespace common_installer {
69 namespace configuration {
71 StepParseManifest::StepParseManifest(
72 InstallerContext* context, ManifestLocation manifest_location,
73 StoreLocation store_location)
75 manifest_location_(manifest_location),
76 store_location_(store_location) {
79 Step::Status StepParseManifest::precheck() {
80 switch (manifest_location_) {
81 case ManifestLocation::RECOVERY:
82 if (context_->pkgid.get().empty())
83 return Status::RECOVERY_DONE;
85 case ManifestLocation::INSTALLED:
86 if (context_->pkgid.get().empty()) {
87 LOG(ERROR) << "Package id is not set";
88 return Status::INVALID_VALUE;
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;
98 LOG(ERROR) << "Unknown manifest location";
99 return Status::INVALID_VALUE;
104 bool StepParseManifest::LocateConfigFile() {
105 boost::filesystem::path manifest;
106 switch (manifest_location_) {
107 case ManifestLocation::RECOVERY: {
108 context_->pkg_path.set(
109 context_->root_application_path.get() / context_->pkgid.get());
110 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
111 context_->pkg_path.get()) / kManifestFileName;
112 bf::path in_package_path = context_->pkg_path.get() / kManifestFileName;
113 bf::path install_path =
114 bf::path(getUserManifestPath(context_->uid.get(),
115 context_->is_readonly_package.get()))
116 / bf::path(context_->pkgid.get());
117 install_path += ".xml";
118 if (bf::exists(backup_path))
119 manifest = backup_path;
120 else if (bf::exists(in_package_path))
121 manifest = in_package_path;
122 else if (bf::exists(install_path))
123 manifest = install_path;
126 case ManifestLocation::INSTALLED: {
128 bool is_readonly = context_->is_readonly_package.get();
129 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
130 if (pkg_query.IsGlobalPackage())
131 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
133 uid = context_->uid.get();
135 bf::path(getUserManifestPath(uid, is_readonly))
136 / bf::path(context_->pkgid.get());
138 context_->xml_path.set(xml_path);
139 manifest = context_->xml_path.get();
140 if (!boost::filesystem::exists(manifest)) {
141 /* This routine has added for platform update */
142 manifest = context_->unpacked_dir_path.get();
143 manifest /= kManifestFileName;
147 case ManifestLocation::PACKAGE: {
148 manifest = context_->unpacked_dir_path.get();
149 manifest /= kManifestFileName;
153 LOG(ERROR) << "Unknown manifest location value";
158 LOG(DEBUG) << "manifest path: " << manifest;
160 if (!boost::filesystem::exists(manifest))
167 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
169 std::size_t found = std::string::npos;
171 found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
172 if (found != std::string::npos)
173 mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
175 found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
176 if (found != std::string::npos)
177 mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
179 found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
180 if (found != std::string::npos)
181 mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
186 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
187 manifest->root_path = strdup(
188 (context_->root_application_path.get() / manifest->package).c_str());
189 manifest->installed_time =
190 strdup(std::to_string(std::chrono::system_clock::to_time_t(
191 std::chrono::system_clock::now())).c_str());
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));
200 LOG(ERROR) << "Package info manifest data has not been found.";
204 auto ui_application_list =
205 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
206 parser_->GetManifestData(app_keys::kUIApplicationKey));
207 auto service_application_list =
208 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
209 parser_->GetManifestData(app_keys::kServiceApplicationKey));
210 auto widget_application_list =
211 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
212 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
213 auto watch_application_list =
214 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
215 parser_->GetManifestData(app_keys::kWatchApplicationKey));
218 if (!ui_application_list && !service_application_list &&
219 !widget_application_list && !watch_application_list) {
220 LOG(ERROR) << "UI Application or Service Application or Widget Application "
221 "or Watch Application are mandatory and has not been found.";
225 int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
227 manifest->ns = strdup(pkg_info->xmlns().c_str());
228 manifest->package = strdup(pkg_info->package().c_str());
229 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
230 manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
231 manifest->appsetting = strdup("false");
232 manifest->support_disable = strdup(pkg_info->support_disable().c_str());
233 manifest->version = strdup(pkg_info->version().c_str());
234 manifest->installlocation = strdup(pkg_info->install_location().c_str());
235 manifest->api_version = strdup(pkg_info->api_version().c_str());
236 manifest->readonly = strdup(pkg_info->readonly().c_str());
237 manifest->preload = strdup(pkg_info->preload().c_str());
238 manifest->removable = strdup(pkg_info->removable().c_str());
240 common_installer::RequestType req_type = context_->request_type.get();
241 if (pkg_info->type().empty()) {
242 if ((req_type == RequestType::ManifestDirectInstall ||
243 req_type == RequestType::ManifestDirectUpdate) &&
244 context_->is_readonly_package.get())
245 manifest->type = strdup("rpm");
247 manifest->type = strdup("tpk");
249 manifest->type = strdup(pkg_info->type().c_str());
252 // Set external path if the package is installed at external storage.
253 if (req_type == RequestType::ManifestDirectInstall ||
254 req_type == RequestType::ManifestDirectUpdate ||
255 req_type == RequestType::ManifestPartialInstall ||
256 req_type == RequestType::ManifestPartialUpdate) {
257 App2ExtDynamicService service;
258 std::string image_path = service.GetExternalImagePath(
259 context_->pkgid.get().c_str(), context_->uid.get());
260 if (!image_path.empty()) {
261 manifest->external_path = strdup(image_path.c_str());
262 manifest->installed_storage = strdup(kInstalledExternally);
266 for (auto& pair : pkg_info->labels()) {
267 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
269 LOG(ERROR) << "Out of memory";
272 if (!pair.first.empty())
273 label->lang = strdup(pair.first.c_str());
275 label->lang = strdup(DEFAULT_LOCALE);
276 label->text = strdup(pair.second.c_str());
277 manifest->label = g_list_append(manifest->label, label);
280 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
281 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
282 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
284 for (auto& profile : profile_info->profiles()) {
285 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
286 strdup(profile.c_str()));
290 // set installed_storage if package is installed
291 // this is internal field in package manager but after reading configuration
293 if (!manifest->installed_storage) {
294 if (manifest_location_ == ManifestLocation::INSTALLED ||
295 manifest_location_ == ManifestLocation::RECOVERY) {
296 PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
297 std::string storage = pkg_query.StorageForPkgId();
298 if (storage.empty()) {
299 // Failed to query installation storage, assign internal
300 manifest->installed_storage = strdup(kInstalledInternally);
302 manifest->installed_storage = strdup(storage.c_str());
305 manifest->installed_storage = strdup(kInstalledInternally);
312 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
313 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
314 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
315 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
320 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
322 LOG(ERROR) << "Out of memory";
325 author->text = strdup(author_info->name().c_str());
326 author->email = strdup(author_info->email().c_str());
327 author->href = strdup(author_info->href().c_str());
328 author->lang = strdup(DEFAULT_LOCALE);
329 manifest->author = g_list_append(manifest->author, author);
333 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
334 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
335 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
336 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
338 if (!description_info)
341 for (auto& desc : description_info->descriptions) {
342 description_x* description = reinterpret_cast<description_x*>
343 (calloc(1, sizeof(description_x)));
345 LOG(ERROR) << "Out of memory";
348 description->text = strdup(desc.description().c_str());
349 description->lang = !desc.xml_lang().empty() ?
350 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
351 manifest->description = g_list_append(manifest->description, description);
356 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
357 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
358 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
359 parser_->GetManifestData(app_keys::kPrivilegesKey));
363 const auto& privileges = perm_info->GetPrivileges();
364 for (auto& priv : privileges) {
365 privilege_x* privilege =
366 reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
368 LOG(ERROR) << "Out of memory";
371 privilege->value = strdup(priv.first.c_str());
372 privilege->type = strdup(priv.second.c_str());
373 manifest->privileges = g_list_append(manifest->privileges, privilege);
376 const auto& appdef_privileges_list =
377 perm_info->GetAppDefinedPrivilegeInfoList();
378 for (auto& appdef_info : appdef_privileges_list) {
379 appdefined_privilege_x* privilege =
380 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
381 sizeof(appdefined_privilege_x)));
382 if (privilege == nullptr) {
383 LOG(ERROR) << "Memory alloc failure";
386 auto& priv = appdef_info.GetAppDefinedPrivilege();
387 privilege->value = strdup(priv.privilege.c_str());
388 privilege->type = strdup(priv.type.c_str());
389 if (!priv.license.empty()) {
390 if (bf::path(priv.license).is_absolute())
391 privilege->license = strdup(priv.license.c_str());
393 privilege->license = strdup((context_->pkg_path.get()
394 / priv.license).c_str());
396 manifest->appdefined_privileges =
397 g_list_append(manifest->appdefined_privileges, privilege);
403 bool StepParseManifest::FillProvidesAppDefinedPrivileges(
404 manifest_x* manifest) {
405 std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
406 priv_info = std::static_pointer_cast<
407 const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
408 parser_->GetManifestData(
409 app_keys::kProvidesAppDefinedPrivilegesKey));
413 const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
414 for (auto& appdef_info : privileges_list) {
415 appdefined_privilege_x* privilege =
416 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
417 sizeof(appdefined_privilege_x)));
418 if (privilege == nullptr) {
419 LOG(ERROR) << "Memory alloc failure";
422 auto& priv = appdef_info.GetAppDefinedPrivilege();
423 privilege->value = strdup(priv.privilege.c_str());
424 privilege->type = strdup(priv.type.c_str());
425 if (!priv.license.empty()) {
426 if (bf::path(priv.license).is_absolute())
427 privilege->license = strdup(priv.license.c_str());
429 privilege->license = strdup((context_->pkg_path.get()
430 / priv.license).c_str());
432 manifest->provides_appdefined_privileges =
433 g_list_append(manifest->provides_appdefined_privileges, privilege);
439 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
440 auto widget_application_list =
441 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
442 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
443 if (!widget_application_list)
446 for (const auto& application : widget_application_list->items) {
447 int package_support_mode_val = atoi(manifest->support_mode);
448 int app_support_mode_val = package_support_mode_val |
449 GetSupportModeVal(application.app_info.support_mode());
451 application_x* widget_app =
452 static_cast<application_x*>(calloc(1, sizeof(application_x)));
454 LOG(ERROR) << "Out of memory";
457 widget_app->appid = strdup(application.app_info.appid().c_str());
458 widget_app->launch_mode =
459 strdup(application.app_info.launch_mode().c_str());
460 widget_app->multiple = strdup("false");
461 widget_app->nodisplay = strdup("true");
462 widget_app->support_mode =
463 strdup((std::to_string(app_support_mode_val)).c_str());
464 widget_app->taskmanage = strdup("false");
465 widget_app->indicatordisplay = strdup("false");
467 strdup(application.app_info.type().c_str());
468 widget_app->component_type = strdup("widgetapp");
469 widget_app->hwacceleration =
470 strdup(application.app_info.hwacceleration().c_str());
471 widget_app->onboot = strdup("false");
472 widget_app->autorestart = strdup("false");
473 widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
474 widget_app->screenreader = strdup("use-system-setting");
475 widget_app->recentimage = strdup("false");
476 widget_app->launchcondition = strdup("false");
477 widget_app->guestmode_visibility = strdup("true");
478 widget_app->permission_type = strdup("normal");
479 widget_app->support_ambient = strdup("false");
480 widget_app->effectimage_type = strdup("image");
481 widget_app->submode = strdup("false");
482 widget_app->process_pool = strdup("false");
483 widget_app->package = strdup(manifest->package);
484 widget_app->support_disable = strdup(manifest->support_disable);
485 widget_app->launch_mode = strdup("single");
486 widget_app->api_version = strdup(manifest->api_version);
487 manifest->application = g_list_append(manifest->application, widget_app);
488 if (bf::path(application.app_info.exec().c_str()).is_absolute())
489 widget_app->exec = strdup(application.app_info.exec().c_str());
491 widget_app->exec = strdup((context_->root_application_path.get()
492 / manifest->package / "bin"
493 / application.app_info.exec()).c_str());
495 if (!FillApplicationIconPaths(widget_app, application.app_icons))
497 if (!FillLabel(widget_app, application.label))
499 if (!FillImage(widget_app, application.app_images))
501 if (!FillCategories(widget_app, application.categories))
503 if (!FillMetadata(widget_app, application.meta_data))
509 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
510 auto service_application_list =
511 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
512 parser_->GetManifestData(app_keys::kServiceApplicationKey));
513 if (!service_application_list)
516 for (const auto& application : service_application_list->items) {
517 int package_support_mode_val = atoi(manifest->support_mode);
518 int app_support_mode_val = package_support_mode_val |
519 GetSupportModeVal(application.app_info.support_mode());
521 application_x* service_app =
522 static_cast<application_x*>(calloc(1, sizeof(application_x)));
524 LOG(ERROR) << "Out of memory";
527 service_app->appid = strdup(application.app_info.appid().c_str());
528 service_app->multiple = strdup(application.app_info.multiple().c_str());
529 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
530 service_app->support_mode =
531 strdup((std::to_string(app_support_mode_val)).c_str());
532 service_app->autorestart =
533 strdup(application.app_info.auto_restart().c_str());
534 service_app->onboot = strdup(application.app_info.on_boot().c_str());
535 service_app->type = strdup(application.app_info.type().c_str());
536 service_app->process_pool =
537 strdup(application.app_info.process_pool().c_str());
538 service_app->component_type = strdup("svcapp");
539 service_app->mainapp = strdup(application.app_info.mainapp().c_str());
540 service_app->nodisplay = strdup("true");
541 service_app->hwacceleration = strdup("default");
542 service_app->screenreader = strdup("use-system-setting");
543 service_app->recentimage = strdup("false");
544 service_app->launchcondition = strdup("false");
545 service_app->indicatordisplay = strdup("true");
546 service_app->effectimage_type = strdup("image");
547 service_app->guestmode_visibility = strdup("true");
548 service_app->permission_type = strdup("normal");
549 service_app->submode = strdup("false");
550 service_app->process_pool = strdup("false");
551 service_app->support_ambient = strdup("false");
552 service_app->package = strdup(manifest->package);
553 service_app->support_disable = strdup(manifest->support_disable);
554 service_app->launch_mode = strdup("single");
555 service_app->api_version = strdup(manifest->api_version);
556 manifest->application = g_list_append(manifest->application, service_app);
557 if (bf::path(application.app_info.exec().c_str()).is_absolute())
558 service_app->exec = strdup(application.app_info.exec().c_str());
560 service_app->exec = strdup((context_->root_application_path.get()
561 / manifest->package / "bin"
562 / application.app_info.exec()).c_str());
564 if (!FillAppControl(service_app, application.app_control))
566 if (!FillDataControl(service_app, application.data_control))
568 if (!FillApplicationIconPaths(service_app, application.app_icons))
570 if (!FillLabel(service_app, application.label))
572 if (!FillMetadata(service_app, application.meta_data))
574 if (!FillCategories(service_app, application.categories))
576 if (!FillBackgroundCategoryInfo(service_app,
577 application.background_category))
583 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
584 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
585 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
586 parser_->GetManifestData(app_keys::kUIApplicationKey));
587 if (!ui_application_list)
590 for (const auto& application : ui_application_list->items) {
591 int package_support_mode_val = atoi(manifest->support_mode);
592 int app_support_mode_val = package_support_mode_val |
593 GetSupportModeVal(application.app_info.support_mode());
595 application_x* ui_app =
596 static_cast<application_x*>(calloc(1, sizeof(application_x)));
598 LOG(ERROR) << "Out of memory";
601 ui_app->appid = strdup(application.app_info.appid().c_str());
602 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
603 ui_app->multiple = strdup(application.app_info.multiple().c_str());
604 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
605 ui_app->support_mode =
606 strdup((std::to_string(app_support_mode_val)).c_str());
607 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
608 ui_app->type = strdup(application.app_info.type().c_str());
609 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
610 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
611 ui_app->submode = strdup(application.app_info.submode().c_str());
612 if (!application.app_info.indicator_display().empty())
613 ui_app->indicatordisplay =
614 strdup(application.app_info.indicator_display().c_str());
615 if (!application.app_info.effectimage_type().empty())
616 ui_app->effectimage_type =
617 strdup(application.app_info.effectimage_type().c_str());
618 if (!application.app_info.portrait_image().empty()) {
619 ui_app->portraitimg =
620 strdup(application.app_info.portrait_image().c_str());
621 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
622 application.app_info.effectimage_type(), {}, kPortraitOrientation,
623 application.app_info.indicator_display(), {}, {});
625 if (!application.app_info.landscape_image().empty()) {
626 ui_app->landscapeimg =
627 strdup(application.app_info.landscape_image().c_str());
628 AppendSplashScreen(ui_app, application.app_info.landscape_image(),
629 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
630 application.app_info.indicator_display(), {}, {});
632 ui_app->submode_mainid =
633 strdup(application.app_info.submode_mainid().c_str());
634 ui_app->hwacceleration =
635 strdup(application.app_info.hwacceleration().c_str());
636 ui_app->onboot = strdup("false");
637 ui_app->autorestart = strdup("false");
638 ui_app->component_type = strdup("uiapp");
639 ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
640 ui_app->screenreader = strdup("use-system-setting");
641 ui_app->recentimage = strdup("false");
642 ui_app->launchcondition = strdup("false");
643 ui_app->guestmode_visibility = strdup("true");
644 ui_app->permission_type = strdup("normal");
645 ui_app->support_ambient = strdup("false");
646 ui_app->package = strdup(manifest->package);
647 ui_app->support_disable = strdup(manifest->support_disable);
648 ui_app->splash_screen_display =
649 strdup(application.app_info.splash_screen_display().c_str());
650 ui_app->api_version = strdup(manifest->api_version);
651 manifest->application = g_list_append(manifest->application, ui_app);
652 if (bf::path(application.app_info.exec().c_str()).is_absolute())
653 ui_app->exec = strdup(application.app_info.exec().c_str());
655 ui_app->exec = strdup((context_->root_application_path.get()
656 / manifest->package / "bin"
657 / application.app_info.exec()).c_str());
660 if (!FillAppControl(ui_app, application.app_control))
662 if (!FillDataControl(ui_app, application.data_control))
664 if (!FillApplicationIconPaths(ui_app, application.app_icons))
666 if (!FillLabel(ui_app, application.label))
668 if (!FillImage(ui_app, application.app_images))
670 if (!FillMetadata(ui_app, application.meta_data))
672 if (!FillCategories(ui_app, application.categories))
674 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
676 if (!FillSplashScreen(ui_app, application.app_splashscreens))
682 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
683 auto watch_application_list =
684 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
685 parser_->GetManifestData(app_keys::kWatchApplicationKey));
686 if (!watch_application_list)
689 for (const auto& watch_application : watch_application_list->items) {
690 int package_support_mode_val = atoi(manifest->support_mode);
691 int app_support_mode_val = package_support_mode_val |
692 GetSupportModeVal(watch_application.app_info.support_mode());
694 application_x* watch_app =
695 static_cast<application_x*>(calloc(1, sizeof(application_x)));
697 LOG(ERROR) << "Out of memory";
700 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
702 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
703 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
705 watch_app->exec = strdup(
706 (context_->root_application_path.get()
707 / manifest->package / "bin" /
708 watch_application.app_info.exec()).c_str());
709 watch_app->nodisplay = strdup("true");
710 watch_app->multiple = strdup("false");
711 watch_app->type = strdup(watch_application.app_info.type().c_str());
712 watch_app->taskmanage = strdup("false");
713 watch_app->hwacceleration = strdup("default");
714 watch_app->screenreader = strdup("use-system-setting");
715 watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
716 watch_app->recentimage = strdup("false");
717 watch_app->launchcondition = strdup("false");
718 watch_app->indicatordisplay = strdup("true");
719 watch_app->effectimage_type = strdup("image");
720 watch_app->guestmode_visibility = strdup("true");
721 watch_app->permission_type = strdup("normal");
722 watch_app->component_type = strdup("watchapp");
723 watch_app->preload = strdup("false");
724 watch_app->submode = strdup("false");
725 watch_app->process_pool = strdup("false");
726 watch_app->autorestart = strdup("false");
727 watch_app->onboot = strdup("false");
728 watch_app->support_mode =
729 strdup((std::to_string(app_support_mode_val)).c_str());
730 watch_app->ui_gadget = strdup("false");
731 watch_app->launch_mode = strdup("single");
732 watch_app->api_version = strdup(manifest->api_version);
733 watch_app->support_ambient =
734 strdup(watch_application.app_info.ambient_support().c_str());
735 watch_app->package = strdup(manifest->package);
736 if (!watch_application.app_info.setup_appid().empty())
737 watch_app->setup_appid =
738 strdup(watch_application.app_info.setup_appid().c_str());
740 if (!FillLabel(watch_app, watch_application.label))
742 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
744 if (!FillMetadata(watch_app, watch_application.meta_data))
746 if (!FillCategories(watch_app, watch_application.categories))
748 if (!FillBackgroundCategoryInfo(watch_app,
749 watch_application.background_category))
751 manifest->application = g_list_append(manifest->application, watch_app);
756 bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
757 std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
758 std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
759 parser_->GetManifestData(app_keys::kTrustAnchorKey));
760 if (!trust_anchor_info)
763 if (trust_anchor_info->get_use_system_certs().empty()) {
764 LOG(ERROR) << "Invalid trust anchor data";
768 manifest->use_system_certs =
769 strdup(trust_anchor_info->get_use_system_certs().c_str());
774 bool StepParseManifest::CheckFeatures() {
776 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
777 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
782 FeatureValidator validator(feature_info->features());
783 if (!validator.Validate(&error)) {
784 LOG(ERROR) << "Feature validation error. " << error;
791 template <typename T>
792 bool StepParseManifest::FillAppControl(application_x* app,
793 const T& app_control_list) {
794 if (app_control_list.empty())
797 for (const auto& control : app_control_list) {
798 appcontrol_x* app_control =
799 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
801 LOG(ERROR) << "Out of memory";
804 app_control->operation = strdup(control.operation().c_str());
805 if (!control.mime().empty())
806 app_control->mime = strdup(control.mime().c_str());
807 if (!control.uri().empty())
808 app_control->uri = strdup(control.uri().c_str());
809 for (const auto& priv : control.privileges()) {
810 app_control->privileges = g_list_append(app_control->privileges,
811 strdup(priv.c_str()));
813 app->appcontrol = g_list_append(app->appcontrol, app_control);
818 template <typename T>
819 bool StepParseManifest::FillDataControl(application_x* app,
820 const T& data_control_list) {
821 if (data_control_list.empty())
824 for (const auto& control : data_control_list) {
825 datacontrol_x* data_control =
826 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
828 LOG(ERROR) << "Out of memory";
831 data_control->access = strdup(control.access().c_str());
832 data_control->providerid = strdup(control.providerid().c_str());
833 data_control->type = strdup(control.type().c_str());
834 if (!control.trusted().empty())
835 data_control->trusted = strdup(control.trusted().c_str());
837 data_control->trusted = strdup("false");
838 for (const auto& priv : control.privileges())
839 data_control->privileges = g_list_append(data_control->privileges,
840 strdup(priv.c_str()));
842 app->datacontrol = g_list_append(app->datacontrol, data_control);
847 template <typename T>
848 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
849 const T& icons_info) {
850 for (auto& application_icon : icons_info.icons()) {
851 icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
853 LOG(ERROR) << "Out of memory";
857 if (bf::path(application_icon.path()).is_absolute()) {
858 text = application_icon.path();
860 text = context_->root_application_path.get()
861 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
863 // NOTE: name is an attribute, but the xml writer uses it as text.
864 // This must be fixed in whole app-installer modules, including wgt.
865 // Current implementation is just for compatibility.
866 icon->text = strdup(text.c_str());
867 if (application_icon.lang().empty())
868 icon->lang = strdup(DEFAULT_LOCALE);
870 icon->lang = strdup(application_icon.lang().c_str());
872 if (!application_icon.dpi().empty())
873 icon->dpi = strdup(application_icon.dpi().c_str());
874 app->icon = g_list_append(app->icon, icon);
879 template <typename T>
880 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
881 if (label_list.empty())
884 for (const auto& control : label_list) {
886 static_cast<label_x*>(calloc(1, sizeof(label_x)));
888 LOG(ERROR) << "Out of memory";
891 // NOTE: name is an attribute, but the xml writer uses it as text.
892 // This must be fixed in whole app-installer modules, including wgt.
893 // Current implementation is just for compatibility.
894 label->text = strdup(control.text().c_str());
895 label->name = strdup(control.name().c_str());
896 label->lang = !control.xml_lang().empty() ?
897 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
898 app->label = g_list_append(app->label, label);
903 template <typename T>
904 bool StepParseManifest::FillMetadata(application_x* app,
905 const T& meta_data_list) {
906 if (meta_data_list.empty())
909 for (auto& meta : meta_data_list) {
910 metadata_x* metadata =
911 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
913 LOG(ERROR) << "Out of memory";
916 metadata->key = strdup(meta.key().c_str());
917 metadata->value = strdup(meta.val().c_str());
918 app->metadata = g_list_append(app->metadata, metadata);
920 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
925 template <typename T>
926 bool StepParseManifest::FillCategories(application_x* manifest,
927 const T& categories) {
928 for (auto& category : categories) {
929 manifest->category = g_list_append(manifest->category,
930 strdup(category.c_str()));
935 void StepParseManifest::AppendSplashScreen(application_x* app,
936 const std::string& src, const std::string& type, const std::string& dpi,
937 const std::string& orientation, const std::string& indicatordisplay,
938 const std::string& operation, const std::string& color_depth) {
939 splashscreen_x* splashscreen =
940 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
942 LOG(ERROR) << "Out of memory";
945 if (bf::path(src).is_absolute()) {
946 splashscreen->src = strdup(src.c_str());
948 bf::path full_path = context_->pkg_path.get() / src;
949 splashscreen->src = strdup(full_path.string().c_str());
951 if (src.substr(src.find_last_of(".") + 1) == "edj")
952 splashscreen->type = strdup("edj");
953 else if (type == "edj")
954 splashscreen->type = strdup("edj");
956 splashscreen->type = strdup("img");
958 splashscreen->dpi = strdup(dpi.c_str());
959 splashscreen->orientation = strdup(orientation.c_str());
960 if (!indicatordisplay.empty())
961 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
963 splashscreen->indicatordisplay = strdup("true");
964 if (operation == "launch_effect")
965 splashscreen->operation = strdup("launch-effect");
966 else if (!operation.empty())
967 splashscreen->operation = strdup(operation.c_str());
969 splashscreen->operation = strdup("launch-effect");
970 if (!color_depth.empty())
971 splashscreen->color_depth = strdup(color_depth.c_str());
973 splashscreen->color_depth = strdup("24");
974 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
977 template <typename T>
978 bool StepParseManifest::FillSplashScreen(application_x* app,
979 const T& splashscreens_info) {
980 for (auto& splash_screen : splashscreens_info.splashscreens()) {
982 if (context_->is_readonly_package.get())
983 src = splash_screen.src();
985 src = bf::path(context_->root_application_path.get()
986 / app->package / "shared" / "res" / splash_screen.src()).string();
988 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
989 splash_screen.orientation(), splash_screen.indicatordisplay(),
990 splash_screen.operation(), splash_screen.colordepth());
995 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
996 const std::string& key, const std::string& val) {
997 std::string operation;
998 if (key.find(kOperationEffectKey) != std::string::npos) {
999 boost::char_separator<char> sep("=");
1000 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
1001 auto iter = tokens.begin();
1004 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
1005 operation = std::string("launch-effect");
1007 // not a metadata splashscreen
1011 boost::char_separator<char> sep("=|");
1012 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
1013 auto iter = tokens.begin();
1014 std::string portrait_src;
1015 std::string landscape_src;
1016 std::string indicatordisplay;
1017 while (iter != tokens.end()) {
1018 if (!(*iter).compare(kPortraitEffectImageValue)) {
1020 portrait_src = *iter;
1021 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
1023 landscape_src = *iter;
1024 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
1026 indicatordisplay = *iter;
1030 if (!portrait_src.empty())
1031 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
1032 indicatordisplay, operation, {});
1033 if (!landscape_src.empty())
1034 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
1035 indicatordisplay, operation, {});
1038 bool StepParseManifest::FillImage(application_x* app,
1039 const tpk::parse::ApplicationImagesInfo& image_list) {
1040 for (auto& app_image : image_list.images) {
1042 static_cast<image_x*>(calloc(1, sizeof(image_x)));
1044 LOG(ERROR) << "Out of memory";
1047 const std::string& lang = app_image.lang();
1049 image->lang = strdup(lang.c_str());
1051 image->lang = strdup(DEFAULT_LOCALE);
1052 if (!app_image.section().empty())
1053 image->section = strdup(app_image.section().c_str());
1054 app->image = g_list_append(app->image, image);
1059 template <typename T>
1060 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
1061 const T& background_category_data_list) {
1062 for (const auto& background_category : background_category_data_list) {
1063 app->background_category = g_list_append(
1064 app->background_category, strdup(background_category.value().c_str()));
1070 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
1071 if (manifest_location_ == ManifestLocation::INSTALLED) {
1072 // recovery of tep value for installed package
1073 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
1074 std::string old_tep = pkg_query.TepPath();
1075 if (!old_tep.empty())
1076 manifest->tep_name = strdup(old_tep.c_str());
1078 // recovery of zip mount file for installed package
1079 std::string zip_mount_file = pkg_query.ZipMountFile();
1080 if (!zip_mount_file.empty())
1081 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1084 // in case of hybrid package, main app is already set by wgt-backend
1085 application_x* mainapp = nullptr;
1086 if (!context_->cross_app_rules.get()) {
1088 for (const auto& app : GListRange<application_x*>(manifest->application)) {
1089 if (!strcmp(app->mainapp, "true")) {
1094 if (mainapp == nullptr)
1095 mainapp = reinterpret_cast<application_x*>(
1096 g_list_first(manifest->application)->data);
1097 free(mainapp->mainapp);
1098 mainapp->mainapp = strdup("true");
1099 manifest->mainapp_id = strdup(mainapp->appid);
1102 // mark mainapp=false at other apps
1103 for (auto& app : GListRange<application_x*>(manifest->application)) {
1107 app->mainapp = strdup("false");
1112 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
1113 if (!FillPackageInfo(manifest))
1115 if (!FillInstallationInfo(manifest))
1117 if (!FillUIApplication(manifest))
1119 if (!FillServiceApplication(manifest))
1121 if (!FillWidgetApplication(manifest))
1123 if (!FillWatchApplication(manifest))
1125 if (!FillPrivileges(manifest))
1127 if (!FillProvidesAppDefinedPrivileges(manifest))
1129 if (!FillAuthorInfo(manifest))
1131 if (!FillDescriptionInfo(manifest))
1133 if (!FillExtraInfo(manifest))
1135 if (!FillTrustAnchorInfo(manifest))
1140 Step::Status StepParseManifest::process() {
1141 if (context_->force_clean_from_db.get())
1142 return Step::Status::OK;
1143 if (!LocateConfigFile()) {
1144 // continue if this is recovery, manifest file may never been created
1145 if (manifest_location_ == ManifestLocation::RECOVERY) {
1146 LOG(DEBUG) << "Manifest for recovery not found";
1147 return Step::Status::OK;
1149 LOG(ERROR) << "No manifest file exists";
1150 return Step::Status::MANIFEST_NOT_FOUND;
1152 parser_.reset(new tpk::parse::TPKConfigParser());
1153 if (!parser_->ParseManifest(path_)) {
1154 if (manifest_location_ == ManifestLocation::RECOVERY) {
1155 LOG(DEBUG) << "Manifest for recovery is invalid";
1157 return Step::Status::OK;
1159 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
1160 return Step::Status::PARSE_ERROR;
1163 // Copy data from ManifestData to InstallerContext
1164 std::shared_ptr<const tpk::parse::PackageInfo> info =
1165 std::static_pointer_cast<const tpk::parse::PackageInfo>(
1166 parser_->GetManifestData(app_keys::kManifestKey));
1168 context_->pkgid.set(info->package());
1169 context_->pkg_path.set(
1170 context_->root_application_path.get() / context_->pkgid.get());
1172 manifest_x* manifest =
1173 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1175 LOG(ERROR) << "Out of memory";
1176 return Step::Status::ERROR;
1179 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1180 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1181 << parser_->GetErrorMessage();
1182 pkgmgr_parser_free_manifest_xml(manifest);
1183 return Step::Status::PARSE_ERROR;
1186 // write pkgid for recovery file
1187 if (context_->recovery_info.get().recovery_file) {
1188 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1189 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1192 LOG(DEBUG) << "Parsed package id: " << info->package();
1194 switch (store_location_) {
1195 case StoreLocation::NORMAL:
1196 context_->manifest_data.set(manifest);
1198 case StoreLocation::BACKUP:
1199 context_->old_manifest_data.set(manifest);
1202 LOG(ERROR) << "Unknown store location for parsed data";
1203 return Step::Status::ERROR;
1205 return Step::Status::OK;
1208 } // namespace configuration
1209 } // namespace common_installer