4e6699b24e10fbdf459deab8a379ef1285b0c202
[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/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 #include <dpl/utils/path.h>
55
56 #include <installer_log.h>
57
58 #define DEFAULT_ICON_NAME   "icon.png"
59 #define DEFAULT_PREVIEW_NAME   "preview.png"
60
61 using namespace WrtDB;
62
63 namespace {
64 typedef std::map<DPL::String, DPL::String> LanguageTagMap;
65
66 const char* const STR_TRUE = "true";
67 const char* const STR_FALSE = "false";
68 const char* const STR_NODISPLAY = "nodisplay";
69
70 LanguageTagMap getLanguageTagMap()
71 {
72     LanguageTagMap map;
73
74 #define ADD(tag, l_tag) map.insert(std::make_pair(L###tag, L###l_tag));
75 #include "languages.def"
76 #undef ADD
77
78     return map;
79 }
80
81 DPL::OptionalString getLangTag(const DPL::String& tag)
82 {
83     static LanguageTagMap TagsMap =
84         getLanguageTagMap();
85
86     DPL::String langTag = tag;
87
88     _D("Trying to map language tag: %ls", langTag.c_str());
89     size_t pos = langTag.find_first_of(L'_');
90     if (pos != DPL::String::npos) {
91         langTag.erase(pos);
92     }
93     DPL::OptionalString ret;
94
95     LanguageTagMap::iterator it = TagsMap.find(langTag);
96     if (it != TagsMap.end()) {
97         ret = it->second;
98         _D("Mapping IANA Language tag to language tag: %ls -> %ls", langTag.c_str(), (*ret).c_str());
99     }
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             _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
152     }
153
154     // app-control widgets
155     unsigned int indexMax = 0;
156     FOREACH(it, m_context.widgetConfig.configInfo.appControlList) {
157         if (it->m_index > indexMax) {
158             indexMax = it->m_index;
159         }
160     }
161
162     for (std::size_t i = 1; i <= indexMax; ++i) {
163         std::stringstream postfix;
164         postfix << AppControlPrefix::PROCESS_PREFIX << i;
165         std::string controlExec = exec;
166         controlExec.append(postfix.str());
167         errno = 0;
168         if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0) {
169             int error = errno;
170             if (error) {
171                 _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
172             }
173         }
174     }
175 #else
176     //default widget
177     _D("link -s %s %s", clientExeStr.c_str(), exec.c_str());
178     errno = 0;
179     if (symlink(clientExeStr.c_str(), exec.c_str()) != 0)
180     {
181         int error = errno;
182         if (error)
183             _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
184     }
185 #endif
186     // creation of box symlink
187     ConfigParserData::LiveboxList& liveboxList =
188         m_context.widgetConfig.configInfo.m_livebox;
189     if (!liveboxList.empty()) {
190         std::string boxExec = "/usr/bin/WebProcess";
191         std::string boxSymlink = m_context.locations->getExecFile();
192         boxSymlink += ".d-box";
193
194         errno = 0;
195         if (symlink(boxExec.c_str(), boxSymlink.c_str()) != 0) {
196             int error = errno;
197             if (error) {
198                 _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
199             }
200         }
201     }
202
203     m_context.job->UpdateProgress(
204             InstallerContext::INSTALL_CREATE_EXECFILE,
205             "Widget execfile creation Finished");
206 }
207
208 void TaskManifestFile::stepCopyIconFiles()
209 {
210     _D("CopyIconFiles");
211
212     //This function copies icon to desktop icon path. For each locale avaliable
213     //which there is at least one icon in widget for, icon file is copied.
214     //Coping prioritize last positions when coping. If there is several icons
215     //with given locale, the one, that will be copied, will be icon
216     //which is declared by <icon> tag later than the others in config.xml of
217     // widget
218
219     std::vector<Locale> generatedLocales;
220
221     WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
222         m_context.widgetConfig.localizationData.icons;
223
224     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
225          icon = icons.begin();
226          icon != icons.end();
227          ++icon)
228     {
229         DPL::String src = icon->src;
230         FOREACH(locale, icon->availableLocales)
231         {
232             _D("Icon for locale: %ls is: %ls", (*locale).c_str(), src.c_str());
233
234             if (std::find(generatedLocales.begin(), generatedLocales.end(),
235                     *locale) != generatedLocales.end())
236             {
237                 _D("Skipping - has that locale");
238                 continue;
239             } else {
240                 generatedLocales.push_back(*locale);
241             }
242
243             DPL::Utils::Path sourceFile(m_context.locations->getSourceDir());
244             if (!locale->empty()) {
245                 sourceFile /= "locales";
246                 sourceFile /= *locale;
247             }
248             sourceFile /= src;
249
250             DPL::Utils::Path targetFile(GlobalConfig::GetUserWidgetDesktopIconPath());
251             targetFile /= getIconTargetFilename(*locale, sourceFile.Extension());
252
253             if (m_context.widgetConfig.packagingType ==
254                 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
255             {
256                 m_context.locations->setIconTargetFilenameForLocale(
257                     targetFile.Fullpath());
258             }
259
260             _D("Copying icon: %s -> %s", sourceFile.Filename().c_str(), targetFile.Filename().c_str());
261
262             icon_list.push_back(targetFile.Fullpath());
263
264             Try
265             {
266                 DPL::FileInput input(sourceFile.Fullpath());
267                 DPL::FileOutput output(targetFile.Fullpath());
268                 DPL::Copy(&input, &output);
269             }
270
271             Catch(DPL::FileInput::Exception::Base)
272             {
273                 // Error while opening or closing source file
274                 //ReThrowMsg(InstallerException::CopyIconFailed,
275                 // sourceFile.str());
276                 _E("Copying widget's icon failed. Widget's icon will not be" \
277                     "available from Main Screen");
278             }
279
280             Catch(DPL::FileOutput::Exception::Base)
281             {
282                 // Error while opening or closing target file
283                 //ReThrowMsg(InstallerException::CopyIconFailed,
284                 // targetFile.str());
285                 _E("Copying widget's icon failed. Widget's icon will not be" \
286                     "available from Main Screen");
287             }
288
289             Catch(DPL::CopyFailed)
290             {
291                 // Error while copying
292                 //ReThrowMsg(InstallerException::CopyIconFailed,
293                 // targetFile.str());
294                 _E("Copying widget's icon failed. Widget's icon will not be" \
295                     "available from Main Screen");
296             }
297         }
298     }
299
300     m_context.job->UpdateProgress(
301         InstallerContext::INSTALL_COPY_ICONFILE,
302         "Widget iconfile copy Finished");
303 }
304
305 void TaskManifestFile::stepCopyLiveboxFiles()
306 {
307     _D("Copy Livebox Files");
308
309     using namespace WrtDB;
310     ConfigParserData &data = m_context.widgetConfig.configInfo;
311     ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
312
313     if (liveBoxList.size() <= 0) {
314         return;
315     }
316
317     std::ostringstream sourceFile;
318     std::ostringstream targetFile;
319
320     FOREACH (boxIt, liveBoxList) {
321         ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
322             (**boxIt).m_boxInfo.m_boxSize;
323         FOREACH (sizeIt, boxSizeList) {
324             std::string preview = DPL::ToUTF8String((*sizeIt).m_preview);
325             if (preview.empty()) {
326                 continue;
327             }
328             sourceFile << m_context.locations->getSourceDir() << "/";
329             sourceFile << preview;
330             targetFile << m_context.locations->getSharedDataDir() << "/";
331             targetFile << (**boxIt).m_liveboxId << ".";
332             targetFile << DPL::ToUTF8String((*sizeIt).m_size) << "." << DEFAULT_PREVIEW_NAME;
333
334             copyDynamicBoxFile(sourceFile.str(), targetFile.str());
335
336             // clear stream objects
337             sourceFile.str("");
338             targetFile.str("");
339         }
340         // check this livebox has icon element
341         std::string icon = DPL::ToUTF8String((**boxIt).m_icon);
342         if (icon.empty()) {
343             continue;
344         }
345         sourceFile << m_context.locations->getSourceDir() << "/";
346         sourceFile << icon;
347         targetFile << m_context.locations->getSharedDataDir() << "/";
348         targetFile << (**boxIt).m_liveboxId << "." << DEFAULT_ICON_NAME;
349
350         copyDynamicBoxFile(sourceFile.str(), targetFile.str());
351
352         // clear stream objects
353         sourceFile.str("");
354         targetFile.str("");
355     }
356     m_context.job->UpdateProgress(
357         InstallerContext::INSTALL_COPY_LIVEBOX_FILES,
358         "Livebox files copy Finished");
359 }
360
361 void TaskManifestFile::copyDynamicBoxFile(const std::string& sourceFile,
362                                           const std::string& targetFile)
363 {
364     Try
365     {
366         DPL::FileInput input(sourceFile);
367         DPL::FileOutput output(targetFile);
368         DPL::Copy(&input, &output);
369     }
370     Catch(DPL::Exception)
371     {
372         _E("Copying Dynamic Box File Failed. %s to %s", sourceFile.c_str(), targetFile.c_str());
373         ReThrowMsg(Exceptions::DynamicBoxFailed, "Dynamic Box File Copy Failed.");
374     }
375 }
376
377 bool TaskManifestFile::addBoxUiApplication(Manifest& manifest)
378 {
379     UiApplication uiApp;
380     std::string postfix = ".d-box";
381     static bool isAdded = false;
382
383     Try
384     {
385         if (isAdded) {
386             _D("UiApplication for d-box is already added");
387             return false;
388         }
389         uiApp.setNodisplay(true);
390         uiApp.setTaskmanage(false);
391         uiApp.setMultiple(false);
392         setWidgetName(manifest, uiApp);
393         setWidgetIcons(uiApp);
394
395         // appid for box is like [webapp id].d-box
396         setWidgetIds(manifest, uiApp, postfix);
397         // executable path for box is like [app path]/bin/[webapp id].d-box
398         setWidgetExecPath(uiApp, postfix);
399         manifest.addUiApplication(uiApp);
400         isAdded = true;
401
402         return true;
403     }
404     Catch(DPL::Exception)
405     {
406         _E("Adding UiApplication on xml is failed.");
407         isAdded = false;
408         return false;
409     }
410 }
411
412 void TaskManifestFile::stepBackupIconFiles()
413 {
414     _D("Backup Icon Files");
415
416     backup_dir << m_context.locations->getBackupDir() << "/";
417
418     backupIconFiles();
419
420     m_context.job->UpdateProgress(
421         InstallerContext::INSTALL_BACKUP_ICONFILE,
422         "New Widget icon file backup Finished");
423 }
424
425 void TaskManifestFile::stepAbortIconFiles()
426 {
427     _D("Abrot Icon Files");
428     FOREACH(it, icon_list)
429     {
430         _D("Remove Update Icon : %s", (*it).c_str());
431         unlink((*it).c_str());
432     }
433
434     std::ostringstream b_icon_dir;
435     b_icon_dir << backup_dir.str() << "icons";
436
437     std::list<std::string> fileList;
438     getFileList(b_icon_dir.str().c_str(), fileList);
439
440     FOREACH(back_icon, fileList)
441     {
442         std::ostringstream res_file;
443         res_file << GlobalConfig::GetUserWidgetDesktopIconPath();
444         res_file << "/" << (*back_icon);
445
446         std::ostringstream backup_file;
447         backup_file << b_icon_dir.str() << "/" << (*back_icon);
448
449         Try
450         {
451             DPL::FileInput input(backup_file.str());
452             DPL::FileOutput output(res_file.str());
453             DPL::Copy(&input, &output);
454         }
455         Catch(DPL::FileInput::Exception::Base)
456         {
457             _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
458         }
459
460         Catch(DPL::FileOutput::Exception::Base)
461         {
462             _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
463         }
464         Catch(DPL::CopyFailed)
465         {
466             _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
467         }
468     }
469 }
470
471 DPL::String TaskManifestFile::getIconTargetFilename(
472     const DPL::String& languageTag, const std::string & ext) const
473 {
474     DPL::OStringStream filename;
475     TizenAppId appid = m_context.widgetConfig.tzAppid;
476
477     filename << DPL::ToUTF8String(appid).c_str();
478
479     if (!languageTag.empty()) {
480         DPL::OptionalString tag = getLangTag(languageTag); // translate en ->
481                                                            // en_US etc
482         if (tag.IsNull()) {
483             tag = languageTag;
484         }
485         DPL::String locale =
486             LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
487
488         if (locale.empty()) {
489             filename << L"." << languageTag;
490         } else {
491             filename << L"." << locale;
492         }
493     }
494
495     if(!ext.empty())
496     {
497         filename << L"." + DPL::FromUTF8String(ext);
498     }
499     return filename.str();
500 }
501
502 void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
503                                         const DPL::String& key,
504                                         const DPL::String& languageTag)
505 {
506     DPL::String locale =
507         LanguageTagsProvider::BCP47LanguageTagToLocale(languageTag);
508
509     file << key;
510     if (!locale.empty()) {
511         file << "[" << locale << "]";
512     }
513     file << "=";
514 }
515
516 void TaskManifestFile::backupIconFiles()
517 {
518     _D("Backup Icon Files");
519
520     std::ostringstream b_icon_dir;
521     b_icon_dir << backup_dir.str() << "icons";
522
523     _D("Create icon backup folder : %s", b_icon_dir.str().c_str());
524     WrtUtilMakeDir(b_icon_dir.str());
525
526     std::list<std::string> fileList;
527     getFileList(GlobalConfig::GetUserWidgetDesktopIconPath(), fileList);
528     std::string appid = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
529
530     FOREACH(it, fileList)
531     {
532         if (0 == (strncmp((*it).c_str(), appid.c_str(),
533                           strlen(appid.c_str()))))
534         {
535             std::ostringstream icon_file, backup_icon;
536             icon_file << GlobalConfig::GetUserWidgetDesktopIconPath();
537             icon_file << "/" << (*it);
538
539             backup_icon << b_icon_dir.str() << "/" << (*it);
540
541             _D("Backup icon file %s to %s", icon_file.str().c_str(), backup_icon.str().c_str());
542             Try
543             {
544                 DPL::FileInput input(icon_file.str());
545                 DPL::FileOutput output(backup_icon.str());
546                 DPL::Copy(&input, &output);
547             }
548             Catch(DPL::FileInput::Exception::Base)
549             {
550                 _E("Backup Desktop File Failed.");
551                 ReThrowMsg(Exceptions::BackupFailed, icon_file.str());
552             }
553
554             Catch(DPL::FileOutput::Exception::Base)
555             {
556                 _E("Backup Desktop File Failed.");
557                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
558             }
559             Catch(DPL::CopyFailed)
560             {
561                 _E("Backup Desktop File Failed.");
562                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
563             }
564             unlink((*it).c_str());
565         }
566     }
567 }
568
569 void TaskManifestFile::getFileList(const char* path,
570                                    std::list<std::string> &list)
571 {
572     DIR* dir = opendir(path);
573     if (!dir) {
574         _E("icon directory doesn't exist");
575         ThrowMsg(Exceptions::FileOperationFailed, path);
576     }
577
578     struct dirent entry;
579     struct dirent *result;
580     int return_code;
581     errno = 0;
582     for (return_code = readdir_r(dir, &entry, &result);
583             result != NULL && return_code == 0;
584             return_code = readdir_r(dir, &entry, &result))
585     {
586         if (strcmp(entry.d_name, ".") == 0 ||
587             strcmp(entry.d_name, "..") == 0)
588         {
589             continue;
590         }
591         std::string file_name = entry.d_name;
592         list.push_back(file_name);
593     }
594
595     if (return_code != 0 || errno != 0) {
596         _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
597     }
598
599     if (-1 == closedir(dir)) {
600         _E("Failed to close dir: %s with error: %s", path, DPL::GetErrnoString().c_str());
601     }
602 }
603
604 void TaskManifestFile::stepGenerateManifest()
605 {
606     TizenPkgId pkgid = m_context.widgetConfig.tzPkgid;
607     manifest_name = pkgid + L".xml";
608     manifest_file += L"/tmp/" + manifest_name;
609
610     //libxml - init and check
611     LibxmlSingleton::Instance().init();
612
613     writeManifest(manifest_file);
614
615     std::ostringstream destFile;
616     if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
617         destFile << WrtDB::GlobalConfig::GetPreloadManifestPath() << "/";
618     } else {
619         destFile << WrtDB::GlobalConfig::GetManifestPath() << "/";
620     }
621
622     destFile << DPL::ToUTF8String(manifest_name);
623     commit_manifest = destFile.str();
624     _D("Commiting manifest file : %s", commit_manifest.c_str());
625
626     commitManifest();
627
628     m_context.job->UpdateProgress(
629         InstallerContext::INSTALL_CREATE_MANIFEST,
630         "Widget Manifest Creation Finished");
631 }
632
633 void TaskManifestFile::commitManifest()
634 {
635
636     if (!(m_context.mode.rootPath == InstallMode::RootPath::RO &&
637                 m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
638                 && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
639         _D("cp %ls %s", manifest_file.c_str(), commit_manifest.c_str());
640
641         DPL::FileInput input(DPL::ToUTF8String(manifest_file));
642         DPL::FileOutput output(commit_manifest);
643         DPL::Copy(&input, &output);
644         _D("Manifest writen to: %s", commit_manifest.c_str());
645
646         //removing temp file
647         unlink((DPL::ToUTF8String(manifest_file)).c_str());
648         manifest_file = DPL::FromUTF8String(commit_manifest);
649     }
650 }
651
652 void TaskManifestFile::writeManifest(const DPL::String & path)
653 {
654     _D("Generating manifest file : %ls", path.c_str());
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     _D("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     _D("exec = %s", exec.c_str());
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     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
834          icon = icons.begin();
835          icon != icons.end();
836          ++icon)
837     {
838         FOREACH(locale, icon->availableLocales)
839         {
840             if (std::find(generatedLocales.begin(), generatedLocales.end(),
841                           *locale) != generatedLocales.end())
842             {
843                 _D("Skipping - has that locale - already in manifest");
844                 continue;
845             } else {
846                 generatedLocales.push_back(*locale);
847             }
848
849             DPL::OptionalString tag = getLangTag(*locale); // translate en ->
850                                                            // en_US etc
851             if (tag.IsNull()) {
852                 tag = *locale;
853             }
854
855             generateWidgetIcon(uiApp, tag, *locale, DPL::Utils::Path(icon->src).Extension(), defaultIconSaved);
856         }
857     }
858     if (!!defaultLocale && !defaultIconSaved) {
859         generateWidgetIcon(uiApp, DPL::OptionalString::Null,
860                            DPL::String(),
861                            std::string(),
862                            defaultIconSaved);
863     }
864 }
865
866 void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp,
867                                           const DPL::OptionalString& tag,
868                                           const DPL::String& language,
869                                           const std::string & extension,
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, extension);
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, extension);
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     if (!m_context.callerPkgId.empty()) {
942         manifest.setStoreClientId(m_context.callerPkgId);
943     }
944 }
945
946 void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
947 {
948     FOREACH(it, m_context.widgetConfig.configInfo.settingsList)
949     {
950         if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), STR_NODISPLAY)) {
951             if (!strcmp(DPL::ToUTF8String(it->m_value).c_str(), STR_TRUE)) {
952                 uiApp.setNodisplay(true);
953                 uiApp.setTaskmanage(false);
954             } else {
955                 uiApp.setNodisplay(false);
956                 uiApp.setTaskmanage(true);
957             }
958         }
959     }
960     //TODO
961     //There is no "X-TIZEN-PackageType=wgt"
962     //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" <<
963     // DPL::ToUTF8String(*widgetID).c_str()
964     //There is no Comment in pkgmgr "Comment=Widget application"
965     //that were in desktop file
966 }
967
968 void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
969 {
970     WrtDB::ConfigParserData::AppControlInfoList appControlList =
971         m_context.widgetConfig.configInfo.appControlList;
972
973     if (appControlList.empty()) {
974         _D("Widget doesn't contain app control");
975         return;
976     }
977
978      // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
979     FOREACH(it, appControlList) {
980         setAppControlInfo(uiApp, *it);
981     }
982 }
983
984 void TaskManifestFile::setAppControlInfo(UiApplication & uiApp,
985                                          const WrtDB::ConfigParserData::AppControlInfo & service)
986 {
987     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
988     AppControl appControl;
989     if (!service.m_operation.empty()) {
990         appControl.addOperation(service.m_operation); //TODO: encapsulation?
991     }
992     if (!service.m_uriList.empty()) {
993         FOREACH(uri, service.m_uriList) {
994             appControl.addUri(*uri);
995         }
996     }
997     if (!service.m_mimeList.empty()) {
998         FOREACH(mime, service.m_mimeList) {
999             appControl.addMime(*mime);
1000         }
1001     }
1002     uiApp.addAppControl(appControl);
1003 }
1004
1005 void TaskManifestFile::setAppCategory(UiApplication &uiApp)
1006 {
1007     WrtDB::ConfigParserData::CategoryList categoryList =
1008         m_context.widgetConfig.configInfo.categoryList;
1009
1010     if (categoryList.empty()) {
1011         _D("Widget doesn't contain application category");
1012         return;
1013     }
1014     FOREACH(it, categoryList) {
1015         if (!(*it).empty()) {
1016             uiApp.addAppCategory(*it);
1017         }
1018     }
1019 }
1020
1021 void TaskManifestFile::setMetadata(UiApplication &uiApp)
1022 {
1023     WrtDB::ConfigParserData::MetadataList metadataList =
1024         m_context.widgetConfig.configInfo.metadataList;
1025
1026     if (metadataList.empty()) {
1027         _D("Web application doesn't contain metadata");
1028         return;
1029     }
1030     FOREACH(it, metadataList) {
1031         MetadataType metadataType(it->key, it->value);
1032         uiApp.addMetadata(metadataType);
1033     }
1034 }
1035
1036 void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
1037 {
1038     ConfigParserData::LiveboxList& liveboxList =
1039         m_context.widgetConfig.configInfo.m_livebox;
1040
1041     if (liveboxList.empty()) {
1042         _D("no livebox");
1043         return;
1044     }
1045
1046     if (!addBoxUiApplication(manifest)) {
1047         _D("error during adding UiApplication for d-box");
1048         return;
1049     }
1050
1051     FOREACH(it, liveboxList) {
1052         LogDebug("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         std::list<std::pair<DPL::String, DPL::String> > boxLabelList;
1083         if (!ConfigInfo->m_label.empty()) {
1084             FOREACH(im, ConfigInfo->m_label) {
1085                 std::pair<DPL::String, DPL::String> boxSize;
1086                 Locale i = (*im).first;
1087                 // translate en -> en_US etc
1088                 DPL::OptionalString tag = getLangTag(i);
1089                 if (tag.IsNull()) {
1090                     tag = i;
1091                 }
1092                 boxSize.first = (*tag);
1093                 boxSize.second = (*im).second;
1094                 boxLabelList.push_back(boxSize);
1095             }
1096             liveBox.setLabel(boxLabelList);
1097         }
1098
1099         DPL::String defaultLocale =
1100             DPL::FromUTF8String(m_context.locations->getPackageInstallationDir()) +
1101             DPL::String(L"/res/wgt/");
1102
1103         if (ConfigInfo->m_icon != L"") {
1104             DPL::String icon =
1105                 DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
1106                 DPL::String(L"/") +
1107                 ConfigInfo->m_liveboxId + DPL::String(L".icon.png");
1108             liveBox.setIcon(icon);
1109         }
1110
1111         if (ConfigInfo->m_boxInfo.m_boxSrc.empty() ||
1112             ConfigInfo->m_boxInfo.m_boxSize.empty())
1113         {
1114             _D("Widget doesn't contain box");
1115             return;
1116         } else {
1117             BoxInfoType box;
1118             if (!ConfigInfo->m_boxInfo.m_boxSrc.empty()) {
1119                 if ((0 == ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 4, L"http"))
1120                     || (0 ==
1121                         ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 5, L"https")))
1122                 {
1123                     box.boxSrc = ConfigInfo->m_boxInfo.m_boxSrc;
1124                 } else {
1125                     box.boxSrc = defaultLocale + ConfigInfo->m_boxInfo.m_boxSrc;
1126                 }
1127             }
1128
1129             if (ConfigInfo->m_boxInfo.m_boxMouseEvent == L"true") {
1130                 std::string boxType;
1131                 if (ConfigInfo->m_type == L"") {
1132                     // in case of default livebox
1133                     boxType = web_provider_livebox_get_default_type();
1134                 } else {
1135                     boxType = DPL::ToUTF8String(ConfigInfo->m_type);
1136                 }
1137
1138                 int box_scrollable =
1139                     web_provider_plugin_get_box_scrollable(boxType.c_str());
1140
1141                 if (box_scrollable) {
1142                     box.boxMouseEvent = L"true";
1143                 } else {
1144                     box.boxMouseEvent = L"false";
1145                 }
1146             } else {
1147                 box.boxMouseEvent = L"false";
1148             }
1149
1150             if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
1151                 box.boxTouchEffect = L"true";
1152             } else {
1153                 box.boxTouchEffect= L"false";
1154             }
1155
1156             ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
1157                 ConfigInfo->m_boxInfo.m_boxSize;
1158             FOREACH(it, boxSizeList) {
1159                 if (!(*it).m_preview.empty()) {
1160                     (*it).m_preview =
1161                         DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
1162                         DPL::String(L"/") +
1163                         ConfigInfo->m_liveboxId + DPL::String(L".") +
1164                         (*it).m_size + DPL::String(L".preview.png");
1165                 }
1166                 box.boxSize.push_back((*it));
1167             }
1168
1169             if (!ConfigInfo->m_boxInfo.m_pdSrc.empty()
1170                 && !ConfigInfo->m_boxInfo.m_pdWidth.empty()
1171                 && !ConfigInfo->m_boxInfo.m_pdHeight.empty())
1172             {
1173                 if ((0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 4, L"http"))
1174                     || (0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 5, L"https")))
1175                 {
1176                     box.pdSrc = ConfigInfo->m_boxInfo.m_pdSrc;
1177                 } else {
1178                     box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
1179                 }
1180                 box.pdWidth = ConfigInfo->m_boxInfo.m_pdWidth;
1181                 box.pdHeight = ConfigInfo->m_boxInfo.m_pdHeight;
1182             }
1183             liveBox.setBox(box);
1184         }
1185         manifest.addLivebox(liveBox);
1186     }
1187 }
1188
1189 void TaskManifestFile::setAccount(Manifest& manifest)
1190 {
1191     WrtDB::ConfigParserData::AccountProvider account =
1192         m_context.widgetConfig.configInfo.accountProvider;
1193
1194     AccountProviderType provider;
1195
1196     if (account.m_iconSet.empty()) {
1197         _D("Widget doesn't contain Account");
1198         return;
1199     }
1200     if (account.m_multiAccountSupport) {
1201         provider.multiAccount = L"true";
1202     } else {
1203         provider.multiAccount = L"false";
1204     }
1205     provider.appid = m_context.widgetConfig.tzAppid;
1206
1207     FOREACH(it, account.m_iconSet) {
1208         std::pair<DPL::String, DPL::String> icon;
1209
1210         if (it->first == ConfigParserData::IconSectionType::DefaultIcon) {
1211             icon.first = L"account";
1212         } else if (it->first == ConfigParserData::IconSectionType::SmallIcon) {
1213             icon.first = L"account-small";
1214         }
1215         icon.second = it->second;
1216
1217         provider.icon.push_back(icon);
1218     }
1219
1220     FOREACH(it, account.m_displayNameSet) {
1221         provider.name.push_back(LabelType(it->second, it->first));
1222     }
1223
1224     FOREACH(it, account.m_capabilityList) {
1225         provider.capability.push_back(*it);
1226     }
1227
1228     Account accountInfo;
1229     accountInfo.addAccountProvider(provider);
1230     manifest.addAccount(accountInfo);
1231 }
1232
1233 void TaskManifestFile::setPrivilege(Manifest& manifest)
1234 {
1235     WrtDB::ConfigParserData::PrivilegeList privileges =
1236         m_context.widgetConfig.configInfo.privilegeList;
1237
1238     PrivilegeType privilege;
1239
1240     FOREACH(it, privileges)
1241     {
1242         privilege.addPrivilegeName(it->name);
1243     }
1244
1245     manifest.addPrivileges(privilege);
1246 }
1247
1248 void TaskManifestFile::StartStep()
1249 {
1250
1251 }
1252
1253 void TaskManifestFile::EndStep()
1254 {
1255
1256 }
1257 } //namespace WidgetInstall
1258 } //namespace Jobs