Update wrt-installer_0.0.51
[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 <string>
25 #include <dpl/assert.h>
26 #include <dirent.h>
27 #include<fstream>
28 #include <ail.h>
29
30 //WRT INCLUDES
31 #include <widget_install/task_manifest_file.h>
32 #include <widget_install/job_widget_install.h>
33 #include <widget_install/widget_install_errors.h>
34 #include <widget_install/widget_install_context.h>
35 #include <dpl/wrt-dao-ro/global_config.h>
36 #include <dpl/log/log.h>
37 #include <dpl/file_input.h>
38 #include <dpl/file_output.h>
39 #include <dpl/copy.h>
40 #include <dpl/exception.h>
41 #include <dpl/foreach.h>
42 #include <dpl/sstream.h>
43 #include <dpl/string.h>
44 #include <dpl/optional.h>
45 #include <dpl/utils/wrt_utility.h>
46 #include <map>
47 #include <libxml_utils.h>
48 #include <pkgmgr/pkgmgr_parser.h>
49
50 using namespace WrtDB;
51
52 namespace {
53 typedef std::map<DPL::String, DPL::String> LanguageTagMap;
54
55 LanguageTagMap getLanguageTagMap()
56 {
57     LanguageTagMap map;
58
59 #define ADD(tag, l_tag) map.insert(std::make_pair(L ## # tag, L ## # l_tag));
60 #include "languages.def"
61 #undef ADD
62
63     return map;
64 }
65
66 DPL::OptionalString getLangTag(const DPL::String& tag)
67 {
68     static LanguageTagMap TagsMap =
69         getLanguageTagMap();
70
71     DPL::String langTag = tag;
72
73     LogDebug("Trying to map language tag: " << langTag);
74     size_t pos = langTag.find_first_of(L'_');
75     if (pos != DPL::String::npos) {
76         langTag.erase(pos);
77     }
78     DPL::OptionalString ret;
79
80     LanguageTagMap::iterator it = TagsMap.find(langTag);
81     if (it != TagsMap.end()) {
82         ret = it->second;
83     }
84     LogDebug("Mapping IANA Language tag to language tag: " <<
85              langTag << " -> " << ret);
86
87     return ret;
88 }
89 }
90
91 namespace Jobs {
92 namespace WidgetInstall {
93
94 const char * TaskManifestFile::encoding = "UTF-8";
95
96 TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
97     DPL::TaskDecl<TaskManifestFile>(this),
98     m_context(inCont)
99 {
100     if (false == m_context.existingWidgetInfo.isExist) {
101         AddStep(&TaskManifestFile::stepCopyIconFiles);
102         //AddStep(&TaskManifestFile::stepCreateDesktopFile);
103         AddStep(&TaskManifestFile::stepGenerateManifest);
104         AddStep(&TaskManifestFile::stepParseManifest);
105         AddStep(&TaskManifestFile::stepCreateExecFile);
106         AddStep(&TaskManifestFile::stepFinalize);
107     } else {
108     // for widget update.
109         AddStep(&TaskManifestFile::stepBackupIconFiles);
110         AddStep(&TaskManifestFile::stepCopyIconFiles);
111         //AddStep(&TaskManifestFile::stepUpdateDesktopFile);
112         AddStep(&TaskManifestFile::stepGenerateManifest);
113         AddStep(&TaskManifestFile::stepParseUpgradedManifest);
114         AddStep(&TaskManifestFile::stepUpdateFinalize);
115
116         AddAbortStep(&TaskManifestFile::stepAbortIconFiles);
117         //AddAbortStep(&TaskManifestFile::stepAbortDesktopFile);
118     }
119 }
120
121 TaskManifestFile::~TaskManifestFile()
122 {
123 }
124
125
126 void TaskManifestFile::stepCreateDesktopFile()
127 {
128     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
129     desktop_name << pkgname << ".desktop";
130     desktop_file << "/tmp/" << desktop_name.str();
131     LogInfo("desktop file : " << desktop_file.str());
132     std::ofstream file(desktop_file.str().c_str());
133
134     saveWidgetType(file);
135     saveWidgetExecPath(file);
136     saveWidgetName(file);
137     saveWidgetIcons(file);
138     saveWidgetVersion(file);
139     saveWidgetOtherInfo(file);
140     saveAppServiceInfo(file);
141
142     file.close();
143
144     moveDesktopFile();
145
146     m_context.job->UpdateProgress(
147         InstallerContext::INSTALL_CREATE_DESKTOP,
148         "Widget Desktop Creation Finished");
149 }
150
151 void TaskManifestFile::stepCreateExecFile()
152 {
153     //ln -s /usr/bin/wrt-client {widget-handle}
154
155     std::ostringstream real_path;
156     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
157     if (pkgname.IsNull()) {
158         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
159     }
160
161     real_path << GlobalConfig::GetUserInstalledWidgetPath() << "/";
162     real_path << pkgname << "/";
163     real_path << GlobalConfig::GetUserWidgetExecPath() << "/" <<
164     m_context.widgetHandle;
165     std::string clientExeStr = GlobalConfig::GetWrtClientExec();
166
167     LogInfo("link -s " << clientExeStr << " " << real_path.str());
168     symlink(clientExeStr.c_str(), real_path.str().c_str());
169
170     m_context.job->UpdateProgress(
171         InstallerContext::INSTALL_CREATE_EXECFILE,
172         "Widget execfile creation Finished");
173 }
174
175 void TaskManifestFile::stepCopyIconFiles()
176 {
177     LogDebug("CopyIconFiles");
178
179     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
180     if (pkgname.IsNull()) {
181         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
182     }
183
184     Assert(!!m_context.widgetHandle);
185     WidgetDAOReadOnly dao(*m_context.widgetHandle);
186     WidgetDAOReadOnly::WidgetLocalizedIconList locList = dao.getLocalizedIconList();
187     WidgetDAOReadOnly::WidgetIconList list = dao.getIconList();
188     FOREACH(it, locList)
189     {
190         DPL::String i = it->widgetLocale;
191         DPL::OptionalString src;
192         FOREACH(icon, list)
193         {
194             if (icon->iconId == it->iconId) {
195                 src = icon->iconSrc;
196             }
197         }
198         LogDebug("Icon for locale: " << i << "is : " << src);
199
200         std::ostringstream sourceFile;
201         std::ostringstream targetFile;
202
203         if (!!src) {
204             sourceFile << GlobalConfig::GetUserInstalledWidgetPath() << "/";
205             sourceFile << pkgname << "/";
206             sourceFile << GlobalConfig::GetWidgetSrcPath() << "/";
207
208             targetFile << GlobalConfig::GetUserWidgetDesktopIconPath() << "/";
209
210             if (!i.empty()) {
211                 sourceFile << "locales/" << i << "/";
212             }
213             sourceFile << *src;
214             targetFile << getIconTargetFilename(i);
215
216         } else {
217             //Use WRT default (not from the widget) only if widget default (not
218             // localized) doesn't exist.
219             if (i.empty()) {
220                 LogError("Using Default Icon for widget");
221                 sourceFile << GlobalConfig::GetUserWidgetDefaultIconFile();
222             } else {
223                 continue;
224             }
225         }
226
227         LogDebug("Copying icon: " << sourceFile.str() <<
228                  " -> " << targetFile.str());
229
230         icon_list.push_back(targetFile.str());
231
232         Try
233         {
234             DPL::FileInput input(sourceFile.str());
235             DPL::FileOutput output(targetFile.str());
236             DPL::Copy(&input, &output);
237         }
238
239         Catch(DPL::FileInput::Exception::Base)
240         {
241             // Error while opening or closing source file
242             //ReThrowMsg(InstallerException::CopyIconFailed, sourceFile.str());
243             LogError(
244                 "Copying widget's icon failed. Widget's icon will not be"\
245                 "available from Main Screen");
246         }
247
248         Catch(DPL::FileOutput::Exception::Base)
249         {
250             // Error while opening or closing target file
251             //ReThrowMsg(InstallerException::CopyIconFailed, targetFile.str());
252             LogError(
253                 "Copying widget's icon failed. Widget's icon will not be"\
254                 "available from Main Screen");
255         }
256
257         Catch(DPL::CopyFailed)
258         {
259             // Error while copying
260             //ReThrowMsg(InstallerException::CopyIconFailed, targetFile.str());
261             LogError(
262                 "Copying widget's icon failed. Widget's icon will not be"\
263                 "available from Main Screen");
264         }
265     }
266
267     m_context.job->UpdateProgress(
268         InstallerContext::INSTALL_COPY_ICONFILE,
269         "Widget iconfile copy Finished");
270 }
271
272 void TaskManifestFile::stepBackupIconFiles()
273 {
274     LogDebug("Backup Icon Files");
275     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
276     desktop_name << pkgname << ".desktop";
277
278     desktop_file << GlobalConfig::GetUserWidgetDesktopPath() << "/";
279     desktop_file << desktop_name.str();
280
281     backup_dir << GlobalConfig::GetUserInstalledWidgetPath();
282     backup_dir << "/" << m_context.widgetConfig.pkgname;
283     backup_dir << "/" << "backup" << "/";
284
285     backupIconFiles();
286
287     m_context.job->UpdateProgress(
288         InstallerContext::INSTALL_BACKUP_ICONFILE,
289         "New Widget icon file backup Finished");
290 }
291
292
293 void TaskManifestFile::stepUpdateDesktopFile()
294 {
295     LogDebug("Update Desktop File");
296     backupDesktopFile();
297
298     std::ofstream file(desktop_file.str().c_str(), std::ios::trunc);
299
300     saveWidgetType(file);
301     saveWidgetExecPath(file);
302     saveWidgetName(file);
303     saveWidgetIcons(file);
304     saveWidgetVersion(file);
305     saveWidgetOtherInfo(file);
306     saveAppServiceInfo(file);
307
308     file.close();
309
310     updateAilInfo();
311
312     m_context.job->UpdateProgress(
313         InstallerContext::INSTALL_UPDATE_DESKTOP,
314         "New Widget desktop file update Finished");
315 }
316
317 void TaskManifestFile::stepAbortIconFiles()
318 {
319     LogDebug("Abrot Icon Files");
320     FOREACH(it, icon_list)
321     {
322         LogDebug("Remove Update Icon : " << (*it));
323         unlink((*it).c_str());
324     }
325
326     std::ostringstream b_icon_dir;
327     b_icon_dir << backup_dir.str() << "icons";
328
329     std::list<std::string> fileList;
330     getFileList(b_icon_dir.str().c_str(), fileList);
331
332     FOREACH(back_icon, fileList)
333     {
334         std::ostringstream res_file;
335         res_file << GlobalConfig::GetUserWidgetDesktopIconPath();
336         res_file << "/" << (*back_icon);
337
338         std::ostringstream backup_file;
339         backup_file << b_icon_dir.str() << "/" << (*back_icon);
340
341         Try
342         {
343             DPL::FileInput input(backup_file.str());
344             DPL::FileOutput output(res_file.str());
345             DPL::Copy(&input, &output);
346         }
347         Catch(DPL::FileInput::Exception::Base)
348         {
349             LogError("Restoration icon File Failed." << backup_file.str()
350                     << " to " << res_file.str());
351         }
352
353         Catch(DPL::FileOutput::Exception::Base)
354         {
355             LogError("Restoration icon File Failed." << backup_file.str()
356                     << " to " << res_file.str());
357         }
358         Catch(DPL::CopyFailed)
359         {
360             LogError("Restoration icon File Failed." << backup_file.str()
361                     << " to " << res_file.str());
362         }
363     }
364 }
365
366 void TaskManifestFile::stepUpdateFinalize()
367 {
368     LogDebug("Finished Update Desktopfile");
369 }
370
371 void TaskManifestFile::stepAbortDesktopFile()
372 {
373     LogDebug("Abort desktop backup ");
374
375     std::ifstream backupFile(bp_desktop_file.str().c_str());
376     std::ofstream file(desktop_file.str().c_str(), std::ios::trunc);
377
378     while(!backupFile.eof()) {
379         char contents[256] = {0, };
380
381         backupFile.getline(contents, sizeof(contents));
382         file << contents << std::endl;
383     }
384     backupFile.close();
385     file.close();
386
387     updateAilInfo();
388
389     m_context.job->UpdateProgress(
390         InstallerContext::INSTALL_UPDATE_DESKTOP,
391         "New Widget desktop file update Finished");
392 }
393
394 void TaskManifestFile::moveDesktopFile()
395 {
396     std::ostringstream destFile;
397     destFile << GlobalConfig::GetUserWidgetDesktopPath() << "/";
398     destFile << desktop_name.str();
399     LogInfo("cp " << desktop_file.str() << " " << destFile.str());
400     Try
401     {
402         DPL::FileInput input(desktop_file.str());
403         DPL::FileOutput output(destFile.str());
404         DPL::Copy(&input, &output);
405     }
406
407     Catch(DPL::FileInput::Exception::Base)
408     {
409         // Error while opening or closing source file
410         //        ReThrowMsg(InstallerException::CopyIconFailed,
411         //                   desktop_file.str());
412         LogError(
413             "Creating Desktop File Failed. Widget's icon will not be available"\
414             "from Main Screen");
415     }
416
417     Catch(DPL::FileOutput::Exception::Base)
418     {
419         // Error while opening or closing target file
420         //        ReThrowMsg(InstallerException::CopyIconFailed,
421         //                   destFile.str());
422         LogError(
423             "Creating Desktop File Failed. Widget's icon will not be available"\
424             "from Main Screen");
425     }
426
427     Catch(DPL::CopyFailed)
428     {
429         // Error while copying
430         //        ReThrowMsg(InstallerException::CopyIconFailed,
431         //                   destFile.str());
432         LogError(
433             "Creating Desktop File Failed. Widget's icon will not be available"\
434             "from Main Screen");
435     }
436
437     updateAilInfo();
438
439     //removing temp file
440     unlink(desktop_file.str().c_str());
441 }
442
443 void TaskManifestFile::saveWidgetType(std::ofstream &file)
444 {
445     file << "Type=" << "Application" << std::endl;
446 }
447
448 void TaskManifestFile::saveWidgetExecPath(std::ofstream &file)
449 {
450     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
451     if (pkgname.IsNull()) {
452         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
453     }
454
455     file << "Exec=";
456     file << GlobalConfig::GetUserInstalledWidgetPath() << "/";
457     file << pkgname << "/";
458     file << GlobalConfig::GetUserWidgetExecPath() << "/";
459     file << m_context.widgetHandle << std::endl;
460 }
461
462 void TaskManifestFile::saveWidgetVersion(std::ofstream &file)
463 {
464     DPL::OptionalString widget_version = m_context.widgetConfig.version;
465     file << "Version=" << widget_version << std::endl;
466 }
467
468 void TaskManifestFile::saveWidgetName(std::ofstream &file)
469 {
470     Assert(!!m_context.widgetHandle);
471     WidgetDAOReadOnly dao(*m_context.widgetHandle);
472     LanguageTagsList languageTags(dao.getLanguageTags());
473     bool defaultNameSaved = false;
474     auto generateWidgetName = [&] (const DPL::OptionalString& tag,
475                                    const DPL::OptionalString& language)
476     {
477         DPL::OptionalString name = dao.getLocalizedInfo(*language).name;
478         if (!!name) {
479             if (!!tag)
480             {
481                 saveLocalizedKey(file, L"Name", *tag);
482             }
483             else
484             {
485                 file << "Name=";
486                 defaultNameSaved = true;
487             }
488             file << *name;
489             file << std::endl;
490         }
491     };
492
493     FOREACH(i, languageTags)
494     {
495         DPL::OptionalString tag = getLangTag(*i);// translate en -> en_US etc
496         if (tag.IsNull()) { tag = *i; }
497
498         generateWidgetName(tag, *i);
499
500     }
501     DPL::OptionalString defaultLocale = dao.getDefaultlocale();
502     if (!!defaultLocale && !defaultNameSaved)
503     {
504         generateWidgetName(DPL::OptionalString::Null, *defaultLocale);
505     }
506 }
507
508 void TaskManifestFile::saveWidgetIcons(std::ofstream &file)
509 {
510     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
511     if (pkgname.IsNull()) {
512         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
513     }
514
515     //TODO this file will need to be updated when user locale preferences
516     //changes.
517     Assert(!!m_context.widgetHandle);
518     WidgetDAOReadOnly dao(*m_context.widgetHandle);
519
520     WidgetDAOReadOnly::WidgetLocalizedIconList locList = dao.getLocalizedIconList();
521     WidgetDAOReadOnly::WidgetIconList list = dao.getIconList();
522
523     LanguageTagsList languageTags(dao.getLanguageTags());
524     bool defaultIconSaved = false;
525
526
527     auto generateWidgetIcon = [&] (const DPL::OptionalString& tag,
528                                    const DPL::String& language,
529                                    int iconId)
530     {
531         if (!!tag)
532         {
533             saveLocalizedKey(file, L"Icon", *tag);
534         }
535         else
536         {
537             file << "Icon=";
538             defaultIconSaved = true;
539         }
540
541         DPL::OptionalString src;
542         FOREACH(icon, list)
543         {
544             if (icon->iconId == iconId) {
545                 src = icon->iconSrc;
546             }
547         }
548         if (!!src) {
549             //If menuscreen need use absolute path of widget's icon, comment out
550             //the following lines.
551
552             file << GlobalConfig::GetUserWidgetDesktopIconPath() << "/";
553             file << getIconTargetFilename(language) << std::endl;
554         }
555     };
556
557     FOREACH(it, locList)
558     {
559         DPL::String i = it->widgetLocale;
560         DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
561         if (tag.IsNull()) { tag = i; }
562
563         generateWidgetIcon(tag, i, it->iconId);
564
565     }
566     DPL::OptionalString defaultLocale = dao.getDefaultlocale();
567     if (!!defaultLocale && !defaultIconSaved)
568     {
569         int iconId = -1;
570         FOREACH(it, locList)
571         {
572             if (it->widgetLocale == *defaultLocale)
573             {
574                 iconId = it->iconId;
575             }
576         }
577         if (-1 != iconId)
578         {
579             generateWidgetIcon(DPL::OptionalString::Null,
580                                DPL::String(),
581                                iconId);
582         }
583     }
584 }
585
586 DPL::String TaskManifestFile::getIconTargetFilename(
587         const DPL::String& languageTag) const
588 {
589     DPL::OStringStream filename;
590     DPL::Optional<DPL::String> pkgname = m_context.widgetConfig.pkgname;
591     if (pkgname.IsNull()) {
592         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
593     }
594
595     filename << DPL::ToUTF8String(*pkgname).c_str();
596
597     if (!languageTag.empty()) {
598         DPL::OptionalString tag = getLangTag(languageTag); // translate en -> en_US etc
599         if (tag.IsNull()) { tag = languageTag; }
600         DPL::String locale =
601             LocalizationUtils::BCP47LanguageTagToLocale(*tag);
602
603        if(locale.empty()) {
604             filename << L"." << languageTag;
605         } else {
606             filename << L"." << locale;
607         }
608     }
609
610     filename << L".png";
611     return filename.str();
612 }
613
614 void TaskManifestFile::saveWidgetOtherInfo(std::ofstream &file)
615 {
616     DPL::Optional<DPL::String> widgetID = m_context.widgetConfig.guid;
617
618     //    /* network */
619     //    strncat(desktop, format_network, strlen(format_network));
620     //    //TODO -- get the network value from the widget
621     //    strncat(desktop, "True", 4);
622     //    strncat(desktop, line, strlen(line));
623
624     /* Comment */
625     file << "Comment=Widget application" << std::endl;
626
627     /* bg_schedule */
628     //file << "BG_SCHEDULE=True" << std::endl;
629
630     /* visible */
631     file << "nodisplay=FALSE" << std::endl;
632
633     file << "X-TIZEN-PackageType=wgt" << std::endl;
634     if (!widgetID.IsNull()) {
635         file << "X-TIZEN-PackageID=" << DPL::ToUTF8String(*widgetID).c_str() << std::endl;
636     }
637 }
638
639 void TaskManifestFile::saveAppServiceInfo(std::ofstream &file)
640 {
641     Assert(!!m_context.widgetHandle);
642     WidgetDAOReadOnly dao(*m_context.widgetHandle);
643     WidgetApplicationServiceList appServiceList;
644     dao.getAppServiceList(appServiceList);
645
646     if (appServiceList.empty()) {
647         LogInfo("Widget doesn't contain application service");
648         return;
649     }
650
651     // x-tizen-svc=http://tizen.org/appsvc/operation/pick|NULL|image;
652     file << "X-TIZEN-SVC=";
653     FOREACH(it, appServiceList) {
654         if (appServiceList.begin() != it) {
655             file << ";";
656         }
657         file << DPL::ToUTF8String(it->operation).c_str() << "|";
658         if (it->scheme.empty()) {
659             file << "NULL" << "|";
660         } else {
661             file << DPL::ToUTF8String(it->scheme).c_str() << "|";
662         }
663         if (it->mime.empty()) {
664             file << "NULL";
665         } else {
666             file << DPL::ToUTF8String(it->mime).c_str();
667         }
668     }
669 }
670
671 void TaskManifestFile::stepFinalize()
672 {
673     LogInfo("Finished ManifestFile step");
674 }
675
676 void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
677         const DPL::String& key,
678         const DPL::String& languageTag)
679 {
680     DPL::String locale =
681         LocalizationUtils::BCP47LanguageTagToLocale(languageTag);
682
683     file << key;
684     if (!locale.empty()) {
685         file << "[" << locale << "]";
686     }
687     file << "=";
688 }
689
690 void TaskManifestFile::updateAilInfo()
691 {
692     // Update ail for desktop
693     std::string cfgPkgname =
694         DPL::ToUTF8String(*m_context.widgetConfig.pkgname);
695     const char* pkgname = cfgPkgname.c_str();
696
697     LogDebug("Update ail desktop : " << pkgname );
698     ail_appinfo_h ai = NULL;
699     ail_error_e ret;
700
701     ret = ail_package_get_appinfo(pkgname, &ai);
702     if (ai) {
703         ail_package_destroy_appinfo(ai);
704     }
705     
706     if (AIL_ERROR_NO_DATA == ret) {
707         if (ail_desktop_add(pkgname) < 0) {
708             LogDebug("Failed to add ail desktop : " << pkgname);
709         }
710     } else if (AIL_ERROR_OK == ret) {
711         if (ail_desktop_update(pkgname) < 0) {
712             LogDebug("Failed to update ail desktop : " << pkgname);
713         }
714     }
715 }
716
717 void TaskManifestFile::backupIconFiles()
718 {
719     LogInfo("Backup Icon Files");
720
721     std::ostringstream b_icon_dir;
722     b_icon_dir << backup_dir.str() << "icons";
723
724     LogDebug("Create icon backup folder : " << b_icon_dir.str());
725     _WrtMakeDir(b_icon_dir.str().c_str(), 0755, WRT_FILEUTILS_RECUR);
726
727     std::list<std::string> fileList;
728     getFileList(GlobalConfig::GetUserWidgetDesktopIconPath(), fileList);
729     std::string pkgname = DPL::ToUTF8String(*m_context.widgetConfig.pkgname);
730     
731     FOREACH(it, fileList)
732     {
733         if (0 == (strncmp((*it).c_str(), pkgname.c_str(),
734                         strlen(pkgname.c_str())))) {
735             std::ostringstream icon_file, backup_icon;
736             icon_file << GlobalConfig::GetUserWidgetDesktopIconPath();
737             icon_file << "/" << (*it);
738
739             backup_icon << b_icon_dir.str() << "/" << (*it);
740
741             LogDebug("Backup icon file " << icon_file.str() << " to " <<
742                     backup_icon.str());
743             Try
744             {
745                 DPL::FileInput input(icon_file.str());
746                 DPL::FileOutput output(backup_icon.str());
747                 DPL::Copy(&input, &output);
748             }
749             Catch(DPL::FileInput::Exception::Base)
750             {
751                 LogError("Backup Desktop File Failed.");
752                 ReThrowMsg(Exceptions::BackupFailed, icon_file.str());
753             }
754
755             Catch(DPL::FileOutput::Exception::Base)
756             {
757                 LogError("Backup Desktop File Failed.");
758                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
759             }
760             Catch(DPL::CopyFailed)
761             {
762                 LogError("Backup Desktop File Failed.");
763                 ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
764             }
765             unlink((*it).c_str());
766         }
767     }
768 }
769
770 void TaskManifestFile::backupDesktopFile()
771 {
772     LogInfo("Backup Desktop File");
773
774     std::ostringstream b_desktop_dir;
775     b_desktop_dir << backup_dir.str() <<  "desktop";
776
777     LogDebug("Create desktop file backup folder : " << b_desktop_dir.str());
778     _WrtMakeDir(b_desktop_dir.str().c_str(), 0755, WRT_FILEUTILS_RECUR);
779
780     bp_desktop_file << b_desktop_dir.str() << "/" << desktop_name.str();
781
782     Try
783     {
784         DPL::FileInput input(desktop_file.str());
785         DPL::FileOutput output(bp_desktop_file.str());
786         DPL::Copy(&input, &output);
787     }
788
789     Catch(DPL::FileInput::Exception::Base)
790     {
791         ReThrowMsg(Exceptions::BackupFailed, desktop_file.str());
792     }
793
794     Catch(DPL::FileOutput::Exception::Base)
795     {
796         ReThrowMsg(Exceptions::BackupFailed, bp_desktop_file.str());
797     }
798     Catch(DPL::CopyFailed)
799     {
800         ReThrowMsg(Exceptions::BackupFailed, bp_desktop_file.str());
801     }
802 }
803
804 void TaskManifestFile::getFileList(const char* path,
805         std::list<std::string> &list)
806 {
807     DIR* dir = opendir(path);
808     if (!dir) {
809         LogError("icon directory doesn't exist");
810         ThrowMsg(Exceptions::InternalError, path);
811     }
812
813     struct dirent* d_ent;
814     do {
815         if ((d_ent = readdir(dir))) {
816             if(strcmp(d_ent->d_name, ".") == 0 || 
817                     strcmp(d_ent->d_name, "..") == 0) {
818                 continue;
819             }
820             std::string file_name = d_ent->d_name;
821             list.push_back(file_name);
822         }
823     }while(d_ent);
824 }
825
826 void TaskManifestFile::stepGenerateManifest()
827 {
828     DPL::String pkgname = *m_context.widgetConfig.pkgname;
829     manifest_name = pkgname + L".xml";
830     manifest_file += L"/tmp/" + manifest_name;
831
832     //libxml - init and check
833     LibxmlSingleton::Instance().init();
834
835     writeManifest(manifest_file);
836     validateManifest();
837     commitManifest();
838
839     m_context.job->UpdateProgress(
840         InstallerContext::INSTALL_CREATE_MANIFEST,
841         "Widget Manifest Creation Finished");
842 }
843
844 void TaskManifestFile::stepParseManifest()
845 {
846     int code = pkgmgr_parser_parse_manifest_for_installation(
847             DPL::ToUTF8String(manifest_file).c_str(), NULL);
848
849     if(code != 0)
850     {
851         LogError("Manifest parser error: " << code);
852         ThrowMsg(ManifestParsingError, "Parser returncode: " << code);
853     }
854
855     // TODO : It will be removed. AIL update is temporary code request by pkgmgr team.
856     updateAilInfo();
857
858     m_context.job->UpdateProgress(
859         InstallerContext::INSTALL_CREATE_MANIFEST,
860         "Widget Manifest Parsing Finished");
861     LogDebug("Manifest parsed");
862 }
863
864 void TaskManifestFile::stepParseUpgradedManifest()
865 {
866     int code = pkgmgr_parser_parse_manifest_for_upgrade(
867             DPL::ToUTF8String(manifest_file).c_str(), NULL);
868
869     if(code != 0)
870     {
871         LogError("Manifest parser error: " << code);
872         ThrowMsg(ManifestParsingError, "Parser returncode: " << code);
873     }
874
875     // TODO : It will be removed. AIL update is temporary code request by pkgmgr team.
876     updateAilInfo();
877
878     m_context.job->UpdateProgress(
879         InstallerContext::INSTALL_CREATE_MANIFEST,
880         "Widget Manifest Parsing Finished");
881     LogDebug("Manifest parsed");
882 }
883
884 void TaskManifestFile::validateManifest()
885 {
886     int code = pkgmgr_parser_check_manifest_validation(
887             DPL::ToUTF8String(manifest_name).c_str());
888
889     if(code != 0)
890     {
891         LogError("Manifest validation error");
892         //TODO: manifest files are not yet validating properly because of href
893         // attribute in author element (incompatible types in W3C spec. and
894         // manifest spec.)
895         //ThrowMsg(ManifestValidationError, "Validation returncode: " << code);
896     }
897
898     m_context.job->UpdateProgress(
899         InstallerContext::INSTALL_CREATE_MANIFEST,
900         "Widget Manifest Validation Finished");
901     LogDebug("Manifest validated");
902 }
903
904 void TaskManifestFile::commitManifest()
905 {
906     LogDebug("Commiting manifest file : " << manifest_file);
907
908     std::ostringstream destFile;
909     destFile << "/opt/share/packages" << "/"; //TODO constant with path
910     destFile << DPL::ToUTF8String(manifest_name);
911     LogInfo("cp " << manifest_file << " " << destFile.str());
912
913     DPL::FileInput input(DPL::ToUTF8String(manifest_file));
914     DPL::FileOutput output(destFile.str());
915     DPL::Copy(&input, &output);
916     LogDebug("Manifest writen to: " << destFile.str());
917
918     //removing temp file
919     unlink((DPL::ToUTF8String(manifest_file)).c_str());
920     manifest_file = DPL::FromUTF8String(destFile.str().c_str());
921 }
922
923 void TaskManifestFile::writeManifest(const DPL::String & path)
924 {
925     LogDebug("Generating manifest file : " << path);
926     Manifest manifest;
927     UiApplication uiApp;
928
929     setWidgetExecPath(uiApp);
930     setWidgetName(manifest, uiApp);
931     setWidgetIcons(uiApp);
932     setWidgetManifest(manifest);
933     setWidgetOtherInfo(uiApp);
934     setAppServiceInfo(uiApp);
935
936     manifest.addUiApplication(uiApp);
937     manifest.generate(path);
938     LogDebug("Manifest file serialized");
939 }
940
941 void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp)
942 {
943     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
944     if (pkgname.IsNull()) {
945         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
946     }
947
948     std::ostringstream path;
949     path << GlobalConfig::GetUserInstalledWidgetPath() << "/" << *pkgname << "/";
950     path << GlobalConfig::GetUserWidgetExecPath() << "/" << *m_context.widgetHandle;
951     uiApp.setExec(DPL::FromASCIIString(path.str()));
952 }
953
954 void TaskManifestFile::setWidgetName(Manifest & manifest, UiApplication & uiApp)
955 {
956     Assert(!!m_context.widgetHandle);
957     WidgetDAOReadOnly dao(*m_context.widgetHandle);
958     LanguageTagsList languageTags(dao.getLanguageTags());
959     bool defaultNameSaved = false;
960
961     //labels
962     FOREACH(i, languageTags)
963     {
964         DPL::OptionalString tag = getLangTag(*i); // translate en -> en_US etc
965         if (tag.IsNull())
966         {
967             tag = *i;
968         }
969         DPL::OptionalString name = dao.getLocalizedInfo(*i).name;
970         generateWidgetName(manifest, uiApp, tag, name, defaultNameSaved);
971     }
972     DPL::OptionalString defaultLocale = dao.getDefaultlocale();
973     if (!!defaultLocale && !defaultNameSaved)
974     {
975         DPL::OptionalString name = dao.getLocalizedInfo(*defaultLocale).name;
976         generateWidgetName(manifest, uiApp, DPL::OptionalString::Null, name, defaultNameSaved);
977     }
978     //appid
979     DPL::String pkgname;
980     if(!!m_context.widgetConfig.pkgname)
981     {
982         pkgname = *m_context.widgetConfig.pkgname;
983         uiApp.setAppid(pkgname);
984     }
985
986     //extraid
987     if(!!m_context.widgetConfig.guid) {
988         uiApp.setExtraid(*m_context.widgetConfig.guid);
989     } else {
990         if(!pkgname.empty()) {
991             uiApp.setExtraid(DPL::String(L"http://") + pkgname);
992         }
993     }
994
995     //type
996     uiApp.setType(DPL::FromASCIIString("webapp"));
997     manifest.setType(L"wgt");
998     uiApp.setTaskmanage(true);
999 }
1000
1001 void TaskManifestFile::generateWidgetName(Manifest & manifest, UiApplication &uiApp, const DPL::OptionalString& tag, DPL::OptionalString name, bool & defaultNameSaved)
1002 {
1003     if (!!name) {
1004         if (!!tag)
1005         {
1006             DPL::String locale =
1007                 LocalizationUtils::BCP47LanguageTagToLocale(*tag);
1008
1009             if (!locale.empty()) {
1010                 uiApp.addLabel(LabelType(*name,*tag));
1011             }
1012             else
1013             {
1014                 uiApp.addLabel(LabelType(*name));
1015                 manifest.addLabel(LabelType(*name));
1016             }
1017         }
1018         else
1019         {
1020             defaultNameSaved = true;
1021             uiApp.addLabel(LabelType(*name));
1022             manifest.addLabel(LabelType(*name));
1023         }
1024     }
1025 }
1026
1027 void TaskManifestFile::setWidgetIcons(UiApplication & uiApp)
1028 {
1029     DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
1030     if (pkgname.IsNull()) {
1031         ThrowMsg(Exceptions::InternalError, "No Package name exists.");
1032     }
1033
1034     //TODO this file will need to be updated when user locale preferences
1035     //changes.
1036     Assert(!!m_context.widgetHandle);
1037     WidgetDAOReadOnly dao(*m_context.widgetHandle);
1038
1039     WidgetDAOReadOnly::WidgetLocalizedIconList locList = dao.getLocalizedIconList();
1040     WidgetDAOReadOnly::WidgetIconList list = dao.getIconList();
1041     bool defaultIconSaved = false;
1042
1043     FOREACH(it, locList)
1044     {
1045         DPL::String i = it->widgetLocale;
1046         DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
1047         if (tag.IsNull()) { tag = i; }
1048
1049         generateWidgetIcon(uiApp, tag, i, it->iconId, list, defaultIconSaved);
1050     }
1051     DPL::OptionalString defaultLocale = dao.getDefaultlocale();
1052     if (!!defaultLocale && !defaultIconSaved)
1053     {
1054         int iconId = -1;
1055         FOREACH(it, locList)
1056         {
1057             if (it->widgetLocale == *defaultLocale)
1058             {
1059                 iconId = it->iconId;
1060             }
1061         }
1062         if (-1 != iconId)
1063         {
1064             generateWidgetIcon(uiApp, DPL::OptionalString::Null,
1065                                DPL::String(),
1066                                iconId,
1067                                list,
1068                                defaultIconSaved);
1069         }
1070     }
1071 }
1072
1073 void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp, const DPL::OptionalString& tag, const DPL::String& language, int iconId, const WrtDB::WidgetDAOReadOnly::WidgetIconList & list, bool & defaultIconSaved)
1074 {
1075     DPL::String locale;
1076     if (!!tag)
1077     {
1078         locale = LocalizationUtils::BCP47LanguageTagToLocale(*tag);
1079     }
1080     else
1081     {
1082         defaultIconSaved = true;
1083     }
1084
1085     DPL::OptionalString src;
1086     FOREACH(icon, list)
1087     {
1088         if (icon->iconId == iconId) {
1089             src = icon->iconSrc;
1090         }
1091     }
1092     if (!!src) {
1093         DPL::String iconText;
1094         iconText += /*DPL::FromASCIIString(GlobalConfig::GetUserWidgetDesktopIconPath()) + L"/" +*/ getIconTargetFilename(language);
1095         if(!locale.empty())
1096         {
1097             uiApp.addIcon(IconType(iconText,locale));
1098         }
1099         else
1100         {
1101             uiApp.addIcon(IconType(iconText));
1102         }
1103     }
1104 }
1105
1106 void TaskManifestFile::setWidgetManifest(Manifest & manifest)
1107 {
1108     if(!!m_context.widgetConfig.pkgname)
1109     {
1110         manifest.setPackage(*m_context.widgetConfig.pkgname);
1111     }
1112     if(!!m_context.widgetConfig.version)
1113     {
1114         manifest.setVersion(*m_context.widgetConfig.version);
1115     }
1116     DPL::String email = (!!m_context.widgetConfig.configInfo.authorEmail ?
1117                             *m_context.widgetConfig.configInfo.authorEmail : L"");
1118     DPL::String href = (!!m_context.widgetConfig.configInfo.authorHref ?
1119                             *m_context.widgetConfig.configInfo.authorHref : L"");
1120     DPL::String name = (!!m_context.widgetConfig.configInfo.authorName ?
1121                             *m_context.widgetConfig.configInfo.authorName : L"");
1122     manifest.addAuthor(Author(email,href,L"",name));
1123 }
1124
1125 void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
1126 {
1127     uiApp.setNodisplay(false);
1128     //TODO(t.iwanek):
1129     //There is no "X-TIZEN-PackageType=wgt", there is not field in manifest
1130     //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" << DPL::ToUTF8String(*widgetID).c_str()
1131     //There is no Comment in pkgmgr "Comment=Widget application"
1132 }
1133
1134 void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp)
1135 {
1136     Assert(!!m_context.widgetHandle);
1137     WidgetDAOReadOnly dao(*m_context.widgetHandle);
1138     WidgetApplicationServiceList appServiceList;
1139     dao.getAppServiceList(appServiceList);
1140
1141     if (appServiceList.empty()) {
1142         LogInfo("Widget doesn't contain application service");
1143         return;
1144     }
1145
1146     // x-tizen-svc=http://tizen.org/appsvc/operation/pick|NULL|image;
1147     FOREACH(it, appServiceList) {
1148         ApplicationService appService;
1149         appService.addOperation(it->operation);
1150         appService.addOperation(it->scheme);
1151         appService.addOperation(it->mime);
1152         uiApp.addApplicationService(appService);
1153     }
1154 }
1155
1156 } //namespace WidgetInstall
1157 } //namespace Jobs