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