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_widget_config.h>
59 #include <widget_install/task_file_manipulation.h>
60 #include <widget_install/task_ace_check.h>
61 #include <widget_install/task_smack.h>
62 #include <widget_install/task_manifest_file.h>
63 #include <widget_install/task_prepare_files.h>
64 #include <widget_install/task_recovery.h>
65 #include <widget_install/task_install_ospsvc.h>
66 #include <widget_install/task_update_files.h>
67 #include <widget_install/task_database.h>
68 #include <widget_install/task_remove_backup.h>
69 #include <widget_install/task_encrypt_resource.h>
70 #include <widget_install/task_certificates.h>
71 #include <widget_install/task_commons.h>
72 #include <widget_install/task_prepare_reinstall.h>
74 #include <widget_install/widget_install_errors.h>
75 #include <widget_install/widget_install_context.h>
76 #include <widget_install_to_external.h>
77 #include <widget_install/widget_unzip.h>
79 using namespace WrtDB;
80 using namespace Jobs::Exceptions;
82 namespace // anonymous
84 const char * const CONFIG_XML = "config.xml";
85 const char * const WITH_OSP_XML = "res/wgt/config.xml";
86 const char * const OSP_MANIFEST_XML = "info/manifest.xml";
88 //allowed: a-z, A-Z, 0-9
89 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
90 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
91 const size_t PACKAGE_ID_LENGTH = 10;
93 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
94 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
95 static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
96 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
98 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
101 const std::string XML_EXTENSION = ".xml";
103 bool hasExtension(const std::string& filename, const std::string& extension)
105 LogDebug("Looking for extension " << extension << " in: " << filename);
106 size_t fileLen = filename.length();
107 size_t extLen = extension.length();
108 if (fileLen < extLen) {
109 LogError("Filename " << filename << " is shorter than extension "
113 return (0 == filename.compare(fileLen - extLen, extLen, extension));
115 } // namespace anonymous
118 namespace WidgetInstall {
119 class InstallerTaskFail :
120 public DPL::TaskDecl<InstallerTaskFail>
123 ConfigureResult m_result;
127 if (m_result == ConfigureResult::Failed_InvalidConfig) {
128 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
130 } else if (m_result == ConfigureResult::Failed_OpenZipError) {
131 ThrowMsg(Jobs::WidgetInstall::Exceptions::OpenZipFailed,
132 "can't open wgt file");
133 } else if (m_result == ConfigureResult::Failed_UnzipError) {
134 ThrowMsg(Jobs::WidgetInstall::Exceptions::ExtractFileFailed,
135 "can't extract wgt file");
136 } else if (m_result == ConfigureResult::Failed_LowerVersion) {
137 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion,
138 "package version is lower than installed version");
139 } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) {
140 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
141 "package is already installed");
142 } else if (m_result == ConfigureResult::Failed_WidgetRunning) {
143 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
144 "widget is running");
145 } else if (m_result == ConfigureResult::Failed_DrmError) {
146 ThrowMsg(Jobs::WidgetInstall::Exceptions::DrmDecryptFailed,
148 } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) {
149 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
150 "RDS update failed");
152 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
153 "widget installation or update not allowed!");
158 InstallerTaskFail(ConfigureResult result) :
159 DPL::TaskDecl<InstallerTaskFail>(this),
162 AddStep(&InstallerTaskFail::StepFail);
166 JobWidgetInstall::JobWidgetInstall(
167 std::string const &widgetPath,
168 const WidgetInstallationStruct &
171 JobContextBase<WidgetInstallationStruct>(installerStruct),
172 m_exceptionCaught(Jobs::Exceptions::Success)
174 m_installerContext.mode = m_jobStruct.m_installMode;
175 ConfigureResult result = prepareInstallation(widgetPath);
177 if (result == ConfigureResult::Ok) {
178 LogInfo("Configure installation succeeded");
179 m_installerContext.job->SetProgressFlag(true);
181 AddTask(new TaskRecovery(m_installerContext));
183 AddTask(new TaskWidgetConfig(m_installerContext));
184 if (m_installerContext.widgetConfig.packagingType ==
185 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
187 AddTask(new TaskPrepareFiles(m_installerContext));
189 AddTask(new TaskCertify(m_installerContext));
190 if (m_needEncryption) {
191 AddTask(new TaskEncryptResource(m_installerContext));
194 AddTask(new TaskFileManipulation(m_installerContext));
195 AddTask(new TaskManifestFile(m_installerContext));
196 if (m_installerContext.widgetConfig.packagingType ==
197 PKG_TYPE_HYBRID_WEB_APP)
199 AddTask(new TaskInstallOspsvc(m_installerContext));
201 AddTask(new TaskCertificates(m_installerContext));
202 AddTask(new TaskDatabase(m_installerContext));
203 AddTask(new TaskAceCheck(m_installerContext));
204 AddTask(new TaskSmack(m_installerContext));
205 } else if (result == ConfigureResult::Updated) {
206 LogInfo("Configure installation updated");
207 LogInfo("Widget Update");
208 m_installerContext.job->SetProgressFlag(true);
210 if (m_installerContext.mode.command ==
211 InstallMode::Command::REINSTALL)
213 AddTask(new TaskPrepareReinstall(m_installerContext));
216 AddTask(new TaskWidgetConfig(m_installerContext));
218 if (m_installerContext.widgetConfig.packagingType ==
219 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
221 AddTask(new TaskPrepareFiles(m_installerContext));
224 AddTask(new TaskCertify(m_installerContext));
225 if (m_needEncryption) {
226 AddTask(new TaskEncryptResource(m_installerContext));
229 if (m_installerContext.mode.extension !=
230 InstallMode::ExtensionType::DIR) {
231 AddTask(new TaskUpdateFiles(m_installerContext));
232 AddTask(new TaskFileManipulation(m_installerContext));
235 AddTask(new TaskManifestFile(m_installerContext));
236 if (m_installerContext.widgetConfig.packagingType ==
237 PKG_TYPE_HYBRID_WEB_APP)
239 AddTask(new TaskInstallOspsvc(m_installerContext));
241 AddTask(new TaskCertificates(m_installerContext));
242 AddTask(new TaskDatabase(m_installerContext));
243 AddTask(new TaskAceCheck(m_installerContext));
244 //TODO: remove widgetHandle from this task and move before database task
245 // by now widget handle is needed in ace check
246 // Any error in acecheck while update will break widget
247 AddTask(new TaskSmack(m_installerContext));
248 AddTask(new TaskRemoveBackupFiles(m_installerContext));
250 // Installation is not allowed to proceed due to widget update policy
251 LogWarning("Configure installation failed!");
253 AddTask(new InstallerTaskFail(result));
257 ConfigureResult JobWidgetInstall::prepareInstallation(
258 const std::string &widgetPath)
260 ConfigureResult result;
261 m_needEncryption = false;
266 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
267 if (m_installerContext.mode.command ==
268 InstallMode::Command::REINSTALL) {
269 std::ostringstream tempPathBuilder;
270 tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
271 tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
272 tempPathBuilder << "/";
273 tempPathBuilder << widgetPath;
274 tempDir = tempPathBuilder.str();;
276 tempDir = widgetPath;
280 Jobs::WidgetInstall::createTempPath(
281 m_installerContext.mode.rootPath ==
282 InstallMode::RootPath::RO);
283 WidgetUnzip wgtUnzip;
284 wgtUnzip.unzipWgtFile(widgetPath, tempDir);
287 LogDebug("widgetPath:" << widgetPath);
288 LogDebug("tempPath:" << tempDir);
290 m_installerContext.widgetConfig.packagingType =
291 checkPackageType(widgetPath, tempDir);
292 ConfigParserData configData = getWidgetDataFromXML(
295 m_installerContext.widgetConfig.packagingType,
296 m_installerContext.mode.command == InstallMode::Command::REINSTALL);
297 LogDebug("widget packaging type : " <<
298 m_installerContext.widgetConfig.packagingType.pkgType);
300 setTizenId(configData);
301 setApplicationType(configData);
302 m_needEncryption = detectResourceEncryption(configData);
303 setInstallLocationType(configData);
305 // Configure installation
306 result = ConfigureInstallation(widgetPath, configData, tempDir);
308 Catch(Exceptions::OpenZipFailed)
310 LogError("Failed to unzip for widget");
311 result = ConfigureResult::Failed_OpenZipError;
313 Catch(Exceptions::ExtractFileFailed)
315 LogError("Failed to unzip for widget");
316 result = ConfigureResult::Failed_UnzipError;
318 Catch(Exceptions::DrmDecryptFailed)
320 LogError("Failed to unzip for widget");
321 result = ConfigureResult::Failed_DrmError;
323 Catch(Exceptions::MissingConfig)
325 LogError("Failed to localize config.xml");
326 result = ConfigureResult::Failed_InvalidConfig;
328 Catch(Exceptions::WidgetConfigFileInvalid)
330 LogError("Invalid configuration file");
331 result = ConfigureResult::Failed_InvalidConfig;
333 Catch(DPL::Exception)
335 LogError("Unknown exception");
336 result = ConfigureResult::Failed;
342 void JobWidgetInstall::setTizenId(
343 const WrtDB::ConfigParserData &configInfo)
345 bool shouldMakeAppid = false;
346 using namespace PackageManager;
347 if (!!configInfo.tizenAppId) {
348 LogDebug("Setting tizenAppId provided in config.xml: " <<
349 configInfo.tizenAppId);
351 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
353 if (!!configInfo.tizenPkgId) {
354 LogDebug("Setting tizenPkgId provided in config.xml: " <<
355 configInfo.tizenPkgId);
357 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
359 DPL::String appid = *configInfo.tizenAppId;
360 if (appid.length() > PACKAGE_ID_LENGTH) {
361 m_installerContext.widgetConfig.tzPkgid =
362 appid.substr(0, PACKAGE_ID_LENGTH);
364 //old version appid only has 10byte random character is able to install for a while.
365 //this case appid equal pkgid.
366 m_installerContext.widgetConfig.tzPkgid =
367 *configInfo.tizenAppId;
368 shouldMakeAppid = true;
372 shouldMakeAppid = true;
373 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
374 LogDebug("Checking if pkg id is unique");
376 if (!validateTizenPackageID(pkgId)) {
377 //path exist, chose another one
378 pkgId = WidgetDAOReadOnly::generatePkgId();
383 m_installerContext.widgetConfig.tzPkgid = pkgId;
384 LogInfo("tizen_id name was generated by WRT: " <<
385 m_installerContext.widgetConfig.tzPkgid);
388 if (shouldMakeAppid == true) {
389 DPL::OptionalString name;
390 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
392 FOREACH(localizedData, configInfo.localizedDataSet)
394 Locale i = localizedData->first;
395 if (!!defaultLocale) {
396 if (defaultLocale == i) {
397 name = localizedData->second.name;
401 name = localizedData->second.name;
406 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
407 LogDebug("Regcomp failed");
410 LogDebug("Name : " << name);
411 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
412 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
414 // TODO : generate name move to wrt-commons
415 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
416 std::ostringstream genName;
418 gettimeofday(&tv, NULL);
419 unsigned int seed = time(NULL) + tv.tv_usec;
421 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
422 name = DPL::FromUTF8String(genName.str());
423 LogDebug("name was generated by WRT");
426 LogDebug("Name : " << name);
427 std::ostringstream genid;
428 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
429 LogDebug("tizen appid was generated by WRT : " << genid.str());
431 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
432 NormalizeAndTrimSpaceString(appid);
433 m_installerContext.widgetConfig.tzAppid = *appid;
436 // send start signal of pkgmgr
437 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
441 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
442 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
443 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
446 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
447 const std::string& tempPath)
449 m_installerContext.locations =
450 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
452 widgetPath, tempPath,
453 m_installerContext.widgetConfig.packagingType,
454 m_installerContext.mode.rootPath ==
455 InstallMode::RootPath::RO,
456 m_installerContext.mode.extension);
457 m_installerContext.locations->registerAppid(
458 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
460 LogInfo("widgetSource " << widgetPath);
463 ConfigureResult JobWidgetInstall::ConfigureInstallation(
464 const std::string &widgetSource,
465 const WrtDB::ConfigParserData &configData,
466 const std::string &tempPath)
468 ConfigureResult result = ConfigureResult::Failed;
469 WidgetUpdateInfo update;
471 // checking installed web application
473 // checking existing application is installed
474 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
475 // no excpetion means, it isn't update mode
476 getInstallerStruct().pkgmgrInterface->sendSignal(
478 PKGMGR_START_UPDATE);
480 update = detectWidgetUpdate(configData,
481 m_installerContext.widgetConfig.tzAppid);
482 result = checkWidgetUpdate(update);
483 if (result != ConfigureResult::Updated) {
484 // Already installed TizenAppId. return failed
485 return ConfigureResult::Failed_AlreadyInstalled;
487 if (!checkSupportRDSUpdate(configData)) {
488 return ConfigureResult::Failed_NotSupportRDSUpdate;
490 m_installerContext.isUpdateMode = true;
492 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
493 result = ConfigureResult::Ok;
494 getInstallerStruct().pkgmgrInterface->sendSignal(
496 PKGMGR_START_INSTALL);
497 m_installerContext.isUpdateMode = false;
499 if (!validateTizenApplicationID(
500 m_installerContext.widgetConfig.tzAppid))
502 LogError("tizen application ID is already used");
503 return ConfigureResult::Failed_InvalidConfig;
505 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
506 LogError("tizen package ID is already used");
507 return ConfigureResult::Failed_AlreadyInstalled;
511 configureWidgetLocation(widgetSource, tempPath);
513 // Init installer context
514 m_installerContext.installStep = InstallerContext::INSTALL_START;
515 m_installerContext.job = this;
516 m_installerContext.widgetConfig.shareHref = std::string();
521 bool JobWidgetInstall::validateTizenApplicationID(
522 const WrtDB::TizenAppId &tizenAppId)
524 LogInfo("tizen application ID = [" << tizenAppId << "]");
527 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
528 LogDebug("Regcomp failed");
531 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
541 bool JobWidgetInstall::validateTizenPackageID(
542 const WrtDB::TizenPkgId &tizenPkgId)
544 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
546 std::string installPath =
547 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
551 if ((stat(installPath.c_str(), &dirStat) == 0))
558 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
559 const WidgetUpdateInfo &update)
561 if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
562 return ConfigureResult::Failed;
565 LogInfo("existing version = '" << update.existingVersion);
566 LogInfo("incoming version = '" << update.incomingVersion);
567 LogInfo("Tizen AppID = " << update.tzAppId);
569 // Check running state
570 bool isRunning = false;
572 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
574 if (APP_MANAGER_ERROR_NONE != ret) {
575 LogError("Fail to get running state");
576 return ConfigureResult::Failed_WidgetRunning;
579 if (true == isRunning) {
580 // get app_context for running application
581 // app_context must be released with app_context_destroy
582 app_context_h appCtx = NULL;
584 app_manager_get_app_context(
585 DPL::ToUTF8String(update.tzAppId).c_str(),
587 if (APP_MANAGER_ERROR_NONE != ret) {
588 LogError("Fail to get app_context");
589 return ConfigureResult::Failed_WidgetRunning;
592 // terminate app_context_h
593 ret = app_manager_terminate_app(appCtx);
594 if (APP_MANAGER_ERROR_NONE != ret) {
595 LogError("Fail to terminate running application");
596 app_context_destroy(appCtx);
597 return ConfigureResult::Failed_WidgetRunning;
599 app_context_destroy(appCtx);
600 // app_manager_terminate_app isn't sync API
601 // wait until application isn't running (50ms * 100)
602 bool isStillRunning = true;
603 int checkingloop = 100;
604 struct timespec duration = { 0, 50 * 1000 * 1000 };
605 while (--checkingloop >= 0) {
606 nanosleep(&duration, NULL);
608 app_manager_is_running(
609 DPL::ToUTF8String(update.tzAppId).c_str(),
611 if (APP_MANAGER_ERROR_NONE != ret) {
612 LogError("Fail to get running state");
613 return ConfigureResult::Failed_WidgetRunning;
615 if (!isStillRunning) {
619 if (isStillRunning) {
620 LogError("Fail to terminate running application");
621 return ConfigureResult::Failed_WidgetRunning;
623 LogInfo("terminate application");
627 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
629 if (!!update.existingVersion ||
630 m_installerContext.mode.extension ==
631 InstallMode::ExtensionType::DIR) {
632 return ConfigureResult::Updated;
635 return ConfigureResult::Failed;
638 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
639 const std::string &widgetSource,
640 const std::string &tempPath,
641 WrtDB::PackagingType pkgType,
646 ConfigParserData configInfo;
649 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
650 parser.Parse(widgetSource,
652 new RootParser<WidgetParser>(configInfo,
653 DPL::FromUTF32String(
656 std::string configFile;
657 configFile = tempPath + "/" + CONFIG_XML;
658 if (!WrtUtilFileExists(configFile)) {
659 configFile = tempPath + "/" + WITH_OSP_XML;
663 // checking RDS data directory
664 if (access(configFile.c_str(), F_OK) != 0) {
665 std::string tzAppId =
666 widgetSource.substr(widgetSource.find_last_of("/")+1);
667 WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
668 configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
670 configFile += WITH_OSP_XML;
674 if(!DPL::Utils::Path(configFile).Exists())
676 ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
679 parser.Parse(configFile,
681 new RootParser<WidgetParser>(configInfo,
687 Catch(ElementParser::Exception::ParseError)
689 LogError("Failed to parse config.xml file");
690 return ConfigParserData();
692 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
694 LogError("Failed to find installed widget - give proper tizenId");
695 return ConfigParserData();
697 Catch(Exceptions::WidgetConfigFileNotFound){
698 LogError("Failed to find config.xml");
699 return ConfigParserData();
705 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
706 const ConfigParserData &configInfo,
707 const WrtDB::TizenAppId &tizenId)
709 LogInfo("Checking up widget package for config.xml...");
710 OptionalWidgetVersion incomingVersion;
712 if (!configInfo.version.IsNull()) {
714 DPL::Optional<WidgetVersion>(
715 WidgetVersion(*configInfo.version));
718 WidgetDAOReadOnly dao(tizenId);
720 OptionalWidgetVersion optVersion;
721 DPL::OptionalString version = dao.getVersion();
722 if (!version.IsNull()) {
723 optVersion = OptionalWidgetVersion(WidgetVersion(*version));
726 return WidgetUpdateInfo(
732 void JobWidgetInstall::SendProgress()
734 using namespace PackageManager;
735 if (GetProgressFlag() != false) {
736 if (getInstallerStruct().progressCallback != NULL) {
737 // send progress signal of pkgmgr
738 std::ostringstream percent;
739 percent << static_cast<int>(GetProgressPercent());
740 getInstallerStruct().pkgmgrInterface->sendSignal(
744 LogDebug("Call widget install progressCallbak");
745 getInstallerStruct().progressCallback(
746 getInstallerStruct().userParam,
747 GetProgressPercent(),
748 GetProgressDescription());
753 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
755 using namespace PackageManager;
756 if (GetProgressFlag() != false) {
757 if (getInstallerStruct().progressCallback != NULL) {
758 // send progress signal of pkgmgr
759 getInstallerStruct().pkgmgrInterface->sendSignal(
766 void JobWidgetInstall::SendFinishedSuccess()
768 using namespace PackageManager;
769 // TODO : sync should move to separate task.
772 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
773 if (m_installerContext.isUpdateMode) {
774 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
776 WidgetInstallToExtSingleton::Instance().postInstallation(true);
778 WidgetInstallToExtSingleton::Instance().deinitialize();
781 // remove widget install information file
782 unlink(m_installerContext.installInfo.c_str());
785 JobWidgetInstall::displayWidgetInfo();
787 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
789 // send signal of pkgmgr
790 getInstallerStruct().pkgmgrInterface->sendSignal(
794 LogDebug("Call widget install successfinishedCallback");
795 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
797 tizenId), Jobs::Exceptions::Success);
800 void JobWidgetInstall::SendFinishedFailure()
802 using namespace PackageManager;
803 // remove widget install information file
804 unlink(m_installerContext.installInfo.c_str());
806 LogError("Error number: " << m_exceptionCaught);
807 LogError("Message: " << m_exceptionMessage);
808 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
810 LogDebug("Call widget install failure finishedCallback");
811 std::stringstream errorNum;
812 errorNum << m_exceptionCaught;
814 // send signal of pkgmgr
815 getInstallerStruct().pkgmgrInterface->sendSignal(
819 getInstallerStruct().pkgmgrInterface->sendSignal(
823 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
825 tizenId), m_exceptionCaught);
828 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
830 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
831 m_exceptionMessage = e.GetMessage();
834 void JobWidgetInstall::displayWidgetInfo()
836 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
838 std::ostringstream out;
839 WidgetLocalizedInfo localizedInfo =
840 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
843 "===================================== INSTALLED WIDGET INFO =========" \
844 "============================";
845 out << std::endl << "Name: " << localizedInfo.name;
846 out << std::endl << "AppId: " << dao.getTzAppId();
847 WidgetSize size = dao.getPreferredSize();
848 out << std::endl << "Width: " << size.width;
849 out << std::endl << "Height: " << size.height;
850 out << std::endl << "Start File: " <<
851 W3CFileLocalization::getStartFile(dao.getTzAppId());
852 out << std::endl << "Version: " << dao.getVersion();
853 out << std::endl << "Licence: " <<
854 localizedInfo.license;
855 out << std::endl << "Licence Href: " <<
856 localizedInfo.licenseHref;
857 out << std::endl << "Description: " <<
858 localizedInfo.description;
859 out << std::endl << "Widget Id: " << dao.getGUID();
860 out << std::endl << "Widget recognized: " << dao.isRecognized();
861 out << std::endl << "Widget distributor signed: " <<
862 dao.isDistributorSigned();
863 out << std::endl << "Widget trusted: " << dao.isTrusted();
865 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
866 DPL::OptionalString iconSrc =
867 !!icon ? icon->src : DPL::OptionalString::Null;
868 out << std::endl << "Icon: " << iconSrc;
870 out << std::endl << "Preferences:";
872 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
875 out << std::endl << " Key: " <<
877 out << std::endl << " Readonly: " <<
882 out << std::endl << "Features:";
884 WidgetFeatureSet list = dao.getFeaturesList();
887 out << std::endl << " Name: " << it->name;
896 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
897 const std::string &widgetSource,
898 const std::string &tempPath)
900 if (hasExtension(widgetSource, XML_EXTENSION)) {
901 LogInfo("Hosted app installation");
902 return PKG_TYPE_HOSTED_WEB_APP;
905 std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
906 if (WrtUtilFileExists(configFile)) {
907 return PKG_TYPE_HYBRID_WEB_APP;
910 return PKG_TYPE_NOMAL_WEB_APP;
913 void JobWidgetInstall::setApplicationType(
914 const WrtDB::ConfigParserData &configInfo)
916 AppType widgetAppType = APP_TYPE_UNKNOWN;
917 FOREACH(iterator, configInfo.nameSpaces) {
918 LogInfo("namespace = [" << *iterator << "]");
920 if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
921 if (widgetAppType != APP_TYPE_UNKNOWN &&
922 widgetAppType != APP_TYPE_TIZENWEBAPP)
924 LogError("To many namespaces declared in configuration fileA.");
925 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
926 "Config.xml has more than one valid namespace");
928 widgetAppType = APP_TYPE_TIZENWEBAPP;
930 LogDebug("Namespace ignored.");
934 m_installerContext.widgetConfig.webAppType = widgetAppType;
936 LogInfo("type = [" <<
937 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
941 bool JobWidgetInstall::detectResourceEncryption(
942 const WrtDB::ConfigParserData &configData)
944 FOREACH(it, configData.settingsList)
946 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
947 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
949 LogDebug("resource need encryption");
956 void JobWidgetInstall::setInstallLocationType(
957 const WrtDB::ConfigParserData & configData)
959 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
960 if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) {
961 FOREACH(it, configData.settingsList) {
962 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
964 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
966 LogDebug("This widget will be installed to sd card");
967 m_installerContext.locationType =
968 INSTALL_LOCATION_TYPE_EXTERNAL;
974 bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
977 if (m_installerContext.mode.command ==
978 InstallMode::Command::REINSTALL)
980 DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
981 DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
983 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
984 WrtDB::WidgetSettings widgetSettings;
985 dao.getWidgetSettings(widgetSettings);
987 FOREACH(it, widgetSettings) {
988 if (it->settingName == SETTING_VALUE_ENCRYPTION) {
989 dbValue = it->settingValue;
993 FOREACH(data, configInfo.settingsList)
995 if (data->m_name == SETTING_VALUE_ENCRYPTION)
997 configValue = data->m_value;
1000 if (configValue != dbValue) {
1001 LogError("Not Support RDS mode because of encryption setting");
1008 } //namespace WidgetInstall