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/wrt-dao-ro/common_dao_types.h>
42 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
43 #include <dpl/wrt-dao-ro/global_config.h>
44 #include <dpl/wrt-dao-ro/config_parser_data.h>
45 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
46 #include <dpl/localization/w3c_file_localization.h>
48 #include <libiriwrapper.h>
49 #include <pkg-manager/pkgmgr_signal.h>
50 #include <app_manager.h>
52 #include "root_parser.h"
53 #include "widget_parser.h"
54 #include "parser_runner.h"
55 #include <widget_install/job_widget_install.h>
56 #include <widget_install/task_certify.h>
57 #include <widget_install/task_widget_config.h>
58 #include <widget_install/task_file_manipulation.h>
59 #include <widget_install/task_ace_check.h>
60 #include <widget_install/task_smack.h>
61 #include <widget_install/task_manifest_file.h>
62 #include <widget_install/task_prepare_files.h>
63 #include <widget_install/task_recovery.h>
64 #include <widget_install/task_install_ospsvc.h>
65 #include <widget_install/task_update_files.h>
66 #include <widget_install/task_database.h>
67 #include <widget_install/task_remove_backup.h>
68 #include <widget_install/task_encrypt_resource.h>
69 #include <widget_install/task_certificates.h>
70 #include <widget_install/task_commons.h>
71 #include <widget_install/task_prepare_reinstall.h>
73 #include <widget_install/widget_install_errors.h>
74 #include <widget_install/widget_install_context.h>
75 #include <widget_install_to_external.h>
76 #include <widget_install/widget_unzip.h>
78 using namespace WrtDB;
79 using namespace Jobs::Exceptions;
81 namespace // anonymous
83 const char * const CONFIG_XML = "config.xml";
84 const char * const WITH_OSP_XML = "res/wgt/config.xml";
86 //allowed: a-z, A-Z, 0-9
87 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
88 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
89 const size_t PACKAGE_ID_LENGTH = 10;
91 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
92 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
93 static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
94 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
96 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
99 const std::string XML_EXTENSION = ".xml";
101 bool hasExtension(const std::string& filename, const std::string& extension)
103 LogDebug("Looking for extension " << extension << " in: " << filename);
104 size_t fileLen = filename.length();
105 size_t extLen = extension.length();
106 if (fileLen < extLen) {
107 LogError("Filename " << filename << " is shorter than extension "
111 return (0 == filename.compare(fileLen - extLen, extLen, extension));
113 } // namespace anonymous
116 namespace WidgetInstall {
117 class InstallerTaskFail :
118 public DPL::TaskDecl<InstallerTaskFail>
121 ConfigureResult m_result;
125 if (m_result == ConfigureResult::Failed_InvalidConfig) {
126 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
128 } else if (m_result == ConfigureResult::Failed_LowerVersion) {
129 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion,
130 "package version is lower than installed version");
131 } else if (m_result == ConfigureResult::Failed_TheSameVersion) {
132 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageTheSameVersion,
133 "package version is the same as installed version");
134 } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) {
135 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
136 "package is already installed");
137 } else if (m_result == ConfigureResult::Failed_WidgetRunning) {
138 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
139 "widget is running");
140 } else if (m_result == ConfigureResult::Failed_DrmError) {
141 ThrowMsg(Jobs::WidgetInstall::Exceptions::DRMFailed,
143 } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) {
144 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
145 "RDS update failed");
147 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
148 "widget installation or update not allowed!");
153 InstallerTaskFail(ConfigureResult result) :
154 DPL::TaskDecl<InstallerTaskFail>(this),
157 AddStep(&InstallerTaskFail::StepFail);
161 JobWidgetInstall::JobWidgetInstall(
162 std::string const &widgetPath,
163 const WidgetInstallationStruct &
166 JobContextBase<WidgetInstallationStruct>(installerStruct),
167 m_exceptionCaught(Jobs::Exceptions::Success)
169 m_installerContext.mode = m_jobStruct.m_installMode;
170 ConfigureResult result = prepareInstallation(widgetPath);
172 if (result == ConfigureResult::Ok) {
173 LogInfo("Configure installation succeeded");
174 m_installerContext.job->SetProgressFlag(true);
176 AddTask(new TaskRecovery(m_installerContext));
178 AddTask(new TaskWidgetConfig(m_installerContext));
179 if (m_installerContext.widgetConfig.packagingType ==
180 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
182 AddTask(new TaskPrepareFiles(m_installerContext));
184 AddTask(new TaskCertify(m_installerContext));
185 if (m_needEncryption) {
186 AddTask(new TaskEncryptResource(m_installerContext));
189 AddTask(new TaskFileManipulation(m_installerContext));
190 AddTask(new TaskManifestFile(m_installerContext));
191 if (m_installerContext.widgetConfig.packagingType ==
192 PKG_TYPE_HYBRID_WEB_APP)
194 AddTask(new TaskInstallOspsvc(m_installerContext));
196 AddTask(new TaskCertificates(m_installerContext));
197 AddTask(new TaskDatabase(m_installerContext));
198 AddTask(new TaskAceCheck(m_installerContext));
199 AddTask(new TaskSmack(m_installerContext));
200 } else if (result == ConfigureResult::Updated) {
201 LogInfo("Configure installation updated");
202 LogInfo("Widget Update");
203 m_installerContext.job->SetProgressFlag(true);
205 if (m_installerContext.mode.command ==
206 InstallMode::Command::REINSTALL)
208 AddTask(new TaskPrepareReinstall(m_installerContext));
211 AddTask(new TaskWidgetConfig(m_installerContext));
213 if (m_installerContext.widgetConfig.packagingType ==
214 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
216 AddTask(new TaskPrepareFiles(m_installerContext));
219 AddTask(new TaskCertify(m_installerContext));
220 if (m_needEncryption) {
221 AddTask(new TaskEncryptResource(m_installerContext));
224 if (m_installerContext.widgetConfig.packagingType !=
225 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
227 AddTask(new TaskUpdateFiles(m_installerContext));
228 AddTask(new TaskFileManipulation(m_installerContext));
231 AddTask(new TaskManifestFile(m_installerContext));
232 if (m_installerContext.widgetConfig.packagingType ==
233 PKG_TYPE_HYBRID_WEB_APP)
235 AddTask(new TaskInstallOspsvc(m_installerContext));
237 AddTask(new TaskCertificates(m_installerContext));
238 AddTask(new TaskDatabase(m_installerContext));
239 AddTask(new TaskAceCheck(m_installerContext));
240 //TODO: remove widgetHandle from this task and move before database task
241 // by now widget handle is needed in ace check
242 // Any error in acecheck while update will break widget
243 AddTask(new TaskSmack(m_installerContext));
244 AddTask(new TaskRemoveBackupFiles(m_installerContext));
245 } else if (result >= ConfigureResult::Failed &&
246 result <= ConfigureResult::Failed_NotSupportRDSUpdate) {
247 // Installation is not allowed to proceed due to widget update policy
248 LogWarning("Configure installation failed!");
250 AddTask(new InstallerTaskFail(result));
252 Assert(false && "Invalid configure result!");
256 ConfigureResult JobWidgetInstall::prepareInstallation(
257 const std::string &widgetPath)
259 ConfigureResult result;
260 m_needEncryption = false;
265 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
266 if (m_installerContext.mode.command ==
267 InstallMode::Command::REINSTALL) {
268 std::ostringstream tempPathBuilder;
269 tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
270 tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
271 tempPathBuilder << "/";
272 tempPathBuilder << widgetPath;
273 tempDir = tempPathBuilder.str();;
275 tempDir = widgetPath;
279 Jobs::WidgetInstall::createTempPath(
280 m_installerContext.mode.rootPath ==
281 InstallMode::RootPath::RO);
282 WidgetUnzip wgtUnzip;
283 wgtUnzip.unzipWgtFile(widgetPath, tempDir);
286 LogDebug("widgetPath:" << widgetPath);
287 LogDebug("tempPath:" << tempDir);
289 m_installerContext.widgetConfig.packagingType =
290 checkPackageType(widgetPath, tempDir);
291 ConfigParserData configData = getWidgetDataFromXML(
294 m_installerContext.widgetConfig.packagingType,
295 m_installerContext.mode.command == InstallMode::Command::REINSTALL);
296 LogDebug("widget packaging type : " <<
297 m_installerContext.widgetConfig.packagingType.pkgType);
299 setTizenId(configData);
300 setApplicationType(configData);
301 m_needEncryption = detectResourceEncryption(configData);
302 setInstallLocationType(configData);
304 // Configure installation
305 result = ConfigureInstallation(widgetPath, configData, tempDir);
307 Catch(Exceptions::ExtractFileFailed)
309 LogError("Failed to create temporary path for widget");
310 result = ConfigureResult::Failed_InvalidConfig;
316 void JobWidgetInstall::setTizenId(
317 const WrtDB::ConfigParserData &configInfo)
319 bool shouldMakeAppid = false;
320 using namespace PackageManager;
321 if (!!configInfo.tizenAppId) {
322 LogDebug("Setting tizenAppId provided in config.xml: " <<
323 configInfo.tizenAppId);
325 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
327 if (!!configInfo.tizenPkgId) {
328 LogDebug("Setting tizenPkgId provided in config.xml: " <<
329 configInfo.tizenPkgId);
331 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
333 DPL::String appid = *configInfo.tizenAppId;
334 if (appid.length() > PACKAGE_ID_LENGTH) {
335 m_installerContext.widgetConfig.tzPkgid =
336 appid.substr(0, PACKAGE_ID_LENGTH);
338 //old version appid only has 10byte random character is able to install for a while.
339 //this case appid equal pkgid.
340 m_installerContext.widgetConfig.tzPkgid =
341 *configInfo.tizenAppId;
342 shouldMakeAppid = true;
346 shouldMakeAppid = true;
347 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
348 LogDebug("Checking if pkg id is unique");
350 if (!validateTizenPackageID(pkgId)) {
351 //path exist, chose another one
352 pkgId = WidgetDAOReadOnly::generatePkgId();
357 m_installerContext.widgetConfig.tzPkgid = pkgId;
358 LogInfo("tizen_id name was generated by WRT: " <<
359 m_installerContext.widgetConfig.tzPkgid);
362 if (shouldMakeAppid == true) {
363 DPL::OptionalString name;
364 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
366 FOREACH(localizedData, configInfo.localizedDataSet)
368 Locale i = localizedData->first;
369 if (!!defaultLocale) {
370 if (defaultLocale == i) {
371 name = localizedData->second.name;
375 name = localizedData->second.name;
380 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
381 LogDebug("Regcomp failed");
384 LogDebug("Name : " << name);
385 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
386 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
388 // TODO : generate name move to wrt-commons
389 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
390 std::ostringstream genName;
392 gettimeofday(&tv, NULL);
393 unsigned int seed = time(NULL) + tv.tv_usec;
395 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
396 name = DPL::FromUTF8String(genName.str());
397 LogDebug("name was generated by WRT");
400 LogDebug("Name : " << name);
401 std::ostringstream genid;
402 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
403 LogDebug("tizen appid was generated by WRT : " << genid.str());
405 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
406 NormalizeAndTrimSpaceString(appid);
407 m_installerContext.widgetConfig.tzAppid = *appid;
410 // send start signal of pkgmgr
411 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
415 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
416 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
417 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
420 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
421 const std::string& tempPath)
423 m_installerContext.locations =
424 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
426 widgetPath, tempPath,
427 m_installerContext.widgetConfig.packagingType,
428 m_installerContext.mode.rootPath ==
429 InstallMode::RootPath::RO);
430 m_installerContext.locations->registerAppid(
431 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
433 LogInfo("widgetSource " << widgetPath);
436 ConfigureResult JobWidgetInstall::ConfigureInstallation(
437 const std::string &widgetSource,
438 const WrtDB::ConfigParserData &configData,
439 const std::string &tempPath)
441 ConfigureResult result = ConfigureResult::Failed;
442 WidgetUpdateInfo update;
444 // checking installed web application
446 // checking existing application is installed
447 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
448 // no excpetion means, it isn't update mode
449 getInstallerStruct().pkgmgrInterface->sendSignal(
451 PKGMGR_START_UPDATE);
453 update = detectWidgetUpdate(configData,
454 m_installerContext.widgetConfig.tzAppid);
455 result = checkWidgetUpdate(update);
456 if (result != ConfigureResult::Updated) {
457 // Already installed TizenAppId. return failed
458 return ConfigureResult::Failed_AlreadyInstalled;
460 if (!checkSupportRDSUpdate(configData)) {
461 return ConfigureResult::Failed_NotSupportRDSUpdate;
463 m_installerContext.isUpdateMode = true;
465 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
466 result = ConfigureResult::Ok;
467 getInstallerStruct().pkgmgrInterface->sendSignal(
469 PKGMGR_START_INSTALL);
470 m_installerContext.isUpdateMode = false;
472 if (!validateTizenApplicationID(
473 m_installerContext.widgetConfig.tzAppid))
475 LogError("tizen application ID is already used");
476 return ConfigureResult::Failed_InvalidConfig;
478 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
479 LogError("tizen package ID is already used");
480 return ConfigureResult::Failed_AlreadyInstalled;
484 configureWidgetLocation(widgetSource, tempPath);
486 // Init installer context
487 m_installerContext.installStep = InstallerContext::INSTALL_START;
488 m_installerContext.job = this;
489 m_installerContext.widgetConfig.shareHref = std::string();
494 bool JobWidgetInstall::validateTizenApplicationID(
495 const WrtDB::TizenAppId &tizenAppId)
497 LogInfo("tizen application ID = [" << tizenAppId << "]");
500 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
501 LogDebug("Regcomp failed");
504 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
514 bool JobWidgetInstall::validateTizenPackageID(
515 const WrtDB::TizenPkgId &tizenPkgId)
517 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
519 std::string installPath =
520 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
524 if ((stat(installPath.c_str(), &dirStat) == 0))
531 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
532 const WidgetUpdateInfo &update)
534 if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
535 return ConfigureResult::Failed;
538 LogInfo("existing version = '" << update.existingVersion);
539 LogInfo("incoming version = '" << update.incomingVersion);
540 LogInfo("Tizen AppID = " << update.tzAppId);
542 if (update.incomingVersion < update.existingVersion) {
543 LogError("Widget is older than installed one.");
544 return ConfigureResult::Failed_LowerVersion;
547 if (update.incomingVersion == update.existingVersion) {
548 LogError("Widget is already installed in this version.");
549 return ConfigureResult::Failed_TheSameVersion;
552 // Check running state
553 bool isRunning = false;
555 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
557 if (APP_MANAGER_ERROR_NONE != ret) {
558 LogError("Fail to get running state");
559 return ConfigureResult::Failed_WidgetRunning;
562 if (true == isRunning) {
563 // get app_context for running application
564 // app_context must be released with app_context_destroy
565 app_context_h appCtx = NULL;
567 app_manager_get_app_context(
568 DPL::ToUTF8String(update.tzAppId).c_str(),
570 if (APP_MANAGER_ERROR_NONE != ret) {
571 LogError("Fail to get app_context");
572 return ConfigureResult::Failed_WidgetRunning;
575 // terminate app_context_h
576 ret = app_manager_terminate_app(appCtx);
577 if (APP_MANAGER_ERROR_NONE != ret) {
578 LogError("Fail to terminate running application");
579 app_context_destroy(appCtx);
580 return ConfigureResult::Failed_WidgetRunning;
582 app_context_destroy(appCtx);
583 // app_manager_terminate_app isn't sync API
584 // wait until application isn't running (50ms * 100)
585 bool isStillRunning = true;
586 int checkingloop = 100;
587 struct timespec duration = { 0, 50 * 1000 * 1000 };
588 while (--checkingloop >= 0) {
589 nanosleep(&duration, NULL);
591 app_manager_is_running(
592 DPL::ToUTF8String(update.tzAppId).c_str(),
594 if (APP_MANAGER_ERROR_NONE != ret) {
595 LogError("Fail to get running state");
596 return ConfigureResult::Failed_WidgetRunning;
598 if (!isStillRunning) {
602 if (isStillRunning) {
603 LogError("Fail to terminate running application");
604 return ConfigureResult::Failed_WidgetRunning;
606 LogInfo("terminate application");
610 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
612 if (!!update.existingVersion ||
613 m_installerContext.mode.extension ==
614 InstallMode::ExtensionType::DIR) {
615 return ConfigureResult::Updated;
618 return ConfigureResult::Failed;
621 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
622 const std::string &widgetSource,
623 const std::string &tempPath,
624 WrtDB::PackagingType pkgType,
629 ConfigParserData configInfo;
633 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
634 parser.Parse(widgetSource,
636 new RootParser<WidgetParser>(configInfo,
637 DPL::FromUTF32String(
639 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
640 std::string configPath;
641 configPath = tempPath;
643 configPath += WITH_OSP_XML;
646 // checking RDS data directory
647 if (access(configPath.c_str(), F_OK) != 0) {
648 std::string tzAppId =
649 widgetSource.substr(widgetSource.find_last_of("/")+1);
650 WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
651 configPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
653 configPath += WITH_OSP_XML;
656 parser.Parse(configPath,
658 new RootParser<WidgetParser>(
660 DPL::FromUTF32String(L"widget"))));
662 std::string configFile;
663 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
664 configFile = tempPath + "/" + WITH_OSP_XML;
666 configFile = tempPath + "/" + CONFIG_XML;
669 parser.Parse(configFile,
671 new RootParser<WidgetParser>(configInfo,
677 Catch(ElementParser::Exception::ParseError)
679 LogError("Failed to parse config.xml file");
680 return ConfigParserData();
682 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
684 LogError("Failed to find installed widget - give proper tizenId");
685 return ConfigParserData();
691 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
692 const ConfigParserData &configInfo,
693 const WrtDB::TizenAppId &tizenId)
695 LogInfo("Checking up widget package for config.xml...");
696 OptionalWidgetVersion incomingVersion;
698 if (!configInfo.version.IsNull()) {
700 DPL::Optional<WidgetVersion>(
701 WidgetVersion(*configInfo.version));
704 WidgetDAOReadOnly dao(tizenId);
706 OptionalWidgetVersion optVersion;
707 DPL::OptionalString version = dao.getVersion();
708 if (!version.IsNull()) {
709 optVersion = OptionalWidgetVersion(WidgetVersion(*version));
712 return WidgetUpdateInfo(
718 void JobWidgetInstall::SendProgress()
720 using namespace PackageManager;
721 if (GetProgressFlag() != false) {
722 if (getInstallerStruct().progressCallback != NULL) {
723 // send progress signal of pkgmgr
724 std::ostringstream percent;
725 percent << static_cast<int>(GetProgressPercent());
726 getInstallerStruct().pkgmgrInterface->sendSignal(
730 LogDebug("Call widget install progressCallbak");
731 getInstallerStruct().progressCallback(
732 getInstallerStruct().userParam,
733 GetProgressPercent(),
734 GetProgressDescription());
739 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
741 using namespace PackageManager;
742 if (GetProgressFlag() != false) {
743 if (getInstallerStruct().progressCallback != NULL) {
744 // send progress signal of pkgmgr
745 getInstallerStruct().pkgmgrInterface->sendSignal(
752 void JobWidgetInstall::SendFinishedSuccess()
754 using namespace PackageManager;
755 // TODO : sync should move to separate task.
758 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
759 if (m_installerContext.isUpdateMode) {
760 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
762 WidgetInstallToExtSingleton::Instance().postInstallation(true);
764 WidgetInstallToExtSingleton::Instance().deinitialize();
767 // remove widget install information file
768 unlink(m_installerContext.installInfo.c_str());
771 JobWidgetInstall::displayWidgetInfo();
773 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
775 // send signal of pkgmgr
776 getInstallerStruct().pkgmgrInterface->sendSignal(
780 LogDebug("Call widget install successfinishedCallback");
781 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
783 tizenId), Jobs::Exceptions::Success);
786 void JobWidgetInstall::SendFinishedFailure()
788 using namespace PackageManager;
789 // remove widget install information file
790 unlink(m_installerContext.installInfo.c_str());
792 LogError("Error number: " << m_exceptionCaught);
793 LogError("Message: " << m_exceptionMessage);
794 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
796 LogDebug("Call widget install failure finishedCallback");
797 std::stringstream errorNum;
798 errorNum << m_exceptionCaught;
800 // send signal of pkgmgr
801 getInstallerStruct().pkgmgrInterface->sendSignal(
805 getInstallerStruct().pkgmgrInterface->sendSignal(
809 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
811 tizenId), m_exceptionCaught);
814 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
816 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
817 m_exceptionMessage = e.GetMessage();
820 void JobWidgetInstall::displayWidgetInfo()
822 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
824 std::ostringstream out;
825 WidgetLocalizedInfo localizedInfo =
826 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
829 "===================================== INSTALLED WIDGET INFO =========" \
830 "============================";
831 out << std::endl << "Name: " << localizedInfo.name;
832 out << std::endl << "AppId: " << dao.getTzAppId();
833 WidgetSize size = dao.getPreferredSize();
834 out << std::endl << "Width: " << size.width;
835 out << std::endl << "Height: " << size.height;
836 out << std::endl << "Start File: " <<
837 W3CFileLocalization::getStartFile(dao.getTzAppId());
838 out << std::endl << "Version: " << dao.getVersion();
839 out << std::endl << "Licence: " <<
840 localizedInfo.license;
841 out << std::endl << "Licence Href: " <<
842 localizedInfo.licenseHref;
843 out << std::endl << "Description: " <<
844 localizedInfo.description;
845 out << std::endl << "Widget Id: " << dao.getGUID();
846 out << std::endl << "Widget recognized: " << dao.isRecognized();
847 out << std::endl << "Widget distributor signed: " <<
848 dao.isDistributorSigned();
849 out << std::endl << "Widget trusted: " << dao.isTrusted();
851 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
852 DPL::OptionalString iconSrc =
853 !!icon ? icon->src : DPL::OptionalString::Null;
854 out << std::endl << "Icon: " << iconSrc;
856 out << std::endl << "Preferences:";
858 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
861 out << std::endl << " Key: " <<
863 out << std::endl << " Readonly: " <<
868 out << std::endl << "Features:";
870 WidgetFeatureSet list = dao.getFeaturesList();
873 out << std::endl << " Name: " << it->name;
882 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
883 const std::string &widgetSource,
884 const std::string &tempPath)
886 // Check installation type (direcotory/ or config.xml or widget.wgt)
887 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
888 LogDebug("Install directly from directory");
889 return PKG_TYPE_DIRECTORY_WEB_APP;
891 if (hasExtension(widgetSource, XML_EXTENSION)) {
892 LogInfo("Hosted app installation");
893 return PKG_TYPE_HOSTED_WEB_APP;
896 std::string configFile = tempPath + "/" + CONFIG_XML;
897 if (WrtUtilFileExists(configFile)) {
898 return PKG_TYPE_NOMAL_WEB_APP;
901 configFile = tempPath + "/" + WITH_OSP_XML;
902 if (WrtUtilFileExists(configFile)) {
903 return PKG_TYPE_HYBRID_WEB_APP;
906 return PKG_TYPE_UNKNOWN;
909 void JobWidgetInstall::setApplicationType(
910 const WrtDB::ConfigParserData &configInfo)
912 FOREACH(iterator, configInfo.nameSpaces) {
913 LogInfo("namespace = [" << *iterator << "]");
914 AppType currentAppType = APP_TYPE_UNKNOWN;
916 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
920 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
922 ConfigurationNamespace::WacWidgetNamespaceName)
924 currentAppType = APP_TYPE_WAC20;
925 } else if (*iterator ==
926 ConfigurationNamespace::TizenWebAppNamespaceName)
928 currentAppType = APP_TYPE_TIZENWEBAPP;
931 if (m_installerContext.widgetConfig.webAppType ==
934 m_installerContext.widgetConfig.webAppType = currentAppType;
935 } else if (m_installerContext.widgetConfig.webAppType ==
940 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
941 "Config.xml has more than one namespace");
945 // If there is no define, type set to WAC 2.0
946 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
947 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
950 LogInfo("type = [" <<
951 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
955 bool JobWidgetInstall::detectResourceEncryption(
956 const WrtDB::ConfigParserData &configData)
958 FOREACH(it, configData.settingsList)
960 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
961 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
963 LogDebug("resource need encryption");
970 void JobWidgetInstall::setInstallLocationType(
971 const WrtDB::ConfigParserData & configData)
973 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
974 if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) {
975 FOREACH(it, configData.settingsList) {
976 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
978 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
980 LogDebug("This widget will be installed to sd card");
981 m_installerContext.locationType =
982 INSTALL_LOCATION_TYPE_EXTERNAL;
988 bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
991 if (m_installerContext.mode.command ==
992 InstallMode::Command::REINSTALL)
994 DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
995 DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
997 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
998 WrtDB::WidgetSettings widgetSettings;
999 dao.getWidgetSettings(widgetSettings);
1001 FOREACH(it, widgetSettings) {
1002 if (it->settingName == SETTING_VALUE_ENCRYPTION) {
1003 dbValue = it->settingValue;
1007 FOREACH(data, configInfo.settingsList)
1009 if (data->m_name == SETTING_VALUE_ENCRYPTION)
1011 configValue = data->m_value;
1014 if (configValue != dbValue) {
1015 LogError("Not Support RDS mode because of encryption setting");
1022 } //namespace WidgetInstall