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/application_manifest_constants.h>
14 #include <tpk_manifest_handlers/author_handler.h>
15 #include <tpk_manifest_handlers/description_handler.h>
16 #include <tpk_manifest_handlers/feature_handler.h>
17 #include <tpk_manifest_handlers/package_handler.h>
18 #include <tpk_manifest_handlers/privileges_handler.h>
19 #include <tpk_manifest_handlers/profile_handler.h>
20 #include <tpk_manifest_handlers/service_application_handler.h>
21 #include <tpk_manifest_handlers/shortcut_handler.h>
22 #include <tpk_manifest_handlers/ui_application_handler.h>
23 #include <tpk_manifest_handlers/watch_application_handler.h>
24 #include <tpk_manifest_handlers/widget_application_handler.h>
32 #include <type_traits>
36 #include "common/app_installer.h"
37 #include "common/feature_validator.h"
38 #include "common/installer_context.h"
39 #include "common/paths.h"
40 #include "common/privileges.h"
41 #include "common/pkgmgr_registration.h"
42 #include "common/pkgmgr_query.h"
43 #include "common/step/step.h"
44 #include "common/utils/glist_range.h"
46 namespace app_keys = tpk::application_keys;
47 namespace bf = boost::filesystem;
51 const char kManifestFileName[] = "tizen-manifest.xml";
52 const char kInstalledInternally[] = "installed_internal";
53 const char kPortraitOrientation[] = "portrait";
54 const char kLandscapeOrientation[] = "landscape";
55 const char kOperationEffectKey[] = "operation_effect";
56 const char kLaunchEffectKey[] = "launch_effect";
57 const char kPortraitEffectImageValue[] = "portrait-effectimage";
58 const char kLandscapeEffectImageValue[] = "landscape-effectimage";
59 const char kIndicatorDisplayValue[] = "indicatordisplay";
63 namespace common_installer {
64 namespace configuration {
66 StepParseManifest::StepParseManifest(
67 InstallerContext* context, ManifestLocation manifest_location,
68 StoreLocation store_location)
70 manifest_location_(manifest_location),
71 store_location_(store_location) {
74 Step::Status StepParseManifest::precheck() {
75 switch (manifest_location_) {
76 case ManifestLocation::RECOVERY:
77 case ManifestLocation::INSTALLED:
78 if (context_->pkgid.get().empty()) {
79 LOG(ERROR) << "Package id is not set";
80 return Status::INVALID_VALUE;
83 case ManifestLocation::PACKAGE:
84 if (context_->unpacked_dir_path.get().empty()) {
85 LOG(ERROR) << "Unpacked directory doesn't exist";
86 return Status::INVALID_VALUE;
90 LOG(ERROR) << "Unknown manifest location";
91 return Status::INVALID_VALUE;
96 bool StepParseManifest::LocateConfigFile() {
97 boost::filesystem::path manifest;
98 switch (manifest_location_) {
99 case ManifestLocation::RECOVERY: {
100 context_->pkg_path.set(
101 context_->root_application_path.get() / context_->pkgid.get());
102 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
103 context_->pkg_path.get()) / kManifestFileName;
104 bf::path in_package_path = context_->pkg_path.get() / kManifestFileName;
105 bf::path install_path =
106 bf::path(getUserManifestPath(context_->uid.get(), false))
107 / bf::path(context_->pkgid.get());
108 install_path += ".xml";
109 if (bf::exists(backup_path))
110 manifest = backup_path;
111 else if (bf::exists(in_package_path))
112 manifest = in_package_path;
113 else if (bf::exists(install_path))
114 manifest = install_path;
117 case ManifestLocation::INSTALLED: {
119 bool is_readonly = context_->is_readonly_package.get();
120 if (QueryIsGlobalPackage(context_->pkgid.get(), context_->uid.get()))
121 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
123 uid = context_->uid.get();
125 bf::path(getUserManifestPath(uid, is_readonly))
126 / bf::path(context_->pkgid.get());
128 context_->xml_path.set(xml_path);
129 manifest = context_->xml_path.get();
130 if (!boost::filesystem::exists(manifest)) {
131 /* This routine has added for platform update */
132 manifest = context_->unpacked_dir_path.get();
133 manifest /= kManifestFileName;
137 case ManifestLocation::PACKAGE: {
138 manifest = context_->unpacked_dir_path.get();
139 manifest /= kManifestFileName;
143 LOG(ERROR) << "Unknown manifest location value";
148 LOG(DEBUG) << "manifest path: " << manifest;
150 if (!boost::filesystem::exists(manifest))
157 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
159 std::size_t found = std::string::npos;
161 found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
162 if (found != std::string::npos)
163 mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
165 found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
166 if (found != std::string::npos)
167 mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
169 found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
170 if (found != std::string::npos)
171 mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
176 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
177 manifest->root_path = strdup(
178 (context_->root_application_path.get() / manifest->package).c_str());
179 manifest->installed_time =
180 strdup(std::to_string(std::chrono::system_clock::to_time_t(
181 std::chrono::system_clock::now())).c_str());
185 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
186 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
187 std::static_pointer_cast<const tpk::parse::PackageInfo>(
188 parser_->GetManifestData(app_keys::kManifestKey));
190 LOG(ERROR) << "Package info manifest data has not been found.";
194 auto ui_application_list =
195 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
196 parser_->GetManifestData(app_keys::kUIApplicationKey));
197 auto service_application_list =
198 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
199 parser_->GetManifestData(app_keys::kServiceApplicationKey));
200 auto widget_application_list =
201 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
202 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
203 auto watch_application_list =
204 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
205 parser_->GetManifestData(app_keys::kWatchApplicationKey));
208 if (!ui_application_list && !service_application_list &&
209 !widget_application_list && !watch_application_list) {
210 LOG(ERROR) << "UI Application or Service Application or Widget Application "
211 "or Watch Application are mandatory and has not been found.";
215 int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
217 manifest->ns = strdup(pkg_info->xmlns().c_str());
218 manifest->package = strdup(pkg_info->package().c_str());
219 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
220 manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
221 manifest->appsetting = strdup("false");
222 manifest->support_disable = strdup("false");
223 manifest->version = strdup(pkg_info->version().c_str());
224 manifest->installlocation = strdup(pkg_info->install_location().c_str());
225 manifest->api_version = strdup(pkg_info->api_version().c_str());
226 manifest->readonly = strdup(pkg_info->readonly().c_str());
227 manifest->preload = strdup(pkg_info->preload().c_str());
228 manifest->removable = strdup(pkg_info->removable().c_str());
230 // set update true if package is updated preload package
231 common_installer::RequestType req_type = context_->request_type.get();
232 if (req_type == RequestType::ReadonlyUpdateInstall)
233 manifest->update = strdup("true");
234 else if (req_type == RequestType::ReadonlyUpdateUninstall)
235 manifest->update = strdup("false");
236 else if (QueryIsUpdatedReadonlyPackage(pkg_info->package(),
237 context_->uid.get()))
238 manifest->update = strdup("true");
240 manifest->update = strdup("false");
242 if (pkg_info->type().empty()) {
243 if ((req_type == RequestType::ManifestDirectInstall ||
244 req_type == RequestType::ManifestDirectUpdate) &&
245 context_->is_readonly_package.get())
246 manifest->type = strdup("rpm");
248 manifest->type = strdup("tpk");
250 manifest->type = strdup(pkg_info->type().c_str());
253 for (auto& pair : pkg_info->labels()) {
254 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
255 if (!pair.first.empty())
256 label->lang = strdup(pair.first.c_str());
258 label->lang = strdup(DEFAULT_LOCALE);
259 label->text = strdup(pair.second.c_str());
260 manifest->label = g_list_append(manifest->label, label);
263 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
264 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
265 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
267 for (auto& profile : profile_info->profiles()) {
268 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
269 strdup(profile.c_str()));
273 // set installed_storage if package is installed
274 // this is internal field in package manager but after reading configuration
276 if (manifest_location_ == ManifestLocation::INSTALLED ||
277 manifest_location_ == ManifestLocation::RECOVERY) {
278 std::string storage = QueryStorageForPkgId(manifest->package,
279 context_->uid.get());
280 if (storage.empty()) {
281 // Failed to query installation storage, assign internal
282 manifest->installed_storage = strdup(kInstalledInternally);
284 manifest->installed_storage = strdup(storage.c_str());
287 manifest->installed_storage = strdup(kInstalledInternally);
290 if (ui_application_list) {
291 manifest->mainapp_id =
292 strdup(ui_application_list->items[0].app_info.appid().c_str());
293 } else if (service_application_list) {
294 manifest->mainapp_id =
295 strdup(service_application_list->items[0].app_info.appid().c_str());
296 } else if (widget_application_list) {
297 manifest->mainapp_id =
298 strdup(widget_application_list->items[0].app_info.appid().c_str());
299 } else if (watch_application_list) {
300 manifest->mainapp_id =
301 strdup(watch_application_list->items[0].app_info.appid().c_str());
306 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
307 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
308 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
309 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
314 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
315 author->text = strdup(author_info->name().c_str());
316 author->email = strdup(author_info->email().c_str());
317 author->href = strdup(author_info->href().c_str());
318 author->lang = strdup(DEFAULT_LOCALE);
319 manifest->author = g_list_append(manifest->author, author);
323 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
324 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
325 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
326 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
328 if (!description_info)
331 for (auto& desc : description_info->descriptions) {
332 description_x* description = reinterpret_cast<description_x*>
333 (calloc(1, sizeof(description_x)));
334 description->text = strdup(desc.description().c_str());
335 description->lang = !desc.xml_lang().empty() ?
336 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
337 manifest->description = g_list_append(manifest->description, description);
342 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
343 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
344 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
345 parser_->GetManifestData(app_keys::kPrivilegesKey));
349 const auto& privileges = perm_info->GetPrivileges();
350 for (auto& priv : privileges) {
351 privilege_x* privilege =
352 reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
353 privilege->value = strdup(priv.first.c_str());
354 privilege->type = strdup(priv.second.c_str());
355 manifest->privileges = g_list_append(manifest->privileges, privilege);
360 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
361 auto widget_application_list =
362 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
363 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
364 if (!widget_application_list)
366 int mainapps = std::count_if(widget_application_list->items.begin(),
367 widget_application_list->items.end(),
368 [](const tpk::parse::WidgetApplicationSingleEntry& app) {
369 return app.app_info.main() == "true";
371 if (mainapps > 1) // only one main app is permitted
374 for (const auto& application : widget_application_list->items) {
375 // if there is no app yet and not hybrid package installation,
376 // set this app as mainapp
377 bool main_app = (context_->cross_app_rules.get() == false &&
378 manifest->application == nullptr);
380 int package_support_mode_val = atoi(manifest->support_mode);
381 int app_support_mode_val = package_support_mode_val |
382 GetSupportModeVal(application.app_info.support_mode());
384 application_x* widget_app =
385 static_cast<application_x*>(calloc(1, sizeof(application_x)));
386 widget_app->appid = strdup(application.app_info.appid().c_str());
387 widget_app->launch_mode =
388 strdup(application.app_info.launch_mode().c_str());
389 widget_app->multiple = strdup("false");
390 widget_app->nodisplay = strdup("true");
391 widget_app->support_mode =
392 strdup((std::to_string(app_support_mode_val)).c_str());
393 widget_app->taskmanage = strdup("false");
394 widget_app->indicatordisplay = strdup("false");
396 strdup(application.app_info.type().c_str());
397 widget_app->component_type = strdup("widgetapp");
398 widget_app->hwacceleration =
399 strdup(application.app_info.hwacceleration().c_str());
400 widget_app->onboot = strdup("false");
401 widget_app->autorestart = strdup("false");
403 widget_app->mainapp = strdup(application.app_info.main().c_str());
405 widget_app->mainapp = main_app ? strdup("true") : strdup("false");
407 widget_app->enabled = strdup("true");
408 widget_app->screenreader = strdup("use-system-setting");
409 widget_app->recentimage = strdup("false");
410 widget_app->launchcondition = strdup("false");
411 widget_app->guestmode_visibility = strdup("true");
412 widget_app->permission_type = strdup("normal");
413 widget_app->support_ambient = strdup("false");
414 widget_app->effectimage_type = strdup("image");
415 widget_app->submode = strdup("false");
416 widget_app->process_pool = strdup("false");
417 widget_app->package = strdup(manifest->package);
418 widget_app->support_disable = strdup(manifest->support_disable);
419 manifest->application = g_list_append(manifest->application, widget_app);
420 if (bf::path(application.app_info.exec().c_str()).is_absolute())
421 widget_app->exec = strdup(application.app_info.exec().c_str());
423 widget_app->exec = strdup((context_->root_application_path.get()
424 / manifest->package / "bin"
425 / application.app_info.exec()).c_str());
427 if (!FillApplicationIconPaths(widget_app, application.app_icons))
429 if (!FillLabel(widget_app, application.label))
431 if (!FillImage(widget_app, application.app_images))
433 if (!FillCategories(widget_app, application.categories))
435 if (!FillMetadata(widget_app, application.meta_data))
437 // FIXME: For hotfix, must be removed
438 if (!FillSupportSize(widget_app, application.support_sizes))
444 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
445 auto service_application_list =
446 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
447 parser_->GetManifestData(app_keys::kServiceApplicationKey));
448 if (!service_application_list)
451 for (const auto& application : service_application_list->items) {
452 // if there is no app yet, set this app as mainapp
453 bool main_app = (context_->cross_app_rules.get() == false &&
454 manifest->application == nullptr);
456 int package_support_mode_val = atoi(manifest->support_mode);
457 int app_support_mode_val = package_support_mode_val |
458 GetSupportModeVal(application.app_info.support_mode());
460 application_x* service_app =
461 static_cast<application_x*>(calloc(1, sizeof(application_x)));
462 service_app->appid = strdup(application.app_info.appid().c_str());
463 service_app->multiple = strdup(application.app_info.multiple().c_str());
464 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
465 service_app->support_mode =
466 strdup((std::to_string(app_support_mode_val)).c_str());
467 service_app->autorestart =
468 strdup(application.app_info.auto_restart().c_str());
469 service_app->onboot = strdup(application.app_info.on_boot().c_str());
470 service_app->type = strdup(application.app_info.type().c_str());
471 service_app->process_pool =
472 strdup(application.app_info.process_pool().c_str());
473 service_app->component_type = strdup("svcapp");
474 service_app->mainapp = main_app ? strdup("true") : strdup("false");
475 service_app->enabled = strdup("true");
476 service_app->nodisplay = strdup("true");
477 service_app->hwacceleration = strdup("default");
478 service_app->screenreader = strdup("use-system-setting");
479 service_app->recentimage = strdup("false");
480 service_app->launchcondition = strdup("false");
481 service_app->indicatordisplay = strdup("true");
482 service_app->effectimage_type = strdup("image");
483 service_app->guestmode_visibility = strdup("true");
484 service_app->permission_type = strdup("normal");
485 service_app->submode = strdup("false");
486 service_app->process_pool = strdup("false");
487 service_app->support_ambient = strdup("false");
488 service_app->package = strdup(manifest->package);
489 service_app->support_disable = strdup(manifest->support_disable);
490 manifest->application = g_list_append(manifest->application, service_app);
491 if (bf::path(application.app_info.exec().c_str()).is_absolute())
492 service_app->exec = strdup(application.app_info.exec().c_str());
494 service_app->exec = strdup((context_->root_application_path.get()
495 / manifest->package / "bin"
496 / application.app_info.exec()).c_str());
498 if (!FillAppControl(service_app, application.app_control))
500 if (!FillDataControl(service_app, application.data_control))
502 if (!FillApplicationIconPaths(service_app, application.app_icons))
504 if (!FillLabel(service_app, application.label))
506 if (!FillMetadata(service_app, application.meta_data))
508 if (!FillCategories(service_app, application.categories))
510 if (!FillBackgroundCategoryInfo(service_app,
511 application.background_category))
517 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
518 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
519 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
520 parser_->GetManifestData(app_keys::kUIApplicationKey));
521 if (!ui_application_list)
524 for (const auto& application : ui_application_list->items) {
525 // if there is no app yet, set this app as mainapp
526 bool main_app = (context_->cross_app_rules.get() == false &&
527 manifest->application == nullptr);
529 int package_support_mode_val = atoi(manifest->support_mode);
530 int app_support_mode_val = package_support_mode_val |
531 GetSupportModeVal(application.app_info.support_mode());
533 application_x* ui_app =
534 static_cast<application_x*>(calloc(1, sizeof(application_x)));
535 ui_app->appid = strdup(application.app_info.appid().c_str());
536 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
537 ui_app->multiple = strdup(application.app_info.multiple().c_str());
538 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
539 ui_app->support_mode =
540 strdup((std::to_string(app_support_mode_val)).c_str());
541 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
542 ui_app->type = strdup(application.app_info.type().c_str());
543 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
544 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
545 ui_app->submode = strdup(application.app_info.submode().c_str());
546 if (!application.app_info.indicator_display().empty())
547 ui_app->indicatordisplay =
548 strdup(application.app_info.indicator_display().c_str());
549 if (!application.app_info.effectimage_type().empty())
550 ui_app->effectimage_type =
551 strdup(application.app_info.effectimage_type().c_str());
552 if (!application.app_info.portrait_image().empty()) {
553 ui_app->portraitimg =
554 strdup(application.app_info.portrait_image().c_str());
555 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
556 application.app_info.effectimage_type(), {}, kPortraitOrientation,
557 application.app_info.indicator_display(), {}, {});
559 if (!application.app_info.landscape_image().empty()) {
560 ui_app->landscapeimg =
561 strdup(application.app_info.landscape_image().c_str());
562 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
563 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
564 application.app_info.indicator_display(), {}, {});
566 ui_app->submode_mainid =
567 strdup(application.app_info.submode_mainid().c_str());
568 ui_app->hwacceleration =
569 strdup(application.app_info.hwacceleration().c_str());
570 ui_app->onboot = strdup("false");
571 ui_app->autorestart = strdup("false");
572 ui_app->component_type = strdup("uiapp");
573 ui_app->mainapp = main_app ? strdup("true") : strdup("false");
574 ui_app->enabled = strdup("true");
575 ui_app->screenreader = strdup("use-system-setting");
576 ui_app->recentimage = strdup("false");
577 ui_app->launchcondition = strdup("false");
578 ui_app->guestmode_visibility = strdup("true");
579 ui_app->permission_type = strdup("normal");
580 ui_app->support_ambient = strdup("false");
581 ui_app->package = strdup(manifest->package);
582 ui_app->support_disable = strdup(manifest->support_disable);
583 ui_app->splash_screen_display =
584 strdup(application.app_info.splash_screen_display().c_str());
585 manifest->application = g_list_append(manifest->application, ui_app);
586 if (bf::path(application.app_info.exec().c_str()).is_absolute())
587 ui_app->exec = strdup(application.app_info.exec().c_str());
589 ui_app->exec = strdup((context_->root_application_path.get()
590 / manifest->package / "bin"
591 / application.app_info.exec()).c_str());
594 if (!FillAppControl(ui_app, application.app_control))
596 if (!FillDataControl(ui_app, application.data_control))
598 if (!FillApplicationIconPaths(ui_app, application.app_icons))
600 if (!FillLabel(ui_app, application.label))
602 if (!FillImage(ui_app, application.app_images))
604 if (!FillMetadata(ui_app, application.meta_data))
606 if (!FillCategories(ui_app, application.categories))
608 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
610 if (!FillSplashScreen(ui_app, application.app_splashscreens))
616 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
617 auto watch_application_list =
618 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
619 parser_->GetManifestData(app_keys::kWatchApplicationKey));
620 if (!watch_application_list)
623 for (const auto& watch_application : watch_application_list->items) {
624 bool main_app = (context_->cross_app_rules.get() == false &&
625 manifest->application == nullptr);
627 int package_support_mode_val = atoi(manifest->support_mode);
628 int app_support_mode_val = package_support_mode_val |
629 GetSupportModeVal(watch_application.app_info.support_mode());
631 application_x* watch_app =
632 static_cast<application_x*>(calloc(1, sizeof(application_x)));
633 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
635 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
636 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
638 watch_app->exec = strdup(
639 (context_->root_application_path.get()
640 / manifest->package / "bin" /
641 watch_application.app_info.exec()).c_str());
642 watch_app->nodisplay = strdup("true");
643 watch_app->multiple = strdup("false");
644 watch_app->type = strdup(watch_application.app_info.type().c_str());
645 watch_app->taskmanage = strdup("false");
646 watch_app->enabled = strdup("true");
647 watch_app->hwacceleration = strdup("default");
648 watch_app->screenreader = strdup("use-system-setting");
649 watch_app->mainapp = main_app ? strdup("true") : strdup("false");
650 watch_app->recentimage = strdup("false");
651 watch_app->launchcondition = strdup("false");
652 watch_app->indicatordisplay = strdup("true");
653 watch_app->effectimage_type = strdup("image");
654 watch_app->guestmode_visibility = strdup("true");
655 watch_app->permission_type = strdup("normal");
656 watch_app->component_type = strdup("watchapp");
657 watch_app->preload = strdup("false");
658 watch_app->submode = strdup("false");
659 watch_app->process_pool = strdup("false");
660 watch_app->autorestart = strdup("false");
661 watch_app->onboot = strdup("false");
662 watch_app->support_mode =
663 strdup((std::to_string(app_support_mode_val)).c_str());
664 watch_app->ui_gadget = strdup("false");
665 watch_app->launch_mode = strdup("single");
666 watch_app->support_ambient =
667 strdup(watch_application.app_info.ambient_support().c_str());
668 watch_app->package = strdup(manifest->package);
669 if (!FillLabel(watch_app, watch_application.label))
671 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
673 if (!FillMetadata(watch_app, watch_application.meta_data))
675 if (!FillCategories(watch_app, watch_application.categories))
677 if (!FillBackgroundCategoryInfo(watch_app,
678 watch_application.background_category))
680 manifest->application = g_list_append(manifest->application, watch_app);
685 bool StepParseManifest::CheckFeatures() {
687 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
688 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
693 FeatureValidator validator(feature_info->features());
694 if (!validator.Validate(&error)) {
695 LOG(ERROR) << "Feature validation error. " << error;
702 template <typename T>
703 bool StepParseManifest::FillAppControl(application_x* app,
704 const T& app_control_list) {
705 if (app_control_list.empty())
708 for (const auto& control : app_control_list) {
709 appcontrol_x* app_control =
710 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
711 app_control->operation = strdup(control.operation().c_str());
712 if (!control.mime().empty())
713 app_control->mime = strdup(control.mime().c_str());
714 if (!control.uri().empty())
715 app_control->uri = strdup(control.uri().c_str());
716 app->appcontrol = g_list_append(app->appcontrol, app_control);
721 template <typename T>
722 bool StepParseManifest::FillDataControl(application_x* app,
723 const T& data_control_list) {
724 if (data_control_list.empty())
727 for (const auto& control : data_control_list) {
728 datacontrol_x* data_control =
729 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
730 data_control->access = strdup(control.access().c_str());
731 data_control->providerid = strdup(control.providerid().c_str());
732 data_control->type = strdup(control.type().c_str());
733 app->datacontrol = g_list_append(app->datacontrol, data_control);
738 template <typename T>
739 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
740 const T& icons_info) {
741 for (auto& application_icon : icons_info.icons()) {
742 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
744 if (bf::path(application_icon.path()).is_absolute()) {
745 text = application_icon.path();
747 text = context_->root_application_path.get()
748 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
750 // NOTE: name is an attribute, but the xml writer uses it as text.
751 // This must be fixed in whole app-installer modules, including wgt.
752 // Current implementation is just for compatibility.
753 icon->text = strdup(text.c_str());
754 if (application_icon.lang().empty())
755 icon->lang = strdup(DEFAULT_LOCALE);
757 icon->lang = strdup(application_icon.lang().c_str());
759 if (!application_icon.dpi().empty())
760 icon->dpi = strdup(application_icon.dpi().c_str());
761 app->icon = g_list_append(app->icon, icon);
766 template <typename T>
767 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
768 if (label_list.empty())
771 for (const auto& control : label_list) {
773 static_cast<label_x*>(calloc(1, sizeof(label_x)));
774 // NOTE: name is an attribute, but the xml writer uses it as text.
775 // This must be fixed in whole app-installer modules, including wgt.
776 // Current implementation is just for compatibility.
777 label->text = strdup(control.text().c_str());
778 label->name = strdup(control.name().c_str());
779 label->lang = !control.xml_lang().empty() ?
780 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
781 app->label = g_list_append(app->label, label);
786 template <typename T>
787 bool StepParseManifest::FillMetadata(application_x* app,
788 const T& meta_data_list) {
789 if (meta_data_list.empty())
792 for (auto& meta : meta_data_list) {
793 metadata_x* metadata =
794 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
795 metadata->key = strdup(meta.key().c_str());
796 metadata->value = strdup(meta.val().c_str());
797 app->metadata = g_list_append(app->metadata, metadata);
799 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
804 // FIXME: For hotfix, must be removed
805 template <typename T>
806 bool StepParseManifest::FillSupportSize(application_x* app,
807 const T& support_size_list) {
808 if (support_size_list.empty())
811 for (auto& ss : support_size_list) {
812 support_size_x* support_size =
813 static_cast<support_size_x*>(calloc(1, sizeof(support_size_x)));
814 support_size->preview = strdup(ss.preview().c_str());
815 support_size->size = strdup(ss.size().c_str());
816 app->support_sizes = g_list_append(app->support_sizes, support_size);
821 template <typename T>
822 bool StepParseManifest::FillCategories(application_x* manifest,
823 const T& categories) {
824 for (auto& category : categories) {
825 manifest->category = g_list_append(manifest->category,
826 strdup(category.c_str()));
831 void StepParseManifest::AppendSplashScreen(application_x* app,
832 const std::string& src, const std::string& type, const std::string& dpi,
833 const std::string& orientation, const std::string& indicatordisplay,
834 const std::string& operation, const std::string& color_depth) {
835 splashscreen_x* splashscreen =
836 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
837 if (bf::path(src).is_absolute()) {
838 splashscreen->src = strdup(src.c_str());
840 bf::path full_path = context_->pkg_path.get() / src;
841 splashscreen->src = strdup(full_path.string().c_str());
843 if (src.substr(src.find_last_of(".") + 1) == "edj")
844 splashscreen->type = strdup("edj");
845 else if (type == "edj")
846 splashscreen->type = strdup("edj");
848 splashscreen->type = strdup("img");
850 splashscreen->dpi = strdup(dpi.c_str());
851 splashscreen->orientation = strdup(orientation.c_str());
852 if (!indicatordisplay.empty())
853 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
855 splashscreen->indicatordisplay = strdup("true");
856 if (operation == "launch_effect")
857 splashscreen->operation = strdup("launch-effect");
858 else if (!operation.empty())
859 splashscreen->operation = strdup(operation.c_str());
861 splashscreen->operation = strdup("launch-effect");
862 if (!color_depth.empty())
863 splashscreen->color_depth = strdup(color_depth.c_str());
865 splashscreen->color_depth = strdup("24");
866 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
869 template <typename T>
870 bool StepParseManifest::FillSplashScreen(application_x* app,
871 const T& splashscreens_info) {
872 for (auto& splash_screen : splashscreens_info.splashscreens()) {
874 if (context_->is_readonly_package.get())
875 src = splash_screen.src();
877 src = bf::path(context_->root_application_path.get()
878 / app->package / "shared" / "res" / splash_screen.src()).string();
880 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
881 splash_screen.orientation(), splash_screen.indicatordisplay(),
882 splash_screen.operation(), splash_screen.colordepth());
887 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
888 const std::string& key, const std::string& val) {
889 std::string operation;
890 if (key.find(kOperationEffectKey) != std::string::npos) {
891 boost::char_separator<char> sep("=");
892 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
893 auto iter = tokens.begin();
896 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
897 operation = std::string("launch-effect");
899 // not a metadata splashscreen
903 boost::char_separator<char> sep("=|");
904 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
905 auto iter = tokens.begin();
906 std::string portrait_src;
907 std::string landscape_src;
908 std::string indicatordisplay;
909 while (iter != tokens.end()) {
910 if (!(*iter).compare(kPortraitEffectImageValue)) {
912 portrait_src = *iter;
913 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
915 landscape_src = *iter;
916 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
918 indicatordisplay = *iter;
922 if (!portrait_src.empty())
923 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
924 indicatordisplay, operation, {});
925 if (!landscape_src.empty())
926 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
927 indicatordisplay, operation, {});
930 bool StepParseManifest::FillImage(application_x* app,
931 const tpk::parse::ApplicationImagesInfo& image_list) {
932 for (auto& app_image : image_list.images) {
934 static_cast<image_x*>(calloc(1, sizeof(image_x)));
935 const std::string& lang = app_image.lang();
937 image->lang = strdup(lang.c_str());
939 image->lang = strdup(DEFAULT_LOCALE);
940 if (!app_image.section().empty())
941 image->section = strdup(app_image.section().c_str());
942 app->image = g_list_append(app->image, image);
947 template <typename T>
948 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
949 const T& background_category_data_list) {
950 for (const auto& background_category : background_category_data_list) {
951 app->background_category = g_list_append(
952 app->background_category, strdup(background_category.value().c_str()));
958 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
959 if (!FillPackageInfo(manifest))
961 if (!FillInstallationInfo(manifest))
963 if (!FillUIApplication(manifest))
965 if (!FillServiceApplication(manifest))
967 if (!FillWidgetApplication(manifest))
969 if (!FillWatchApplication(manifest))
971 if (!FillPrivileges(manifest))
973 if (!FillAuthorInfo(manifest))
975 if (!FillDescriptionInfo(manifest))
980 Step::Status StepParseManifest::process() {
981 if (context_->force_clean_from_db.get())
982 return Step::Status::OK;
983 if (!LocateConfigFile()) {
984 // continue if this is recovery, manifest file may never been created
985 if (manifest_location_ == ManifestLocation::RECOVERY) {
986 LOG(DEBUG) << "Manifest for recovery not found";
987 return Step::Status::OK;
989 LOG(ERROR) << "No manifest file exists";
990 return Step::Status::MANIFEST_NOT_FOUND;
992 parser_.reset(new tpk::parse::TPKConfigParser());
993 if (!parser_->ParseManifest(path_)) {
994 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
995 return Step::Status::PARSE_ERROR;
998 // Copy data from ManifestData to InstallerContext
999 std::shared_ptr<const tpk::parse::PackageInfo> info =
1000 std::static_pointer_cast<const tpk::parse::PackageInfo>(
1001 parser_->GetManifestData(app_keys::kManifestKey));
1003 context_->pkgid.set(info->package());
1004 context_->pkg_path.set(
1005 context_->root_application_path.get() / context_->pkgid.get());
1007 manifest_x* manifest =
1008 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1010 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1011 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1012 << parser_->GetErrorMessage();
1013 return Step::Status::PARSE_ERROR;
1016 if (manifest_location_ == ManifestLocation::INSTALLED) {
1017 // recovery of tep value for installed package
1018 std::string old_tep =
1019 QueryTepPath(context_->pkgid.get(), context_->uid.get());
1020 if (!old_tep.empty())
1021 manifest->tep_name = strdup(old_tep.c_str());
1023 // recovery of zip mount file for installed package
1024 std::string zip_mount_file =
1025 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
1026 if (!zip_mount_file.empty())
1027 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
1030 // write pkgid for recovery file
1031 if (context_->recovery_info.get().recovery_file) {
1032 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1033 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1036 LOG(DEBUG) << "Parsed package id: " << info->package();
1038 switch (store_location_) {
1039 case StoreLocation::NORMAL:
1040 context_->manifest_data.set(manifest);
1042 case StoreLocation::BACKUP:
1043 context_->old_manifest_data.set(manifest);
1046 LOG(ERROR) << "Unknown store location for parsed data";
1047 return Step::Status::ERROR;
1049 return Step::Status::OK;
1052 } // namespace configuration
1053 } // namespace common_installer