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(),
107 context_->is_readonly_package.get()))
108 / bf::path(context_->pkgid.get());
109 install_path += ".xml";
110 if (bf::exists(backup_path))
111 manifest = backup_path;
112 else if (bf::exists(in_package_path))
113 manifest = in_package_path;
114 else if (bf::exists(install_path))
115 manifest = install_path;
118 case ManifestLocation::INSTALLED: {
120 bool is_readonly = context_->is_readonly_package.get();
121 if (QueryIsGlobalPackage(context_->pkgid.get(), context_->uid.get()))
122 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
124 uid = context_->uid.get();
126 bf::path(getUserManifestPath(uid, is_readonly))
127 / bf::path(context_->pkgid.get());
129 context_->xml_path.set(xml_path);
130 manifest = context_->xml_path.get();
131 if (!boost::filesystem::exists(manifest)) {
132 /* This routine has added for platform update */
133 manifest = context_->unpacked_dir_path.get();
134 manifest /= kManifestFileName;
138 case ManifestLocation::PACKAGE: {
139 manifest = context_->unpacked_dir_path.get();
140 manifest /= kManifestFileName;
144 LOG(ERROR) << "Unknown manifest location value";
149 LOG(DEBUG) << "manifest path: " << manifest;
151 if (!boost::filesystem::exists(manifest))
158 int StepParseManifest::GetSupportModeVal(std::string support_mode) {
160 std::size_t found = std::string::npos;
162 found = support_mode.find(APP_SUPPORT_MODE_ULTRA_POWER_SAVING_STR);
163 if (found != std::string::npos)
164 mode |= APP_SUPPORT_MODE_ULTRA_POWER_SAVING_VAL;
166 found = support_mode.find(APP_SUPPORT_MODE_COOL_DOWN_STR);
167 if (found != std::string::npos)
168 mode |= APP_SUPPORT_MODE_COOL_DOWN_VAL;
170 found = support_mode.find(APP_SUPPORT_MODE_SCREEN_READER_STR);
171 if (found != std::string::npos)
172 mode |= APP_SUPPORT_MODE_SCREEN_READER_VAL;
177 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
178 manifest->root_path = strdup(
179 (context_->root_application_path.get() / manifest->package).c_str());
180 manifest->installed_time =
181 strdup(std::to_string(std::chrono::system_clock::to_time_t(
182 std::chrono::system_clock::now())).c_str());
186 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
187 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
188 std::static_pointer_cast<const tpk::parse::PackageInfo>(
189 parser_->GetManifestData(app_keys::kManifestKey));
191 LOG(ERROR) << "Package info manifest data has not been found.";
195 auto ui_application_list =
196 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
197 parser_->GetManifestData(app_keys::kUIApplicationKey));
198 auto service_application_list =
199 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
200 parser_->GetManifestData(app_keys::kServiceApplicationKey));
201 auto widget_application_list =
202 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
203 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
204 auto watch_application_list =
205 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
206 parser_->GetManifestData(app_keys::kWatchApplicationKey));
209 if (!ui_application_list && !service_application_list &&
210 !widget_application_list && !watch_application_list) {
211 LOG(ERROR) << "UI Application or Service Application or Widget Application "
212 "or Watch Application are mandatory and has not been found.";
216 int support_mode_val = GetSupportModeVal(pkg_info->support_mode());
218 manifest->ns = strdup(pkg_info->xmlns().c_str());
219 manifest->package = strdup(pkg_info->package().c_str());
220 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
221 manifest->support_mode = strdup((std::to_string(support_mode_val)).c_str());
222 manifest->appsetting = strdup("false");
223 manifest->support_disable = strdup(pkg_info->support_disable().c_str());
224 manifest->version = strdup(pkg_info->version().c_str());
225 manifest->installlocation = strdup(pkg_info->install_location().c_str());
226 manifest->api_version = strdup(pkg_info->api_version().c_str());
227 manifest->readonly = strdup(pkg_info->readonly().c_str());
228 manifest->preload = strdup(pkg_info->preload().c_str());
229 manifest->removable = strdup(pkg_info->removable().c_str());
231 // set update true if package is updated preload package
232 common_installer::RequestType req_type = context_->request_type.get();
233 if (req_type == RequestType::ReadonlyUpdateInstall)
234 manifest->update = strdup("true");
235 else if (req_type == RequestType::ReadonlyUpdateUninstall)
236 manifest->update = strdup("false");
237 else if (QueryIsUpdatedReadonlyPackage(pkg_info->package(),
238 context_->uid.get()))
239 manifest->update = strdup("true");
241 manifest->update = strdup("false");
243 if (pkg_info->type().empty()) {
244 if ((req_type == RequestType::ManifestDirectInstall ||
245 req_type == RequestType::ManifestDirectUpdate) &&
246 context_->is_readonly_package.get())
247 manifest->type = strdup("rpm");
249 manifest->type = strdup("tpk");
251 manifest->type = strdup(pkg_info->type().c_str());
254 for (auto& pair : pkg_info->labels()) {
255 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
256 if (!pair.first.empty())
257 label->lang = strdup(pair.first.c_str());
259 label->lang = strdup(DEFAULT_LOCALE);
260 label->text = strdup(pair.second.c_str());
261 manifest->label = g_list_append(manifest->label, label);
264 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
265 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
266 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
268 for (auto& profile : profile_info->profiles()) {
269 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
270 strdup(profile.c_str()));
274 // set installed_storage if package is installed
275 // this is internal field in package manager but after reading configuration
277 if (manifest_location_ == ManifestLocation::INSTALLED ||
278 manifest_location_ == ManifestLocation::RECOVERY) {
279 std::string storage = QueryStorageForPkgId(manifest->package,
280 context_->uid.get());
281 if (storage.empty()) {
282 // Failed to query installation storage, assign internal
283 manifest->installed_storage = strdup(kInstalledInternally);
285 manifest->installed_storage = strdup(storage.c_str());
288 manifest->installed_storage = strdup(kInstalledInternally);
294 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
295 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
296 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
297 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
302 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
303 author->text = strdup(author_info->name().c_str());
304 author->email = strdup(author_info->email().c_str());
305 author->href = strdup(author_info->href().c_str());
306 author->lang = strdup(DEFAULT_LOCALE);
307 manifest->author = g_list_append(manifest->author, author);
311 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
312 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
313 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
314 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
316 if (!description_info)
319 for (auto& desc : description_info->descriptions) {
320 description_x* description = reinterpret_cast<description_x*>
321 (calloc(1, sizeof(description_x)));
322 description->text = strdup(desc.description().c_str());
323 description->lang = !desc.xml_lang().empty() ?
324 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
325 manifest->description = g_list_append(manifest->description, description);
330 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
331 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
332 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
333 parser_->GetManifestData(app_keys::kPrivilegesKey));
337 const auto& privileges = perm_info->GetPrivileges();
338 for (auto& priv : privileges) {
339 privilege_x* privilege =
340 reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
341 privilege->value = strdup(priv.first.c_str());
342 privilege->type = strdup(priv.second.c_str());
343 manifest->privileges = g_list_append(manifest->privileges, privilege);
348 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
349 auto widget_application_list =
350 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
351 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
352 if (!widget_application_list)
355 for (const auto& application : widget_application_list->items) {
356 int package_support_mode_val = atoi(manifest->support_mode);
357 int app_support_mode_val = package_support_mode_val |
358 GetSupportModeVal(application.app_info.support_mode());
360 application_x* widget_app =
361 static_cast<application_x*>(calloc(1, sizeof(application_x)));
362 widget_app->appid = strdup(application.app_info.appid().c_str());
363 widget_app->launch_mode =
364 strdup(application.app_info.launch_mode().c_str());
365 widget_app->multiple = strdup("false");
366 widget_app->nodisplay = strdup("true");
367 widget_app->support_mode =
368 strdup((std::to_string(app_support_mode_val)).c_str());
369 widget_app->taskmanage = strdup("false");
370 widget_app->indicatordisplay = strdup("false");
372 strdup(application.app_info.type().c_str());
373 widget_app->component_type = strdup("widgetapp");
374 widget_app->hwacceleration =
375 strdup(application.app_info.hwacceleration().c_str());
376 widget_app->onboot = strdup("false");
377 widget_app->autorestart = strdup("false");
378 widget_app->mainapp = strdup(application.app_info.mainapp().c_str());
379 widget_app->screenreader = strdup("use-system-setting");
380 widget_app->recentimage = strdup("false");
381 widget_app->launchcondition = strdup("false");
382 widget_app->guestmode_visibility = strdup("true");
383 widget_app->permission_type = strdup("normal");
384 widget_app->support_ambient = strdup("false");
385 widget_app->effectimage_type = strdup("image");
386 widget_app->submode = strdup("false");
387 widget_app->process_pool = strdup("false");
388 widget_app->package = strdup(manifest->package);
389 widget_app->support_disable = strdup(manifest->support_disable);
390 widget_app->launch_mode = strdup("single");
391 manifest->application = g_list_append(manifest->application, widget_app);
392 if (bf::path(application.app_info.exec().c_str()).is_absolute())
393 widget_app->exec = strdup(application.app_info.exec().c_str());
395 widget_app->exec = strdup((context_->root_application_path.get()
396 / manifest->package / "bin"
397 / application.app_info.exec()).c_str());
399 if (!FillApplicationIconPaths(widget_app, application.app_icons))
401 if (!FillLabel(widget_app, application.label))
403 if (!FillImage(widget_app, application.app_images))
405 if (!FillCategories(widget_app, application.categories))
407 if (!FillMetadata(widget_app, application.meta_data))
413 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
414 auto service_application_list =
415 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
416 parser_->GetManifestData(app_keys::kServiceApplicationKey));
417 if (!service_application_list)
420 for (const auto& application : service_application_list->items) {
421 int package_support_mode_val = atoi(manifest->support_mode);
422 int app_support_mode_val = package_support_mode_val |
423 GetSupportModeVal(application.app_info.support_mode());
425 application_x* service_app =
426 static_cast<application_x*>(calloc(1, sizeof(application_x)));
427 service_app->appid = strdup(application.app_info.appid().c_str());
428 service_app->multiple = strdup(application.app_info.multiple().c_str());
429 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
430 service_app->support_mode =
431 strdup((std::to_string(app_support_mode_val)).c_str());
432 service_app->autorestart =
433 strdup(application.app_info.auto_restart().c_str());
434 service_app->onboot = strdup(application.app_info.on_boot().c_str());
435 service_app->type = strdup(application.app_info.type().c_str());
436 service_app->process_pool =
437 strdup(application.app_info.process_pool().c_str());
438 service_app->component_type = strdup("svcapp");
439 service_app->mainapp = strdup(application.app_info.mainapp().c_str());
440 service_app->nodisplay = strdup("true");
441 service_app->hwacceleration = strdup("default");
442 service_app->screenreader = strdup("use-system-setting");
443 service_app->recentimage = strdup("false");
444 service_app->launchcondition = strdup("false");
445 service_app->indicatordisplay = strdup("true");
446 service_app->effectimage_type = strdup("image");
447 service_app->guestmode_visibility = strdup("true");
448 service_app->permission_type = strdup("normal");
449 service_app->submode = strdup("false");
450 service_app->process_pool = strdup("false");
451 service_app->support_ambient = strdup("false");
452 service_app->package = strdup(manifest->package);
453 service_app->support_disable = strdup(manifest->support_disable);
454 service_app->launch_mode = strdup("single");
455 manifest->application = g_list_append(manifest->application, service_app);
456 if (bf::path(application.app_info.exec().c_str()).is_absolute())
457 service_app->exec = strdup(application.app_info.exec().c_str());
459 service_app->exec = strdup((context_->root_application_path.get()
460 / manifest->package / "bin"
461 / application.app_info.exec()).c_str());
463 if (!FillAppControl(service_app, application.app_control))
465 if (!FillDataControl(service_app, application.data_control))
467 if (!FillApplicationIconPaths(service_app, application.app_icons))
469 if (!FillLabel(service_app, application.label))
471 if (!FillMetadata(service_app, application.meta_data))
473 if (!FillCategories(service_app, application.categories))
475 if (!FillBackgroundCategoryInfo(service_app,
476 application.background_category))
482 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
483 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
484 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
485 parser_->GetManifestData(app_keys::kUIApplicationKey));
486 if (!ui_application_list)
489 for (const auto& application : ui_application_list->items) {
490 int package_support_mode_val = atoi(manifest->support_mode);
491 int app_support_mode_val = package_support_mode_val |
492 GetSupportModeVal(application.app_info.support_mode());
494 application_x* ui_app =
495 static_cast<application_x*>(calloc(1, sizeof(application_x)));
496 ui_app->appid = strdup(application.app_info.appid().c_str());
497 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
498 ui_app->multiple = strdup(application.app_info.multiple().c_str());
499 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
500 ui_app->support_mode =
501 strdup((std::to_string(app_support_mode_val)).c_str());
502 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
503 ui_app->type = strdup(application.app_info.type().c_str());
504 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
505 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
506 ui_app->submode = strdup(application.app_info.submode().c_str());
507 if (!application.app_info.indicator_display().empty())
508 ui_app->indicatordisplay =
509 strdup(application.app_info.indicator_display().c_str());
510 if (!application.app_info.effectimage_type().empty())
511 ui_app->effectimage_type =
512 strdup(application.app_info.effectimage_type().c_str());
513 if (!application.app_info.portrait_image().empty()) {
514 ui_app->portraitimg =
515 strdup(application.app_info.portrait_image().c_str());
516 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
517 application.app_info.effectimage_type(), {}, kPortraitOrientation,
518 application.app_info.indicator_display(), {}, {});
520 if (!application.app_info.landscape_image().empty()) {
521 ui_app->landscapeimg =
522 strdup(application.app_info.landscape_image().c_str());
523 AppendSplashScreen(ui_app, application.app_info.landscape_image(),
524 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
525 application.app_info.indicator_display(), {}, {});
527 ui_app->submode_mainid =
528 strdup(application.app_info.submode_mainid().c_str());
529 ui_app->hwacceleration =
530 strdup(application.app_info.hwacceleration().c_str());
531 ui_app->onboot = strdup("false");
532 ui_app->autorestart = strdup("false");
533 ui_app->component_type = strdup("uiapp");
534 ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
535 ui_app->screenreader = strdup("use-system-setting");
536 ui_app->recentimage = strdup("false");
537 ui_app->launchcondition = strdup("false");
538 ui_app->guestmode_visibility = strdup("true");
539 ui_app->permission_type = strdup("normal");
540 ui_app->support_ambient = strdup("false");
541 ui_app->package = strdup(manifest->package);
542 ui_app->support_disable = strdup(manifest->support_disable);
543 ui_app->splash_screen_display =
544 strdup(application.app_info.splash_screen_display().c_str());
545 manifest->application = g_list_append(manifest->application, ui_app);
546 if (bf::path(application.app_info.exec().c_str()).is_absolute())
547 ui_app->exec = strdup(application.app_info.exec().c_str());
549 ui_app->exec = strdup((context_->root_application_path.get()
550 / manifest->package / "bin"
551 / application.app_info.exec()).c_str());
554 if (!FillAppControl(ui_app, application.app_control))
556 if (!FillDataControl(ui_app, application.data_control))
558 if (!FillApplicationIconPaths(ui_app, application.app_icons))
560 if (!FillLabel(ui_app, application.label))
562 if (!FillImage(ui_app, application.app_images))
564 if (!FillMetadata(ui_app, application.meta_data))
566 if (!FillCategories(ui_app, application.categories))
568 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
570 if (!FillSplashScreen(ui_app, application.app_splashscreens))
576 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
577 auto watch_application_list =
578 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
579 parser_->GetManifestData(app_keys::kWatchApplicationKey));
580 if (!watch_application_list)
583 for (const auto& watch_application : watch_application_list->items) {
584 int package_support_mode_val = atoi(manifest->support_mode);
585 int app_support_mode_val = package_support_mode_val |
586 GetSupportModeVal(watch_application.app_info.support_mode());
588 application_x* watch_app =
589 static_cast<application_x*>(calloc(1, sizeof(application_x)));
590 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
592 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
593 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
595 watch_app->exec = strdup(
596 (context_->root_application_path.get()
597 / manifest->package / "bin" /
598 watch_application.app_info.exec()).c_str());
599 watch_app->nodisplay = strdup("true");
600 watch_app->multiple = strdup("false");
601 watch_app->type = strdup(watch_application.app_info.type().c_str());
602 watch_app->taskmanage = strdup("false");
603 watch_app->hwacceleration = strdup("default");
604 watch_app->screenreader = strdup("use-system-setting");
605 watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
606 watch_app->recentimage = strdup("false");
607 watch_app->launchcondition = strdup("false");
608 watch_app->indicatordisplay = strdup("true");
609 watch_app->effectimage_type = strdup("image");
610 watch_app->guestmode_visibility = strdup("true");
611 watch_app->permission_type = strdup("normal");
612 watch_app->component_type = strdup("watchapp");
613 watch_app->preload = strdup("false");
614 watch_app->submode = strdup("false");
615 watch_app->process_pool = strdup("false");
616 watch_app->autorestart = strdup("false");
617 watch_app->onboot = strdup("false");
618 watch_app->support_mode =
619 strdup((std::to_string(app_support_mode_val)).c_str());
620 watch_app->ui_gadget = strdup("false");
621 watch_app->launch_mode = strdup("single");
622 watch_app->support_ambient =
623 strdup(watch_application.app_info.ambient_support().c_str());
624 watch_app->package = strdup(manifest->package);
625 if (!watch_application.app_info.setup_appid().empty())
626 watch_app->setup_appid =
627 strdup(watch_application.app_info.setup_appid().c_str());
629 if (!FillLabel(watch_app, watch_application.label))
631 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
633 if (!FillMetadata(watch_app, watch_application.meta_data))
635 if (!FillCategories(watch_app, watch_application.categories))
637 if (!FillBackgroundCategoryInfo(watch_app,
638 watch_application.background_category))
640 manifest->application = g_list_append(manifest->application, watch_app);
645 bool StepParseManifest::CheckFeatures() {
647 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
648 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
653 FeatureValidator validator(feature_info->features());
654 if (!validator.Validate(&error)) {
655 LOG(ERROR) << "Feature validation error. " << error;
662 template <typename T>
663 bool StepParseManifest::FillAppControl(application_x* app,
664 const T& app_control_list) {
665 if (app_control_list.empty())
668 for (const auto& control : app_control_list) {
669 appcontrol_x* app_control =
670 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
671 app_control->operation = strdup(control.operation().c_str());
672 if (!control.mime().empty())
673 app_control->mime = strdup(control.mime().c_str());
674 if (!control.uri().empty())
675 app_control->uri = strdup(control.uri().c_str());
676 app->appcontrol = g_list_append(app->appcontrol, app_control);
681 template <typename T>
682 bool StepParseManifest::FillDataControl(application_x* app,
683 const T& data_control_list) {
684 if (data_control_list.empty())
687 for (const auto& control : data_control_list) {
688 datacontrol_x* data_control =
689 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
690 data_control->access = strdup(control.access().c_str());
691 data_control->providerid = strdup(control.providerid().c_str());
692 data_control->type = strdup(control.type().c_str());
693 app->datacontrol = g_list_append(app->datacontrol, data_control);
698 template <typename T>
699 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
700 const T& icons_info) {
701 for (auto& application_icon : icons_info.icons()) {
702 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
704 if (bf::path(application_icon.path()).is_absolute()) {
705 text = application_icon.path();
707 text = context_->root_application_path.get()
708 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
710 // NOTE: name is an attribute, but the xml writer uses it as text.
711 // This must be fixed in whole app-installer modules, including wgt.
712 // Current implementation is just for compatibility.
713 icon->text = strdup(text.c_str());
714 if (application_icon.lang().empty())
715 icon->lang = strdup(DEFAULT_LOCALE);
717 icon->lang = strdup(application_icon.lang().c_str());
719 if (!application_icon.dpi().empty())
720 icon->dpi = strdup(application_icon.dpi().c_str());
721 app->icon = g_list_append(app->icon, icon);
726 template <typename T>
727 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
728 if (label_list.empty())
731 for (const auto& control : label_list) {
733 static_cast<label_x*>(calloc(1, sizeof(label_x)));
734 // NOTE: name is an attribute, but the xml writer uses it as text.
735 // This must be fixed in whole app-installer modules, including wgt.
736 // Current implementation is just for compatibility.
737 label->text = strdup(control.text().c_str());
738 label->name = strdup(control.name().c_str());
739 label->lang = !control.xml_lang().empty() ?
740 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
741 app->label = g_list_append(app->label, label);
746 template <typename T>
747 bool StepParseManifest::FillMetadata(application_x* app,
748 const T& meta_data_list) {
749 if (meta_data_list.empty())
752 for (auto& meta : meta_data_list) {
753 metadata_x* metadata =
754 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
755 metadata->key = strdup(meta.key().c_str());
756 metadata->value = strdup(meta.val().c_str());
757 app->metadata = g_list_append(app->metadata, metadata);
759 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
764 template <typename T>
765 bool StepParseManifest::FillCategories(application_x* manifest,
766 const T& categories) {
767 for (auto& category : categories) {
768 manifest->category = g_list_append(manifest->category,
769 strdup(category.c_str()));
774 void StepParseManifest::AppendSplashScreen(application_x* app,
775 const std::string& src, const std::string& type, const std::string& dpi,
776 const std::string& orientation, const std::string& indicatordisplay,
777 const std::string& operation, const std::string& color_depth) {
778 splashscreen_x* splashscreen =
779 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
780 if (bf::path(src).is_absolute()) {
781 splashscreen->src = strdup(src.c_str());
783 bf::path full_path = context_->pkg_path.get() / src;
784 splashscreen->src = strdup(full_path.string().c_str());
786 if (src.substr(src.find_last_of(".") + 1) == "edj")
787 splashscreen->type = strdup("edj");
788 else if (type == "edj")
789 splashscreen->type = strdup("edj");
791 splashscreen->type = strdup("img");
793 splashscreen->dpi = strdup(dpi.c_str());
794 splashscreen->orientation = strdup(orientation.c_str());
795 if (!indicatordisplay.empty())
796 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
798 splashscreen->indicatordisplay = strdup("true");
799 if (operation == "launch_effect")
800 splashscreen->operation = strdup("launch-effect");
801 else if (!operation.empty())
802 splashscreen->operation = strdup(operation.c_str());
804 splashscreen->operation = strdup("launch-effect");
805 if (!color_depth.empty())
806 splashscreen->color_depth = strdup(color_depth.c_str());
808 splashscreen->color_depth = strdup("24");
809 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
812 template <typename T>
813 bool StepParseManifest::FillSplashScreen(application_x* app,
814 const T& splashscreens_info) {
815 for (auto& splash_screen : splashscreens_info.splashscreens()) {
817 if (context_->is_readonly_package.get())
818 src = splash_screen.src();
820 src = bf::path(context_->root_application_path.get()
821 / app->package / "shared" / "res" / splash_screen.src()).string();
823 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
824 splash_screen.orientation(), splash_screen.indicatordisplay(),
825 splash_screen.operation(), splash_screen.colordepth());
830 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
831 const std::string& key, const std::string& val) {
832 std::string operation;
833 if (key.find(kOperationEffectKey) != std::string::npos) {
834 boost::char_separator<char> sep("=");
835 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
836 auto iter = tokens.begin();
839 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
840 operation = std::string("launch-effect");
842 // not a metadata splashscreen
846 boost::char_separator<char> sep("=|");
847 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
848 auto iter = tokens.begin();
849 std::string portrait_src;
850 std::string landscape_src;
851 std::string indicatordisplay;
852 while (iter != tokens.end()) {
853 if (!(*iter).compare(kPortraitEffectImageValue)) {
855 portrait_src = *iter;
856 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
858 landscape_src = *iter;
859 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
861 indicatordisplay = *iter;
865 if (!portrait_src.empty())
866 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
867 indicatordisplay, operation, {});
868 if (!landscape_src.empty())
869 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
870 indicatordisplay, operation, {});
873 bool StepParseManifest::FillImage(application_x* app,
874 const tpk::parse::ApplicationImagesInfo& image_list) {
875 for (auto& app_image : image_list.images) {
877 static_cast<image_x*>(calloc(1, sizeof(image_x)));
878 const std::string& lang = app_image.lang();
880 image->lang = strdup(lang.c_str());
882 image->lang = strdup(DEFAULT_LOCALE);
883 if (!app_image.section().empty())
884 image->section = strdup(app_image.section().c_str());
885 app->image = g_list_append(app->image, image);
890 template <typename T>
891 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
892 const T& background_category_data_list) {
893 for (const auto& background_category : background_category_data_list) {
894 app->background_category = g_list_append(
895 app->background_category, strdup(background_category.value().c_str()));
901 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
902 if (manifest_location_ == ManifestLocation::INSTALLED) {
903 // recovery of tep value for installed package
904 std::string old_tep =
905 QueryTepPath(context_->pkgid.get(), context_->uid.get());
906 if (!old_tep.empty())
907 manifest->tep_name = strdup(old_tep.c_str());
909 // recovery of zip mount file for installed package
910 std::string zip_mount_file =
911 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
912 if (!zip_mount_file.empty())
913 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
916 // in case of hybrid package, main app is already set by wgt-backend
917 application_x* mainapp = nullptr;
918 if (!context_->cross_app_rules.get()) {
920 for (const auto& app : GListRange<application_x*>(manifest->application)) {
921 if (!strcmp(app->mainapp, "true")) {
926 if (mainapp == nullptr)
927 mainapp = reinterpret_cast<application_x*>(
928 g_list_first(manifest->application)->data);
929 free(mainapp->mainapp);
930 mainapp->mainapp = strdup("true");
931 manifest->mainapp_id = strdup(mainapp->appid);
934 // mark mainapp=false at other apps
935 for (auto& app : GListRange<application_x*>(manifest->application)) {
939 app->mainapp = strdup("false");
944 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
945 if (!FillPackageInfo(manifest))
947 if (!FillInstallationInfo(manifest))
949 if (!FillUIApplication(manifest))
951 if (!FillServiceApplication(manifest))
953 if (!FillWidgetApplication(manifest))
955 if (!FillWatchApplication(manifest))
957 if (!FillPrivileges(manifest))
959 if (!FillAuthorInfo(manifest))
961 if (!FillDescriptionInfo(manifest))
963 if (!FillExtraInfo(manifest))
968 Step::Status StepParseManifest::process() {
969 if (context_->force_clean_from_db.get())
970 return Step::Status::OK;
971 if (!LocateConfigFile()) {
972 // continue if this is recovery, manifest file may never been created
973 if (manifest_location_ == ManifestLocation::RECOVERY) {
974 LOG(DEBUG) << "Manifest for recovery not found";
975 return Step::Status::OK;
977 LOG(ERROR) << "No manifest file exists";
978 return Step::Status::MANIFEST_NOT_FOUND;
980 parser_.reset(new tpk::parse::TPKConfigParser());
981 if (!parser_->ParseManifest(path_)) {
982 if (manifest_location_ == ManifestLocation::RECOVERY) {
983 LOG(DEBUG) << "Manifest for recovery is invalid";
985 return Step::Status::OK;
987 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
988 return Step::Status::PARSE_ERROR;
991 // Copy data from ManifestData to InstallerContext
992 std::shared_ptr<const tpk::parse::PackageInfo> info =
993 std::static_pointer_cast<const tpk::parse::PackageInfo>(
994 parser_->GetManifestData(app_keys::kManifestKey));
996 context_->pkgid.set(info->package());
997 context_->pkg_path.set(
998 context_->root_application_path.get() / context_->pkgid.get());
1000 manifest_x* manifest =
1001 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
1003 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
1004 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
1005 << parser_->GetErrorMessage();
1006 return Step::Status::PARSE_ERROR;
1009 // write pkgid for recovery file
1010 if (context_->recovery_info.get().recovery_file) {
1011 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1012 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1015 LOG(DEBUG) << "Parsed package id: " << info->package();
1017 switch (store_location_) {
1018 case StoreLocation::NORMAL:
1019 context_->manifest_data.set(manifest);
1021 case StoreLocation::BACKUP:
1022 context_->old_manifest_data.set(manifest);
1025 LOG(ERROR) << "Unknown store location for parsed data";
1026 return Step::Status::ERROR;
1028 return Step::Status::OK;
1031 } // namespace configuration
1032 } // namespace common_installer