Fix wrong condition for checking shortcut info
[platform/core/appfw/wgt-backend.git] / src / wgt / step / pkgmgr / step_generate_xml.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/pkgmgr/step_generate_xml.h"
7
8 #include <boost/filesystem/path.hpp>
9 #include <boost/system/error_code.hpp>
10
11 #include <common/utils/file_util.h>
12 #include <common/utils/glist_range.h>
13 #include <common/privileges.h>
14
15 #include <libxml/parser.h>
16 #include <libxml/xmlreader.h>
17 #include <pkgmgr-info.h>
18 #include <pkgmgr_parser.h>
19 #include <tzplatform_config.h>
20 #include <unistd.h>
21
22 #include <cassert>
23 #include <cstring>
24 #include <string>
25
26 #include "wgt/wgt_backend_data.h"
27
28 namespace bs = boost::system;
29 namespace bf = boost::filesystem;
30
31 namespace {
32
33 const char kResWgt[] = "res/wgt";
34 const char kSharedRes[] = "shared/res";
35
36 void WriteUIApplicationAttributes(
37     xmlTextWriterPtr writer, application_x *app) {
38   if (app->taskmanage)
39     xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage",
40         BAD_CAST app->taskmanage);
41   if (app->nodisplay)
42     xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay",
43         BAD_CAST app->nodisplay);
44   if (app->multiple)
45     xmlTextWriterWriteAttribute(writer, BAD_CAST "multiple",
46         BAD_CAST app->multiple);
47   if (app->launch_mode && strlen(app->launch_mode))
48     xmlTextWriterWriteAttribute(writer, BAD_CAST "launch_mode",
49         BAD_CAST app->launch_mode);
50   if (app->ui_gadget && strlen(app->ui_gadget))
51     xmlTextWriterWriteAttribute(writer, BAD_CAST "ui-gadget",
52         BAD_CAST app->ui_gadget);
53   if (app->submode && strlen(app->submode))
54     xmlTextWriterWriteAttribute(writer, BAD_CAST "submode",
55         BAD_CAST app->submode);
56   if (app->submode_mainid && strlen(app->submode_mainid))
57     xmlTextWriterWriteAttribute(writer, BAD_CAST "submode-mainid",
58         BAD_CAST app->submode_mainid);
59   if (app->indicatordisplay && strlen(app->indicatordisplay))
60     xmlTextWriterWriteAttribute(writer, BAD_CAST "indicatordisplay",
61         BAD_CAST app->indicatordisplay);
62   if (app->portraitimg && strlen(app->portraitimg))
63     xmlTextWriterWriteAttribute(writer, BAD_CAST "portrait-effectimage",
64         BAD_CAST app->portraitimg);
65   if (app->landscapeimg && strlen(app->landscapeimg))
66     xmlTextWriterWriteAttribute(writer, BAD_CAST "landscape-effectimage",
67         BAD_CAST app->landscapeimg);
68   if (app->effectimage_type && strlen(app->effectimage_type))
69     xmlTextWriterWriteAttribute(writer, BAD_CAST "effectimage-type",
70         BAD_CAST app->effectimage_type);
71   if (app->hwacceleration && strlen(app->hwacceleration))
72     xmlTextWriterWriteAttribute(writer, BAD_CAST "hwacceleration",
73         BAD_CAST app->hwacceleration);
74 }
75
76 void WriteServiceApplicationAttributes(
77     xmlTextWriterPtr writer, application_x *app) {
78   xmlTextWriterWriteAttribute(writer, BAD_CAST "auto-restart",
79       BAD_CAST(app->autorestart ? app->autorestart : "false"));
80   xmlTextWriterWriteAttribute(writer, BAD_CAST "on-boot",
81       BAD_CAST(app->onboot ? app->onboot : "false"));
82   if (app->taskmanage)
83       xmlTextWriterWriteAttribute(writer, BAD_CAST "taskmanage",
84          BAD_CAST app->taskmanage);
85 }
86
87 bool WriteWidgetApplicationAttributesAndElements(
88     xmlTextWriterPtr writer, application_x *app,
89     const wgt::parse::AppWidgetInfo& widget_info,
90     const bf::path& shared_path) {
91   if (app->nodisplay)
92     xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay",
93         BAD_CAST app->nodisplay);
94   if (app->multiple)
95     xmlTextWriterWriteAttribute(writer, BAD_CAST "multiple",
96         BAD_CAST app->multiple);
97   if (app->mainapp)
98     xmlTextWriterWriteAttribute(writer, BAD_CAST "main",
99         BAD_CAST app->mainapp);
100
101   auto& appwidgets = widget_info.app_widgets();
102   const auto& appwidget = std::find_if(appwidgets.begin(), appwidgets.end(),
103                                  [app](const wgt::parse::AppWidget& widget) {
104                                     return widget.id == app->appid;
105                                  });
106   if (appwidget == appwidgets.end()) {
107     return true;
108   }
109
110   // Add extra elements for wgt widget-application
111   if (!appwidget->update_period.empty()) {
112         xmlTextWriterWriteAttribute(writer, BAD_CAST "update-period", BAD_CAST
113             std::to_string(static_cast<int>(
114                     appwidget->update_period.front())).c_str());
115   }
116
117   xmlTextWriterWriteAttribute(writer, BAD_CAST "max-instance",
118       BAD_CAST std::to_string(appwidget->max_instance).c_str());
119
120   for (auto& size : appwidget->content_size) {
121     xmlTextWriterStartElement(writer, BAD_CAST "support-size");
122
123     std::string type = wgt::parse::AppWidgetSizeTypeToString(size.type);
124     if (!size.preview.empty()) {
125       std::string icon_name = shared_path.string() + "/"
126           + appwidget->id + "." + type + "." + "preview" +
127           bf::path(size.preview).extension().string();
128       xmlTextWriterWriteAttribute(writer, BAD_CAST "preview",
129           BAD_CAST icon_name.c_str());  // NOLINT
130     }
131
132     xmlTextWriterWriteAttribute(writer, BAD_CAST "frame",
133                                 BAD_CAST "true");
134     xmlTextWriterWriteString(writer,
135         BAD_CAST type.c_str());
136     xmlTextWriterEndElement(writer);
137   }
138
139   for (auto& pair : appwidget->metadata) {
140     xmlTextWriterStartElement(writer, BAD_CAST "metadata");
141     xmlTextWriterWriteAttribute(writer, BAD_CAST "key",
142                                 BAD_CAST pair.first.c_str());
143     if (!pair.second.empty())
144       xmlTextWriterWriteAttribute(writer, BAD_CAST "value",
145                                   BAD_CAST pair.second.c_str());
146     xmlTextWriterEndElement(writer);
147   }
148   return true;
149 }
150
151 void WriteWatchApplicationAttributes(
152     xmlTextWriterPtr writer, application_x* app) {
153   if (app->support_ambient)
154     xmlTextWriterWriteAttribute(writer, BAD_CAST "ambient-support",
155         BAD_CAST app->support_ambient);
156 }
157
158 }  // namespace
159
160 namespace wgt {
161 namespace pkgmgr {
162
163 common_installer::Step::Status StepGenerateXml::GenerateApplicationCommonXml(
164     application_x* app, xmlTextWriterPtr writer, AppCompType type) {
165   xmlTextWriterWriteAttribute(writer, BAD_CAST "appid", BAD_CAST app->appid);
166
167   // binary is a symbolic link named <appid> and is located in <pkgid>/<appid>
168   bf::path exec_path = context_->pkg_path.get()
169       / bf::path("bin") / bf::path(app->appid);
170   xmlTextWriterWriteAttribute(writer, BAD_CAST "exec",
171                               BAD_CAST exec_path.string().c_str());
172   if (app->type)
173     xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST app->type);
174   else
175     xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST "capp");
176
177   if (app->process_pool && strlen(app->process_pool))
178     xmlTextWriterWriteAttribute(writer, BAD_CAST "process-pool",
179                                 BAD_CAST app->process_pool);
180   // app-specific attributes
181   switch (type) {
182   case AppCompType::UIAPP:
183     WriteUIApplicationAttributes(writer, app);
184     break;
185   case AppCompType::SVCAPP:
186     WriteServiceApplicationAttributes(writer, app);
187     break;
188   case AppCompType::WIDGETAPP:
189     if (!WriteWidgetApplicationAttributesAndElements(writer, app,
190         static_cast<WgtBackendData*>(
191             context_->backend_data.get())->appwidgets.get(),
192         context_->pkg_path.get() / "shared" / "res"))
193       return Status::MANIFEST_ERROR;
194     break;
195   case AppCompType::WATCHAPP:
196     WriteWatchApplicationAttributes(writer, app);
197     break;
198   }
199
200   for (label_x* label : GListRange<label_x*>(app->label)) {
201     if (label->name && strcmp(label->name, "") != 0) {
202       xmlTextWriterStartElement(writer, BAD_CAST "label");
203       if (label->lang && strcmp(DEFAULT_LOCALE, label->lang) != 0) {
204         xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
205                                     BAD_CAST label->lang);
206       }
207       xmlTextWriterWriteString(writer, BAD_CAST label->name);
208       xmlTextWriterEndElement(writer);
209     }
210   }
211
212   for (auto& icon : GListRange<icon_x*>(app->icon)) {
213     xmlTextWriterStartElement(writer, BAD_CAST "icon");
214     if (icon->lang && strcmp(DEFAULT_LOCALE, icon->lang) != 0) {
215       xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
216                                   BAD_CAST icon->lang);
217     }
218     xmlTextWriterWriteString(writer, BAD_CAST icon->text);
219     xmlTextWriterEndElement(writer);
220   }
221
222   for (image_x* image : GListRange<image_x*>(app->image)) {
223     xmlTextWriterStartElement(writer, BAD_CAST "image");
224     if (image->lang && strcmp(DEFAULT_LOCALE, image->lang) != 0) {
225       xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
226
227                                   BAD_CAST image->lang);
228     }
229     if (image->section)
230       xmlTextWriterWriteAttribute(writer, BAD_CAST "section",
231                                   BAD_CAST image->section);
232     xmlTextWriterEndElement(writer);
233   }
234
235   for (appcontrol_x* appc : GListRange<appcontrol_x*>(app->appcontrol)) {
236     xmlTextWriterStartElement(writer, BAD_CAST "app-control");
237
238     if (appc->operation) {
239       xmlTextWriterStartElement(writer, BAD_CAST "operation");
240       xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
241           BAD_CAST appc->operation);
242       xmlTextWriterEndElement(writer);
243     }
244
245     if (appc->uri) {
246       xmlTextWriterStartElement(writer, BAD_CAST "uri");
247       xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
248           BAD_CAST appc->uri);
249       xmlTextWriterEndElement(writer);
250     }
251
252     if (appc->mime) {
253       xmlTextWriterStartElement(writer, BAD_CAST "mime");
254       xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
255           BAD_CAST appc->mime);
256       xmlTextWriterEndElement(writer);
257     }
258
259     xmlTextWriterEndElement(writer);
260   }
261
262   for (datacontrol_x* datacontrol :
263        GListRange<datacontrol_x*>(app->datacontrol)) {
264     xmlTextWriterStartElement(writer, BAD_CAST "datacontrol");
265     if (datacontrol->access) {
266       xmlTextWriterWriteAttribute(writer, BAD_CAST "access",
267           BAD_CAST datacontrol->access);
268     }
269     if (datacontrol->providerid) {
270       xmlTextWriterWriteAttribute(writer, BAD_CAST "providerid",
271           BAD_CAST datacontrol->providerid);
272     }
273     if (datacontrol->type) {
274       xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
275           BAD_CAST datacontrol->type);
276     }
277     xmlTextWriterEndElement(writer);
278   }
279
280   for (metadata_x* meta : GListRange<metadata_x*>(app->metadata)) {
281     xmlTextWriterStartElement(writer, BAD_CAST "metadata");
282     xmlTextWriterWriteAttribute(writer, BAD_CAST "key",
283         BAD_CAST meta->key);
284     if (meta->value)
285       xmlTextWriterWriteAttribute(writer, BAD_CAST "value",
286           BAD_CAST meta->value);
287     xmlTextWriterEndElement(writer);
288   }
289
290   for (const char* category : GListRange<char*>(app->category)) {
291     xmlTextWriterStartElement(writer, BAD_CAST "category");
292     xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST category);
293     xmlTextWriterEndElement(writer);
294   }
295
296   for (const char* background_category : GListRange<char*>(
297       app->background_category)) {
298     xmlTextWriterStartElement(writer, BAD_CAST "background-category");
299     xmlTextWriterWriteAttribute(writer, BAD_CAST "value",
300         BAD_CAST background_category);
301     xmlTextWriterEndElement(writer);
302   }
303
304   return Step::Status::OK;
305 }
306
307 common_installer::Step::Status StepGenerateXml::undo() {
308   bs::error_code error;
309   if (bf::exists(context_->xml_path.get()))
310     bf::remove_all(context_->xml_path.get(), error);
311   return Status::OK;
312 }
313
314 common_installer::Step::Status StepGenerateXml::precheck() {
315   if (!context_->manifest_data.get()) {
316     LOG(ERROR) << "manifest_data attribute is empty";
317     return Step::Status::INVALID_VALUE;
318   }
319   if (context_->pkgid.get().empty()) {
320     LOG(ERROR) << "pkgid attribute is empty";
321     return Step::Status::PACKAGE_NOT_FOUND;
322   }
323
324   if (!context_->manifest_data.get()->application) {
325     LOG(ERROR) << "No application in package";
326     return Step::Status::INVALID_VALUE;
327   }
328
329   return Step::Status::OK;
330 }
331
332 common_installer::Step::Status StepGenerateXml::process() {
333   bf::path xml_path =
334       bf::path(getUserManifestPath(context_->uid.get(),
335                   context_->is_readonly_package.get()))
336       / bf::path(context_->pkgid.get());
337   xml_path += ".xml";
338   context_->xml_path.set(xml_path.string());
339
340   bs::error_code error;
341   if (!bf::exists(xml_path.parent_path(), error)) {
342     if (!common_installer::CreateDir(xml_path.parent_path())) {
343       LOG(ERROR) <<
344           "Directory for manifest xml is missing and cannot be created";
345       return Status::MANIFEST_ERROR;
346     }
347   }
348
349   xmlTextWriterPtr writer;
350   writer = xmlNewTextWriterFilename(context_->xml_path.get().c_str(), 0);
351   if (!writer) {
352     LOG(ERROR) << "Failed to create new file";
353     return Step::Status::MANIFEST_ERROR;
354   }
355
356   xmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr);
357   xmlTextWriterSetIndent(writer, 1);
358
359   Status status = GenerateManifestElement(writer);
360   if (status != Status::OK) {
361     return status;
362   }
363
364   xmlTextWriterEndDocument(writer);
365   xmlFreeTextWriter(writer);
366
367   if (pkgmgr_parser_check_manifest_validation(
368       context_->xml_path.get().c_str()) != 0) {
369     LOG(ERROR) << "Manifest is not valid";
370     return Step::Status::MANIFEST_ERROR;
371   }
372
373   LOG(DEBUG) << "Successfully create manifest xml "
374       << context_->xml_path.get();
375   return Status::OK;
376 }
377
378 common_installer::Step::Status StepGenerateXml::GenerateManifestElement(
379         xmlTextWriterPtr writer) {
380   xmlTextWriterStartElement(writer, BAD_CAST "manifest");
381
382   GenerateManifestElementAttributes(writer);
383   GenerateLangLabels(writer);
384   GenerateAuthor(writer);
385   GenerateDescription(writer);
386   Status status = GenerateApplications(writer);
387   if (status != Status::OK) {
388     return status;
389   }
390   GeneratePrivilege(writer);
391   GenerateAccount(writer);
392   GenerateIme(writer);
393   GenerateProfiles(writer);
394   GenerateShortcuts(writer);
395
396   xmlTextWriterEndElement(writer);
397   return Status::OK;
398 }
399
400 void StepGenerateXml::GenerateManifestElementAttributes(
401         xmlTextWriterPtr writer) {
402   xmlTextWriterWriteAttribute(writer, BAD_CAST "xmlns",
403       BAD_CAST "http://tizen.org/ns/packages");
404   xmlTextWriterWriteAttribute(writer, BAD_CAST "package",
405       BAD_CAST context_->manifest_data.get()->package);
406   xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
407       BAD_CAST context_->manifest_data.get()->type);
408   xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
409       BAD_CAST context_->manifest_data.get()->version);
410   xmlTextWriterWriteAttribute(writer, BAD_CAST "api-version",
411       BAD_CAST context_->manifest_data.get()->api_version);
412   xmlTextWriterWriteAttribute(writer, BAD_CAST "nodisplay-setting",
413       BAD_CAST context_->manifest_data.get()->nodisplay_setting);
414   if (context_->is_readonly_package.get()) {
415     xmlTextWriterWriteAttribute(writer, BAD_CAST "readonly", BAD_CAST "true");
416     xmlTextWriterWriteAttribute(writer, BAD_CAST "preload", BAD_CAST "true");
417   } else if (context_->is_preload_rw_package.get()) {
418     xmlTextWriterWriteAttribute(writer, BAD_CAST "preload", BAD_CAST "true");
419   }
420 }
421
422 void StepGenerateXml::GenerateLangLabels(xmlTextWriterPtr writer) {
423   for (label_x* label :
424        GListRange<label_x*>(context_->manifest_data.get()->label)) {
425     if (label->name && strcmp(label->name, "") != 0) {
426       xmlTextWriterStartElement(writer, BAD_CAST "label");
427       if (label->lang && strcmp(DEFAULT_LOCALE, label->lang) != 0) {
428       xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
429                                     BAD_CAST label->lang);
430       }
431       xmlTextWriterWriteString(writer, BAD_CAST label->name);
432       xmlTextWriterEndElement(writer);
433     }
434   }
435 }
436
437 void StepGenerateXml::GenerateAuthor(xmlTextWriterPtr writer) {
438   for (author_x* author :
439        GListRange<author_x*>(context_->manifest_data.get()->author)) {
440     xmlTextWriterStartElement(writer, BAD_CAST "author");
441     if (author->email && strlen(author->email)) {
442       xmlTextWriterWriteAttribute(writer, BAD_CAST "email",
443                                   BAD_CAST author->email);
444     }
445     if (author->href && strlen(author->href)) {
446       xmlTextWriterWriteAttribute(writer, BAD_CAST "href",
447                                   BAD_CAST author->href);
448     }
449     xmlTextWriterWriteString(writer, BAD_CAST author->text);
450     xmlTextWriterEndElement(writer);
451   }
452 }
453
454 void StepGenerateXml::GenerateDescription(xmlTextWriterPtr writer) {
455   for (description_x* description :
456        GListRange<description_x*>(context_->manifest_data.get()->description)) {
457     xmlTextWriterStartElement(writer, BAD_CAST "description");
458     if (description->lang && strcmp(DEFAULT_LOCALE, description->lang) != 0) {
459       xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
460                                   BAD_CAST description->lang);
461     }
462     xmlTextWriterWriteString(writer, BAD_CAST description->text);
463     xmlTextWriterEndElement(writer);
464   }
465 }
466
467 common_installer::Step::Status StepGenerateXml::GenerateApplications(
468         xmlTextWriterPtr writer) {
469   for (application_x* app :
470        GListRange<application_x*>(context_->manifest_data.get()->application)) {
471     AppCompType type;
472     if (strcmp(app->component_type, "uiapp") == 0) {
473       type = AppCompType::UIAPP;
474       xmlTextWriterStartElement(writer, BAD_CAST "ui-application");
475     } else if (strcmp(app->component_type, "svcapp") == 0) {
476       type = AppCompType::SVCAPP;
477       xmlTextWriterStartElement(writer, BAD_CAST "service-application");
478     } else if (strcmp(app->component_type, "widgetapp") == 0) {
479       type = AppCompType::WIDGETAPP;
480       xmlTextWriterStartElement(writer, BAD_CAST "widget-application");
481     } else if (strcmp(app->component_type, "watchapp") == 0) {
482       type = AppCompType::WATCHAPP;
483       xmlTextWriterStartElement(writer, BAD_CAST "watch-application");
484     } else {
485       LOG(ERROR) << "Unknown application component_type";
486       xmlFreeTextWriter(writer);
487       return Status::ERROR;
488     }
489     Status status = GenerateApplicationCommonXml(app, writer, type);
490     if (status != Status::OK) {
491       xmlFreeTextWriter(writer);
492       return status;
493     }
494     xmlTextWriterEndElement(writer);
495   }
496   return Status::OK;
497 }
498
499 void StepGenerateXml::GeneratePrivilege(xmlTextWriterPtr writer) {
500   if (context_->manifest_data.get()->privileges) {
501     xmlTextWriterStartElement(writer, BAD_CAST "privileges");
502     for (privilege_x* priv :
503          GListRange<privilege_x*>(context_->manifest_data.get()->privileges)) {
504       xmlTextWriterStartElement(writer, BAD_CAST "privilege");
505       xmlTextWriterWriteAttribute(writer, BAD_CAST "type",
506                                   BAD_CAST priv->type);
507       xmlTextWriterWriteString(writer, BAD_CAST priv->value);
508       xmlTextWriterEndElement(writer);
509     }
510
511     xmlTextWriterEndElement(writer);
512   }
513 }
514
515 void StepGenerateXml::GenerateAccount(xmlTextWriterPtr writer) {
516   const auto& accounts =
517       context_->manifest_plugins_data.get().account_info.get().accounts();
518   if (!accounts.empty()) {
519     xmlTextWriterStartElement(writer, BAD_CAST "account");
520     // add account info
521     for (auto& account : accounts) {
522       xmlTextWriterStartElement(writer, BAD_CAST "account-provider");
523
524       xmlTextWriterWriteAttribute(writer, BAD_CAST "appid",
525                                   BAD_CAST account.appid.c_str());
526
527       if (!account.providerid.empty())
528         xmlTextWriterWriteAttribute(writer, BAD_CAST "providerid",
529                                     BAD_CAST account.providerid.c_str());
530
531       if (account.multiple_account_support)
532         xmlTextWriterWriteAttribute(writer,
533                                     BAD_CAST "multiple-accounts-support",
534                                     BAD_CAST "true");
535       else
536         xmlTextWriterWriteAttribute(writer,
537                                     BAD_CAST "multiple-accounts-support",
538                                     BAD_CAST "false");
539       for (auto& icon_pair : account.icon_paths) {
540         xmlTextWriterStartElement(writer, BAD_CAST "icon");
541         if (icon_pair.first == "AccountSmall")
542           xmlTextWriterWriteAttribute(writer, BAD_CAST "section",
543                                       BAD_CAST "account-small");
544         else
545           xmlTextWriterWriteAttribute(writer, BAD_CAST "section",
546                                       BAD_CAST "account");
547         xmlTextWriterWriteString(writer, BAD_CAST icon_pair.second.c_str());
548         xmlTextWriterEndElement(writer);
549       }
550
551       for (auto& name_pair : account.names) {
552         xmlTextWriterStartElement(writer, BAD_CAST "label");
553         if (!name_pair.second.empty())
554           xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
555                                       BAD_CAST name_pair.second.c_str());
556         xmlTextWriterWriteString(writer, BAD_CAST name_pair.first.c_str());
557         xmlTextWriterEndElement(writer);
558       }
559
560       for (auto& capability : account.capabilities) {
561         xmlTextWriterWriteFormatElement(writer, BAD_CAST "capability",
562           "%s", BAD_CAST capability.c_str());
563       }
564
565       xmlTextWriterEndElement(writer);
566     }
567     xmlTextWriterEndElement(writer);
568   }
569 }
570
571 void StepGenerateXml::GenerateIme(xmlTextWriterPtr writer) {
572   const auto &ime = context_->manifest_plugins_data.get().ime_info.get();
573   const auto ime_uuid = ime.uuid();
574   if (!ime_uuid.empty()) {
575     xmlTextWriterStartElement(writer, BAD_CAST "ime");
576
577     GListRange<application_x*> app_range(
578         context_->manifest_data.get()->application);
579     if (!app_range.Empty()) {
580       // wgt app have ui-application as first application element.
581       // there may be service-applications but not as first element.
582       application_x* app = *app_range.begin();
583       xmlTextWriterWriteAttribute(writer, BAD_CAST "appid",
584                                   BAD_CAST app->appid);
585     }
586
587     xmlTextWriterStartElement(writer, BAD_CAST "uuid");
588     xmlTextWriterWriteString(writer, BAD_CAST ime_uuid.c_str());
589     xmlTextWriterEndElement(writer);
590
591     xmlTextWriterStartElement(writer, BAD_CAST "languages");
592
593     for (auto it = ime.LanguagesBegin(); it != ime.LanguagesEnd(); ++it) {
594       xmlTextWriterStartElement(writer, BAD_CAST "language");
595       xmlTextWriterWriteString(writer, BAD_CAST it->c_str());
596       xmlTextWriterEndElement(writer);
597     }
598
599     xmlTextWriterEndElement(writer);
600
601     xmlTextWriterEndElement(writer);
602   }
603 }
604
605 void StepGenerateXml::GenerateProfiles(xmlTextWriterPtr writer) {
606   for (const char* profile :
607        GListRange<char*>(context_->manifest_data.get()->deviceprofile)) {
608     xmlTextWriterStartElement(writer, BAD_CAST "profile");
609     xmlTextWriterWriteAttribute(writer, BAD_CAST "name",
610                                 BAD_CAST profile);
611     xmlTextWriterEndElement(writer);
612   }
613 }
614
615 void StepGenerateXml::GenerateShortcuts(xmlTextWriterPtr writer) {
616   const auto& shortcuts =
617       context_->manifest_plugins_data.get().shortcut_info.get();
618   if (!shortcuts.empty()) {
619     xmlTextWriterStartElement(writer, BAD_CAST "shortcut-list");
620     for (auto& shortcut : shortcuts) {
621       xmlTextWriterStartElement(writer, BAD_CAST "shortcut");
622       if (!shortcut.app_id.empty())
623         xmlTextWriterWriteAttribute(writer, BAD_CAST "appid",
624                                     BAD_CAST shortcut.app_id.c_str());
625       if (!shortcut.extra_data.empty())
626         xmlTextWriterWriteAttribute(writer, BAD_CAST "extra_data",
627                                     BAD_CAST shortcut.extra_data.c_str());
628       if (!shortcut.extra_key.empty())
629         xmlTextWriterWriteAttribute(writer, BAD_CAST "extra_key",
630                                     BAD_CAST shortcut.extra_key.c_str());
631       if (!shortcut.icon.empty()) {
632         xmlTextWriterStartElement(writer, BAD_CAST "icon");
633         xmlTextWriterWriteString(writer, BAD_CAST shortcut.icon.c_str());
634         xmlTextWriterEndElement(writer);
635       }
636       for (auto& label : shortcut.labels) {
637         xmlTextWriterStartElement(writer, BAD_CAST "label");
638         if (!label.first.empty())
639           xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
640                                       BAD_CAST label.first.c_str());
641         xmlTextWriterWriteString(writer, BAD_CAST label.second.c_str());
642         xmlTextWriterEndElement(writer);
643       }
644       xmlTextWriterEndElement(writer);
645     }
646     xmlTextWriterEndElement(writer);
647   }
648 }
649
650 }  // namespace pkgmgr
651 }  // namespace wgt