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