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