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 <pkgmgr/pkgmgr_parser.h>
8 #include <pkgmgr-info.h>
10 #include <tpk_manifest_handlers/account_handler.h>
11 #include <tpk_manifest_handlers/application_manifest_constants.h>
12 #include <tpk_manifest_handlers/author_handler.h>
13 #include <tpk_manifest_handlers/description_handler.h>
14 #include <tpk_manifest_handlers/feature_handler.h>
15 #include <tpk_manifest_handlers/package_handler.h>
16 #include <tpk_manifest_handlers/privileges_handler.h>
17 #include <tpk_manifest_handlers/profile_handler.h>
18 #include <tpk_manifest_handlers/service_application_handler.h>
19 #include <tpk_manifest_handlers/shortcut_handler.h>
20 #include <tpk_manifest_handlers/ui_application_handler.h>
21 #include <tpk_manifest_handlers/watch_application_handler.h>
22 #include <tpk_manifest_handlers/widget_application_handler.h>
30 #include <type_traits>
34 #include "common/app_installer.h"
35 #include "common/feature_validator.h"
36 #include "common/installer_context.h"
37 #include "common/paths.h"
38 #include "common/pkgmgr_registration.h"
39 #include "common/pkgmgr_query.h"
40 #include "common/step/step.h"
41 #include "common/utils/glist_range.h"
43 namespace app_keys = tpk::application_keys;
44 namespace bf = boost::filesystem;
48 const char kManifestFileName[] = "tizen-manifest.xml";
49 const char kInstalledInternally[] = "installed_internal";
53 namespace common_installer {
54 namespace configuration {
56 StepParseManifest::StepParseManifest(
57 InstallerContext* context, ManifestLocation manifest_location,
58 StoreLocation store_location)
60 manifest_location_(manifest_location),
61 store_location_(store_location) {
64 Step::Status StepParseManifest::precheck() {
65 switch (manifest_location_) {
66 case ManifestLocation::RECOVERY:
67 case ManifestLocation::INSTALLED:
68 if (context_->pkgid.get().empty()) {
69 LOG(ERROR) << "Package id is not set";
70 return Status::INVALID_VALUE;
73 case ManifestLocation::PACKAGE:
74 if (context_->unpacked_dir_path.get().empty()) {
75 LOG(ERROR) << "Unpacked directory doesn't exist";
76 return Status::INVALID_VALUE;
80 LOG(ERROR) << "Unknown manifest location";
81 return Status::INVALID_VALUE;
86 bool StepParseManifest::LocateConfigFile() {
87 boost::filesystem::path manifest;
88 switch (manifest_location_) {
89 case ManifestLocation::RECOVERY: {
90 context_->pkg_path.set(
91 context_->root_application_path.get() / context_->pkgid.get());
92 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
93 context_->pkg_path.get()) / kManifestFileName;
94 bf::path in_package_path = context_->pkg_path.get() / kManifestFileName;
95 bf::path install_path =
96 bf::path(getUserManifestPath(context_->uid.get(), false))
97 / bf::path(context_->pkgid.get());
98 install_path += ".xml";
99 if (bf::exists(backup_path))
100 manifest = backup_path;
101 else if (bf::exists(in_package_path))
102 manifest = in_package_path;
103 else if (bf::exists(install_path))
104 manifest = install_path;
107 case ManifestLocation::INSTALLED: {
110 if (QueryIsGlobalPackage(context_->pkgid.get(), context_->uid.get())) {
111 uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
112 is_preload = QueryIsPreloadPackage(context_->pkgid.get(),
113 context_->uid.get());
115 uid = context_->uid.get();
116 is_preload = context_->is_preload_request.get();
119 bf::path(getUserManifestPath(uid, is_preload))
120 / bf::path(context_->pkgid.get());
122 context_->xml_path.set(xml_path);
123 manifest = context_->xml_path.get();
124 if (!boost::filesystem::exists(manifest)) {
125 /* This routine has added for platform update */
126 manifest = context_->unpacked_dir_path.get();
127 manifest /= kManifestFileName;
131 case ManifestLocation::PACKAGE: {
132 manifest = context_->unpacked_dir_path.get();
133 manifest /= kManifestFileName;
137 LOG(ERROR) << "Unknown manifest location value";
142 LOG(DEBUG) << "manifest path: " << manifest;
144 if (!boost::filesystem::exists(manifest))
151 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
152 manifest->root_path = strdup(
153 (context_->root_application_path.get() / manifest->package).c_str());
154 manifest->installed_time =
155 strdup(std::to_string(std::chrono::system_clock::to_time_t(
156 std::chrono::system_clock::now())).c_str());
160 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
161 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
162 std::static_pointer_cast<const tpk::parse::PackageInfo>(
163 parser_->GetManifestData(app_keys::kManifestKey));
165 LOG(ERROR) << "Package info manifest data has not been found.";
169 auto ui_application_list =
170 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
171 parser_->GetManifestData(app_keys::kUIApplicationKey));
172 auto service_application_list =
173 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
174 parser_->GetManifestData(app_keys::kServiceApplicationKey));
175 auto widget_application_list =
176 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
177 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
178 auto watch_application_list =
179 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
180 parser_->GetManifestData(app_keys::kWatchApplicationKey));
183 if (!ui_application_list && !service_application_list &&
184 !widget_application_list && !watch_application_list) {
185 LOG(ERROR) << "UI Application or Service Application or Widget Application "
186 "or Watch Application are mandatory and has not been found.";
190 manifest->ns = strdup(pkg_info->xmlns().c_str());
191 manifest->package = strdup(pkg_info->package().c_str());
192 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
193 manifest->appsetting = strdup("false");
194 manifest->support_disable = strdup("false");
195 manifest->version = strdup(pkg_info->version().c_str());
196 manifest->installlocation = strdup(pkg_info->install_location().c_str());
197 manifest->api_version = strdup(pkg_info->api_version().c_str());
198 manifest->preload = strdup(pkg_info->preload().c_str());
200 if (pkg_info->type().empty()) {
201 common_installer::RequestType req_type = context_->request_type.get();
202 if ((req_type == RequestType::ManifestDirectInstall ||
203 req_type == RequestType::ManifestDirectUpdate) &&
204 context_->is_preload_request.get())
205 manifest->type = strdup("rpm");
207 manifest->type = strdup("tpk");
209 manifest->type = strdup(pkg_info->type().c_str());
212 for (auto& pair : pkg_info->labels()) {
213 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
214 if (!pair.first.empty())
215 label->lang = strdup(pair.first.c_str());
217 label->lang = strdup(DEFAULT_LOCALE);
218 label->text = strdup(pair.second.c_str());
219 manifest->label = g_list_append(manifest->label, label);
222 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
223 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
224 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
226 for (auto& profile : profile_info->profiles()) {
227 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
228 strdup(profile.c_str()));
232 // set installed_storage if package is installed
233 // this is internal field in package manager but after reading configuration
235 if (manifest_location_ == ManifestLocation::INSTALLED ||
236 manifest_location_ == ManifestLocation::RECOVERY) {
237 std::string storage = QueryStorageForPkgId(manifest->package,
238 context_->uid.get());
239 if (storage.empty()) {
240 // Failed to query installation storage, assign internal for preloaded
242 manifest->installed_storage = strdup(kInstalledInternally);
244 manifest->installed_storage = strdup(storage.c_str());
247 manifest->installed_storage = strdup(kInstalledInternally);
250 if (ui_application_list) {
251 manifest->mainapp_id =
252 strdup(ui_application_list->items[0].app_info.appid().c_str());
253 } else if (service_application_list) {
254 manifest->mainapp_id =
255 strdup(service_application_list->items[0].app_info.appid().c_str());
256 } else if (widget_application_list) {
257 manifest->mainapp_id =
258 strdup(widget_application_list->items[0].app_info.appid().c_str());
259 } else if (watch_application_list) {
260 manifest->mainapp_id =
261 strdup(watch_application_list->items[0].app_info.appid().c_str());
266 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
267 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
268 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
269 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
274 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
275 author->text = strdup(author_info->name().c_str());
276 author->email = strdup(author_info->email().c_str());
277 author->href = strdup(author_info->href().c_str());
278 author->lang = strdup(DEFAULT_LOCALE);
279 manifest->author = g_list_append(manifest->author, author);
283 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
284 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
285 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
286 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
288 if (!description_info)
291 for (auto& desc : description_info->descriptions) {
292 description_x* description = reinterpret_cast<description_x*>
293 (calloc(1, sizeof(description_x)));
294 description->text = strdup(desc.description().c_str());
295 description->lang = !desc.xml_lang().empty() ?
296 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
297 manifest->description = g_list_append(manifest->description, description);
302 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
303 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
304 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
305 parser_->GetManifestData(app_keys::kPrivilegesKey));
309 std::set<std::string> privileges = perm_info->GetPrivileges();
310 for (auto& priv : privileges) {
311 manifest->privileges = g_list_append(manifest->privileges,
312 strdup(priv.c_str()));
317 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
318 auto widget_application_list =
319 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
320 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
321 if (!widget_application_list)
324 for (const auto& application : widget_application_list->items) {
325 // if there is no app yet, set this app as mainapp
326 bool main_app = manifest->application == nullptr;
328 application_x* widget_app =
329 static_cast<application_x*>(calloc(1, sizeof(application_x)));
330 widget_app->appid = strdup(application.app_info.appid().c_str());
331 widget_app->launch_mode =
332 strdup(application.app_info.launch_mode().c_str());
333 widget_app->multiple = strdup("false");
334 widget_app->nodisplay = strdup("true");
335 widget_app->taskmanage = strdup("false");
336 widget_app->indicatordisplay = strdup("false");
338 strdup(application.app_info.type().c_str());
339 widget_app->component_type = strdup("widgetapp");
340 widget_app->hwacceleration =
341 strdup(application.app_info.hwacceleration().c_str());
342 widget_app->onboot = strdup("false");
343 widget_app->autorestart = strdup("false");
344 widget_app->mainapp = main_app ? strdup("true") : strdup("false");
345 widget_app->enabled = strdup("true");
346 widget_app->screenreader = strdup("use-system-setting");
347 widget_app->recentimage = strdup("false");
348 widget_app->launchcondition = strdup("false");
349 widget_app->guestmode_visibility = strdup("true");
350 widget_app->permission_type = strdup("normal");
351 widget_app->ambient_support = strdup("false");
352 widget_app->effectimage_type = strdup("image");
353 widget_app->submode = strdup("false");
354 widget_app->process_pool = strdup("false");
355 widget_app->package = strdup(manifest->package);
356 widget_app->support_disable = strdup(manifest->support_disable);
357 manifest->application = g_list_append(manifest->application, widget_app);
358 if (bf::path(application.app_info.exec().c_str()).is_absolute())
359 widget_app->exec = strdup(application.app_info.exec().c_str());
361 widget_app->exec = strdup((context_->root_application_path.get()
362 / manifest->package / "bin"
363 / application.app_info.exec()).c_str());
365 if (!FillApplicationIconPaths(widget_app, application.app_icons))
367 if (!FillLabel(widget_app, application.label))
369 if (!FillImage(widget_app, application.app_images))
371 if (!FillCategories(widget_app, application.categories))
373 if (!FillMetadata(widget_app, application.meta_data))
375 // FIXME: For hotfix, must be removed
376 if (!FillSupportSize(widget_app, application.support_sizes))
382 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
383 auto service_application_list =
384 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
385 parser_->GetManifestData(app_keys::kServiceApplicationKey));
386 if (!service_application_list)
389 for (const auto& application : service_application_list->items) {
390 // if there is no app yet, set this app as mainapp
391 bool main_app = manifest->application == nullptr;
393 application_x* service_app =
394 static_cast<application_x*>(calloc(1, sizeof(application_x)));
395 service_app->appid = strdup(application.app_info.appid().c_str());
396 service_app->multiple = strdup(application.app_info.multiple().c_str());
397 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
398 service_app->autorestart =
399 strdup(application.app_info.auto_restart().c_str());
400 service_app->onboot = strdup(application.app_info.on_boot().c_str());
401 service_app->type = strdup(application.app_info.type().c_str());
402 service_app->process_pool =
403 strdup(application.app_info.process_pool().c_str());
404 service_app->component_type = strdup("svcapp");
405 service_app->mainapp = main_app ? strdup("true") : strdup("false");
406 service_app->enabled = strdup("true");
407 service_app->nodisplay = strdup("true");
408 service_app->hwacceleration = strdup("default");
409 service_app->screenreader = strdup("use-system-setting");
410 service_app->recentimage = strdup("false");
411 service_app->launchcondition = strdup("false");
412 service_app->indicatordisplay = strdup("true");
413 service_app->effectimage_type = strdup("image");
414 service_app->guestmode_visibility = strdup("true");
415 service_app->permission_type = strdup("normal");
416 service_app->submode = strdup("false");
417 service_app->process_pool = strdup("false");
418 service_app->ambient_support = strdup("false");
419 service_app->package = strdup(manifest->package);
420 service_app->support_disable = strdup(manifest->support_disable);
421 manifest->application = g_list_append(manifest->application, service_app);
422 if (bf::path(application.app_info.exec().c_str()).is_absolute())
423 service_app->exec = strdup(application.app_info.exec().c_str());
425 service_app->exec = strdup((context_->root_application_path.get()
426 / manifest->package / "bin"
427 / application.app_info.exec()).c_str());
429 if (!FillAppControl(service_app, application.app_control))
431 if (!FillDataControl(service_app, application.data_control))
433 if (!FillApplicationIconPaths(service_app, application.app_icons))
435 if (!FillLabel(service_app, application.label))
437 if (!FillMetadata(service_app, application.meta_data))
439 if (!FillCategories(service_app, application.categories))
441 if (!FillBackgroundCategoryInfo(service_app,
442 application.background_category))
448 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
449 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
450 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
451 parser_->GetManifestData(app_keys::kUIApplicationKey));
452 if (!ui_application_list)
455 for (const auto& application : ui_application_list->items) {
456 // if there is no app yet, set this app as mainapp
457 bool main_app = manifest->application == nullptr;
459 application_x* ui_app =
460 static_cast<application_x*>(calloc(1, sizeof(application_x)));
461 ui_app->appid = strdup(application.app_info.appid().c_str());
462 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
463 ui_app->multiple = strdup(application.app_info.multiple().c_str());
464 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
465 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
466 ui_app->type = strdup(application.app_info.type().c_str());
467 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
468 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
469 ui_app->submode = strdup(application.app_info.submode().c_str());
470 if (!application.app_info.indicator_display().empty())
471 ui_app->indicatordisplay =
472 strdup(application.app_info.indicator_display().c_str());
473 if (!application.app_info.effectimage_type().empty())
474 ui_app->effectimage_type =
475 strdup(application.app_info.effectimage_type().c_str());
476 if (!application.app_info.portrait_image().empty())
477 ui_app->portraitimg =
478 strdup(application.app_info.portrait_image().c_str());
479 if (!application.app_info.landscape_image().empty())
480 ui_app->landscapeimg =
481 strdup(application.app_info.landscape_image().c_str());
482 ui_app->submode_mainid =
483 strdup(application.app_info.submode_mainid().c_str());
484 ui_app->hwacceleration =
485 strdup(application.app_info.hwacceleration().c_str());
486 ui_app->onboot = strdup("false");
487 ui_app->autorestart = strdup("false");
488 ui_app->component_type = strdup("uiapp");
489 ui_app->mainapp = main_app ? strdup("true") : strdup("false");
490 ui_app->enabled = strdup("true");
491 ui_app->screenreader = strdup("use-system-setting");
492 ui_app->recentimage = strdup("false");
493 ui_app->launchcondition = strdup("false");
494 ui_app->guestmode_visibility = strdup("true");
495 ui_app->permission_type = strdup("normal");
496 ui_app->ambient_support = strdup("false");
497 ui_app->package = strdup(manifest->package);
498 ui_app->support_disable = strdup(manifest->support_disable);
499 ui_app->splash_screen_display =
500 strdup(application.app_info.splash_screen_display().c_str());
501 manifest->application = g_list_append(manifest->application, ui_app);
502 if (bf::path(application.app_info.exec().c_str()).is_absolute())
503 ui_app->exec = strdup(application.app_info.exec().c_str());
505 ui_app->exec = strdup((context_->root_application_path.get()
506 / manifest->package / "bin"
507 / application.app_info.exec()).c_str());
510 if (!FillAppControl(ui_app, application.app_control))
512 if (!FillDataControl(ui_app, application.data_control))
514 if (!FillApplicationIconPaths(ui_app, application.app_icons))
516 if (!FillLabel(ui_app, application.label))
518 if (!FillImage(ui_app, application.app_images))
520 if (!FillMetadata(ui_app, application.meta_data))
522 if (!FillCategories(ui_app, application.categories))
524 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
526 if (!FillSplashScreen(ui_app, application.app_splashscreens))
532 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
533 auto watch_application_list =
534 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
535 parser_->GetManifestData(app_keys::kWatchApplicationKey));
536 if (!watch_application_list)
539 for (const auto& watch_application : watch_application_list->items) {
540 bool main_app = manifest->application == nullptr;
542 application_x* watch_app =
543 static_cast<application_x*>(calloc(1, sizeof(application_x)));
544 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
546 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
547 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
549 watch_app->exec = strdup(
550 (context_->root_application_path.get()
551 / manifest->package / "bin" /
552 watch_application.app_info.exec()).c_str());
553 watch_app->nodisplay = strdup("true");
554 watch_app->multiple = strdup("false");
555 watch_app->type = strdup(watch_application.app_info.type().c_str());
556 watch_app->taskmanage = strdup("false");
557 watch_app->enabled = strdup("true");
558 watch_app->hwacceleration = strdup("default");
559 watch_app->screenreader = strdup("use-system-setting");
560 watch_app->mainapp = main_app ? strdup("true") : strdup("false");
561 watch_app->recentimage = strdup("false");
562 watch_app->launchcondition = strdup("false");
563 watch_app->indicatordisplay = strdup("true");
564 watch_app->effectimage_type = strdup("image");
565 watch_app->guestmode_visibility = strdup("true");
566 watch_app->permission_type = strdup("normal");
567 watch_app->component_type = strdup("watchapp");
568 watch_app->preload = strdup("false");
569 watch_app->submode = strdup("false");
570 watch_app->process_pool = strdup("false");
571 watch_app->autorestart = strdup("false");
572 watch_app->onboot = strdup("false");
573 watch_app->support_disable = strdup(manifest->support_disable);
574 watch_app->ui_gadget = strdup("false");
575 watch_app->launch_mode = strdup("single");
576 watch_app->ambient_support =
577 strdup(watch_application.app_info.ambient_support().c_str());
578 watch_app->package = strdup(manifest->package);
579 if (!FillLabel(watch_app, watch_application.label))
581 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
583 if (!FillMetadata(watch_app, watch_application.meta_data))
585 if (!FillCategories(watch_app, watch_application.categories))
587 if (!FillBackgroundCategoryInfo(watch_app,
588 watch_application.background_category))
590 manifest->application = g_list_append(manifest->application, watch_app);
595 bool StepParseManifest::CheckFeatures() {
597 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
598 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
603 FeatureValidator validator(feature_info->features());
604 if (!validator.Validate(&error)) {
605 LOG(ERROR) << "Feature validation error. " << error;
612 template <typename T>
613 bool StepParseManifest::FillAppControl(application_x* app,
614 const T& app_control_list) {
615 if (app_control_list.empty())
618 for (const auto& control : app_control_list) {
619 appcontrol_x* app_control =
620 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
621 app_control->operation = strdup(control.operation().c_str());
622 if (!control.mime().empty())
623 app_control->mime = strdup(control.mime().c_str());
624 if (!control.uri().empty())
625 app_control->uri = strdup(control.uri().c_str());
626 app->appcontrol = g_list_append(app->appcontrol, app_control);
631 template <typename T>
632 bool StepParseManifest::FillDataControl(application_x* app,
633 const T& data_control_list) {
634 if (data_control_list.empty())
637 for (const auto& control : data_control_list) {
638 datacontrol_x* data_control =
639 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
640 data_control->access = strdup(control.access().c_str());
641 data_control->providerid = strdup(control.providerid().c_str());
642 data_control->type = strdup(control.type().c_str());
643 app->datacontrol = g_list_append(app->datacontrol, data_control);
648 template <typename T>
649 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
650 const T& icons_info) {
651 for (auto& application_icon : icons_info.icons()) {
652 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
654 if (bf::path(application_icon.path()).is_absolute()) {
655 text = application_icon.path();
657 text = context_->root_application_path.get()
658 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
660 // NOTE: name is an attribute, but the xml writer uses it as text.
661 // This must be fixed in whole app-installer modules, including wgt.
662 // Current implementation is just for compatibility.
663 icon->text = strdup(text.c_str());
664 if (application_icon.lang().empty())
665 icon->lang = strdup(DEFAULT_LOCALE);
667 icon->lang = strdup(application_icon.lang().c_str());
669 if (!application_icon.dpi().empty())
670 icon->dpi = strdup(application_icon.dpi().c_str());
671 app->icon = g_list_append(app->icon, icon);
676 template <typename T>
677 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
678 if (label_list.empty())
681 for (const auto& control : label_list) {
683 static_cast<label_x*>(calloc(1, sizeof(label_x)));
684 // NOTE: name is an attribute, but the xml writer uses it as text.
685 // This must be fixed in whole app-installer modules, including wgt.
686 // Current implementation is just for compatibility.
687 label->text = strdup(control.text().c_str());
688 label->name = strdup(control.name().c_str());
689 label->lang = !control.xml_lang().empty() ?
690 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
691 app->label = g_list_append(app->label, label);
696 template <typename T>
697 bool StepParseManifest::FillMetadata(application_x* app,
698 const T& meta_data_list) {
699 if (meta_data_list.empty())
702 for (auto& meta : meta_data_list) {
703 metadata_x* metadata =
704 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
705 metadata->key = strdup(meta.key().c_str());
706 metadata->value = strdup(meta.val().c_str());
707 app->metadata = g_list_append(app->metadata, metadata);
712 // FIXME: For hotfix, must be removed
713 template <typename T>
714 bool StepParseManifest::FillSupportSize(application_x* app,
715 const T& support_size_list) {
716 if (support_size_list.empty())
719 for (auto& ss : support_size_list) {
720 support_size_x* support_size =
721 static_cast<support_size_x*>(calloc(1, sizeof(support_size_x)));
722 support_size->preview = strdup(ss.preview().c_str());
723 support_size->size = strdup(ss.size().c_str());
724 app->support_sizes = g_list_append(app->support_sizes, support_size);
729 template <typename T>
730 bool StepParseManifest::FillCategories(application_x* manifest,
731 const T& categories) {
732 for (auto& category : categories) {
733 manifest->category = g_list_append(manifest->category,
734 strdup(category.c_str()));
739 template <typename T>
740 bool StepParseManifest::FillSplashScreen(application_x* app,
741 const T& splashscreens_info) {
742 for (auto& splash_screen : splashscreens_info.splashscreens()) {
743 splashscreen_x* splashscreen =
744 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
745 if (context_->is_preload_request.get())
746 splashscreen->src = strdup(splash_screen.src().c_str());
748 splashscreen->src = strdup((context_->root_application_path.get()
749 / app->package / "shared" / "res" / splash_screen.src()).c_str());
751 splashscreen->type = strdup(splash_screen.type().c_str());
752 if (!splash_screen.dpi().empty())
753 splashscreen->dpi = strdup(splash_screen.dpi().c_str());
754 splashscreen->orientation = strdup(splash_screen.orientation().c_str());
755 if (!splash_screen.indicatordisplay().empty())
756 splashscreen->indicatordisplay = strdup(
757 splash_screen.indicatordisplay().c_str());
759 splashscreen->indicatordisplay = strdup("true");
761 if (!splash_screen.operation().empty())
762 splashscreen->operation = strdup(splash_screen.operation().c_str());
764 splashscreen->operation = strdup("launch-effect");
766 if (!splash_screen.colordepth().empty())
767 splashscreen->color_depth = strdup(splash_screen.colordepth().c_str());
769 splashscreen->color_depth = strdup("24");
771 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
776 bool StepParseManifest::FillImage(application_x* app,
777 const tpk::parse::ApplicationImagesInfo& image_list) {
778 for (auto& app_image : image_list.images) {
780 static_cast<image_x*>(calloc(1, sizeof(image_x)));
781 const std::string& lang = app_image.lang();
783 image->lang = strdup(lang.c_str());
785 image->lang = strdup(DEFAULT_LOCALE);
786 if (!app_image.section().empty())
787 image->section = strdup(app_image.section().c_str());
788 app->image = g_list_append(app->image, image);
793 template <typename T>
794 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
795 const T& background_category_data_list) {
796 for (const auto& background_category : background_category_data_list) {
797 app->background_category = g_list_append(
798 app->background_category, strdup(background_category.value().c_str()));
804 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
805 if (!FillPackageInfo(manifest))
807 if (!FillInstallationInfo(manifest))
809 if (!FillUIApplication(manifest))
811 if (!FillServiceApplication(manifest))
813 if (!FillWidgetApplication(manifest))
815 if (!FillWatchApplication(manifest))
817 if (!FillPrivileges(manifest))
819 if (!FillAuthorInfo(manifest))
821 if (!FillDescriptionInfo(manifest))
826 Step::Status StepParseManifest::process() {
827 if (!LocateConfigFile()) {
828 // continue if this is recovery, manifest file may never been created
829 if (manifest_location_ == ManifestLocation::RECOVERY) {
830 LOG(DEBUG) << "Manifest for recovery not found";
831 return Step::Status::OK;
833 LOG(ERROR) << "No manifest file exists";
834 return Step::Status::MANIFEST_NOT_FOUND;
836 parser_.reset(new tpk::parse::TPKConfigParser());
837 if (!parser_->ParseManifest(path_)) {
838 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
839 return Step::Status::PARSE_ERROR;
842 // Copy data from ManifestData to InstallerContext
843 std::shared_ptr<const tpk::parse::PackageInfo> info =
844 std::static_pointer_cast<const tpk::parse::PackageInfo>(
845 parser_->GetManifestData(app_keys::kManifestKey));
847 context_->pkgid.set(info->package());
848 context_->pkg_path.set(
849 context_->root_application_path.get() / context_->pkgid.get());
851 manifest_x* manifest =
852 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
854 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
855 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
856 << parser_->GetErrorMessage();
857 return Step::Status::PARSE_ERROR;
860 if (manifest_location_ == ManifestLocation::INSTALLED) {
861 // recovery of tep value for installed package
862 std::string old_tep =
863 QueryTepPath(context_->pkgid.get(), context_->uid.get());
864 if (!old_tep.empty())
865 manifest->tep_name = strdup(old_tep.c_str());
867 // recovery of zip mount file for installed package
868 std::string zip_mount_file =
869 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
870 if (!zip_mount_file.empty())
871 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
874 // write pkgid for recovery file
875 if (context_->recovery_info.get().recovery_file) {
876 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
877 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
880 LOG(DEBUG) << "Parsed package id: " << info->package();
882 switch (store_location_) {
883 case StoreLocation::NORMAL:
884 context_->manifest_data.set(manifest);
886 case StoreLocation::BACKUP:
887 context_->old_manifest_data.set(manifest);
890 LOG(ERROR) << "Unknown store location for parsed data";
891 return Step::Status::ERROR;
893 return Step::Status::OK;
896 } // namespace configuration
897 } // namespace common_installer