Unnecessary queries if pkg_id is empty
[platform/core/appfw/wgt-backend.git] / src / wgt / step / configuration / step_parse.cc
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.
5
6 #include "wgt/step/configuration/step_parse.h"
7
8 #include <boost/filesystem/path.hpp>
9
10 #include <common/app_installer.h>
11 #include <common/paths.h>
12 #include <common/installer_context.h>
13 #include <common/pkgmgr_query.h>
14 #include <common/privileges.h>
15 #include <common/step/step.h>
16 #include <common/utils/glist_range.h>
17 #include <manifest_parser/utils/version_number.h>
18 #include <wgt_manifest_handlers/account_handler.h>
19 #include <wgt_manifest_handlers/app_control_handler.h>
20 #include <wgt_manifest_handlers/application_icons_handler.h>
21 #include <wgt_manifest_handlers/application_manifest_constants.h>
22 #include <wgt_manifest_handlers/background_category_handler.h>
23 #include <wgt_manifest_handlers/category_handler.h>
24 #include <wgt_manifest_handlers/content_handler.h>
25 #include <wgt_manifest_handlers/ime_handler.h>
26 #include <wgt_manifest_handlers/metadata_handler.h>
27 #include <wgt_manifest_handlers/service_handler.h>
28 #include <wgt_manifest_handlers/setting_handler.h>
29 #include <wgt_manifest_handlers/tizen_application_handler.h>
30 #include <wgt_manifest_handlers/widget_handler.h>
31 #include <wgt_manifest_handlers/w3c_pc_utils.h>
32
33 #include <pkgmgr/pkgmgr_parser.h>
34
35 #include <string.h>
36
37 #include <chrono>
38 #include <cstdio>
39 #include <cstdlib>
40 #include <memory>
41 #include <set>
42 #include <string>
43 #include <vector>
44 #include <utility>
45
46 #include "wgt/wgt_backend_data.h"
47
48 namespace bf = boost::filesystem;
49 namespace ci = common_installer;
50
51 namespace {
52
53 const char kCategoryWearableClock[] =
54     "http://tizen.org/category/wearable_clock";
55 const char kCategoryWatchClock[] = "com.samsung.wmanager.WATCH_CLOCK";
56
57 const char kManifestVersion[] = "1.0.0";
58 const char kTizenPackageXmlNamespace[] = "http://tizen.org/ns/packages";
59 const char kImeCategoryName[] = "http://tizen.org/category/ime";
60 const char kDownloadableFontCategoryName[] =
61     "http://tizen.org/category/downloadable_font";
62 const char kTTSCategoryName[] = "http://tizen.org/category/tts";
63
64 const char kResWgt[] = "res/wgt";
65 const char kConfigFileName[] = "config.xml";
66
67 GList* GenerateMetadataListX(const wgt::parse::MetaDataInfo& meta_info) {
68   GList* list = nullptr;
69   for (auto& meta : meta_info.metadata()) {
70     metadata_x* new_meta =
71         static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
72     new_meta->key = strdup(meta.first.c_str());
73     if (!meta.second.empty())
74       new_meta->value = strdup(meta.second.c_str());
75     list = g_list_append(list, new_meta);
76   }
77   return list;
78 }
79
80 void AppendWidgetMetadata(GList** metadatas,
81     const std::vector<std::pair<std::string, std::string>> metadata) {
82   GList* list = *metadatas;
83   for (auto& meta : metadata) {
84     metadata_x* new_meta =
85         static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
86     new_meta->key = strdup(meta.first.c_str());
87     if (!meta.second.empty())
88       new_meta->value = strdup(meta.second.c_str());
89
90     list = g_list_append(list, new_meta);
91   }
92
93   *metadatas = list;
94 }
95
96 void SetApplicationXDefaults(application_x* application) {
97   application->effectimage_type = strdup("image");
98   application->guestmode_visibility = strdup("true");
99   application->hwacceleration = strdup("default");
100   application->indicatordisplay = strdup("true");
101   application->launchcondition = strdup("false");
102   application->permission_type = strdup("normal");
103   application->process_pool = strdup("false");
104   application->recentimage = strdup("false");
105   application->screenreader = strdup("use-system-setting");
106   application->submode = strdup("false");
107   application->support_disable = strdup("false");
108   application->ui_gadget = strdup("false");
109   application->multiple = strdup("false");
110 }
111
112 template<typename T>
113 void AppendLabel(T* root, const std::string& label,
114                  const std::string& locale) {
115   label_x* label_item = reinterpret_cast<label_x*>(calloc(1, sizeof(label_x)));
116   label_item->name = strdup(label.c_str());
117   label_item->text = strdup(label.c_str());
118   label_item->lang = !locale.empty() ?
119       strdup(locale.c_str()) : strdup(DEFAULT_LOCALE);
120   root->label = g_list_append(root->label, label_item);
121 }
122
123 }  // namespace
124
125 namespace wgt {
126 namespace configuration {
127
128 namespace app_keys = wgt::application_widget_keys;
129 namespace sc = std::chrono;
130
131 StepParse::StepParse(common_installer::InstallerContext* context,
132                      ConfigLocation config_location,
133                      bool check_start_file)
134     : Step(context),
135       config_location_(config_location),
136       check_start_file_(check_start_file) {
137 }
138
139 std::set<std::string> StepParse::ExtractPrivileges(
140     std::shared_ptr<const wgt::parse::PermissionsInfo> perm_info) const {
141   return perm_info->GetAPIPermissions();
142 }
143
144 std::string StepParse::GetPackageVersion(
145      const std::string& manifest_version) {
146   if (manifest_version.empty()) {
147     return kManifestVersion;
148   }
149   std::string version = manifest_version.substr(0,
150       manifest_version.find_first_not_of("1234567890."));
151
152   return version;
153 }
154
155 bool StepParse::FillInstallationInfo(manifest_x* manifest) {
156   manifest->root_path = strdup(
157       (context_->root_application_path.get() / manifest->package).c_str());
158   manifest->installed_time =
159       strdup(std::to_string(sc::system_clock::to_time_t(
160           sc::system_clock::now())).c_str());
161   return true;
162 }
163
164 bool StepParse::FillIconPaths(manifest_x* manifest) {
165   auto app_info =
166       GetManifestDataForKey<const wgt::parse::TizenApplicationInfo>(
167              app_keys::kTizenApplicationKey);
168   if (!app_info) {
169     LOG(ERROR) << "Application info manifest data has not been found.";
170     return false;
171   }
172   auto icons_info =
173     GetManifestDataForKey<const wgt::parse::ApplicationIconsInfo>(
174            app_keys::kIconsKey);
175   if (!icons_info) {
176     icons_info.reset(new wgt::parse::ApplicationIconsInfo());
177   }
178   wgt::parse::LocalizedApplicationIconsInfo localized_list =
179       wgt::parse::GetLocalizedIconList(*icons_info, widget_path_);
180   // We need to generate icon for each locale and icons are already set into
181   // lookup order. There isn't said that all icons should be received from
182   // one <icon> tag position so we iterate utils we run out of icons creating
183   // any icon element that are possible for given locale.
184   std::set<std::string> found_locales;
185   for (auto& application_icon : localized_list) {
186     const std::string& locale = application_icon.locale();
187     if (found_locales.find(locale) != found_locales.end())
188       continue;
189     found_locales.insert(locale);
190
191     icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
192     bf::path icon_path = context_->root_application_path.get()
193         / app_info->package() / "res" / "wgt" / application_icon.path();
194     icon->text = strdup(icon_path.c_str());
195     if (!locale.empty())
196       icon->lang = strdup(locale.c_str());
197     else
198       icon->lang = strdup(DEFAULT_LOCALE);
199     manifest->icon = g_list_append(manifest->icon, icon);
200   }
201   return true;
202 }
203
204 bool StepParse::FillWidgetInfo(manifest_x* manifest) {
205   auto wgt_info =
206       GetManifestDataForKey<const wgt::parse::WidgetInfo>(
207              app_keys::kWidgetKey);
208
209   if (!wgt_info.get()) {
210     LOG(ERROR) << "Widget info manifest data has not been found.";
211     return false;
212   }
213
214   const std::string& version = wgt_info->version();
215
216   manifest->ns = strdup(kTizenPackageXmlNamespace);
217   manifest->version = strdup(GetPackageVersion(version).c_str());
218
219   for (auto& item : wgt_info->description_set()) {
220     description_x* description = reinterpret_cast<description_x*>
221         (calloc(1, sizeof(description_x)));
222     description->text = strdup(item.second.c_str());
223     description->lang = !item.first.empty() ?
224         strdup(item.first.c_str()) : strdup(DEFAULT_LOCALE);
225     manifest->description = g_list_append(manifest->description, description);
226   }
227
228   for (auto& item : wgt_info->name_set()) {
229     AppendLabel(manifest, item.second, item.first);
230   }
231
232   manifest->type = strdup("wgt");
233   manifest->appsetting = strdup("false");
234   manifest->nodisplay_setting = strdup("false");
235   manifest->installed_storage = strdup("installed_internal");
236
237   // For wgt package use the long name
238   application_x* app =
239       reinterpret_cast<application_x*>(manifest->application->data);
240   for (auto& item : wgt_info->name_set()) {
241     AppendLabel(app, item.second, item.first);
242   }
243
244   author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
245   if (!wgt_info->author().empty())
246     author->text = strdup(wgt_info->author().c_str());
247   if (!wgt_info->author_email().empty())
248     author->email = strdup(wgt_info->author_email().c_str());
249   if (!wgt_info->author_href().empty())
250     author->href = strdup(wgt_info->author_href().c_str());
251   author->lang = strdup(DEFAULT_LOCALE);
252   manifest->author = g_list_append(manifest->author, author);
253
254   auto settings_info =
255       GetManifestDataForKey<const wgt::parse::SettingInfo>(
256              wgt::application_widget_keys::kTizenSettingKey);
257   if (settings_info) {
258     switch (settings_info->install_location()) {
259     case wgt::parse::SettingInfo::InstallLocation::AUTO: {
260       manifest->installlocation = strdup("auto");
261       break;
262     }
263     case wgt::parse::SettingInfo::InstallLocation::INTERNAL: {
264       manifest->installlocation = strdup("internal-only");
265       break;
266     }
267     case wgt::parse::SettingInfo::InstallLocation::EXTERNAL: {
268       manifest->installlocation = strdup("prefer-external");
269       break;
270     }
271     }
272   } else {
273     manifest->installlocation = strdup("auto");
274   }
275
276   if (!context_->pkgid.get().empty()) {
277     // set update true if package is updated preload package
278     ci::RequestType req_type = context_->request_type.get();
279     if (ci::QueryIsUpdatedPackage(context_->pkgid.get(), context_->uid.get()))
280       manifest->update = strdup("true");
281     else if (ci::QueryIsPreloadPackage(context_->pkgid.get(),
282         context_->uid.get()) &&
283             (req_type == ci::RequestType::Update ||
284              req_type == ci::RequestType::Delta ||
285              req_type == ci::RequestType::MountUpdate ||
286              req_type == ci::RequestType::ReadonlyUpdateInstall))
287       manifest->update = strdup("true");
288     else
289       manifest->update = strdup("false");
290   }
291   else {
292     manifest->update = strdup("false");
293   }
294
295   return true;
296 }
297
298 bool StepParse::FillMainApplicationInfo(manifest_x* manifest) {
299   auto app_info =
300       GetManifestDataForKey<const wgt::parse::TizenApplicationInfo>(
301              app_keys::kTizenApplicationKey);
302   if (!app_info) {
303     LOG(ERROR) << "Application info manifest data has not been found.";
304     return false;
305   }
306   bool has_watch_category = false;
307   bool has_ime = false;
308   bool has_downloadable_font = false;
309   bool has_tts = false;
310   auto category_info =
311       GetManifestDataForKey<const wgt::parse::CategoryInfoList>(
312              app_keys::kTizenCategoryKey);
313
314   if (category_info) {
315     has_watch_category = std::find_if(category_info->categories.begin(),
316                                        category_info->categories.end(),
317                                        [](const std::string& category) {
318       return category == kCategoryWearableClock ||
319              category == kCategoryWatchClock;
320     }) != category_info->categories.end();
321     has_ime = std::find(category_info->categories.begin(),
322                                        category_info->categories.end(),
323                                        kImeCategoryName)
324         != category_info->categories.end();
325     has_downloadable_font = std::find(category_info->categories.begin(),
326                                        category_info->categories.end(),
327                                        kDownloadableFontCategoryName)
328         != category_info->categories.end();
329     has_tts = std::find(category_info->categories.begin(),
330                                        category_info->categories.end(),
331                                        kTTSCategoryName)
332         != category_info->categories.end();
333   }
334
335   // application data
336   application_x* application = reinterpret_cast<application_x*>(
337       calloc(1, sizeof(application_x)));
338   application->component_type =
339       has_watch_category ? strdup("watchapp") : strdup("uiapp");
340   application->mainapp = strdup("true");
341   application->appid = strdup(app_info->id().c_str());
342   auto settings_info =
343       GetManifestDataForKey<const wgt::parse::SettingInfo>(
344              wgt::application_widget_keys::kTizenSettingKey);
345
346   bool no_display = settings_info ? settings_info->no_display() : false;
347   bool has_no_display_category =
348       has_watch_category || has_ime || has_tts || has_downloadable_font;
349
350   application->nodisplay = (has_no_display_category || no_display) ?
351       strdup("true") : strdup("false");
352   application->taskmanage = has_no_display_category ? strdup("false") :
353       strdup("true");
354
355   SetApplicationXDefaults(application);
356   if (has_watch_category)
357     application->support_ambient =
358         strdup(app_info->ambient_support() ? "true" : "false");
359   else
360     application->support_ambient = strdup("false");
361   application->package = strdup(app_info->package().c_str());
362
363   application->exec =
364       strdup((context_->root_application_path.get() / app_info->package()
365               / "bin" / application->appid).c_str());
366   application->type = strdup("webapp");
367   application->onboot = strdup("false");
368   application->autorestart = strdup("false");
369
370   application->launch_mode = strdup(app_info->launch_mode().c_str());
371   for (auto& icon : GListRange<icon_x*>(manifest->icon)) {
372     icon_x* app_icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
373     app_icon->text = strdup(icon->text);
374     app_icon->lang = strdup(icon->lang);
375     application->icon = g_list_append(application->icon, app_icon);
376   }
377   // guarantees that the main app will be at the begining of the list
378   manifest->application = g_list_insert(manifest->application, application, 0);
379
380   manifest->package = strdup(app_info->package().c_str());
381   manifest->mainapp_id = strdup(app_info->id().c_str());
382   return true;
383 }
384
385 bool StepParse::FillServiceApplicationInfo(manifest_x* manifest) {
386   auto service_list =
387       GetManifestDataForKey<const wgt::parse::ServiceList>(
388              app_keys::kTizenServiceKey);
389   if (!service_list)
390     return true;
391   for (auto& service_info : service_list->services) {
392     application_x* application = reinterpret_cast<application_x*>
393         (calloc(1, sizeof(application_x)));
394     application->component_type = strdup("svcapp");
395     application->mainapp = strdup("false");
396     application->appid = strdup(service_info.id().c_str());
397     application->exec =
398         strdup((context_->root_application_path.get() / manifest->package
399                 / "bin" / application->appid).c_str());
400     application->type = strdup("webapp");
401     application->onboot =
402         service_info.on_boot() ? strdup("true") : strdup("false");
403     application->autorestart =
404         service_info.auto_restart() ? strdup("true") : strdup("false");
405     application->nodisplay = strdup("false");
406     application->taskmanage = strdup("true");
407     SetApplicationXDefaults(application);
408     application->support_ambient = strdup("false");
409     application->package = strdup(manifest->package);
410
411     for (auto& pair : service_info.names()) {
412       AppendLabel(application, pair.second, pair.first);
413     }
414
415     if (!service_info.icon().empty()) {
416       bf::path icon_path = context_->root_application_path.get()
417           / manifest->package / "res" / "wgt" / service_info.icon();
418       icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
419       icon->text = strdup(icon_path.c_str());
420       icon->lang = strdup(DEFAULT_LOCALE);
421       application->icon = g_list_append(application->icon, icon);
422     }
423
424     for (auto& category : service_info.categories()) {
425       application->category = g_list_append(application->category,
426                                             strdup(category.c_str()));
427     }
428
429     for (auto& pair : service_info.metadata_set()) {
430       metadata_x* item = reinterpret_cast<metadata_x*>(
431           calloc(1, sizeof(metadata_x)));
432       item->key = strdup(pair.first.c_str());
433       if (!pair.second.empty())
434         item->value = strdup(pair.second.c_str());
435       application->metadata = g_list_append(application->metadata, item);
436     }
437
438     manifest->application = g_list_append(manifest->application, application);
439   }
440   return true;
441 }
442
443 bool StepParse::FillWidgetApplicationInfo(manifest_x* manifest) {
444   auto appwidget_info =
445       GetManifestDataForKey<const wgt::parse::AppWidgetInfo>(
446              wgt::application_widget_keys::kTizenAppWidgetFullKey);
447   if (!appwidget_info)
448     return true;
449   for (auto& app_widget : appwidget_info->app_widgets()) {
450     application_x* application = reinterpret_cast<application_x*>
451         (calloc(1, sizeof(application_x)));
452     application->component_type = strdup("widgetapp");
453     application->mainapp = strdup("false");
454     application->appid = strdup(app_widget.id.c_str());
455     application->exec =
456         strdup((context_->root_application_path.get() / manifest->package
457                 / "bin" / application->appid).c_str());
458     application->type = strdup("webapp");
459     application->nodisplay = strdup("true");
460     application->taskmanage = strdup("false");
461     SetApplicationXDefaults(application);
462     application->support_ambient = strdup("false");
463     application->package = strdup(manifest->package);
464
465     if (!app_widget.label.default_value.empty()) {
466       AppendLabel(application, app_widget.label.default_value, std::string());
467     }
468
469     for (auto& pair : app_widget.label.lang_value_map) {
470       AppendLabel(application, pair.second, pair.first);
471     }
472
473     if (!app_widget.icon_src.empty()) {
474       icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
475       icon->text = strdup(app_widget.icon_src.c_str());
476       icon->lang = strdup(DEFAULT_LOCALE);
477       application->icon = g_list_append(application->icon, icon);
478     }
479
480     if (!app_widget.metadata.empty())
481       AppendWidgetMetadata(&application->metadata, app_widget.metadata);
482
483     manifest->application = g_list_append(manifest->application, application);
484   }
485   return true;
486 }
487
488
489 bool StepParse::FillBackgroundCategoryInfo(manifest_x* manifest) {
490   auto manifest_data = parser_->GetManifestData(
491       app_keys::kTizenBackgroundCategoryKey);
492   std::shared_ptr<const wgt::parse::BackgroundCategoryInfoList> bc_list =
493       std::static_pointer_cast<const wgt::parse::BackgroundCategoryInfoList>(
494           manifest_data);
495
496   if (!bc_list)
497     return true;
498
499   application_x* app =
500       reinterpret_cast<application_x*>(manifest->application->data);
501
502   for (auto& background_category : bc_list->background_categories) {
503     app->background_category = g_list_append(
504         app->background_category, strdup(background_category.value().c_str()));
505   }
506
507   return true;
508 }
509
510 bool StepParse::FillAppControl(manifest_x* manifest) {
511   auto app_info_list =
512       GetManifestDataForKey<const wgt::parse::AppControlInfoList>(
513              app_keys::kTizenApplicationAppControlsKey);
514
515   application_x* app =
516       reinterpret_cast<application_x*>(manifest->application->data);
517   if (app_info_list) {
518     for (const auto& control : app_info_list->controls) {
519       appcontrol_x* app_control =
520           static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
521       app_control->operation = strdup(control.operation().c_str());
522       app_control->mime = strdup(control.mime().c_str());
523       app_control->uri = strdup(control.uri().c_str());
524       app->appcontrol = g_list_append(app->appcontrol, app_control);
525     }
526   }
527   return true;
528 }
529
530 bool StepParse::FillPrivileges(manifest_x* manifest) {
531   auto perm_info =
532       GetManifestDataForKey<const wgt::parse::PermissionsInfo>(
533              app_keys::kTizenPermissionsKey);
534   std::set<std::string> privileges;
535   if (perm_info)
536     privileges = ExtractPrivileges(perm_info);
537
538   for (auto& priv : privileges) {
539     privilege_x* privilege =
540         reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
541     privilege->type = strdup(common_installer::kWebPrivilegeType);
542     privilege->value = strdup(priv.c_str());
543     manifest->privileges = g_list_append(manifest->privileges, privilege);
544   }
545   return true;
546 }
547
548 bool StepParse::FillCategories(manifest_x* manifest) {
549   auto category_info =
550       GetManifestDataForKey<const wgt::parse::CategoryInfoList>(
551              app_keys::kTizenCategoryKey);
552   if (!category_info)
553     return true;
554
555   application_x* app =
556       reinterpret_cast<application_x*>(manifest->application->data);
557   // there is one app atm
558   for (auto& category : category_info->categories) {
559     app->category = g_list_append(app->category, strdup(category.c_str()));
560   }
561   return true;
562 }
563
564 bool StepParse::FillMetadata(manifest_x* manifest) {
565   auto meta_info =
566       GetManifestDataForKey<const wgt::parse::MetaDataInfo>(
567              app_keys::kTizenMetaDataKey);
568   if (!meta_info)
569     return true;
570
571   for (application_x* app : GListRange<application_x*>(manifest->application)) {
572     app->metadata = GenerateMetadataListX(*meta_info);
573   }
574   return true;
575 }
576
577 bool StepParse::FillAppWidget() {
578   // This is needed to store preview icons which are not saved into manifest_x
579   WgtBackendData* backend_data =
580       static_cast<WgtBackendData*>(context_->backend_data.get());
581
582   auto appwidget_info =
583       GetManifestDataForKey<const wgt::parse::AppWidgetInfo>(
584              wgt::application_widget_keys::kTizenAppWidgetFullKey);
585   if (appwidget_info)
586     backend_data->appwidgets.set(*appwidget_info);
587   return true;
588 }
589
590 bool StepParse::FillAccounts(manifest_x* manifest) {
591   auto account_info =
592       GetManifestDataForKey<const wgt::parse::AccountInfo>(
593              app_keys::kAccountKey);
594   if (!account_info)
595     return true;
596   common_installer::AccountInfo info;
597   for (auto& account : account_info->accounts()) {
598     common_installer::SingleAccountInfo single_info;
599     single_info.capabilities = account.capabilities;
600     single_info.icon_paths = account.icon_paths;
601     single_info.multiple_account_support = account.multiple_account_support;
602     single_info.names = account.names;
603     // wgt can contain only one app so this assumes mainapp_id is valid here
604     single_info.appid = manifest->mainapp_id;
605     info.set_account(single_info);
606   }
607   context_->manifest_plugins_data.get().account_info.set(info);
608   return true;
609 }
610
611 bool StepParse::FillImeInfo() {
612   auto ime_info =
613       GetManifestDataForKey<const wgt::parse::ImeInfo>(
614              app_keys::kTizenImeKey);
615   if (!ime_info)
616     return true;
617
618   common_installer::ImeInfo info;
619   info.setUuid(ime_info->uuid());
620
621   const auto &languages = ime_info->languages();
622   for (const auto &language : languages)
623     info.AddLanguage(language);
624
625   context_->manifest_plugins_data.get().ime_info.set(std::move(info));
626   return true;
627 }
628
629 bool StepParse::FillExtraManifestInfo(manifest_x* manifest) {
630   return FillAccounts(manifest) && FillImeInfo() && FillAppWidget();
631 }
632
633 bool StepParse::FillManifestX(manifest_x* manifest) {
634   // Fill data for main application
635   if (!FillIconPaths(manifest))
636     return false;
637   if (!FillMainApplicationInfo(manifest))
638     return false;
639   if (!FillWidgetInfo(manifest))
640     return false;
641   if (!FillInstallationInfo(manifest))
642     return false;
643   if (!FillPrivileges(manifest))
644     return false;
645   if (!FillAppControl(manifest))
646     return false;
647   if (!FillCategories(manifest))
648     return false;
649   if (!FillMetadata(manifest))
650     return false;
651   if (!FillBackgroundCategoryInfo(manifest))
652     return false;
653
654   // Fill data for other applications
655   if (!FillAdditionalApplications(manifest))
656     return false;
657
658   // Fill extra data, other than manifest_x structure
659   if (!FillExtraManifestInfo(manifest))
660     return false;
661
662   return true;
663 }
664
665
666 bool StepParse::FillAdditionalApplications(manifest_x* manifest) {
667   if (!FillServiceApplicationInfo(manifest))
668     return false;
669   if (!FillWidgetApplicationInfo(manifest))
670     return false;
671   return true;
672 }
673
674 bool StepParse::LocateConfigFile() {
675   switch (config_location_) {
676     case ConfigLocation::PACKAGE:
677       return StepParse::Check(context_->unpacked_dir_path.get());
678     case ConfigLocation::INSTALLED:
679       return StepParse::Check(context_->pkg_path.get() / kResWgt);
680     case ConfigLocation::RECOVERY:
681       if (StepParse::Check(common_installer::GetBackupPathForPackagePath(
682           context_->root_application_path.get()
683               / context_->pkgid.get()) / kResWgt))
684         return true;
685       if (StepParse::Check(
686           context_->root_application_path.get()
687               / context_->pkgid.get() / kResWgt))
688         return true;
689       return false;
690     case ConfigLocation::RESOURCE_WGT:
691       return StepParse::Check(context_->unpacked_dir_path.get() / kResWgt);
692     default:
693       LOG(ERROR) << "Unknown config location";
694       return false;
695   }
696 }
697
698 common_installer::Step::Status StepParse::process() {
699   if (!LocateConfigFile()) {
700     LOG(ERROR) << "No config.xml";
701     return common_installer::Step::Status::MANIFEST_NOT_FOUND;
702   }
703
704   parser_.reset(new wgt::parse::WidgetConfigParser());
705   if (!parser_->ParseManifest(widget_path_ / kConfigFileName)) {
706     LOG(ERROR) << "[Parse] Parse failed. " <<  parser_->GetErrorMessage();
707     return common_installer::Step::Status::PARSE_ERROR;
708   }
709
710   WgtBackendData* backend_data =
711     static_cast<WgtBackendData*>(context_->backend_data.get());
712
713   if (check_start_file_) {
714     if (!parser_->CheckValidStartFile()) {
715       LOG(ERROR) << parser_->GetErrorMessage();
716       return common_installer::Step::Status::PARSE_ERROR;
717     }
718     if (!parser_->CheckValidServicesStartFiles()) {
719       LOG(ERROR) << parser_->GetErrorMessage();
720       return common_installer::Step::Status::PARSE_ERROR;
721     }
722   } else {
723     // making backup of content data and services content data
724     auto content_info =
725       GetManifestDataForKey<const wgt::parse::ContentInfo>(
726               wgt::application_widget_keys::kTizenContentKey);
727     auto service_list =
728       GetManifestDataForKey<const wgt::parse::ServiceList>(
729               wgt::application_widget_keys::kTizenServiceKey);
730     if (content_info)
731       backend_data->content.set(*content_info);
732     if (service_list)
733       backend_data->service_list.set(*service_list);
734   }
735
736   manifest_x* manifest =
737       static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
738   if (!FillManifestX(manifest)) {
739     LOG(ERROR) << "[Parse] Storing manifest_x failed. "
740                <<  parser_->GetErrorMessage();
741     return common_installer::Step::Status::PARSE_ERROR;
742   }
743
744   // Copy data from ManifestData to InstallerContext
745   auto info =
746       GetManifestDataForKey<const wgt::parse::TizenApplicationInfo>(
747               wgt::application_widget_keys::kTizenApplicationKey);
748   auto wgt_info =
749       GetManifestDataForKey<const wgt::parse::WidgetInfo>(
750               wgt::application_widget_keys::kTizenWidgetKey);
751
752   std::string name;
753   const auto& name_set = wgt_info->name_set();
754   if (name_set.find("") != name_set.end())
755     name = name_set.find("")->second;
756   if (name_set.begin() != name_set.end())
757     name = name_set.begin()->second;
758
759   std::string short_name;
760   const auto& short_name_set = wgt_info->short_name_set();
761   if (short_name_set.find("") != short_name_set.end())
762     short_name = short_name_set.find("")->second;
763   if (short_name_set.begin() != short_name_set.end())
764     short_name = short_name_set.begin()->second;
765
766   const std::string& package_version = wgt_info->version();
767   const std::string& required_api_version = info->required_version();
768
769   manifest->api_version = strdup(required_api_version.c_str());
770
771   context_->pkgid.set(manifest->package);
772
773   // write pkgid for recovery file
774   if (context_->recovery_info.get().recovery_file) {
775     context_->recovery_info.get().recovery_file->set_pkgid(manifest->package);
776     context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
777   }
778
779   auto perm_info =
780       GetManifestDataForKey<const wgt::parse::PermissionsInfo>(
781               wgt::application_widget_keys::kTizenPermissionsKey);
782   parser::PermissionSet permissions;
783   if (perm_info)
784      permissions = perm_info->GetAPIPermissions();
785
786   auto settings_info =
787       GetManifestDataForKey<const wgt::parse::SettingInfo>(
788               wgt::application_widget_keys::kTizenSettingKey);
789   if (settings_info)
790     backend_data->settings.set(*settings_info);
791
792   LOG(DEBUG) << " Read data -[ ";
793   LOG(DEBUG) << "App id: " << info->id();
794   LOG(DEBUG) << "  package     = " <<  info->package();
795   LOG(DEBUG) << "  id          = " <<  info->id();
796   LOG(DEBUG) << "  name        = " <<  name;
797   LOG(DEBUG) << "  short_name  = " <<  short_name;
798   LOG(DEBUG) << "  aplication version     = " <<  package_version;
799   LOG(DEBUG) << "  api_version = " <<  info->required_version();
800   LOG(DEBUG) << "  launch_mode = " <<  info->launch_mode();
801   LOG(DEBUG) << "  privileges -[";
802   for (const auto& p : permissions) {
803     LOG(DEBUG) << "    " << p;
804   }
805   LOG(DEBUG) << "  ]-";
806   LOG(DEBUG) << "]-";
807
808   if (context_->manifest_data.get())
809     pkgmgr_parser_free_manifest_xml(context_->manifest_data.get());
810
811   context_->manifest_data.set(manifest);
812   return common_installer::Step::Status::OK;
813 }
814
815 bool StepParse::Check(const boost::filesystem::path& widget_path) {
816   LOG(DEBUG) << "unpacked widget path: " << widget_path;
817
818   widget_path_ = widget_path;
819
820   boost::filesystem::path config = widget_path / kConfigFileName;
821   LOG(DEBUG) << "config.xml path: " << config;
822   if (!boost::filesystem::exists(config))
823     return false;
824   return true;
825 }
826
827 }  // namespace configuration
828 }  // namespace wgt