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/dependencies_handler.h>
17 #include <tpk_manifest_handlers/description_handler.h>
18 #include <tpk_manifest_handlers/feature_handler.h>
19 #include <tpk_manifest_handlers/package_handler.h>
20 #include <tpk_manifest_handlers/privileges_handler.h>
21 #include <tpk_manifest_handlers/profile_handler.h>
22 #include <tpk_manifest_handlers/provides_appdefined_privileges_handler.h>
23 #include <tpk_manifest_handlers/service_application_handler.h>
24 #include <tpk_manifest_handlers/shortcut_handler.h>
25 #include <tpk_manifest_handlers/trust_anchor_handler.h>
26 #include <tpk_manifest_handlers/ui_application_handler.h>
27 #include <tpk_manifest_handlers/watch_application_handler.h>
28 #include <tpk_manifest_handlers/widget_application_handler.h>
36 #include <type_traits>
40 #include "common/app2ext_dynamic_service.h"
41 #include "common/app_installer.h"
42 #include "common/feature_validator.h"
43 #include "common/installer_context.h"
44 #include "common/paths.h"
45 #include "common/privileges.h"
46 #include "common/pkgmgr_registration.h"
47 #include "common/pkgmgr_query.h"
48 #include "common/step/step.h"
49 #include "common/utils/glist_range.h"
51 namespace app_keys = tpk::application_keys;
52 namespace bf = boost::filesystem;
56 const char kManifestFileName[] = "tizen-manifest.xml";
57 const char kInstalledInternally[] = "installed_internal";
58 const char kInstalledExternally[] = "installed_external";
59 const char kPortraitOrientation[] = "portrait";
60 const char kLandscapeOrientation[] = "landscape";
61 const char kOperationEffectKey[] = "operation_effect";
62 const char kLaunchEffectKey[] = "launch_effect";
63 const char kPortraitEffectImageValue[] = "portrait-effectimage";
64 const char kLandscapeEffectImageValue[] = "landscape-effectimage";
65 const char kIndicatorDisplayValue[] = "indicatordisplay";
69 namespace common_installer {
70 namespace configuration {
72 StepParseManifest::StepParseManifest(
73 InstallerContext* context, ManifestLocation manifest_location,
74 StoreLocation store_location)
76 manifest_location_(manifest_location),
77 store_location_(store_location) {
80 Step::Status StepParseManifest::precheck() {
81 switch (manifest_location_) {
82 case ManifestLocation::RECOVERY:
83 if (context_->pkgid.get().empty())
84 return Status::RECOVERY_DONE;
86 case ManifestLocation::INSTALLED:
87 if (context_->pkgid.get().empty()) {
88 LOG(ERROR) << "Package id is not set";
89 return Status::INVALID_VALUE;
92 case ManifestLocation::PACKAGE:
93 if (context_->unpacked_dir_path.get().empty()) {
94 LOG(ERROR) << "Unpacked directory doesn't exist";
95 return Status::INVALID_VALUE;
99 LOG(ERROR) << "Unknown manifest location";
100 return Status::INVALID_VALUE;
105 bool StepParseManifest::LocateConfigFile() {
106 boost::filesystem::path manifest;
107 switch (manifest_location_) {
108 case ManifestLocation::RECOVERY: {
109 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
110 context_->GetPkgPath()) / kManifestFileName;
111 bf::path in_package_path = context_->GetPkgPath() / kManifestFileName;
112 bf::path install_path =
113 bf::path(getUserManifestPath(context_->uid.get(),
114 context_->is_readonly_package.get()))
115 / bf::path(context_->pkgid.get());
116 install_path += ".xml";
117 if (bf::exists(backup_path))
118 manifest = backup_path;
119 else if (bf::exists(in_package_path))
120 manifest = in_package_path;
121 else if (bf::exists(install_path))
122 manifest = install_path;
125 case ManifestLocation::INSTALLED: {
127 bool is_readonly = context_->is_readonly_package.get();
128 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
129 if (pkg_query.IsGlobalPackage())
130 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
132 uid = context_->uid.get();
134 bf::path(getUserManifestPath(uid, is_readonly))
135 / bf::path(context_->pkgid.get());
137 context_->xml_path.set(xml_path);
138 manifest = context_->xml_path.get();
139 if (!boost::filesystem::exists(manifest)) {
140 /* This routine has added for platform update */
141 manifest = context_->unpacked_dir_path.get();
142 manifest /= kManifestFileName;
146 case ManifestLocation::PACKAGE: {
147 manifest = context_->unpacked_dir_path.get();
148 manifest /= kManifestFileName;
152 LOG(ERROR) << "Unknown manifest location value";
157 LOG(DEBUG) << "manifest path: " << manifest;
159 if (!boost::filesystem::exists(manifest))
166 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
168 std::size_t found = std::string::npos;
170 found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
171 if (found != std::string::npos)
172 mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
174 found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
175 if (found != std::string::npos)
176 mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
178 found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
179 if (found != std::string::npos)
180 mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
185 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
186 manifest->root_path = strdup(
187 (context_->root_application_path.get() / manifest->package).c_str());
188 manifest->installed_time =
189 strdup(std::to_string(std::chrono::system_clock::to_time_t(
190 std::chrono::system_clock::now())).c_str());
194 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
195 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
196 std::static_pointer_cast<const tpk::parse::PackageInfo>(
197 parser_->GetManifestData(app_keys::kManifestKey));
199 LOG(ERROR) << "Package info manifest data has not been found.";
203 auto ui_application_list =
204 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
205 parser_->GetManifestData(app_keys::kUIApplicationKey));
206 auto service_application_list =
207 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
208 parser_->GetManifestData(app_keys::kServiceApplicationKey));
209 auto widget_application_list =
210 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
211 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
212 auto watch_application_list =
213 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
214 parser_->GetManifestData(app_keys::kWatchApplicationKey));
217 if (!ui_application_list && !service_application_list &&
218 !widget_application_list && !watch_application_list) {
219 LOG(ERROR) << "UI Application or Service Application or Widget Application "
220 "or Watch Application are mandatory and has not been found.";
224 int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
226 manifest->ns = strdup(pkg_info->xmlns().c_str());
227 manifest->package = strdup(pkg_info->package().c_str());
228 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
229 manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
230 manifest->appsetting = strdup("false");
231 manifest->support_disable = strdup(pkg_info->support_disable().c_str());
232 manifest->version = strdup(pkg_info->version().c_str());
233 manifest->installlocation = strdup(pkg_info->install_location().c_str());
234 manifest->api_version = strdup(pkg_info->api_version().c_str());
235 manifest->readonly = strdup(pkg_info->readonly().c_str());
236 manifest->preload = strdup(pkg_info->preload().c_str());
237 manifest->removable = strdup(pkg_info->removable().c_str());
239 common_installer::RequestType req_type = context_->request_type.get();
240 if (pkg_info->type().empty()) {
241 if ((req_type == RequestType::ManifestDirectInstall ||
242 req_type == RequestType::ManifestDirectUpdate) &&
243 context_->is_readonly_package.get())
244 manifest->type = strdup("rpm");
246 manifest->type = strdup("tpk");
248 manifest->type = strdup(pkg_info->type().c_str());
251 // Set external path if the package is installed at external storage.
252 if (req_type == RequestType::ManifestDirectInstall ||
253 req_type == RequestType::ManifestDirectUpdate ||
254 req_type == RequestType::ManifestPartialInstall ||
255 req_type == RequestType::ManifestPartialUpdate ||
256 req_type == RequestType::RecoverDB) {
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 PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
294 if (!manifest->installed_storage) {
295 if (manifest_location_ == ManifestLocation::INSTALLED ||
296 manifest_location_ == ManifestLocation::RECOVERY) {
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);
309 // retrieve and set plugin execution info if exists
310 if (manifest_location_ == ManifestLocation::INSTALLED ||
311 manifest_location_ == ManifestLocation::RECOVERY) {
312 std::vector<PkgQueryInterface::PluginInfo> plugin_list;
313 pkg_query.PluginExecutionInfo(&plugin_list);
315 for (const auto& plugin_info : plugin_list) {
317 reinterpret_cast<plugin_x*>(calloc(1, sizeof(plugin_x)));
319 LOG(ERROR) << "Out of memory";
323 plugin->pkgid = strdup(manifest->package);
324 plugin->appid = strdup(std::get<1>(plugin_info).c_str());
325 plugin->plugin_type = strdup(std::get<2>(plugin_info).c_str());
326 plugin->plugin_name = strdup(std::get<3>(plugin_info).c_str());
327 manifest->plugin = g_list_append(manifest->plugin, plugin);
333 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
334 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
335 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
336 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
341 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
343 LOG(ERROR) << "Out of memory";
346 author->text = strdup(author_info->name().c_str());
347 author->email = strdup(author_info->email().c_str());
348 author->href = strdup(author_info->href().c_str());
349 author->lang = strdup(DEFAULT_LOCALE);
350 manifest->author = g_list_append(manifest->author, author);
354 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
355 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
356 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
357 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
359 if (!description_info)
362 for (auto& desc : description_info->descriptions) {
363 description_x* description = reinterpret_cast<description_x*>
364 (calloc(1, sizeof(description_x)));
366 LOG(ERROR) << "Out of memory";
369 description->text = strdup(desc.description().c_str());
370 description->lang = !desc.xml_lang().empty() ?
371 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
372 manifest->description = g_list_append(manifest->description, description);
377 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
378 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
379 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
380 parser_->GetManifestData(app_keys::kPrivilegesKey));
384 const auto& privileges = perm_info->GetPrivileges();
385 for (auto& priv : privileges) {
386 privilege_x* privilege =
387 reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
389 LOG(ERROR) << "Out of memory";
392 privilege->value = strdup(priv.first.c_str());
393 privilege->type = strdup(priv.second.c_str());
394 manifest->privileges = g_list_append(manifest->privileges, privilege);
397 const auto& appdef_privileges_list =
398 perm_info->GetAppDefinedPrivilegeInfoList();
399 for (auto& appdef_info : appdef_privileges_list) {
400 appdefined_privilege_x* privilege =
401 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
402 sizeof(appdefined_privilege_x)));
403 if (privilege == nullptr) {
404 LOG(ERROR) << "Memory alloc failure";
407 auto& priv = appdef_info.GetAppDefinedPrivilege();
408 privilege->value = strdup(priv.privilege.c_str());
409 privilege->type = strdup(priv.type.c_str());
410 if (!priv.license.empty()) {
411 if (bf::path(priv.license).is_absolute())
412 privilege->license = strdup(priv.license.c_str());
414 privilege->license = strdup((context_->GetPkgPath()
415 / priv.license).c_str());
417 manifest->appdefined_privileges =
418 g_list_append(manifest->appdefined_privileges, privilege);
424 bool StepParseManifest::FillProvidesAppDefinedPrivileges(
425 manifest_x* manifest) {
426 std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
427 priv_info = std::static_pointer_cast<
428 const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
429 parser_->GetManifestData(
430 app_keys::kProvidesAppDefinedPrivilegesKey));
434 const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
435 for (auto& appdef_info : privileges_list) {
436 appdefined_privilege_x* privilege =
437 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
438 sizeof(appdefined_privilege_x)));
439 if (privilege == nullptr) {
440 LOG(ERROR) << "Memory alloc failure";
443 auto& priv = appdef_info.GetAppDefinedPrivilege();
444 privilege->value = strdup(priv.privilege.c_str());
445 privilege->type = strdup(priv.type.c_str());
446 if (!priv.license.empty()) {
447 if (bf::path(priv.license).is_absolute())
448 privilege->license = strdup(priv.license.c_str());
450 privilege->license = strdup((context_->GetPkgPath()
451 / priv.license).c_str());
453 manifest->provides_appdefined_privileges =
454 g_list_append(manifest->provides_appdefined_privileges, privilege);
460 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
461 auto widget_application_list =
462 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
463 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
464 if (!widget_application_list)
467 for (const auto& application : widget_application_list->items) {
468 int package_support_mode_val = atoi(manifest->support_mode);
469 int app_support_mode_val = package_support_mode_val |
470 GetSupportModeVal(application.app_info.support_mode());
472 application_x* widget_app =
473 static_cast<application_x*>(calloc(1, sizeof(application_x)));
475 LOG(ERROR) << "Out of memory";
478 widget_app->appid = strdup(application.app_info.appid().c_str());
479 widget_app->launch_mode =
480 strdup(application.app_info.launch_mode().c_str());
481 widget_app->multiple = strdup("false");
482 widget_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
483 widget_app->support_mode =
484 strdup((std::to_string(app_support_mode_val)).c_str());
485 widget_app->taskmanage = strdup("false");
486 widget_app->indicatordisplay = strdup("false");
487 if (!application.app_info.type().empty())
488 widget_app->type = strdup(application.app_info.type().c_str());
490 widget_app->type = strdup("capp");
491 widget_app->component_type = strdup("widgetapp");
492 widget_app->hwacceleration =
493 strdup(application.app_info.hwacceleration().c_str());
494 widget_app->onboot = strdup("false");
495 widget_app->autorestart = strdup("false");
496 widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
497 widget_app->screenreader = strdup("use-system-setting");
498 widget_app->recentimage = strdup("false");
499 widget_app->launchcondition = strdup("false");
500 widget_app->guestmode_visibility = strdup("true");
501 widget_app->permission_type = strdup("normal");
502 widget_app->support_ambient = strdup("false");
503 widget_app->effectimage_type = strdup("image");
504 widget_app->submode = strdup("false");
505 widget_app->process_pool = strdup("false");
506 widget_app->package = strdup(manifest->package);
507 widget_app->support_disable = strdup(manifest->support_disable);
508 widget_app->launch_mode = strdup("single");
509 widget_app->api_version = strdup(manifest->api_version);
510 manifest->application = g_list_append(manifest->application, widget_app);
511 if (bf::path(application.app_info.exec().c_str()).is_absolute())
512 widget_app->exec = strdup(application.app_info.exec().c_str());
514 widget_app->exec = strdup((context_->root_application_path.get()
515 / manifest->package / "bin"
516 / application.app_info.exec()).c_str());
518 if (!FillApplicationIconPaths(widget_app, application.app_icons))
520 if (!FillLabel(widget_app, application.label))
522 if (!FillImage(widget_app, application.app_images))
524 if (!FillCategories(widget_app, application.categories))
526 if (!FillMetadata(widget_app, application.meta_data))
532 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
533 auto service_application_list =
534 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
535 parser_->GetManifestData(app_keys::kServiceApplicationKey));
536 if (!service_application_list)
539 for (const auto& application : service_application_list->items) {
540 int package_support_mode_val = atoi(manifest->support_mode);
541 int app_support_mode_val = package_support_mode_val |
542 GetSupportModeVal(application.app_info.support_mode());
544 application_x* service_app =
545 static_cast<application_x*>(calloc(1, sizeof(application_x)));
547 LOG(ERROR) << "Out of memory";
550 service_app->appid = strdup(application.app_info.appid().c_str());
551 service_app->multiple = strdup(application.app_info.multiple().c_str());
552 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
553 service_app->support_mode =
554 strdup((std::to_string(app_support_mode_val)).c_str());
555 service_app->autorestart =
556 strdup(application.app_info.auto_restart().c_str());
557 service_app->onboot = strdup(application.app_info.on_boot().c_str());
558 if (!application.app_info.type().empty())
559 service_app->type = strdup(application.app_info.type().c_str());
561 service_app->type = strdup("capp");
562 service_app->process_pool =
563 strdup(application.app_info.process_pool().c_str());
564 service_app->component_type = strdup("svcapp");
565 service_app->mainapp = strdup(application.app_info.mainapp().c_str());
566 service_app->nodisplay = strdup("true");
567 service_app->hwacceleration = strdup("default");
568 service_app->screenreader = strdup("use-system-setting");
569 service_app->recentimage = strdup("false");
570 service_app->launchcondition = strdup("false");
571 service_app->indicatordisplay = strdup("true");
572 service_app->effectimage_type = strdup("image");
573 service_app->guestmode_visibility = strdup("true");
574 service_app->permission_type = strdup("normal");
575 service_app->submode = strdup("false");
576 service_app->process_pool = strdup("false");
577 service_app->support_ambient = strdup("false");
578 service_app->package = strdup(manifest->package);
579 service_app->support_disable = strdup(manifest->support_disable);
580 service_app->launch_mode = strdup("single");
581 service_app->api_version = strdup(manifest->api_version);
582 manifest->application = g_list_append(manifest->application, service_app);
583 if (bf::path(application.app_info.exec().c_str()).is_absolute())
584 service_app->exec = strdup(application.app_info.exec().c_str());
586 service_app->exec = strdup((context_->root_application_path.get()
587 / manifest->package / "bin"
588 / application.app_info.exec()).c_str());
590 if (!FillAppControl(service_app, application.app_control))
592 if (!FillDataControl(service_app, application.data_control))
594 if (!FillApplicationIconPaths(service_app, application.app_icons))
596 if (!FillLabel(service_app, application.label))
598 if (!FillMetadata(service_app, application.meta_data))
600 if (!FillCategories(service_app, application.categories))
602 if (!FillBackgroundCategoryInfo(service_app,
603 application.background_category))
609 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
610 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
611 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
612 parser_->GetManifestData(app_keys::kUIApplicationKey));
613 if (!ui_application_list)
616 for (const auto& application : ui_application_list->items) {
617 int package_support_mode_val = atoi(manifest->support_mode);
618 int app_support_mode_val = package_support_mode_val |
619 GetSupportModeVal(application.app_info.support_mode());
621 application_x* ui_app =
622 static_cast<application_x*>(calloc(1, sizeof(application_x)));
624 LOG(ERROR) << "Out of memory";
627 ui_app->appid = strdup(application.app_info.appid().c_str());
628 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
629 ui_app->multiple = strdup(application.app_info.multiple().c_str());
630 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
631 ui_app->support_mode =
632 strdup((std::to_string(app_support_mode_val)).c_str());
633 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
634 if (!application.app_info.type().empty())
635 ui_app->type = strdup(application.app_info.type().c_str());
637 ui_app->type = strdup("capp");
638 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
639 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
640 ui_app->submode = strdup(application.app_info.submode().c_str());
641 if (!application.app_info.indicator_display().empty())
642 ui_app->indicatordisplay =
643 strdup(application.app_info.indicator_display().c_str());
644 if (!application.app_info.effectimage_type().empty())
645 ui_app->effectimage_type =
646 strdup(application.app_info.effectimage_type().c_str());
647 if (!application.app_info.portrait_image().empty()) {
648 ui_app->portraitimg =
649 strdup(application.app_info.portrait_image().c_str());
650 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
651 application.app_info.effectimage_type(), {}, kPortraitOrientation,
652 application.app_info.indicator_display(), {}, {});
654 if (!application.app_info.landscape_image().empty()) {
655 ui_app->landscapeimg =
656 strdup(application.app_info.landscape_image().c_str());
657 AppendSplashScreen(ui_app, application.app_info.landscape_image(),
658 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
659 application.app_info.indicator_display(), {}, {});
661 ui_app->submode_mainid =
662 strdup(application.app_info.submode_mainid().c_str());
663 ui_app->hwacceleration =
664 strdup(application.app_info.hwacceleration().c_str());
665 ui_app->onboot = strdup("false");
666 ui_app->autorestart = strdup("false");
667 ui_app->component_type = strdup("uiapp");
668 ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
669 ui_app->screenreader = strdup("use-system-setting");
670 ui_app->recentimage = strdup("false");
671 ui_app->launchcondition = strdup("false");
672 ui_app->guestmode_visibility = strdup("true");
673 ui_app->permission_type = strdup("normal");
674 ui_app->support_ambient = strdup("false");
675 ui_app->package = strdup(manifest->package);
676 ui_app->support_disable = strdup(manifest->support_disable);
677 ui_app->splash_screen_display =
678 strdup(application.app_info.splash_screen_display().c_str());
679 ui_app->api_version = strdup(manifest->api_version);
680 manifest->application = g_list_append(manifest->application, ui_app);
681 if (bf::path(application.app_info.exec().c_str()).is_absolute())
682 ui_app->exec = strdup(application.app_info.exec().c_str());
684 ui_app->exec = strdup((context_->root_application_path.get()
685 / manifest->package / "bin"
686 / application.app_info.exec()).c_str());
689 if (!FillAppControl(ui_app, application.app_control))
691 if (!FillDataControl(ui_app, application.data_control))
693 if (!FillApplicationIconPaths(ui_app, application.app_icons))
695 if (!FillLabel(ui_app, application.label))
697 if (!FillImage(ui_app, application.app_images))
699 if (!FillMetadata(ui_app, application.meta_data))
701 if (!FillCategories(ui_app, application.categories))
703 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
705 if (!FillSplashScreen(ui_app, application.app_splashscreens))
711 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
712 auto watch_application_list =
713 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
714 parser_->GetManifestData(app_keys::kWatchApplicationKey));
715 if (!watch_application_list)
718 for (const auto& watch_application : watch_application_list->items) {
719 int package_support_mode_val = atoi(manifest->support_mode);
720 int app_support_mode_val = package_support_mode_val |
721 GetSupportModeVal(watch_application.app_info.support_mode());
723 application_x* watch_app =
724 static_cast<application_x*>(calloc(1, sizeof(application_x)));
726 LOG(ERROR) << "Out of memory";
729 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
731 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
732 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
734 watch_app->exec = strdup(
735 (context_->root_application_path.get()
736 / manifest->package / "bin" /
737 watch_application.app_info.exec()).c_str());
738 watch_app->nodisplay = strdup("true");
739 watch_app->multiple = strdup("false");
740 if (!watch_application.app_info.type().empty())
741 watch_app->type = strdup(watch_application.app_info.type().c_str());
743 watch_app->type = strdup("capp");
744 watch_app->taskmanage = strdup("false");
745 watch_app->hwacceleration = strdup("default");
746 watch_app->screenreader = strdup("use-system-setting");
747 watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
748 watch_app->recentimage = strdup("false");
749 watch_app->launchcondition = strdup("false");
750 watch_app->indicatordisplay = strdup("true");
751 watch_app->effectimage_type = strdup("image");
752 watch_app->guestmode_visibility = strdup("true");
753 watch_app->permission_type = strdup("normal");
754 watch_app->component_type = strdup("watchapp");
755 watch_app->preload = strdup("false");
756 watch_app->submode = strdup("false");
757 watch_app->process_pool = strdup("false");
758 watch_app->autorestart = strdup("false");
759 watch_app->onboot = strdup("false");
760 watch_app->support_mode =
761 strdup((std::to_string(app_support_mode_val)).c_str());
762 watch_app->ui_gadget = strdup("false");
763 watch_app->launch_mode = strdup("single");
764 watch_app->api_version = strdup(manifest->api_version);
765 watch_app->support_ambient =
766 strdup(watch_application.app_info.ambient_support().c_str());
767 watch_app->package = strdup(manifest->package);
768 if (!watch_application.app_info.setup_appid().empty())
769 watch_app->setup_appid =
770 strdup(watch_application.app_info.setup_appid().c_str());
772 if (!FillLabel(watch_app, watch_application.label))
774 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
776 if (!FillMetadata(watch_app, watch_application.meta_data))
778 if (!FillCategories(watch_app, watch_application.categories))
780 if (!FillBackgroundCategoryInfo(watch_app,
781 watch_application.background_category))
783 manifest->application = g_list_append(manifest->application, watch_app);
788 bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
789 std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
790 std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
791 parser_->GetManifestData(app_keys::kTrustAnchorKey));
792 if (!trust_anchor_info)
795 if (trust_anchor_info->get_use_system_certs().empty()) {
796 LOG(ERROR) << "Invalid trust anchor data";
800 manifest->use_system_certs =
801 strdup(trust_anchor_info->get_use_system_certs().c_str());
806 bool StepParseManifest::FillDependencyInfo(manifest_x* manifest) {
807 std::shared_ptr<const tpk::parse::DependenciesInfo> dependencies_info =
808 std::static_pointer_cast<const tpk::parse::DependenciesInfo>(
809 parser_->GetManifestData(app_keys::kDependenciesKey));
810 if (!dependencies_info)
813 for (const auto& dependency : dependencies_info->dependencies()) {
815 static_cast<dependency_x*>(calloc(1, sizeof(dependency_x)));
817 LOG(ERROR) << "Out of memory";
820 dep->depends_on = strdup(dependency.pkgid().c_str());
821 dep->type = strdup(dependency.type().c_str());
822 if (!dependency.required_version().empty())
823 dep->required_version = strdup(dependency.required_version().c_str());
824 manifest->dependencies = g_list_append(manifest->dependencies, dep);
830 bool StepParseManifest::CheckFeatures() {
832 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
833 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
838 FeatureValidator validator(feature_info->features());
839 if (!validator.Validate(&error)) {
840 LOG(ERROR) << "Feature validation error. " << error;
847 template <typename T>
848 bool StepParseManifest::FillAppControl(application_x* app,
849 const T& app_control_list) {
850 if (app_control_list.empty())
853 for (const auto& control : app_control_list) {
854 appcontrol_x* app_control =
855 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
857 LOG(ERROR) << "Out of memory";
860 app_control->operation = strdup(control.operation().c_str());
861 if (!control.mime().empty())
862 app_control->mime = strdup(control.mime().c_str());
863 if (!control.uri().empty())
864 app_control->uri = strdup(control.uri().c_str());
865 if (!control.visibility().empty())
866 app_control->visibility = strdup(control.visibility().c_str());
868 app_control->visibility = strdup("local-only");
869 if (!control.id().empty())
870 app_control->id = strdup(control.id().c_str());
872 app_control->id = strdup("no-name-app-control");
873 for (const auto& priv : control.privileges()) {
874 app_control->privileges = g_list_append(app_control->privileges,
875 strdup(priv.c_str()));
877 app->appcontrol = g_list_append(app->appcontrol, app_control);
882 template <typename T>
883 bool StepParseManifest::FillDataControl(application_x* app,
884 const T& data_control_list) {
885 if (data_control_list.empty())
888 for (const auto& control : data_control_list) {
889 datacontrol_x* data_control =
890 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
892 LOG(ERROR) << "Out of memory";
895 data_control->access = strdup(control.access().c_str());
896 data_control->providerid = strdup(control.providerid().c_str());
897 data_control->type = strdup(control.type().c_str());
898 if (!control.trusted().empty())
899 data_control->trusted = strdup(control.trusted().c_str());
901 data_control->trusted = strdup("false");
902 for (const auto& priv : control.privileges())
903 data_control->privileges = g_list_append(data_control->privileges,
904 strdup(priv.c_str()));
906 app->datacontrol = g_list_append(app->datacontrol, data_control);
911 template <typename T>
912 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
913 const T& icons_info) {
914 for (auto& application_icon : icons_info.icons()) {
915 icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
917 LOG(ERROR) << "Out of memory";
921 if (bf::path(application_icon.path()).is_absolute()) {
922 text = application_icon.path();
924 text = context_->root_application_path.get()
925 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
927 // NOTE: name is an attribute, but the xml writer uses it as text.
928 // This must be fixed in whole app-installer modules, including wgt.
929 // Current implementation is just for compatibility.
930 icon->text = strdup(text.c_str());
931 if (application_icon.lang().empty())
932 icon->lang = strdup(DEFAULT_LOCALE);
934 icon->lang = strdup(application_icon.lang().c_str());
936 if (!application_icon.dpi().empty())
937 icon->dpi = strdup(application_icon.dpi().c_str());
938 app->icon = g_list_append(app->icon, icon);
943 template <typename T>
944 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
945 if (label_list.empty())
948 for (const auto& control : label_list) {
950 static_cast<label_x*>(calloc(1, sizeof(label_x)));
952 LOG(ERROR) << "Out of memory";
955 // NOTE: name is an attribute, but the xml writer uses it as text.
956 // This must be fixed in whole app-installer modules, including wgt.
957 // Current implementation is just for compatibility.
958 label->text = strdup(control.text().c_str());
959 label->name = strdup(control.name().c_str());
960 label->lang = !control.xml_lang().empty() ?
961 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
962 app->label = g_list_append(app->label, label);
967 template <typename T>
968 bool StepParseManifest::FillMetadata(application_x* app,
969 const T& meta_data_list) {
970 if (meta_data_list.empty())
973 for (auto& meta : meta_data_list) {
974 metadata_x* metadata =
975 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
977 LOG(ERROR) << "Out of memory";
980 metadata->key = strdup(meta.key().c_str());
981 metadata->value = strdup(meta.val().c_str());
982 app->metadata = g_list_append(app->metadata, metadata);
984 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
989 template <typename T>
990 bool StepParseManifest::FillCategories(application_x* manifest,
991 const T& categories) {
992 for (auto& category : categories) {
993 manifest->category = g_list_append(manifest->category,
994 strdup(category.c_str()));
999 void StepParseManifest::AppendSplashScreen(application_x* app,
1000 const std::string& src, const std::string& type, const std::string& dpi,
1001 const std::string& orientation, const std::string& indicatordisplay,
1002 const std::string& operation, const std::string& color_depth) {
1003 splashscreen_x* splashscreen =
1004 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
1005 if (!splashscreen) {
1006 LOG(ERROR) << "Out of memory";
1009 if (bf::path(src).is_absolute()) {
1010 splashscreen->src = strdup(src.c_str());
1012 bf::path full_path = context_->GetPkgPath() / src;
1013 splashscreen->src = strdup(full_path.string().c_str());
1015 if (src.substr(src.find_last_of(".") + 1) == "edj")
1016 splashscreen->type = strdup("edj");
1017 else if (type == "edj")
1018 splashscreen->type = strdup("edj");
1020 splashscreen->type = strdup("img");
1022 splashscreen->dpi = strdup(dpi.c_str());
1023 splashscreen->orientation = strdup(orientation.c_str());
1024 if (!indicatordisplay.empty())
1025 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
1027 splashscreen->indicatordisplay = strdup("true");
1028 if (operation == "launch_effect")
1029 splashscreen->operation = strdup("launch-effect");
1030 else if (!operation.empty())
1031 splashscreen->operation = strdup(operation.c_str());
1033 splashscreen->operation = strdup("launch-effect");
1034 if (!color_depth.empty())
1035 splashscreen->color_depth = strdup(color_depth.c_str());
1037 splashscreen->color_depth = strdup("24");
1038 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
1041 template <typename T>
1042 bool StepParseManifest::FillSplashScreen(application_x* app,
1043 const T& splashscreens_info) {
1044 for (auto& splash_screen : splashscreens_info.splashscreens()) {
1046 if (context_->is_readonly_package.get())
1047 src = splash_screen.src();
1049 src = bf::path(context_->root_application_path.get()
1050 / app->package / "shared" / "res" / splash_screen.src()).string();
1052 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
1053 splash_screen.orientation(), splash_screen.indicatordisplay(),
1054 splash_screen.operation(), splash_screen.colordepth());
1059 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
1060 const std::string& key, const std::string& val) {
1061 std::string operation;
1062 if (key.find(kOperationEffectKey) != std::string::npos) {
1063 boost::char_separator<char> sep("=");
1064 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
1065 auto iter = tokens.begin();
1068 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
1069 operation = std::string("launch-effect");
1071 // not a metadata splashscreen
1075 boost::char_separator<char> sep("=|");
1076 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
1077 auto iter = tokens.begin();
1078 std::string portrait_src;
1079 std::string landscape_src;
1080 std::string indicatordisplay;
1081 while (iter != tokens.end()) {
1082 if (!(*iter).compare(kPortraitEffectImageValue)) {
1084 portrait_src = *iter;
1085 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
1087 landscape_src = *iter;
1088 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
1090 indicatordisplay = *iter;
1094 if (!portrait_src.empty())
1095 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
1096 indicatordisplay, operation, {});
1097 if (!landscape_src.empty())
1098 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
1099 indicatordisplay, operation, {});
1102 bool StepParseManifest::FillImage(application_x* app,
1103 const tpk::parse::ApplicationImagesInfo& image_list) {
1104 for (auto& app_image : image_list.images) {
1106 static_cast<image_x*>(calloc(1, sizeof(image_x)));
1108 LOG(ERROR) << "Out of memory";
1111 const std::string& lang = app_image.lang();
1113 image->lang = strdup(lang.c_str());
1115 image->lang = strdup(DEFAULT_LOCALE);
1116 if (!app_image.section().empty())
1117 image->section = strdup(app_image.section().c_str());
1118 app->image = g_list_append(app->image, image);
1123 template <typename T>
1124 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
1125 const T& background_category_data_list) {
1126 for (const auto& background_category : background_category_data_list) {
1127 app->background_category = g_list_append(
1128 app->background_category, strdup(background_category.value().c_str()));
1134 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
1135 if (manifest_location_ == ManifestLocation::INSTALLED) {
1136 // recovery of tep value for installed package
1137 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
1138 std::string old_tep = pkg_query.TepPath();
1139 if (!old_tep.empty())
1140 manifest->tep_name = strdup(old_tep.c_str());
1142 // recovery of zip mount file for installed package
1143 std::string zip_mount_file = pkg_query.ZipMountFile();
1144 if (!zip_mount_file.empty())
1145 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1148 // in case of hybrid package, main app is already set by wgt-backend
1149 application_x* mainapp = nullptr;
1150 if (!context_->cross_app_rules.get()) {
1152 for (const auto& app : GListRange<application_x*>(manifest->application)) {
1153 if (!strcmp(app->mainapp, "true")) {
1158 if (mainapp == nullptr)
1159 mainapp = reinterpret_cast<application_x*>(
1160 g_list_first(manifest->application)->data);
1161 free(mainapp->mainapp);
1162 mainapp->mainapp = strdup("true");
1163 manifest->mainapp_id = strdup(mainapp->appid);
1166 // mark mainapp=false at other apps
1167 for (auto& app : GListRange<application_x*>(manifest->application)) {
1171 app->mainapp = strdup("false");
1176 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
1177 if (!FillPackageInfo(manifest))
1179 if (!FillInstallationInfo(manifest))
1181 if (!FillUIApplication(manifest))
1183 if (!FillServiceApplication(manifest))
1185 if (!FillWidgetApplication(manifest))
1187 if (!FillWatchApplication(manifest))
1189 if (!FillPrivileges(manifest))
1191 if (!FillProvidesAppDefinedPrivileges(manifest))
1193 if (!FillAuthorInfo(manifest))
1195 if (!FillDescriptionInfo(manifest))
1197 if (!FillExtraInfo(manifest))
1199 if (!FillTrustAnchorInfo(manifest))
1201 if (!FillDependencyInfo(manifest))
1206 Step::Status StepParseManifest::process() {
1207 if (context_->force_clean_from_db.get())
1208 return Step::Status::OK;
1209 if (!LocateConfigFile()) {
1210 // continue if this is recovery, manifest file may never been created
1211 if (manifest_location_ == ManifestLocation::RECOVERY) {
1212 LOG(DEBUG) << "Manifest for recovery not found";
1213 return Step::Status::OK;
1215 LOG(ERROR) << "No manifest file exists";
1216 return Step::Status::MANIFEST_NOT_FOUND;
1218 parser_.reset(new tpk::parse::TPKConfigParser());
1219 if (!parser_->ParseManifest(path_)) {
1220 if (manifest_location_ == ManifestLocation::RECOVERY) {
1221 LOG(DEBUG) << "Manifest for recovery is invalid";
1223 return Step::Status::OK;
1225 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
1226 return Step::Status::PARSE_ERROR;
1229 // Copy data from ManifestData to InstallerContext
1230 std::shared_ptr<const tpk::parse::PackageInfo> info =
1231 std::static_pointer_cast<const tpk::parse::PackageInfo>(
1232 parser_->GetManifestData(app_keys::kManifestKey));
1234 context_->pkgid.set(info->package());
1236 manifest_x* manifest =
1237 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1239 LOG(ERROR) << "Out of memory";
1240 return Step::Status::ERROR;
1243 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1244 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1245 << parser_->GetErrorMessage();
1246 pkgmgr_parser_free_manifest_xml(manifest);
1247 return Step::Status::PARSE_ERROR;
1250 // write pkgid for recovery file
1251 if (context_->recovery_info.get().recovery_file) {
1252 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1253 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1256 LOG(DEBUG) << "Parsed package id: " << info->package();
1258 switch (store_location_) {
1259 case StoreLocation::NORMAL:
1260 context_->manifest_data.set(manifest);
1262 case StoreLocation::BACKUP:
1263 context_->old_manifest_data.set(manifest);
1266 LOG(ERROR) << "Unknown store location for parsed data";
1267 return Step::Status::ERROR;
1269 return Step::Status::OK;
1272 } // namespace configuration
1273 } // namespace common_installer