[Release] wrt-installer_0.1.114
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_widget_config.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file    task_widget_config.cpp
18  * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task widget config
21  */
22
23 #include <map>
24 #include <sstream>
25 #include <string>
26 #include <sys/stat.h>
27 #include <dirent.h>
28
29 #include <dpl/errno_string.h>
30 #include <dpl/foreach.h>
31 #include <dpl/localization/w3c_file_localization.h>
32 #include <dpl/singleton_impl.h>
33 #include <dpl/utils/mime_type_utils.h>
34 #include <dpl/utils/wrt_global_settings.h>
35 #include <dpl/utils/wrt_utility.h>
36 #include <dpl/wrt-dao-ro/global_config.h>
37 #include <dpl/wrt-dao-ro/config_parser_data.h>
38 #include <dpl/wrt-dao-rw/feature_dao.h>
39
40 #include <libiriwrapper.h>
41 #include <parser_runner.h>
42 #include <root_parser.h>
43
44 #include <widget_install/job_widget_install.h>
45 #include <widget_install/task_widget_config.h>
46 #include <widget_install/widget_install_context.h>
47 #include <widget_install/widget_install_errors.h>
48 #include <widget_parser.h>
49 #include <web_provider_plugin_info.h>
50 #include <web_provider_livebox_info.h>
51 #include <manifest.h>
52
53 namespace { // anonymous
54 const DPL::String BR = DPL::FromUTF8String("<br>");
55 const std::string WIDGET_NOT_COMPATIBLE = "This widget is "
56                                           "not compatible with WRT.<br><br>";
57 const std::string QUESTION = "Do you want to install it anyway?";
58
59 const char *const DEFAULT_LANGUAGE = "default";
60
61 const char *const WRT_WIDGET_CONFIG_FILE_NAME = "config.xml";
62
63 const std::string WINDGET_INSTALL_NETWORK_ACCESS = "network access";
64
65 const char WRT_WIDGETS_XML_SCHEMA[] = "/usr/etc/wrt-installer/widgets.xsd";
66 }
67
68 namespace Jobs {
69 namespace WidgetInstall {
70
71 TaskWidgetConfig::TaskWidgetConfig(InstallerContext& installContext) :
72     DPL::TaskDecl<TaskWidgetConfig>(this),
73     m_installContext(installContext)
74 {
75     AddStep(&TaskWidgetConfig::StartStep);
76     AddStep(&TaskWidgetConfig::StepProcessConfigurationFile);
77     AddStep(&TaskWidgetConfig::ReadLocaleFolders);
78     AddStep(&TaskWidgetConfig::ProcessLocalizedStartFiles);
79     AddStep(&TaskWidgetConfig::ProcessBackgroundPageFile);
80     AddStep(&TaskWidgetConfig::ProcessLocalizedIcons);
81     AddStep(&TaskWidgetConfig::ProcessWidgetInstalledPath);
82     AddStep(&TaskWidgetConfig::ProcessAppControlInfo);
83     AddStep(&TaskWidgetConfig::ProcessSecurityModel);
84     AddStep(&TaskWidgetConfig::StepVerifyFeatures);
85     AddStep(&TaskWidgetConfig::StepCheckMinVersionInfo);
86     AddStep(&TaskWidgetConfig::EndStep);
87 }
88
89 void TaskWidgetConfig::StepProcessConfigurationFile()
90 {
91     Try
92     {
93         std::string path = m_installContext.locations->getConfigurationDir();
94         LogDebug("path: " << path);
95
96         processFile(path, m_installContext.widgetConfig);
97     }
98     Catch(Exception::ConfigParseFailed)
99     {
100         LogError("Parsing failed.");
101         ReThrow(Exceptions::WidgetConfigFileInvalid);
102     }
103
104     m_installContext.job->UpdateProgress(
105         InstallerContext::INSTALL_WIDGET_CONFIG1,
106         "Parse elements of configuration file and save them");
107 }
108
109 void TaskWidgetConfig::ReadLocaleFolders()
110 {
111     LogDebug("Reading locale");
112     //Adding default locale
113     m_localeFolders.insert(L"");
114
115     std::string localePath =
116         m_installContext.locations->getConfigurationDir() + "/locales";
117     DIR* localeDir = opendir(localePath.c_str());
118     if (!localeDir) {
119         LogDebug("No /locales directory in the widget package.");
120         return;
121     }
122
123     struct stat statStruct;
124     struct dirent dirent;
125     struct dirent *result;
126     int return_code;
127     errno = 0;
128     for (return_code = readdir_r(localeDir, &dirent, &result);
129             result != NULL && return_code == 0;
130             return_code = readdir_r(localeDir, &dirent, &result))
131     {
132         DPL::String dirName = DPL::FromUTF8String(dirent.d_name);
133         std::string absoluteDirName = localePath + "/";
134         absoluteDirName += dirent.d_name;
135
136         if (stat(absoluteDirName.c_str(), &statStruct) != 0) {
137             LogError("stat() failed with " << DPL::GetErrnoString());
138             continue;
139         }
140
141         if (S_ISDIR(statStruct.st_mode)) {
142             //Yes, we ignore current, parent & hidden directories
143             if (dirName[0] != L'.') {
144                 LogDebug("Adding locale directory \"" << dirName << "\"");
145                 m_localeFolders.insert(dirName);
146             }
147         }
148     }
149
150     if (return_code != 0 || errno != 0) {
151         LogError("readdir_r() failed with " << DPL::GetErrnoString());
152     }
153
154     if (-1 == TEMP_FAILURE_RETRY(closedir(localeDir))) {
155         LogError("Failed to close dir: " << localePath << " with error: "
156                                          << DPL::GetErrnoString());
157     }
158 }
159
160 void TaskWidgetConfig::ProcessLocalizedStartFiles()
161 {
162     typedef DPL::String S;
163     ProcessStartFile(
164         m_installContext.widgetConfig.configInfo.startFile,
165         m_installContext.widgetConfig.configInfo.
166             startFileContentType,
167         m_installContext.widgetConfig.configInfo.startFileEncoding,
168         true);
169     ProcessStartFile(S(L"index.htm"), S(L"text/html"));
170     ProcessStartFile(S(L"index.html"), S(L"text/html"));
171     ProcessStartFile(S(L"index.svg"), S(L"image/svg+xml"));
172     ProcessStartFile(S(L"index.xhtml"), S(L"application/xhtml+xml"));
173     ProcessStartFile(S(L"index.xht"), S(L"application/xhtml+xml"));
174     // TODO: we need better check if in current locales widget is valid
175     FOREACH(it, m_installContext.widgetConfig.localizationData.startFiles) {
176         if (it->propertiesForLocales.size() > 0) {
177             return;
178         }
179     }
180     ThrowMsg(Exceptions::InvalidStartFile,
181              "The Widget has no valid start file");
182 }
183
184 void TaskWidgetConfig::ProcessStartFile(const DPL::OptionalString& path,
185                                         const DPL::OptionalString& type,
186                                         const DPL::OptionalString& encoding,
187                                         bool typeForcedInConfig)
188 {
189     using namespace WrtDB;
190
191     if (!!path) {
192         WidgetRegisterInfo::LocalizedStartFile startFileData;
193         startFileData.path = *path;
194
195         FOREACH(i, m_localeFolders) {
196             DPL::String pathPrefix = *i;
197             if (!pathPrefix.empty()) {
198                 pathPrefix = L"locales/" + pathPrefix + L"/";
199             }
200
201             DPL::String relativePath = pathPrefix + *path;
202             DPL::String absolutePath = DPL::FromUTF8String(
203                     m_installContext.locations->getConfigurationDir()) + L"/" +
204                 relativePath;
205
206             // get property data from packaged app
207             if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
208                 WidgetRegisterInfo::StartFileProperties startFileProperties;
209                 if (!!type) {
210                     startFileProperties.type = *type;
211                 } else {
212                     startFileProperties.type =
213                         MimeTypeUtils::identifyFileMimeType(absolutePath);
214                 }
215
216                 //proceed only if MIME type is supported
217                 if (MimeTypeUtils::isMimeTypeSupportedForStartFile(
218                         startFileProperties.type))
219                 {
220                     if (!!encoding) {
221                         startFileProperties.encoding = *encoding;
222                     } else {
223                         MimeTypeUtils::MimeAttributes attributes =
224                             MimeTypeUtils::getMimeAttributes(
225                                 startFileProperties.type);
226                         if (attributes.count(L"charset") > 0) {
227                             startFileProperties.encoding =
228                                 attributes[L"charset"];
229                         } else {
230                             startFileProperties.encoding = L"UTF-8";
231                         }
232                     }
233
234                     startFileData.propertiesForLocales[*i] =
235                         startFileProperties;
236                 } else {
237                     //9.1.16.5.content.8
238                     //(there seems to be no similar requirement in .6,
239                     //so let's throw only when mime type is
240                     // provided explcitly in config.xml)
241                     if (typeForcedInConfig) {
242                         ThrowMsg(Exceptions::WidgetConfigFileInvalid,
243                                  "Unsupported MIME type for start file.");
244                     }
245                 }
246             } else {
247                 // set property data for hosted start url
248                 // Hosted start url only support TIZEN WebApp
249                 if (m_installContext.widgetConfig.webAppType ==
250                     APP_TYPE_TIZENWEBAPP)
251                 {
252                     std::string startPath = DPL::ToUTF8String(
253                             startFileData.path);
254
255                     if (strstr(startPath.c_str(),
256                                "http") == startPath.c_str())
257                     {
258                         WidgetRegisterInfo::StartFileProperties
259                             startFileProperties;
260                         if (!!type) {
261                             startFileProperties.type = *type;
262                         }
263                         if (!!encoding) {
264                             startFileProperties.encoding = *encoding;
265                         }
266                         startFileData.propertiesForLocales[*i] =
267                             startFileProperties;
268                     }
269                 }
270             }
271         }
272
273         m_installContext.widgetConfig.localizationData.startFiles.push_back(
274             startFileData);
275     }
276 }
277
278 void TaskWidgetConfig::ProcessBackgroundPageFile()
279 {
280     if (!!m_installContext.widgetConfig.configInfo.backgroundPage) {
281         // check whether file exists
282         DPL::String backgroundPagePath = DPL::FromUTF8String(
283                 m_installContext.locations->getConfigurationDir()) + L"/" +
284             *m_installContext.widgetConfig.configInfo.backgroundPage;
285         //if no then cancel installation
286         if (!WrtUtilFileExists(DPL::ToUTF8String(backgroundPagePath))) {
287             ThrowMsg(Exceptions::WidgetConfigFileInvalid,
288                      L"Given background page file not found in archive");
289         }
290     }
291 }
292
293 void TaskWidgetConfig::ProcessLocalizedIcons()
294 {
295     using namespace WrtDB;
296         FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList)
297     {
298         ProcessIcon(*i);
299     }
300     ProcessIcon(ConfigParserData::Icon(L"icon.svg"));
301     ProcessIcon(ConfigParserData::Icon(L"icon.ico"));
302     ProcessIcon(ConfigParserData::Icon(L"icon.png"));
303     ProcessIcon(ConfigParserData::Icon(L"icon.gif"));
304     ProcessIcon(ConfigParserData::Icon(L"icon.jpg"));
305 }
306
307 void TaskWidgetConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon)
308 {
309     LogDebug("enter");
310     bool isAnyIconValid = false;
311     //In case a default filename is passed as custom filename in config.xml, we
312     //need to keep a set of already processed filenames to avoid icon
313     // duplication
314     //in database.
315
316     using namespace WrtDB;
317
318     if (m_processedIconSet.count(icon.src) > 0) {
319         return;
320     }
321     m_processedIconSet.insert(icon.src);
322
323     LocaleSet localesAvailableForIcon;
324
325     FOREACH(i, m_localeFolders)
326     {
327         DPL::String pathPrefix = *i;
328         if (!pathPrefix.empty()) {
329             pathPrefix = L"locales/" + pathPrefix + L"/";
330         }
331
332         DPL::String relativePath = pathPrefix + icon.src;
333         DPL::String absolutePath = DPL::FromUTF8String(
334                 m_installContext.locations->getConfigurationDir()) + L"/" +
335             relativePath;
336
337         if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
338             DPL::String type = MimeTypeUtils::identifyFileMimeType(absolutePath);
339
340             if (MimeTypeUtils::isMimeTypeSupportedForIcon(type)) {
341                 isAnyIconValid = true;
342                 localesAvailableForIcon.insert(*i);
343                 LogDebug("Icon absolutePath :" << absolutePath <<
344                         ", assigned locale :" << *i << ", type: " << type);
345             }
346         }
347     }
348
349     if (isAnyIconValid) {
350         WidgetRegisterInfo::LocalizedIcon localizedIcon(icon,
351                                                         localesAvailableForIcon);
352         m_installContext.widgetConfig.localizationData.icons.push_back(
353             localizedIcon);
354     }
355 }
356
357 void TaskWidgetConfig::ProcessWidgetInstalledPath()
358 {
359     LogDebug("ProcessWidgetInstalledPath");
360     m_installContext.widgetConfig.widgetInstalledPath =
361         DPL::FromUTF8String(
362             m_installContext.locations->getPackageInstallationDir());
363 }
364
365 void TaskWidgetConfig::ProcessAppControlInfo()
366 {
367     LogDebug("ProcessAppControlInfo");
368     using namespace WrtDB;
369
370     WrtDB::ConfigParserData::AppControlInfo::Disposition disposition =
371         WrtDB::ConfigParserData::AppControlInfo::Disposition::WINDOW;
372     FOREACH(it, m_installContext.widgetConfig.configInfo.settingsList) {
373         if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), "nodisplay") &&
374             !strcmp(DPL::ToUTF8String(it->m_value).c_str(), "true"))
375         {
376             disposition =
377                 WrtDB::ConfigParserData::AppControlInfo::Disposition::INLINE;
378         }
379     }
380
381     std::map<std::string, int> srcMap;
382     int index = 0;
383     // index = 0 is reserved for start file
384     FOREACH(startFileIt, m_installContext.widgetConfig.localizationData.startFiles)
385     {
386         if (!startFileIt->propertiesForLocales.empty()) {
387             std::string src = DPL::ToUTF8String(startFileIt->path);
388              if (srcMap.find(src) == srcMap.end()) {
389                 LogDebug("Insert [" << src << "," << index << "]");
390                 srcMap.insert(std::pair<std::string, int>(src, index++));
391             }
392         }
393     }
394
395     FOREACH(appControlIt, m_installContext.widgetConfig.configInfo.appControlList)
396     {
397         appControlIt->m_disposition = disposition;
398         std::string src = DPL::ToUTF8String(appControlIt->m_src);
399         LogDebug("src = [" << src << "]");
400         std::map<std::string, int>::iterator findIt = srcMap.find(src);
401         if (findIt == srcMap.end()) {
402             LogDebug("Insert [" << src << "," << index << "]");
403             srcMap.insert(std::pair<std::string, int>(src, index));
404             appControlIt->m_index = index++;
405         } else {
406             LogDebug("Exist  [" << src << "," << findIt->second << "]");
407             appControlIt->m_index = findIt->second;
408         }
409     }
410 }
411
412 void TaskWidgetConfig::ProcessSecurityModel()
413 {
414     // 0104.  If the "required_version" specified in the Web Application's
415     // configuration is 2.2 or higher and if the Web Application's
416     // configuration is "CSP-compatible configuration", then the WRT MUST be
417     // set to "CSP-based security mode". Otherwise, the WRT MUST be set to
418     // "WARP-based security mode".
419     // 0105.  A Web Application configuration is "CSP-compatible configuration"
420     // if the configuration includes one or more of
421     // <tizen:content-security-policy> /
422     // <tizen:content-security-policy-report-only> /
423     // <tizen:allow-navigation> elements.
424
425     bool isSecurityModelV1 = false;
426     bool isSecurityModelV2 = false;
427     WrtDB::ConfigParserData &data = m_installContext.widgetConfig.configInfo;
428
429     if (!data.cspPolicy.IsNull() ||
430         !data.cspPolicyReportOnly.IsNull() ||
431         !data.allowNavigationInfoList.empty())
432     {
433         data.accessInfoSet.clear();
434     }
435
436     // WARP is V1
437     if (!data.accessInfoSet.empty()) {
438         isSecurityModelV1 = true;
439     }
440
441     // CSP & allow-navigation is V2
442     if (!data.cspPolicy.IsNull() ||
443         !data.cspPolicyReportOnly.IsNull() ||
444         !data.allowNavigationInfoList.empty())
445     {
446         isSecurityModelV2 = true;
447     }
448
449     if (isSecurityModelV1 && isSecurityModelV2) {
450         LogError("Security model is conflict");
451         ThrowMsg(Exceptions::NotAllowed, "Security model is conflict");
452     } else if (isSecurityModelV1) {
453         data.securityModelVersion =
454             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
455     } else if (isSecurityModelV2) {
456         data.securityModelVersion =
457             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V2;
458     } else {
459         data.securityModelVersion =
460             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
461     }
462
463     m_installContext.job->UpdateProgress(
464         InstallerContext::INSTALL_WIDGET_CONFIG2,
465         "Finished process security model");
466 }
467
468 void TaskWidgetConfig::StepCheckMinVersionInfo()
469 {
470     if (!isMinVersionCompatible(
471             m_installContext.widgetConfig.webAppType.appType,
472             m_installContext.widgetConfig.minVersion))
473     {
474         LogError(
475             "Platform version lower than required -> cancelling installation");
476         ThrowMsg(Exceptions::NotAllowed,
477                  "Platform version does not meet requirements");
478     }
479
480     m_installContext.job->UpdateProgress(
481         InstallerContext::INSTALL_WIDGET_CONFIG2,
482         "Check MinVersion Finished");
483 }
484
485 void TaskWidgetConfig::StepVerifyFeatures()
486 {
487     using namespace WrtDB;
488     ConfigParserData &data = m_installContext.widgetConfig.configInfo;
489     ConfigParserData::FeaturesList list = data.featuresList;
490     ConfigParserData::FeaturesList newList;
491
492     //in case of tests, this variable is unused
493     std::string featureInfo;
494     FOREACH(it, list)
495     {
496         // check feature vender for permission
497         // WAC, TIZEN WebApp cannot use other feature
498
499         if (!isFeatureAllowed(m_installContext.widgetConfig.webAppType.appType,
500                               it->name))
501         {
502             LogDebug("This application type not allowed to use this feature");
503             ThrowMsg(
504                 Exceptions::WidgetConfigFileInvalid,
505                 "This app type [" <<
506                 m_installContext.widgetConfig.webAppType.getApptypeToString()
507                                   <<
508                 "] cannot be allowed to use [" <<
509                 DPL::ToUTF8String(it->name) + "] feature");
510         } else {
511             newList.insert(*it);
512             featureInfo += DPL::ToUTF8String(it->name);
513             featureInfo += DPL::ToUTF8String(BR);
514         }
515     }
516     if (!data.accessInfoSet.empty()) {
517         featureInfo += WINDGET_INSTALL_NETWORK_ACCESS;
518         featureInfo += DPL::ToUTF8String(BR);
519     }
520     data.featuresList = newList;
521
522     m_installContext.job->UpdateProgress(
523         InstallerContext::INSTALL_WIDGET_CONFIG2,
524         "Widget Config step2 Finished");
525 }
526
527 void TaskWidgetConfig::StepVerifyLivebox()
528 {
529     using namespace WrtDB;
530     ConfigParserData &data = m_installContext.widgetConfig.configInfo;
531     ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
532
533     if (liveBoxList.size() <= 0) {
534         return;
535     }
536
537     FOREACH (it, liveBoxList) {
538         std::string boxType;
539
540         if ((**it).m_type.empty()) {
541             boxType = web_provider_livebox_get_default_type();
542         } else {
543             boxType = DPL::ToUTF8String((**it).m_type);
544         }
545
546         LogDebug("livebox type: " << boxType);
547
548         ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
549             (**it).m_boxInfo.m_boxSize;
550         char** boxSize = static_cast<char**>(
551             malloc(sizeof(char*)* boxSizeList.size()));
552
553         int boxSizeCnt = 0;
554         FOREACH (m, boxSizeList) {
555             boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str());
556         }
557
558         bool chkSize = web_provider_plugin_check_supported_size(
559             boxType.c_str(), boxSize, boxSizeCnt);
560
561         for(int i = 0; i < boxSizeCnt; i++) {
562             free(boxSize[i]);
563         }
564         free(boxSize);
565
566         if(!chkSize) {
567             LogError("Invalid boxSize");
568             ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid boxSize");
569         }
570     }
571 }
572
573 bool TaskWidgetConfig::isFeatureAllowed(WrtDB::AppType appType,
574                                         DPL::String featureName)
575 {
576     using namespace WrtDB;
577     LogDebug("AppType = [" <<
578             WidgetType(appType).getApptypeToString() << "]");
579     LogDebug("FetureName = [" << featureName << "]");
580
581     AppType featureType = APP_TYPE_UNKNOWN;
582     std::string featureStr = DPL::ToUTF8String(featureName);
583     const char* feature = featureStr.c_str();
584
585     // check prefix of  feature name
586     if (strstr(feature, PluginsPrefix::TIZENPluginsPrefix) == feature) {
587         // Tizen WebApp feature
588         featureType = APP_TYPE_TIZENWEBAPP;
589     } else if (strstr(feature, PluginsPrefix::W3CPluginsPrefix) == feature) {
590         // W3C standard feature
591         // Both WAC and TIZEN WebApp are possible to use W3C plugins
592         return true;
593     } else {
594         // unknown feature
595         // unknown feature will be checked next step
596         return true;
597     }
598
599     if (appType == featureType) {
600         return true;
601     }
602     return false;
603 }
604
605 bool TaskWidgetConfig::parseVersionString(const std::string &version,
606                                           long &majorVersion,
607                                           long &minorVersion,
608                                           long &microVersion) const
609 {
610     std::istringstream inputString(version);
611     inputString >> majorVersion;
612     if (inputString.bad() || inputString.fail()) {
613         LogWarning("Invalid minVersion format.");
614         return false;
615     }
616     inputString.get(); // skip period
617     inputString >> minorVersion;
618     if (inputString.bad() || inputString.fail()) {
619         LogWarning("Invalid minVersion format");
620         return false;
621     } else {
622         inputString.get(); // skip period
623         if (inputString.bad() || inputString.fail()) {
624             inputString >> microVersion;
625         }
626     }
627     return true;
628 }
629
630 bool TaskWidgetConfig::isMinVersionCompatible(
631     WrtDB::AppType appType,
632     const DPL::OptionalString &
633     widgetVersion) const
634 {
635     if (widgetVersion.IsNull() || (*widgetVersion).empty()) {
636         if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
637             return false;
638         } else {
639             LogWarning("minVersion attribute is empty. WRT assumes platform "
640                     "supports this widget.");
641             return true;
642         }
643     }
644
645     //Parse widget version
646     long majorWidget = 0, minorWidget = 0, microWidget = 0;
647     if (!parseVersionString(DPL::ToUTF8String(*widgetVersion), majorWidget,
648                             minorWidget, microWidget))
649     {
650         LogWarning("Invalid format of widget version string.");
651         return false;
652     }
653
654     //Parse supported version
655     long majorSupported = 0, minorSupported = 0, microSupported = 0;
656     std::string version;
657     if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
658         version = WrtDB::GlobalConfig::GetTizenVersion();
659     } else {
660         LogWarning("Invaild AppType");
661         return false;
662     }
663
664     if (!parseVersionString(version,
665                             majorSupported, minorSupported, microSupported))
666     {
667         LogWarning("Invalid format of platform version string.");
668         return true;
669     }
670
671     if (majorWidget > majorSupported ||
672         (majorWidget == majorSupported && minorWidget > minorSupported) ||
673         (majorWidget == majorSupported && minorWidget == minorSupported
674          && microWidget > microSupported))
675     {
676         LogDebug("Platform doesn't support this widget.");
677         return false;
678     }
679     return true;
680 }
681
682 bool TaskWidgetConfig::isTizenWebApp() const
683 {
684     bool ret = FALSE;
685     if (m_installContext.widgetConfig.webAppType.appType
686         == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
687     {
688         ret = TRUE;
689     }
690
691     return ret;
692 }
693
694 bool TaskWidgetConfig::parseConfigurationFileBrowser(
695     WrtDB::ConfigParserData& configInfo,
696     const std::string& _currentPath)
697 {
698     ParserRunner parser;
699     Try
700     {
701         parser.Parse(_currentPath, ElementParserPtr(new
702                                                     RootParser<
703                                                         WidgetParser>(
704                                                         configInfo,
705                                                         DPL::FromUTF32String(
706                                                             L"widget"))));
707     }
708     Catch(ElementParser::Exception::Base)
709     {
710         LogError("Invalid widget configuration file!");
711         return false;
712     }
713     return true;
714 }
715
716 bool TaskWidgetConfig::parseConfigurationFileWidget(
717     WrtDB::ConfigParserData& configInfo,
718     const std::string& _currentPath)
719 {
720     std::string configFilePath;
721     WrtUtilJoinPaths(configFilePath, _currentPath, WRT_WIDGET_CONFIG_FILE_NAME);
722     if (!WrtUtilFileExists(configFilePath))
723     {
724         LogError("Archive does not contain configuration file");
725         return false;
726     }
727
728     LogDebug("Configuration file: " << configFilePath);
729
730     Try
731     {
732         ParserRunner parser;
733 #ifdef SCHEMA_VALIDATION_ENABLED
734         if(!parser.Validate(configFilePath, WRT_WIDGETS_XML_SCHEMA))
735         {
736             LogError("Invalid configuration file - schema validation failed");
737             return false;
738         }
739 #endif
740         parser.Parse(configFilePath,
741                      ElementParserPtr(new RootParser<WidgetParser>(
742                                           configInfo,
743                                           DPL::FromUTF32String(L"widget"))));
744         return true;
745     }
746     Catch (ElementParser::Exception::Base)
747     {
748         LogError("Invalid configuration file!");
749         return false;
750     }
751 }
752
753 bool TaskWidgetConfig::locateAndParseConfigurationFile(
754     const std::string& _currentPath,
755     WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
756     const std::string& baseFolder)
757 {
758     using namespace WrtDB;
759
760     ConfigParserData& configInfo = pWidgetConfigInfo.configInfo;
761
762     // check if this installation from browser, or not.
763     size_t pos = _currentPath.rfind("/");
764     std::ostringstream infoPath;
765     infoPath << _currentPath.substr(pos + 1);
766
767     if (infoPath.str() != WRT_WIDGET_CONFIG_FILE_NAME) {
768         if (_currentPath.empty() || baseFolder.empty()) {
769             return false;
770         }
771         // in case of general installation using wgt archive
772         if (!parseConfigurationFileWidget(configInfo, _currentPath))
773         {
774             return false;
775         }
776     } else {
777         // in case of browser installation
778         if (!parseConfigurationFileBrowser(configInfo, _currentPath))
779         {
780             return false;
781         }
782     }
783
784     if (!fillWidgetConfig(pWidgetConfigInfo, configInfo)) {
785         return false;
786     }
787     return true;
788 }
789
790 bool TaskWidgetConfig::fillWidgetConfig(
791     WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
792     WrtDB::ConfigParserData& configInfo)
793 {
794     if (!!configInfo.widget_id) {
795         if (!pWidgetConfigInfo.guid) {
796             pWidgetConfigInfo.guid = configInfo.widget_id;
797         } else {
798             if (pWidgetConfigInfo.guid != configInfo.widget_id) {
799                 LogError("Invalid archive");
800                 return false;
801             }
802         }
803     }
804     if (!!configInfo.tizenAppId) {
805         if (DPL::ToUTF8String(pWidgetConfigInfo.tzAppid).compare(
806                 DPL::ToUTF8String(*configInfo.tizenAppId)) < 0)
807         {
808             LogError("Invalid archive - Tizen App ID not same error");
809             return false;
810         }
811     }
812     if (!!configInfo.tizenPkgId) {
813         if (pWidgetConfigInfo.tzPkgid != *configInfo.tizenPkgId) {
814             LogError("Invalid archive - Tizen Pkg ID not same error");
815             return false;
816         }
817     }
818     if (!!configInfo.version) {
819         if (!pWidgetConfigInfo.version) {
820             pWidgetConfigInfo.version = configInfo.version;
821         } else {
822             if (pWidgetConfigInfo.version != configInfo.version) {
823                 LogError("Invalid archive");
824                 return false;
825             }
826         }
827     }
828     if (!!configInfo.minVersionRequired) {
829         pWidgetConfigInfo.minVersion = configInfo.minVersionRequired;
830     } else if (!!configInfo.tizenMinVersionRequired) {
831         pWidgetConfigInfo.minVersion = configInfo.tizenMinVersionRequired;
832     }
833     return true;
834 }
835
836 void TaskWidgetConfig::processFile(
837     const std::string& path,
838     WrtDB::WidgetRegisterInfo &
839     widgetConfiguration)
840 {
841     if (!locateAndParseConfigurationFile(path, widgetConfiguration,
842                                          DEFAULT_LANGUAGE))
843     {
844         LogWarning("Widget archive: Failed while parsing config file");
845         ThrowMsg(Exception::ConfigParseFailed, path);
846     }
847 }
848
849 void TaskWidgetConfig::StartStep()
850 {
851     LogDebug("--------- <TaskWidgetConfig> : START ----------");
852 }
853
854 void TaskWidgetConfig::EndStep()
855 {
856     LogDebug("--------- <TaskWidgetConfig> : END ----------");
857 }
858 } //namespace WidgetInstall
859 } //namespace Jobs