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