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