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";
52 namespace common_installer {
53 namespace configuration {
55 StepParseManifest::StepParseManifest(
56 InstallerContext* context, ManifestLocation manifest_location,
57 StoreLocation store_location)
59 manifest_location_(manifest_location),
60 store_location_(store_location) {
63 Step::Status StepParseManifest::precheck() {
64 switch (manifest_location_) {
65 case ManifestLocation::RECOVERY:
66 case ManifestLocation::INSTALLED:
67 if (context_->pkgid.get().empty()) {
68 LOG(ERROR) << "Package id is not set";
69 return Status::INVALID_VALUE;
72 case ManifestLocation::PACKAGE:
73 if (context_->unpacked_dir_path.get().empty()) {
74 LOG(ERROR) << "Unpacked directory doesn't exist";
75 return Status::INVALID_VALUE;
79 LOG(ERROR) << "Unknown manifest location";
80 return Status::INVALID_VALUE;
85 bool StepParseManifest::LocateConfigFile() {
86 boost::filesystem::path manifest;
87 switch (manifest_location_) {
88 case ManifestLocation::RECOVERY: {
89 context_->pkg_path.set(
90 context_->root_application_path.get() / context_->pkgid.get());
91 bf::path backup_path = common_installer::GetBackupPathForPackagePath(
92 context_->pkg_path.get()) / kManifestFileName;
93 bf::path in_package_path = context_->pkg_path.get() / kManifestFileName;
94 bf::path install_path =
95 bf::path(getUserManifestPath(context_->uid.get(), false))
96 / bf::path(context_->pkgid.get());
97 install_path += ".xml";
98 if (bf::exists(backup_path))
99 manifest = backup_path;
100 else if (bf::exists(in_package_path))
101 manifest = in_package_path;
102 else if (bf::exists(install_path))
103 manifest = install_path;
106 case ManifestLocation::INSTALLED: {
108 bf::path(getUserManifestPath(context_->uid.get(),
109 context_->is_preload_request.get()))
110 / bf::path(context_->pkgid.get());
112 context_->xml_path.set(xml_path);
113 manifest = context_->xml_path.get();
116 case ManifestLocation::PACKAGE: {
117 manifest = context_->unpacked_dir_path.get();
118 manifest /= kManifestFileName;
122 LOG(ERROR) << "Unknown manifest location value";
127 LOG(DEBUG) << "manifest path: " << manifest;
129 if (!boost::filesystem::exists(manifest))
136 bool StepParseManifest::FillInstallationInfo(manifest_x* manifest) {
137 manifest->root_path = strdup(
138 (context_->root_application_path.get() / manifest->package).c_str());
139 manifest->installed_time =
140 strdup(std::to_string(std::chrono::system_clock::to_time_t(
141 std::chrono::system_clock::now())).c_str());
145 bool StepParseManifest::FillPackageInfo(manifest_x* manifest) {
146 std::shared_ptr<const tpk::parse::PackageInfo> pkg_info =
147 std::static_pointer_cast<const tpk::parse::PackageInfo>(
148 parser_->GetManifestData(app_keys::kManifestKey));
150 LOG(ERROR) << "Package info manifest data has not been found.";
154 auto ui_application_list =
155 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
156 parser_->GetManifestData(app_keys::kUIApplicationKey));
157 auto service_application_list =
158 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
159 parser_->GetManifestData(app_keys::kServiceApplicationKey));
160 auto widget_application_list =
161 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
162 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
163 auto watch_application_list =
164 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
165 parser_->GetManifestData(app_keys::kWatchApplicationKey));
168 if (!ui_application_list && !service_application_list &&
169 !widget_application_list && !watch_application_list) {
170 LOG(ERROR) << "UI Application or Service Application or Widget Application "
171 "or Watch Application are mandatory and has not been found.";
175 manifest->ns = strdup(pkg_info->xmlns().c_str());
176 manifest->package = strdup(pkg_info->package().c_str());
177 manifest->nodisplay_setting = strdup(pkg_info->nodisplay_setting().c_str());
178 manifest->appsetting = strdup("false");
179 manifest->support_disable = strdup("false");
180 manifest->version = strdup(pkg_info->version().c_str());
181 manifest->installlocation = strdup(pkg_info->install_location().c_str());
182 manifest->api_version = strdup(pkg_info->api_version().c_str());
183 manifest->preload = strdup(pkg_info->preload().c_str());
185 if (pkg_info->type().empty()) {
186 common_installer::RequestType req_type = context_->request_type.get();
187 if (req_type == RequestType::ManifestDirectInstall ||
188 req_type == RequestType::ManifestDirectUpdate) {
189 manifest->type = strdup("rpm");
190 if (!context_->is_preload_request.get()) {
191 LOG(ERROR) << "Non-preload rpm installation not allowed";
195 manifest->type = strdup("tpk");
198 manifest->type = strdup(pkg_info->type().c_str());
201 for (auto& pair : pkg_info->labels()) {
202 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
203 if (!pair.first.empty())
204 label->lang = strdup(pair.first.c_str());
206 label->lang = strdup(DEFAULT_LOCALE);
207 label->text = strdup(pair.second.c_str());
208 manifest->label = g_list_append(manifest->label, label);
211 std::shared_ptr<const tpk::parse::ProfileInfo> profile_info =
212 std::static_pointer_cast<const tpk::parse::ProfileInfo>(
213 parser_->GetManifestData(tpk::parse::ProfileInfo::Key()));
215 for (auto& profile : profile_info->profiles()) {
216 manifest->deviceprofile = g_list_append(manifest->deviceprofile,
217 strdup(profile.c_str()));
221 // set installed_storage if package is installed
222 // this is internal field in package manager but after reading configuration
224 std::string storage = QueryStorageForPkgId(manifest->package,
225 context_->uid.get());
226 manifest->installed_storage = strdup(storage.c_str());
228 if (ui_application_list) {
229 manifest->mainapp_id =
230 strdup(ui_application_list->items[0].app_info.appid().c_str());
231 } else if (service_application_list) {
232 manifest->mainapp_id =
233 strdup(service_application_list->items[0].app_info.appid().c_str());
234 } else if (widget_application_list) {
235 manifest->mainapp_id =
236 strdup(widget_application_list->items[0].app_info.appid().c_str());
237 } else if (watch_application_list) {
238 manifest->mainapp_id =
239 strdup(watch_application_list->items[0].app_info.appid().c_str());
244 bool StepParseManifest::FillAuthorInfo(manifest_x* manifest) {
245 std::shared_ptr<const tpk::parse::AuthorInfo> author_info =
246 std::static_pointer_cast<const tpk::parse::AuthorInfo>(
247 parser_->GetManifestData(tpk::parse::AuthorInfo::Key()));
252 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
253 author->text = strdup(author_info->name().c_str());
254 author->email = strdup(author_info->email().c_str());
255 author->href = strdup(author_info->href().c_str());
256 author->lang = strdup(DEFAULT_LOCALE);
257 manifest->author = g_list_append(manifest->author, author);
261 bool StepParseManifest::FillDescriptionInfo(manifest_x* manifest) {
262 std::shared_ptr<const tpk::parse::DescriptionInfoList> description_info =
263 std::static_pointer_cast<const tpk::parse::DescriptionInfoList>(
264 parser_->GetManifestData(tpk::parse::DescriptionInfoList::Key()));
266 if (!description_info)
269 for (auto& desc : description_info->descriptions) {
270 description_x* description = reinterpret_cast<description_x*>
271 (calloc(1, sizeof(description_x)));
272 description->text = strdup(desc.description().c_str());
273 description->lang = !desc.xml_lang().empty() ?
274 strdup(desc.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
275 manifest->description = g_list_append(manifest->description, description);
280 bool StepParseManifest::FillPrivileges(manifest_x* manifest) {
281 std::shared_ptr<const tpk::parse::PrivilegesInfo> perm_info =
282 std::static_pointer_cast<const tpk::parse::PrivilegesInfo>(
283 parser_->GetManifestData(app_keys::kPrivilegesKey));
287 std::set<std::string> privileges = perm_info->GetPrivileges();
288 for (auto& priv : privileges) {
289 manifest->privileges = g_list_append(manifest->privileges,
290 strdup(priv.c_str()));
295 bool StepParseManifest::FillWidgetApplication(manifest_x* manifest) {
296 auto widget_application_list =
297 std::static_pointer_cast<const tpk::parse::WidgetApplicationInfoList>(
298 parser_->GetManifestData(app_keys::kWidgetApplicationKey));
299 if (!widget_application_list)
302 for (const auto& application : widget_application_list->items) {
303 // if there is no app yet, set this app as mainapp
304 bool main_app = manifest->application == nullptr;
306 application_x* widget_app =
307 static_cast<application_x*>(calloc(1, sizeof(application_x)));
308 widget_app->appid = strdup(application.app_info.appid().c_str());
309 widget_app->launch_mode =
310 strdup(application.app_info.launch_mode().c_str());
311 widget_app->multiple = strdup("false");
312 widget_app->nodisplay = strdup("true");
313 widget_app->taskmanage = strdup("false");
314 widget_app->indicatordisplay = strdup("false");
315 widget_app->type = strdup("capp");
316 widget_app->component_type = strdup("widgetapp");
317 widget_app->hwacceleration =
318 strdup(application.app_info.hwacceleration().c_str());
319 widget_app->onboot = strdup("false");
320 widget_app->autorestart = strdup("false");
321 widget_app->mainapp = main_app ? strdup("true") : strdup("false");
322 widget_app->enabled = strdup("true");
323 widget_app->screenreader = strdup("use-system-setting");
324 widget_app->recentimage = strdup("false");
325 widget_app->launchcondition = strdup("false");
326 widget_app->guestmode_visibility = strdup("true");
327 widget_app->permission_type = strdup("normal");
328 widget_app->ambient_support = strdup("false");
329 widget_app->effectimage_type = strdup("image");
330 widget_app->submode = strdup("false");
331 widget_app->process_pool = strdup("false");
332 widget_app->package = strdup(manifest->package);
333 widget_app->support_disable = strdup(manifest->support_disable);
334 manifest->application = g_list_append(manifest->application, widget_app);
335 if (bf::path(application.app_info.exec().c_str()).is_absolute())
336 widget_app->exec = strdup(application.app_info.exec().c_str());
338 widget_app->exec = strdup((context_->root_application_path.get()
339 / manifest->package / "bin"
340 / application.app_info.exec()).c_str());
342 if (!FillApplicationIconPaths(widget_app, application.app_icons))
344 if (!FillLabel(widget_app, application.label))
346 if (!FillImage(widget_app, application.app_images))
348 if (!FillCategories(widget_app, application.categories))
350 if (!FillMetadata(widget_app, application.meta_data))
356 bool StepParseManifest::FillServiceApplication(manifest_x* manifest) {
357 auto service_application_list =
358 std::static_pointer_cast<const tpk::parse::ServiceApplicationInfoList>(
359 parser_->GetManifestData(app_keys::kServiceApplicationKey));
360 if (!service_application_list)
363 for (const auto& application : service_application_list->items) {
364 // if there is no app yet, set this app as mainapp
365 bool main_app = manifest->application == nullptr;
367 application_x* service_app =
368 static_cast<application_x*>(calloc(1, sizeof(application_x)));
369 service_app->appid = strdup(application.app_info.appid().c_str());
370 service_app->multiple = strdup(application.app_info.multiple().c_str());
371 service_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
372 service_app->autorestart =
373 strdup(application.app_info.auto_restart().c_str());
374 service_app->onboot = strdup(application.app_info.on_boot().c_str());
375 service_app->type = strdup(application.app_info.type().c_str());
376 service_app->process_pool =
377 strdup(application.app_info.process_pool().c_str());
378 service_app->component_type = strdup("svcapp");
379 service_app->mainapp = main_app ? strdup("true") : strdup("false");
380 service_app->enabled = strdup("true");
381 service_app->nodisplay = strdup("true");
382 service_app->hwacceleration = strdup("default");
383 service_app->screenreader = strdup("use-system-setting");
384 service_app->recentimage = strdup("false");
385 service_app->launchcondition = strdup("false");
386 service_app->indicatordisplay = strdup("true");
387 service_app->effectimage_type = strdup("image");
388 service_app->guestmode_visibility = strdup("true");
389 service_app->permission_type = strdup("normal");
390 service_app->submode = strdup("false");
391 service_app->process_pool = strdup("false");
392 service_app->ambient_support = strdup("false");
393 service_app->package = strdup(manifest->package);
394 service_app->support_disable = strdup(manifest->support_disable);
395 manifest->application = g_list_append(manifest->application, service_app);
396 if (bf::path(application.app_info.exec().c_str()).is_absolute())
397 service_app->exec = strdup(application.app_info.exec().c_str());
399 service_app->exec = strdup((context_->root_application_path.get()
400 / manifest->package / "bin"
401 / application.app_info.exec()).c_str());
403 if (!FillAppControl(service_app, application.app_control))
405 if (!FillDataControl(service_app, application.data_control))
407 if (!FillApplicationIconPaths(service_app, application.app_icons))
409 if (!FillLabel(service_app, application.label))
411 if (!FillMetadata(service_app, application.meta_data))
413 if (!FillCategories(service_app, application.categories))
415 if (!FillBackgroundCategoryInfo(service_app,
416 application.background_category))
422 bool StepParseManifest::FillUIApplication(manifest_x* manifest) {
423 std::shared_ptr<const tpk::parse::UIApplicationInfoList> ui_application_list =
424 std::static_pointer_cast<const tpk::parse::UIApplicationInfoList>(
425 parser_->GetManifestData(app_keys::kUIApplicationKey));
426 if (!ui_application_list)
429 for (const auto& application : ui_application_list->items) {
430 // if there is no app yet, set this app as mainapp
431 bool main_app = manifest->application == nullptr;
433 application_x* ui_app =
434 static_cast<application_x*>(calloc(1, sizeof(application_x)));
435 ui_app->appid = strdup(application.app_info.appid().c_str());
436 ui_app->launch_mode = strdup(application.app_info.launch_mode().c_str());
437 ui_app->multiple = strdup(application.app_info.multiple().c_str());
438 ui_app->nodisplay = strdup(application.app_info.nodisplay().c_str());
439 ui_app->taskmanage = strdup(application.app_info.taskmanage().c_str());
440 ui_app->type = strdup(application.app_info.type().c_str());
441 ui_app->ui_gadget = strdup(application.app_info.uigadget().c_str());
442 ui_app->process_pool = strdup(application.app_info.process_pool().c_str());
443 ui_app->submode = strdup(application.app_info.submode().c_str());
444 if (!application.app_info.indicator_display().empty())
445 ui_app->indicatordisplay =
446 strdup(application.app_info.indicator_display().c_str());
447 if (!application.app_info.effectimage_type().empty())
448 ui_app->effectimage_type =
449 strdup(application.app_info.effectimage_type().c_str());
450 if (!application.app_info.portrait_image().empty())
451 ui_app->portraitimg =
452 strdup(application.app_info.portrait_image().c_str());
453 if (!application.app_info.landscape_image().empty())
454 ui_app->landscapeimg =
455 strdup(application.app_info.landscape_image().c_str());
456 ui_app->submode_mainid =
457 strdup(application.app_info.submode_mainid().c_str());
458 ui_app->hwacceleration =
459 strdup(application.app_info.hwacceleration().c_str());
460 ui_app->onboot = strdup("false");
461 ui_app->autorestart = strdup("false");
462 ui_app->component_type = strdup("uiapp");
463 ui_app->mainapp = main_app ? strdup("true") : strdup("false");
464 ui_app->enabled = strdup("true");
465 ui_app->screenreader = strdup("use-system-setting");
466 ui_app->recentimage = strdup("false");
467 ui_app->launchcondition = strdup("false");
468 ui_app->guestmode_visibility = strdup("true");
469 ui_app->permission_type = strdup("normal");
470 ui_app->ambient_support = strdup("false");
471 ui_app->package = strdup(manifest->package);
472 ui_app->support_disable = strdup(manifest->support_disable);
473 ui_app->splash_screen_display =
474 strdup(application.app_info.splash_screen_display().c_str());
475 manifest->application = g_list_append(manifest->application, ui_app);
476 if (bf::path(application.app_info.exec().c_str()).is_absolute())
477 ui_app->exec = strdup(application.app_info.exec().c_str());
479 ui_app->exec = strdup((context_->root_application_path.get()
480 / manifest->package / "bin"
481 / application.app_info.exec()).c_str());
484 if (!FillAppControl(ui_app, application.app_control))
486 if (!FillDataControl(ui_app, application.data_control))
488 if (!FillApplicationIconPaths(ui_app, application.app_icons))
490 if (!FillLabel(ui_app, application.label))
492 if (!FillImage(ui_app, application.app_images))
494 if (!FillMetadata(ui_app, application.meta_data))
496 if (!FillCategories(ui_app, application.categories))
498 if (!FillBackgroundCategoryInfo(ui_app, application.background_category))
500 if (!FillSplashScreen(ui_app, application.app_splashscreens))
506 bool StepParseManifest::FillWatchApplication(manifest_x* manifest) {
507 auto watch_application_list =
508 std::static_pointer_cast<const tpk::parse::WatchApplicationInfoList>(
509 parser_->GetManifestData(app_keys::kWatchApplicationKey));
510 if (!watch_application_list)
513 for (const auto& watch_application : watch_application_list->items) {
514 bool main_app = manifest->application == nullptr;
516 application_x* watch_app =
517 static_cast<application_x*>(calloc(1, sizeof(application_x)));
518 watch_app->appid = strdup(watch_application.app_info.appid().c_str());
520 if (bf::path(watch_application.app_info.exec().c_str()).is_absolute())
521 watch_app->exec = strdup(watch_application.app_info.exec().c_str());
523 watch_app->exec = strdup(
524 (context_->root_application_path.get()
525 / manifest->package / "bin" /
526 watch_application.app_info.exec()).c_str());
527 watch_app->nodisplay = strdup("true");
528 watch_app->multiple = strdup("false");
529 watch_app->type = strdup(watch_application.app_info.type().c_str());
530 watch_app->taskmanage = strdup("false");
531 watch_app->enabled = strdup("true");
532 watch_app->hwacceleration = strdup("default");
533 watch_app->screenreader = strdup("use-system-setting");
534 watch_app->mainapp = main_app ? strdup("true") : strdup("false");
535 watch_app->recentimage = strdup("false");
536 watch_app->launchcondition = strdup("false");
537 watch_app->indicatordisplay = strdup("true");
538 watch_app->effectimage_type = strdup("image");
539 watch_app->guestmode_visibility = strdup("true");
540 watch_app->permission_type = strdup("normal");
541 watch_app->component_type = strdup("watchapp");
542 watch_app->preload = strdup("false");
543 watch_app->submode = strdup("false");
544 watch_app->process_pool = strdup("false");
545 watch_app->autorestart = strdup("false");
546 watch_app->onboot = strdup("false");
547 watch_app->support_disable = strdup(manifest->support_disable);
548 watch_app->ui_gadget = strdup("false");
549 watch_app->launch_mode = strdup("single");
550 watch_app->ambient_support =
551 strdup(watch_application.app_info.ambient_support().c_str());
552 if (!FillLabel(watch_app, watch_application.label))
554 if (!FillApplicationIconPaths(watch_app, watch_application.app_icons))
556 if (!FillMetadata(watch_app, watch_application.meta_data))
558 if (!FillCategories(watch_app, watch_application.categories))
560 if (!FillBackgroundCategoryInfo(watch_app,
561 watch_application.background_category))
563 manifest->application = g_list_append(manifest->application, watch_app);
568 bool StepParseManifest::CheckFeatures() {
570 std::static_pointer_cast<const tpk::parse::FeatureInfo>(
571 parser_->GetManifestData(tpk::parse::FeatureInfo::Key()));
576 FeatureValidator validator(feature_info->features());
577 if (!validator.Validate(&error)) {
578 LOG(ERROR) << "Feature validation error. " << error;
585 template <typename T>
586 bool StepParseManifest::FillAppControl(application_x* app,
587 const T& app_control_list) {
588 if (app_control_list.empty())
591 for (const auto& control : app_control_list) {
592 appcontrol_x* app_control =
593 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
594 app_control->operation = strdup(control.operation().c_str());
595 if (!control.mime().empty())
596 app_control->mime = strdup(control.mime().c_str());
597 if (!control.uri().empty())
598 app_control->uri = strdup(control.uri().c_str());
599 app->appcontrol = g_list_append(app->appcontrol, app_control);
604 template <typename T>
605 bool StepParseManifest::FillDataControl(application_x* app,
606 const T& data_control_list) {
607 if (data_control_list.empty())
610 for (const auto& control : data_control_list) {
611 datacontrol_x* data_control =
612 static_cast<datacontrol_x*>(calloc(1, sizeof(datacontrol_x)));
613 data_control->access = strdup(control.access().c_str());
614 data_control->providerid = strdup(control.providerid().c_str());
615 data_control->type = strdup(control.type().c_str());
616 app->datacontrol = g_list_append(app->datacontrol, data_control);
621 template <typename T>
622 bool StepParseManifest::FillApplicationIconPaths(application_x* app,
623 const T& icons_info) {
624 for (auto& application_icon : icons_info.icons()) {
625 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
627 if (bf::path(application_icon.path()).is_absolute()) {
628 text = application_icon.path();
630 text = context_->root_application_path.get()
631 / context_->pkgid.get() / "shared" / "res" / application_icon.path();
633 // NOTE: name is an attribute, but the xml writer uses it as text.
634 // This must be fixed in whole app-installer modules, including wgt.
635 // Current implementation is just for compatibility.
636 icon->text = strdup(text.c_str());
637 if (application_icon.lang().empty())
638 icon->lang = strdup(DEFAULT_LOCALE);
640 icon->lang = strdup(application_icon.lang().c_str());
642 if (!application_icon.dpi().empty())
643 icon->dpi = strdup(application_icon.dpi().c_str());
644 app->icon = g_list_append(app->icon, icon);
649 template <typename T>
650 bool StepParseManifest::FillLabel(application_x* app, const T& label_list) {
651 if (label_list.empty())
654 for (const auto& control : label_list) {
656 static_cast<label_x*>(calloc(1, sizeof(label_x)));
657 // NOTE: name is an attribute, but the xml writer uses it as text.
658 // This must be fixed in whole app-installer modules, including wgt.
659 // Current implementation is just for compatibility.
660 label->text = strdup(control.text().c_str());
661 label->name = strdup(control.name().c_str());
662 label->lang = !control.xml_lang().empty() ?
663 strdup(control.xml_lang().c_str()) : strdup(DEFAULT_LOCALE);
664 app->label = g_list_append(app->label, label);
669 template <typename T>
670 bool StepParseManifest::FillMetadata(application_x* app,
671 const T& meta_data_list) {
672 if (meta_data_list.empty())
675 for (auto& meta : meta_data_list) {
676 metadata_x* metadata =
677 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
678 metadata->key = strdup(meta.key().c_str());
679 metadata->value = strdup(meta.val().c_str());
680 app->metadata = g_list_append(app->metadata, metadata);
685 template <typename T>
686 bool StepParseManifest::FillCategories(application_x* manifest,
687 const T& categories) {
688 for (auto& category : categories) {
689 manifest->category = g_list_append(manifest->category,
690 strdup(category.c_str()));
695 template <typename T>
696 bool StepParseManifest::FillSplashScreen(application_x* app,
697 const T& splashscreens_info) {
698 for (auto& splash_screen : splashscreens_info.splashscreens()) {
699 splashscreen_x* splashscreen =
700 static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
701 if (context_->is_preload_request.get())
702 splashscreen->src = strdup(splash_screen.src().c_str());
704 splashscreen->src = strdup((context_->root_application_path.get()
705 / app->package / "shared" / "res" / splash_screen.src()).c_str());
707 splashscreen->type = strdup(splash_screen.type().c_str());
708 if (!splash_screen.dpi().empty())
709 splashscreen->dpi = strdup(splash_screen.dpi().c_str());
710 splashscreen->orientation = strdup(splash_screen.orientation().c_str());
711 if (!splash_screen.indicatordisplay().empty())
712 splashscreen->indicatordisplay = strdup(
713 splash_screen.indicatordisplay().c_str());
715 splashscreen->indicatordisplay = strdup("true");
716 if (!splash_screen.operation().empty())
717 splashscreen->operation = strdup(splash_screen.operation().c_str());
718 if (!splash_screen.colordepth().empty())
719 splashscreen->color_depth = strdup(splash_screen.colordepth().c_str());
720 app->splashscreens = g_list_append(app->splashscreens, splashscreen);
725 bool StepParseManifest::FillImage(application_x* app,
726 const tpk::parse::ApplicationImagesInfo& image_list) {
727 for (auto& app_image : image_list.images) {
729 static_cast<image_x*>(calloc(1, sizeof(image_x)));
730 const std::string& lang = app_image.lang();
732 image->lang = strdup(lang.c_str());
734 image->lang = strdup(DEFAULT_LOCALE);
735 if (!app_image.section().empty())
736 image->section = strdup(app_image.section().c_str());
737 app->image = g_list_append(app->image, image);
742 template <typename T>
743 bool StepParseManifest::FillBackgroundCategoryInfo(application_x* app,
744 const T& background_category_data_list) {
745 for (const auto& background_category : background_category_data_list) {
746 app->background_category = g_list_append(
747 app->background_category, strdup(background_category.value().c_str()));
753 bool StepParseManifest::FillManifestX(manifest_x* manifest) {
754 if (!FillPackageInfo(manifest))
756 if (!FillInstallationInfo(manifest))
758 if (!FillUIApplication(manifest))
760 if (!FillServiceApplication(manifest))
762 if (!FillWidgetApplication(manifest))
764 if (!FillWatchApplication(manifest))
766 if (!FillPrivileges(manifest))
768 if (!FillAuthorInfo(manifest))
770 if (!FillDescriptionInfo(manifest))
775 Step::Status StepParseManifest::process() {
776 if (!LocateConfigFile()) {
777 // continue if this is recovery, manifest file may never been created
778 if (manifest_location_ == ManifestLocation::RECOVERY) {
779 LOG(DEBUG) << "Manifest for recovery not found";
780 return Step::Status::OK;
782 LOG(ERROR) << "No manifest file exists";
783 return Step::Status::MANIFEST_NOT_FOUND;
785 parser_.reset(new tpk::parse::TPKConfigParser());
786 if (!parser_->ParseManifest(path_)) {
787 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
788 return Step::Status::PARSE_ERROR;
791 // Copy data from ManifestData to InstallerContext
792 std::shared_ptr<const tpk::parse::PackageInfo> info =
793 std::static_pointer_cast<const tpk::parse::PackageInfo>(
794 parser_->GetManifestData(app_keys::kManifestKey));
796 context_->pkgid.set(info->package());
797 context_->pkg_path.set(
798 context_->root_application_path.get() / context_->pkgid.get());
800 manifest_x* manifest =
801 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
803 if (!FillManifestX(const_cast<manifest_x*>(manifest))) {
804 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
805 << parser_->GetErrorMessage();
806 return Step::Status::PARSE_ERROR;
809 if (!CheckFeatures())
810 return Status::PARSE_ERROR;
812 if (manifest_location_ == ManifestLocation::INSTALLED) {
813 // recovery of tep value for installed package
814 std::string old_tep =
815 QueryTepPath(context_->pkgid.get(), context_->uid.get());
816 if (!old_tep.empty())
817 manifest->tep_name = strdup(old_tep.c_str());
819 // recovery of zip mount file for installed package
820 std::string zip_mount_file =
821 QueryZipMountFile(context_->pkgid.get(), context_->uid.get());
822 if (!zip_mount_file.empty())
823 manifest->zip_mount_file = strdup(zip_mount_file.c_str());
826 // write pkgid for recovery file
827 if (context_->recovery_info.get().recovery_file) {
828 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
829 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
832 LOG(DEBUG) << "Parsed package id: " << info->package();
834 switch (store_location_) {
835 case StoreLocation::NORMAL:
836 context_->manifest_data.set(manifest);
838 case StoreLocation::BACKUP:
839 context_->old_manifest_data.set(manifest);
842 LOG(ERROR) << "Unknown store location for parsed data";
843 return Step::Status::ERROR;
845 return Step::Status::OK;
848 } // namespace configuration
849 } // namespace common_installer