2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file job_widget_install.cpp
18 * @author Radoslaw Wicik r.wicik@samsung.com
19 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
21 * @brief Implementation file for main installer task
25 #include <dpl/noncopyable.h>
26 #include <dpl/abstract_waitable_input_adapter.h>
27 #include <dpl/abstract_waitable_output_adapter.h>
28 #include <dpl/zip_input.h>
29 #include <dpl/binary_queue.h>
31 #include <dpl/assert.h>
32 #include <dpl/sstream.h>
33 #include <dpl/wrt-dao-ro/common_dao_types.h>
34 #include "root_parser.h"
35 #include "widget_parser.h"
36 #include "parser_runner.h"
37 #include <widget_install/job_widget_install.h>
38 #include <widget_install/task_unzip.h>
39 #include <widget_install/task_certify.h>
40 #include <widget_install/task_widget_config.h>
41 #include <widget_install/task_file_manipulation.h>
42 #include <widget_install/task_ace_check.h>
43 #include <widget_install/task_smack.h>
44 #include <widget_install/task_manifest_file.h>
45 #include <widget_install/task_private_storage.h>
46 #include <widget_install/task_prepare_files.h>
47 #include <widget_install/task_recovery.h>
48 #include <widget_install/task_install_ospsvc.h>
49 #include <widget_install/task_update_files.h>
50 #include <widget_install/task_database.h>
51 #include <widget_install/task_remove_backup.h>
52 #include <widget_install/task_encrypt_resource.h>
53 #include <widget_install/task_certificates.h>
54 #include <widget_install/task_plugins_copy.h>
56 #include <widget_install/widget_install_errors.h>
57 #include <widget_install/widget_install_context.h>
64 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
65 #include <dpl/wrt-dao-ro/global_config.h>
66 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
67 #include <dpl/localization/w3c_file_localization.h>
68 #include <libiriwrapper.h>
69 #include <pkg-manager/pkgmgr_signal.h>
70 #include <app_manager.h>
72 using namespace WrtDB;
74 namespace // anonymous
76 const char * const CONFIG_XML = "config.xml";
77 const char * const WITH_OSP_XML = "res/wgt/config.xml";
79 //allowed: a-z, A-Z, 0-9
80 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}$";
81 const int MAX_TIZENID_LENGTH = 10;
83 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
84 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
86 class InstallerTaskFail :
87 public DPL::TaskDecl<InstallerTaskFail>
95 ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred,
96 "Widget installation or update deferred!");
98 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
99 "Widget installation or update not allowed!");
104 InstallerTaskFail(bool deferred) :
105 DPL::TaskDecl<InstallerTaskFail>(this),
108 AddStep(&InstallerTaskFail::StepFail);
112 const std::string XML_EXTENSION = ".xml";
114 bool hasExtension(const std::string& filename, const std::string& extension) {
115 LogDebug("Looking for extension " << extension << " in: " << filename);
116 size_t fileLen = filename.length();
117 size_t extLen = extension.length();
118 if (fileLen < extLen) {
119 LogError("Filename " << filename << " is shorter than extension "
123 return (0 == filename.compare(fileLen-extLen, extLen, extension));
125 } // namespace anonymous
128 namespace WidgetInstall {
129 JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath,
130 const WidgetInstallationStruct &installerStruct) :
132 JobContextBase<WidgetInstallationStruct>(installerStruct),
133 m_exceptionCaught(Exceptions::Success)
135 // Check installation type (config.xml or widget.wgt)
136 bool browserRequest = hasExtension(widgetPath, XML_EXTENSION);
138 LogInfo("Hosted app installation: " << browserRequest);
141 gettimeofday(&tv, NULL);
142 srand(time(NULL) + tv.tv_usec);
144 m_installerContext.m_quiet = m_jobStruct.m_quiet;
148 m_installerContext.widgetConfig.pType = checkPackageType(widgetPath);
152 m_installerContext.widgetConfig.pType = WrtDB::PKG_TYPE_TIZEN_WEBAPP;
154 LogDebug("widgetPath:" << widgetPath);
156 ConfigParserData configData = getWidgetDataFromXML(widgetPath, browserRequest,
157 m_installerContext.widgetConfig.pType);
158 WidgetUpdateInfo update = detectWidgetUpdate(configData);
159 bool needEncryption = detectResourceEncryption(configData);
161 // Configure installation
162 ConfigureResult result = ConfigureInstallation(widgetPath, configData,
163 update, browserRequest);
165 if (result == ConfigureResult::Ok) {
166 LogInfo("Configure installation succeeded");
168 AddTask(new TaskRecovery(m_installerContext));
170 // Create installation tasks
171 if (!m_installerContext.locations->browserRequest()) {
172 AddTask(new TaskUnzip(m_installerContext));
174 AddTask(new TaskWidgetConfig(m_installerContext));
175 if (m_installerContext.locations->browserRequest()) {
176 AddTask(new TaskPrepareFiles(m_installerContext));
178 AddTask(new TaskCertify(m_installerContext));
179 if (needEncryption) {
180 AddTask(new TaskEncryptResource(m_installerContext));
182 AddTask(new TaskFileManipulation(m_installerContext));
183 // TODO: Update progress information for this task
185 AddTask(new TaskPrivateStorage(m_installerContext));
187 //This is sort of quick solution, because ACE verdicts are based upon
188 //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
190 AddTask(new TaskSmack(m_installerContext));
192 AddTask(new TaskManifestFile(m_installerContext));
193 AddTask(new TaskCertificates(m_installerContext));
194 if (m_installerContext.widgetConfig.pType ==
195 PKG_TYPE_TIZEN_WITHSVCAPP) {
196 AddTask(new TaskInstallOspsvc(m_installerContext));
198 AddTask(new TaskPluginsCopy(m_installerContext));
199 AddTask(new TaskDatabase(m_installerContext));
200 AddTask(new TaskAceCheck(m_installerContext));
201 } else if (result == ConfigureResult::Updated) {
202 LogInfo("Configure installation updated");
203 LogInfo("Widget Update");
205 if (!m_installerContext.locations->browserRequest()) {
206 AddTask(new TaskUnzip(m_installerContext));
208 AddTask(new TaskWidgetConfig(m_installerContext));
209 if (m_installerContext.locations->browserRequest()) {
210 AddTask(new TaskPrepareFiles(m_installerContext));
213 AddTask(new TaskCertify(m_installerContext));
214 AddTask(new TaskUpdateFiles(m_installerContext));
216 /* TODO : To backup file, save md5 values */
217 AddTask(new TaskSmack(m_installerContext));
219 AddTask(new TaskManifestFile(m_installerContext));
220 if (m_installerContext.widgetConfig.pType ==
221 PKG_TYPE_TIZEN_WITHSVCAPP) {
222 AddTask(new TaskInstallOspsvc(m_installerContext));
224 AddTask(new TaskRemoveBackupFiles(m_installerContext));
225 AddTask(new TaskPluginsCopy(m_installerContext));
226 AddTask(new TaskDatabase(m_installerContext));
227 AddTask(new TaskAceCheck(m_installerContext));
228 //TODO: remove widgetHandle from this task and move before database task
229 // by now widget handle is needed in ace check
230 // Any error in acecheck while update will break widget
232 } else if (result == ConfigureResult::Deferred) {
233 // Installation is deferred
234 LogInfo("Configure installation deferred");
236 AddTask(new InstallerTaskFail(true));
237 } else if (result == ConfigureResult::Failed) {
238 // Installation is not allowed to proceed due to widget update policy
239 LogWarning("Configure installation failed!");
241 AddTask(new InstallerTaskFail(false));
243 Assert(false && "Invalid configure result!");
247 std::string JobWidgetInstall::generateTizenId() {
248 std::string allowed("0123456789"
249 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
250 "abcdefghijklmnopqrstuvwxyz");
252 tizenId.resize(MAX_TIZENID_LENGTH);
253 for (int i = 0; i < MAX_TIZENID_LENGTH; ++i) {
254 tizenId[i] = allowed[rand() % allowed.length()];
259 bool JobWidgetInstall::setTizenId(
260 const WrtDB::ConfigParserData &configInfo, ConfigureResult result)
263 regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED);
265 if(!!configInfo.tizenId) {
266 LogDebug("Setting tizenId provided in config.xml: " << configInfo.tizenId);
267 if ((regexec(®, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(),
268 static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
269 ((stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/"
270 + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0)
271 && result != ConfigureResult::Updated))
273 //it is true when tizenId does not fit REG_TIZENID_PATTERN
274 LogError("tizen_id provided but not proper.");
278 m_installerContext.widgetConfig.pkgname = configInfo.tizenId;
281 std::string tizenId = generateTizenId();
283 // only for installation, not for update
284 if (result == ConfigureResult::Ok) {
285 //check if there is package with same name and if generate different name
286 std::string path = GlobalConfig::GetUserInstalledWidgetPath();
289 std::ostringstream newPath;
290 newPath << path << tizenId;
292 LogDebug("Checking if tizen id is unique");
294 if (stat(newPath.str().c_str(), &dirStat) == 0) {
295 //path exist, chose another one
296 tizenId = generateTizenId();
298 newPath << path << tizenId;
304 m_installerContext.widgetConfig.pkgname =
305 DPL::FromUTF8String(tizenId);
307 LogInfo("tizen_id name was generated by WRT: " << tizenId);
311 LogInfo("Tizen Id : " << m_installerContext.widgetConfig.pkgname);
312 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
316 DPL::OptionalString JobWidgetInstall::getNewTizenId() const
318 return m_installerContext.widgetConfig.pkgname;
321 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, bool browserRequest)
323 m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
324 widgetPath, browserRequest, m_installerContext.widgetConfig.pType);
326 LogInfo("widgetSource " << widgetPath);
329 JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
330 const std::string &widgetSource,
331 const WrtDB::ConfigParserData &configData,
332 const WidgetUpdateInfo &update,
336 "Widget install/update: incoming guid = '" <<
337 update.incomingGUID << "'");
339 "Widget install/update: incoming version = '" <<
340 update.incomingVersion << "'");
343 WidgetUpdateMode::Type updateTypeCheckBit;
344 JobWidgetInstall::ConfigureResult ret = ConfigureResult::Ok;
346 if (update.existingWidgetInfo.isExist == false) {
347 LogInfo("Widget info does not exist");
348 updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
350 LogInfo("Widget info exists. PkgName: " <<
351 update.existingWidgetInfo.pkgname);
353 DPL::OptionalString pkgname = update.existingWidgetInfo.pkgname;
355 if(pkgname.IsNull()) {
356 LogInfo("But package name doesn't exist");
357 return ConfigureResult::Failed;
360 LogInfo("Widget model exists. package name: " << pkgname);
362 // Check running state
363 int retval = APP_MANAGER_ERROR_NONE;
364 bool isRunning = false;
365 retval = app_manager_is_running(DPL::ToUTF8String(*pkgname).c_str(), &isRunning);
366 if (APP_MANAGER_ERROR_NONE != retval) {
367 LogError("Fail to get running state");
368 return ConfigureResult::Failed;
371 if (true == isRunning) {
372 // Must be deferred when update in progress
373 if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
375 "Widget is already running. Policy is update according to WAC");
377 return ConfigureResult::Deferred;
380 "Widget is already running. Policy is not update according to WAC");
381 LogInfo("Installation aborted: " << widgetSource);
383 return ConfigureResult::Failed;
387 m_installerContext.widgetConfig.pkgname = pkgname;
388 OptionalWidgetVersion existingVersion;
389 existingVersion = update.existingWidgetInfo.existingVersion;
390 OptionalWidgetVersion incomingVersion = update.incomingVersion;
392 updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
395 if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0) {
396 LogInfo("Whether widget policy allow proceed ok");
397 ret = ConfigureResult::Updated;
400 return ConfigureResult::Failed;
403 if (!setTizenId(configData, ret)) {
404 return ConfigureResult::Failed;
406 using namespace PackageManager;
407 LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname);
409 configureWidgetLocation(widgetSource, browserRequest);
411 // send start signal of pkgmgr
412 PkgmgrSignalSingleton::Instance().setPkgname(
414 *m_installerContext.widgetConfig.pkgname));
415 PkgmgrSignalSingleton::Instance().sendSignal(
417 PKGMGR_START_INSTALL);
420 // Init installer context
421 m_installerContext.installStep = InstallerContext::INSTALL_START;
422 m_installerContext.job = this;
423 m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
424 m_installerContext.widgetConfig.shareHref = std::string();
430 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
431 const OptionalWidgetVersion &existingVersion,
432 const OptionalWidgetVersion &incomingVersion) const
434 // Widget is installed, check versions
435 if (!existingVersion && !incomingVersion) {
436 return WidgetUpdateMode::ExistingVersionEqual;
437 } else if (!existingVersion && !!incomingVersion) {
438 return WidgetUpdateMode::ExistingVersionNewer;
439 } else if (!!existingVersion && !incomingVersion) {
440 return WidgetUpdateMode::ExistingVersionOlder;
442 LogInfo("Existing widget: version = '" << *existingVersion << "'");
444 if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
445 return WidgetUpdateMode::BothVersionsNotStd;
446 } else if (!existingVersion->IsWac()) {
447 return WidgetUpdateMode::ExistingVersionNotStd;
448 } else if (!incomingVersion->IsWac()) {
449 return WidgetUpdateMode::IncomingVersionNotStd;
451 // Both versions are WAC-comparable. Do compare.
452 if (*incomingVersion == *existingVersion) {
453 return WidgetUpdateMode::ExistingVersionEqual;
454 } else if (*incomingVersion > *existingVersion) {
455 return WidgetUpdateMode::ExistingVersionOlder;
457 return WidgetUpdateMode::ExistingVersionNewer;
463 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
464 const std::string &widgetSource,
465 bool fromBrowser, WrtDB::PkgType isOspsvc)
471 ConfigParserData configInfo;
474 parser.Parse(widgetSource,
476 new RootParser<WidgetParser>(configInfo,
477 DPL::FromUTF32String(
482 std::unique_ptr<DPL::ZipInput> zipFile(
483 new DPL::ZipInput(widgetSource));
485 std::unique_ptr<DPL::ZipInput::File> configFile;
487 // Open config.xml file
488 if (isOspsvc == PKG_TYPE_TIZEN_WITHSVCAPP) {
489 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
491 configFile.reset(zipFile->OpenFile(CONFIG_XML));
495 DPL::BinaryQueue buffer;
496 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
497 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
498 DPL::Copy(&inputAdapter, &outputAdapter);
499 parser.Parse(&buffer,
501 new RootParser<WidgetParser>(configInfo,
502 DPL::FromUTF32String(
508 Catch(DPL::ZipInput::Exception::OpenFailed)
510 LogError("Failed to open widget package");
511 return ConfigParserData();
513 Catch(DPL::ZipInput::Exception::OpenFileFailed)
515 LogError("Failed to open config.xml file");
516 return ConfigParserData();
518 Catch(DPL::CopyFailed)
520 LogError("Failed to extract config.xml file");
521 return ConfigParserData();
523 Catch(ElementParser::Exception::ParseError)
525 LogError("Failed to parse config.xml file");
526 return ConfigParserData();
530 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
531 const ConfigParserData &configInfo)
533 LogInfo("Checking up widget package for config.xml...");
535 DPL::OptionalString widgetGUID;
536 OptionalWidgetVersion widgetVersion;
539 widgetGUID = configInfo.widget_id;
541 if (widgetGUID.IsNull()) {
542 LogWarning("Installed widget has no GUID");
543 return WidgetUpdateInfo();
546 LogDebug("Installed widget GUID: " << *widgetGUID);
548 // Locate widget ID with this GUID
549 // Incoming widget version
550 if (!configInfo.version.IsNull()) {
552 DPL::Optional<WidgetVersion>(
553 WidgetVersion(*configInfo.version));
558 // Search widget handle by GUID
559 WidgetDAOReadOnly dao(widgetGUID);
560 return WidgetUpdateInfo(
563 WidgetUpdateInfo::ExistingWidgetInfo(
564 *dao.getPkgname(), dao.getVersion()));
566 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
568 // GUID isn't installed
569 return WidgetUpdateInfo(
572 WidgetUpdateInfo::ExistingWidgetInfo());
576 void JobWidgetInstall::SendProgress()
578 using namespace PackageManager;
579 if (GetProgressFlag() != false) {
580 if (getInstallerStruct().progressCallback != NULL) {
581 // send progress signal of pkgmgr
582 std::ostringstream percent;
583 percent << static_cast<int>(GetProgressPercent());
584 PkgmgrSignalSingleton::Instance().sendSignal(
588 LogDebug("Call widget install progressCallbak");
589 getInstallerStruct().progressCallback(getInstallerStruct().userParam,
590 GetProgressPercent(),GetProgressDescription());
595 void JobWidgetInstall::SendFinishedSuccess()
597 using namespace PackageManager;
598 // TODO : sync should move to separate task.
601 // remove widget install information file
602 unlink(m_installerContext.installInfo.c_str());
605 JobWidgetInstall::displayWidgetInfo();
607 DPL::OptionalString tizenId = getNewTizenId();
609 // send signal of pkgmgr
610 PkgmgrSignalSingleton::Instance().sendSignal(
614 LogDebug("Call widget install successfinishedCallback");
615 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
616 tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), Exceptions::Success);
619 void JobWidgetInstall::SendFinishedFailure()
621 using namespace PackageManager;
622 // remove widget install information file
623 unlink(m_installerContext.installInfo.c_str());
625 LogError("Error in installation step: " << m_exceptionCaught);
626 LogError("Message: " << m_exceptionMessage);
627 DPL::OptionalString tizenId = getNewTizenId();
629 LogDebug("Call widget install failure finishedCallback");
631 // send signal of pkgmgr
632 PkgmgrSignalSingleton::Instance().sendSignal(
636 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
637 tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), m_exceptionCaught);
640 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
642 m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
643 m_exceptionMessage = e.GetMessage();
646 void JobWidgetInstall::displayWidgetInfo()
648 WidgetDAOReadOnly dao(m_installerContext.locations->getPkgname());
650 std::ostringstream out;
651 WidgetLocalizedInfo localizedInfo =
652 W3CFileLocalization::getLocalizedInfo(*dao.getPkgname());
655 "===================================== INSTALLED WIDGET INFO ========="\
656 "============================";
657 out << std::endl << "Name: " << localizedInfo.name;
658 out << std::endl << "PkgName: " << dao.getPkgname();
659 WidgetSize size = dao.getPreferredSize();
660 out << std::endl << "Width: " << size.width;
661 out << std::endl << "Height: " << size.height;
662 out << std::endl << "Start File: " <<
663 W3CFileLocalization::getStartFile(*dao.getPkgname());
664 out << std::endl << "Version: " << dao.getVersion();
665 out << std::endl << "Licence: " <<
666 localizedInfo.license;
667 out << std::endl << "Licence Href: " <<
668 localizedInfo.licenseHref;
669 out << std::endl << "Description: " <<
670 localizedInfo.description;
671 out << std::endl << "Widget Id: " << dao.getGUID();
672 out << std::endl << "Widget recognized: " << dao.isRecognized();
673 out << std::endl << "Widget wac signed: " << dao.isWacSigned();
674 out << std::endl << "Widget distributor signed: " <<
675 dao.isDistributorSigned();
676 out << std::endl << "Widget trusted: " << dao.isTrusted();
678 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(*dao.getPkgname());
679 DPL::OptionalString iconSrc =
680 !!icon ? icon->src : DPL::OptionalString::Null;
681 out << std::endl << "Icon: " << iconSrc;
683 out << std::endl << "Preferences:";
685 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
688 out << std::endl << " Key: " <<
690 out << std::endl << " Readonly: " <<
695 out << std::endl << "Features:";
697 WidgetFeatureSet list = dao.getFeaturesList();
700 out << std::endl << " Name: " << it->name;
701 out << std::endl << " Required: " << it->required;
702 out << std::endl << " Params:";
711 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
712 const std::string &widgetSource)
714 using namespace WrtDB;
716 PackagingType pType = PKG_TYPE_UNKNOWN;
717 std::unique_ptr<DPL::ZipInput> zipFile;
722 zipFile.reset(new DPL::ZipInput(widgetSource));
725 Catch(DPL::ZipInput::Exception::OpenFailed)
727 LogError("Failed to open widget package");
728 return PKG_TYPE_UNKNOWN;
733 // Open config.xml file in package root
734 std::unique_ptr<DPL::ZipInput::File> configFile(
735 zipFile->OpenFile(CONFIG_XML));
736 pType = PKG_TYPE_TIZEN_WEBAPP;
738 Catch(DPL::ZipInput::Exception::OpenFileFailed)
740 LogWarning("Could not find ./config.xml");
745 // Open config.xml file in package root
746 std::unique_ptr<DPL::ZipInput::File> configFile(
747 zipFile->OpenFile(WITH_OSP_XML));
748 if (pType == PKG_TYPE_TIZEN_WEBAPP) {
749 LogWarning("Two config.xml's found. Application type is unknown.");
750 return PKG_TYPE_UNKNOWN;
753 pType = PKG_TYPE_TIZEN_WITHSVCAPP;
755 Catch(DPL::ZipInput::Exception::OpenFileFailed)
757 LogWarning("Could not find ./res/wgt/config.xml");
760 if (pType == PKG_TYPE_UNKNOWN) {
761 LogWarning("config.xml not found. Application type is unknown.");
766 bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
768 FOREACH(it, configData.settingsList)
770 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
771 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
772 LogDebug("resource need encryption");
779 } //namespace WidgetInstall