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>
51 //#include <drm_client.h>
52 #include <drm-oem-intel.h> //temporary code
54 #include "root_parser.h"
55 #include "widget_parser.h"
56 #include "parser_runner.h"
57 #include <widget_install/job_widget_install.h>
58 #include <widget_install/task_certify.h>
59 #include <widget_install/task_widget_config.h>
60 #include <widget_install/task_file_manipulation.h>
61 #include <widget_install/task_ace_check.h>
62 #include <widget_install/task_smack.h>
63 #include <widget_install/task_manifest_file.h>
64 #include <widget_install/task_prepare_files.h>
65 #include <widget_install/task_recovery.h>
66 #include <widget_install/task_install_ospsvc.h>
67 #include <widget_install/task_update_files.h>
68 #include <widget_install/task_database.h>
69 #include <widget_install/task_remove_backup.h>
70 #include <widget_install/task_encrypt_resource.h>
71 #include <widget_install/task_certificates.h>
72 #include <widget_install/task_unzip.h>
73 #include <widget_install/task_commons.h>
75 #include <widget_install/task_plugins_copy.h>
77 #include <widget_install/widget_install_errors.h>
78 #include <widget_install/widget_install_context.h>
79 #include <widget_install_to_external.h>
81 using namespace WrtDB;
82 using namespace Jobs::Exceptions;
84 namespace // anonymous
86 const char * const CONFIG_XML = "config.xml";
87 const char * const WITH_OSP_XML = "res/wgt/config.xml";
89 //allowed: a-z, A-Z, 0-9
90 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
91 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
92 const size_t PACKAGE_ID_LENGTH = 10;
94 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
95 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
96 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
97 L"install-location-type";
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::Deferred) {
128 ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred,
129 "widget installation or update deferred!");
130 } else if (m_result == ConfigureResult::Failed_InvalidConfig) {
131 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
133 } else if (m_result == ConfigureResult::Failed_LowerVersion) {
134 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion,
135 "package version is lower than installed version");
136 } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) {
137 ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
138 "package is already installed");
139 } else if (m_result == ConfigureResult::Failed_WidgetRunning) {
140 ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
141 "widget is running");
142 } else if (m_result == ConfigureResult::Failed_DrmError) {
143 ThrowMsg(Jobs::WidgetInstall::Exceptions::DRMFailed,
146 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
147 "widget installation or update not allowed!");
152 InstallerTaskFail(ConfigureResult result) :
153 DPL::TaskDecl<InstallerTaskFail>(this),
156 AddStep(&InstallerTaskFail::StepFail);
160 JobWidgetInstall::JobWidgetInstall(
161 std::string const &widgetPath,
162 const WidgetInstallationStruct &
165 JobContextBase<WidgetInstallationStruct>(installerStruct),
166 m_exceptionCaught(Jobs::Exceptions::Success)
168 m_installerContext.m_quiet = m_jobStruct.m_quiet;
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 // TODO: Update progress information for this task
202 //This is sort of quick solution, because ACE verdicts are based upon
203 //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
205 AddTask(new TaskSmack(m_installerContext));
207 AddTask(new TaskManifestFile(m_installerContext));
208 if (m_installerContext.widgetConfig.packagingType ==
209 PKG_TYPE_HYBRID_WEB_APP)
211 AddTask(new TaskInstallOspsvc(m_installerContext));
213 AddTask(new TaskCertificates(m_installerContext));
214 AddTask(new TaskPluginsCopy(m_installerContext));
215 AddTask(new TaskDatabase(m_installerContext));
216 AddTask(new TaskAceCheck(m_installerContext));
217 } else if (result == ConfigureResult::Updated) {
218 LogInfo("Configure installation updated");
219 LogInfo("Widget Update");
220 m_installerContext.job->SetProgressFlag(true);
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));
249 /* TODO : To backup file, save md5 values */
250 AddTask(new TaskSmack(m_installerContext));
252 AddTask(new TaskManifestFile(m_installerContext));
253 if (m_installerContext.widgetConfig.packagingType ==
254 PKG_TYPE_HYBRID_WEB_APP)
256 AddTask(new TaskInstallOspsvc(m_installerContext));
258 if (m_installerContext.widgetConfig.packagingType !=
259 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
261 AddTask(new TaskRemoveBackupFiles(m_installerContext));
263 AddTask(new TaskPluginsCopy(m_installerContext));
264 AddTask(new TaskDatabase(m_installerContext));
265 AddTask(new TaskAceCheck(m_installerContext));
266 //TODO: remove widgetHandle from this task and move before database task
267 // by now widget handle is needed in ace check
268 // Any error in acecheck while update will break widget
269 } else if (result == ConfigureResult::Deferred) {
270 // Installation is deferred
271 LogInfo("Configure installation deferred");
273 AddTask(new InstallerTaskFail(result));
274 } else if (result >= ConfigureResult::Failed &&
275 result <= ConfigureResult::Failed_DrmError) {
276 // Installation is not allowed to proceed due to widget update policy
277 LogWarning("Configure installation failed!");
279 AddTask(new InstallerTaskFail(result));
281 Assert(false && "Invalid configure result!");
285 ConfigureResult JobWidgetInstall::PrePareInstallation(
286 const std::string &widgetPath)
288 ConfigureResult result;
289 m_needEncryption = false;
293 std::string tempDir =
294 Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload);
296 m_isDRM = isDRMWidget(widgetPath);
297 if (true == m_isDRM) {
298 LogDebug("decrypt DRM widget");
299 if (DecryptDRMWidget(widgetPath, tempDir)) {
300 LogDebug("Failed decrypt DRM widget");
301 return ConfigureResult::Failed_DrmError;
305 LogDebug("widgetPath:" << widgetPath);
307 m_installerContext.widgetConfig.packagingType =
308 checkPackageType(widgetPath, tempDir);
309 ConfigParserData configData = getWidgetDataFromXML(
312 m_installerContext.widgetConfig.packagingType,
314 LogDebug("widget packaging type : " <<
315 m_installerContext.widgetConfig.packagingType.pkgType);
317 setTizenId(configData);
318 setApplicationType(configData);
319 m_needEncryption = detectResourceEncryption(configData);
320 setInstallLocationType(configData);
322 // Configure installation
323 result = ConfigureInstallation(widgetPath, configData, tempDir);
325 Catch(Exceptions::ExtractFileFailed)
327 LogError("Failed to create temporary path for widget");
328 result = ConfigureResult::Failed_InvalidConfig;
334 void JobWidgetInstall::setTizenId(
335 const WrtDB::ConfigParserData &configInfo)
337 bool shouldMakeAppid = false;
338 using namespace PackageManager;
339 if (!!configInfo.tizenAppId) {
340 LogDebug("Setting tizenAppId provided in config.xml: " <<
341 configInfo.tizenAppId);
343 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
345 if (!!configInfo.tizenPkgId) {
346 LogDebug("Setting tizenPkgId provided in config.xml: " <<
347 configInfo.tizenPkgId);
349 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
351 DPL::String appid = *configInfo.tizenAppId;
352 if (appid.length() > PACKAGE_ID_LENGTH) {
353 m_installerContext.widgetConfig.tzPkgid =
354 appid.substr(0, PACKAGE_ID_LENGTH);
356 //old version appid only has 10byte random character is able to install for a while.
357 //this case appid equal pkgid.
358 m_installerContext.widgetConfig.tzPkgid =
359 *configInfo.tizenAppId;
360 shouldMakeAppid = true;
364 shouldMakeAppid = true;
365 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
366 LogDebug("Checking if pkg id is unique");
368 if (!validateTizenPackageID(pkgId)) {
369 //path exist, chose another one
370 pkgId = WidgetDAOReadOnly::generatePkgId();
375 m_installerContext.widgetConfig.tzPkgid = pkgId;
376 LogInfo("tizen_id name was generated by WRT: " <<
377 m_installerContext.widgetConfig.tzPkgid);
380 if (shouldMakeAppid == true) {
381 DPL::OptionalString name;
382 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
384 FOREACH(localizedData, configInfo.localizedDataSet)
386 Locale i = localizedData->first;
387 if (!!defaultLocale) {
388 if (defaultLocale == i) {
389 name = localizedData->second.name;
393 name = localizedData->second.name;
398 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
399 LogDebug("Regcomp failed");
402 LogDebug("Name : " << name);
403 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
404 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
406 // TODO : generate name move to wrt-commons
407 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
408 std::ostringstream genName;
410 gettimeofday(&tv, NULL);
411 unsigned int seed = time(NULL) + tv.tv_usec;
413 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
414 name = DPL::FromUTF8String(genName.str());
415 LogDebug("name was generated by WRT");
418 LogDebug("Name : " << name);
419 std::ostringstream genid;
420 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
421 LogDebug("tizen appid was generated by WRT : " << genid.str());
423 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
424 NormalizeAndTrimSpaceString(appid);
425 m_installerContext.widgetConfig.tzAppid = *appid;
428 // send start signal of pkgmgr
429 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
433 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
434 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
435 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
438 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
439 const std::string& tempPath)
441 m_installerContext.locations =
442 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
444 widgetPath, tempPath,
445 m_installerContext.widgetConfig.packagingType,
446 m_installerContext.locationType);
447 m_installerContext.locations->registerAppid(
448 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
450 LogInfo("widgetSource " << widgetPath);
453 ConfigureResult JobWidgetInstall::ConfigureInstallation(
454 const std::string &widgetSource,
455 const WrtDB::ConfigParserData &configData,
456 const std::string &tempPath)
458 ConfigureResult result = ConfigureResult::Failed;
459 WidgetUpdateInfo update;
461 // checking installed web application
463 // checking existing application is installed
464 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
465 // no excpetion means, it isn't update mode
466 getInstallerStruct().pkgmgrInterface->sendSignal(
468 PKGMGR_START_UPDATE);
470 update = detectWidgetUpdate(configData,
471 m_installerContext.widgetConfig.tzAppid);
472 result = checkWidgetUpdate(update);
473 if (result != ConfigureResult::Updated) {
474 // Already installed TizenAppId. return failed
475 return ConfigureResult::Failed_AlreadyInstalled;
477 m_installerContext.isUpdateMode = true;
479 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
480 result = ConfigureResult::Ok;
481 getInstallerStruct().pkgmgrInterface->sendSignal(
483 PKGMGR_START_INSTALL);
484 m_installerContext.isUpdateMode = false;
486 if (!validateTizenApplicationID(
487 m_installerContext.widgetConfig.tzAppid))
489 LogError("tizen application ID is already used");
490 return ConfigureResult::Failed_InvalidConfig;
492 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
493 LogError("tizen package ID is already used");
494 return ConfigureResult::Failed_AlreadyInstalled;
498 configureWidgetLocation(widgetSource, tempPath);
500 // Init installer context
501 m_installerContext.installStep = InstallerContext::INSTALL_START;
502 m_installerContext.job = this;
503 m_installerContext.widgetConfig.shareHref = std::string();
508 bool JobWidgetInstall::validateTizenApplicationID(
509 const WrtDB::TizenAppId &tizenAppId)
511 LogInfo("tizen application ID = [" << tizenAppId << "]");
514 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
515 LogDebug("Regcomp failed");
518 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
528 bool JobWidgetInstall::validateTizenPackageID(
529 const WrtDB::TizenPkgId &tizenPkgId)
531 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
533 std::string installPath =
534 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
536 std::string preinstallPath =
537 std::string(GlobalConfig::GetUserPreloadedWidgetPath()) +
541 if ((stat(installPath.c_str(), &dirStat) == 0) ||
542 (stat(preinstallPath.c_str(), &dirStat) == 0))
549 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
550 const WidgetUpdateInfo &update)
552 LogInfo("incoming version = '" << update.incomingVersion);
553 LogInfo("Tizen AppID = " << update.tzAppId);
555 // Check running state
556 bool isRunning = false;
558 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
560 if (APP_MANAGER_ERROR_NONE != retval || isRunning) {
561 LogError("Fail to get running state");
562 return ConfigureResult::Failed_WidgetRunning;
565 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
567 WidgetUpdateMode::Type updateTypeCheckBit;
568 updateTypeCheckBit = CalcWidgetUpdatePolicy(update.existingVersion,
569 update.incomingVersion);
571 if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 ||
572 m_jobStruct.updateMode ==
573 WidgetUpdateMode::PolicyDirectoryForceInstall)
575 LogInfo("Whether widget policy allow proceed ok");
576 return ConfigureResult::Updated;
578 return ConfigureResult::Failed_LowerVersion;
581 return ConfigureResult::Failed;
584 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
585 const OptionalWidgetVersion &existingVersion,
586 const OptionalWidgetVersion &incomingVersion) const
588 // Widget is installed, check versions
589 if (!existingVersion && !incomingVersion) {
590 return WidgetUpdateMode::ExistingVersionEqual;
591 } else if (!existingVersion && !!incomingVersion) {
592 return WidgetUpdateMode::ExistingVersionNewer;
593 } else if (!!existingVersion && !incomingVersion) {
594 return WidgetUpdateMode::ExistingVersionOlder;
596 LogInfo("Existing widget: version = '" << *existingVersion << "'");
598 if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
599 return WidgetUpdateMode::BothVersionsNotStd;
600 } else if (!existingVersion->IsWac()) {
601 return WidgetUpdateMode::ExistingVersionNotStd;
602 } else if (!incomingVersion->IsWac()) {
603 return WidgetUpdateMode::IncomingVersionNotStd;
605 // Both versions are WAC-comparable. Do compare.
606 if (*incomingVersion == *existingVersion) {
607 return WidgetUpdateMode::ExistingVersionEqual;
608 } else if (*incomingVersion > *existingVersion) {
609 return WidgetUpdateMode::ExistingVersionOlder;
611 return WidgetUpdateMode::ExistingVersionNewer;
617 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
618 const std::string &widgetSource,
619 const std::string &tempPath,
620 WrtDB::PackagingType pkgType,
625 ConfigParserData configInfo;
629 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
630 parser.Parse(widgetSource,
632 new RootParser<WidgetParser>(configInfo,
633 DPL::FromUTF32String(
635 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
636 parser.Parse(widgetSource + '/' + WITH_OSP_XML,
638 new RootParser<WidgetParser>(
640 DPL::FromUTF32String(L"widget"))));
643 std::unique_ptr<DPL::ZipInput> zipFile(
644 new DPL::ZipInput(widgetSource));
646 std::unique_ptr<DPL::ZipInput::File> configFile;
648 // Open config.xml file
649 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
650 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
652 configFile.reset(zipFile->OpenFile(CONFIG_XML));
656 DPL::BinaryQueue buffer;
657 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
658 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
659 DPL::Copy(&inputAdapter, &outputAdapter);
660 parser.Parse(&buffer,
662 new RootParser<WidgetParser>(configInfo,
668 std::string configFile;
669 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
670 configFile = tempPath + "/" + WITH_OSP_XML;
672 configFile = tempPath + "/" + CONFIG_XML;
675 parser.Parse(configFile,
677 new RootParser<WidgetParser>(configInfo,
684 Catch(DPL::ZipInput::Exception::OpenFailed)
686 LogError("Failed to open widget package");
687 return ConfigParserData();
689 Catch(DPL::ZipInput::Exception::OpenFileFailed)
691 LogError("Failed to open config.xml file");
692 return ConfigParserData();
694 Catch(DPL::CopyFailed)
696 LogError("Failed to extract config.xml file");
697 return ConfigParserData();
699 Catch(DPL::FileInput::Exception::OpenFailed)
701 LogError("Failed to open config.xml file");
702 return ConfigParserData();
704 Catch(ElementParser::Exception::ParseError)
706 LogError("Failed to parse config.xml file");
707 return ConfigParserData();
709 Catch(DPL::ZipInput::Exception::SeekFileFailed)
711 LogError("Failed to seek widget archive - corrupted package?");
712 return ConfigParserData();
717 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
718 const ConfigParserData &configInfo,
719 const WrtDB::TizenAppId &tizenId)
721 LogInfo("Checking up widget package for config.xml...");
722 OptionalWidgetVersion incomingVersion;
724 if (!configInfo.version.IsNull()) {
726 DPL::Optional<WidgetVersion>(
727 WidgetVersion(*configInfo.version));
730 WidgetDAOReadOnly dao(tizenId);
731 return WidgetUpdateInfo(
733 WidgetVersion(*dao.getVersion()),
737 void JobWidgetInstall::SendProgress()
739 using namespace PackageManager;
740 if (GetProgressFlag() != false) {
741 if (getInstallerStruct().progressCallback != NULL) {
742 // send progress signal of pkgmgr
743 std::ostringstream percent;
744 percent << static_cast<int>(GetProgressPercent());
745 getInstallerStruct().pkgmgrInterface->sendSignal(
749 LogDebug("Call widget install progressCallbak");
750 getInstallerStruct().progressCallback(
751 getInstallerStruct().userParam,
752 GetProgressPercent(),
753 GetProgressDescription());
758 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
760 using namespace PackageManager;
761 if (GetProgressFlag() != false) {
762 if (getInstallerStruct().progressCallback != NULL) {
763 // send progress signal of pkgmgr
764 getInstallerStruct().pkgmgrInterface->sendSignal(
771 void JobWidgetInstall::SendFinishedSuccess()
773 using namespace PackageManager;
774 // TODO : sync should move to separate task.
777 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
778 if (m_installerContext.isUpdateMode) {
779 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
781 WidgetInstallToExtSingleton::Instance().postInstallation(true);
783 WidgetInstallToExtSingleton::Instance().deinitialize();
786 // remove widget install information file
787 unlink(m_installerContext.installInfo.c_str());
790 JobWidgetInstall::displayWidgetInfo();
792 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
794 // send signal of pkgmgr
795 getInstallerStruct().pkgmgrInterface->sendSignal(
799 LogDebug("Call widget install successfinishedCallback");
800 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
802 tizenId), Jobs::Exceptions::Success);
805 void JobWidgetInstall::SendFinishedFailure()
807 using namespace PackageManager;
808 // remove widget install information file
809 unlink(m_installerContext.installInfo.c_str());
811 LogError("Error number: " << m_exceptionCaught);
812 LogError("Message: " << m_exceptionMessage);
813 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
815 LogDebug("Call widget install failure finishedCallback");
816 std::stringstream errorNum;
817 errorNum << m_exceptionCaught;
819 // send signal of pkgmgr
820 getInstallerStruct().pkgmgrInterface->sendSignal(
824 getInstallerStruct().pkgmgrInterface->sendSignal(
828 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
830 tizenId), m_exceptionCaught);
833 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
835 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
836 m_exceptionMessage = e.GetMessage();
839 void JobWidgetInstall::displayWidgetInfo()
841 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
843 std::ostringstream out;
844 WidgetLocalizedInfo localizedInfo =
845 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
848 "===================================== INSTALLED WIDGET INFO =========" \
849 "============================";
850 out << std::endl << "Name: " << localizedInfo.name;
851 out << std::endl << "AppId: " << dao.getTzAppId();
852 WidgetSize size = dao.getPreferredSize();
853 out << std::endl << "Width: " << size.width;
854 out << std::endl << "Height: " << size.height;
855 out << std::endl << "Start File: " <<
856 W3CFileLocalization::getStartFile(dao.getTzAppId());
857 out << std::endl << "Version: " << dao.getVersion();
858 out << std::endl << "Licence: " <<
859 localizedInfo.license;
860 out << std::endl << "Licence Href: " <<
861 localizedInfo.licenseHref;
862 out << std::endl << "Description: " <<
863 localizedInfo.description;
864 out << std::endl << "Widget Id: " << dao.getGUID();
865 out << std::endl << "Widget recognized: " << dao.isRecognized();
866 out << std::endl << "Widget distributor signed: " <<
867 dao.isDistributorSigned();
868 out << std::endl << "Widget trusted: " << dao.isTrusted();
870 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
871 DPL::OptionalString iconSrc =
872 !!icon ? icon->src : DPL::OptionalString::Null;
873 out << std::endl << "Icon: " << iconSrc;
875 out << std::endl << "Preferences:";
877 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
880 out << std::endl << " Key: " <<
882 out << std::endl << " Readonly: " <<
887 out << std::endl << "Features:";
889 WidgetFeatureSet list = dao.getFeaturesList();
892 out << std::endl << " Name: " << it->name;
901 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
902 const std::string &widgetSource,
903 const std::string &tempPath)
905 // Check installation type (direcotory/ or config.xml or widget.wgt)
906 if (WidgetUpdateMode::PolicyDirectoryForceInstall ==
907 m_jobStruct.updateMode)
909 LogDebug("Install directly from directory");
910 return PKG_TYPE_DIRECTORY_WEB_APP;
912 if (hasExtension(widgetSource, XML_EXTENSION)) {
913 LogInfo("Hosted app installation");
914 return PKG_TYPE_HOSTED_WEB_APP;
918 std::string configFile = tempPath + "/" + CONFIG_XML;
919 if (WrtUtilFileExists(configFile)) {
920 return PKG_TYPE_NOMAL_WEB_APP;
923 configFile = tempPath + "/" + WITH_OSP_XML;
924 if (WrtUtilFileExists(configFile)) {
925 return PKG_TYPE_HYBRID_WEB_APP;
928 std::unique_ptr<DPL::ZipInput> zipFile;
933 zipFile.reset(new DPL::ZipInput(widgetSource));
935 Catch(DPL::ZipInput::Exception::OpenFailed)
937 LogDebug("Failed to open widget package");
938 return PKG_TYPE_UNKNOWN;
940 Catch(DPL::ZipInput::Exception::SeekFileFailed)
942 LogError("Failed to seek widget package file");
943 return PKG_TYPE_UNKNOWN;
948 // Open config.xml file in package root
949 std::unique_ptr<DPL::ZipInput::File> configFile(
950 zipFile->OpenFile(CONFIG_XML));
951 return PKG_TYPE_NOMAL_WEB_APP;
953 Catch(DPL::ZipInput::Exception::OpenFileFailed)
955 LogDebug("Could not find config.xml");
960 // Open config.xml file in package root
961 std::unique_ptr<DPL::ZipInput::File> configFile(
962 zipFile->OpenFile(WITH_OSP_XML));
964 return PKG_TYPE_HYBRID_WEB_APP;
966 Catch(DPL::ZipInput::Exception::OpenFileFailed)
968 LogDebug("Could not find wgt/config.xml");
969 return PKG_TYPE_UNKNOWN;
973 return PKG_TYPE_UNKNOWN;
976 void JobWidgetInstall::setApplicationType(
977 const WrtDB::ConfigParserData &configInfo)
979 FOREACH(iterator, configInfo.nameSpaces) {
980 LogInfo("namespace = [" << *iterator << "]");
981 AppType currentAppType = APP_TYPE_UNKNOWN;
983 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
987 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
989 ConfigurationNamespace::WacWidgetNamespaceName)
991 currentAppType = APP_TYPE_WAC20;
992 } else if (*iterator ==
993 ConfigurationNamespace::TizenWebAppNamespaceName)
995 currentAppType = APP_TYPE_TIZENWEBAPP;
998 if (m_installerContext.widgetConfig.webAppType ==
1001 m_installerContext.widgetConfig.webAppType = currentAppType;
1002 } else if (m_installerContext.widgetConfig.webAppType ==
1007 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
1008 "Config.xml has more than one namespace");
1012 // If there is no define, type set to WAC 2.0
1013 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
1014 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
1017 LogInfo("type = [" <<
1018 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
1022 bool JobWidgetInstall::detectResourceEncryption(
1023 const WrtDB::ConfigParserData &configData)
1025 FOREACH(it, configData.settingsList)
1027 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1028 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
1030 LogDebug("resource need encryption");
1037 void JobWidgetInstall::setInstallLocationType(
1039 WrtDB::ConfigParserData &
1042 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1044 if (true == m_jobStruct.m_preload) {
1045 m_installerContext.locationType =
1046 INSTALL_LOCATION_TYPE_PRELOAD;
1048 FOREACH(it, configData.settingsList)
1050 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1052 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
1054 LogDebug("This widget will be installed to sd card");
1055 m_installerContext.locationType =
1056 INSTALL_LOCATION_TYPE_EXTERNAL;
1062 bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
1065 * drm_bool_type_e is_drm_file = DRM_UNKNOWN;
1068 * ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file);
1069 * if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) {
1072 /* blow code temporary code for drm. */
1073 int ret = drm_oem_intel_isDrmFile(const_cast<char*>(widgetPath.c_str()));
1081 bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath,
1082 std::string destPath)
1085 * drm_trusted_sapps_decrypt_package_info_s package_info;
1087 * strncpy(package_info.sadcf_filepath, widgetPath.c_str(),
1088 * sizeof(package_info.sadcf_filepath));
1089 * strncpy(package_info.decrypt_filepath, destPath.c_str(),
1090 * sizeof(package_info.decrypt_filepath));
1092 * drm_trusted_request_type_e requestType =
1093 * DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
1095 * int ret = drm_trusted_handle_request(requestType,
1096 * (void *)&package_info, NULL);
1097 * if (DRM_TRUSTED_RETURN_SUCCESS == ret) {
1103 if (drm_oem_intel_decrypt_package(const_cast<char*>(widgetPath.c_str()),
1104 const_cast<char*>(destPath.c_str())) != 0)
1111 } //namespace WidgetInstall