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
31 #include <dpl/noncopyable.h>
32 #include <dpl/abstract_waitable_input_adapter.h>
33 #include <dpl/abstract_waitable_output_adapter.h>
34 #include <dpl/zip_input.h>
35 #include <dpl/binary_queue.h>
37 #include <dpl/assert.h>
38 #include <dpl/sstream.h>
39 #include <dpl/file_input.h>
40 #include <dpl/utils/wrt_utility.h>
41 #include <dpl/utils/path.h>
42 #include <dpl/wrt-dao-ro/common_dao_types.h>
43 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
44 #include <dpl/wrt-dao-ro/global_config.h>
45 #include <dpl/wrt-dao-ro/config_parser_data.h>
46 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
47 #include <dpl/localization/w3c_file_localization.h>
49 #include <libiriwrapper.h>
50 #include <pkg-manager/pkgmgr_signal.h>
51 #include <app_manager.h>
53 #include "root_parser.h"
54 #include "widget_parser.h"
55 #include "parser_runner.h"
56 #include <widget_install/job_widget_install.h>
57 #include <widget_install/task_certify.h>
58 #include <widget_install/task_certify_level.h>
59 #include <widget_install/task_widget_config.h>
60 #include <widget_install/task_file_manipulation.h>
61 #include <widget_install/task_ace_check.h>
62 #include <widget_install/task_smack.h>
63 #include <widget_install/task_manifest_file.h>
64 #include <widget_install/task_prepare_files.h>
65 #include <widget_install/task_recovery.h>
66 #include <widget_install/task_install_ospsvc.h>
67 #include <widget_install/task_update_files.h>
68 #include <widget_install/task_database.h>
69 #include <widget_install/task_remove_backup.h>
70 #include <widget_install/task_encrypt_resource.h>
71 #include <widget_install/task_pkg_info_update.h>
72 #include <widget_install/task_commons.h>
73 #include <widget_install/task_prepare_reinstall.h>
75 #include <widget_install/widget_install_errors.h>
76 #include <widget_install/widget_install_context.h>
77 #include <widget_install_to_external.h>
78 #include <widget_install/widget_unzip.h>
80 using namespace WrtDB;
81 using namespace Jobs::Exceptions;
83 namespace // anonymous
85 const char * const CONFIG_XML = "config.xml";
86 const char * const WITH_OSP_XML = "res/wgt/config.xml";
87 const char * const OSP_MANIFEST_XML = "info/manifest.xml";
89 //allowed: a-z, A-Z, 0-9
90 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
91 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
92 const size_t PACKAGE_ID_LENGTH = 10;
94 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
95 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
96 static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
97 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
99 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
102 const std::string XML_EXTENSION = ".xml";
104 bool hasExtension(const std::string& filename, const std::string& extension)
106 LogDebug("Looking for extension " << extension << " in: " << filename);
107 size_t fileLen = filename.length();
108 size_t extLen = extension.length();
109 if (fileLen < extLen) {
110 LogError("Filename " << filename << " is shorter than extension "
114 return (0 == filename.compare(fileLen - extLen, extLen, extension));
116 } // namespace anonymous
119 namespace WidgetInstall {
120 class InstallerTaskFail :
121 public DPL::TaskDecl<InstallerTaskFail>
124 ConfigureResult m_result;
128 if (m_result == ConfigureResult::Failed_InvalidConfig) {
129 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
131 } else if (m_result == ConfigureResult::Failed_OpenZipError) {
132 ThrowMsg(Jobs::WidgetInstall::Exceptions::OpenZipFailed,
133 "can't open wgt file");
134 } else if (m_result == ConfigureResult::Failed_UnzipError) {
135 ThrowMsg(Jobs::WidgetInstall::Exceptions::ExtractFileFailed,
136 "can't extract wgt file");
137 } else if (m_result == ConfigureResult::Failed_LowerVersion) {
138 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion,
139 "package version is lower than installed version");
140 } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) {
141 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
142 "package is already installed");
143 } else if (m_result == ConfigureResult::Failed_WidgetRunning) {
144 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
145 "widget is running");
146 } else if (m_result == ConfigureResult::Failed_DrmError) {
147 ThrowMsg(Jobs::WidgetInstall::Exceptions::DrmDecryptFailed,
149 } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) {
150 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
151 "RDS update failed");
153 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
154 "widget installation or update not allowed!");
159 InstallerTaskFail(ConfigureResult result) :
160 DPL::TaskDecl<InstallerTaskFail>(this),
163 AddStep(&InstallerTaskFail::StepFail);
167 JobWidgetInstall::JobWidgetInstall(
168 std::string const &widgetPath,
169 const WidgetInstallationStruct &
172 JobContextBase<WidgetInstallationStruct>(installerStruct),
173 m_exceptionCaught(Jobs::Exceptions::Success)
175 m_installerContext.mode = m_jobStruct.m_installMode;
176 getInstallerStruct().pkgmgrInterface->sendSignal(
178 PKGMGR_START_INSTALL);
179 getInstallerStruct().pkgmgrInterface->sendSignal(
182 ConfigureResult result = prepareInstallation(widgetPath);
184 if (result == ConfigureResult::Ok) {
185 LogDebug("Configure installation succeeded");
186 m_installerContext.job->SetProgressFlag(true);
188 AddTask(new TaskRecovery(m_installerContext));
190 AddTask(new TaskWidgetConfig(m_installerContext));
191 if (m_installerContext.widgetConfig.packagingType ==
192 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
194 AddTask(new TaskPrepareFiles(m_installerContext));
196 AddTask(new TaskCertify(m_installerContext));
197 AddTask(new TaskCertifyLevel(m_installerContext));
198 if (m_needEncryption) {
199 AddTask(new TaskEncryptResource(m_installerContext));
201 AddTask(new TaskFileManipulation(m_installerContext));
202 AddTask(new TaskManifestFile(m_installerContext));
203 if (m_installerContext.widgetConfig.packagingType ==
204 PKG_TYPE_HYBRID_WEB_APP)
206 AddTask(new TaskInstallOspsvc(m_installerContext));
208 AddTask(new TaskDatabase(m_installerContext));
209 AddTask(new TaskAceCheck(m_installerContext));
210 AddTask(new TaskSmack(m_installerContext));
211 AddTask(new TaskPkgInfoUpdate(m_installerContext));
212 } else if (result == ConfigureResult::Updated) {
213 LogDebug("Configure installation updated");
214 LogDebug("Widget Update");
215 m_installerContext.job->SetProgressFlag(true);
217 if (m_installerContext.mode.command ==
218 InstallMode::Command::REINSTALL)
220 AddTask(new TaskPrepareReinstall(m_installerContext));
223 AddTask(new TaskWidgetConfig(m_installerContext));
225 if (m_installerContext.widgetConfig.packagingType ==
226 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
228 AddTask(new TaskPrepareFiles(m_installerContext));
231 AddTask(new TaskCertify(m_installerContext));
232 AddTask(new TaskCertifyLevel(m_installerContext));
233 if (m_needEncryption) {
234 AddTask(new TaskEncryptResource(m_installerContext));
236 if (m_installerContext.mode.extension !=
237 InstallMode::ExtensionType::DIR) {
238 AddTask(new TaskUpdateFiles(m_installerContext));
239 AddTask(new TaskFileManipulation(m_installerContext));
242 AddTask(new TaskManifestFile(m_installerContext));
243 if (m_installerContext.widgetConfig.packagingType ==
244 PKG_TYPE_HYBRID_WEB_APP)
246 AddTask(new TaskInstallOspsvc(m_installerContext));
248 AddTask(new TaskDatabase(m_installerContext));
249 AddTask(new TaskAceCheck(m_installerContext));
250 //TODO: remove widgetHandle from this task and move before database task
251 // by now widget handle is needed in ace check
252 // Any error in acecheck while update will break widget
253 AddTask(new TaskSmack(m_installerContext));
254 AddTask(new TaskRemoveBackupFiles(m_installerContext));
255 AddTask(new TaskPkgInfoUpdate(m_installerContext));
257 // Installation is not allowed to proceed due to widget update policy
258 LogWarning("Configure installation failed!");
260 AddTask(new InstallerTaskFail(result));
264 ConfigureResult JobWidgetInstall::prepareInstallation(
265 const std::string &widgetPath)
267 ConfigureResult result;
268 m_needEncryption = false;
272 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
273 if (m_installerContext.mode.command ==
274 InstallMode::Command::REINSTALL) {
275 std::ostringstream tempPathBuilder;
276 tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
277 tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
278 tempPathBuilder << "/";
279 tempPathBuilder << widgetPath;
280 tempDir = tempPathBuilder.str();;
282 tempDir = widgetPath;
286 Jobs::WidgetInstall::createTempPath(
287 m_installerContext.mode.rootPath ==
288 InstallMode::RootPath::RO);
289 WidgetUnzip wgtUnzip;
290 wgtUnzip.unzipWgtFile(widgetPath, tempDir);
293 LogDebug("widgetPath:" << widgetPath);
294 LogDebug("tempPath:" << tempDir);
296 m_installerContext.widgetConfig.packagingType =
297 checkPackageType(widgetPath, tempDir);
298 ConfigParserData configData = getWidgetDataFromXML(
301 m_installerContext.widgetConfig.packagingType,
302 m_installerContext.mode.command == InstallMode::Command::REINSTALL);
303 LogDebug("widget packaging type : " <<
304 m_installerContext.widgetConfig.packagingType.pkgType);
306 setTizenId(configData);
307 setApplicationType(configData);
308 m_needEncryption = detectResourceEncryption(configData);
309 setInstallLocationType(configData);
310 m_installerContext.callerPkgId =
311 DPL::FromUTF8String(getInstallerStruct().pkgmgrInterface->getCallerId());
312 LogDebug("Caller Package Id : " << m_installerContext.callerPkgId);
314 // Configure installation
315 result = ConfigureInstallation(widgetPath, configData, tempDir);
317 Catch(Exceptions::OpenZipFailed)
319 LogError("Failed to unzip for widget");
320 result = ConfigureResult::Failed_OpenZipError;
322 Catch(Exceptions::ExtractFileFailed)
324 LogError("Failed to unzip for widget");
325 result = ConfigureResult::Failed_UnzipError;
327 Catch(Exceptions::DrmDecryptFailed)
329 LogError("Failed to unzip for widget");
330 result = ConfigureResult::Failed_DrmError;
332 Catch(Exceptions::MissingConfig)
334 LogError("Failed to localize config.xml");
335 result = ConfigureResult::Failed_InvalidConfig;
337 Catch(Exceptions::WidgetConfigFileInvalid)
339 LogError("Invalid configuration file");
340 result = ConfigureResult::Failed_InvalidConfig;
342 Catch(DPL::Exception)
344 LogError("Unknown exception");
345 result = ConfigureResult::Failed;
351 void JobWidgetInstall::setTizenId(
352 const WrtDB::ConfigParserData &configInfo)
354 bool shouldMakeAppid = false;
355 using namespace PackageManager;
356 if (!!configInfo.tizenAppId) {
357 LogDebug("Setting tizenAppId provided in config.xml: " <<
358 configInfo.tizenAppId);
360 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
362 if (!!configInfo.tizenPkgId) {
363 LogDebug("Setting tizenPkgId provided in config.xml: " <<
364 configInfo.tizenPkgId);
366 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
368 DPL::String appid = *configInfo.tizenAppId;
369 if (appid.length() > PACKAGE_ID_LENGTH) {
370 m_installerContext.widgetConfig.tzPkgid =
371 appid.substr(0, PACKAGE_ID_LENGTH);
373 //old version appid only has 10byte random character is able to install for a while.
374 //this case appid equal pkgid.
375 m_installerContext.widgetConfig.tzPkgid =
376 *configInfo.tizenAppId;
377 shouldMakeAppid = true;
381 shouldMakeAppid = true;
382 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
383 LogDebug("Checking if pkg id is unique");
385 if (!validateTizenPackageID(pkgId)) {
386 //path exist, chose another one
387 pkgId = WidgetDAOReadOnly::generatePkgId();
392 m_installerContext.widgetConfig.tzPkgid = pkgId;
393 LogDebug("tizen_id name was generated by WRT: " <<
394 m_installerContext.widgetConfig.tzPkgid);
397 if (shouldMakeAppid == true) {
398 DPL::OptionalString name;
399 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
401 FOREACH(localizedData, configInfo.localizedDataSet)
403 Locale i = localizedData->first;
404 if (!!defaultLocale) {
405 if (defaultLocale == i) {
406 name = localizedData->second.name;
410 name = localizedData->second.name;
415 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
416 LogDebug("Regcomp failed");
419 LogDebug("Name : " << name);
420 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
421 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
423 // TODO : generate name move to wrt-commons
424 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
425 std::ostringstream genName;
427 gettimeofday(&tv, NULL);
428 unsigned int seed = time(NULL) + tv.tv_usec;
430 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
431 name = DPL::FromUTF8String(genName.str());
432 LogDebug("name was generated by WRT");
435 LogDebug("Name : " << name);
436 std::ostringstream genid;
437 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
438 LogDebug("tizen appid was generated by WRT : " << genid.str());
440 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
441 NormalizeAndTrimSpaceString(appid);
442 m_installerContext.widgetConfig.tzAppid = *appid;
445 // send start signal of pkgmgr
446 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
450 LogDebug("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
451 LogDebug("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
452 LogDebug("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
455 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
456 const std::string& tempPath)
458 m_installerContext.locations =
459 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
461 widgetPath, tempPath,
462 m_installerContext.widgetConfig.packagingType,
463 m_installerContext.mode.rootPath ==
464 InstallMode::RootPath::RO,
465 m_installerContext.mode.extension);
466 m_installerContext.locations->registerAppid(
467 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
469 LogDebug("widgetSource " << widgetPath);
472 ConfigureResult JobWidgetInstall::ConfigureInstallation(
473 const std::string &widgetSource,
474 const WrtDB::ConfigParserData &configData,
475 const std::string &tempPath)
477 ConfigureResult result = ConfigureResult::Failed;
478 WidgetUpdateInfo update;
480 // checking installed web application
482 // checking existing application is installed
483 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
484 // no excpetion means, it isn't update mode
485 getInstallerStruct().pkgmgrInterface->sendSignal(
487 PKGMGR_START_UPDATE);
489 update = detectWidgetUpdate(configData,
490 m_installerContext.widgetConfig.tzAppid);
491 result = checkWidgetUpdate(update);
492 if (result != ConfigureResult::Updated) {
493 // Already installed TizenAppId. return failed
494 return ConfigureResult::Failed_AlreadyInstalled;
496 if (!checkSupportRDSUpdate(configData)) {
497 return ConfigureResult::Failed_NotSupportRDSUpdate;
499 m_installerContext.isUpdateMode = true;
501 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
502 result = ConfigureResult::Ok;
503 m_installerContext.isUpdateMode = false;
505 if (!validateTizenApplicationID(
506 m_installerContext.widgetConfig.tzAppid))
508 LogError("tizen application ID is already used");
509 return ConfigureResult::Failed_InvalidConfig;
511 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
512 LogError("tizen package ID is already used");
513 return ConfigureResult::Failed_AlreadyInstalled;
517 configureWidgetLocation(widgetSource, tempPath);
519 // Init installer context
520 m_installerContext.installStep = InstallerContext::INSTALL_START;
521 m_installerContext.job = this;
522 m_installerContext.widgetConfig.shareHref = std::string();
527 bool JobWidgetInstall::validateTizenApplicationID(
528 const WrtDB::TizenAppId &tizenAppId)
530 LogDebug("tizen application ID = [" << tizenAppId << "]");
533 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
534 LogDebug("Regcomp failed");
537 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
547 bool JobWidgetInstall::validateTizenPackageID(
548 const WrtDB::TizenPkgId &tizenPkgId)
550 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
552 std::string installPath =
553 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
557 if ((stat(installPath.c_str(), &dirStat) == 0))
564 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
565 const WidgetUpdateInfo &update)
567 if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
568 return ConfigureResult::Failed;
571 LogDebug("existing version = '" << update.existingVersion);
572 LogDebug("incoming version = '" << update.incomingVersion);
573 LogDebug("Tizen AppID = " << update.tzAppId);
575 // Check running state
576 bool isRunning = false;
578 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
580 if (APP_MANAGER_ERROR_NONE != ret) {
581 LogError("Fail to get running state");
582 return ConfigureResult::Failed_WidgetRunning;
585 if (true == isRunning) {
586 // get app_context for running application
587 // app_context must be released with app_context_destroy
588 app_context_h appCtx = NULL;
590 app_manager_get_app_context(
591 DPL::ToUTF8String(update.tzAppId).c_str(),
593 if (APP_MANAGER_ERROR_NONE != ret) {
594 LogError("Fail to get app_context");
595 return ConfigureResult::Failed_WidgetRunning;
598 // terminate app_context_h
599 ret = app_manager_terminate_app(appCtx);
600 if (APP_MANAGER_ERROR_NONE != ret) {
601 LogError("Fail to terminate running application");
602 app_context_destroy(appCtx);
603 return ConfigureResult::Failed_WidgetRunning;
605 app_context_destroy(appCtx);
606 // app_manager_terminate_app isn't sync API
607 // wait until application isn't running (50ms * 100)
608 bool isStillRunning = true;
609 int checkingloop = 100;
610 struct timespec duration = { 0, 50 * 1000 * 1000 };
611 while (--checkingloop >= 0) {
612 nanosleep(&duration, NULL);
614 app_manager_is_running(
615 DPL::ToUTF8String(update.tzAppId).c_str(),
617 if (APP_MANAGER_ERROR_NONE != ret) {
618 LogError("Fail to get running state");
619 return ConfigureResult::Failed_WidgetRunning;
621 if (!isStillRunning) {
625 if (isStillRunning) {
626 LogError("Fail to terminate running application");
627 return ConfigureResult::Failed_WidgetRunning;
629 LogDebug("terminate application");
633 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
635 if (!!update.existingVersion ||
636 m_installerContext.mode.extension ==
637 InstallMode::ExtensionType::DIR) {
638 return ConfigureResult::Updated;
641 return ConfigureResult::Failed;
644 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
645 const std::string &widgetSource,
646 const std::string &tempPath,
647 WrtDB::PackagingType pkgType,
652 ConfigParserData configInfo;
655 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
656 parser.Parse(widgetSource,
658 new RootParser<WidgetParser>(configInfo,
659 DPL::FromUTF32String(
662 std::string configFile;
663 configFile = tempPath + "/" + CONFIG_XML;
664 if (!WrtUtilFileExists(configFile)) {
665 configFile = tempPath + "/" + WITH_OSP_XML;
669 // checking RDS data directory
670 if (access(configFile.c_str(), F_OK) != 0) {
671 std::string tzAppId =
672 widgetSource.substr(widgetSource.find_last_of("/")+1);
673 WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
674 configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
676 configFile += WITH_OSP_XML;
680 if(!DPL::Utils::Path(configFile).Exists())
682 ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
685 parser.Parse(configFile,
687 new RootParser<WidgetParser>(configInfo,
693 Catch(ElementParser::Exception::ParseError)
695 LogError("Failed to parse config.xml file");
696 return ConfigParserData();
698 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
700 LogError("Failed to find installed widget - give proper tizenId");
701 return ConfigParserData();
703 Catch(Exceptions::WidgetConfigFileNotFound){
704 LogError("Failed to find config.xml");
705 return ConfigParserData();
711 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
712 const ConfigParserData &configInfo,
713 const WrtDB::TizenAppId &tizenId)
715 LogDebug("Checking up widget package for config.xml...");
716 OptionalWidgetVersion incomingVersion;
718 if (!configInfo.version.IsNull()) {
720 DPL::Optional<WidgetVersion>(
721 WidgetVersion(*configInfo.version));
724 WidgetDAOReadOnly dao(tizenId);
726 OptionalWidgetVersion optVersion;
727 DPL::OptionalString version = dao.getVersion();
728 if (!version.IsNull()) {
729 optVersion = OptionalWidgetVersion(WidgetVersion(*version));
732 return WidgetUpdateInfo(
738 void JobWidgetInstall::SendProgress()
740 using namespace PackageManager;
741 if (GetProgressFlag() != false) {
742 if (getInstallerStruct().progressCallback != NULL) {
743 // send progress signal of pkgmgr
744 std::ostringstream percent;
745 percent << static_cast<int>(GetProgressPercent());
746 getInstallerStruct().pkgmgrInterface->sendSignal(
750 LogDebug("Call widget install progressCallbak");
751 getInstallerStruct().progressCallback(
752 getInstallerStruct().userParam,
753 GetProgressPercent(),
754 GetProgressDescription());
759 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
761 using namespace PackageManager;
762 if (GetProgressFlag() != false) {
763 if (getInstallerStruct().progressCallback != NULL) {
764 // send progress signal of pkgmgr
765 getInstallerStruct().pkgmgrInterface->sendSignal(
772 void JobWidgetInstall::SendFinishedSuccess()
774 using namespace PackageManager;
775 // TODO : sync should move to separate task.
778 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
779 if (m_installerContext.isUpdateMode) {
780 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
782 WidgetInstallToExtSingleton::Instance().postInstallation(true);
784 WidgetInstallToExtSingleton::Instance().deinitialize();
787 // remove widget install information file
788 unlink(m_installerContext.installInfo.c_str());
791 JobWidgetInstall::displayWidgetInfo();
793 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
795 // send signal of pkgmgr
796 getInstallerStruct().pkgmgrInterface->sendSignal(
800 LogDebug("Call widget install successfinishedCallback");
801 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
803 tizenId), Jobs::Exceptions::Success);
806 void JobWidgetInstall::SendFinishedFailure()
808 using namespace PackageManager;
809 // remove widget install information file
810 unlink(m_installerContext.installInfo.c_str());
812 LogError("Error number: " << m_exceptionCaught);
813 LogError("Message: " << m_exceptionMessage);
814 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
816 LogDebug("Call widget install failure finishedCallback");
817 std::stringstream errorNum;
818 errorNum << m_exceptionCaught;
820 // send signal of pkgmgr
821 getInstallerStruct().pkgmgrInterface->sendSignal(
825 getInstallerStruct().pkgmgrInterface->sendSignal(
829 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
831 tizenId), m_exceptionCaught);
834 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
836 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
837 m_exceptionMessage = e.GetMessage();
840 void JobWidgetInstall::displayWidgetInfo()
842 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
844 std::ostringstream out;
845 WidgetLocalizedInfo localizedInfo =
846 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
849 "===================================== INSTALLED WIDGET INFO =========" \
850 "============================";
851 out << std::endl << "Name: " << localizedInfo.name;
852 out << std::endl << "AppId: " << dao.getTzAppId();
853 WidgetSize size = dao.getPreferredSize();
854 out << std::endl << "Width: " << size.width;
855 out << std::endl << "Height: " << size.height;
856 out << std::endl << "Start File: " <<
857 W3CFileLocalization::getStartFile(dao.getTzAppId());
858 out << std::endl << "Version: " << dao.getVersion();
859 out << std::endl << "Licence: " <<
860 localizedInfo.license;
861 out << std::endl << "Licence Href: " <<
862 localizedInfo.licenseHref;
863 out << std::endl << "Description: " <<
864 localizedInfo.description;
865 out << std::endl << "Widget Id: " << dao.getGUID();
866 out << std::endl << "Widget recognized: " << dao.isRecognized();
867 out << std::endl << "Widget distributor signed: " <<
868 dao.isDistributorSigned();
869 out << std::endl << "Widget trusted: " << dao.isTrusted();
871 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
872 DPL::OptionalString iconSrc =
873 !!icon ? icon->src : DPL::OptionalString::Null;
874 out << std::endl << "Icon: " << iconSrc;
876 out << std::endl << "Preferences:";
878 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
881 out << std::endl << " Key: " <<
883 out << std::endl << " Readonly: " <<
888 out << std::endl << "Features:";
890 WidgetFeatureSet list = dao.getFeaturesList();
893 out << std::endl << " Name: " << it->name;
902 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
903 const std::string &widgetSource,
904 const std::string &tempPath)
906 if (hasExtension(widgetSource, XML_EXTENSION)) {
907 LogDebug("Hosted app installation");
908 return PKG_TYPE_HOSTED_WEB_APP;
911 std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
912 if (WrtUtilFileExists(configFile)) {
913 return PKG_TYPE_HYBRID_WEB_APP;
916 return PKG_TYPE_NOMAL_WEB_APP;
919 void JobWidgetInstall::setApplicationType(
920 const WrtDB::ConfigParserData &configInfo)
922 AppType widgetAppType = APP_TYPE_UNKNOWN;
923 FOREACH(iterator, configInfo.nameSpaces) {
924 LogDebug("namespace = [" << *iterator << "]");
926 if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
927 if (widgetAppType != APP_TYPE_UNKNOWN &&
928 widgetAppType != APP_TYPE_TIZENWEBAPP)
930 LogError("To many namespaces declared in configuration fileA.");
931 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
932 "Config.xml has more than one valid namespace");
934 widgetAppType = APP_TYPE_TIZENWEBAPP;
936 LogDebug("Namespace ignored.");
940 m_installerContext.widgetConfig.webAppType = widgetAppType;
942 LogDebug("type = [" <<
943 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
947 bool JobWidgetInstall::detectResourceEncryption(
948 const WrtDB::ConfigParserData &configData)
950 FOREACH(it, configData.settingsList)
952 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
953 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
955 LogDebug("resource need encryption");
962 void JobWidgetInstall::setInstallLocationType(
963 const WrtDB::ConfigParserData & configData)
965 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
966 if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) {
967 FOREACH(it, configData.settingsList) {
968 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
970 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
972 LogDebug("This widget will be installed to sd card");
973 m_installerContext.locationType =
974 INSTALL_LOCATION_TYPE_EXTERNAL;
980 bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
983 if (m_installerContext.mode.command ==
984 InstallMode::Command::REINSTALL)
986 DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
987 DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
989 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
990 WrtDB::WidgetSettings widgetSettings;
991 dao.getWidgetSettings(widgetSettings);
993 FOREACH(it, widgetSettings) {
994 if (it->settingName == SETTING_VALUE_ENCRYPTION) {
995 dbValue = it->settingValue;
999 FOREACH(data, configInfo.settingsList)
1001 if (data->m_name == SETTING_VALUE_ENCRYPTION)
1003 configValue = data->m_value;
1006 if (configValue != dbValue) {
1007 LogError("Not Support RDS mode because of encryption setting");
1014 } //namespace WidgetInstall