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