57958eba217a7f68e2f55adba8c71daec3757689
[platform/framework/web/wrt-installer.git] / src / jobs / widget_install / task_process_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_process_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 <string>
24 #include <sys/stat.h>
25 #include <dirent.h>
26
27 #include <dpl/errno_string.h>
28 #include <dpl/foreach.h>
29 #include <dpl/localization/w3c_file_localization.h>
30 #include <dpl/singleton_impl.h>
31 #include <dpl/utils/mime_type_utils.h>
32 #include <dpl/utils/wrt_global_settings.h>
33 #include <dpl/utils/wrt_utility.h>
34 #include <dpl/wrt-dao-ro/global_config.h>
35 #include <dpl/wrt-dao-ro/config_parser_data.h>
36 #include <dpl/wrt-dao-rw/feature_dao.h>
37
38 #include <widget_install/job_widget_install.h>
39 #include <widget_install/task_process_config.h>
40 #include <widget_install/widget_install_context.h>
41 #include <widget_install/widget_install_errors.h>
42 #include <widget_parser.h>
43 #include <web_provider_plugin_info.h>
44 #include <web_provider_livebox_info.h>
45 #include <manifest.h>
46
47 #include <installer_log.h>
48
49 namespace { // anonymous
50 const DPL::String BR = DPL::FromUTF8String("<br>");
51 const std::string WINDGET_INSTALL_NETWORK_ACCESS = "network access";
52 }
53
54 namespace Jobs {
55 namespace WidgetInstall {
56
57 TaskProcessConfig::TaskProcessConfig(InstallerContext& installContext) :
58     DPL::TaskDecl<TaskProcessConfig>(this),
59     m_installContext(installContext)
60 {
61     AddStep(&TaskProcessConfig::StartStep);
62     AddStep(&TaskProcessConfig::ReadLocaleFolders);
63     AddStep(&TaskProcessConfig::StepFillWidgetConfig);
64     AddStep(&TaskProcessConfig::ProcessLocalizedStartFiles);
65     AddStep(&TaskProcessConfig::ProcessBackgroundPageFile);
66     AddStep(&TaskProcessConfig::ProcessLocalizedIcons);
67     AddStep(&TaskProcessConfig::ProcessWidgetInstalledPath);
68     AddStep(&TaskProcessConfig::ProcessAppControlInfo);
69     AddStep(&TaskProcessConfig::ProcessSecurityModel);
70     AddStep(&TaskProcessConfig::StepVerifyFeatures);
71     AddStep(&TaskProcessConfig::StepVerifyLivebox);
72     AddStep(&TaskProcessConfig::StepCheckMinVersionInfo);
73     AddStep(&TaskProcessConfig::EndStep);
74 }
75
76 void TaskProcessConfig::StepFillWidgetConfig()
77 {
78     if (!fillWidgetConfig(m_installContext.widgetConfig,
79                          m_installContext.widgetConfig.configInfo))
80     {
81         _E("Widget configuration is illformed");
82         ThrowMsg(Exception::ConfigParseFailed, "Widget configuration is illformed");
83     }
84 }
85
86 void TaskProcessConfig::ReadLocaleFolders()
87 {
88     _D("Reading locale");
89     //Adding default locale
90     m_localeFolders.insert(L"");
91
92     std::string localePath =
93         m_installContext.locations->getConfigurationDir() + "/locales";
94     DIR* localeDir = opendir(localePath.c_str());
95     if (!localeDir) {
96         _D("No /locales directory in the widget package.");
97         return;
98     }
99
100     struct stat statStruct;
101     struct dirent dirent;
102     struct dirent *result;
103     int return_code;
104     errno = 0;
105     for (return_code = readdir_r(localeDir, &dirent, &result);
106             result != NULL && return_code == 0;
107             return_code = readdir_r(localeDir, &dirent, &result))
108     {
109         DPL::String dirName = DPL::FromUTF8String(dirent.d_name);
110         std::string absoluteDirName = localePath + "/";
111         absoluteDirName += dirent.d_name;
112
113         if (stat(absoluteDirName.c_str(), &statStruct) != 0) {
114             _E("stat() failed with %s", DPL::GetErrnoString().c_str());
115             continue;
116         }
117
118         if (S_ISDIR(statStruct.st_mode)) {
119             //Yes, we ignore current, parent & hidden directories
120             if (dirName[0] != L'.') {
121                 _D("Adding locale directory \"%ls\"", dirName.c_str());
122                 m_localeFolders.insert(dirName);
123             }
124         }
125     }
126
127     if (return_code != 0 || errno != 0) {
128         _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
129     }
130
131     if (-1 == closedir(localeDir)) {
132         _E("Failed to close dir: %s with error: %s", localePath.c_str(), DPL::GetErrnoString().c_str());
133     }
134
135     m_installContext.job->UpdateProgress(InstallerContext::INSTALL_WIDGET_CONFIG1, "Read locale folders");
136 }
137
138 void TaskProcessConfig::ProcessLocalizedStartFiles()
139 {
140     typedef DPL::String S;
141     ProcessStartFile(
142         m_installContext.widgetConfig.configInfo.startFile,
143         m_installContext.widgetConfig.configInfo.
144             startFileContentType,
145         m_installContext.widgetConfig.configInfo.startFileEncoding,
146         true);
147     ProcessStartFile(S(L"index.htm"), S(L"text/html"));
148     ProcessStartFile(S(L"index.html"), S(L"text/html"));
149     ProcessStartFile(S(L"index.svg"), S(L"image/svg+xml"));
150     ProcessStartFile(S(L"index.xhtml"), S(L"application/xhtml+xml"));
151     ProcessStartFile(S(L"index.xht"), S(L"application/xhtml+xml"));
152     // TODO: we need better check if in current locales widget is valid
153     FOREACH(it, m_installContext.widgetConfig.localizationData.startFiles) {
154         if (it->propertiesForLocales.size() > 0) {
155             return;
156         }
157     }
158     ThrowMsg(Exceptions::InvalidStartFile,
159              "The Widget has no valid start file");
160 }
161
162 void TaskProcessConfig::ProcessStartFile(const DPL::OptionalString& path,
163                                         const DPL::OptionalString& type,
164                                         const DPL::OptionalString& encoding,
165                                         bool typeForcedInConfig)
166 {
167     using namespace WrtDB;
168
169     if (!!path) {
170         WidgetRegisterInfo::LocalizedStartFile startFileData;
171         startFileData.path = *path;
172
173         FOREACH(i, m_localeFolders) {
174             DPL::String pathPrefix = *i;
175             if (!pathPrefix.empty()) {
176                 pathPrefix = L"locales/" + pathPrefix + L"/";
177             }
178
179             DPL::String relativePath = pathPrefix + *path;
180             DPL::String absolutePath = DPL::FromUTF8String(
181                     m_installContext.locations->getConfigurationDir()) + L"/" +
182                 relativePath;
183
184             // get property data from packaged app
185             if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
186                 WidgetRegisterInfo::StartFileProperties startFileProperties;
187                 if (!!type) {
188                     startFileProperties.type = *type;
189                 } else {
190                     startFileProperties.type =
191                         MimeTypeUtils::identifyFileMimeType(absolutePath);
192                 }
193
194                 //proceed only if MIME type is supported
195                 if (MimeTypeUtils::isMimeTypeSupportedForStartFile(
196                         startFileProperties.type))
197                 {
198                     if (!!encoding) {
199                         startFileProperties.encoding = *encoding;
200                     } else {
201                         MimeTypeUtils::MimeAttributes attributes =
202                             MimeTypeUtils::getMimeAttributes(
203                                 startFileProperties.type);
204                         if (attributes.count(L"charset") > 0) {
205                             startFileProperties.encoding =
206                                 attributes[L"charset"];
207                         } else {
208                             startFileProperties.encoding = L"UTF-8";
209                         }
210                     }
211
212                     startFileData.propertiesForLocales[*i] =
213                         startFileProperties;
214                 } else {
215                     //9.1.16.5.content.8
216                     //(there seems to be no similar requirement in .6,
217                     //so let's throw only when mime type is
218                     // provided explcitly in config.xml)
219                     if (typeForcedInConfig) {
220                         ThrowMsg(Exceptions::WidgetConfigFileInvalid,
221                                  "Unsupported MIME type for start file.");
222                     }
223                 }
224             } else {
225                 // set property data for hosted start url
226                 // Hosted start url only support TIZEN WebApp
227                 if (m_installContext.widgetConfig.webAppType ==
228                     APP_TYPE_TIZENWEBAPP)
229                 {
230                     std::string startPath = DPL::ToUTF8String(
231                             startFileData.path);
232
233                     if (strstr(startPath.c_str(),
234                                "http") == startPath.c_str())
235                     {
236                         WidgetRegisterInfo::StartFileProperties
237                             startFileProperties;
238                         if (!!type) {
239                             startFileProperties.type = *type;
240                         }
241                         if (!!encoding) {
242                             startFileProperties.encoding = *encoding;
243                         }
244                         startFileData.propertiesForLocales[*i] =
245                             startFileProperties;
246                     }
247                 }
248             }
249         }
250
251         m_installContext.widgetConfig.localizationData.startFiles.push_back(
252             startFileData);
253     }
254 }
255
256 void TaskProcessConfig::ProcessBackgroundPageFile()
257 {
258     if (!!m_installContext.widgetConfig.configInfo.backgroundPage) {
259         // check whether file exists
260         DPL::String backgroundPagePath = DPL::FromUTF8String(
261                 m_installContext.locations->getConfigurationDir()) + L"/" +
262             *m_installContext.widgetConfig.configInfo.backgroundPage;
263         //if no then cancel installation
264         if (!WrtUtilFileExists(DPL::ToUTF8String(backgroundPagePath))) {
265             ThrowMsg(Exceptions::WidgetConfigFileInvalid,
266                      L"Given background page file not found in archive");
267         }
268     }
269 }
270
271 void TaskProcessConfig::ProcessLocalizedIcons()
272 {
273     using namespace WrtDB;
274     FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList)
275     {
276         ProcessIcon(*i);
277     }
278     ProcessIcon(ConfigParserData::Icon(L"icon.svg"));
279     ProcessIcon(ConfigParserData::Icon(L"icon.ico"));
280     ProcessIcon(ConfigParserData::Icon(L"icon.png"));
281     ProcessIcon(ConfigParserData::Icon(L"icon.gif"));
282     ProcessIcon(ConfigParserData::Icon(L"icon.jpg"));
283 }
284
285 void TaskProcessConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon)
286 {
287     _D("enter");
288     bool isAnyIconValid = false;
289     //In case a default filename is passed as custom filename in config.xml, we
290     //need to keep a set of already processed filenames to avoid icon
291     // duplication
292     //in database.
293
294     using namespace WrtDB;
295
296     if (m_processedIconSet.count(icon.src) > 0) {
297         return;
298     }
299     m_processedIconSet.insert(icon.src);
300
301     LocaleSet localesAvailableForIcon;
302
303     FOREACH(i, m_localeFolders)
304     {
305         DPL::String pathPrefix = *i;
306         if (!pathPrefix.empty()) {
307             pathPrefix = L"locales/" + pathPrefix + L"/";
308         }
309
310         DPL::String relativePath = pathPrefix + icon.src;
311         DPL::String absolutePath = DPL::FromUTF8String(
312                 m_installContext.locations->getConfigurationDir()) + L"/" +
313             relativePath;
314
315         if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
316             DPL::String type = MimeTypeUtils::identifyFileMimeType(absolutePath);
317
318             if (MimeTypeUtils::isMimeTypeSupportedForIcon(type)) {
319                 isAnyIconValid = true;
320                 localesAvailableForIcon.insert(*i);
321                 _D("Icon absolutePath: %ls, assigned locale: %ls, type: %ls",
322                     absolutePath.c_str(), (*i).c_str(), type.c_str());
323             }
324         }
325     }
326
327     if (isAnyIconValid) {
328         WidgetRegisterInfo::LocalizedIcon localizedIcon(icon,
329                                                         localesAvailableForIcon);
330         m_installContext.widgetConfig.localizationData.icons.push_back(
331             localizedIcon);
332     }
333 }
334
335 void TaskProcessConfig::ProcessWidgetInstalledPath()
336 {
337     _D("ProcessWidgetInstalledPath");
338     m_installContext.widgetConfig.widgetInstalledPath =
339         DPL::FromUTF8String(
340             m_installContext.locations->getPackageInstallationDir());
341 }
342
343 void TaskProcessConfig::ProcessAppControlInfo()
344 {
345     _D("ProcessAppControlInfo");
346     using namespace WrtDB;
347
348     // In case of dispostion is inline, set the seperate execute
349     int index = 1;
350     // 0 index is reserved by default execute
351     FOREACH(it, m_installContext.widgetConfig.configInfo.appControlList) {
352         if (it->m_disposition ==
353             ConfigParserData::AppControlInfo::Disposition::INLINE)
354         {
355             it->m_index = index++;
356         } else {
357             it->m_index = 0;
358         }
359     }
360 }
361
362 void TaskProcessConfig::ProcessSecurityModel()
363 {
364     // 0104.  If the "required_version" specified in the Web Application's
365     // configuration is 2.2 or higher and if the Web Application's
366     // configuration is "CSP-compatible configuration", then the WRT MUST be
367     // set to "CSP-based security mode". Otherwise, the WRT MUST be set to
368     // "WARP-based security mode".
369     // 0105.  A Web Application configuration is "CSP-compatible configuration"
370     // if the configuration includes one or more of
371     // <tizen:content-security-policy> /
372     // <tizen:content-security-policy-report-only> /
373     // <tizen:allow-navigation> elements.
374
375     bool isSecurityModelV1 = false;
376     bool isSecurityModelV2 = false;
377     WrtDB::ConfigParserData &data = m_installContext.widgetConfig.configInfo;
378
379     if (!data.cspPolicy.IsNull() ||
380         !data.cspPolicyReportOnly.IsNull() ||
381         !data.allowNavigationInfoList.empty())
382     {
383         data.accessInfoSet.clear();
384     }
385
386     // WARP is V1
387     if (!data.accessInfoSet.empty()) {
388         isSecurityModelV1 = true;
389     }
390
391     // CSP & allow-navigation is V2
392     if (!data.cspPolicy.IsNull() ||
393         !data.cspPolicyReportOnly.IsNull() ||
394         !data.allowNavigationInfoList.empty())
395     {
396         isSecurityModelV2 = true;
397     }
398
399     if (isSecurityModelV1 && isSecurityModelV2) {
400         _E("Security model is conflict");
401         ThrowMsg(Exceptions::NotAllowed, "Security model is conflict");
402     } else if (isSecurityModelV1) {
403         data.securityModelVersion =
404             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
405     } else if (isSecurityModelV2) {
406         data.securityModelVersion =
407             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V2;
408     } else {
409         data.securityModelVersion =
410             WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
411     }
412
413     m_installContext.job->UpdateProgress(
414         InstallerContext::INSTALL_WIDGET_CONFIG2,
415         "Finished process security model");
416 }
417
418 void TaskProcessConfig::StepCheckMinVersionInfo()
419 {
420     if (!isMinVersionCompatible(
421             m_installContext.widgetConfig.webAppType.appType,
422             m_installContext.widgetConfig.minVersion))
423     {
424         _E("Platform version lower than required -> cancelling installation");
425         ThrowMsg(Exceptions::NotAllowed,
426                  "Platform version does not meet requirements");
427     }
428
429     m_installContext.job->UpdateProgress(
430         InstallerContext::INSTALL_WIDGET_CONFIG2,
431         "Check MinVersion Finished");
432 }
433
434 void TaskProcessConfig::StepVerifyFeatures()
435 {
436     using namespace WrtDB;
437     ConfigParserData &data = m_installContext.widgetConfig.configInfo;
438     ConfigParserData::FeaturesList list = data.featuresList;
439     ConfigParserData::FeaturesList newList;
440
441     //in case of tests, this variable is unused
442     std::string featureInfo;
443     FOREACH(it, list)
444     {
445         // check feature vender for permission
446         // WAC, TIZEN WebApp cannot use other feature
447
448         if (!isFeatureAllowed(m_installContext.widgetConfig.webAppType.appType,
449                               it->name))
450         {
451             _D("This application type not allowed to use this feature");
452             ThrowMsg(
453                 Exceptions::WidgetConfigFileInvalid,
454                 "This app type [" <<
455                 m_installContext.widgetConfig.webAppType.getApptypeToString()
456                                   <<
457                 "] cannot be allowed to use [" <<
458                 DPL::ToUTF8String(it->name) + "] feature");
459         } else {
460             newList.insert(*it);
461             featureInfo += DPL::ToUTF8String(it->name);
462             featureInfo += DPL::ToUTF8String(BR);
463         }
464     }
465     if (!data.accessInfoSet.empty()) {
466         featureInfo += WINDGET_INSTALL_NETWORK_ACCESS;
467         featureInfo += DPL::ToUTF8String(BR);
468     }
469     data.featuresList = newList;
470
471     m_installContext.job->UpdateProgress(
472         InstallerContext::INSTALL_WIDGET_CONFIG2,
473         "Widget Config step2 Finished");
474 }
475
476 void TaskProcessConfig::StepVerifyLivebox()
477 {
478     using namespace WrtDB;
479     ConfigParserData &data = m_installContext.widgetConfig.configInfo;
480     ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
481
482     if (liveBoxList.size() <= 0) {
483         return;
484     }
485
486     FOREACH (it, liveBoxList) {
487         std::string boxType;
488
489         if ((**it).m_liveboxId.find(m_installContext.widgetConfig.tzAppid) != 0) {
490             _E("Invalid app-widget id (doesn't begin with application id)");
491             ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid app-widget id (doesn't begin with application id)");
492         }
493
494         if ((**it).m_type.empty()) {
495             boxType = web_provider_livebox_get_default_type();
496         } else {
497             boxType = DPL::ToUTF8String((**it).m_type);
498         }
499
500         _D("livebox type: %s", boxType.c_str());
501
502         ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
503             (**it).m_boxInfo.m_boxSize;
504         char** boxSize = static_cast<char**>(
505             malloc(sizeof(char*)* boxSizeList.size()));
506
507         int boxSizeCnt = 0;
508         FOREACH (m, boxSizeList) {
509             boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str());
510         }
511
512         bool chkSize = web_provider_plugin_check_supported_size(
513             boxType.c_str(), boxSize, boxSizeCnt);
514
515         for(int i = 0; i < boxSizeCnt; i++) {
516             free(boxSize[i]);
517         }
518         free(boxSize);
519
520         if(!chkSize) {
521             _E("Invalid boxSize");
522             ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid boxSize");
523         }
524     }
525 }
526
527 bool TaskProcessConfig::isFeatureAllowed(WrtDB::AppType appType,
528                                         DPL::String featureName)
529 {
530     using namespace WrtDB;
531     _D("AppType = [%s]", WidgetType(appType).getApptypeToString().c_str());
532     _D("FetureName = [%ls]", featureName.c_str());
533
534     AppType featureType = APP_TYPE_UNKNOWN;
535     std::string featureStr = DPL::ToUTF8String(featureName);
536     const char* feature = featureStr.c_str();
537
538     // check prefix of  feature name
539     if (strstr(feature, PluginsPrefix::TIZENPluginsPrefix) == feature) {
540         // Tizen WebApp feature
541         featureType = APP_TYPE_TIZENWEBAPP;
542     } else if (strstr(feature, PluginsPrefix::W3CPluginsPrefix) == feature) {
543         // W3C standard feature
544         // Both WAC and TIZEN WebApp are possible to use W3C plugins
545         return true;
546     } else {
547         // unknown feature
548         // unknown feature will be checked next step
549         return true;
550     }
551
552     if (appType == featureType) {
553         return true;
554     }
555     return false;
556 }
557
558 bool TaskProcessConfig::parseVersionString(const std::string &version,
559                                           long &majorVersion,
560                                           long &minorVersion,
561                                           long &microVersion) const
562 {
563     std::istringstream inputString(version);
564     inputString >> majorVersion;
565     if (inputString.bad() || inputString.fail()) {
566         _W("Invalid minVersion format.");
567         return false;
568     }
569     inputString.get(); // skip period
570     inputString >> minorVersion;
571     if (inputString.bad() || inputString.fail()) {
572         _W("Invalid minVersion format");
573         return false;
574     } else {
575         inputString.get(); // skip period
576         if (inputString.bad() || inputString.fail()) {
577             inputString >> microVersion;
578         }
579     }
580     return true;
581 }
582
583 bool TaskProcessConfig::isMinVersionCompatible(
584     WrtDB::AppType appType,
585     const DPL::OptionalString &
586     widgetVersion) const
587 {
588     if (widgetVersion.IsNull() || (*widgetVersion).empty()) {
589         if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
590             return false;
591         } else {
592             _W("minVersion attribute is empty. WRT assumes platform "
593                "supports this widget.");
594             return true;
595         }
596     }
597
598     //Parse widget version
599     long majorWidget = 0, minorWidget = 0, microWidget = 0;
600     if (!parseVersionString(DPL::ToUTF8String(*widgetVersion), majorWidget,
601                             minorWidget, microWidget))
602     {
603         _W("Invalid format of widget version string.");
604         return false;
605     }
606
607     //Parse supported version
608     long majorSupported = 0, minorSupported = 0, microSupported = 0;
609     std::string version;
610     if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
611         version = WrtDB::GlobalConfig::GetTizenVersion();
612     } else {
613         _W("Invaild AppType");
614         return false;
615     }
616
617     if (!parseVersionString(version,
618                             majorSupported, minorSupported, microSupported))
619     {
620         _W("Invalid format of platform version string.");
621         return true;
622     }
623
624     if (majorWidget > majorSupported ||
625         (majorWidget == majorSupported && minorWidget > minorSupported) ||
626         (majorWidget == majorSupported && minorWidget == minorSupported
627          && microWidget > microSupported))
628     {
629         _D("Platform doesn't support this widget.");
630         return false;
631     }
632     return true;
633 }
634
635 bool TaskProcessConfig::isTizenWebApp() const
636 {
637     if (m_installContext.widgetConfig.webAppType.appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
638     {
639         return true;
640     }
641     return false;
642 }
643
644 bool TaskProcessConfig::fillWidgetConfig(
645     WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
646     WrtDB::ConfigParserData& configInfo)
647 {
648     pWidgetConfigInfo.guid = configInfo.widget_id;
649
650     if (!!configInfo.version) {
651         if (!pWidgetConfigInfo.version) {
652             pWidgetConfigInfo.version = configInfo.version;
653         } else {
654             if (pWidgetConfigInfo.version != configInfo.version) {
655                 _E("Invalid archive");
656                 return false;
657             }
658         }
659     }
660     if (!!configInfo.minVersionRequired) {
661         pWidgetConfigInfo.minVersion = configInfo.minVersionRequired;
662     } else if (!!configInfo.tizenMinVersionRequired) {
663         pWidgetConfigInfo.minVersion = configInfo.tizenMinVersionRequired;
664     }
665     return true;
666 }
667
668 void TaskProcessConfig::StartStep()
669 {
670     _D("--------- <TaskProcessConfig> : START ----------");
671 }
672
673 void TaskProcessConfig::EndStep()
674 {
675     _D("--------- <TaskProcessConfig> : END ----------");
676 }
677
678 } //namespace WidgetInstall
679 } //namespace Jobs