TaskConfiguration refactoring - part 1/3
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_configuration.cpp
1 /*
2  * Copyright (c) 2013 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_configuration.cpp
18  * @version 1.0
19  * @author  Tomasz Iwanek
20  * @brief   implementation file for configuration task
21  */
22 #include "task_configuration.h"
23
24 #include <string>
25 #include <sstream>
26 #include <memory>
27 #include <sys/time.h>
28 #include <ctime>
29 #include <cstdlib>
30 #include <limits.h>
31 #include <regex.h>
32
33 #include <dpl/utils/wrt_utility.h>
34 #include <dpl/utils/path.h>
35 #include <dpl/wrt-dao-ro/common_dao_types.h>
36 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
37 #include <dpl/wrt-dao-ro/global_config.h>
38 #include <dpl/wrt-dao-ro/config_parser_data.h>
39 #include <dpl/localization/w3c_file_localization.h>
40
41 #include <libiriwrapper.h>
42 #include <pkg-manager/pkgmgr_signal.h>
43 #include <app_manager.h>
44
45 #include "root_parser.h"
46 #include "widget_parser.h"
47 #include "parser_runner.h"
48
49 #include <widget_install/widget_install_errors.h>
50 #include <widget_install/widget_install_context.h>
51 #include <widget_install_to_external.h>
52 #include <widget_install/widget_unzip.h>
53 #include <widget_install/job_widget_install.h>
54 #include <widget_install/task_commons.h>
55
56 #include <installer_log.h>
57
58 using namespace WrtDB;
59
60 namespace {
61 const char* const CONFIG_XML = "config.xml";
62 const char* const WITH_OSP_XML = "res/wgt/config.xml";
63 const char* const OSP_MANIFEST_XML = "info/manifest.xml";
64
65 //allowed: a-z, A-Z, 0-9
66 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
67 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
68 const size_t PACKAGE_ID_LENGTH = 10;
69
70 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
71 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
72 static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
73 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
74     L"install-location";
75 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
76     L"prefer-external";
77
78 const std::string XML_EXTENSION = ".xml";
79
80 bool hasExtension(const std::string& filename, const std::string& extension)
81 {
82     _D("Looking for extension %s in %s", extension.c_str(), filename.c_str());
83     size_t fileLen = filename.length();
84     size_t extLen = extension.length();
85     if (fileLen < extLen) {
86         _E("Filename %s is shorter than extension %s", filename.c_str(), extension.c_str());
87         return false;
88     }
89     return (0 == filename.compare(fileLen - extLen, extLen, extension));
90 }
91 } // namespace anonymous
92
93 namespace Jobs {
94 namespace WidgetInstall {
95
96 TaskConfiguration::TaskConfiguration(InstallerContext& context) :
97     DPL::TaskDecl<TaskConfiguration>(this),
98     m_context(context)
99 {
100     AddStep(&TaskConfiguration::StartStep);
101     AddStep(&TaskConfiguration::PrepareInstallationStep);
102     AddStep(&TaskConfiguration::AppendTasklistStep);
103     AddStep(&TaskConfiguration::EndStep);
104 }
105
106 void TaskConfiguration::StartStep()
107 {
108     _D("--------- <TaskConfiguration> : START ----------");
109 }
110
111 void TaskConfiguration::EndStep()
112 {
113     _D("--------- <TaskConfiguration> : END ----------");
114 }
115
116 void TaskConfiguration::AppendTasklistStep()
117 {
118     if (!m_context.isUpdateMode) {
119         _D("TaskConfiguration -> new installation task list");
120         m_context.job->appendNewInstallationTaskList();
121     } else {
122         _D("TaskConfiguration -> update installation task list");
123         m_context.job->appendUpdateInstallationTaskList();
124     }
125 }
126
127 void TaskConfiguration::PrepareInstallationStep()
128 {
129     // TODO: (job_install_refactoring) clean up this task
130     std::string widgetPath = m_context.requestedPath;
131     bool result;
132     m_context.needEncryption = false;
133     std::string tempDir;
134     if (m_context.mode.extension == InstallMode::ExtensionType::DIR) {
135         if (m_context.mode.command ==
136                 InstallMode::Command::REINSTALL) {
137             std::ostringstream tempPathBuilder;
138             tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
139             tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
140             tempPathBuilder << "/";
141             tempPathBuilder << widgetPath;
142             tempDir = tempPathBuilder.str();
143         } else {
144             tempDir = widgetPath;
145         }
146     } else {
147         tempDir =
148             Jobs::WidgetInstall::createTempPath(
149                     m_context.mode.rootPath ==
150                         InstallMode::RootPath::RO);
151         WidgetUnzip wgtUnzip;
152         wgtUnzip.unzipWgtFile(widgetPath, tempDir);
153     }
154
155     _D("widgetPath: %s", widgetPath.c_str());
156     _D("tempPath: %s", tempDir.c_str());
157
158     m_context.widgetConfig.packagingType =
159         checkPackageType(widgetPath, tempDir);
160     ConfigParserData configData = getWidgetDataFromXML(
161             widgetPath,
162             tempDir,
163             m_context.widgetConfig.packagingType,
164             m_context.mode.command == InstallMode::Command::REINSTALL);
165     _D("widget packaging type : %d", static_cast<WrtDB::PkgType>(m_context.widgetConfig.packagingType.pkgType));
166
167     setTizenId(configData);
168     setApplicationType(configData);
169     m_context.needEncryption = detectResourceEncryption(configData);
170     setInstallLocationType(configData);
171     // TODO: (job_install_refactoring) hide this call
172     m_context.callerPkgId =
173         DPL::FromUTF8String(m_context.job->GetInstallerStruct().pkgmgrInterface->getCallerId());
174     _D("Caller Package Id : %s", DPL::ToUTF8String(m_context.callerPkgId).c_str());
175
176     // Configure installation
177     result = ConfigureInstallation(widgetPath, configData, tempDir);
178     // TODO: (job_install_refactoring) hide this call
179     m_context.job->GetInstallerStruct().pkgmgrInterface->sendSignal(
180             PKGMGR_PROGRESS_KEY,
181             PKGMGR_START_VALUE);
182
183     m_context.isUpdateMode = result;
184 }
185
186 void TaskConfiguration::setTizenId(
187     const WrtDB::ConfigParserData &configInfo)
188 {
189     bool shouldMakeAppid = false;
190     using namespace PackageManager;
191     if (!!configInfo.tizenAppId) {
192         _D("Setting tizenAppId provided in config.xml: %ls", (*configInfo.tizenAppId).c_str());
193         m_context.widgetConfig.tzAppid = *configInfo.tizenAppId;
194         //check package id.
195         if (!!configInfo.tizenPkgId) {
196             _D("Setting tizenPkgId provided in config.xml: %ls", (*configInfo.tizenPkgId).c_str());
197             m_context.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
198         } else {
199             DPL::String appid = *configInfo.tizenAppId;
200             if (appid.length() > PACKAGE_ID_LENGTH) {
201                 m_context.widgetConfig.tzPkgid =
202                     appid.substr(0, PACKAGE_ID_LENGTH);
203             } else {
204                 //old version appid only has 10byte random character is able to install for a while.
205                 //this case appid equal pkgid.
206                 m_context.widgetConfig.tzPkgid =
207                     *configInfo.tizenAppId;
208                 shouldMakeAppid = true;
209             }
210         }
211     } else {
212         shouldMakeAppid = true;
213         TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
214         _D("Checking if pkg id is unique");
215         while (true) {
216             if (!validateTizenPackageID(pkgId)) {
217                 //path exist, chose another one
218                 pkgId = WidgetDAOReadOnly::generatePkgId();
219                 continue;
220             }
221             break;
222         }
223         m_context.widgetConfig.tzPkgid = pkgId;
224         _D("tizen_id name was generated by WRT: %ls", m_context.widgetConfig.tzPkgid.c_str());
225     }
226
227     if (shouldMakeAppid == true) {
228         DPL::OptionalString name;
229         DPL::OptionalString defaultLocale = configInfo.defaultlocale;
230
231         FOREACH(localizedData, configInfo.localizedDataSet)
232         {
233             Locale i = localizedData->first;
234             if (!!defaultLocale) {
235                 if (defaultLocale == i) {
236                     name = localizedData->second.name;
237                     break;
238                 }
239             } else {
240                 name = localizedData->second.name;
241                 break;
242             }
243         }
244         regex_t regx;
245         if (regcomp(&regx, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
246             _D("Regcomp failed");
247         }
248
249         _D("Name : %ls", (*name).c_str());
250         if (!name || (regexec(&regx, DPL::ToUTF8String(*name).c_str(),
251                               static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
252         {
253             // TODO : (job_install_refactoring) generate name move to wrt-commons
254             std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
255             std::ostringstream genName;
256             struct timeval tv;
257             gettimeofday(&tv, NULL);
258             unsigned int seed = time(NULL) + tv.tv_usec;
259
260             genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
261             name = DPL::FromUTF8String(genName.str());
262             _D("name was generated by WRT");
263         }
264         regfree(&regx);
265         _D("Name : %ls", (*name).c_str());
266         std::ostringstream genid;
267         genid << m_context.widgetConfig.tzPkgid << "." << name;
268         _D("tizen appid was generated by WRT : %s", genid.str().c_str());
269
270         DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
271         NormalizeAndTrimSpaceString(appid);
272         m_context.widgetConfig.tzAppid = *appid;
273     }
274
275     // send start signal of pkgmgr
276     // TODO: (job_install_refactoring) hide this call
277     m_context.job->GetInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
278                                                          m_context.
279                                                              widgetConfig.
280                                                              tzPkgid));
281     _D("Tizen App Id : %ls", m_context.widgetConfig.tzAppid.c_str());
282     _D("Tizen Pkg Id : %ls", m_context.widgetConfig.tzPkgid.c_str());
283 }
284
285 void TaskConfiguration::configureWidgetLocation(const std::string & widgetPath,
286                                                const std::string& tempPath)
287 {
288     m_context.locations =
289         WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig.
290                                              tzPkgid),
291                        widgetPath, tempPath,
292                        m_context.widgetConfig.packagingType,
293                        m_context.mode.rootPath ==
294                            InstallMode::RootPath::RO,
295                            m_context.mode.extension);
296     m_context.locations->registerAppid(
297         DPL::ToUTF8String(m_context.widgetConfig.tzAppid));
298
299     _D("widgetSource %s", widgetPath.c_str());
300 }
301
302 bool TaskConfiguration::ConfigureInstallation(
303     const std::string &widgetSource,
304     const WrtDB::ConfigParserData &configData,
305     const std::string &tempPath)
306 {
307     bool result;
308
309     WidgetUpdateInfo update;
310
311     // checking installed web application
312     Try {
313         // no excpetion means, it isn't update mode
314         // TODO: (job_install_refactoring) hide this call/
315         m_context.job->GetInstallerStruct().pkgmgrInterface->sendSignal(
316                 PKGMGR_START_KEY,
317                 PKGMGR_START_UPDATE);
318
319         update = detectWidgetUpdate(configData,
320                                     m_context.widgetConfig.tzAppid);
321         result = checkWidgetUpdate(update);
322         if (!result) {
323             // Already installed TizenAppId. return failed
324             ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
325                 "package is already installed");
326         }
327         if (!checkSupportRDSUpdate(configData)) {
328             ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
329                 "RDS update failed");
330         }
331         result = true;
332     }
333     Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
334         // TODO: (job_install_refactoring) hide this call
335         m_context.job->GetInstallerStruct().pkgmgrInterface->sendSignal(
336                 PKGMGR_START_KEY,
337                 PKGMGR_START_INSTALL);
338         result = false;
339
340         if (!validateTizenApplicationID(
341             m_context.widgetConfig.tzAppid))
342         {
343             _E("tizen application ID is already used");
344             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
345                 "invalid config");
346         }
347         if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) {
348             _E("tizen package ID is already used");
349             ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
350                 "package is already installed");
351         }
352     }
353
354     configureWidgetLocation(widgetSource, tempPath);
355
356     return result;
357 }
358
359 bool TaskConfiguration::validateTizenApplicationID(
360     const WrtDB::TizenAppId &tizenAppId)
361 {
362     _D("tizen application ID = [%ls]", tizenAppId.c_str());
363
364     regex_t reg;
365     if (regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
366         _D("Regcomp failed");
367     }
368
369     if (regexec(&reg, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
370         == REG_NOMATCH)
371     {
372         regfree(&reg);
373         return false;
374     }
375     regfree(&reg);
376     return true;
377 }
378
379 bool TaskConfiguration::validateTizenPackageID(
380     const WrtDB::TizenPkgId &tizenPkgId)
381 {
382     std::string pkgId = DPL::ToUTF8String(tizenPkgId);
383
384     std::string installPath =
385         std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
386         "/" + pkgId;
387
388     struct stat dirStat;
389     if ((stat(installPath.c_str(), &dirStat) == 0))
390     {
391         return false;
392     }
393     return true;
394 }
395
396 bool TaskConfiguration::checkWidgetUpdate(
397     const WidgetUpdateInfo &update)
398 {
399     if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
400         return false;
401     }
402
403     _D("existing version = '%ls", update.existingVersion->Raw().c_str());
404     _D("incoming version = '%ls", update.incomingVersion->Raw().c_str());
405     _D("Tizen AppID = %ls", update.tzAppId.c_str());
406
407     // Check running state
408     bool isRunning = false;
409     int ret =
410         app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
411                                &isRunning);
412     if (APP_MANAGER_ERROR_NONE != ret) {
413         _E("Fail to get running state");
414         ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
415             "widget is running");
416     }
417
418     if (true == isRunning) {
419         // get app_context for running application
420         // app_context must be released with app_context_destroy
421         app_context_h appCtx = NULL;
422         ret =
423             app_manager_get_app_context(
424                 DPL::ToUTF8String(update.tzAppId).c_str(),
425                 &appCtx);
426         if (APP_MANAGER_ERROR_NONE != ret) {
427             _E("Fail to get app_context");
428             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
429                 "widget is running");
430         }
431
432         // terminate app_context_h
433         ret = app_manager_terminate_app(appCtx);
434         if (APP_MANAGER_ERROR_NONE != ret) {
435             _E("Fail to terminate running application");
436             app_context_destroy(appCtx);
437             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
438                 "widget is running");
439         } else {
440             app_context_destroy(appCtx);
441             // app_manager_terminate_app isn't sync API
442             // wait until application isn't running (50ms * 100)
443             bool isStillRunning = true;
444             int checkingloop = 100;
445             struct timespec duration = { 0, 50 * 1000 * 1000 };
446             while (--checkingloop >= 0) {
447                 nanosleep(&duration, NULL);
448                 int ret =
449                     app_manager_is_running(
450                         DPL::ToUTF8String(update.tzAppId).c_str(),
451                         &isStillRunning);
452                 if (APP_MANAGER_ERROR_NONE != ret) {
453                     _E("Fail to get running state");
454                     ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
455                         "widget is running");
456                 }
457                 if (!isStillRunning) {
458                     break;
459                 }
460             }
461             if (isStillRunning) {
462                 _E("Fail to terminate running application");
463                 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
464                     "widget is running");
465             }
466             _D("terminate application");
467         }
468     }
469
470     m_context.widgetConfig.tzAppid = update.tzAppId;
471
472     if (!!update.existingVersion ||
473             m_context.mode.extension ==
474             InstallMode::ExtensionType::DIR) {
475         return true;
476     }
477
478     return false;
479 }
480
481 ConfigParserData TaskConfiguration::getWidgetDataFromXML(
482     const std::string &widgetSource,
483     const std::string &tempPath,
484     WrtDB::PackagingType pkgType,
485     bool isReinstall)
486 {
487     // Parse config
488     ParserRunner parser;
489     ConfigParserData configInfo;
490     Try
491     {
492         if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
493             parser.Parse(widgetSource,
494                          ElementParserPtr(
495                              new RootParser<WidgetParser>(configInfo,
496                                                           DPL::FromUTF32String(
497                                                               L"widget"))));
498         } else {
499             std::string configFile;
500             configFile = tempPath + "/" + CONFIG_XML;
501             if (!WrtUtilFileExists(configFile)) {
502                 configFile = tempPath + "/" + WITH_OSP_XML;
503             }
504
505             if (isReinstall) {
506                 // checking RDS data directory
507                 if (access(configFile.c_str(), F_OK) != 0) {
508                     std::string tzAppId =
509                         widgetSource.substr(widgetSource.find_last_of("/")+1);
510                     WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
511                     configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
512                     configFile += "/";
513                     configFile += WITH_OSP_XML;
514                 }
515             }
516
517             if(!DPL::Utils::Path(configFile).Exists())
518             {
519                 ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
520             }
521
522             parser.Parse(configFile,
523                     ElementParserPtr(
524                         new RootParser<WidgetParser>(configInfo,
525                             DPL::
526                             FromUTF32String(
527                                 L"widget"))));
528         }
529     }
530     Catch(ElementParser::Exception::ParseError)
531     {
532         _E("Failed to parse config.xml file");
533         ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
534     }
535     Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
536     {
537         _E("Failed to find installed widget - give proper tizenId");
538         ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
539     }
540     Catch(Exceptions::WidgetConfigFileNotFound){
541         _E("Failed to find config.xml");
542         ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
543     }
544
545     return configInfo;
546 }
547
548 WidgetUpdateInfo TaskConfiguration::detectWidgetUpdate(
549     const ConfigParserData &configInfo,
550     const WrtDB::TizenAppId &tizenId)
551 {
552     _D("Checking up widget package for config.xml...");
553     OptionalWidgetVersion incomingVersion;
554
555     if (!configInfo.version.IsNull()) {
556         incomingVersion =
557             DPL::Optional<WidgetVersion>(
558                 WidgetVersion(*configInfo.version));
559     }
560
561     WidgetDAOReadOnly dao(tizenId);
562
563     OptionalWidgetVersion optVersion;
564     DPL::OptionalString version = dao.getVersion();
565     if (!version.IsNull()) {
566         optVersion = OptionalWidgetVersion(WidgetVersion(*version));
567     }
568
569     return WidgetUpdateInfo(
570         dao.getTzAppId(),
571         optVersion,
572         incomingVersion);
573 }
574
575
576 WrtDB::PackagingType TaskConfiguration::checkPackageType(
577     const std::string &widgetSource,
578     const std::string &tempPath)
579 {
580     if (hasExtension(widgetSource, XML_EXTENSION)) {
581         _D("Hosted app installation");
582         return PKG_TYPE_HOSTED_WEB_APP;
583     }
584
585     std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
586     if (WrtUtilFileExists(configFile)) {
587         return PKG_TYPE_HYBRID_WEB_APP;
588     }
589
590     return PKG_TYPE_NOMAL_WEB_APP;
591 }
592
593 void TaskConfiguration::setApplicationType(
594     const WrtDB::ConfigParserData &configInfo)
595 {
596     AppType widgetAppType = APP_TYPE_UNKNOWN;
597     FOREACH(iterator, configInfo.nameSpaces) {
598         _D("namespace = [%ls]", (*iterator).c_str());
599
600         if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
601             widgetAppType = APP_TYPE_TIZENWEBAPP;
602             break;
603         }
604     }
605
606     m_context.widgetConfig.webAppType = widgetAppType;
607
608     _D("type = [%s]", m_context.widgetConfig.webAppType.getApptypeToString().c_str());
609 }
610
611 bool TaskConfiguration::detectResourceEncryption(
612     const WrtDB::ConfigParserData &configData)
613 {
614     FOREACH(it, configData.settingsList)
615     {
616         if (it->m_name == SETTING_VALUE_ENCRYPTION &&
617             it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
618         {
619             _D("resource need encryption");
620             return true;
621         }
622     }
623     return false;
624 }
625
626 void TaskConfiguration::setInstallLocationType(
627     const WrtDB::ConfigParserData & configData)
628 {
629     m_context.locationType = INSTALL_LOCATION_TYPE_NOMAL;
630     if (m_context.mode.installTime != InstallMode::InstallTime::PRELOAD) {
631         FOREACH(it, configData.settingsList) {
632             if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
633                 it->m_value ==
634                 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
635             {
636                 _D("This widget will be installed to sd card");
637                 m_context.locationType =
638                     INSTALL_LOCATION_TYPE_EXTERNAL;
639             }
640         }
641     }
642 }
643
644 bool TaskConfiguration::checkSupportRDSUpdate(const WrtDB::ConfigParserData
645         &configInfo)
646 {
647     if (m_context.mode.command ==
648             InstallMode::Command::REINSTALL)
649     {
650         DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
651         DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
652
653         WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid);
654         WrtDB::WidgetSettings widgetSettings;
655         dao.getWidgetSettings(widgetSettings);
656
657         FOREACH(it, widgetSettings) {
658             if (it->settingName == SETTING_VALUE_ENCRYPTION) {
659                 dbValue = it->settingValue;
660             }
661         }
662
663         FOREACH(data, configInfo.settingsList)
664         {
665             if (data->m_name == SETTING_VALUE_ENCRYPTION)
666             {
667                 configValue = data->m_value;
668             }
669         }
670         if (configValue != dbValue) {
671             _E("Not Support RDS mode because of encryption setting");
672             return false;
673         }
674     }
675
676     return true;
677 }
678
679 }
680 }