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 manifest->application = g_list_append(manifest->application, widget_app);
391 if (bf::path(application.app_info.exec().c_str()).is_absolute())
392 widget_app->exec = strdup(application.app_info.exec().c_str());
394 widget_app->exec = strdup((context_->root_application_path.get()
395 / manifest->package / "bin"
396 / application.app_info.exec()).c_str());
398 if (!FillApplicationIconPaths(widget_app, application.app_icons))
400 if (!FillLabel(widget_app, application.label))
402 if (!FillImage(widget_app, application.app_images))
404 if (!FillCategories(widget_app, application.categories))
406 if (!FillMetadata(widget_app, application.meta_data))
412 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
413 auto service_application_list =
414 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
415 parser_->GetManifestData(app_keys::kServiceApplicationKey));
416 if (!service_application_list)
419 for (const auto& application : service_application_list->items) {
420 int package_support_mode_val = atoi(manifest->support_mode);
421 int app_support_mode_val = package_support_mode_val |
422 GetSupportModeVal(application.app_info.support_mode());
424 application_x* service_app =
425 static_cast<application_x*>(calloc(1, sizeof(application_x)));
426 service_app->appid = strdup(application.app_info.appid().c_str());
427 service_app->multiple = strdup(application.app_info.multiple().c_str());
428 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
429 service_app->support_mode =
430 strdup((std::to_string(app_support_mode_val)).c_str());
431 service_app->autorestart =
432 strdup(application.app_info.auto_restart().c_str());
433 service_app->onboot = strdup(application.app_info.on_boot().c_str());
434 service_app->type = strdup(application.app_info.type().c_str());
435 service_app->process_pool =
436 strdup(application.app_info.process_pool().c_str());
437 service_app->component_type = strdup("svcapp");
438 service_app->mainapp = strdup(application.app_info.mainapp().c_str());
439 service_app->nodisplay = strdup("true");
440 service_app->hwacceleration = strdup("default");
441 service_app->screenreader = strdup("use-system-setting");
442 service_app->recentimage = strdup("false");
443 service_app->launchcondition = strdup("false");
444 service_app->indicatordisplay = strdup("true");
445 service_app->effectimage_type = strdup("image");
446 service_app->guestmode_visibility = strdup("true");
447 service_app->permission_type = strdup("normal");
448 service_app->submode = strdup("false");
449 service_app->process_pool = strdup("false");
450 service_app->support_ambient = strdup("false");
451 service_app->package = strdup(manifest->package);
452 service_app->support_disable = strdup(manifest->support_disable);
453 manifest->application = g_list_append(manifest->application, service_app);
454 if (bf::path(application.app_info.exec().c_str()).is_absolute())
455 service_app->exec = strdup(application.app_info.exec().c_str());
457 service_app->exec = strdup((context_->root_application_path.get()
458 / manifest->package / "bin"
459 / application.app_info.exec()).c_str());
461 if (!FillAppControl(service_app, application.app_control))
463 if (!FillDataControl(service_app, application.data_control))
465 if (!FillApplicationIconPaths(service_app, application.app_icons))
467 if (!FillLabel(service_app, application.label))
469 if (!FillMetadata(service_app, application.meta_data))
471 if (!FillCategories(service_app, application.categories))
473 if (!FillBackgroundCategoryInfo(service_app,
474 application.background_category))
480 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
481 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
482 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
483 parser_->GetManifestData(app_keys::kUIApplicationKey));
484 if (!ui_application_list)
487 for (const auto& application : ui_application_list->items) {
488 int package_support_mode_val = atoi(manifest->support_mode);
489 int app_support_mode_val = package_support_mode_val |
490 GetSupportModeVal(application.app_info.support_mode());
492 application_x* ui_app =
493 static_cast<application_x*>(calloc(1, sizeof(application_x)));
494 ui_app->appid = strdup(application.app_info.appid().c_str());
495 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
496 ui_app->multiple = strdup(application.app_info.multiple().c_str());
497 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
498 ui_app->support_mode =
499 strdup((std::to_string(app_support_mode_val)).c_str());
500 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
501 ui_app->type = strdup(application.app_info.type().c_str());
502 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
503 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
504 ui_app->submode = strdup(application.app_info.submode().c_str());
505 if (!application.app_info.indicator_display().empty())
506 ui_app->indicatordisplay =
507 strdup(application.app_info.indicator_display().c_str());
508 if (!application.app_info.effectimage_type().empty())
509 ui_app->effectimage_type =
510 strdup(application.app_info.effectimage_type().c_str());
511 if (!application.app_info.portrait_image().empty()) {
512 ui_app->portraitimg =
513 strdup(application.app_info.portrait_image().c_str());
514 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
515 application.app_info.effectimage_type(), {}, kPortraitOrientation,
516 application.app_info.indicator_display(), {}, {});
518 if (!application.app_info.landscape_image().empty()) {
519 ui_app->landscapeimg =
520 strdup(application.app_info.landscape_image().c_str());
521 AppendSplashScreen(ui_app, application.app_info.portrait_image(),
522 application.app_info.effectimage_type(), {}, kLandscapeOrientation,
523 application.app_info.indicator_display(), {}, {});
525 ui_app->submode_mainid =
526 strdup(application.app_info.submode_mainid().c_str());
527 ui_app->hwacceleration =
528 strdup(application.app_info.hwacceleration().c_str());
529 ui_app->onboot = strdup("false");
530 ui_app->autorestart = strdup("false");
531 ui_app->component_type = strdup("uiapp");
532 ui_app->mainapp = strdup(application.app_info.mainapp().c_str());
533 ui_app->screenreader = strdup("use-system-setting");
534 ui_app->recentimage = strdup("false");
535 ui_app->launchcondition = strdup("false");
536 ui_app->guestmode_visibility = strdup("true");
537 ui_app->permission_type = strdup("normal");
538 ui_app->support_ambient = strdup("false");
539 ui_app->package = strdup(manifest->package);
540 ui_app->support_disable = strdup(manifest->support_disable);
541 ui_app->splash_screen_display =
542 strdup(application.app_info.splash_screen_display().c_str());
543 manifest->application = g_list_append(manifest->application, ui_app);
544 if (bf::path(application.app_info.exec().c_str()).is_absolute())
545 ui_app->exec = strdup(application.app_info.exec().c_str());
547 ui_app->exec = strdup((context_->root_application_path.get()
548 / manifest->package / "bin"
549 / application.app_info.exec()).c_str());
552 if (!FillAppControl(ui_app, application.app_control))
554 if (!FillDataControl(ui_app, application.data_control))
556 if (!FillApplicationIconPaths(ui_app, application.app_icons))
558 if (!FillLabel(ui_app, application.label))
560 if (!FillImage(ui_app, application.app_images))
562 if (!FillMetadata(ui_app, application.meta_data))
564 if (!FillCategories(ui_app, application.categories))
566 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
568 if (!FillSplashScreen(ui_app, application.app_splashscreens))
574 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
575 auto watch_application_list =
576 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
577 parser_->GetManifestData(app_keys::kWatchApplicationKey));
578 if (!watch_application_list)
581 for (const auto& watch_application : watch_application_list->items) {
582 int package_support_mode_val = atoi(manifest->support_mode);
583 int app_support_mode_val = package_support_mode_val |
584 GetSupportModeVal(watch_application.app_info.support_mode());
586 application_x* watch_app =
587 static_cast<application_x*>(calloc(1, sizeof(application_x)));
588 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
590 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
591 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
593 watch_app->exec = strdup(
594 (context_->root_application_path.get()
595 / manifest->package / "bin" /
596 watch_application.app_info.exec()).c_str());
597 watch_app->nodisplay = strdup("true");
598 watch_app->multiple = strdup("false");
599 watch_app->type = strdup(watch_application.app_info.type().c_str());
600 watch_app->taskmanage = strdup("false");
601 watch_app->hwacceleration = strdup("default");
602 watch_app->screenreader = strdup("use-system-setting");
603 watch_app->mainapp = strdup(watch_application.app_info.mainapp().c_str());
604 watch_app->recentimage = strdup("false");
605 watch_app->launchcondition = strdup("false");
606 watch_app->indicatordisplay = strdup("true");
607 watch_app->effectimage_type = strdup("image");
608 watch_app->guestmode_visibility = strdup("true");
609 watch_app->permission_type = strdup("normal");
610 watch_app->component_type = strdup("watchapp");
611 watch_app->preload = strdup("false");
612 watch_app->submode = strdup("false");
613 watch_app->process_pool = strdup("false");
614 watch_app->autorestart = strdup("false");
615 watch_app->onboot = strdup("false");
616 watch_app->support_mode =
617 strdup((std::to_string(app_support_mode_val)).c_str());
618 watch_app->ui_gadget = strdup("false");
619 watch_app->launch_mode = strdup("single");
620 watch_app->support_ambient =
621 strdup(watch_application.app_info.ambient_support().c_str());
622 watch_app->package = strdup(manifest->package);
623 if (!FillLabel(watch_app, watch_application.label))
625 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
627 if (!FillMetadata(watch_app, watch_application.meta_data))
629 if (!FillCategories(watch_app, watch_application.categories))
631 if (!FillBackgroundCategoryInfo(watch_app,
632 watch_application.background_category))
634 manifest->application = g_list_append(manifest->application, watch_app);
639 bool StepParseManifest::CheckFeatures() {
641 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
642 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
647 FeatureValidator validator(feature_info->features());
648 if (!validator.Validate(&error)) {
649 LOG(ERROR) << "Feature validation error. " << error;
656 template <typename T>
657 bool StepParseManifest::FillAppControl(application_x* app,
658 const T& app_control_list) {
659 if (app_control_list.empty())
662 for (const auto& control : app_control_list) {
663 appcontrol_x* app_control =
664 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
665 app_control->operation = strdup(control.operation().c_str());
666 if (!control.mime().empty())
667 app_control->mime = strdup(control.mime().c_str());
668 if (!control.uri().empty())
669 app_control->uri = strdup(control.uri().c_str());
670 app->appcontrol = g_list_append(app->appcontrol, app_control);
675 template <typename T>
676 bool StepParseManifest::FillDataControl(application_x* app,
677 const T& data_control_list) {
678 if (data_control_list.empty())
681 for (const auto& control : data_control_list) {
682 datacontrol_x* data_control =
683 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
684 data_control->access = strdup(control.access().c_str());
685 data_control->providerid = strdup(control.providerid().c_str());
686 data_control->type = strdup(control.type().c_str());
687 app->datacontrol = g_list_append(app->datacontrol, data_control);
692 template <typename T>
693 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
694 const T& icons_info) {
695 for (auto& application_icon : icons_info.icons()) {
696 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
698 if (bf::path(application_icon.path()).is_absolute()) {
699 text = application_icon.path();
701 text = context_->root_application_path.get()
702 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
704 // NOTE: name is an attribute, but the xml writer uses it as text.
705 // This must be fixed in whole app-installer modules, including wgt.
706 // Current implementation is just for compatibility.
707 icon->text = strdup(text.c_str());
708 if (application_icon.lang().empty())
709 icon->lang = strdup(DEFAULT_LOCALE);
711 icon->lang = strdup(application_icon.lang().c_str());
713 if (!application_icon.dpi().empty())
714 icon->dpi = strdup(application_icon.dpi().c_str());
715 app->icon = g_list_append(app->icon, icon);
720 template <typename T>
721 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
722 if (label_list.empty())
725 for (const auto& control : label_list) {
727 static_cast<label_x*>(calloc(1, sizeof(label_x)));
728 // NOTE: name is an attribute, but the xml writer uses it as text.
729 // This must be fixed in whole app-installer modules, including wgt.
730 // Current implementation is just for compatibility.
731 label->text = strdup(control.text().c_str());
732 label->name = strdup(control.name().c_str());
733 label->lang = !control.xml_lang().empty() ?
734 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
735 app->label = g_list_append(app->label, label);
740 template <typename T>
741 bool StepParseManifest::FillMetadata(application_x* app,
742 const T& meta_data_list) {
743 if (meta_data_list.empty())
746 for (auto& meta : meta_data_list) {
747 metadata_x* metadata =
748 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
749 metadata->key = strdup(meta.key().c_str());
750 metadata->value = strdup(meta.val().c_str());
751 app->metadata = g_list_append(app->metadata, metadata);
753 GetLegacySplashScreenFromMetadata(app, meta.key(), meta.val());
758 template <typename T>
759 bool StepParseManifest::FillCategories(application_x* manifest,
760 const T& categories) {
761 for (auto& category : categories) {
762 manifest->category = g_list_append(manifest->category,
763 strdup(category.c_str()));
768 void StepParseManifest::AppendSplashScreen(application_x* app,
769 const std::string& src, const std::string& type, const std::string& dpi,
770 const std::string& orientation, const std::string& indicatordisplay,
771 const std::string& operation, const std::string& color_depth) {
772 splashscreen_x* splashscreen =
773 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
774 if (bf::path(src).is_absolute()) {
775 splashscreen->src = strdup(src.c_str());
777 bf::path full_path = context_->pkg_path.get() / src;
778 splashscreen->src = strdup(full_path.string().c_str());
780 if (src.substr(src.find_last_of(".") + 1) == "edj")
781 splashscreen->type = strdup("edj");
782 else if (type == "edj")
783 splashscreen->type = strdup("edj");
785 splashscreen->type = strdup("img");
787 splashscreen->dpi = strdup(dpi.c_str());
788 splashscreen->orientation = strdup(orientation.c_str());
789 if (!indicatordisplay.empty())
790 splashscreen->indicatordisplay = strdup(indicatordisplay.c_str());
792 splashscreen->indicatordisplay = strdup("true");
793 if (operation == "launch_effect")
794 splashscreen->operation = strdup("launch-effect");
795 else if (!operation.empty())
796 splashscreen->operation = strdup(operation.c_str());
798 splashscreen->operation = strdup("launch-effect");
799 if (!color_depth.empty())
800 splashscreen->color_depth = strdup(color_depth.c_str());
802 splashscreen->color_depth = strdup("24");
803 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
806 template <typename T>
807 bool StepParseManifest::FillSplashScreen(application_x* app,
808 const T& splashscreens_info) {
809 for (auto& splash_screen : splashscreens_info.splashscreens()) {
811 if (context_->is_readonly_package.get())
812 src = splash_screen.src();
814 src = bf::path(context_->root_application_path.get()
815 / app->package / "shared" / "res" / splash_screen.src()).string();
817 AppendSplashScreen(app, src, splash_screen.type(), splash_screen.dpi(),
818 splash_screen.orientation(), splash_screen.indicatordisplay(),
819 splash_screen.operation(), splash_screen.colordepth());
824 void StepParseManifest::GetLegacySplashScreenFromMetadata(application_x* app,
825 const std::string& key, const std::string& val) {
826 std::string operation;
827 if (key.find(kOperationEffectKey) != std::string::npos) {
828 boost::char_separator<char> sep("=");
829 boost::tokenizer<boost::char_separator<char>> tokens(key, sep);
830 auto iter = tokens.begin();
833 } else if (key.find(kLaunchEffectKey) != std::string::npos) {
834 operation = std::string("launch-effect");
836 // not a metadata splashscreen
840 boost::char_separator<char> sep("=|");
841 boost::tokenizer<boost::char_separator<char>> tokens(val, sep);
842 auto iter = tokens.begin();
843 std::string portrait_src;
844 std::string landscape_src;
845 std::string indicatordisplay;
846 while (iter != tokens.end()) {
847 if (!(*iter).compare(kPortraitEffectImageValue)) {
849 portrait_src = *iter;
850 } else if (!(*iter).compare(kLandscapeEffectImageValue)) {
852 landscape_src = *iter;
853 } else if (!(*iter).compare(kIndicatorDisplayValue)) {
855 indicatordisplay = *iter;
859 if (!portrait_src.empty())
860 AppendSplashScreen(app, portrait_src, {}, {}, kPortraitOrientation,
861 indicatordisplay, operation, {});
862 if (!landscape_src.empty())
863 AppendSplashScreen(app, landscape_src, {}, {}, kLandscapeOrientation,
864 indicatordisplay, operation, {});
867 bool StepParseManifest::FillImage(application_x* app,
868 const tpk::parse::ApplicationImagesInfo& image_list) {
869 for (auto& app_image : image_list.images) {
871 static_cast<image_x*>(calloc(1, sizeof(image_x)));
872 const std::string& lang = app_image.lang();
874 image->lang = strdup(lang.c_str());
876 image->lang = strdup(DEFAULT_LOCALE);
877 if (!app_image.section().empty())
878 image->section = strdup(app_image.section().c_str());
879 app->image = g_list_append(app->image, image);
884 template <typename T>
885 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
886 const T& background_category_data_list) {
887 for (const auto& background_category : background_category_data_list) {
888 app->background_category = g_list_append(
889 app->background_category, strdup(background_category.value().c_str()));
895 bool StepParseManifest::FillExtraInfo(manifest_x* manifest) {
896 if (manifest_location_ == ManifestLocation::INSTALLED) {
897 // recovery of tep value for installed package
898 std::string old_tep =
899 QueryTepPath(context_->pkgid.get(), context_->uid.get());
900 if (!old_tep.empty())
901 manifest->tep_name = strdup(old_tep.c_str());
903 // recovery of zip mount file for installed package
904 std::string zip_mount_file =
905 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
906 if (!zip_mount_file.empty())
907 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
910 // in case of hybrid package, main app is already set by wgt-backend
911 application_x* mainapp = nullptr;
912 if (!context_->cross_app_rules.get()) {
914 for (const auto& app : GListRange<application_x*>(manifest->application)) {
915 if (!strcmp(app->mainapp, "true")) {
920 if (mainapp == nullptr)
921 mainapp = reinterpret_cast<application_x*>(
922 g_list_first(manifest->application)->data);
923 free(mainapp->mainapp);
924 mainapp->mainapp = strdup("true");
925 manifest->mainapp_id = strdup(mainapp->appid);
928 // mark mainapp=false at other apps
929 for (auto& app : GListRange<application_x*>(manifest->application)) {
933 app->mainapp = strdup("false");
938 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
939 if (!FillPackageInfo(manifest))
941 if (!FillInstallationInfo(manifest))
943 if (!FillUIApplication(manifest))
945 if (!FillServiceApplication(manifest))
947 if (!FillWidgetApplication(manifest))
949 if (!FillWatchApplication(manifest))
951 if (!FillPrivileges(manifest))
953 if (!FillAuthorInfo(manifest))
955 if (!FillDescriptionInfo(manifest))
957 if (!FillExtraInfo(manifest))
962 Step::Status StepParseManifest::process() {
963 if (context_->force_clean_from_db.get())
964 return Step::Status::OK;
965 if (!LocateConfigFile()) {
966 // continue if this is recovery, manifest file may never been created
967 if (manifest_location_ == ManifestLocation::RECOVERY) {
968 LOG(DEBUG) << "Manifest for recovery not found";
969 return Step::Status::OK;
971 LOG(ERROR) << "No manifest file exists";
972 return Step::Status::MANIFEST_NOT_FOUND;
974 parser_.reset(new tpk::parse::TPKConfigParser());
975 if (!parser_->ParseManifest(path_)) {
976 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
977 return Step::Status::PARSE_ERROR;
980 // Copy data from ManifestData to InstallerContext
981 std::shared_ptr<const tpk::parse::PackageInfo> info =
982 std::static_pointer_cast<const tpk::parse::PackageInfo>(
983 parser_->GetManifestData(app_keys::kManifestKey));
985 context_->pkgid.set(info->package());
986 context_->pkg_path.set(
987 context_->root_application_path.get() / context_->pkgid.get());
989 manifest_x* manifest =
990 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
992 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
993 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
994 << parser_->GetErrorMessage();
995 return Step::Status::PARSE_ERROR;
998 // write pkgid for recovery file
999 if (context_->recovery_info.get().recovery_file) {
1000 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
1001 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
1004 LOG(DEBUG) << "Parsed package id: " << info->package();
1006 switch (store_location_) {
1007 case StoreLocation::NORMAL:
1008 context_->manifest_data.set(manifest);
1010 case StoreLocation::BACKUP:
1011 context_->old_manifest_data.set(manifest);
1014 LOG(ERROR) << "Unknown store location for parsed data";
1015 return Step::Status::ERROR;
1017 return Step::Status::OK;
1020 } // namespace configuration
1021 } // namespace common_installer