[Release] wrt-installer_0.1.58.2
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_manifest_file.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    task_manifest_file.cpp
18  * @author  Pawel Sikorski (p.sikorski@samgsung.com)
19  * @version
20  * @brief
21  */
22
23 //SYSTEM INCLUDES
24 #include <unistd.h>
25 #include <string>
26 #include <dpl/assert.h>
27 #include <dirent.h>
28 #include <fstream>
29 #include <ail.h>
30
31 //WRT INCLUDES
32 #include <widget_install/task_manifest_file.h>
33 #include <widget_install/job_widget_install.h>
34 #include <widget_install/widget_install_errors.h>
35 #include <widget_install/widget_install_context.h>
36 #include <web_provider_livebox_info.h>
37 #include <web_provider_plugin_info.h>
38 #include <dpl/wrt-dao-ro/global_config.h>
39 #include <dpl/log/log.h>
40 #include <dpl/file_input.h>
41 #include <dpl/errno_string.h>
42 #include <dpl/file_output.h>
43 #include <dpl/copy.h>
44 #include <dpl/exception.h>
45 #include <dpl/foreach.h>
46 #include <dpl/sstream.h>
47 #include <dpl/string.h>
48 #include <dpl/optional.h>
49 #include <dpl/utils/wrt_utility.h>
50 #include <map>
51 #include <libxml_utils.h>
52 #include <pkgmgr/pkgmgr_parser.h>
53 #include <dpl/localization/LanguageTagsProvider.h>
54
55 #define DEFAULT_ICON_NAME   "icon.png"
56
57 using namespace WrtDB;
58
59 namespace {
60 typedef std::map<DPL::String, DPL::String> LanguageTagMap;
61
62 const char* const ST_TRUE = "true";
63 const char* const ST_NODISPLAY = "nodisplay";
64
65 LanguageTagMap getLanguageTagMap()
66 {
67     LanguageTagMap map;
68
69 #define ADD(tag, l_tag) map.insert(std::make_pair(L###tag, L###l_tag));
70 #include "languages.def"
71 #undef ADD
72
73     return map;
74 }
75
76 DPL::OptionalString getLangTag(const DPL::String& tag)
77 {
78     static LanguageTagMap TagsMap =
79         getLanguageTagMap();
80
81     DPL::String langTag = tag;
82
83     LogDebug("Trying to map language tag: " << langTag);
84     size_t pos = langTag.find_first_of(L'_');
85     if (pos != DPL::String::npos) {
86         langTag.erase(pos);
87     }
88     DPL::OptionalString ret;
89
90     LanguageTagMap::iterator it = TagsMap.find(langTag);
91     if (it != TagsMap.end()) {
92         ret = it->second;
93     }
94     LogDebug("Mapping IANA Language tag to language tag: " <<
95              langTag << " -> " << ret);
96
97     return ret;
98 }
99 }
100
101 namespace Jobs {
102 namespace WidgetInstall {
103 const char * TaskManifestFile::encoding = "UTF-8";
104
105 TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
106     DPL::TaskDecl<TaskManifestFile>(this),
107     m_context(inCont),
108     writer(NULL)
109 {
110     if (m_context.isUpdateMode) {
111         // for widget update.
112         AddStep(&TaskManifestFile::stepBackupIconFiles);
113         AddStep(&TaskManifestFile::stepCopyIconFiles);
114         AddStep(&TaskManifestFile::stepCopyLiveboxFiles);
115         AddStep(&TaskManifestFile::stepCreateExecFile);
116         AddStep(&TaskManifestFile::stepGenerateManifest);
117         AddStep(&TaskManifestFile::stepParseUpgradedManifest);
118         AddStep(&TaskManifestFile::stepUpdateFinalize);
119
120         AddAbortStep(&TaskManifestFile::stepAbortIconFiles);
121     } else {
122         AddStep(&TaskManifestFile::stepCopyIconFiles);
123         AddStep(&TaskManifestFile::stepCopyLiveboxFiles);
124         AddStep(&TaskManifestFile::stepCreateExecFile);
125         AddStep(&TaskManifestFile::stepGenerateManifest);
126         AddStep(&TaskManifestFile::stepParseManifest);
127         AddStep(&TaskManifestFile::stepFinalize);
128
129         AddAbortStep(&TaskManifestFile::stepAbortParseManifest);
130     }
131 }
132
133 TaskManifestFile::~TaskManifestFile()
134 {}
135
136 void TaskManifestFile::stepCreateExecFile()
137 {
138     std::string exec = m_context.locations->getExecFile();
139     std::string clientExeStr = GlobalConfig::GetWrtClientExec();
140
141 #ifdef MULTIPROCESS_SERVICE_SUPPORT
142     //default widget
143     std::stringstream postfix;
144     postfix << AppControlPrefix::PROCESS_PREFIX << 0;
145     std::string controlExec = exec;
146     controlExec.append(postfix.str());
147
148     errno = 0;
149     if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0)
150     {
151         int error = errno;
152         if (error)
153             LogPedantic("Failed to make a symbolic name for a file "
154                     << "[" <<  DPL::GetErrnoString(error) << "]");
155         ThrowMsg(Exceptions::FileOperationFailed,
156                 "Symbolic link creating is not done.");
157     }
158
159     // app-control widgets
160     unsigned int indexMax = 0;
161     FOREACH(it, m_context.widgetConfig.configInfo.appControlList) {
162         if (it->m_index > indexMax) {
163             indexMax = it->m_index;
164         }
165     }
166
167     for (std::size_t i = 1; i <= indexMax; ++i) {
168         std::stringstream postfix;
169         postfix << AppControlPrefix::PROCESS_PREFIX << i;
170         std::string controlExec = exec;
171         controlExec.append(postfix.str());
172         errno = 0;
173         if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0) {
174             int error = errno;
175             if (error) {
176                 LogPedantic("Failed to make a symbolic name for a file "
177                     << "[" <<  DPL::GetErrnoString(error) << "]");
178             }
179             ThrowMsg(Exceptions::FileOperationFailed,
180                      "Symbolic link creating is not done.");
181         }
182     }
183 #else
184     //default widget
185     LogInfo("link -s " << clientExeStr << " " << exec);
186     errno = 0;
187     if (symlink(clientExeStr.c_str(), exec.c_str()) != 0)
188     {
189         int error = errno;
190         if (error)
191             LogPedantic("Failed to make a symbolic name for a file "
192                     << "[" <<  DPL::GetErrnoString(error) << "]");
193         ThrowMsg(Exceptions::FileOperationFailed,
194                 "Symbolic link creating is not done.");
195     }
196 #endif
197     m_context.job->UpdateProgress(
198             InstallerContext::INSTALL_CREATE_EXECFILE,
199             "Widget execfile creation Finished");
200 }
201
202 void TaskManifestFile::stepCopyIconFiles()
203 {
204     LogDebug("CopyIconFiles");
205
206     //This function copies icon to desktop icon path. For each locale avaliable
207     //which there is at least one icon in widget for, icon file is copied.
208     //Coping prioritize last positions when coping. If there is several icons
209     //with given locale, the one, that will be copied, will be icon
210     //which is declared by <icon> tag later than the others in config.xml of
211     // widget
212
213     std::vector<Locale> generatedLocales;
214
215     WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
216         m_context.widgetConfig.localizationData.icons;
217
218     //reversed: last <icon> has highest priority to be copied if it has given
219     // locale (TODO: why was that working that way?)
220     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_reverse_iterator
221          icon = icons.rbegin();
222          icon != icons.rend();
223          ++icon)
224     {
225         FOREACH(locale, icon->availableLocales)
226         {
227             DPL::String src = icon->src;
228             LogDebug("Icon for locale: " << *locale << "is : " << src);
229
230             if (std::find(generatedLocales.begin(), generatedLocales.end(),
231                           *locale) != generatedLocales.end())
232             {
233                 LogDebug("Skipping - has that locale");
234                 continue;
235             } else {
236                 generatedLocales.push_back(*locale);
237             }
238
239             std::ostringstream sourceFile;
240             std::ostringstream targetFile;
241
242             sourceFile << m_context.locations->getSourceDir() << "/";
243
244             if (!locale->empty()) {
245                 sourceFile << "locales/" << *locale << "/";
246             }
247
248             sourceFile << src;
249
250             targetFile << GlobalConfig::GetUserWidgetDesktopIconPath() << "/";
251             targetFile << getIconTargetFilename(*locale);
252
253             if (m_context.widgetConfig.packagingType ==
254                 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
255             {
256                 m_context.locations->setIconTargetFilenameForLocale(
257                     targetFile.str());
258             }
259
260             LogDebug("Copying icon: " << sourceFile.str() <<
261                      " -> " << targetFile.str());
262
263             icon_list.push_back(targetFile.str());
264
265             Try
266             {
267                 DPL::FileInput input(sourceFile.str());
268                 DPL::FileOutput output(targetFile.str());
269                 DPL::Copy(&input, &output);
270             }
271
272             Catch(DPL::FileInput::Exception::Base)
273             {
274                 // Error while opening or closing source file
275                 //ReThrowMsg(InstallerException::CopyIconFailed,
276                 // sourceFile.str());
277                 LogError(
278                     "Copying widget's icon failed. Widget's icon will not be" \
279                     "available from Main Screen");
280             }
281
282             Catch(DPL::FileOutput::Exception::Base)
283             {
284                 // Error while opening or closing target file
285                 //ReThrowMsg(InstallerException::CopyIconFailed,
286                 // targetFile.str());
287                 LogError(
288                     "Copying widget's icon failed. Widget's icon will not be" \
289                     "available from Main Screen");
290             }
291
292             Catch(DPL::CopyFailed)
293             {
294                 // Error while copying
295                 //ReThrowMsg(InstallerException::CopyIconFailed,
296                 // targetFile.str());
297                 LogError(
298                     "Copying widget's icon failed. Widget's icon will not be" \
299                     "available from Main Screen");
300             }
301         }
302     }
303
304     m_context.job->UpdateProgress(
305         InstallerContext::INSTALL_COPY_ICONFILE,
306         "Widget iconfile copy Finished");
307 }
308
309 void TaskManifestFile::stepCopyLiveboxFiles()
310 {
311     LogDebug("Copy Livebox Files");
312
313     using namespace WrtDB;
314     ConfigParserData &data = m_context.widgetConfig.configInfo;
315     ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
316
317     if (liveBoxList.size() <= 0) {
318         return;
319     }
320
321     std::ostringstream sourceFile;
322     std::ostringstream targetFile;
323
324     FOREACH (boxIt, liveBoxList) {
325         boxSizeType boxSizeList = (**boxIt).m_boxInfo.m_boxSize;
326         FOREACH (sizeIt, boxSizeList) {
327             std::string preview = DPL::ToUTF8String((*sizeIt).second);
328             if (preview.empty()) {
329                 continue;
330             }
331             // copy preview image to shared directory
332             sourceFile << m_context.locations->getSourceDir() << "/";
333             sourceFile << preview;
334             targetFile << m_context.locations->getSharedDataDir() << "/";
335             targetFile << (**boxIt).m_liveboxId << ".";
336             targetFile << DPL::ToUTF8String((*sizeIt).first) << ".preview.png";
337
338             DPL::FileInput input(sourceFile.str());
339             DPL::FileOutput output(targetFile.str());
340             DPL::Copy(&input, &output);
341
342             // clear stream objects
343             sourceFile.str("");
344             targetFile.str("");
345         }
346         // check this livebox has icon element
347         std::string icon = DPL::ToUTF8String((**boxIt).m_icon);
348         if (icon.empty()) {
349             continue;
350         }
351         // copy icon to shared directory
352         sourceFile << m_context.locations->getSourceDir() << "/";
353         sourceFile << icon;
354         targetFile << m_context.locations->getSharedDataDir() << "/";
355         targetFile << (**boxIt).m_liveboxId << ".icon.png";
356
357         DPL::FileInput input(sourceFile.str());
358         DPL::FileOutput output(targetFile.str());
359         DPL::Copy(&input, &output);
360
361         // clear stream objects
362         sourceFile.str("");
363         targetFile.str("");
364     }
365
366     m_context.job->UpdateProgress(
367         InstallerContext::INSTALL_COPY_LIVEBOX_FILES,
368         "Livebox files copy Finished");
369 }
370
371 void TaskManifestFile::stepBackupIconFiles()
372 {
373     LogDebug("Backup Icon Files");
374
375     backup_dir << m_context.locations->getBackupDir() << "/";
376
377     backupIconFiles();
378
379     m_context.job->UpdateProgress(
380         InstallerContext::INSTALL_BACKUP_ICONFILE,
381         "New Widget icon file backup Finished");
382 }
383
384 void TaskManifestFile::stepAbortIconFiles()
385 {
386     LogDebug("Abrot Icon Files");
387     FOREACH(it, icon_list)
388     {
389         LogDebug("Remove Update Icon : " << (*it));
390         unlink((*it).c_str());
391     }
392
393     std::ostringstream b_icon_dir;
394     b_icon_dir << backup_dir.str() << "icons";
395
396     std::list<std::string> fileList;
397     getFileList(b_icon_dir.str().c_str(), fileList);
398
399     FOREACH(back_icon, fileList)
400     {
401         std::ostringstream res_file;
402         res_file << GlobalConfig::GetUserWidgetDesktopIconPath();
403         res_file << "/" << (*back_icon);
404
405         std::ostringstream backup_file;
406         backup_file << b_icon_dir.str() << "/" << (*back_icon);
407
408         Try
409         {
410             DPL::FileInput input(backup_file.str());
411             DPL::FileOutput output(res_file.str());
412             DPL::Copy(&input, &output);
413         }
414         Catch(DPL::FileInput::Exception::Base)
415         {
416             LogError("Restoration icon File Failed." << backup_file.str()
417                                                      << " to " << res_file.str());
418         }
419
420         Catch(DPL::FileOutput::Exception::Base)
421         {
422             LogError("Restoration icon File Failed." << backup_file.str()
423                                                      << " to " << res_file.str());
424         }
425         Catch(DPL::CopyFailed)
426         {
427             LogError("Restoration icon File Failed." << backup_file.str()
428                                                      << " to " << res_file.str());
429         }
430     }
431 }
432
433 void TaskManifestFile::stepUpdateFinalize()
434 {
435     commitManifest();
436     LogDebug("Finished Update Desktopfile");
437 }
438
439 DPL::String TaskManifestFile::getIconTargetFilename(
440     const DPL::String& languageTag) const
441 {
442     DPL::OStringStream filename;
443     TizenAppId appid = m_context.widgetConfig.tzAppid;
444
445     filename << DPL::ToUTF8String(appid).c_str();
446
447     if (!languageTag.empty()) {
448         DPL::OptionalString tag = getLangTag(languageTag); // translate en ->
449                                                            // en_US etc
450         if (tag.IsNull()) {
451             tag = languageTag;
452         }
453         DPL::String locale =
454             LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
455
456         if (locale.empty()) {
457             filename << L"." << languageTag;
458         } else {
459             filename << L"." << locale;
460         }
461     }
462
463     filename << L".png";
464     return filename.str();
465 }
466
467 void TaskManifestFile::stepFinalize()
468 {
469     commitManifest();
470     LogInfo("Finished ManifestFile step");
471 }
472
473 void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
474                                         const DPL::String& key,
475                                         const DPL::String& languageTag)
476 {
477     DPL::String locale =
478         LanguageTagsProvider::BCP47LanguageTagToLocale(languageTag);
479
480     file << key;
481     if (!locale.empty()) {
482         file << "[" << locale << "]";
483     }
484     file << "=";
485 }
486
487 void TaskManifestFile::backupIconFiles()
488 {
489     LogInfo("Backup Icon Files");
490
491     std::ostringstream b_icon_dir;
492     b_icon_dir << backup_dir.str() << "icons";
493
494     LogDebug("Create icon backup folder : " << b_icon_dir.str());
495     WrtUtilMakeDir(b_icon_dir.str());
496
497     std::list<std::string> fileList;
498     getFileList(GlobalConfig::GetUserWidgetDesktopIconPath(), fileList);
499     std::string appid = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
500
501     FOREACH(it, fileList)
502     {
503         if (0 == (strncmp((*it).c_str(), appid.c_str(),
504                           strlen(appid.c_str()))))
505         {
506             std::ostringstream icon_file, backup_icon;
507             icon_file << GlobalConfig::GetUserWidgetDesktopIconPath();
508             icon_file << "/" << (*it);
509
510             backup_icon << b_icon_dir.str() << "/" << (*it);
511
512             LogDebug("Backup icon file " << icon_file.str() << " to " <<
513                      backup_icon.str());
514             Try
515             {
516                 DPL::FileInput input(icon_file.str());
517                 DPL::FileOutput output(backup_icon.str());
518                 DPL::Copy(&input, &output);
519             }
520             Catch(DPL::FileInput::Exception::Base)
521             {
522                 LogError("Backup Desktop File Failed.");
523                 ReThrowMsg(Exceptions::BackupFailed, icon_file.str());
524             }
525
526             Catch(DPL::FileOutput::Exception::Base)
527             {
528                 LogError("Backup Desktop File Failed.");
529                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
530             }
531             Catch(DPL::CopyFailed)
532             {
533                 LogError("Backup Desktop File Failed.");
534                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
535             }
536             unlink((*it).c_str());
537         }
538     }
539 }
540
541 void TaskManifestFile::getFileList(const char* path,
542                                    std::list<std::string> &list)
543 {
544     DIR* dir = opendir(path);
545     if (!dir) {
546         LogError("icon directory doesn't exist");
547         ThrowMsg(Exceptions::FileOperationFailed, path);
548     }
549
550     struct dirent entry;
551     struct dirent *result;
552     int return_code;
553     errno = 0;
554     for (return_code = readdir_r(dir, &entry, &result);
555             result != NULL && return_code == 0;
556             return_code = readdir_r(dir, &entry, &result))
557     {
558         if (strcmp(entry.d_name, ".") == 0 ||
559             strcmp(entry.d_name, "..") == 0)
560         {
561             continue;
562         }
563         std::string file_name = entry.d_name;
564         list.push_back(file_name);
565     }
566
567     if (return_code != 0 || errno != 0) {
568         LogError("readdir_r() failed with " << DPL::GetErrnoString());
569     }
570
571     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
572         LogError("Failed to close dir: " << path << " with error: "
573                                          << DPL::GetErrnoString());
574     }
575 }
576
577 void TaskManifestFile::stepGenerateManifest()
578 {
579     TizenPkgId pkgid = m_context.widgetConfig.tzPkgid;
580     manifest_name = pkgid + L".xml";
581     manifest_file += L"/tmp/" + manifest_name;
582
583     //libxml - init and check
584     LibxmlSingleton::Instance().init();
585
586     writeManifest(manifest_file);
587
588     m_context.job->UpdateProgress(
589         InstallerContext::INSTALL_CREATE_MANIFEST,
590         "Widget Manifest Creation Finished");
591 }
592
593 void TaskManifestFile::stepParseManifest()
594 {
595     int code = pkgmgr_parser_parse_manifest_for_installation(
596             DPL::ToUTF8String(manifest_file).c_str(), NULL);
597
598     if (code != 0) {
599         LogError("Manifest parser error: " << code);
600         ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
601     }
602
603     m_context.job->UpdateProgress(
604         InstallerContext::INSTALL_CREATE_MANIFEST,
605         "Widget Manifest Parsing Finished");
606     LogDebug("Manifest parsed");
607 }
608
609 void TaskManifestFile::stepParseUpgradedManifest()
610 {
611     if (m_context.widgetConfig.packagingType !=
612             PKG_TYPE_HYBRID_WEB_APP)
613     {
614         int code = pkgmgr_parser_parse_manifest_for_upgrade(
615                 DPL::ToUTF8String(manifest_file).c_str(), NULL);
616
617         if (code != 0) {
618             LogError("Manifest parser error: " << code);
619             ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
620         }
621
622         m_context.job->UpdateProgress(
623                 InstallerContext::INSTALL_CREATE_MANIFEST,
624                 "Widget Manifest Parsing Finished");
625         LogDebug("Manifest parsed");
626     }
627 }
628
629 void TaskManifestFile::commitManifest()
630 {
631     LogDebug("Commiting manifest file : " << manifest_file);
632
633     std::ostringstream destFile;
634     if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
635         destFile << "/usr/share/packages" << "/"; //TODO constant with path
636     } else {
637         destFile << "/opt/share/packages" << "/"; //TODO constant with path
638     }
639     destFile << DPL::ToUTF8String(manifest_name);
640     LogInfo("cp " << manifest_file << " " << destFile.str());
641
642     DPL::FileInput input(DPL::ToUTF8String(manifest_file));
643     DPL::FileOutput output(destFile.str());
644     DPL::Copy(&input, &output);
645     LogDebug("Manifest writen to: " << destFile.str());
646
647     //removing temp file
648     unlink((DPL::ToUTF8String(manifest_file)).c_str());
649     manifest_file = DPL::FromUTF8String(destFile.str().c_str());
650 }
651
652 void TaskManifestFile::writeManifest(const DPL::String & path)
653 {
654     LogDebug("Generating manifest file : " << path);
655     Manifest manifest;
656     UiApplication uiApp;
657
658 #ifdef MULTIPROCESS_SERVICE_SUPPORT
659     //default widget content
660     std::stringstream postfix;
661     // index 0 is reserved
662     postfix << AppControlPrefix::PROCESS_PREFIX << 0;
663     setWidgetExecPath(uiApp, postfix.str());
664     setWidgetName(manifest, uiApp);
665     setWidgetIds(manifest, uiApp);
666     setWidgetIcons(uiApp);
667     setWidgetDescription(manifest);
668     setWidgetManifest(manifest);
669     setWidgetOtherInfo(uiApp);
670     setAppCategory(uiApp);
671     setMetadata(uiApp);
672     setLiveBoxInfo(manifest);
673     setAccount(manifest);
674     setPrivilege(manifest);
675     manifest.addUiApplication(uiApp);
676
677     //app-control content
678     ConfigParserData::AppControlInfoList appControlList =
679         m_context.widgetConfig.configInfo.appControlList;
680     FOREACH(it, appControlList) {
681         UiApplication uiApp;
682
683         uiApp.setTaskmanage(true);
684         uiApp.setNodisplay(true);
685 #ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
686         uiApp.setTaskmanage(ConfigParserData::AppControlInfo::Disposition::INLINE != it->m_disposition);
687         uiApp.setMultiple(ConfigParserData::AppControlInfo::Disposition::INLINE == it->m_disposition);
688 #endif
689         std::stringstream postfix;
690         postfix << AppControlPrefix::PROCESS_PREFIX << it->m_index;
691         setWidgetExecPath(uiApp, postfix.str());
692         setWidgetName(manifest, uiApp);
693         setWidgetIds(manifest, uiApp);
694         setWidgetIcons(uiApp);
695         setAppControlInfo(uiApp, *it);
696         setAppCategory(uiApp);
697         setMetadata(uiApp);
698         manifest.addUiApplication(uiApp);
699     }
700 #else
701     //default widget content
702     setWidgetExecPath(uiApp);
703     setWidgetName(manifest, uiApp);
704     setWidgetIds(manifest, uiApp);
705     setWidgetIcons(uiApp);
706     setWidgetDescription(manifest);
707     setWidgetManifest(manifest);
708     setWidgetOtherInfo(uiApp);
709     setAppControlsInfo(uiApp);
710     setAppCategory(uiApp);
711     setMetadata(uiApp);
712     setLiveBoxInfo(manifest);
713     setAccount(manifest);
714     setPrivilege(manifest);
715
716     manifest.addUiApplication(uiApp);
717 #endif
718
719     manifest.generate(path);
720     LogDebug("Manifest file serialized");
721 }
722
723 void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp,
724                                          const std::string &postfix)
725 {
726     std::string exec = m_context.locations->getExecFile();
727     if (!postfix.empty()) {
728         exec.append(postfix);
729     }
730     LogDebug("exec = " << exec);
731     uiApp.setExec(DPL::FromASCIIString(exec));
732 }
733
734 void TaskManifestFile::setWidgetName(Manifest & manifest,
735                                      UiApplication & uiApp)
736 {
737     bool defaultNameSaved = false;
738
739     DPL::OptionalString defaultLocale =
740         m_context.widgetConfig.configInfo.defaultlocale;
741     std::pair<DPL::String,
742               WrtDB::ConfigParserData::LocalizedData> defaultLocalizedData;
743     //labels
744     FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
745     {
746         Locale i = localizedData->first;
747         DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
748         if (tag.IsNull()) {
749             tag = i;
750         }
751         DPL::OptionalString name = localizedData->second.name;
752         generateWidgetName(manifest, uiApp, tag, name, defaultNameSaved);
753
754         //store default locale localized data
755         if (!!defaultLocale && defaultLocale == i) {
756             defaultLocalizedData = *localizedData;
757         }
758     }
759
760     if (!!defaultLocale && !defaultNameSaved) {
761         DPL::OptionalString name = defaultLocalizedData.second.name;
762         generateWidgetName(manifest,
763                            uiApp,
764                            DPL::OptionalString::Null,
765                            name,
766                            defaultNameSaved);
767     }
768 }
769
770 void TaskManifestFile::setWidgetIds(Manifest & manifest,
771                                     UiApplication & uiApp,
772                                     const std::string &postfix)
773 {
774     //appid
775     TizenAppId appid = m_context.widgetConfig.tzAppid;
776     if (!postfix.empty()) {
777         appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix));
778     }
779     uiApp.setAppid(appid);
780
781     //extraid
782     if (!!m_context.widgetConfig.guid) {
783         uiApp.setExtraid(*m_context.widgetConfig.guid);
784     } else {
785         if (!appid.empty()) {
786             uiApp.setExtraid(DPL::String(L"http://") + appid);
787         }
788     }
789
790     //type
791     uiApp.setType(DPL::FromASCIIString("webapp"));
792     manifest.setType(L"wgt");
793 }
794
795 void TaskManifestFile::generateWidgetName(Manifest & manifest,
796                                           UiApplication &uiApp,
797                                           const DPL::OptionalString& tag,
798                                           DPL::OptionalString name,
799                                           bool & defaultNameSaved)
800 {
801     if (!!name) {
802         if (!!tag) {
803             DPL::String locale =
804                 LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
805
806             if (!locale.empty()) {
807                 uiApp.addLabel(LabelType(*name, *tag));
808             } else {
809                 uiApp.addLabel(LabelType(*name));
810                 manifest.addLabel(LabelType(*name));
811             }
812         } else {
813             defaultNameSaved = true;
814             uiApp.addLabel(LabelType(*name));
815             manifest.addLabel(LabelType(*name));
816         }
817     }
818 }
819
820 void TaskManifestFile::setWidgetIcons(UiApplication & uiApp)
821 {
822     //TODO this file will need to be updated when user locale preferences
823     //changes.
824     bool defaultIconSaved = false;
825
826     DPL::OptionalString defaultLocale =
827         m_context.widgetConfig.configInfo.defaultlocale;
828
829     std::vector<Locale> generatedLocales;
830     WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
831         m_context.widgetConfig.localizationData.icons;
832
833     //reversed: last <icon> has highest priority to be writen to manifest if it
834     // has given locale (TODO: why was that working that way?)
835     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_reverse_iterator
836          icon = icons.rbegin();
837          icon != icons.rend();
838          ++icon)
839     {
840         FOREACH(locale, icon->availableLocales)
841         {
842             if (std::find(generatedLocales.begin(), generatedLocales.end(),
843                           *locale) != generatedLocales.end())
844             {
845                 LogDebug("Skipping - has that locale - already in manifest");
846                 continue;
847             } else {
848                 generatedLocales.push_back(*locale);
849             }
850
851             DPL::OptionalString tag = getLangTag(*locale); // translate en ->
852                                                            // en_US etc
853             if (tag.IsNull()) {
854                 tag = *locale;
855             }
856
857             generateWidgetIcon(uiApp, tag, *locale, defaultIconSaved);
858         }
859     }
860     if (!!defaultLocale && !defaultIconSaved) {
861         generateWidgetIcon(uiApp, DPL::OptionalString::Null,
862                            DPL::String(),
863                            defaultIconSaved);
864     }
865 }
866
867 void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp,
868                                           const DPL::OptionalString& tag,
869                                           const DPL::String& language,
870                                           bool & defaultIconSaved)
871 {
872     DPL::String locale;
873     if (!!tag) {
874         locale = LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
875     } else {
876         defaultIconSaved = true;
877     }
878
879     DPL::String iconText;
880     iconText += getIconTargetFilename(language);
881
882     if (!locale.empty()) {
883         uiApp.addIcon(IconType(iconText, locale));
884     } else {
885         uiApp.addIcon(IconType(iconText));
886     }
887     std::ostringstream iconPath;
888     iconPath << GlobalConfig::GetUserWidgetDesktopIconPath() << "/";
889     iconPath << getIconTargetFilename(locale);
890      m_context.job->SendProgressIconPath(iconPath.str());
891 }
892
893 void TaskManifestFile::setWidgetDescription(Manifest & manifest)
894 {
895     FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
896     {
897         Locale i = localizedData->first;
898         DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
899         if (tag.IsNull()) {
900             tag = i;
901         }
902         DPL::OptionalString description = localizedData->second.description;
903         generateWidgetDescription(manifest, tag, description);
904     }
905 }
906
907 void TaskManifestFile::generateWidgetDescription(Manifest & manifest,
908                                                  const DPL::OptionalString& tag,
909                                                   DPL::OptionalString description)
910 {
911     if (!!description) {
912         if (!!tag) {
913             DPL::String locale =
914                 LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
915             if (!locale.empty()) {
916                 manifest.addDescription(DescriptionType(*description, locale));
917             } else {
918                 manifest.addDescription(DescriptionType(*description));
919             }
920         } else {
921             manifest.addDescription(DescriptionType(*description));
922         }
923     }
924 }
925
926 void TaskManifestFile::setWidgetManifest(Manifest & manifest)
927 {
928     manifest.setPackage(m_context.widgetConfig.tzPkgid);
929
930     if (!!m_context.widgetConfig.version) {
931         manifest.setVersion(*m_context.widgetConfig.version);
932     }
933     DPL::String email = (!!m_context.widgetConfig.configInfo.authorEmail ?
934                          *m_context.widgetConfig.configInfo.authorEmail : L"");
935     DPL::String href = (!!m_context.widgetConfig.configInfo.authorHref ?
936                         *m_context.widgetConfig.configInfo.authorHref : L"");
937     DPL::String name = (!!m_context.widgetConfig.configInfo.authorName ?
938                         *m_context.widgetConfig.configInfo.authorName : L"");
939     manifest.addAuthor(Author(email, href, L"", name));
940 }
941
942 void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
943 {
944     FOREACH(it, m_context.widgetConfig.configInfo.settingsList)
945     {
946         if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), ST_NODISPLAY)) {
947             if (!strcmp(DPL::ToUTF8String(it->m_value).c_str(), ST_TRUE)) {
948                 uiApp.setNodisplay(true);
949                 uiApp.setTaskmanage(false);
950             } else {
951                 uiApp.setNodisplay(false);
952                 uiApp.setTaskmanage(true);
953             }
954         }
955     }
956     //TODO
957     //There is no "X-TIZEN-PackageType=wgt"
958     //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" <<
959     // DPL::ToUTF8String(*widgetID).c_str()
960     //There is no Comment in pkgmgr "Comment=Widget application"
961     //that were in desktop file
962 }
963
964 void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
965 {
966     WrtDB::ConfigParserData::AppControlInfoList appControlList =
967         m_context.widgetConfig.configInfo.appControlList;
968
969     if (appControlList.empty()) {
970         LogInfo("Widget doesn't contain app control");
971         return;
972     }
973
974      // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
975     FOREACH(it, appControlList) {
976         setAppControlInfo(uiApp, *it);
977     }
978 }
979
980 void TaskManifestFile::setAppControlInfo(UiApplication & uiApp,
981                                          const WrtDB::ConfigParserData::AppControlInfo & service)
982 {
983     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
984     AppControl appControl;
985     if (!service.m_operation.empty()) {
986         appControl.addOperation(service.m_operation); //TODO: encapsulation?
987     }
988     if (!service.m_uriList.empty()) {
989         FOREACH(uri, service.m_uriList) {
990             appControl.addUri(*uri);
991         }
992     }
993     if (!service.m_mimeList.empty()) {
994         FOREACH(mime, service.m_mimeList) {
995             appControl.addMime(*mime);
996         }
997     }
998     uiApp.addAppControl(appControl);
999 }
1000
1001 void TaskManifestFile::setAppCategory(UiApplication &uiApp)
1002 {
1003     WrtDB::ConfigParserData::CategoryList categoryList =
1004         m_context.widgetConfig.configInfo.categoryList;
1005
1006     if (categoryList.empty()) {
1007         LogInfo("Widget doesn't contain application category");
1008         return;
1009     }
1010     FOREACH(it, categoryList) {
1011         if (!(*it).empty()) {
1012             uiApp.addAppCategory(*it);
1013         }
1014     }
1015 }
1016
1017 void TaskManifestFile::setMetadata(UiApplication &uiApp)
1018 {
1019     WrtDB::ConfigParserData::MetadataList metadataList =
1020         m_context.widgetConfig.configInfo.metadataList;
1021
1022     if (metadataList.empty()) {
1023         LogInfo("Web application doesn't contain metadata");
1024         return;
1025     }
1026     FOREACH(it, metadataList) {
1027         MetadataType metadataType(it->key, it->value);
1028         uiApp.addMetadata(metadataType);
1029     }
1030 }
1031
1032 void TaskManifestFile::stepAbortParseManifest()
1033 {
1034     LogError("[Parse Manifest] Abroting....");
1035
1036     int code = pkgmgr_parser_parse_manifest_for_uninstallation(
1037             DPL::ToUTF8String(manifest_file).c_str(), NULL);
1038
1039     if (0 != code) {
1040         LogWarning("Manifest parser error: " << code);
1041         ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
1042     }
1043     int ret = unlink(DPL::ToUTF8String(manifest_file).c_str());
1044     if (0 != ret) {
1045         LogWarning("No manifest file found: " << manifest_file);
1046     }
1047 }
1048
1049 void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
1050 {
1051     FOREACH(it, m_context.widgetConfig.configInfo.m_livebox) {
1052         LogInfo("setLiveBoxInfo");
1053         LiveBoxInfo liveBox;
1054         DPL::Optional<WrtDB::ConfigParserData::LiveboxInfo> ConfigInfo = *it;
1055         DPL::String appid = m_context.widgetConfig.tzAppid;
1056
1057         if (ConfigInfo->m_liveboxId != L"") {
1058             size_t found = ConfigInfo->m_liveboxId.find_last_of(L".");
1059             if (found != std::string::npos) {
1060                 if (0 == ConfigInfo->m_liveboxId.compare(0, found, appid)) {
1061                     liveBox.setLiveboxId(ConfigInfo->m_liveboxId);
1062                 } else {
1063                     DPL::String liveboxId =
1064                         appid + DPL::String(L".") + ConfigInfo->m_liveboxId;
1065                     liveBox.setLiveboxId(liveboxId);
1066                 }
1067             } else {
1068                 DPL::String liveboxId =
1069                     appid + DPL::String(L".") + ConfigInfo->m_liveboxId;
1070                 liveBox.setLiveboxId(liveboxId);
1071             }
1072         }
1073
1074         if (ConfigInfo->m_primary != L"") {
1075             liveBox.setPrimary(ConfigInfo->m_primary);
1076         }
1077
1078         if (ConfigInfo->m_updatePeriod != L"") {
1079             liveBox.setUpdatePeriod(ConfigInfo->m_updatePeriod);
1080         }
1081
1082         if (ConfigInfo->m_label != L"") {
1083             liveBox.setLabel(ConfigInfo->m_label);
1084         }
1085
1086         DPL::String defaultLocale =
1087             DPL::FromUTF8String(m_context.locations->getPackageInstallationDir()) +
1088             DPL::String(L"/res/wgt/");
1089
1090         if (ConfigInfo->m_icon != L"") {
1091             DPL::String icon =
1092                 DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
1093                 DPL::String(L"/") +
1094                 ConfigInfo->m_liveboxId + DPL::String(L".icon.png");
1095             liveBox.setIcon(icon);
1096         }
1097
1098         if (ConfigInfo->m_boxInfo.m_boxSrc.empty() ||
1099             ConfigInfo->m_boxInfo.m_boxSize.empty())
1100         {
1101             LogInfo("Widget doesn't contain box");
1102             return;
1103         } else {
1104             BoxInfoType box;
1105             if (!ConfigInfo->m_boxInfo.m_boxSrc.empty()) {
1106                 if ((0 == ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 4, L"http"))
1107                     || (0 ==
1108                         ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 5, L"https")))
1109                 {
1110                     box.boxSrc = ConfigInfo->m_boxInfo.m_boxSrc;
1111                 } else {
1112                     box.boxSrc = defaultLocale + ConfigInfo->m_boxInfo.m_boxSrc;
1113                 }
1114             }
1115
1116             if (ConfigInfo->m_boxInfo.m_boxMouseEvent == L"true") {
1117                 std::string boxType;
1118                 if (ConfigInfo->m_type == L"") {
1119                     // in case of default livebox
1120                     boxType = web_provider_livebox_get_default_type();
1121                 } else {
1122                     boxType = DPL::ToUTF8String(ConfigInfo->m_type);
1123                 }
1124
1125                 int box_scrollable =
1126                     web_provider_plugin_get_box_scrollable(boxType.c_str());
1127
1128                 if (box_scrollable) {
1129                     box.boxMouseEvent = L"true";
1130                 } else {
1131                     box.boxMouseEvent = L"false";
1132                 }
1133             } else {
1134                 box.boxMouseEvent = L"false";
1135             }
1136
1137             if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
1138                 box.boxTouchEffect = L"true";
1139             } else {
1140                 box.boxTouchEffect= L"false";
1141             }
1142
1143             std::list<std::pair<DPL::String, DPL::String> > BoxSizeList
1144                 = ConfigInfo->m_boxInfo.m_boxSize;
1145             FOREACH(im, BoxSizeList) {
1146                 std::pair<DPL::String, DPL::String> boxSize = *im;
1147                 if (!boxSize.second.empty()) {
1148                     boxSize.second =
1149                         DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
1150                         DPL::String(L"/") +
1151                         ConfigInfo->m_liveboxId + DPL::String(L".") +
1152                         boxSize.first + DPL::String(L".preview.png");
1153                 }
1154                 box.boxSize.push_back(boxSize);
1155             }
1156
1157             if (!ConfigInfo->m_boxInfo.m_pdSrc.empty()
1158                 && !ConfigInfo->m_boxInfo.m_pdWidth.empty()
1159                 && !ConfigInfo->m_boxInfo.m_pdHeight.empty())
1160             {
1161                 if ((0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 4, L"http"))
1162                     || (0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 5, L"https")))
1163                 {
1164                     box.pdSrc = ConfigInfo->m_boxInfo.m_pdSrc;
1165                 } else {
1166                     box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
1167                 }
1168                 box.pdWidth = ConfigInfo->m_boxInfo.m_pdWidth;
1169                 box.pdHeight = ConfigInfo->m_boxInfo.m_pdHeight;
1170             }
1171             liveBox.setBox(box);
1172         }
1173         manifest.addLivebox(liveBox);
1174     }
1175 }
1176
1177 void TaskManifestFile::setAccount(Manifest& manifest)
1178 {
1179     WrtDB::ConfigParserData::AccountProvider account =
1180         m_context.widgetConfig.configInfo.accountProvider;
1181
1182     AccountProviderType provider;
1183
1184     if (account.m_iconSet.empty()) {
1185         LogInfo("Widget doesn't contain Account");
1186         return;
1187     }
1188     if (account.m_multiAccountSupport) {
1189         provider.multiAccount = L"ture";
1190     } else {
1191         provider.multiAccount = L"false";
1192     }
1193     provider.appid = m_context.widgetConfig.tzAppid;
1194
1195     FOREACH(it, account.m_iconSet) {
1196         std::pair<DPL::String, DPL::String> icon;
1197
1198         if (it->first == ConfigParserData::IconSectionType::DefaultIcon) {
1199             icon.first = L"account";
1200         } else if (it->first == ConfigParserData::IconSectionType::SmallIcon) {
1201             icon.first = L"account-small";
1202         }
1203         icon.second = it->second;
1204
1205         provider.icon.push_back(icon);
1206     }
1207
1208     FOREACH(it, account.m_displayNameSet) {
1209         provider.name.push_back(LabelType(it->second, it->first));
1210     }
1211
1212     FOREACH(it, account.m_capabilityList) {
1213         provider.capability.push_back(*it);
1214     }
1215
1216     Account accountInfo;
1217     accountInfo.addAccountProvider(provider);
1218     manifest.addAccount(accountInfo);
1219 }
1220
1221 void TaskManifestFile::setPrivilege(Manifest& manifest)
1222 {
1223     WrtDB::ConfigParserData::PrivilegeList privileges =
1224         m_context.widgetConfig.configInfo.privilegeList;
1225
1226     PrivilegeType privilege;
1227
1228     FOREACH(it, privileges)
1229     {
1230         privilege.addPrivilegeName(it->name);
1231     }
1232
1233     manifest.addPrivileges(privilege);
1234 }
1235
1236 } //namespace WidgetInstall
1237 } //namespace Jobs