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