Update wrt-installer_0.0.54
[framework/web/wrt-installer.git] / src / jobs / widget_install / job_widget_install.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    job_widget_install.cpp
18  * @author  Radoslaw Wicik r.wicik@samsung.com
19  * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20  * @version 1.0
21  * @brief   Implementation file for main installer task
22  */
23 #include <dpl/noncopyable.h>
24 #include <dpl/abstract_waitable_input_adapter.h>
25 #include <dpl/abstract_waitable_output_adapter.h>
26 #include <dpl/zip_input.h>
27 #include <dpl/scoped_ptr.h>
28 #include <dpl/binary_queue.h>
29 #include <dpl/copy.h>
30 #include <dpl/assert.h>
31 #include <dpl/sstream.h>
32 #include <dpl/wrt-dao-ro/common_dao_types.h>
33 #include <dpl/utils/file_utils.h>
34 #include "root_parser.h"
35 #include "widget_parser.h"
36 #include "parser_runner.h"
37 #include <widget_install/job_widget_install.h>
38 #include <widget_install/task_unzip.h>
39 #include <widget_install/task_certify.h>
40 #include <widget_install/task_widget_config.h>
41 #include <widget_install/task_db_update.h>
42 #include <widget_install/task_file_manipulation.h>
43 #include <widget_install/task_ace_check.h>
44 #include <widget_install/task_smack.h>
45 #include <widget_install/task_manifest_file.h>
46 #include <widget_install/task_private_storage.h>
47 #include <widget_install/task_prepare_files.h>
48 #include <widget_install/task_recovery.h>
49 #include <widget_install/task_install_ospsvc.h>
50 #include <widget_install/task_update_files.h>
51 #include <widget_install/task_new_db_insert.h>
52 #include <widget_install/task_remove_backup.h>
53 #include <widget_install/task_encrypt_resource.h>
54 #include <widget_install/widget_install_errors.h>
55 #include <widget_install/widget_install_context.h>
56 #include <string>
57 #include <sys/time.h>
58 #include <ctime>
59 #include <cstdlib>
60 #include <limits.h>
61 #include <regex.h>
62 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
63 #include <dpl/wrt-dao-ro/global_config.h>
64 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
65 #include <aul.h>
66 #include <dpl/localization/w3c_file_localization.h>
67 #include <libiriwrapper.h>
68 #include <pkg-manager/pkgmgr_signal.h>
69
70 using namespace WrtDB;
71
72 namespace // anonymous
73 {
74 const char * const CONFIG_XML = "config.xml";
75 const char * const WITH_OSP_XML = "res/wgt/config.xml";
76
77 //allowed: a-z, A-Z, 0-9, '.', '-', '_', ' '
78 const char* REG_TIZENID_PATTERN = "^[-. a-zA-Z0-9_@+=]*$";
79 const int RESERVED_COUNT = 20;  //number of chars reserved in name (e.g. for '.desktop')
80 const int MAX_TIZENID_LENTH = 255 - RESERVED_COUNT;
81
82 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
83 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
84
85 class InstallerTaskFail :
86     public DPL::TaskDecl<InstallerTaskFail>
87 {
88   private:
89     bool m_deferred;
90
91     void StepFail()
92     {
93         if (m_deferred) {
94             ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred,
95                      "Widget installation or update deferred!");
96         } else {
97             ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
98                      "Widget installation or update not allowed!");
99         }
100     }
101
102   public:
103     InstallerTaskFail(bool deferred) :
104         DPL::TaskDecl<InstallerTaskFail>(this),
105         m_deferred(deferred)
106     {
107         AddStep(&InstallerTaskFail::StepFail);
108     }
109 };
110
111 const std::string XML_EXTENSION = ".xml";
112
113 bool hasExtension(const std::string& filename, const std::string& extension) {
114     LogDebug("Looking for extension " << extension << " in: "  << filename);
115     size_t fileLen = filename.length();
116     size_t extLen = extension.length();
117     if (fileLen < extLen) {
118         LogError("Filename " << filename << " is shorter than extension "
119                  << extension);
120         return false;
121     }
122     return (0 == filename.compare(fileLen-extLen, extLen, extension));
123 }
124 } // namespace anonymous
125
126 namespace Jobs {
127 namespace WidgetInstall {
128 JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath,
129         const WidgetInstallationStruct &installerStruct) :
130     Job(Installation),
131     JobContextBase<WidgetInstallationStruct>(installerStruct),
132     m_exceptionCaught(Exceptions::Success)
133 {
134     // Check installation type (config.xml or widget.wgt)
135     bool browserRequest = hasExtension(widgetPath, XML_EXTENSION);
136
137     LogInfo("Hosted app installation: " << browserRequest);
138
139     struct timeval tv;
140     gettimeofday(&tv, NULL);
141     srand(time(NULL) + tv.tv_usec);
142     WrtDB::DbWidgetHandle handle;
143     do {
144         handle = rand() % INT_MAX + 1;
145         LogInfo("Random widget handle: " << handle);
146     } while (WidgetDAOReadOnly::isWidgetInstalled(handle));
147
148     m_installerContext.widgetHandle = handle;
149     m_installerContext.m_quiet = m_jobStruct.m_quiet;
150
151     if(!browserRequest)
152     {
153         m_installerContext.widgetConfig.pType = checkPackageType(widgetPath);
154     }
155     else
156     {
157         m_installerContext.widgetConfig.pType = WrtDB::PKG_TYPE_TIZEN_WEBAPP;
158     }
159     LogDebug("widgetPath:" << widgetPath);
160
161     ConfigParserData configData = getWidgetDataFromXML(widgetPath, browserRequest,
162             m_installerContext.widgetConfig.pType);
163     WidgetUpdateInfo update = detectWidgetUpdate(configData);
164
165     bool needEncryption = detectResourceEncryption(configData);
166
167
168     // Configure installation
169     ConfigureResult result = ConfigureInstallation(widgetPath, update);
170     if (!setTizenId(configData)) {
171         result = ConfigureResult::Failed;
172     } else {
173         using namespace PackageManager;
174         LogInfo("WidgetHandle: " << m_installerContext.widgetHandle);
175         LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname);
176
177         configureWidgetLocation(widgetPath, browserRequest);
178
179         // send start signal of pkgmgr
180         PkgmgrSignalSingleton::Instance().setPkgname(
181                     DPL::ToUTF8String(
182                         *m_installerContext.widgetConfig.pkgname));
183         PkgmgrSignalSingleton::Instance().sendSignal(
184                     PKGMGR_START_KEY,
185                     PKGMGR_START_INSTALL);
186     }
187     if (result == ConfigureResult::Ok) {
188         LogInfo("Configure installation succeeded");
189
190         AddTask(new TaskRecovery(m_installerContext));
191
192         // Create installation tasks
193         if (!m_installerContext.locations->browserRequest()) {
194             AddTask(new TaskUnzip(m_installerContext));
195         }
196         AddTask(new TaskWidgetConfig(m_installerContext));
197         if (m_installerContext.locations->browserRequest()) {
198             AddTask(new TaskPrepareFiles(m_installerContext));
199         }
200         AddTask(new TaskCertify(m_installerContext));
201         if (needEncryption) {
202             AddTask(new TaskEncryptResource(m_installerContext));
203         }
204         AddTask(new TaskDbUpdate(m_installerContext));
205         AddTask(new TaskFileManipulation(m_installerContext));
206         // TODO: Update progress information for this task
207
208         AddTask(new TaskPrivateStorage(m_installerContext));
209         AddTask(new TaskAceCheck(m_installerContext));
210         //This is sort of quick solution, because ACE verdicts are based upon
211         //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
212         //task.
213         AddTask(new TaskSmack(m_installerContext));
214
215         AddTask(new TaskManifestFile(m_installerContext));
216         if (m_installerContext.widgetConfig.pType ==
217                 PKG_TYPE_TIZEN_WITHSVCAPP) {
218             AddTask(new TaskInstallOspsvc(m_installerContext));
219         }
220     } else if (result == ConfigureResult::Updated) {
221         LogInfo("Configure installation updated");
222         LogInfo("Widget Update");
223
224         if (!m_installerContext.locations->browserRequest()) {
225             AddTask(new TaskUnzip(m_installerContext));
226         }
227         AddTask(new TaskWidgetConfig(m_installerContext));
228         if (m_installerContext.locations->browserRequest()) {
229             AddTask(new TaskPrepareFiles(m_installerContext));
230         }
231
232         AddTask(new TaskCertify(m_installerContext));
233         AddTask(new TaskUpdateFiles(m_installerContext));
234         AddTask(new TaskNewDbInsert(m_installerContext));
235
236         /* TODO : To backup file, save md5 values */
237         AddTask(new TaskAceCheck(m_installerContext));
238         AddTask(new TaskSmack(m_installerContext));
239
240         AddTask(new TaskManifestFile(m_installerContext));
241         AddTask(new TaskRemoveBackupFiles(m_installerContext));
242         if (m_installerContext.widgetConfig.pType ==
243                 PKG_TYPE_TIZEN_WITHSVCAPP) {
244             AddTask(new TaskInstallOspsvc(m_installerContext));
245         }
246     } else if (result == ConfigureResult::Deferred) {
247         // Installation is deferred
248         LogInfo("Configure installation deferred");
249
250         AddTask(new InstallerTaskFail(true));
251     } else if (result == ConfigureResult::Failed) {
252         // Installation is not allowed to proceed due to widget update policy
253         LogWarning("Configure installation failed!");
254
255         AddTask(new InstallerTaskFail(false));
256     } else {
257         Assert(false && "Invalid configure result!");
258     }
259 }
260
261 bool JobWidgetInstall::setTizenId(
262         const WrtDB::ConfigParserData &configInfo)
263 {
264     Assert(!!m_installerContext.widgetHandle
265            && "Widget Handle should be initialized");
266
267     regex_t reg;
268     regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB);
269     struct stat dirStat;
270     if(!!configInfo.tizenId) {
271         LogDebug("Setting tizenId provided in config.xml");
272         if ((regexec(&reg, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(),
273              static_cast<size_t>(0), NULL, 0) != 0) ||
274             (DPL::ToUTF8String(*(configInfo.tizenId)).size() > MAX_TIZENID_LENTH) ||
275             (stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/"
276                    + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0))
277         {
278             //it is true when tizenId does not fit REG_TIZENID_PATTERN
279             LogError("pkgName provided but not proper.");
280             regfree(&reg);
281             return false;
282         }
283         m_installerContext.widgetConfig.pkgname = configInfo.tizenId;
284
285     } else {
286         LogInfo("package name is generated by WRT");
287         // tizen id should be generated by secure random algorithm
288         std::string pkgName = WrtDB::GlobalConfig::GetPkgnamePrefix();
289
290         bool named = false;
291         FOREACH(it, configInfo.localizedDataSet)
292         {
293             if (!!((it->second).name)) {
294                 //there is a name provided
295                 std::string name =  DPL::ToUTF8String(*(it->second).name);
296                 //cut very long widget's name
297                 name = name.substr(0, MAX_TIZENID_LENTH - strlen(
298                     WrtDB::GlobalConfig::GetPkgnamePrefix()));
299                 //check name if all characters are supported by filesystem
300                 if (regexec(&reg, name.c_str(), static_cast<size_t>(0), NULL, 0)
301                     == 0)
302                 {
303                     //WidgetName is ok and can be used as package name
304                     //replace all spaces with '_'
305                     size_t pos = 0;
306                     while((pos = name.find(" ", pos)) != std::string::npos) {
307                         name.replace(pos, 1, "_");
308                         ++pos;
309                     }
310                     pkgName += name;
311                     named = true;
312                 }
313                 break;
314             }
315         }
316
317         if (!named) // there is no widget name provided, use widgetHandle
318         {
319             pkgName += std::to_string(*(m_installerContext.widgetHandle));
320         }
321
322         //check if there is package with same name and if generate different name
323         std::string path = GlobalConfig::GetUserInstalledWidgetPath();
324         path += "/";
325
326         std::ostringstream newPath;
327         newPath << path << pkgName;
328
329         std::string suffix;
330         for (int i = 0;; ++i) {
331             if (stat(newPath.str().c_str(), &dirStat) == 0) {
332                 //path exist, chose another one, eg. widgetName1
333                 suffix = std::to_string(i + 1);
334                 pkgName = pkgName.substr(
335                         0, MAX_TIZENID_LENTH - suffix.size());
336                 newPath.str("");
337                 newPath << path << pkgName << suffix;
338                 continue;
339             }
340             pkgName += suffix;
341             break;
342         }
343
344         m_installerContext.widgetConfig.pkgname =
345             DPL::FromUTF8String(pkgName);
346
347     }
348     regfree(&reg);
349
350     LogInfo("Tizen Id : " << m_installerContext.widgetConfig.pkgname);
351     LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
352     return true;
353 }
354
355 DPL::Optional<WidgetHandle> JobWidgetInstall::getNewWidgetHandle() const
356 {
357     return m_installerContext.widgetHandle;
358 }
359
360 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, bool browserRequest)
361 {
362     Try
363     {
364         m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
365                     widgetPath, browserRequest, m_installerContext.widgetConfig.pType);
366     }
367     Catch(FileUtils::CreateDirectoryException)
368     {
369         LogError("Failed to create temporary path for widget");
370         ReThrowMsg(FileUtils::CreateDirectoryException, "Failed to create temporary path for widget");
371     }
372
373     LogInfo("widgetSource " << widgetPath);
374 }
375
376 JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
377         const std::string &widgetSource,
378         const WidgetUpdateInfo &update)
379 {
380     LogInfo(
381         "Widget install/update: incoming guid = '" <<
382         update.incomingGUID << "'");
383     LogInfo(
384         "Widget install/update: incoming version = '" <<
385         update.incomingVersion << "'");
386
387     // Check policy
388     WidgetUpdateMode::Type updateTypeCheckBit;
389
390     if (update.existingWidgetInfo.isExist == false) {
391         LogInfo("Widget info does not exist");
392         updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
393     } else {
394         LogInfo("Widget info exists. Handle: " <<
395                 update.existingWidgetInfo.existingHandle);
396
397         DPL::OptionalString pkgname =
398             WidgetDAOReadOnly(update.existingWidgetInfo.existingHandle).getPkgname();
399
400         if(pkgname.IsNull()) {
401             LogInfo("But package name doesn't exist");
402             return ConfigureResult::Failed;
403         }
404
405         LogInfo("Widget model exists. package name: " << pkgname);
406         if (aul_app_is_running(DPL::ToUTF8String(*pkgname).c_str())) {
407             // Must be deferred when update in progress
408             if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
409                 LogInfo(
410                     "Widget is already running. Policy is update according to WAC");
411
412                 return ConfigureResult::Deferred;
413             } else {
414                 LogInfo(
415                     "Widget is already running. Policy is not update according to WAC");
416                 LogInfo("Installation aborted: " << widgetSource);
417
418                 return ConfigureResult::Failed;
419             }
420         }
421
422         m_installerContext.widgetConfig.pkgname = pkgname;
423         OptionalWidgetVersion existingVersion;
424         existingVersion = update.existingWidgetInfo.existingVersion;
425         OptionalWidgetVersion incomingVersion = update.incomingVersion;
426
427         updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
428                                                     incomingVersion);
429     }
430
431     // Calc proceed flag
432     bool canProceed = (m_jobStruct.updateMode & updateTypeCheckBit) > 0;
433
434     LogInfo("Whether widget policy allow proceed: " << canProceed);
435
436     // Init installer context
437     m_installerContext.installStep = InstallerContext::INSTALL_START;
438     m_installerContext.job = this;
439     m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
440     m_installerContext.widgetConfig.shareHref = std::string();
441
442     if (m_installerContext.existingWidgetInfo.isExist) {
443         return canProceed ? ConfigureResult::Updated : ConfigureResult::Failed;
444     }
445
446     // Return result
447     return canProceed ? ConfigureResult::Ok : ConfigureResult::Failed;
448 }
449
450 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
451         const OptionalWidgetVersion &existingVersion,
452         const OptionalWidgetVersion &incomingVersion) const
453 {
454     // Widget is installed, check versions
455     if (!existingVersion && !incomingVersion) {
456         return WidgetUpdateMode::ExistingVersionEqual;
457     } else if (!existingVersion && !!incomingVersion) {
458         return WidgetUpdateMode::ExistingVersionNewer;
459     } else if (!!existingVersion && !incomingVersion) {
460         return WidgetUpdateMode::ExistingVersionOlder;
461     } else {
462         LogInfo("Existing widget: version = '" << *existingVersion << "'");
463
464         if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
465             return WidgetUpdateMode::BothVersionsNotStd;
466         } else if (!existingVersion->IsWac()) {
467             return WidgetUpdateMode::ExistingVersionNotStd;
468         } else if (!incomingVersion->IsWac()) {
469             return WidgetUpdateMode::IncomingVersionNotStd;
470         } else {
471             // Both versions are WAC-comparable. Do compare.
472             if (*incomingVersion == *existingVersion) {
473                 return WidgetUpdateMode::ExistingVersionEqual;
474             } else if (*incomingVersion > *existingVersion) {
475                 return WidgetUpdateMode::ExistingVersionOlder;
476             } else {
477                 return WidgetUpdateMode::ExistingVersionNewer;
478             }
479         }
480     }
481 }
482
483 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
484         const std::string &widgetSource,
485         bool fromBrowser, WrtDB::PkgType isOspsvc)
486 {
487     Try
488     {
489         // Parse config
490         ParserRunner parser;
491         ConfigParserData configInfo;
492
493         if (fromBrowser) {
494             parser.Parse(widgetSource,
495                          ElementParserPtr(
496                              new RootParser<WidgetParser>(configInfo,
497                                                           DPL::FromUTF32String(
498                                                               L"widget"))));
499         }
500         else {
501             // Open zip file
502             DPL::ScopedPtr<DPL::ZipInput> zipFile(
503                 new DPL::ZipInput(widgetSource));
504
505             DPL::ScopedPtr<DPL::ZipInput::File> configFile;
506
507             // Open config.xml file
508             if (isOspsvc == PKG_TYPE_TIZEN_WITHSVCAPP) {
509                 configFile.Reset(zipFile->OpenFile(WITH_OSP_XML));
510             } else {
511                 configFile.Reset(zipFile->OpenFile(CONFIG_XML));
512             }
513
514             // Extract config
515             DPL::BinaryQueue buffer;
516             DPL::AbstractWaitableInputAdapter inputAdapter(configFile.Get());
517             DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
518             DPL::Copy(&inputAdapter, &outputAdapter);
519             parser.Parse(&buffer,
520                          ElementParserPtr(
521                              new RootParser<WidgetParser>(configInfo,
522                                                           DPL::FromUTF32String(
523                                                               L"widget"))));
524         }
525
526         return configInfo;
527     }
528     Catch(DPL::ZipInput::Exception::OpenFailed)
529     {
530         LogDebug("Failed to open widget package");
531         return ConfigParserData();
532     }
533     Catch(DPL::ZipInput::Exception::OpenFileFailed)
534     {
535         LogDebug("Failed to open config.xml file");
536         return ConfigParserData();
537     }
538     Catch(DPL::CopyFailed)
539     {
540         LogDebug("Failed to extract config.xml file");
541         return ConfigParserData();
542     }
543     Catch(ElementParser::Exception::ParseError)
544     {
545         LogDebug("Failed to parse config.xml file");
546         return ConfigParserData();
547     }
548 }
549
550 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
551         const ConfigParserData &configInfo)
552 {
553     LogInfo("Checking up widget package for config.xml...");
554
555     DPL::OptionalString widgetGUID;
556     OptionalWidgetVersion widgetVersion;
557
558     // Check widget id
559     widgetGUID = configInfo.widget_id;
560
561     if (widgetGUID.IsNull()) {
562         LogDebug("Installed widget has no GUID");
563         return WidgetUpdateInfo();
564     }
565
566     LogDebug("Installed widget GUID: " << *widgetGUID);
567
568     // Locate widget ID with this GUID
569     // Incoming widget version
570     if (!configInfo.version.IsNull()) {
571         widgetVersion =
572             DPL::Optional<WidgetVersion>(
573                 WidgetVersion(*configInfo.version));
574     }
575
576     Try
577     {
578         // Search widget handle by GUID
579         WidgetDAOReadOnly dao(widgetGUID);
580         return WidgetUpdateInfo(
581             widgetGUID,
582             widgetVersion,
583             WidgetUpdateInfo::ExistingWidgetInfo(
584                 dao.getHandle(), dao.getVersion()));
585     }
586     Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
587     {
588         // GUID isn't installed
589         return WidgetUpdateInfo(
590             widgetGUID,
591             widgetVersion,
592             WidgetUpdateInfo::ExistingWidgetInfo());
593     }
594 }
595
596 void JobWidgetInstall::SendProgress()
597 {
598     using namespace PackageManager;
599     if (GetProgressFlag() != false) {
600         if (getInstallerStruct().progressCallback != NULL) {
601             // send progress signal of pkgmgr
602             std::ostringstream percent;
603             percent << static_cast<int>(GetProgressPercent());
604             PkgmgrSignalSingleton::Instance().sendSignal(
605                         PKGMGR_PROGRESS_KEY,
606                         percent.str());
607
608             LogDebug("Call widget install progressCallbak");
609             getInstallerStruct().progressCallback(getInstallerStruct().userParam,
610                     GetProgressPercent(),GetProgressDescription());
611         }
612     }
613 }
614
615 void JobWidgetInstall::SendFinishedSuccess()
616 {
617     using namespace PackageManager;
618     // TODO : sync should move to separate task.
619     sync();
620
621     // remove widget install information file
622     unlink(m_installerContext.installInfo.c_str());
623
624     //inform widget info
625     JobWidgetInstall::displayWidgetInfo();
626
627     DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
628
629     // send signal of pkgmgr
630     PkgmgrSignalSingleton::Instance().sendSignal(
631                 PKGMGR_END_KEY,
632                 PKGMGR_END_SUCCESS);
633
634     LogDebug("Call widget install successfinishedCallback");
635     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
636             !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, Exceptions::Success);
637 }
638
639 void JobWidgetInstall::SendFinishedFailure()
640 {
641     using namespace PackageManager;
642     // remove widget install information file
643     unlink(m_installerContext.installInfo.c_str());
644
645     LogError("Error in installation step: " << m_exceptionCaught);
646     LogError("Message: " << m_exceptionMessage);
647     DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
648
649     LogDebug("Call widget install failure finishedCallback");
650
651     // send signal of pkgmgr
652     PkgmgrSignalSingleton::Instance().sendSignal(
653                 PKGMGR_END_KEY,
654                 PKGMGR_END_FAILURE);
655
656     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
657             !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, m_exceptionCaught);
658 }
659
660 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
661 {
662     m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
663     m_exceptionMessage = e.GetMessage();
664 }
665
666 void JobWidgetInstall::displayWidgetInfo()
667 {
668     DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
669     Assert(!!handle);
670
671     WidgetDAOReadOnly dao(*handle);
672
673     std::ostringstream out;
674     WidgetLocalizedInfo localizedInfo =
675         W3CFileLocalization::getLocalizedInfo(*handle);
676
677     out << std::endl <<
678         "===================================== INSTALLED WIDGET INFO ========="\
679         "============================";
680     out << std::endl << "Name:                        " << localizedInfo.name;
681     out << std::endl << "PkgName:                     " << dao.getPkgname();
682     WidgetSize size = dao.getPreferredSize();
683     out << std::endl << "Width:                       " << size.width;
684     out << std::endl << "Height:                      " << size.height;
685     out << std::endl << "Start File:                  " <<
686         W3CFileLocalization::getStartFile(*handle);
687     out << std::endl << "Version:                     " << dao.getVersion();
688     out << std::endl << "Licence:                     " <<
689         localizedInfo.license;
690     out << std::endl << "Licence Href:                " <<
691         localizedInfo.licenseHref;
692     out << std::endl << "Description:                 " <<
693         localizedInfo.description;
694     out << std::endl << "Widget Id:                   " << dao.getGUID();
695     out << std::endl << "Widget recognized:           " << dao.isRecognized();
696     out << std::endl << "Widget wac signed:           " << dao.isWacSigned();
697     out << std::endl << "Widget distributor signed:   " <<
698         dao.isDistributorSigned();
699     out << std::endl << "Widget trusted:              " << dao.isTrusted();
700
701     OptionalWidgetIcon icon = W3CFileLocalization::getIcon(*handle);
702     DPL::OptionalString iconSrc =
703         !!icon ? icon->src : DPL::OptionalString::Null;
704     out << std::endl << "Icon:                        " << iconSrc;
705
706     out << std::endl << "Preferences:";
707     {
708         PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
709         FOREACH(it, list)
710         {
711             out << std::endl << "  Key:                       " <<
712                 it->key_name;
713             out << std::endl << "      Readonly:              " <<
714                 it->readonly;
715         }
716     }
717
718     out << std::endl << "Features:";
719     {
720         WidgetFeatureSet list = dao.getFeaturesList();
721         FOREACH(it, list)
722         {
723             out << std::endl << "  Name:                      " << it->name;
724             out << std::endl << "      Required:              " << it->required;
725             out << std::endl << "      Params:";
726         }
727     }
728
729     out << std::endl;
730
731     LogInfo(out.str());
732 }
733
734 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
735         const std::string &widgetSource)
736 {
737     using namespace WrtDB;
738
739     PackagingType pType = PKG_TYPE_UNKNOWN;
740     DPL::ScopedPtr<DPL::ZipInput> zipFile;
741
742     Try
743     {
744         // Open zip file
745         zipFile.Reset(new DPL::ZipInput(widgetSource));
746
747     }
748     Catch(DPL::ZipInput::Exception::OpenFailed)
749     {
750         LogDebug("Failed to open widget package");
751         return PKG_TYPE_UNKNOWN;
752     }
753
754     Try
755     {
756         // Open config.xml file in package root
757         DPL::ScopedPtr<DPL::ZipInput::File> configFile(
758                 zipFile->OpenFile(CONFIG_XML));
759         pType = PKG_TYPE_TIZEN_WEBAPP;
760     }
761     Catch(DPL::ZipInput::Exception::OpenFileFailed)
762     {
763         LogDebug("Could not find config.xml");
764     }
765
766     Try
767     {
768         // Open config.xml file in package root
769         DPL::ScopedPtr<DPL::ZipInput::File> configFile(
770                 zipFile->OpenFile(WITH_OSP_XML));
771         if (pType == PKG_TYPE_TIZEN_WEBAPP) {
772             return PKG_TYPE_UNKNOWN;
773         }
774
775         pType = PKG_TYPE_TIZEN_WITHSVCAPP;
776     }
777     Catch(DPL::ZipInput::Exception::OpenFileFailed)
778     {
779         LogDebug("Could not find wgt/config.xml");
780         return PKG_TYPE_UNKNOWN;
781     }
782
783     return pType;
784 }
785
786 bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
787 {
788     FOREACH(it, configData.settingsList)
789     {
790         if (it->m_name == SETTING_VALUE_ENCRYPTION &&
791                 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
792             LogDebug("resource need encryption");
793             return true;
794         }
795     }
796     return false;
797 }
798
799 } //namespace WidgetInstall
800 } //namespace Jobs