978a9af6e6f807cbaf188a18e1c66fbae5f8e5ca
[platform/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 #include <vconf.h>
33
34 #include <dpl/utils/wrt_utility.h>
35 #include <dpl/utils/path.h>
36 #include <dpl/wrt-dao-ro/common_dao_types.h>
37 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
38 #include <dpl/wrt-dao-ro/global_config.h>
39 #include <dpl/wrt-dao-ro/config_parser_data.h>
40 #include <dpl/localization/w3c_file_localization.h>
41
42 #include <libiriwrapper.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 = L"install-location";
74 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = L"prefer-external";
75 const DPL::String SETTING_VALUE_INSTALLTOEXT_AUTO = L"auto";
76 const std::string XML_EXTENSION = ".xml";
77
78 bool hasExtension(const std::string& filename, const std::string& extension)
79 {
80     _D("Looking for extension %s in %s", extension.c_str(), filename.c_str());
81     size_t fileLen = filename.length();
82     size_t extLen = extension.length();
83     if (fileLen < extLen) {
84         _E("Filename %s is shorter than extension %s", filename.c_str(), extension.c_str());
85         return false;
86     }
87     return (0 == filename.compare(fileLen - extLen, extLen, extension));
88 }
89 } // namespace anonymous
90
91 namespace Jobs {
92 namespace WidgetInstall {
93
94 TaskConfiguration::TaskConfiguration(InstallerContext& context) :
95     DPL::TaskDecl<TaskConfiguration>(this),
96     m_context(context),
97     m_widgetConfig(m_context.widgetConfig.configInfo)
98 {
99     AddStep(&TaskConfiguration::StartStep);
100
101     AddStep(&TaskConfiguration::SetupTempDirStep);
102     AddStep(&TaskConfiguration::CheckPackageTypeStep);
103
104     AddStep(&TaskConfiguration::ParseXMLConfigStep);
105
106     AddStep(&TaskConfiguration::TizenIdStep);
107     AddStep(&TaskConfiguration::CheckAppRunningStateStep);
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()->sendProgress(0);
135 }
136
137 void TaskConfiguration::AppendTasklistStep()
138 {
139     if (!m_context.isUpdateMode) {
140         _D("TaskConfiguration -> new installation task list");
141         m_context.job->appendNewInstallationTaskList();
142     } else {
143         _D("TaskConfiguration -> update installation task list");
144         m_context.job->appendUpdateInstallationTaskList();
145     }
146 }
147
148 std::shared_ptr<PackageManager::IPkgmgrSignal> TaskConfiguration::pkgMgrInterface()
149 {
150     return m_context.job->GetInstallerStruct().pkgmgrInterface;
151 }
152
153 void TaskConfiguration::SetupTempDirStep()
154 {
155     _D("widgetPath: %s", m_context.requestedPath.c_str());
156     _D("tempPath: %s", m_tempDir.c_str());
157     if (m_context.mode.extension == InstallMode::ExtensionType::DIR) {
158         if (m_context.mode.command ==
159                 InstallMode::Command::REINSTALL) {
160             std::ostringstream tempPathBuilder;
161             tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
162             tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
163             tempPathBuilder << "/";
164             tempPathBuilder << m_context.requestedPath;
165             m_tempDir = tempPathBuilder.str();
166         } else {
167             m_tempDir = m_context.requestedPath;
168         }
169     } else {
170         m_tempDir =
171             Jobs::WidgetInstall::createTempPath(
172                     m_context.mode.rootPath ==
173                         InstallMode::RootPath::RO);
174         if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files
175         {
176             WidgetUnzip wgtUnzip;
177             wgtUnzip.unzipWgtFile(m_context.requestedPath, m_tempDir);
178         }
179         else
180         {
181             _D("From browser installation - unzip is not done");
182         }
183     }
184 }
185
186 void TaskConfiguration::ParseXMLConfigStep()
187 {
188     parseWidgetXMLConfig(
189             m_context.requestedPath, m_tempDir,
190             m_context.widgetConfig.packagingType,
191             m_context.mode.command == InstallMode::Command::REINSTALL);
192     _D("widget packaging type : %d", static_cast<WrtDB::PkgType>(m_context.widgetConfig.packagingType.pkgType));
193 }
194
195 void TaskConfiguration::TizenIdStep()
196 {
197     bool shouldMakeAppid = false;
198     using namespace PackageManager;
199
200     if (!!m_widgetConfig.tizenAppId) {
201         _D("Setting tizenAppId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenAppId).c_str());
202
203         m_context.widgetConfig.tzAppid = *m_widgetConfig.tizenAppId;
204         //check package id.
205         if (!!m_widgetConfig.tizenPkgId) {
206             _D("Setting tizenPkgId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenPkgId).c_str());
207
208             m_context.widgetConfig.tzPkgid = *m_widgetConfig.tizenPkgId;
209         } else {
210             DPL::String appid = *m_widgetConfig.tizenAppId;
211             if (appid.length() > PACKAGE_ID_LENGTH) {
212                 m_context.widgetConfig.tzPkgid =
213                     appid.substr(0, PACKAGE_ID_LENGTH);
214             } else {
215                 //old version appid only has 10byte random character is able to install for a while.
216                 //this case appid equal pkgid.
217                 m_context.widgetConfig.tzPkgid =
218                     *m_widgetConfig.tizenAppId;
219                 shouldMakeAppid = true;
220             }
221         }
222     } else {
223         shouldMakeAppid = true;
224         TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
225         _D("Checking if pkg id is unique");
226         while (true) {
227             if (!validateTizenPackageID(pkgId)) {
228                 //path exist, chose another one
229                 pkgId = WidgetDAOReadOnly::generatePkgId();
230                 continue;
231             }
232             break;
233         }
234         m_context.widgetConfig.tzPkgid = pkgId;
235         _D("tizen_id name was generated by WRT: %ls", m_context.widgetConfig.tzPkgid.c_str());
236     }
237
238     if (shouldMakeAppid == true) {
239         DPL::OptionalString name;
240         DPL::OptionalString defaultLocale = m_widgetConfig.defaultlocale;
241
242         FOREACH(localizedData, m_widgetConfig.localizedDataSet)
243         {
244             Locale i = localizedData->first;
245             if (!!defaultLocale) {
246                 if (defaultLocale == i) {
247                     name = localizedData->second.name;
248                     break;
249                 }
250             } else {
251                 name = localizedData->second.name;
252                 break;
253             }
254         }
255         regex_t regx;
256         if (regcomp(&regx, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
257             _D("Regcomp failed");
258         }
259
260         _D("Name : %ls", (*name).c_str());
261         if (!name || (regexec(&regx, DPL::ToUTF8String(*name).c_str(),
262                               static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
263         {
264             const std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
265             std::ostringstream genName;
266             struct timeval tv;
267             gettimeofday(&tv, NULL);
268             unsigned int seed = time(NULL) + tv.tv_usec;
269
270             genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
271             name = DPL::FromUTF8String(genName.str());
272             _D("name was generated by WRT");
273         }
274         regfree(&regx);
275         _D("Name : %ls", (*name).c_str());
276         std::ostringstream genid;
277         genid << m_context.widgetConfig.tzPkgid << "." << name;
278         _D("tizen appid was generated by WRT : %s", genid.str().c_str());
279
280         DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
281         NormalizeAndTrimSpaceString(appid);
282         m_context.widgetConfig.tzAppid = *appid;
283     }
284
285     // send start signal of pkgmgr
286     pkgMgrInterface()->setPkgname(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid));
287
288     _D("Tizen App Id : %ls", (m_context.widgetConfig.tzAppid).c_str());
289     _D("Tizen Pkg Id : %ls", (m_context.widgetConfig.tzPkgid).c_str());
290 }
291
292 void TaskConfiguration::CheckAppRunningStateStep()
293 {
294     bool isRunning = false;
295     int ret =
296         app_manager_is_running(DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
297                                &isRunning);
298     if (APP_MANAGER_ERROR_NONE != ret) {
299         _E("Fail to get running state");
300         ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
301                 "widget is running");
302     }
303
304     if (true == isRunning) {
305         // get app_context for running application
306         // app_context must be released with app_context_destroy
307         app_context_h appCtx = NULL;
308         ret =
309             app_manager_get_app_context(
310                 DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
311                 &appCtx);
312         if (APP_MANAGER_ERROR_NONE != ret) {
313             _E("Fail to get app_context");
314             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
315                     "widget is running");
316         }
317
318         // terminate app_context_h
319         ret = app_manager_terminate_app(appCtx);
320         if (APP_MANAGER_ERROR_NONE != ret) {
321             _E("Fail to terminate running application");
322             app_context_destroy(appCtx);
323             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
324                     "widget is running");
325         } else {
326             app_context_destroy(appCtx);
327             // app_manager_terminate_app isn't sync API
328             // wait until application isn't running (50ms * 100)
329             bool isStillRunning = true;
330             int checkingloop = 100;
331             struct timespec duration = { 0, 50 * 1000 * 1000 };
332             while (--checkingloop >= 0) {
333                 nanosleep(&duration, NULL);
334                 int ret = app_manager_is_running(
335                         DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
336                         &isStillRunning);
337                 if (APP_MANAGER_ERROR_NONE != ret) {
338                     _E("Fail to get running state");
339                     ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
340                             "widget is running");
341                 }
342                 if (!isStillRunning) {
343                     break;
344                 }
345             }
346             if (isStillRunning) {
347                 _E("Fail to terminate running application");
348                 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
349                         "widget is running");
350             }
351             _D("terminate application");
352         }
353     }
354 }
355
356 void TaskConfiguration::ConfigureWidgetLocationStep()
357 {
358     m_context.locations =
359         WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid),
360                        m_context.requestedPath, m_tempDir,
361                        m_context.widgetConfig.packagingType,
362                        m_context.mode.rootPath ==
363                            InstallMode::RootPath::RO,
364                            m_context.mode.extension);
365     m_context.locations->registerAppid(
366         DPL::ToUTF8String(m_context.widgetConfig.tzAppid));
367
368     _D("widgetSource %s", m_context.requestedPath.c_str());
369 }
370
371 void TaskConfiguration::DetectUpdateInstallationStep()
372 {
373     WidgetUpdateInfo update;
374     // checking installed web application
375     Try {
376         // no excpetion means, it isn't update mode
377         update = detectWidgetUpdate(m_widgetConfig,
378                                     m_context.widgetConfig.tzAppid);
379         checkWidgetUpdate(update);
380
381         m_context.isUpdateMode = true;
382
383         //if update, notify pkgmgr that this is update
384         pkgMgrInterface()->startJob(InstallationType::UpdateInstallation);
385     }
386     Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
387         pkgMgrInterface()->startJob(InstallationType::NewInstallation);
388
389         m_context.isUpdateMode = false;
390
391         if (!validateTizenApplicationID(
392             m_context.widgetConfig.tzAppid))
393         {
394             _E("tizen application ID is already used");
395             ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
396                 "invalid config");
397         }
398         if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) {
399             _E("tizen package ID is already used");
400             ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
401                 "package is already installed");
402         }
403     }
404 }
405
406 void TaskConfiguration::CheckRDSSupportStep()
407 {
408     //update needs RDS support to go ahead if REINSTALL command is given
409     if(m_context.isUpdateMode)
410     {
411         if (!checkSupportRDSUpdateIfReinstall(m_widgetConfig)) {
412             ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
413                 "RDS update failed");
414         }
415     }
416 }
417
418 bool TaskConfiguration::validateTizenApplicationID(
419     const WrtDB::TizenAppId &tizenAppId)
420 {
421     _D("tizen application ID = [%ls]", tizenAppId.c_str());
422
423     regex_t reg;
424     if (regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
425         _D("Regcomp failed");
426     }
427
428     if (regexec(&reg, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
429         == REG_NOMATCH)
430     {
431         regfree(&reg);
432         return false;
433     }
434     regfree(&reg);
435     return true;
436 }
437
438 bool TaskConfiguration::validateTizenPackageID(
439     const WrtDB::TizenPkgId &tizenPkgId)
440 {
441     std::string pkgId = DPL::ToUTF8String(tizenPkgId);
442
443     std::string installPath =
444         std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
445         "/" + pkgId;
446
447     struct stat dirStat;
448     if ((stat(installPath.c_str(), &dirStat) == 0))
449     {
450         return false;
451     }
452     return true;
453 }
454
455 bool TaskConfiguration::checkWidgetUpdate(
456     const WidgetUpdateInfo &update)
457 {
458     if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
459         return false;
460     }
461
462     _D("existing version = '%ls", update.existingVersion->Raw().c_str());
463     _D("incoming version = '%ls", update.incomingVersion->Raw().c_str());
464     _D("Tizen AppID = %ls", update.tzAppId.c_str());
465
466     m_context.widgetConfig.tzAppid = update.tzAppId;
467
468     if (!!update.existingVersion ||
469             m_context.mode.extension ==
470             InstallMode::ExtensionType::DIR) {
471         return true;
472     }
473
474     return false;
475 }
476
477 void TaskConfiguration::parseWidgetXMLConfig(
478     const std::string &widgetSource,
479     const std::string &tempPath,
480     WrtDB::PackagingType pkgType,
481     bool isReinstall)
482 {
483     // Parse config
484     ParserRunner parser;
485     Try
486     {
487         if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
488             parser.Parse(widgetSource,
489                          ElementParserPtr(
490                              new RootParser<WidgetParser>(m_widgetConfig,
491                                                           DPL::FromUTF32String(
492                                                               L"widget"))));
493         } else {
494             std::string configFile;
495             configFile = tempPath + "/" + CONFIG_XML;
496             if (!WrtUtilFileExists(configFile)) {
497                 configFile = tempPath + "/" + WITH_OSP_XML;
498             }
499
500             if (isReinstall) {
501                 // checking RDS data directory
502                 if (access(configFile.c_str(), F_OK) != 0) {
503                     std::string tzAppId =
504                         widgetSource.substr(widgetSource.find_last_of("/")+1);
505                     WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
506                     configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
507                     configFile += "/";
508                     configFile += WITH_OSP_XML;
509                 }
510             }
511
512             if(!DPL::Utils::Path(configFile).Exists())
513             {
514                 ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
515             }
516
517 #ifdef SCHEMA_VALIDATION_ENABLED
518             if(!parser.Validate(configFilePath, WRT_WIDGETS_XML_SCHEMA))
519             {
520                 _E("Invalid configuration file - schema validation failed");
521                 ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Failed to parse config.xml file");
522             }
523 #endif
524             parser.Parse(configFile,
525                     ElementParserPtr(
526                         new RootParser<WidgetParser>(m_widgetConfig,
527                             DPL::
528                             FromUTF32String(
529                                 L"widget"))));
530         }
531     }
532     Catch(ElementParser::Exception::ParseError)
533     {
534         _E("Failed to parse config.xml file");
535         ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
536     }
537     Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
538     {
539         _E("Failed to find installed widget - give proper tizenId");
540         ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
541     }
542     Catch(Exceptions::WidgetConfigFileNotFound){
543         _E("Failed to find config.xml");
544         ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
545     }
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 void TaskConfiguration::CheckPackageTypeStep()
576 {
577     if (hasExtension(m_context.requestedPath, XML_EXTENSION)) {
578         _D("Hosted app installation");
579         m_context.widgetConfig.packagingType = PKG_TYPE_HOSTED_WEB_APP;
580         return;
581     }
582
583     std::string configFile = m_tempDir + "/" + OSP_MANIFEST_XML;
584     if (WrtUtilFileExists(configFile)) {
585         m_context.widgetConfig.packagingType = PKG_TYPE_HYBRID_WEB_APP;
586         return;
587     }
588
589     m_context.widgetConfig.packagingType = PKG_TYPE_NOMAL_WEB_APP;
590 }
591
592 void TaskConfiguration::ApplicationTypeStep() //TODO: is this really needed as WAC is not supported?
593 {
594     AppType widgetAppType = APP_TYPE_UNKNOWN;
595     FOREACH(iterator, m_widgetConfig.nameSpaces) {
596         _D("namespace = [%ls]", (*iterator).c_str());
597
598         if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
599             widgetAppType = APP_TYPE_TIZENWEBAPP;
600             break;
601         }
602     }
603
604     m_context.widgetConfig.webAppType = widgetAppType;
605
606     _D("type = [%s]", m_context.widgetConfig.webAppType.getApptypeToString().c_str());
607 }
608
609 void TaskConfiguration::ResourceEncryptionStep()
610 {    
611     m_context.needEncryption = false;
612     FOREACH(it, m_widgetConfig.settingsList)
613     {
614         if (it->m_name == SETTING_VALUE_ENCRYPTION &&
615             it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
616         {
617             _D("resource need encryption");
618             m_context.needEncryption = true;
619         }
620     }
621 }
622
623 bool TaskConfiguration::getMMCStatus()
624 {
625     int mmcStatus;
626     if (vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus)) {
627         _E("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
628         return false;
629     }
630
631     switch(mmcStatus)
632     {
633     case VCONFKEY_SYSMAN_MMC_MOUNTED:
634         _D("mmcStatus is MMC_MOUNTED.");
635         return true;
636     case VCONFKEY_SYSMAN_MMC_REMOVED:
637     case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED:
638         _D("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
639         return false;
640     default:
641         _E("Platform is not supported, use the default settings");
642         return false;
643     }
644 }
645
646 bool TaskConfiguration::getDefaultExternalStorage()
647 {
648     // XXX NOT IMPLEMENTED.
649     return false;
650 }
651
652 void TaskConfiguration::InstallationFSLocationStep()
653 {
654     m_context.locationType = INSTALL_LOCATION_TYPE_NOMAL;
655     DPL::String locationValue;
656
657     if (m_context.mode.installTime != InstallMode::InstallTime::PRELOAD) {
658         FOREACH(it, m_widgetConfig.settingsList) {
659             if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME) {
660                 locationValue = it->m_value;
661                 break;
662             }
663         }
664
665         if ((SETTING_VALUE_INSTALLTOEXT_PREPER_EXT == locationValue
666                     && getMMCStatus()) ||
667                 (SETTING_VALUE_INSTALLTOEXT_AUTO == locationValue
668                  && getDefaultExternalStorage())) {
669             _D("This webapp will be installed to sd card");
670             m_context.locationType = INSTALL_LOCATION_TYPE_EXTERNAL;
671         }
672     }
673 }
674
675 bool TaskConfiguration::checkSupportRDSUpdateIfReinstall(const WrtDB::ConfigParserData
676         &configInfo)
677 {
678     if (m_context.mode.command ==
679             InstallMode::Command::REINSTALL)
680     {
681         DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
682         DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
683
684         WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid);
685         WrtDB::WidgetSettings widgetSettings;
686         dao.getWidgetSettings(widgetSettings);
687
688         FOREACH(it, widgetSettings) {
689             if (it->settingName == SETTING_VALUE_ENCRYPTION) {
690                 dbValue = it->settingValue;
691             }
692         }
693
694         FOREACH(data, configInfo.settingsList)
695         {
696             if (data->m_name == SETTING_VALUE_ENCRYPTION)
697             {
698                 configValue = data->m_value;
699             }
700         }
701         if (configValue != dbValue) {
702             _E("Not Support RDS mode because of encryption setting");
703             return false;
704         }
705     }
706
707     return true;
708 }
709
710 }
711 }