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.portrait_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 (!FillLabel(watch_app, watch_application.label))
627 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
629 if (!FillMetadata(watch_app, watch_application.meta_data))
631 if (!FillCategories(watch_app, watch_application.categories))
633 if (!FillBackgroundCategoryInfo(watch_app,
634 watch_application.background_category))
636 manifest->application = g_list_append(manifest->application, watch_app);
641 bool StepParseManifest::CheckFeatures() {
643 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
644 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
649 FeatureValidator validator(feature_info->features());
650 if (!validator.Validate(&error)) {
651 LOG(ERROR) << "Feature validation error. " << error;
658 template <typename T>
659 bool StepParseManifest::FillAppControl(application_x* app,
660 const T& app_control_list) {
661 if (app_control_list.empty())
664 for (const auto& control : app_control_list) {
665 appcontrol_x* app_control =
666 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
667 app_control->operation = strdup(control.operation().c_str());
668 if (!control.mime().empty())
669 app_control->mime = strdup(control.mime().c_str());
670 if (!control.uri().empty())
671 app_control->uri = strdup(control.uri().c_str());
672 app->appcontrol = g_list_append(app->appcontrol, app_control);
677 template <typename T>
678 bool StepParseManifest::FillDataControl(application_x* app,
679 const T& data_control_list) {
680 if (data_control_list.empty())
683 for (const auto& control : data_control_list) {
684 datacontrol_x* data_control =
685 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
686 data_control->access = strdup(control.access().c_str());
687 data_control->providerid = strdup(control.providerid().c_str());
688 data_control->type = strdup(control.type().c_str());
689 app->datacontrol = g_list_append(app->datacontrol, data_control);
694 template <typename T>
695 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
696 const T& icons_info) {
697 for (auto& application_icon : icons_info.icons()) {
698 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
700 if (bf::path(application_icon.path()).is_absolute()) {
701 text = application_icon.path();
703 text = context_->root_application_path.get()
704 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
706 // NOTE: name is an attribute, but the xml writer uses it as text.
707 // This must be fixed in whole app-installer modules, including wgt.
708 // Current implementation is just for compatibility.
709 icon->text = strdup(text.c_str());
710 if (application_icon.lang().empty())
711 icon->lang = strdup(DEFAULT_LOCALE);
713 icon->lang = strdup(application_icon.lang().c_str());
715 if (!application_icon.dpi().empty())
716 icon->dpi = strdup(application_icon.dpi().c_str());
717 app->icon = g_list_append(app->icon, icon);
722 template <typename T>
723 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
724 if (label_list.empty())
727 for (const auto& control : label_list) {
729 static_cast<label_x*>(calloc(1, sizeof(label_x)));
730 // NOTE: name is an attribute, but the xml writer uses it as text.
731 // This must be fixed in whole app-installer modules, including wgt.
732 // Current implementation is just for compatibility.
733 label->text = strdup(control.text().c_str());
734 label->name = strdup(control.name().c_str());
735 label->lang = !control.xml_lang().empty() ?
736 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
737 app->label = g_list_append(app->label, label);
742 template <typename T>
743 bool StepParseManifest::FillMetadata(application_x* app,
744 const T& meta_data_list) {
745 if (meta_data_list.empty())
748 for (auto& meta : meta_data_list) {
749 metadata_x* metadata =
750 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
751 metadata->key = strdup(meta.key().c_str());
752 metadata->value = strdup(meta.val().c_str());
753 app->metadata = g_list_append(app->metadata, metadata);
755 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
760 template <typename T>
761 bool StepParseManifest::FillCategories(application_x* manifest,
762 const T& categories) {
763 for (auto& category : categories) {
764 manifest->category = g_list_append(manifest->category,
765 strdup(category.c_str()));
770 void StepParseManifest::AppendSplashScreen(application_x* app,
771 const std::string& src, const std::string& type, const std::string& dpi,
772 const std::string& orientation, const std::string& indicatordisplay,
773 const std::string& operation, const std::string& color_depth) {
774 splashscreen_x* splashscreen =
775 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
776 if (bf::path(src).is_absolute()) {
777 splashscreen->src = strdup(src.c_str());
779 bf::path full_path = context_->pkg_path.get() / src;
780 splashscreen->src = strdup(full_path.string().c_str());
782 if (src.substr(src.find_last_of(".") + 1) == "edj")
783 splashscreen->type = strdup("edj");
784 else if (type == "edj")
785 splashscreen->type = strdup("edj");
787 splashscreen->type = strdup("img");
789 splashscreen->dpi = strdup(dpi.c_str());
790 splashscreen->orientation = strdup(orientation.c_str());
791 if (!indicatordisplay.empty())
792 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
794 splashscreen->indicatordisplay = strdup("true");
795 if (operation == "launch_effect")
796 splashscreen->operation = strdup("launch-effect");
797 else if (!operation.empty())
798 splashscreen->operation = strdup(operation.c_str());
800 splashscreen->operation = strdup("launch-effect");
801 if (!color_depth.empty())
802 splashscreen->color_depth = strdup(color_depth.c_str());
804 splashscreen->color_depth = strdup("24");
805 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
808 template <typename T>
809 bool StepParseManifest::FillSplashScreen(application_x* app,
810 const T& splashscreens_info) {
811 for (auto& splash_screen : splashscreens_info.splashscreens()) {
813 if (context_->is_readonly_package.get())
814 src = splash_screen.src();
816 src = bf::path(context_->root_application_path.get()
817 / app->package / "shared" / "res" / splash_screen.src()).string();
819 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
820 splash_screen.orientation(), splash_screen.indicatordisplay(),
821 splash_screen.operation(), splash_screen.colordepth());
826 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
827 const std::string& key, const std::string& val) {
828 std::string operation;
829 if (key.find(kOperationEffectKey) != std::string::npos) {
830 boost::char_separator<char> sep("=");
831 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
832 auto iter = tokens.begin();
835 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
836 operation = std::string("launch-effect");
838 // not a metadata splashscreen
842 boost::char_separator<char> sep("=|");
843 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
844 auto iter = tokens.begin();
845 std::string portrait_src;
846 std::string landscape_src;
847 std::string indicatordisplay;
848 while (iter != tokens.end()) {
849 if (!(*iter).compare(kPortraitEffectImageValue)) {
851 portrait_src = *iter;
852 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
854 landscape_src = *iter;
855 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
857 indicatordisplay = *iter;
861 if (!portrait_src.empty())
862 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
863 indicatordisplay, operation, {});
864 if (!landscape_src.empty())
865 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
866 indicatordisplay, operation, {});
869 bool StepParseManifest::FillImage(application_x* app,
870 const tpk::parse::ApplicationImagesInfo& image_list) {
871 for (auto& app_image : image_list.images) {
873 static_cast<image_x*>(calloc(1, sizeof(image_x)));
874 const std::string& lang = app_image.lang();
876 image->lang = strdup(lang.c_str());
878 image->lang = strdup(DEFAULT_LOCALE);
879 if (!app_image.section().empty())
880 image->section = strdup(app_image.section().c_str());
881 app->image = g_list_append(app->image, image);
886 template <typename T>
887 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
888 const T& background_category_data_list) {
889 for (const auto& background_category : background_category_data_list) {
890 app->background_category = g_list_append(
891 app->background_category, strdup(background_category.value().c_str()));
897 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
898 if (manifest_location_ == ManifestLocation::INSTALLED) {
899 // recovery of tep value for installed package
900 std::string old_tep =
901 QueryTepPath(context_->pkgid.get(), context_->uid.get());
902 if (!old_tep.empty())
903 manifest->tep_name = strdup(old_tep.c_str());
905 // recovery of zip mount file for installed package
906 std::string zip_mount_file =
907 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
908 if (!zip_mount_file.empty())
909 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
912 // in case of hybrid package, main app is already set by wgt-backend
913 application_x* mainapp = nullptr;
914 if (!context_->cross_app_rules.get()) {
916 for (const auto& app : GListRange<application_x*>(manifest->application)) {
917 if (!strcmp(app->mainapp, "true")) {
922 if (mainapp == nullptr)
923 mainapp = reinterpret_cast<application_x*>(
924 g_list_first(manifest->application)->data);
925 free(mainapp->mainapp);
926 mainapp->mainapp = strdup("true");
927 manifest->mainapp_id = strdup(mainapp->appid);
930 // mark mainapp=false at other apps
931 for (auto& app : GListRange<application_x*>(manifest->application)) {
935 app->mainapp = strdup("false");
940 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
941 if (!FillPackageInfo(manifest))
943 if (!FillInstallationInfo(manifest))
945 if (!FillUIApplication(manifest))
947 if (!FillServiceApplication(manifest))
949 if (!FillWidgetApplication(manifest))
951 if (!FillWatchApplication(manifest))
953 if (!FillPrivileges(manifest))
955 if (!FillAuthorInfo(manifest))
957 if (!FillDescriptionInfo(manifest))
959 if (!FillExtraInfo(manifest))
964 Step::Status StepParseManifest::process() {
965 if (context_->force_clean_from_db.get())
966 return Step::Status::OK;
967 if (!LocateConfigFile()) {
968 // continue if this is recovery, manifest file may never been created
969 if (manifest_location_ == ManifestLocation::RECOVERY) {
970 LOG(DEBUG) << "Manifest for recovery not found";
971 return Step::Status::OK;
973 LOG(ERROR) << "No manifest file exists";
974 return Step::Status::MANIFEST_NOT_FOUND;
976 parser_.reset(new tpk::parse::TPKConfigParser());
977 if (!parser_->ParseManifest(path_)) {
978 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
979 return Step::Status::PARSE_ERROR;
982 // Copy data from ManifestData to InstallerContext
983 std::shared_ptr<const tpk::parse::PackageInfo> info =
984 std::static_pointer_cast<const tpk::parse::PackageInfo>(
985 parser_->GetManifestData(app_keys::kManifestKey));
987 context_->pkgid.set(info->package());
988 context_->pkg_path.set(
989 context_->root_application_path.get() / context_->pkgid.get());
991 manifest_x* manifest =
992 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
994 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
995 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
996 << parser_->GetErrorMessage();
997 return Step::Status::PARSE_ERROR;
1000 // write pkgid for recovery file
1001 if (context_->recovery_info.get().recovery_file) {
1002 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1003 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1006 LOG(DEBUG) << "Parsed package id: " << info->package();
1008 switch (store_location_) {
1009 case StoreLocation::NORMAL:
1010 context_->manifest_data.set(manifest);
1012 case StoreLocation::BACKUP:
1013 context_->old_manifest_data.set(manifest);
1016 LOG(ERROR) << "Unknown store location for parsed data";
1017 return Step::Status::ERROR;
1019 return Step::Status::OK;
1022 } // namespace configuration
1023 } // namespace common_installer