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_AlreadyInstalled) {
132 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
133 "package is already installed");
134 } else if (m_result == ConfigureResult::Failed_WidgetRunning) {
135 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
136 "widget is running");
137 } else if (m_result == ConfigureResult::Failed_DrmError) {
138 ThrowMsg(Jobs::WidgetInstall::Exceptions::DRMFailed,
140 } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) {
141 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
142 "RDS update failed");
144 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
145 "widget installation or update not allowed!");
150 InstallerTaskFail(ConfigureResult result) :
151 DPL::TaskDecl<InstallerTaskFail>(this),
154 AddStep(&InstallerTaskFail::StepFail);
158 JobWidgetInstall::JobWidgetInstall(
159 std::string const &widgetPath,
160 const WidgetInstallationStruct &
163 JobContextBase<WidgetInstallationStruct>(installerStruct),
164 m_exceptionCaught(Jobs::Exceptions::Success)
166 m_installerContext.mode = m_jobStruct.m_installMode;
167 ConfigureResult result = prepareInstallation(widgetPath);
169 if (result == ConfigureResult::Ok) {
170 LogInfo("Configure installation succeeded");
171 m_installerContext.job->SetProgressFlag(true);
173 AddTask(new TaskRecovery(m_installerContext));
175 AddTask(new TaskWidgetConfig(m_installerContext));
176 if (m_installerContext.widgetConfig.packagingType ==
177 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
179 AddTask(new TaskPrepareFiles(m_installerContext));
181 AddTask(new TaskCertify(m_installerContext));
182 if (m_needEncryption) {
183 AddTask(new TaskEncryptResource(m_installerContext));
186 AddTask(new TaskFileManipulation(m_installerContext));
187 AddTask(new TaskManifestFile(m_installerContext));
188 if (m_installerContext.widgetConfig.packagingType ==
189 PKG_TYPE_HYBRID_WEB_APP)
191 AddTask(new TaskInstallOspsvc(m_installerContext));
193 AddTask(new TaskCertificates(m_installerContext));
194 AddTask(new TaskDatabase(m_installerContext));
195 AddTask(new TaskAceCheck(m_installerContext));
196 AddTask(new TaskSmack(m_installerContext));
197 } else if (result == ConfigureResult::Updated) {
198 LogInfo("Configure installation updated");
199 LogInfo("Widget Update");
200 m_installerContext.job->SetProgressFlag(true);
202 if (m_installerContext.mode.command ==
203 InstallMode::Command::REINSTALL)
205 AddTask(new TaskPrepareReinstall(m_installerContext));
208 AddTask(new TaskWidgetConfig(m_installerContext));
210 if (m_installerContext.widgetConfig.packagingType ==
211 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
213 AddTask(new TaskPrepareFiles(m_installerContext));
216 AddTask(new TaskCertify(m_installerContext));
217 if (m_needEncryption) {
218 AddTask(new TaskEncryptResource(m_installerContext));
221 if (m_installerContext.widgetConfig.packagingType !=
222 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
224 AddTask(new TaskUpdateFiles(m_installerContext));
225 AddTask(new TaskFileManipulation(m_installerContext));
228 AddTask(new TaskManifestFile(m_installerContext));
229 if (m_installerContext.widgetConfig.packagingType ==
230 PKG_TYPE_HYBRID_WEB_APP)
232 AddTask(new TaskInstallOspsvc(m_installerContext));
234 AddTask(new TaskCertificates(m_installerContext));
235 AddTask(new TaskDatabase(m_installerContext));
236 AddTask(new TaskAceCheck(m_installerContext));
237 //TODO: remove widgetHandle from this task and move before database task
238 // by now widget handle is needed in ace check
239 // Any error in acecheck while update will break widget
240 AddTask(new TaskSmack(m_installerContext));
241 AddTask(new TaskRemoveBackupFiles(m_installerContext));
242 } else if (result >= ConfigureResult::Failed &&
243 result <= ConfigureResult::Failed_NotSupportRDSUpdate) {
244 // Installation is not allowed to proceed due to widget update policy
245 LogWarning("Configure installation failed!");
247 AddTask(new InstallerTaskFail(result));
249 Assert(false && "Invalid configure result!");
253 ConfigureResult JobWidgetInstall::prepareInstallation(
254 const std::string &widgetPath)
256 ConfigureResult result;
257 m_needEncryption = false;
262 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
263 if (m_installerContext.mode.command ==
264 InstallMode::Command::REINSTALL) {
265 std::ostringstream tempPathBuilder;
266 tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
267 tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
268 tempPathBuilder << "/";
269 tempPathBuilder << widgetPath;
270 tempDir = tempPathBuilder.str();;
272 tempDir = widgetPath;
276 Jobs::WidgetInstall::createTempPath(
277 m_installerContext.mode.rootPath ==
278 InstallMode::RootPath::RO);
279 WidgetUnzip wgtUnzip;
280 wgtUnzip.unzipWgtFile(widgetPath, tempDir);
283 LogDebug("widgetPath:" << widgetPath);
284 LogDebug("tempPath:" << tempDir);
286 m_installerContext.widgetConfig.packagingType =
287 checkPackageType(widgetPath, tempDir);
288 ConfigParserData configData = getWidgetDataFromXML(
291 m_installerContext.widgetConfig.packagingType,
292 m_installerContext.mode.command == InstallMode::Command::REINSTALL);
293 LogDebug("widget packaging type : " <<
294 m_installerContext.widgetConfig.packagingType.pkgType);
296 setTizenId(configData);
297 setApplicationType(configData);
298 m_needEncryption = detectResourceEncryption(configData);
299 setInstallLocationType(configData);
301 // Configure installation
302 result = ConfigureInstallation(widgetPath, configData, tempDir);
304 Catch(Exceptions::ExtractFileFailed)
306 LogError("Failed to create temporary path for widget");
307 result = ConfigureResult::Failed_InvalidConfig;
313 void JobWidgetInstall::setTizenId(
314 const WrtDB::ConfigParserData &configInfo)
316 bool shouldMakeAppid = false;
317 using namespace PackageManager;
318 if (!!configInfo.tizenAppId) {
319 LogDebug("Setting tizenAppId provided in config.xml: " <<
320 configInfo.tizenAppId);
322 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
324 if (!!configInfo.tizenPkgId) {
325 LogDebug("Setting tizenPkgId provided in config.xml: " <<
326 configInfo.tizenPkgId);
328 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
330 DPL::String appid = *configInfo.tizenAppId;
331 if (appid.length() > PACKAGE_ID_LENGTH) {
332 m_installerContext.widgetConfig.tzPkgid =
333 appid.substr(0, PACKAGE_ID_LENGTH);
335 //old version appid only has 10byte random character is able to install for a while.
336 //this case appid equal pkgid.
337 m_installerContext.widgetConfig.tzPkgid =
338 *configInfo.tizenAppId;
339 shouldMakeAppid = true;
343 shouldMakeAppid = true;
344 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
345 LogDebug("Checking if pkg id is unique");
347 if (!validateTizenPackageID(pkgId)) {
348 //path exist, chose another one
349 pkgId = WidgetDAOReadOnly::generatePkgId();
354 m_installerContext.widgetConfig.tzPkgid = pkgId;
355 LogInfo("tizen_id name was generated by WRT: " <<
356 m_installerContext.widgetConfig.tzPkgid);
359 if (shouldMakeAppid == true) {
360 DPL::OptionalString name;
361 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
363 FOREACH(localizedData, configInfo.localizedDataSet)
365 Locale i = localizedData->first;
366 if (!!defaultLocale) {
367 if (defaultLocale == i) {
368 name = localizedData->second.name;
372 name = localizedData->second.name;
377 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
378 LogDebug("Regcomp failed");
381 LogDebug("Name : " << name);
382 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
383 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
385 // TODO : generate name move to wrt-commons
386 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
387 std::ostringstream genName;
389 gettimeofday(&tv, NULL);
390 unsigned int seed = time(NULL) + tv.tv_usec;
392 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
393 name = DPL::FromUTF8String(genName.str());
394 LogDebug("name was generated by WRT");
397 LogDebug("Name : " << name);
398 std::ostringstream genid;
399 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
400 LogDebug("tizen appid was generated by WRT : " << genid.str());
402 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
403 NormalizeAndTrimSpaceString(appid);
404 m_installerContext.widgetConfig.tzAppid = *appid;
407 // send start signal of pkgmgr
408 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
412 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
413 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
414 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
417 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
418 const std::string& tempPath)
420 m_installerContext.locations =
421 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
423 widgetPath, tempPath,
424 m_installerContext.widgetConfig.packagingType,
425 m_installerContext.mode.rootPath ==
426 InstallMode::RootPath::RO);
427 m_installerContext.locations->registerAppid(
428 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
430 LogInfo("widgetSource " << widgetPath);
433 ConfigureResult JobWidgetInstall::ConfigureInstallation(
434 const std::string &widgetSource,
435 const WrtDB::ConfigParserData &configData,
436 const std::string &tempPath)
438 ConfigureResult result = ConfigureResult::Failed;
439 WidgetUpdateInfo update;
441 // checking installed web application
443 // checking existing application is installed
444 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
445 // no excpetion means, it isn't update mode
446 getInstallerStruct().pkgmgrInterface->sendSignal(
448 PKGMGR_START_UPDATE);
450 update = detectWidgetUpdate(configData,
451 m_installerContext.widgetConfig.tzAppid);
452 result = checkWidgetUpdate(update);
453 if (result != ConfigureResult::Updated) {
454 // Already installed TizenAppId. return failed
455 return ConfigureResult::Failed_AlreadyInstalled;
457 if (!checkSupportRDSUpdate(configData)) {
458 return ConfigureResult::Failed_NotSupportRDSUpdate;
460 m_installerContext.isUpdateMode = true;
462 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
463 result = ConfigureResult::Ok;
464 getInstallerStruct().pkgmgrInterface->sendSignal(
466 PKGMGR_START_INSTALL);
467 m_installerContext.isUpdateMode = false;
469 if (!validateTizenApplicationID(
470 m_installerContext.widgetConfig.tzAppid))
472 LogError("tizen application ID is already used");
473 return ConfigureResult::Failed_InvalidConfig;
475 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
476 LogError("tizen package ID is already used");
477 return ConfigureResult::Failed_AlreadyInstalled;
481 configureWidgetLocation(widgetSource, tempPath);
483 // Init installer context
484 m_installerContext.installStep = InstallerContext::INSTALL_START;
485 m_installerContext.job = this;
486 m_installerContext.widgetConfig.shareHref = std::string();
491 bool JobWidgetInstall::validateTizenApplicationID(
492 const WrtDB::TizenAppId &tizenAppId)
494 LogInfo("tizen application ID = [" << tizenAppId << "]");
497 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
498 LogDebug("Regcomp failed");
501 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
511 bool JobWidgetInstall::validateTizenPackageID(
512 const WrtDB::TizenPkgId &tizenPkgId)
514 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
516 std::string installPath =
517 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
521 if ((stat(installPath.c_str(), &dirStat) == 0))
528 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
529 const WidgetUpdateInfo &update)
531 if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
532 return ConfigureResult::Failed;
535 LogInfo("existing version = '" << update.existingVersion);
536 LogInfo("incoming version = '" << update.incomingVersion);
537 LogInfo("Tizen AppID = " << update.tzAppId);
539 // Check running state
540 bool isRunning = false;
542 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
544 if (APP_MANAGER_ERROR_NONE != ret) {
545 LogError("Fail to get running state");
546 return ConfigureResult::Failed_WidgetRunning;
549 if (true == isRunning) {
550 // get app_context for running application
551 // app_context must be released with app_context_destroy
552 app_context_h appCtx = NULL;
554 app_manager_get_app_context(
555 DPL::ToUTF8String(update.tzAppId).c_str(),
557 if (APP_MANAGER_ERROR_NONE != ret) {
558 LogError("Fail to get app_context");
559 return ConfigureResult::Failed_WidgetRunning;
562 // terminate app_context_h
563 ret = app_manager_terminate_app(appCtx);
564 if (APP_MANAGER_ERROR_NONE != ret) {
565 LogError("Fail to terminate running application");
566 app_context_destroy(appCtx);
567 return ConfigureResult::Failed_WidgetRunning;
569 app_context_destroy(appCtx);
570 // app_manager_terminate_app isn't sync API
571 // wait until application isn't running (50ms * 100)
572 bool isStillRunning = true;
573 int checkingloop = 100;
574 struct timespec duration = { 0, 50 * 1000 * 1000 };
575 while (--checkingloop >= 0) {
576 nanosleep(&duration, NULL);
578 app_manager_is_running(
579 DPL::ToUTF8String(update.tzAppId).c_str(),
581 if (APP_MANAGER_ERROR_NONE != ret) {
582 LogError("Fail to get running state");
583 return ConfigureResult::Failed_WidgetRunning;
585 if (!isStillRunning) {
589 if (isStillRunning) {
590 LogError("Fail to terminate running application");
591 return ConfigureResult::Failed_WidgetRunning;
593 LogInfo("terminate application");
597 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
599 if (!!update.existingVersion ||
600 m_installerContext.mode.extension ==
601 InstallMode::ExtensionType::DIR) {
602 return ConfigureResult::Updated;
605 return ConfigureResult::Failed;
608 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
609 const std::string &widgetSource,
610 const std::string &tempPath,
611 WrtDB::PackagingType pkgType,
616 ConfigParserData configInfo;
620 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
621 parser.Parse(widgetSource,
623 new RootParser<WidgetParser>(configInfo,
624 DPL::FromUTF32String(
626 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
627 std::string configPath;
628 configPath = tempPath;
630 configPath += WITH_OSP_XML;
633 // checking RDS data directory
634 if (access(configPath.c_str(), F_OK) != 0) {
635 std::string tzAppId =
636 widgetSource.substr(widgetSource.find_last_of("/")+1);
637 WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
638 configPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
640 configPath += WITH_OSP_XML;
643 parser.Parse(configPath,
645 new RootParser<WidgetParser>(
647 DPL::FromUTF32String(L"widget"))));
649 std::string configFile;
650 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
651 configFile = tempPath + "/" + WITH_OSP_XML;
653 configFile = tempPath + "/" + CONFIG_XML;
656 parser.Parse(configFile,
658 new RootParser<WidgetParser>(configInfo,
664 Catch(ElementParser::Exception::ParseError)
666 LogError("Failed to parse config.xml file");
667 return ConfigParserData();
669 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
671 LogError("Failed to find installed widget - give proper tizenId");
672 return ConfigParserData();
678 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
679 const ConfigParserData &configInfo,
680 const WrtDB::TizenAppId &tizenId)
682 LogInfo("Checking up widget package for config.xml...");
683 OptionalWidgetVersion incomingVersion;
685 if (!configInfo.version.IsNull()) {
687 DPL::Optional<WidgetVersion>(
688 WidgetVersion(*configInfo.version));
691 WidgetDAOReadOnly dao(tizenId);
693 OptionalWidgetVersion optVersion;
694 DPL::OptionalString version = dao.getVersion();
695 if (!version.IsNull()) {
696 optVersion = OptionalWidgetVersion(WidgetVersion(*version));
699 return WidgetUpdateInfo(
705 void JobWidgetInstall::SendProgress()
707 using namespace PackageManager;
708 if (GetProgressFlag() != false) {
709 if (getInstallerStruct().progressCallback != NULL) {
710 // send progress signal of pkgmgr
711 std::ostringstream percent;
712 percent << static_cast<int>(GetProgressPercent());
713 getInstallerStruct().pkgmgrInterface->sendSignal(
717 LogDebug("Call widget install progressCallbak");
718 getInstallerStruct().progressCallback(
719 getInstallerStruct().userParam,
720 GetProgressPercent(),
721 GetProgressDescription());
726 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
728 using namespace PackageManager;
729 if (GetProgressFlag() != false) {
730 if (getInstallerStruct().progressCallback != NULL) {
731 // send progress signal of pkgmgr
732 getInstallerStruct().pkgmgrInterface->sendSignal(
739 void JobWidgetInstall::SendFinishedSuccess()
741 using namespace PackageManager;
742 // TODO : sync should move to separate task.
745 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
746 if (m_installerContext.isUpdateMode) {
747 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
749 WidgetInstallToExtSingleton::Instance().postInstallation(true);
751 WidgetInstallToExtSingleton::Instance().deinitialize();
754 // remove widget install information file
755 unlink(m_installerContext.installInfo.c_str());
758 JobWidgetInstall::displayWidgetInfo();
760 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
762 // send signal of pkgmgr
763 getInstallerStruct().pkgmgrInterface->sendSignal(
767 LogDebug("Call widget install successfinishedCallback");
768 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
770 tizenId), Jobs::Exceptions::Success);
773 void JobWidgetInstall::SendFinishedFailure()
775 using namespace PackageManager;
776 // remove widget install information file
777 unlink(m_installerContext.installInfo.c_str());
779 LogError("Error number: " << m_exceptionCaught);
780 LogError("Message: " << m_exceptionMessage);
781 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
783 LogDebug("Call widget install failure finishedCallback");
784 std::stringstream errorNum;
785 errorNum << m_exceptionCaught;
787 // send signal of pkgmgr
788 getInstallerStruct().pkgmgrInterface->sendSignal(
792 getInstallerStruct().pkgmgrInterface->sendSignal(
796 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
798 tizenId), m_exceptionCaught);
801 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
803 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
804 m_exceptionMessage = e.GetMessage();
807 void JobWidgetInstall::displayWidgetInfo()
809 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
811 std::ostringstream out;
812 WidgetLocalizedInfo localizedInfo =
813 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
816 "===================================== INSTALLED WIDGET INFO =========" \
817 "============================";
818 out << std::endl << "Name: " << localizedInfo.name;
819 out << std::endl << "AppId: " << dao.getTzAppId();
820 WidgetSize size = dao.getPreferredSize();
821 out << std::endl << "Width: " << size.width;
822 out << std::endl << "Height: " << size.height;
823 out << std::endl << "Start File: " <<
824 W3CFileLocalization::getStartFile(dao.getTzAppId());
825 out << std::endl << "Version: " << dao.getVersion();
826 out << std::endl << "Licence: " <<
827 localizedInfo.license;
828 out << std::endl << "Licence Href: " <<
829 localizedInfo.licenseHref;
830 out << std::endl << "Description: " <<
831 localizedInfo.description;
832 out << std::endl << "Widget Id: " << dao.getGUID();
833 out << std::endl << "Widget recognized: " << dao.isRecognized();
834 out << std::endl << "Widget distributor signed: " <<
835 dao.isDistributorSigned();
836 out << std::endl << "Widget trusted: " << dao.isTrusted();
838 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
839 DPL::OptionalString iconSrc =
840 !!icon ? icon->src : DPL::OptionalString::Null;
841 out << std::endl << "Icon: " << iconSrc;
843 out << std::endl << "Preferences:";
845 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
848 out << std::endl << " Key: " <<
850 out << std::endl << " Readonly: " <<
855 out << std::endl << "Features:";
857 WidgetFeatureSet list = dao.getFeaturesList();
860 out << std::endl << " Name: " << it->name;
869 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
870 const std::string &widgetSource,
871 const std::string &tempPath)
873 // Check installation type (direcotory/ or config.xml or widget.wgt)
874 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
875 LogDebug("Install directly from directory");
876 return PKG_TYPE_DIRECTORY_WEB_APP;
878 if (hasExtension(widgetSource, XML_EXTENSION)) {
879 LogInfo("Hosted app installation");
880 return PKG_TYPE_HOSTED_WEB_APP;
883 std::string configFile = tempPath + "/" + CONFIG_XML;
884 if (WrtUtilFileExists(configFile)) {
885 return PKG_TYPE_NOMAL_WEB_APP;
888 configFile = tempPath + "/" + WITH_OSP_XML;
889 if (WrtUtilFileExists(configFile)) {
890 return PKG_TYPE_HYBRID_WEB_APP;
893 return PKG_TYPE_UNKNOWN;
896 void JobWidgetInstall::setApplicationType(
897 const WrtDB::ConfigParserData &configInfo)
899 FOREACH(iterator, configInfo.nameSpaces) {
900 LogInfo("namespace = [" << *iterator << "]");
901 AppType currentAppType = APP_TYPE_UNKNOWN;
903 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
907 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
909 ConfigurationNamespace::WacWidgetNamespaceName)
911 currentAppType = APP_TYPE_WAC20;
912 } else if (*iterator ==
913 ConfigurationNamespace::TizenWebAppNamespaceName)
915 currentAppType = APP_TYPE_TIZENWEBAPP;
918 if (m_installerContext.widgetConfig.webAppType ==
921 m_installerContext.widgetConfig.webAppType = currentAppType;
922 } else if (m_installerContext.widgetConfig.webAppType ==
927 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
928 "Config.xml has more than one namespace");
932 // If there is no define, type set to WAC 2.0
933 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
934 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
937 LogInfo("type = [" <<
938 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
942 bool JobWidgetInstall::detectResourceEncryption(
943 const WrtDB::ConfigParserData &configData)
945 FOREACH(it, configData.settingsList)
947 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
948 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
950 LogDebug("resource need encryption");
957 void JobWidgetInstall::setInstallLocationType(
958 const WrtDB::ConfigParserData & configData)
960 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
961 if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) {
962 FOREACH(it, configData.settingsList) {
963 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
965 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
967 LogDebug("This widget will be installed to sd card");
968 m_installerContext.locationType =
969 INSTALL_LOCATION_TYPE_EXTERNAL;
975 bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
978 if (m_installerContext.mode.command ==
979 InstallMode::Command::REINSTALL)
981 DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
982 DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
984 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
985 WrtDB::WidgetSettings widgetSettings;
986 dao.getWidgetSettings(widgetSettings);
988 FOREACH(it, widgetSettings) {
989 if (it->settingName == SETTING_VALUE_ENCRYPTION) {
990 dbValue = it->settingValue;
994 FOREACH(data, configInfo.settingsList)
996 if (data->m_name == SETTING_VALUE_ENCRYPTION)
998 configValue = data->m_value;
1001 if (configValue != dbValue) {
1002 LogError("Not Support RDS mode because of encryption setting");
1009 } //namespace WidgetInstall