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