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>
73 #include <widget_install/task_plugins_copy.h>
75 #include <widget_install/widget_install_errors.h>
76 #include <widget_install/widget_install_context.h>
77 #include <widget_install_to_external.h>
79 using namespace WrtDB;
80 using namespace Jobs::Exceptions;
82 namespace // anonymous
84 const char * const CONFIG_XML = "config.xml";
85 const char * const WITH_OSP_XML = "res/wgt/config.xml";
87 //allowed: a-z, A-Z, 0-9
88 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
89 const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
90 const size_t PACKAGE_ID_LENGTH = 10;
92 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
93 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
94 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
95 L"install-location-type";
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,
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.m_quiet = m_jobStruct.m_quiet;
168 ConfigureResult result = PrePareInstallation(widgetPath);
170 if (result == ConfigureResult::Ok) {
171 LogInfo("Configure installation succeeded");
172 m_installerContext.job->SetProgressFlag(true);
174 AddTask(new TaskRecovery(m_installerContext));
176 // Create installation tasks
177 if (m_installerContext.widgetConfig.packagingType !=
178 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
179 m_installerContext.widgetConfig.packagingType !=
180 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
183 AddTask(new TaskUnzip(m_installerContext));
186 AddTask(new TaskWidgetConfig(m_installerContext));
187 if (m_installerContext.widgetConfig.packagingType ==
188 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
190 AddTask(new TaskPrepareFiles(m_installerContext));
192 AddTask(new TaskCertify(m_installerContext));
193 if (m_needEncryption) {
194 AddTask(new TaskEncryptResource(m_installerContext));
197 AddTask(new TaskFileManipulation(m_installerContext));
198 // TODO: Update progress information for this task
200 //This is sort of quick solution, because ACE verdicts are based upon
201 //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
203 AddTask(new TaskSmack(m_installerContext));
205 AddTask(new TaskManifestFile(m_installerContext));
206 if (m_installerContext.widgetConfig.packagingType ==
207 PKG_TYPE_HYBRID_WEB_APP)
209 AddTask(new TaskInstallOspsvc(m_installerContext));
211 AddTask(new TaskCertificates(m_installerContext));
212 AddTask(new TaskPluginsCopy(m_installerContext));
213 AddTask(new TaskDatabase(m_installerContext));
214 AddTask(new TaskAceCheck(m_installerContext));
215 } else if (result == ConfigureResult::Updated) {
216 LogInfo("Configure installation updated");
217 LogInfo("Widget Update");
218 m_installerContext.job->SetProgressFlag(true);
219 if (m_installerContext.widgetConfig.packagingType !=
220 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
221 m_installerContext.widgetConfig.packagingType !=
222 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
225 AddTask(new TaskUnzip(m_installerContext));
228 AddTask(new TaskWidgetConfig(m_installerContext));
230 if (m_installerContext.widgetConfig.packagingType ==
231 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
233 AddTask(new TaskPrepareFiles(m_installerContext));
236 AddTask(new TaskCertify(m_installerContext));
237 if (m_needEncryption) {
238 AddTask(new TaskEncryptResource(m_installerContext));
241 if (m_installerContext.widgetConfig.packagingType !=
242 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
244 AddTask(new TaskUpdateFiles(m_installerContext));
247 /* TODO : To backup file, save md5 values */
248 AddTask(new TaskSmack(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 if (m_installerContext.widgetConfig.packagingType !=
257 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
259 AddTask(new TaskRemoveBackupFiles(m_installerContext));
261 AddTask(new TaskPluginsCopy(m_installerContext));
262 AddTask(new TaskDatabase(m_installerContext));
263 AddTask(new TaskAceCheck(m_installerContext));
264 //TODO: remove widgetHandle from this task and move before database task
265 // by now widget handle is needed in ace check
266 // Any error in acecheck while update will break widget
267 } else if (result == ConfigureResult::Deferred) {
268 // Installation is deferred
269 LogInfo("Configure installation deferred");
271 AddTask(new InstallerTaskFail(result));
272 } else if (result >= ConfigureResult::Failed &&
273 result <= ConfigureResult::Failed_DrmError) {
274 // Installation is not allowed to proceed due to widget update policy
275 LogWarning("Configure installation failed!");
277 AddTask(new InstallerTaskFail(result));
279 Assert(false && "Invalid configure result!");
283 ConfigureResult JobWidgetInstall::PrePareInstallation(
284 const std::string &widgetPath)
286 ConfigureResult result;
287 m_needEncryption = false;
291 std::string tempDir =
292 Jobs::WidgetInstall::createTempPath(m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_PRELOAD);
294 m_isDRM = isDRMWidget(widgetPath);
295 if (true == m_isDRM) {
296 LogDebug("decrypt DRM widget");
297 if (DecryptDRMWidget(widgetPath, tempDir)) {
298 LogDebug("Failed decrypt DRM widget");
299 return ConfigureResult::Failed_DrmError;
303 LogDebug("widgetPath:" << widgetPath);
305 m_installerContext.widgetConfig.packagingType =
306 checkPackageType(widgetPath, tempDir);
307 ConfigParserData configData = getWidgetDataFromXML(
310 m_installerContext.widgetConfig.packagingType,
312 LogDebug("widget packaging type : " <<
313 m_installerContext.widgetConfig.packagingType.pkgType);
315 setTizenId(configData);
316 setApplicationType(configData);
317 m_needEncryption = detectResourceEncryption(configData);
318 setInstallLocationType(configData);
320 // Configure installation
321 result = ConfigureInstallation(widgetPath, configData, tempDir);
323 Catch(Exceptions::ExtractFileFailed)
325 LogError("Failed to create temporary path for widget");
326 result = ConfigureResult::Failed_InvalidConfig;
332 void JobWidgetInstall::setTizenId(
333 const WrtDB::ConfigParserData &configInfo)
335 bool shouldMakeAppid = false;
336 using namespace PackageManager;
337 if (!!configInfo.tizenAppId) {
338 LogDebug("Setting tizenAppId provided in config.xml: " <<
339 configInfo.tizenAppId);
341 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
343 if (!!configInfo.tizenPkgId) {
344 LogDebug("Setting tizenPkgId provided in config.xml: " <<
345 configInfo.tizenPkgId);
347 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
349 DPL::String appid = *configInfo.tizenAppId;
350 if (appid.length() > PACKAGE_ID_LENGTH) {
351 m_installerContext.widgetConfig.tzPkgid =
352 appid.substr(0, PACKAGE_ID_LENGTH);
354 //old version appid only has 10byte random character is able to install for a while.
355 //this case appid equal pkgid.
356 m_installerContext.widgetConfig.tzPkgid =
357 *configInfo.tizenAppId;
358 shouldMakeAppid = true;
362 shouldMakeAppid = true;
363 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
364 LogDebug("Checking if pkg id is unique");
366 if (!validateTizenPackageID(pkgId)) {
367 //path exist, chose another one
368 pkgId = WidgetDAOReadOnly::generatePkgId();
373 m_installerContext.widgetConfig.tzPkgid = pkgId;
374 LogInfo("tizen_id name was generated by WRT: " <<
375 m_installerContext.widgetConfig.tzPkgid);
378 if (shouldMakeAppid == true) {
379 DPL::OptionalString name;
380 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
382 FOREACH(localizedData, configInfo.localizedDataSet)
384 Locale i = localizedData->first;
385 if (!!defaultLocale) {
386 if (defaultLocale == i) {
387 name = localizedData->second.name;
391 name = localizedData->second.name;
396 if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
397 LogDebug("Regcomp failed");
400 LogDebug("Name : " << name);
401 if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
402 static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
404 // TODO : generate name move to wrt-commons
405 std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
406 std::ostringstream genName;
408 gettimeofday(&tv, NULL);
409 unsigned int seed = time(NULL) + tv.tv_usec;
411 genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
412 name = DPL::FromUTF8String(genName.str());
413 LogDebug("name was generated by WRT");
416 LogDebug("Name : " << name);
417 std::ostringstream genid;
418 genid << m_installerContext.widgetConfig.tzPkgid << "." << name;
419 LogDebug("tizen appid was generated by WRT : " << genid.str());
421 DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
422 NormalizeAndTrimSpaceString(appid);
423 m_installerContext.widgetConfig.tzAppid = *appid;
426 // send start signal of pkgmgr
427 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
431 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
432 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
433 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
436 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
437 const std::string& tempPath)
439 m_installerContext.locations =
440 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
442 widgetPath, tempPath,
443 m_installerContext.widgetConfig.packagingType,
444 m_installerContext.locationType);
445 m_installerContext.locations->registerAppid(
446 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
448 LogInfo("widgetSource " << widgetPath);
451 ConfigureResult JobWidgetInstall::ConfigureInstallation(
452 const std::string &widgetSource,
453 const WrtDB::ConfigParserData &configData,
454 const std::string &tempPath)
456 ConfigureResult result = ConfigureResult::Failed;
457 WidgetUpdateInfo update;
459 // checking installed web application
461 // checking existing application is installed
462 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
463 // no excpetion means, it isn't update mode
464 getInstallerStruct().pkgmgrInterface->sendSignal(
466 PKGMGR_START_UPDATE);
468 update = detectWidgetUpdate(configData,
469 m_installerContext.widgetConfig.tzAppid);
470 result = checkWidgetUpdate(update);
471 if (result != ConfigureResult::Updated) {
472 // Already installed TizenAppId. return failed
473 return ConfigureResult::Failed_AlreadyInstalled;
475 m_installerContext.isUpdateMode = true;
477 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
478 result = ConfigureResult::Ok;
479 getInstallerStruct().pkgmgrInterface->sendSignal(
481 PKGMGR_START_INSTALL);
482 m_installerContext.isUpdateMode = false;
484 if (!validateTizenApplicationID(
485 m_installerContext.widgetConfig.tzAppid))
487 LogError("tizen application ID is already used");
488 return ConfigureResult::Failed_InvalidConfig;
490 if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) {
491 LogError("tizen package ID is already used");
492 return ConfigureResult::Failed_AlreadyInstalled;
496 configureWidgetLocation(widgetSource, tempPath);
498 // Init installer context
499 m_installerContext.installStep = InstallerContext::INSTALL_START;
500 m_installerContext.job = this;
501 m_installerContext.widgetConfig.shareHref = std::string();
506 bool JobWidgetInstall::validateTizenApplicationID(
507 const WrtDB::TizenAppId &tizenAppId)
509 LogInfo("tizen application ID = [" << tizenAppId << "]");
512 if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
513 LogDebug("Regcomp failed");
516 if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
526 bool JobWidgetInstall::validateTizenPackageID(
527 const WrtDB::TizenPkgId &tizenPkgId)
529 std::string pkgId = DPL::ToUTF8String(tizenPkgId);
531 std::string installPath =
532 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
534 std::string preinstallPath =
535 std::string(GlobalConfig::GetUserPreloadedWidgetPath()) +
539 if ((stat(installPath.c_str(), &dirStat) == 0) ||
540 (stat(preinstallPath.c_str(), &dirStat) == 0))
547 ConfigureResult JobWidgetInstall::checkWidgetUpdate(
548 const WidgetUpdateInfo &update)
550 LogInfo("incoming version = '" << update.incomingVersion);
551 LogInfo("Tizen AppID = " << update.tzAppId);
553 // Check running state
554 bool isRunning = false;
556 app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
558 if (APP_MANAGER_ERROR_NONE != retval || isRunning) {
559 LogError("Fail to get running state");
560 return ConfigureResult::Failed_WidgetRunning;
563 m_installerContext.widgetConfig.tzAppid = update.tzAppId;
565 if (isUpperVersion(update.existingVersion, update.incomingVersion) ||
566 m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY)
568 LogInfo("Whether widget policy allow proceed ok");
569 return ConfigureResult::Updated;
571 return ConfigureResult::Failed_LowerVersion;
574 return ConfigureResult::Failed;
577 bool JobWidgetInstall::isUpperVersion(
578 const OptionalWidgetVersion &existingVersion,
579 const OptionalWidgetVersion &incomingVersion)
581 LogInfo("Existing version = '" << *existingVersion);
582 LogInfo("Incoming version = '" << *incomingVersion);
584 if (!existingVersion && !incomingVersion) {
586 } else if (!existingVersion && !!incomingVersion) {
588 } else if (!!existingVersion && !incomingVersion) {
591 if (!existingVersion->IsWac() || !incomingVersion->IsWac()) {
594 if (*incomingVersion == *existingVersion) {
596 } else if (*incomingVersion > *existingVersion) {
605 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
606 const std::string &widgetSource,
607 const std::string &tempPath,
608 WrtDB::PackagingType pkgType,
613 ConfigParserData configInfo;
617 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
618 parser.Parse(widgetSource,
620 new RootParser<WidgetParser>(configInfo,
621 DPL::FromUTF32String(
623 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
624 parser.Parse(widgetSource + '/' + WITH_OSP_XML,
626 new RootParser<WidgetParser>(
628 DPL::FromUTF32String(L"widget"))));
631 std::unique_ptr<DPL::ZipInput> zipFile(
632 new DPL::ZipInput(widgetSource));
634 std::unique_ptr<DPL::ZipInput::File> configFile;
636 // Open config.xml file
637 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
638 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
640 configFile.reset(zipFile->OpenFile(CONFIG_XML));
644 DPL::BinaryQueue buffer;
645 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
646 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
647 DPL::Copy(&inputAdapter, &outputAdapter);
648 parser.Parse(&buffer,
650 new RootParser<WidgetParser>(configInfo,
656 std::string configFile;
657 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
658 configFile = tempPath + "/" + WITH_OSP_XML;
660 configFile = tempPath + "/" + CONFIG_XML;
663 parser.Parse(configFile,
665 new RootParser<WidgetParser>(configInfo,
672 Catch(DPL::ZipInput::Exception::OpenFailed)
674 LogError("Failed to open widget package");
675 return ConfigParserData();
677 Catch(DPL::ZipInput::Exception::OpenFileFailed)
679 LogError("Failed to open config.xml file");
680 return ConfigParserData();
682 Catch(DPL::CopyFailed)
684 LogError("Failed to extract config.xml file");
685 return ConfigParserData();
687 Catch(DPL::FileInput::Exception::OpenFailed)
689 LogError("Failed to open config.xml file");
690 return ConfigParserData();
692 Catch(ElementParser::Exception::ParseError)
694 LogError("Failed to parse config.xml file");
695 return ConfigParserData();
697 Catch(DPL::ZipInput::Exception::SeekFileFailed)
699 LogError("Failed to seek widget archive - corrupted package?");
700 return ConfigParserData();
705 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
706 const ConfigParserData &configInfo,
707 const WrtDB::TizenAppId &tizenId)
709 LogInfo("Checking up widget package for config.xml...");
710 OptionalWidgetVersion incomingVersion;
712 if (!configInfo.version.IsNull()) {
714 DPL::Optional<WidgetVersion>(
715 WidgetVersion(*configInfo.version));
718 WidgetDAOReadOnly dao(tizenId);
719 return WidgetUpdateInfo(
721 WidgetVersion(*dao.getVersion()),
725 void JobWidgetInstall::SendProgress()
727 using namespace PackageManager;
728 if (GetProgressFlag() != false) {
729 if (getInstallerStruct().progressCallback != NULL) {
730 // send progress signal of pkgmgr
731 std::ostringstream percent;
732 percent << static_cast<int>(GetProgressPercent());
733 getInstallerStruct().pkgmgrInterface->sendSignal(
737 LogDebug("Call widget install progressCallbak");
738 getInstallerStruct().progressCallback(
739 getInstallerStruct().userParam,
740 GetProgressPercent(),
741 GetProgressDescription());
746 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
748 using namespace PackageManager;
749 if (GetProgressFlag() != false) {
750 if (getInstallerStruct().progressCallback != NULL) {
751 // send progress signal of pkgmgr
752 getInstallerStruct().pkgmgrInterface->sendSignal(
759 void JobWidgetInstall::SendFinishedSuccess()
761 using namespace PackageManager;
762 // TODO : sync should move to separate task.
765 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
766 if (m_installerContext.isUpdateMode) {
767 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
769 WidgetInstallToExtSingleton::Instance().postInstallation(true);
771 WidgetInstallToExtSingleton::Instance().deinitialize();
774 // remove widget install information file
775 unlink(m_installerContext.installInfo.c_str());
778 JobWidgetInstall::displayWidgetInfo();
780 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
782 // send signal of pkgmgr
783 getInstallerStruct().pkgmgrInterface->sendSignal(
787 LogDebug("Call widget install successfinishedCallback");
788 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
790 tizenId), Jobs::Exceptions::Success);
793 void JobWidgetInstall::SendFinishedFailure()
795 using namespace PackageManager;
796 // remove widget install information file
797 unlink(m_installerContext.installInfo.c_str());
799 LogError("Error number: " << m_exceptionCaught);
800 LogError("Message: " << m_exceptionMessage);
801 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
803 LogDebug("Call widget install failure finishedCallback");
804 std::stringstream errorNum;
805 errorNum << m_exceptionCaught;
807 // send signal of pkgmgr
808 getInstallerStruct().pkgmgrInterface->sendSignal(
812 getInstallerStruct().pkgmgrInterface->sendSignal(
816 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
818 tizenId), m_exceptionCaught);
821 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
823 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
824 m_exceptionMessage = e.GetMessage();
827 void JobWidgetInstall::displayWidgetInfo()
829 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
831 std::ostringstream out;
832 WidgetLocalizedInfo localizedInfo =
833 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
836 "===================================== INSTALLED WIDGET INFO =========" \
837 "============================";
838 out << std::endl << "Name: " << localizedInfo.name;
839 out << std::endl << "AppId: " << dao.getTzAppId();
840 WidgetSize size = dao.getPreferredSize();
841 out << std::endl << "Width: " << size.width;
842 out << std::endl << "Height: " << size.height;
843 out << std::endl << "Start File: " <<
844 W3CFileLocalization::getStartFile(dao.getTzAppId());
845 out << std::endl << "Version: " << dao.getVersion();
846 out << std::endl << "Licence: " <<
847 localizedInfo.license;
848 out << std::endl << "Licence Href: " <<
849 localizedInfo.licenseHref;
850 out << std::endl << "Description: " <<
851 localizedInfo.description;
852 out << std::endl << "Widget Id: " << dao.getGUID();
853 out << std::endl << "Widget recognized: " << dao.isRecognized();
854 out << std::endl << "Widget distributor signed: " <<
855 dao.isDistributorSigned();
856 out << std::endl << "Widget trusted: " << dao.isTrusted();
858 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
859 DPL::OptionalString iconSrc =
860 !!icon ? icon->src : DPL::OptionalString::Null;
861 out << std::endl << "Icon: " << iconSrc;
863 out << std::endl << "Preferences:";
865 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
868 out << std::endl << " Key: " <<
870 out << std::endl << " Readonly: " <<
875 out << std::endl << "Features:";
877 WidgetFeatureSet list = dao.getFeaturesList();
880 out << std::endl << " Name: " << it->name;
889 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
890 const std::string &widgetSource,
891 const std::string &tempPath)
893 // Check installation type (direcotory/ or config.xml or widget.wgt)
894 if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY)
896 LogDebug("Install directly from directory");
897 return PKG_TYPE_DIRECTORY_WEB_APP;
899 if (hasExtension(widgetSource, XML_EXTENSION)) {
900 LogInfo("Hosted app installation");
901 return PKG_TYPE_HOSTED_WEB_APP;
905 std::string configFile = tempPath + "/" + CONFIG_XML;
906 if (WrtUtilFileExists(configFile)) {
907 return PKG_TYPE_NOMAL_WEB_APP;
910 configFile = tempPath + "/" + WITH_OSP_XML;
911 if (WrtUtilFileExists(configFile)) {
912 return PKG_TYPE_HYBRID_WEB_APP;
915 std::unique_ptr<DPL::ZipInput> zipFile;
920 zipFile.reset(new DPL::ZipInput(widgetSource));
922 Catch(DPL::ZipInput::Exception::OpenFailed)
924 LogDebug("Failed to open widget package");
925 return PKG_TYPE_UNKNOWN;
927 Catch(DPL::ZipInput::Exception::SeekFileFailed)
929 LogError("Failed to seek widget package file");
930 return PKG_TYPE_UNKNOWN;
935 // Open config.xml file in package root
936 std::unique_ptr<DPL::ZipInput::File> configFile(
937 zipFile->OpenFile(CONFIG_XML));
938 return PKG_TYPE_NOMAL_WEB_APP;
940 Catch(DPL::ZipInput::Exception::OpenFileFailed)
942 LogDebug("Could not find config.xml");
947 // Open config.xml file in package root
948 std::unique_ptr<DPL::ZipInput::File> configFile(
949 zipFile->OpenFile(WITH_OSP_XML));
951 return PKG_TYPE_HYBRID_WEB_APP;
953 Catch(DPL::ZipInput::Exception::OpenFileFailed)
955 LogDebug("Could not find wgt/config.xml");
956 return PKG_TYPE_UNKNOWN;
960 return PKG_TYPE_UNKNOWN;
963 void JobWidgetInstall::setApplicationType(
964 const WrtDB::ConfigParserData &configInfo)
966 FOREACH(iterator, configInfo.nameSpaces) {
967 LogInfo("namespace = [" << *iterator << "]");
968 AppType currentAppType = APP_TYPE_UNKNOWN;
970 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
974 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
976 ConfigurationNamespace::WacWidgetNamespaceName)
978 currentAppType = APP_TYPE_WAC20;
979 } else if (*iterator ==
980 ConfigurationNamespace::TizenWebAppNamespaceName)
982 currentAppType = APP_TYPE_TIZENWEBAPP;
985 if (m_installerContext.widgetConfig.webAppType ==
988 m_installerContext.widgetConfig.webAppType = currentAppType;
989 } else if (m_installerContext.widgetConfig.webAppType ==
994 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
995 "Config.xml has more than one namespace");
999 // If there is no define, type set to WAC 2.0
1000 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
1001 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
1004 LogInfo("type = [" <<
1005 m_installerContext.widgetConfig.webAppType.getApptypeToString() <<
1009 bool JobWidgetInstall::detectResourceEncryption(
1010 const WrtDB::ConfigParserData &configData)
1012 FOREACH(it, configData.settingsList)
1014 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1015 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
1017 LogDebug("resource need encryption");
1024 void JobWidgetInstall::setInstallLocationType(
1026 WrtDB::ConfigParserData &
1029 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1031 if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_PRELOAD) {
1032 m_installerContext.locationType =
1033 INSTALL_LOCATION_TYPE_PRELOAD;
1035 FOREACH(it, configData.settingsList)
1037 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1039 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT)
1041 LogDebug("This widget will be installed to sd card");
1042 m_installerContext.locationType =
1043 INSTALL_LOCATION_TYPE_EXTERNAL;
1049 bool JobWidgetInstall::isDRMWidget(std::string /*widgetPath*/)
1055 bool JobWidgetInstall::DecryptDRMWidget(std::string /*widgetPath*/,
1056 std::string /*destPath*/)
1061 } //namespace WidgetInstall