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_unzip.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>
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::Deferred) {
126 ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred,
127 "widget installation or update deferred!");
128 } else if (m_result == ConfigureResult::Failed_InvalidConfig) {
129 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
131 } else if (m_result == ConfigureResult::Failed_LowerVersion) {
132 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion,
133 "package version is lower than 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 // Create installation tasks
179 if (m_installerContext.widgetConfig.packagingType !=
180 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
181 m_installerContext.widgetConfig.packagingType !=
182 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
185 AddTask(new TaskUnzip(m_installerContext));
188 AddTask(new TaskWidgetConfig(m_installerContext));
189 if (m_installerContext.widgetConfig.packagingType ==
190 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
192 AddTask(new TaskPrepareFiles(m_installerContext));
194 AddTask(new TaskCertify(m_installerContext));
195 if (m_needEncryption) {
196 AddTask(new TaskEncryptResource(m_installerContext));
199 AddTask(new TaskFileManipulation(m_installerContext));
200 AddTask(new TaskManifestFile(m_installerContext));
201 if (m_installerContext.widgetConfig.packagingType ==
202 PKG_TYPE_HYBRID_WEB_APP)
204 AddTask(new TaskInstallOspsvc(m_installerContext));
206 AddTask(new TaskCertificates(m_installerContext));
207 AddTask(new TaskDatabase(m_installerContext));
208 AddTask(new TaskAceCheck(m_installerContext));
209 AddTask(new TaskSmack(m_installerContext));
210 } else if (result == ConfigureResult::Updated) {
211 LogInfo("Configure installation updated");
212 LogInfo("Widget Update");
213 m_installerContext.job->SetProgressFlag(true);
215 if (m_installerContext.mode.command ==
216 InstallMode::Command::REINSTALL)
218 AddTask(new TaskPrepareReinstall(m_installerContext));
221 if (m_installerContext.widgetConfig.packagingType !=
222 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
223 m_installerContext.widgetConfig.packagingType !=
224 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
227 AddTask(new TaskUnzip(m_installerContext));
230 AddTask(new TaskWidgetConfig(m_installerContext));
232 if (m_installerContext.widgetConfig.packagingType ==
233 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
235 AddTask(new TaskPrepareFiles(m_installerContext));
238 AddTask(new TaskCertify(m_installerContext));
239 if (m_needEncryption) {
240 AddTask(new TaskEncryptResource(m_installerContext));
243 if (m_installerContext.widgetConfig.packagingType !=
244 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
246 AddTask(new TaskUpdateFiles(m_installerContext));
247 AddTask(new TaskFileManipulation(m_installerContext));
250 AddTask(new TaskManifestFile(m_installerContext));
251 if (m_installerContext.widgetConfig.packagingType ==
252 PKG_TYPE_HYBRID_WEB_APP)
254 AddTask(new TaskInstallOspsvc(m_installerContext));
256 AddTask(new TaskCertificates(m_installerContext));
257 AddTask(new TaskDatabase(m_installerContext));
258 AddTask(new TaskAceCheck(m_installerContext));
259 //TODO: remove widgetHandle from this task and move before database task
260 // by now widget handle is needed in ace check
261 // Any error in acecheck while update will break widget
262 AddTask(new TaskSmack(m_installerContext));
263 AddTask(new TaskRemoveBackupFiles(m_installerContext));
264 } else if (result == ConfigureResult::Deferred) {
265 // Installation is deferred
266 LogInfo("Configure installation deferred");
268 AddTask(new InstallerTaskFail(result));
269 } else if (result >= ConfigureResult::Failed &&
270 result <= ConfigureResult::Failed_DrmError) {
271 // Installation is not allowed to proceed due to widget update policy
272 LogWarning("Configure installation failed!");
274 AddTask(new InstallerTaskFail(result));
276 Assert(false && "Invalid configure result!");
280 ConfigureResult JobWidgetInstall::PrePareInstallation(
281 const std::string &widgetPath)
283 ConfigureResult result;
284 m_needEncryption = false;
289 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
290 std::ostringstream tempPathBuilder;
291 tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
292 tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
293 tempPathBuilder << "/";
294 tempPathBuilder << widgetPath;
295 tempDir = tempPathBuilder.str();;
298 Jobs::WidgetInstall::createTempPath(
299 m_installerContext.mode.rootPath ==
300 InstallMode::RootPath::RO);
303 m_isDRM = isDRMWidget(widgetPath);
304 if (true == m_isDRM) {
305 LogDebug("decrypt DRM widget");
306 if (DecryptDRMWidget(widgetPath, tempDir)) {
307 LogDebug("Failed decrypt DRM widget");
308 return ConfigureResult::Failed_DrmError;
312 LogDebug("widgetPath:" << widgetPath);
314 m_installerContext.widgetConfig.packagingType =
315 checkPackageType(widgetPath, tempDir);
316 ConfigParserData configData = getWidgetDataFromXML(
319 m_installerContext.widgetConfig.packagingType,
321 m_installerContext.mode.command == InstallMode::Command::REINSTALL);
322 LogDebug("widget packaging type : " <<
323 m_installerContext.widgetConfig.packagingType.pkgType);
325 setTizenId(configData);
326 setApplicationType(configData);
327 m_needEncryption = detectResourceEncryption(configData);
328 setInstallLocationType(configData);
330 // Configure installation
331 result = ConfigureInstallation(widgetPath, configData, tempDir);
333 Catch(Exceptions::ExtractFileFailed)
335 LogError("Failed to create temporary path for widget");
336 result = ConfigureResult::Failed_InvalidConfig;
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.locations->registerAppid(
457 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
459 LogInfo("widgetSource " << widgetPath);
462 ConfigureResult JobWidgetInstall::ConfigureInstallation(
463 const std::string &widgetSource,
464 const WrtDB::ConfigParserData &configData,
465 const std::string &tempPath)
467 ConfigureResult result = ConfigureResult::Failed;
468 WidgetUpdateInfo update;
470 // checking installed web application
472 // checking existing application is installed
473 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
474 // no excpetion means, it isn't update mode
475 getInstallerStruct().pkgmgrInterface->sendSignal(
477 PKGMGR_START_UPDATE);
479 update = detectWidgetUpdate(configData,
480 m_installerContext.widgetConfig.tzAppid);
481 result = checkWidgetUpdate(update);
482 if (result != ConfigureResult::Updated) {
483 // Already installed TizenAppId. return failed
484 return ConfigureResult::Failed_AlreadyInstalled;
486 if (!checkSupportRDSUpdate(configData)) {
487 return ConfigureResult::Failed_NotSupportRDSUpdate;
489 m_installerContext.isUpdateMode = true;
491 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
492 result = ConfigureResult::Ok;
493 getInstallerStruct().pkgmgrInterface->sendSignal(
495 PKGMGR_START_INSTALL);
496 m_installerContext.isUpdateMode = false;
498 if (!validateTizenApplicationID(
499 m_installerContext.widgetConfig.tzAppid))
501 LogError("tizen application ID is already used");
502 return ConfigureResult::Failed_InvalidConfig;
504 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
505 LogError("tizen package ID is already used");
506 return ConfigureResult::Failed_AlreadyInstalled;
510 configureWidgetLocation(widgetSource, tempPath);
512 // Init installer context
513 m_installerContext.installStep = InstallerContext::INSTALL_START;
514 m_installerContext.job = this;
515 m_installerContext.widgetConfig.shareHref = std::string();
520 bool JobWidgetInstall::validateTizenApplicationID(
521 const WrtDB::TizenAppId &tizenAppId)
523 LogInfo("tizen application ID = [" << tizenAppId << "]");
526 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
527 LogDebug("Regcomp failed");
530 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
540 bool JobWidgetInstall::validateTizenPackageID(
541 const WrtDB::TizenPkgId &tizenPkgId)
543 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
545 std::string installPath =
546 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
548 std::string preinstallPath =
549 std::string(GlobalConfig::GetUserPreloadedWidgetPath()) +
553 if ((stat(installPath.c_str(), &dirStat) == 0) ||
554 (stat(preinstallPath.c_str(), &dirStat) == 0))
561 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
562 const WidgetUpdateInfo &update)
564 if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
565 return ConfigureResult::Failed;
568 LogInfo("existing version = '" << update.existingVersion);
569 LogInfo("incoming version = '" << update.incomingVersion);
570 LogInfo("Tizen AppID = " << update.tzAppId);
572 // Check running state
573 bool isRunning = false;
575 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
577 if (APP_MANAGER_ERROR_NONE != ret) {
578 LogError("Fail to get running state");
579 return ConfigureResult::Failed_WidgetRunning;
582 if (true == isRunning) {
583 // get app_context for running application
584 // app_context must be released with app_context_destroy
585 app_context_h appCtx = NULL;
587 app_manager_get_app_context(
588 DPL::ToUTF8String(update.tzAppId).c_str(),
590 if (APP_MANAGER_ERROR_NONE != ret) {
591 LogError("Fail to get app_context");
592 return ConfigureResult::Failed_WidgetRunning;
595 // terminate app_context_h
596 ret = app_manager_terminate_app(appCtx);
597 if (APP_MANAGER_ERROR_NONE != ret) {
598 LogError("Fail to terminate running application");
599 app_context_destroy(appCtx);
600 return ConfigureResult::Failed_WidgetRunning;
602 app_context_destroy(appCtx);
603 // app_manager_terminate_app isn't sync API
604 // wait until application isn't running (50ms * 100)
605 bool isStillRunning = true;
606 int checkingloop = 100;
607 struct timespec duration = { 0, 50 * 1000 * 1000 };
608 while (--checkingloop >= 0) {
609 nanosleep(&duration, NULL);
611 app_manager_is_running(
612 DPL::ToUTF8String(update.tzAppId).c_str(),
614 if (APP_MANAGER_ERROR_NONE != ret) {
615 LogError("Fail to get running state");
616 return ConfigureResult::Failed_WidgetRunning;
618 if (!isStillRunning) {
622 if (isStillRunning) {
623 LogError("Fail to terminate running application");
624 return ConfigureResult::Failed_WidgetRunning;
626 LogInfo("terminate application");
630 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
632 if (!!update.existingVersion ||
633 m_installerContext.mode.extension ==
634 InstallMode::ExtensionType::DIR) {
635 return ConfigureResult::Updated;
638 return ConfigureResult::Failed;
641 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
642 const std::string &widgetSource,
643 const std::string &tempPath,
644 WrtDB::PackagingType pkgType,
650 ConfigParserData configInfo;
654 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
655 parser.Parse(widgetSource,
657 new RootParser<WidgetParser>(configInfo,
658 DPL::FromUTF32String(
660 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
661 std::string configPath;
662 configPath = tempPath;
664 configPath += WITH_OSP_XML;
667 // checking RDS data directory
668 if (access(configPath.c_str(), F_OK) != 0) {
669 std::string tzAppId =
670 widgetSource.substr(widgetSource.find_last_of("/")+1);
671 WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
672 configPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
674 configPath += WITH_OSP_XML;
677 parser.Parse(configPath,
679 new RootParser<WidgetParser>(
681 DPL::FromUTF32String(L"widget"))));
684 std::unique_ptr<DPL::ZipInput> zipFile(
685 new DPL::ZipInput(widgetSource));
687 std::unique_ptr<DPL::ZipInput::File> configFile;
689 // Open config.xml file
690 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
691 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
693 configFile.reset(zipFile->OpenFile(CONFIG_XML));
697 DPL::BinaryQueue buffer;
698 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
699 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
700 DPL::Copy(&inputAdapter, &outputAdapter);
701 parser.Parse(&buffer,
703 new RootParser<WidgetParser>(configInfo,
709 std::string configFile;
710 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
711 configFile = tempPath + "/" + WITH_OSP_XML;
713 configFile = tempPath + "/" + CONFIG_XML;
716 parser.Parse(configFile,
718 new RootParser<WidgetParser>(configInfo,
725 Catch(DPL::ZipInput::Exception::OpenFailed)
727 LogError("Failed to open widget package");
728 return ConfigParserData();
730 Catch(DPL::ZipInput::Exception::OpenFileFailed)
732 LogError("Failed to open config.xml file");
733 return ConfigParserData();
735 Catch(DPL::CopyFailed)
737 LogError("Failed to extract config.xml file");
738 return ConfigParserData();
740 Catch(DPL::FileInput::Exception::OpenFailed)
742 LogError("Failed to open config.xml file");
743 return ConfigParserData();
745 Catch(ElementParser::Exception::ParseError)
747 LogError("Failed to parse config.xml file");
748 return ConfigParserData();
750 Catch(DPL::ZipInput::Exception::SeekFileFailed)
752 LogError("Failed to seek widget archive - corrupted package?");
753 return ConfigParserData();
758 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
759 const ConfigParserData &configInfo,
760 const WrtDB::TizenAppId &tizenId)
762 LogInfo("Checking up widget package for config.xml...");
763 OptionalWidgetVersion incomingVersion;
765 if (!configInfo.version.IsNull()) {
767 DPL::Optional<WidgetVersion>(
768 WidgetVersion(*configInfo.version));
771 WidgetDAOReadOnly dao(tizenId);
773 OptionalWidgetVersion optVersion;
774 DPL::OptionalString version = dao.getVersion();
775 if (!version.IsNull()) {
776 optVersion = OptionalWidgetVersion(WidgetVersion(*version));
779 return WidgetUpdateInfo(
785 void JobWidgetInstall::SendProgress()
787 using namespace PackageManager;
788 if (GetProgressFlag() != false) {
789 if (getInstallerStruct().progressCallback != NULL) {
790 // send progress signal of pkgmgr
791 std::ostringstream percent;
792 percent << static_cast<int>(GetProgressPercent());
793 getInstallerStruct().pkgmgrInterface->sendSignal(
797 LogDebug("Call widget install progressCallbak");
798 getInstallerStruct().progressCallback(
799 getInstallerStruct().userParam,
800 GetProgressPercent(),
801 GetProgressDescription());
806 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
808 using namespace PackageManager;
809 if (GetProgressFlag() != false) {
810 if (getInstallerStruct().progressCallback != NULL) {
811 // send progress signal of pkgmgr
812 getInstallerStruct().pkgmgrInterface->sendSignal(
819 void JobWidgetInstall::SendFinishedSuccess()
821 using namespace PackageManager;
822 // TODO : sync should move to separate task.
825 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
826 if (m_installerContext.isUpdateMode) {
827 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
829 WidgetInstallToExtSingleton::Instance().postInstallation(true);
831 WidgetInstallToExtSingleton::Instance().deinitialize();
834 // remove widget install information file
835 unlink(m_installerContext.installInfo.c_str());
838 JobWidgetInstall::displayWidgetInfo();
840 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
842 // send signal of pkgmgr
843 getInstallerStruct().pkgmgrInterface->sendSignal(
847 LogDebug("Call widget install successfinishedCallback");
848 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
850 tizenId), Jobs::Exceptions::Success);
853 void JobWidgetInstall::SendFinishedFailure()
855 using namespace PackageManager;
856 // remove widget install information file
857 unlink(m_installerContext.installInfo.c_str());
859 LogError("Error number: " << m_exceptionCaught);
860 LogError("Message: " << m_exceptionMessage);
861 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
863 LogDebug("Call widget install failure finishedCallback");
864 std::stringstream errorNum;
865 errorNum << m_exceptionCaught;
867 // send signal of pkgmgr
868 getInstallerStruct().pkgmgrInterface->sendSignal(
872 getInstallerStruct().pkgmgrInterface->sendSignal(
876 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
878 tizenId), m_exceptionCaught);
881 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
883 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
884 m_exceptionMessage = e.GetMessage();
887 void JobWidgetInstall::displayWidgetInfo()
889 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
891 std::ostringstream out;
892 WidgetLocalizedInfo localizedInfo =
893 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
896 "===================================== INSTALLED WIDGET INFO =========" \
897 "============================";
898 out << std::endl << "Name: " << localizedInfo.name;
899 out << std::endl << "AppId: " << dao.getTzAppId();
900 WidgetSize size = dao.getPreferredSize();
901 out << std::endl << "Width: " << size.width;
902 out << std::endl << "Height: " << size.height;
903 out << std::endl << "Start File: " <<
904 W3CFileLocalization::getStartFile(dao.getTzAppId());
905 out << std::endl << "Version: " << dao.getVersion();
906 out << std::endl << "Licence: " <<
907 localizedInfo.license;
908 out << std::endl << "Licence Href: " <<
909 localizedInfo.licenseHref;
910 out << std::endl << "Description: " <<
911 localizedInfo.description;
912 out << std::endl << "Widget Id: " << dao.getGUID();
913 out << std::endl << "Widget recognized: " << dao.isRecognized();
914 out << std::endl << "Widget distributor signed: " <<
915 dao.isDistributorSigned();
916 out << std::endl << "Widget trusted: " << dao.isTrusted();
918 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
919 DPL::OptionalString iconSrc =
920 !!icon ? icon->src : DPL::OptionalString::Null;
921 out << std::endl << "Icon: " << iconSrc;
923 out << std::endl << "Preferences:";
925 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
928 out << std::endl << " Key: " <<
930 out << std::endl << " Readonly: " <<
935 out << std::endl << "Features:";
937 WidgetFeatureSet list = dao.getFeaturesList();
940 out << std::endl << " Name: " << it->name;
949 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
950 const std::string &widgetSource,
951 const std::string &tempPath)
953 // Check installation type (direcotory/ or config.xml or widget.wgt)
954 if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
955 LogDebug("Install directly from directory");
956 return PKG_TYPE_DIRECTORY_WEB_APP;
958 if (hasExtension(widgetSource, XML_EXTENSION)) {
959 LogInfo("Hosted app installation");
960 return PKG_TYPE_HOSTED_WEB_APP;
964 std::string configFile = tempPath + "/" + CONFIG_XML;
965 if (WrtUtilFileExists(configFile)) {
966 return PKG_TYPE_NOMAL_WEB_APP;
969 configFile = tempPath + "/" + WITH_OSP_XML;
970 if (WrtUtilFileExists(configFile)) {
971 return PKG_TYPE_HYBRID_WEB_APP;
974 std::unique_ptr<DPL::ZipInput> zipFile;
979 zipFile.reset(new DPL::ZipInput(widgetSource));
981 Catch(DPL::ZipInput::Exception::OpenFailed)
983 LogDebug("Failed to open widget package");
984 return PKG_TYPE_UNKNOWN;
986 Catch(DPL::ZipInput::Exception::SeekFileFailed)
988 LogError("Failed to seek widget package file");
989 return PKG_TYPE_UNKNOWN;
994 // Open config.xml file in package root
995 std::unique_ptr<DPL::ZipInput::File> configFile(
996 zipFile->OpenFile(CONFIG_XML));
997 return PKG_TYPE_NOMAL_WEB_APP;
999 Catch(DPL::ZipInput::Exception::OpenFileFailed)
1001 LogDebug("Could not find config.xml");
1006 // Open config.xml file in package root
1007 std::unique_ptr<DPL::ZipInput::File> configFile(
1008 zipFile->OpenFile(WITH_OSP_XML));
1010 return PKG_TYPE_HYBRID_WEB_APP;
1012 Catch(DPL::ZipInput::Exception::OpenFileFailed)
1014 LogDebug("Could not find wgt/config.xml");
1015 return PKG_TYPE_UNKNOWN;
1019 return PKG_TYPE_UNKNOWN;
1022 void JobWidgetInstall::setApplicationType(
1023 const WrtDB::ConfigParserData &configInfo)
1025 FOREACH(iterator, configInfo.nameSpaces) {
1026 LogInfo("namespace = [" << *iterator << "]");
1027 AppType currentAppType = APP_TYPE_UNKNOWN;
1029 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
1033 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
1035 ConfigurationNamespace::WacWidgetNamespaceName)
1037 currentAppType = APP_TYPE_WAC20;
1038 } else if (*iterator ==
1039 ConfigurationNamespace::TizenWebAppNamespaceName)
1041 currentAppType = APP_TYPE_TIZENWEBAPP;
1044 if (m_installerContext.widgetConfig.webAppType ==
1047 m_installerContext.widgetConfig.webAppType = currentAppType;
1048 } else if (m_installerContext.widgetConfig.webAppType ==
1053 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
1054 "Config.xml has more than one namespace");
1058 // If there is no define, type set to WAC 2.0
1059 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
1060 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
1063 LogInfo("type = [" <<
1064 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
1068 bool JobWidgetInstall::detectResourceEncryption(
1069 const WrtDB::ConfigParserData &configData)
1071 FOREACH(it, configData.settingsList)
1073 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1074 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
1076 LogDebug("resource need encryption");
1083 void JobWidgetInstall::setInstallLocationType(
1084 const WrtDB::ConfigParserData & configData)
1086 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1087 if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) {
1088 FOREACH(it, configData.settingsList) {
1089 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1091 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
1093 LogDebug("This widget will be installed to sd card");
1094 m_installerContext.locationType =
1095 INSTALL_LOCATION_TYPE_EXTERNAL;
1101 bool JobWidgetInstall::isDRMWidget(std::string /*widgetPath*/)
1107 bool JobWidgetInstall::DecryptDRMWidget(std::string /*widgetPath*/,
1108 std::string /*destPath*/)
1114 bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
1117 if (m_installerContext.mode.command ==
1118 InstallMode::Command::REINSTALL)
1120 DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
1121 DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
1123 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
1124 WrtDB::WidgetSettings widgetSettings;
1125 dao.getWidgetSettings(widgetSettings);
1127 FOREACH(it, widgetSettings) {
1128 if (it->settingName == SETTING_VALUE_ENCRYPTION) {
1129 dbValue = it->settingValue;
1133 FOREACH(data, configInfo.settingsList)
1135 if (data->m_name == SETTING_VALUE_ENCRYPTION)
1137 configValue = data->m_value;
1140 if (configValue != dbValue) {
1141 LogError("Not Support RDS mode because of encryption setting");
1148 } //namespace WidgetInstall