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