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 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
109 context_->GetPkgPath()) / kManifestFileName;
110 bf::path in_package_path = context_->GetPkgPath() / kManifestFileName;
111 bf::path install_path =
112 bf::path(getUserManifestPath(context_->uid.get(),
113 context_->is_readonly_package.get()))
114 / bf::path(context_->pkgid.get());
115 install_path += ".xml";
116 if (bf::exists(backup_path))
117 manifest = backup_path;
118 else if (bf::exists(in_package_path))
119 manifest = in_package_path;
120 else if (bf::exists(install_path))
121 manifest = install_path;
124 case ManifestLocation::INSTALLED: {
126 bool is_readonly = context_->is_readonly_package.get();
127 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
128 if (pkg_query.IsGlobalPackage())
129 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
131 uid = context_->uid.get();
133 bf::path(getUserManifestPath(uid, is_readonly))
134 / bf::path(context_->pkgid.get());
136 context_->xml_path.set(xml_path);
137 manifest = context_->xml_path.get();
138 if (!boost::filesystem::exists(manifest)) {
139 /* This routine has added for platform update */
140 manifest = context_->unpacked_dir_path.get();
141 manifest /= kManifestFileName;
145 case ManifestLocation::PACKAGE: {
146 manifest = context_->unpacked_dir_path.get();
147 manifest /= kManifestFileName;
151 LOG(ERROR) << "Unknown manifest location value";
156 LOG(DEBUG) << "manifest path: " << manifest;
158 if (!boost::filesystem::exists(manifest))
165 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
167 std::size_t found = std::string::npos;
169 found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
170 if (found != std::string::npos)
171 mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
173 found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
174 if (found != std::string::npos)
175 mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
177 found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
178 if (found != std::string::npos)
179 mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
184 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
185 manifest->root_path = strdup(
186 (context_->root_application_path.get() / manifest->package).c_str());
187 manifest->installed_time =
188 strdup(std::to_string(std::chrono::system_clock::to_time_t(
189 std::chrono::system_clock::now())).c_str());
193 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
194 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
195 std::static_pointer_cast<const tpk::parse::PackageInfo>(
196 parser_->GetManifestData(app_keys::kManifestKey));
198 LOG(ERROR) << "Package info manifest data has not been found.";
202 auto ui_application_list =
203 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
204 parser_->GetManifestData(app_keys::kUIApplicationKey));
205 auto service_application_list =
206 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
207 parser_->GetManifestData(app_keys::kServiceApplicationKey));
208 auto widget_application_list =
209 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
210 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
211 auto watch_application_list =
212 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
213 parser_->GetManifestData(app_keys::kWatchApplicationKey));
216 if (!ui_application_list && !service_application_list &&
217 !widget_application_list && !watch_application_list) {
218 LOG(ERROR) << "UI Application or Service Application or Widget Application "
219 "or Watch Application are mandatory and has not been found.";
223 int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
225 manifest->ns = strdup(pkg_info->xmlns().c_str());
226 manifest->package = strdup(pkg_info->package().c_str());
227 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
228 manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
229 manifest->appsetting = strdup("false");
230 manifest->support_disable = strdup(pkg_info->support_disable().c_str());
231 manifest->version = strdup(pkg_info->version().c_str());
232 manifest->installlocation = strdup(pkg_info->install_location().c_str());
233 manifest->api_version = strdup(pkg_info->api_version().c_str());
234 manifest->readonly = strdup(pkg_info->readonly().c_str());
235 manifest->preload = strdup(pkg_info->preload().c_str());
236 manifest->removable = strdup(pkg_info->removable().c_str());
238 common_installer::RequestType req_type = context_->request_type.get();
239 if (pkg_info->type().empty()) {
240 if ((req_type == RequestType::ManifestDirectInstall ||
241 req_type == RequestType::ManifestDirectUpdate) &&
242 context_->is_readonly_package.get())
243 manifest->type = strdup("rpm");
245 manifest->type = strdup("tpk");
247 manifest->type = strdup(pkg_info->type().c_str());
250 // Set external path if the package is installed at external storage.
251 if (req_type == RequestType::ManifestDirectInstall ||
252 req_type == RequestType::ManifestDirectUpdate ||
253 req_type == RequestType::ManifestPartialInstall ||
254 req_type == RequestType::ManifestPartialUpdate) {
255 App2ExtDynamicService service;
256 std::string image_path = service.GetExternalImagePath(
257 context_->pkgid.get().c_str(), context_->uid.get());
258 if (!image_path.empty()) {
259 manifest->external_path = strdup(image_path.c_str());
260 manifest->installed_storage = strdup(kInstalledExternally);
264 for (auto& pair : pkg_info->labels()) {
265 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
267 LOG(ERROR) << "Out of memory";
270 if (!pair.first.empty())
271 label->lang = strdup(pair.first.c_str());
273 label->lang = strdup(DEFAULT_LOCALE);
274 label->text = strdup(pair.second.c_str());
275 manifest->label = g_list_append(manifest->label, label);
278 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
279 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
280 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
282 for (auto& profile : profile_info->profiles()) {
283 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
284 strdup(profile.c_str()));
288 // set installed_storage if package is installed
289 // this is internal field in package manager but after reading configuration
291 if (!manifest->installed_storage) {
292 if (manifest_location_ == ManifestLocation::INSTALLED ||
293 manifest_location_ == ManifestLocation::RECOVERY) {
294 PkgQueryInterface pkg_query(manifest->package, context_->uid.get());
295 std::string storage = pkg_query.StorageForPkgId();
296 if (storage.empty()) {
297 // Failed to query installation storage, assign internal
298 manifest->installed_storage = strdup(kInstalledInternally);
300 manifest->installed_storage = strdup(storage.c_str());
303 manifest->installed_storage = strdup(kInstalledInternally);
310 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
311 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
312 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
313 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
318 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
320 LOG(ERROR) << "Out of memory";
323 author->text = strdup(author_info->name().c_str());
324 author->email = strdup(author_info->email().c_str());
325 author->href = strdup(author_info->href().c_str());
326 author->lang = strdup(DEFAULT_LOCALE);
327 manifest->author = g_list_append(manifest->author, author);
331 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
332 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
333 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
334 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
336 if (!description_info)
339 for (auto& desc : description_info->descriptions) {
340 description_x* description = reinterpret_cast<description_x*>
341 (calloc(1, sizeof(description_x)));
343 LOG(ERROR) << "Out of memory";
346 description->text = strdup(desc.description().c_str());
347 description->lang = !desc.xml_lang().empty() ?
348 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
349 manifest->description = g_list_append(manifest->description, description);
354 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
355 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
356 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
357 parser_->GetManifestData(app_keys::kPrivilegesKey));
361 const auto& privileges = perm_info->GetPrivileges();
362 for (auto& priv : privileges) {
363 privilege_x* privilege =
364 reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
366 LOG(ERROR) << "Out of memory";
369 privilege->value = strdup(priv.first.c_str());
370 privilege->type = strdup(priv.second.c_str());
371 manifest->privileges = g_list_append(manifest->privileges, privilege);
374 const auto& appdef_privileges_list =
375 perm_info->GetAppDefinedPrivilegeInfoList();
376 for (auto& appdef_info : appdef_privileges_list) {
377 appdefined_privilege_x* privilege =
378 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
379 sizeof(appdefined_privilege_x)));
380 if (privilege == nullptr) {
381 LOG(ERROR) << "Memory alloc failure";
384 auto& priv = appdef_info.GetAppDefinedPrivilege();
385 privilege->value = strdup(priv.privilege.c_str());
386 privilege->type = strdup(priv.type.c_str());
387 if (!priv.license.empty()) {
388 if (bf::path(priv.license).is_absolute())
389 privilege->license = strdup(priv.license.c_str());
391 privilege->license = strdup((context_->GetPkgPath()
392 / priv.license).c_str());
394 manifest->appdefined_privileges =
395 g_list_append(manifest->appdefined_privileges, privilege);
401 bool StepParseManifest::FillProvidesAppDefinedPrivileges(
402 manifest_x* manifest) {
403 std::shared_ptr<const tpk::parse::ProvidesAppDefinedPrivilegesInfo>
404 priv_info = std::static_pointer_cast<
405 const tpk::parse::ProvidesAppDefinedPrivilegesInfo>(
406 parser_->GetManifestData(
407 app_keys::kProvidesAppDefinedPrivilegesKey));
411 const auto& privileges_list = priv_info->GetAppDefinedPrivilegeInfoList();
412 for (auto& appdef_info : privileges_list) {
413 appdefined_privilege_x* privilege =
414 reinterpret_cast<appdefined_privilege_x*>(calloc(1,
415 sizeof(appdefined_privilege_x)));
416 if (privilege == nullptr) {
417 LOG(ERROR) << "Memory alloc failure";
420 auto& priv = appdef_info.GetAppDefinedPrivilege();
421 privilege->value = strdup(priv.privilege.c_str());
422 privilege->type = strdup(priv.type.c_str());
423 if (!priv.license.empty()) {
424 if (bf::path(priv.license).is_absolute())
425 privilege->license = strdup(priv.license.c_str());
427 privilege->license = strdup((context_->GetPkgPath()
428 / priv.license).c_str());
430 manifest->provides_appdefined_privileges =
431 g_list_append(manifest->provides_appdefined_privileges, privilege);
437 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
438 auto widget_application_list =
439 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
440 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
441 if (!widget_application_list)
444 for (const auto& application : widget_application_list->items) {
445 int package_support_mode_val = atoi(manifest->support_mode);
446 int app_support_mode_val = package_support_mode_val |
447 GetSupportModeVal(application.app_info.support_mode());
449 application_x* widget_app =
450 static_cast<application_x*>(calloc(1, sizeof(application_x)));
452 LOG(ERROR) << "Out of memory";
455 widget_app->appid = strdup(application.app_info.appid().c_str());
456 widget_app->launch_mode =
457 strdup(application.app_info.launch_mode().c_str());
458 widget_app->multiple = strdup("false");
459 widget_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
460 widget_app->support_mode =
461 strdup((std::to_string(app_support_mode_val)).c_str());
462 widget_app->taskmanage = strdup("false");
463 widget_app->indicatordisplay = strdup("false");
465 strdup(application.app_info.type().c_str());
466 widget_app->component_type = strdup("widgetapp");
467 widget_app->hwacceleration =
468 strdup(application.app_info.hwacceleration().c_str());
469 widget_app->onboot = strdup("false");
470 widget_app->autorestart = strdup("false");
471 widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
472 widget_app->screenreader = strdup("use-system-setting");
473 widget_app->recentimage = strdup("false");
474 widget_app->launchcondition = strdup("false");
475 widget_app->guestmode_visibility = strdup("true");
476 widget_app->permission_type = strdup("normal");
477 widget_app->support_ambient = strdup("false");
478 widget_app->effectimage_type = strdup("image");
479 widget_app->submode = strdup("false");
480 widget_app->process_pool = strdup("false");
481 widget_app->package = strdup(manifest->package);
482 widget_app->support_disable = strdup(manifest->support_disable);
483 widget_app->launch_mode = strdup("single");
484 widget_app->api_version = strdup(manifest->api_version);
485 manifest->application = g_list_append(manifest->application, widget_app);
486 if (bf::path(application.app_info.exec().c_str()).is_absolute())
487 widget_app->exec = strdup(application.app_info.exec().c_str());
489 widget_app->exec = strdup((context_->root_application_path.get()
490 / manifest->package / "bin"
491 / application.app_info.exec()).c_str());
493 if (!FillApplicationIconPaths(widget_app, application.app_icons))
495 if (!FillLabel(widget_app, application.label))
497 if (!FillImage(widget_app, application.app_images))
499 if (!FillCategories(widget_app, application.categories))
501 if (!FillMetadata(widget_app, application.meta_data))
507 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
508 auto service_application_list =
509 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
510 parser_->GetManifestData(app_keys::kServiceApplicationKey));
511 if (!service_application_list)
514 for (const auto& application : service_application_list->items) {
515 int package_support_mode_val = atoi(manifest->support_mode);
516 int app_support_mode_val = package_support_mode_val |
517 GetSupportModeVal(application.app_info.support_mode());
519 application_x* service_app =
520 static_cast<application_x*>(calloc(1, sizeof(application_x)));
522 LOG(ERROR) << "Out of memory";
525 service_app->appid = strdup(application.app_info.appid().c_str());
526 service_app->multiple = strdup(application.app_info.multiple().c_str());
527 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
528 service_app->support_mode =
529 strdup((std::to_string(app_support_mode_val)).c_str());
530 service_app->autorestart =
531 strdup(application.app_info.auto_restart().c_str());
532 service_app->onboot = strdup(application.app_info.on_boot().c_str());
533 service_app->type = strdup(application.app_info.type().c_str());
534 service_app->process_pool =
535 strdup(application.app_info.process_pool().c_str());
536 service_app->component_type = strdup("svcapp");
537 service_app->mainapp = strdup(application.app_info.mainapp().c_str());
538 service_app->nodisplay = strdup("true");
539 service_app->hwacceleration = strdup("default");
540 service_app->screenreader = strdup("use-system-setting");
541 service_app->recentimage = strdup("false");
542 service_app->launchcondition = strdup("false");
543 service_app->indicatordisplay = strdup("true");
544 service_app->effectimage_type = strdup("image");
545 service_app->guestmode_visibility = strdup("true");
546 service_app->permission_type = strdup("normal");
547 service_app->submode = strdup("false");
548 service_app->process_pool = strdup("false");
549 service_app->support_ambient = strdup("false");
550 service_app->package = strdup(manifest->package);
551 service_app->support_disable = strdup(manifest->support_disable);
552 service_app->launch_mode = strdup("single");
553 service_app->api_version = strdup(manifest->api_version);
554 manifest->application = g_list_append(manifest->application, service_app);
555 if (bf::path(application.app_info.exec().c_str()).is_absolute())
556 service_app->exec = strdup(application.app_info.exec().c_str());
558 service_app->exec = strdup((context_->root_application_path.get()
559 / manifest->package / "bin"
560 / application.app_info.exec()).c_str());
562 if (!FillAppControl(service_app, application.app_control))
564 if (!FillDataControl(service_app, application.data_control))
566 if (!FillApplicationIconPaths(service_app, application.app_icons))
568 if (!FillLabel(service_app, application.label))
570 if (!FillMetadata(service_app, application.meta_data))
572 if (!FillCategories(service_app, application.categories))
574 if (!FillBackgroundCategoryInfo(service_app,
575 application.background_category))
581 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
582 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
583 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
584 parser_->GetManifestData(app_keys::kUIApplicationKey));
585 if (!ui_application_list)
588 for (const auto& application : ui_application_list->items) {
589 int package_support_mode_val = atoi(manifest->support_mode);
590 int app_support_mode_val = package_support_mode_val |
591 GetSupportModeVal(application.app_info.support_mode());
593 application_x* ui_app =
594 static_cast<application_x*>(calloc(1, sizeof(application_x)));
596 LOG(ERROR) << "Out of memory";
599 ui_app->appid = strdup(application.app_info.appid().c_str());
600 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
601 ui_app->multiple = strdup(application.app_info.multiple().c_str());
602 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
603 ui_app->support_mode =
604 strdup((std::to_string(app_support_mode_val)).c_str());
605 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
606 ui_app->type = strdup(application.app_info.type().c_str());
607 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
608 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
609 ui_app->submode = strdup(application.app_info.submode().c_str());
610 if (!application.app_info.indicator_display().empty())
611 ui_app->indicatordisplay =
612 strdup(application.app_info.indicator_display().c_str());
613 if (!application.app_info.effectimage_type().empty())
614 ui_app->effectimage_type =
615 strdup(application.app_info.effectimage_type().c_str());
616 if (!application.app_info.portrait_image().empty()) {
617 ui_app->portraitimg =
618 strdup(application.app_info.portrait_image().c_str());
619 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
620 application.app_info.effectimage_type(), {}, kPortraitOrientation,
621 application.app_info.indicator_display(), {}, {});
623 if (!application.app_info.landscape_image().empty()) {
624 ui_app->landscapeimg =
625 strdup(application.app_info.landscape_image().c_str());
626 AppendSplashScreen(ui_app, application.app_info.landscape_image(),
627 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
628 application.app_info.indicator_display(), {}, {});
630 ui_app->submode_mainid =
631 strdup(application.app_info.submode_mainid().c_str());
632 ui_app->hwacceleration =
633 strdup(application.app_info.hwacceleration().c_str());
634 ui_app->onboot = strdup("false");
635 ui_app->autorestart = strdup("false");
636 ui_app->component_type = strdup("uiapp");
637 ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
638 ui_app->screenreader = strdup("use-system-setting");
639 ui_app->recentimage = strdup("false");
640 ui_app->launchcondition = strdup("false");
641 ui_app->guestmode_visibility = strdup("true");
642 ui_app->permission_type = strdup("normal");
643 ui_app->support_ambient = strdup("false");
644 ui_app->package = strdup(manifest->package);
645 ui_app->support_disable = strdup(manifest->support_disable);
646 ui_app->splash_screen_display =
647 strdup(application.app_info.splash_screen_display().c_str());
648 ui_app->api_version = strdup(manifest->api_version);
649 manifest->application = g_list_append(manifest->application, ui_app);
650 if (bf::path(application.app_info.exec().c_str()).is_absolute())
651 ui_app->exec = strdup(application.app_info.exec().c_str());
653 ui_app->exec = strdup((context_->root_application_path.get()
654 / manifest->package / "bin"
655 / application.app_info.exec()).c_str());
658 if (!FillAppControl(ui_app, application.app_control))
660 if (!FillDataControl(ui_app, application.data_control))
662 if (!FillApplicationIconPaths(ui_app, application.app_icons))
664 if (!FillLabel(ui_app, application.label))
666 if (!FillImage(ui_app, application.app_images))
668 if (!FillMetadata(ui_app, application.meta_data))
670 if (!FillCategories(ui_app, application.categories))
672 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
674 if (!FillSplashScreen(ui_app, application.app_splashscreens))
680 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
681 auto watch_application_list =
682 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
683 parser_->GetManifestData(app_keys::kWatchApplicationKey));
684 if (!watch_application_list)
687 for (const auto& watch_application : watch_application_list->items) {
688 int package_support_mode_val = atoi(manifest->support_mode);
689 int app_support_mode_val = package_support_mode_val |
690 GetSupportModeVal(watch_application.app_info.support_mode());
692 application_x* watch_app =
693 static_cast<application_x*>(calloc(1, sizeof(application_x)));
695 LOG(ERROR) << "Out of memory";
698 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
700 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
701 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
703 watch_app->exec = strdup(
704 (context_->root_application_path.get()
705 / manifest->package / "bin" /
706 watch_application.app_info.exec()).c_str());
707 watch_app->nodisplay = strdup("true");
708 watch_app->multiple = strdup("false");
709 watch_app->type = strdup(watch_application.app_info.type().c_str());
710 watch_app->taskmanage = strdup("false");
711 watch_app->hwacceleration = strdup("default");
712 watch_app->screenreader = strdup("use-system-setting");
713 watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
714 watch_app->recentimage = strdup("false");
715 watch_app->launchcondition = strdup("false");
716 watch_app->indicatordisplay = strdup("true");
717 watch_app->effectimage_type = strdup("image");
718 watch_app->guestmode_visibility = strdup("true");
719 watch_app->permission_type = strdup("normal");
720 watch_app->component_type = strdup("watchapp");
721 watch_app->preload = strdup("false");
722 watch_app->submode = strdup("false");
723 watch_app->process_pool = strdup("false");
724 watch_app->autorestart = strdup("false");
725 watch_app->onboot = strdup("false");
726 watch_app->support_mode =
727 strdup((std::to_string(app_support_mode_val)).c_str());
728 watch_app->ui_gadget = strdup("false");
729 watch_app->launch_mode = strdup("single");
730 watch_app->api_version = strdup(manifest->api_version);
731 watch_app->support_ambient =
732 strdup(watch_application.app_info.ambient_support().c_str());
733 watch_app->package = strdup(manifest->package);
734 if (!watch_application.app_info.setup_appid().empty())
735 watch_app->setup_appid =
736 strdup(watch_application.app_info.setup_appid().c_str());
738 if (!FillLabel(watch_app, watch_application.label))
740 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
742 if (!FillMetadata(watch_app, watch_application.meta_data))
744 if (!FillCategories(watch_app, watch_application.categories))
746 if (!FillBackgroundCategoryInfo(watch_app,
747 watch_application.background_category))
749 manifest->application = g_list_append(manifest->application, watch_app);
754 bool StepParseManifest::FillTrustAnchorInfo(manifest_x* manifest) {
755 std::shared_ptr<const tpk::parse::TrustAnchorInfo> trust_anchor_info =
756 std::static_pointer_cast<const tpk::parse::TrustAnchorInfo>(
757 parser_->GetManifestData(app_keys::kTrustAnchorKey));
758 if (!trust_anchor_info)
761 if (trust_anchor_info->get_use_system_certs().empty()) {
762 LOG(ERROR) << "Invalid trust anchor data";
766 manifest->use_system_certs =
767 strdup(trust_anchor_info->get_use_system_certs().c_str());
772 bool StepParseManifest::CheckFeatures() {
774 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
775 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
780 FeatureValidator validator(feature_info->features());
781 if (!validator.Validate(&error)) {
782 LOG(ERROR) << "Feature validation error. " << error;
789 template <typename T>
790 bool StepParseManifest::FillAppControl(application_x* app,
791 const T& app_control_list) {
792 if (app_control_list.empty())
795 for (const auto& control : app_control_list) {
796 appcontrol_x* app_control =
797 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
799 LOG(ERROR) << "Out of memory";
802 app_control->operation = strdup(control.operation().c_str());
803 if (!control.mime().empty())
804 app_control->mime = strdup(control.mime().c_str());
805 if (!control.uri().empty())
806 app_control->uri = strdup(control.uri().c_str());
807 for (const auto& priv : control.privileges()) {
808 app_control->privileges = g_list_append(app_control->privileges,
809 strdup(priv.c_str()));
811 app->appcontrol = g_list_append(app->appcontrol, app_control);
816 template <typename T>
817 bool StepParseManifest::FillDataControl(application_x* app,
818 const T& data_control_list) {
819 if (data_control_list.empty())
822 for (const auto& control : data_control_list) {
823 datacontrol_x* data_control =
824 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
826 LOG(ERROR) << "Out of memory";
829 data_control->access = strdup(control.access().c_str());
830 data_control->providerid = strdup(control.providerid().c_str());
831 data_control->type = strdup(control.type().c_str());
832 if (!control.trusted().empty())
833 data_control->trusted = strdup(control.trusted().c_str());
835 data_control->trusted = strdup("false");
836 for (const auto& priv : control.privileges())
837 data_control->privileges = g_list_append(data_control->privileges,
838 strdup(priv.c_str()));
840 app->datacontrol = g_list_append(app->datacontrol, data_control);
845 template <typename T>
846 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
847 const T& icons_info) {
848 for (auto& application_icon : icons_info.icons()) {
849 icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
851 LOG(ERROR) << "Out of memory";
855 if (bf::path(application_icon.path()).is_absolute()) {
856 text = application_icon.path();
858 text = context_->root_application_path.get()
859 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
861 // NOTE: name is an attribute, but the xml writer uses it as text.
862 // This must be fixed in whole app-installer modules, including wgt.
863 // Current implementation is just for compatibility.
864 icon->text = strdup(text.c_str());
865 if (application_icon.lang().empty())
866 icon->lang = strdup(DEFAULT_LOCALE);
868 icon->lang = strdup(application_icon.lang().c_str());
870 if (!application_icon.dpi().empty())
871 icon->dpi = strdup(application_icon.dpi().c_str());
872 app->icon = g_list_append(app->icon, icon);
877 template <typename T>
878 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
879 if (label_list.empty())
882 for (const auto& control : label_list) {
884 static_cast<label_x*>(calloc(1, sizeof(label_x)));
886 LOG(ERROR) << "Out of memory";
889 // NOTE: name is an attribute, but the xml writer uses it as text.
890 // This must be fixed in whole app-installer modules, including wgt.
891 // Current implementation is just for compatibility.
892 label->text = strdup(control.text().c_str());
893 label->name = strdup(control.name().c_str());
894 label->lang = !control.xml_lang().empty() ?
895 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
896 app->label = g_list_append(app->label, label);
901 template <typename T>
902 bool StepParseManifest::FillMetadata(application_x* app,
903 const T& meta_data_list) {
904 if (meta_data_list.empty())
907 for (auto& meta : meta_data_list) {
908 metadata_x* metadata =
909 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
911 LOG(ERROR) << "Out of memory";
914 metadata->key = strdup(meta.key().c_str());
915 metadata->value = strdup(meta.val().c_str());
916 app->metadata = g_list_append(app->metadata, metadata);
918 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
923 template <typename T>
924 bool StepParseManifest::FillCategories(application_x* manifest,
925 const T& categories) {
926 for (auto& category : categories) {
927 manifest->category = g_list_append(manifest->category,
928 strdup(category.c_str()));
933 void StepParseManifest::AppendSplashScreen(application_x* app,
934 const std::string& src, const std::string& type, const std::string& dpi,
935 const std::string& orientation, const std::string& indicatordisplay,
936 const std::string& operation, const std::string& color_depth) {
937 splashscreen_x* splashscreen =
938 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
940 LOG(ERROR) << "Out of memory";
943 if (bf::path(src).is_absolute()) {
944 splashscreen->src = strdup(src.c_str());
946 bf::path full_path = context_->GetPkgPath() / src;
947 splashscreen->src = strdup(full_path.string().c_str());
949 if (src.substr(src.find_last_of(".") + 1) == "edj")
950 splashscreen->type = strdup("edj");
951 else if (type == "edj")
952 splashscreen->type = strdup("edj");
954 splashscreen->type = strdup("img");
956 splashscreen->dpi = strdup(dpi.c_str());
957 splashscreen->orientation = strdup(orientation.c_str());
958 if (!indicatordisplay.empty())
959 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
961 splashscreen->indicatordisplay = strdup("true");
962 if (operation == "launch_effect")
963 splashscreen->operation = strdup("launch-effect");
964 else if (!operation.empty())
965 splashscreen->operation = strdup(operation.c_str());
967 splashscreen->operation = strdup("launch-effect");
968 if (!color_depth.empty())
969 splashscreen->color_depth = strdup(color_depth.c_str());
971 splashscreen->color_depth = strdup("24");
972 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
975 template <typename T>
976 bool StepParseManifest::FillSplashScreen(application_x* app,
977 const T& splashscreens_info) {
978 for (auto& splash_screen : splashscreens_info.splashscreens()) {
980 if (context_->is_readonly_package.get())
981 src = splash_screen.src();
983 src = bf::path(context_->root_application_path.get()
984 / app->package / "shared" / "res" / splash_screen.src()).string();
986 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
987 splash_screen.orientation(), splash_screen.indicatordisplay(),
988 splash_screen.operation(), splash_screen.colordepth());
993 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
994 const std::string& key, const std::string& val) {
995 std::string operation;
996 if (key.find(kOperationEffectKey) != std::string::npos) {
997 boost::char_separator<char> sep("=");
998 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
999 auto iter = tokens.begin();
1002 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
1003 operation = std::string("launch-effect");
1005 // not a metadata splashscreen
1009 boost::char_separator<char> sep("=|");
1010 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
1011 auto iter = tokens.begin();
1012 std::string portrait_src;
1013 std::string landscape_src;
1014 std::string indicatordisplay;
1015 while (iter != tokens.end()) {
1016 if (!(*iter).compare(kPortraitEffectImageValue)) {
1018 portrait_src = *iter;
1019 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
1021 landscape_src = *iter;
1022 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
1024 indicatordisplay = *iter;
1028 if (!portrait_src.empty())
1029 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
1030 indicatordisplay, operation, {});
1031 if (!landscape_src.empty())
1032 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
1033 indicatordisplay, operation, {});
1036 bool StepParseManifest::FillImage(application_x* app,
1037 const tpk::parse::ApplicationImagesInfo& image_list) {
1038 for (auto& app_image : image_list.images) {
1040 static_cast<image_x*>(calloc(1, sizeof(image_x)));
1042 LOG(ERROR) << "Out of memory";
1045 const std::string& lang = app_image.lang();
1047 image->lang = strdup(lang.c_str());
1049 image->lang = strdup(DEFAULT_LOCALE);
1050 if (!app_image.section().empty())
1051 image->section = strdup(app_image.section().c_str());
1052 app->image = g_list_append(app->image, image);
1057 template <typename T>
1058 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
1059 const T& background_category_data_list) {
1060 for (const auto& background_category : background_category_data_list) {
1061 app->background_category = g_list_append(
1062 app->background_category, strdup(background_category.value().c_str()));
1068 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
1069 if (manifest_location_ == ManifestLocation::INSTALLED) {
1070 // recovery of tep value for installed package
1071 PkgQueryInterface pkg_query(context_->pkgid.get(), context_->uid.get());
1072 std::string old_tep = pkg_query.TepPath();
1073 if (!old_tep.empty())
1074 manifest->tep_name = strdup(old_tep.c_str());
1076 // recovery of zip mount file for installed package
1077 std::string zip_mount_file = pkg_query.ZipMountFile();
1078 if (!zip_mount_file.empty())
1079 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1082 // in case of hybrid package, main app is already set by wgt-backend
1083 application_x* mainapp = nullptr;
1084 if (!context_->cross_app_rules.get()) {
1086 for (const auto& app : GListRange<application_x*>(manifest->application)) {
1087 if (!strcmp(app->mainapp, "true")) {
1092 if (mainapp == nullptr)
1093 mainapp = reinterpret_cast<application_x*>(
1094 g_list_first(manifest->application)->data);
1095 free(mainapp->mainapp);
1096 mainapp->mainapp = strdup("true");
1097 manifest->mainapp_id = strdup(mainapp->appid);
1100 // mark mainapp=false at other apps
1101 for (auto& app : GListRange<application_x*>(manifest->application)) {
1105 app->mainapp = strdup("false");
1110 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
1111 if (!FillPackageInfo(manifest))
1113 if (!FillInstallationInfo(manifest))
1115 if (!FillUIApplication(manifest))
1117 if (!FillServiceApplication(manifest))
1119 if (!FillWidgetApplication(manifest))
1121 if (!FillWatchApplication(manifest))
1123 if (!FillPrivileges(manifest))
1125 if (!FillProvidesAppDefinedPrivileges(manifest))
1127 if (!FillAuthorInfo(manifest))
1129 if (!FillDescriptionInfo(manifest))
1131 if (!FillExtraInfo(manifest))
1133 if (!FillTrustAnchorInfo(manifest))
1138 Step::Status StepParseManifest::process() {
1139 if (context_->force_clean_from_db.get())
1140 return Step::Status::OK;
1141 if (!LocateConfigFile()) {
1142 // continue if this is recovery, manifest file may never been created
1143 if (manifest_location_ == ManifestLocation::RECOVERY) {
1144 LOG(DEBUG) << "Manifest for recovery not found";
1145 return Step::Status::OK;
1147 LOG(ERROR) << "No manifest file exists";
1148 return Step::Status::MANIFEST_NOT_FOUND;
1150 parser_.reset(new tpk::parse::TPKConfigParser());
1151 if (!parser_->ParseManifest(path_)) {
1152 if (manifest_location_ == ManifestLocation::RECOVERY) {
1153 LOG(DEBUG) << "Manifest for recovery is invalid";
1155 return Step::Status::OK;
1157 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
1158 return Step::Status::PARSE_ERROR;
1161 // Copy data from ManifestData to InstallerContext
1162 std::shared_ptr<const tpk::parse::PackageInfo> info =
1163 std::static_pointer_cast<const tpk::parse::PackageInfo>(
1164 parser_->GetManifestData(app_keys::kManifestKey));
1166 context_->pkgid.set(info->package());
1168 manifest_x* manifest =
1169 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1171 LOG(ERROR) << "Out of memory";
1172 return Step::Status::ERROR;
1175 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1176 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1177 << parser_->GetErrorMessage();
1178 pkgmgr_parser_free_manifest_xml(manifest);
1179 return Step::Status::PARSE_ERROR;
1182 // write pkgid for recovery file
1183 if (context_->recovery_info.get().recovery_file) {
1184 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1185 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1188 LOG(DEBUG) << "Parsed package id: " << info->package();
1190 switch (store_location_) {
1191 case StoreLocation::NORMAL:
1192 context_->manifest_data.set(manifest);
1194 case StoreLocation::BACKUP:
1195 context_->old_manifest_data.set(manifest);
1198 LOG(ERROR) << "Unknown store location for parsed data";
1199 return Step::Status::ERROR;
1201 return Step::Status::OK;
1204 } // namespace configuration
1205 } // namespace common_installer