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