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