1 /* 2014, Copyright © Intel Coporation, license APACHE-2.0, see LICENSE file */
2 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a apache 2.0 license that can be
4 // found in the LICENSE file.
6 #include "wgt/step/step_parse.h"
8 #include <common/app_installer.h>
9 #include <common/installer_context.h>
10 #include <common/step/step.h>
11 #include <common/utils/glist_range.h>
12 #include <manifest_handlers/account_handler.h>
13 #include <manifest_handlers/app_control_handler.h>
14 #include <manifest_handlers/application_icons_handler.h>
15 #include <manifest_handlers/application_manifest_constants.h>
16 #include <manifest_handlers/background_category_handler.h>
17 #include <manifest_handlers/category_handler.h>
18 #include <manifest_handlers/content_handler.h>
19 #include <manifest_handlers/metadata_handler.h>
20 #include <manifest_handlers/service_handler.h>
21 #include <manifest_handlers/setting_handler.h>
22 #include <manifest_handlers/tizen_application_handler.h>
23 #include <manifest_handlers/widget_handler.h>
25 #include <pkgmgr/pkgmgr_parser.h>
37 #include "wgt/wgt_backend_data.h"
41 const std::string kManifestVersion = "1.0.0";
42 const char kTizenPackageXmlNamespace[] = "http://tizen.org/ns/packages";
44 GList* GenerateMetadataListX(const wgt::parse::MetaDataInfo& meta_info) {
45 GList* list = nullptr;
46 for (auto& meta : meta_info.metadata()) {
47 metadata_x* new_meta =
48 static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
49 new_meta->key = strdup(meta.first.c_str());
50 if (!meta.second.empty())
51 new_meta->value = strdup(meta.second.c_str());
52 list = g_list_append(list, new_meta);
57 void SetApplicationXDefaults(application_x* application) {
58 application->ambient_support = strdup("false");
59 application->effectimage_type = strdup("image");
60 application->enabled = strdup("true");
61 application->guestmode_visibility = strdup("true");
62 application->hwacceleration = strdup("default");
63 application->indicatordisplay = strdup("true");
64 application->launchcondition = strdup("false");
65 application->permission_type = strdup("normal");
66 application->process_pool = strdup("false");
67 application->recentimage = strdup("false");
68 application->screenreader = strdup("use-system-setting");
69 application->submode = strdup("false");
70 application->support_disable = strdup("false");
71 application->taskmanage = strdup("true");
72 application->ui_gadget = strdup("false");
80 namespace app_keys = wgt::application_widget_keys;
81 namespace sc = std::chrono;
83 StepParse::StepParse(common_installer::InstallerContext* context,
84 bool check_start_file)
86 check_start_file_(check_start_file) {
89 std::set<std::string> StepParse::ExtractPrivileges(
90 std::shared_ptr<const PermissionsInfo> perm_info) const {
91 return perm_info->GetAPIPermissions();
94 const std::string& StepParse::GetPackageVersion(
95 const std::string& manifest_version) {
96 if (!manifest_version.empty())
97 return manifest_version;
98 return kManifestVersion;
101 bool StepParse::FillInstallationInfo(manifest_x* manifest) {
102 manifest->root_path = strdup(
103 (context_->root_application_path.get() / manifest->package).c_str());
104 manifest->installed_time =
105 strdup(std::to_string(sc::system_clock::to_time_t(
106 sc::system_clock::now())).c_str());
110 bool StepParse::FillIconPaths(manifest_x* manifest) {
111 std::shared_ptr<const ApplicationIconsInfo> icons_info =
112 std::static_pointer_cast<const ApplicationIconsInfo>(
113 parser_->GetManifestData(app_keys::kIconsKey));
114 if (icons_info.get()) {
115 for (auto& application_icon : icons_info->icons()) {
116 icon_x* icon = reinterpret_cast<icon_x*> (calloc(1, sizeof(icon_x)));
117 icon->text = strdup(application_icon.path().c_str());
118 icon->lang = strdup(DEFAULT_LOCALE);
119 manifest->icon = g_list_append(manifest->icon, icon);
125 bool StepParse::FillWidgetInfo(manifest_x* manifest) {
126 std::shared_ptr<const WidgetInfo> wgt_info =
127 std::static_pointer_cast<const WidgetInfo>(parser_->GetManifestData(
128 app_keys::kWidgetKey));
129 if (!wgt_info.get()) {
130 LOG(ERROR) << "Widget info manifest data has not been found.";
134 const std::string& version = wgt_info->version();
136 manifest->ns = strdup(kTizenPackageXmlNamespace);
137 manifest->version = strdup(GetPackageVersion(version).c_str());
139 for (auto& item : wgt_info->description_set()) {
140 description_x* description = reinterpret_cast<description_x*>
141 (calloc(1, sizeof(description_x)));
142 description->text = strdup(item.second.c_str());
143 description->lang = !item.first.empty() ?
144 strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE);
145 manifest->description = g_list_append(manifest->description, description);
148 for (auto& item : wgt_info->name_set()) {
149 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
150 label->name = strdup(item.second.c_str());
151 label->text = strdup(item.second.c_str());
152 label->lang = !item.first.empty() ?
153 strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE);
154 manifest->label = g_list_append(manifest->label, label);
157 manifest->type = strdup("wgt");
158 manifest->appsetting = strdup("false");
159 manifest->nodisplay_setting = strdup("false");
161 // For wgt package use the long name
162 for (auto& item : wgt_info->name_set()) {
164 reinterpret_cast<application_x*>(manifest->application->data);
165 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
166 label->name = strdup(item.second.c_str());
167 label->text = strdup(item.second.c_str());
168 label->lang = !item.first.empty() ?
169 strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE);
170 app->label = g_list_append(app->label, label);
173 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
174 if (!wgt_info->author().empty())
175 author->text = strdup(wgt_info->author().c_str());
176 if (!wgt_info->author_email().empty())
177 author->email = strdup(wgt_info->author_email().c_str());
178 if (!wgt_info->author_href().empty())
179 author->href = strdup(wgt_info->author_href().c_str());
180 author->lang = strdup(DEFAULT_LOCALE);
181 manifest->author = g_list_append(manifest->author, author);
183 std::shared_ptr<const SettingInfo> settings_info =
184 std::static_pointer_cast<const SettingInfo>(
185 parser_->GetManifestData(
186 wgt::application_widget_keys::kTizenSettingKey));
188 switch (settings_info->install_location()) {
189 case wgt::parse::SettingInfo::InstallLocation::AUTO: {
190 manifest->installlocation = strdup("auto");
193 case wgt::parse::SettingInfo::InstallLocation::INTERNAL: {
194 manifest->installlocation = strdup("internal-only");
197 case wgt::parse::SettingInfo::InstallLocation::EXTERNAL: {
198 manifest->installlocation = strdup("prefer-external");
203 manifest->installlocation = strdup("auto");
209 bool StepParse::FillUIApplicationInfo(manifest_x* manifest) {
210 std::shared_ptr<const TizenApplicationInfo> app_info =
211 std::static_pointer_cast<const TizenApplicationInfo>(
212 parser_->GetManifestData(app_keys::kTizenApplicationKey));
214 LOG(ERROR) << "Application info manifest data has not been found.";
218 application_x* application = reinterpret_cast<application_x*>(
219 calloc(1, sizeof(application_x)));
220 application->component_type = strdup("uiapp");
221 application->mainapp = strdup("true");
222 application->nodisplay = strdup("false");
223 application->multiple = strdup("false");
224 application->appid = strdup(app_info->id().c_str());
225 SetApplicationXDefaults(application);
226 application->package = strdup(app_info->package().c_str());
229 strdup((context_->root_application_path.get() / app_info->package()
230 / "bin" / application->appid).c_str());
231 application->type = strdup("webapp");
232 application->onboot = strdup("false");
233 application->autorestart = strdup("false");
235 application->launch_mode = strdup(app_info->launch_mode().c_str());
236 if (manifest->icon) {
237 icon_x* icon = reinterpret_cast<icon_x*>(manifest->icon->data);
238 icon_x* app_icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
239 app_icon->text = strdup(icon->text);
240 app_icon->lang = strdup(icon->lang);
241 application->icon = g_list_append(application->icon, app_icon);
243 manifest->application = g_list_append(manifest->application, application);
245 manifest->package = strdup(app_info->package().c_str());
246 manifest->mainapp_id = strdup(app_info->id().c_str());
250 bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) {
251 std::shared_ptr<const ServiceList> service_list =
252 std::static_pointer_cast<const ServiceList>(
253 parser_->GetManifestData(app_keys::kTizenServiceKey));
256 for (auto& service_info : service_list->services) {
257 application_x* application = reinterpret_cast<application_x*>
258 (calloc(1, sizeof(application_x)));
259 application->component_type = strdup("svcapp");
260 application->mainapp = strdup("false");
261 application->nodisplay = strdup("false");
262 application->multiple = strdup("false");
263 application->appid = strdup(service_info.id().c_str());
265 strdup((context_->root_application_path.get() / manifest->package
266 / "bin" / application->appid).c_str());
267 application->type = strdup("webapp");
268 application->onboot =
269 service_info.on_boot() ? strdup("true") : strdup("false");
270 application->autorestart =
271 service_info.auto_restart() ? strdup("true") : strdup("false");
272 SetApplicationXDefaults(application);
273 application->package = strdup(manifest->package);
275 for (auto& pair : service_info.names()) {
276 label_x* label = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
277 label->lang = !pair.first.empty() ?
278 strdup(pair.first.c_str()) : strdup(DEFAULT_LOCALE);
279 label->name = strdup(pair.second.c_str());
280 label->text = strdup(pair.second.c_str());
281 application->label = g_list_append(application->label, label);
284 if (!service_info.icon().empty()) {
285 icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
286 icon->text = strdup(service_info.icon().c_str());
287 icon->lang = strdup(DEFAULT_LOCALE);
288 application->icon = g_list_append(application->icon, icon);
291 // TODO(t.iwanek): what about description, how is it different from name?
293 for (auto& category : service_info.categories()) {
294 application->category = g_list_append(application->category,
295 strdup(category.c_str()));
298 for (auto& pair : service_info.metadata_set()) {
299 metadata_x* item = reinterpret_cast<metadata_x*>(
300 calloc(1, sizeof(metadata_x)));
301 item->key = strdup(pair.first.c_str());
302 if (!pair.second.empty())
303 item->value = strdup(pair.second.c_str());
304 application->metadata = g_list_append(application->metadata, item);
307 manifest->application = g_list_append(manifest->application, application);
312 bool StepParse::FillBackgroundCategoryInfo(manifest_x* manifest) {
313 auto manifest_data = parser_->GetManifestData(
314 app_keys::kTizenBackgroundCategoryKey);
315 std::shared_ptr<const BackgroundCategoryInfoList> bc_list =
316 std::static_pointer_cast<const BackgroundCategoryInfoList>(manifest_data);
322 reinterpret_cast<application_x*>(manifest->application->data);
324 for (auto& background_category : bc_list->background_categories) {
325 app->background_category = g_list_append(
326 app->background_category, strdup(background_category.value().c_str()));
332 bool StepParse::FillAppControl(manifest_x* manifest) {
333 std::shared_ptr<const AppControlInfoList> app_info_list =
334 std::static_pointer_cast<const AppControlInfoList>(
335 parser_->GetManifestData(app_keys::kTizenApplicationAppControlsKey));
338 reinterpret_cast<application_x*>(manifest->application->data);
340 for (const auto& control : app_info_list->controls) {
341 appcontrol_x* app_control =
342 static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
343 app_control->operation = strdup(control.operation().c_str());
344 app_control->mime = strdup(control.mime().c_str());
345 app_control->uri = strdup(control.uri().c_str());
346 app->appcontrol = g_list_append(app->appcontrol, app_control);
352 bool StepParse::FillPrivileges(manifest_x* manifest) {
353 std::shared_ptr<const PermissionsInfo> perm_info =
354 std::static_pointer_cast<const PermissionsInfo>(parser_->GetManifestData(
355 app_keys::kTizenPermissionsKey));
356 std::set<std::string> privileges;
358 privileges = ExtractPrivileges(perm_info);
360 for (auto& priv : privileges) {
361 manifest->privileges =
362 g_list_append(manifest->privileges, strdup(priv.c_str()));
367 bool StepParse::FillCategories(manifest_x* manifest) {
368 std::shared_ptr<const CategoryInfoList> category_info =
369 std::static_pointer_cast<const CategoryInfoList>(parser_->GetManifestData(
370 app_keys::kTizenCategoryKey));
375 reinterpret_cast<application_x*>(manifest->application->data);
376 // there is one app atm
377 for (auto& category : category_info->categories) {
378 app->category = g_list_append(app->category, strdup(category.c_str()));
383 bool StepParse::FillMetadata(manifest_x* manifest) {
384 std::shared_ptr<const MetaDataInfo> meta_info =
385 std::static_pointer_cast<const MetaDataInfo>(parser_->GetManifestData(
386 app_keys::kTizenMetaDataKey));
390 for (application_x* app : GListRange<application_x*>(manifest->application)) {
391 app->metadata = GenerateMetadataListX(*meta_info);
396 bool StepParse::FillAccounts(manifest_x* manifest) {
397 std::shared_ptr<const AccountInfo> account_info =
398 std::static_pointer_cast<const AccountInfo>(parser_->GetManifestData(
399 app_keys::kAccountKey));
402 common_installer::AccountInfo info;
403 for (auto& account : account_info->accounts()) {
404 common_installer::SingleAccountInfo single_info;
405 single_info.capabilities = account.capabilities;
406 single_info.icon_paths = account.icon_paths;
407 single_info.multiple_account_support = account.multiple_account_support;
408 single_info.names = account.names;
409 // wgt can contain only one app so this assumes mainapp_id is valid here
410 single_info.appid = manifest->mainapp_id;
411 info.set_account(single_info);
413 context_->manifest_plugins_data.get().account_info.set(info);
417 bool StepParse::FillExtraManifestInfo(manifest_x* manifest) {
418 return FillAccounts(manifest);
421 bool StepParse::FillManifestX(manifest_x* manifest) {
422 if (!FillIconPaths(manifest))
424 if (!FillUIApplicationInfo(manifest))
426 if (!FillWidgetInfo(manifest))
428 if (!FillInstallationInfo(manifest))
430 if (!FillPrivileges(manifest))
432 if (!FillAppControl(manifest))
434 if (!FillCategories(manifest))
436 if (!FillMetadata(manifest))
438 // TODO(t.iwanek): fix adding ui application element
439 // for now adding application service is added here because rest of code
440 // assumes that there is one application at manifest->application
441 // so this must execute last
442 if (!FillServiceApplicationInfo(manifest))
444 if (!FillBackgroundCategoryInfo(manifest))
446 if (!FillExtraManifestInfo(manifest))
451 bool StepParse::LocateConfigFile() {
452 return StepParse::Check(context_->unpacked_dir_path.get());
455 common_installer::Step::Status StepParse::process() {
456 if (!LocateConfigFile()) {
457 LOG(ERROR) << "No config.xml";
458 return common_installer::Step::Status::ERROR;
461 parser_.reset(new wgt::parse::WidgetConfigParser());
462 if (!parser_->ParseManifest(config_)) {
463 LOG(ERROR) << "[Parse] Parse failed. " << parser_->GetErrorMessage();
464 return common_installer::Step::Status::ERROR;
466 if (check_start_file_) {
467 if (!parser_->HasValidStartFile()) {
468 LOG(ERROR) << parser_->GetErrorMessage();
469 return common_installer::Step::Status::ERROR;
471 if (!parser_->HasValidServicesStartFiles()) {
472 LOG(ERROR) << parser_->GetErrorMessage();
473 return common_installer::Step::Status::ERROR;
477 manifest_x* manifest =
478 static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
479 if (!FillManifestX(manifest)) {
480 LOG(ERROR) << "[Parse] Storing manifest_x failed. "
481 << parser_->GetErrorMessage();
482 return common_installer::Step::Status::ERROR;
485 // Copy data from ManifestData to InstallerContext
486 std::shared_ptr<const TizenApplicationInfo> info =
487 std::static_pointer_cast<const TizenApplicationInfo>(
488 parser_->GetManifestData(
489 wgt::application_widget_keys::kTizenApplicationKey));
490 std::shared_ptr<const WidgetInfo> wgt_info =
491 std::static_pointer_cast<const WidgetInfo>(
492 parser_->GetManifestData(
493 wgt::application_widget_keys::kTizenWidgetKey));
496 const auto& name_set = wgt_info->name_set();
497 if (name_set.find("") != name_set.end())
498 name = name_set.find("")->second;
499 if (name_set.begin() != name_set.end())
500 name = name_set.begin()->second;
502 std::string short_name;
503 const auto& short_name_set = wgt_info->short_name_set();
504 if (short_name_set.find("") != short_name_set.end())
505 short_name = short_name_set.find("")->second;
506 if (short_name_set.begin() != short_name_set.end())
507 short_name = short_name_set.begin()->second;
509 const std::string& package_version = wgt_info->version();
510 const std::string& required_api_version = info->required_version();
512 manifest->api_version = strdup(required_api_version.c_str());
513 context_->pkgid.set(manifest->package);
515 // write pkgid for recovery file
516 if (context_->recovery_info.get().recovery_file) {
517 context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
518 context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
521 std::shared_ptr<const PermissionsInfo> perm_info =
522 std::static_pointer_cast<const PermissionsInfo>(
523 parser_->GetManifestData(
524 wgt::application_widget_keys::kTizenPermissionsKey));
525 parser::PermissionSet permissions;
527 permissions = perm_info->GetAPIPermissions();
529 std::unique_ptr<WgtBackendData> backend_data(new WgtBackendData());
531 std::shared_ptr<const SettingInfo> settings_info =
532 std::static_pointer_cast<const SettingInfo>(
533 parser_->GetManifestData(
534 wgt::application_widget_keys::kTizenSettingKey));
536 backend_data->settings.set(*settings_info);
538 context_->backend_data.set(backend_data.release());
540 LOG(DEBUG) << " Read data -[ ";
541 LOG(DEBUG) << "App id: " << info->id();
542 LOG(DEBUG) << " package = " << info->package();
543 LOG(DEBUG) << " id = " << info->id();
544 LOG(DEBUG) << " name = " << name;
545 LOG(DEBUG) << " short_name = " << short_name;
546 LOG(DEBUG) << " aplication version = " << package_version;
547 LOG(DEBUG) << " api_version = " << info->required_version();
548 LOG(DEBUG) << " launch_mode = " << info->launch_mode();
549 LOG(DEBUG) << " privileges -[";
550 for (const auto& p : permissions) {
551 LOG(DEBUG) << " " << p;
556 context_->manifest_data.set(manifest);
557 return common_installer::Step::Status::OK;
560 bool StepParse::Check(const boost::filesystem::path& widget_path) {
561 boost::filesystem::path config = widget_path;
562 config /= "config.xml";
564 LOG(DEBUG) << "config.xml path: " << config;
566 if (!boost::filesystem::exists(config))