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-rw/global_dao.h> // TODO remove
45 #include <dpl/localization/w3c_file_localization.h>
47 #include <libiriwrapper.h>
48 #include <pkg-manager/pkgmgr_signal.h>
49 #include <app_manager.h>
50 //#include <drm_client.h>
51 #include <drm-oem-intel.h> //temporary code
53 #include "root_parser.h"
54 #include "widget_parser.h"
55 #include "parser_runner.h"
56 #include <widget_install/job_widget_install.h>
57 #include <widget_install/task_certify.h>
58 #include <widget_install/task_widget_config.h>
59 #include <widget_install/task_file_manipulation.h>
60 #include <widget_install/task_ace_check.h>
61 #include <widget_install/task_smack.h>
62 #include <widget_install/task_manifest_file.h>
63 #include <widget_install/task_prepare_files.h>
64 #include <widget_install/task_recovery.h>
65 #include <widget_install/task_install_ospsvc.h>
66 #include <widget_install/task_update_files.h>
67 #include <widget_install/task_database.h>
68 #include <widget_install/task_remove_backup.h>
69 #include <widget_install/task_encrypt_resource.h>
70 #include <widget_install/task_certificates.h>
71 #include <widget_install/task_unzip.h>
72 #include <widget_install/task_commons.h>
74 #include <widget_install/task_plugins_copy.h>
76 #include <widget_install/widget_install_errors.h>
77 #include <widget_install/widget_install_context.h>
78 #include <widget_install_to_external.h>
80 using namespace WrtDB;
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 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 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
94 L"install-location-type";
95 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
98 class InstallerTaskFail :
99 public DPL::TaskDecl<InstallerTaskFail>
107 ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred,
108 "Widget installation or update deferred!");
110 ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed,
111 "Widget installation or update not allowed!");
116 InstallerTaskFail(bool deferred) :
117 DPL::TaskDecl<InstallerTaskFail>(this),
120 AddStep(&InstallerTaskFail::StepFail);
124 const std::string XML_EXTENSION = ".xml";
126 bool hasExtension(const std::string& filename, const std::string& extension) {
127 LogDebug("Looking for extension " << extension << " in: " << filename);
128 size_t fileLen = filename.length();
129 size_t extLen = extension.length();
130 if (fileLen < extLen) {
131 LogError("Filename " << filename << " is shorter than extension "
135 return (0 == filename.compare(fileLen-extLen, extLen, extension));
138 bool checkTizenPkgIdExist(const std::string& tizenPkgId) {
139 std::string installPath =
140 std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
142 std::string preinstallPath =
143 std::string(GlobalConfig::GetUserPreloadedWidgetPath()) +
147 if ((stat(installPath.c_str(), &dirStat) == 0) &&
148 (stat(preinstallPath.c_str(), &dirStat) == 0)) {
153 } // namespace anonymous
156 namespace WidgetInstall {
157 JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath,
158 const WidgetInstallationStruct &installerStruct) :
160 JobContextBase<WidgetInstallationStruct>(installerStruct),
161 m_exceptionCaught(Exceptions::Success)
164 gettimeofday(&tv, NULL);
165 srand(time(NULL) + tv.tv_usec);
167 m_installerContext.m_quiet = m_jobStruct.m_quiet;
169 ConfigureResult result = PrePareInstallation(widgetPath);
170 m_installerContext.job->SetProgressFlag(true);
172 if (result == ConfigureResult::Ok) {
173 LogInfo("Configure installation succeeded");
175 AddTask(new TaskRecovery(m_installerContext));
177 // Create installation tasks
178 if (m_installerContext.widgetConfig.packagingType !=
179 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
180 m_installerContext.widgetConfig.packagingType !=
181 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
184 AddTask(new TaskUnzip(m_installerContext));
187 AddTask(new TaskWidgetConfig(m_installerContext));
188 if (m_installerContext.widgetConfig.packagingType ==
189 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
191 AddTask(new TaskPrepareFiles(m_installerContext));
193 AddTask(new TaskCertify(m_installerContext));
194 if (m_needEncryption) {
195 AddTask(new TaskEncryptResource(m_installerContext));
198 AddTask(new TaskFileManipulation(m_installerContext));
199 // TODO: Update progress information for this task
201 //This is sort of quick solution, because ACE verdicts are based upon
202 //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
204 AddTask(new TaskSmack(m_installerContext));
206 AddTask(new TaskManifestFile(m_installerContext));
207 AddTask(new TaskCertificates(m_installerContext));
208 if (m_installerContext.widgetConfig.packagingType ==
209 PKG_TYPE_HYBRID_WEB_APP) {
210 AddTask(new TaskInstallOspsvc(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 if (m_installerContext.widgetConfig.packagingType !=
219 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
220 m_installerContext.widgetConfig.packagingType !=
221 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
224 AddTask(new TaskUnzip(m_installerContext));
227 AddTask(new TaskWidgetConfig(m_installerContext));
229 if (m_installerContext.widgetConfig.packagingType ==
230 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
232 AddTask(new TaskPrepareFiles(m_installerContext));
235 AddTask(new TaskCertify(m_installerContext));
236 if (m_installerContext.widgetConfig.packagingType !=
237 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
239 AddTask(new TaskUpdateFiles(m_installerContext));
242 /* TODO : To backup file, save md5 values */
243 AddTask(new TaskSmack(m_installerContext));
245 AddTask(new TaskManifestFile(m_installerContext));
246 if (m_installerContext.widgetConfig.packagingType ==
247 PKG_TYPE_HYBRID_WEB_APP) {
248 AddTask(new TaskInstallOspsvc(m_installerContext));
250 if (m_installerContext.widgetConfig.packagingType !=
251 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
253 AddTask(new TaskRemoveBackupFiles(m_installerContext));
255 AddTask(new TaskPluginsCopy(m_installerContext));
256 AddTask(new TaskDatabase(m_installerContext));
257 AddTask(new TaskAceCheck(m_installerContext));
258 //TODO: remove widgetHandle from this task and move before database task
259 // by now widget handle is needed in ace check
260 // Any error in acecheck while update will break widget
262 } else if (result == ConfigureResult::Deferred) {
263 // Installation is deferred
264 LogInfo("Configure installation deferred");
266 AddTask(new InstallerTaskFail(true));
267 } else if (result == ConfigureResult::Failed) {
268 // Installation is not allowed to proceed due to widget update policy
269 LogWarning("Configure installation failed!");
271 AddTask(new InstallerTaskFail(false));
273 Assert(false && "Invalid configure result!");
277 JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation(
278 const std::string &widgetPath)
280 ConfigureResult result;
281 m_needEncryption = false;
285 std::string tempDir =
286 Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload);
288 m_isDRM = isDRMWidget(widgetPath);
289 if (true == m_isDRM) {
290 LogDebug("decrypt DRM widget");
291 if(DecryptDRMWidget(widgetPath, tempDir)) {
292 LogDebug("Failed decrypt DRM widget");
293 return ConfigureResult::Failed;
297 LogDebug("widgetPath:" << widgetPath);
299 m_installerContext.widgetConfig.packagingType =
300 checkPackageType(widgetPath, tempDir);
301 ConfigParserData configData = getWidgetDataFromXML(
304 m_installerContext.widgetConfig.packagingType,
306 LogDebug("widget packaging type : " <<
307 m_installerContext.widgetConfig.packagingType.pkgType);
309 setTizenId(configData);
310 setApplicationType(configData);
311 m_needEncryption = detectResourceEncryption(configData);
312 setInstallLocationType(configData);
314 // Configure installation
315 result = ConfigureInstallation(widgetPath, configData, tempDir);
317 Catch(Exceptions::ExtractFileFailed)
319 LogError("Failed to create temporary path for widget");
320 result = ConfigureResult::Failed;
326 void JobWidgetInstall::setTizenId(
327 const WrtDB::ConfigParserData &configInfo)
329 bool shouldMakeAppid = false;
330 using namespace PackageManager;
331 if(!!configInfo.tizenAppId) {
332 LogDebug("Setting tizenAppId provided in config.xml: " <<
333 configInfo.tizenAppId);
335 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
337 if(!!configInfo.tizenPkgId) {
338 LogDebug("Setting tizenPkgId provided in config.xml: " <<
339 configInfo.tizenPkgId);
341 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
343 std::string appid = DPL::ToUTF8String(*configInfo.tizenAppId);
344 if(appid.length() > PACKAGE_ID_LENGTH) {
345 m_installerContext.widgetConfig.tzPkgid =
346 DPL::FromUTF8String(appid.substr(PACKAGE_ID_LENGTH));
348 m_installerContext.widgetConfig.tzPkgid =
349 *configInfo.tizenAppId;
351 shouldMakeAppid = true;
354 shouldMakeAppid = true;
355 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
356 LogDebug("Checking if pkg id is unique");
358 if (checkTizenPkgIdExist(DPL::ToUTF8String(pkgId))) {
359 //path exist, chose another one
360 pkgId = WidgetDAOReadOnly::generatePkgId();
365 m_installerContext.widgetConfig.tzPkgid = pkgId;
366 LogInfo("tizen_id name was generated by WRT: " <<
367 m_installerContext.widgetConfig.tzPkgid);
371 if(shouldMakeAppid == true) {
372 DPL::OptionalString name;
373 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
375 FOREACH(localizedData, configInfo.localizedDataSet)
377 Locale i = localizedData->first;
378 if (!!defaultLocale) {
379 if (defaultLocale == i) {
380 name = localizedData->second.name;
385 name = localizedData->second.name;
390 LogDebug("Name : " << name);
391 std::ostringstream appid;
392 appid << m_installerContext.widgetConfig.tzPkgid << "." << name;
393 LogDebug("tizen appid was generated by WRT : " << appid.str());
394 m_installerContext.widgetConfig.tzAppid =
395 DPL::FromUTF8String(appid.str());
397 m_installerContext.widgetConfig.tzAppid =
398 m_installerContext.widgetConfig.tzPkgid;
402 // send start signal of pkgmgr
403 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
404 m_installerContext.widgetConfig.tzAppid));
405 getInstallerStruct().pkgmgrInterface->sendSignal(
407 PKGMGR_START_INSTALL);
409 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
410 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
411 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
414 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
415 const std::string& tempPath)
417 m_installerContext.locations =
418 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.tzPkgid),
419 widgetPath, tempPath,
420 m_installerContext.widgetConfig.packagingType,
421 m_installerContext.locationType);
422 m_installerContext.locations->registerAppid(
423 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
425 LogInfo("widgetSource " << widgetPath);
428 JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
429 const std::string &widgetSource,
430 const WrtDB::ConfigParserData &configData,
431 const std::string &tempPath)
433 WidgetUpdateInfo update = detectWidgetUpdate(configData,
434 m_installerContext.widgetConfig.webAppType,
435 m_installerContext.widgetConfig.tzAppid);
436 ConfigureResult result = checkWidgetUpdate(update);
440 if(regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
441 LogDebug("Regcomp failed");
445 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid).c_str(),
446 static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
447 (checkTizenPkgIdExist(DPL::ToUTF8String(m_installerContext.widgetConfig.tzPkgid)) &&
448 result != ConfigureResult::Updated))
450 //it is true when tizenId does not fit REG_TIZENID_PATTERN
451 LogError("tizen_id provided but not proper.");
453 return ConfigureResult::Failed;
457 configureWidgetLocation(widgetSource, tempPath);
459 // Init installer context
460 m_installerContext.installStep = InstallerContext::INSTALL_START;
461 m_installerContext.job = this;
462 m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
463 m_installerContext.widgetConfig.shareHref = std::string();
468 JobWidgetInstall::ConfigureResult JobWidgetInstall::checkWidgetUpdate(
469 const WidgetUpdateInfo &update)
472 "Widget install/update: incoming guid = '" <<
473 update.incomingGUID << "'");
475 "Widget install/update: incoming version = '" <<
476 update.incomingVersion << "'");
479 WidgetUpdateMode::Type updateTypeCheckBit;
481 if (update.existingWidgetInfo.isExist == false) {
482 LogInfo("Widget info does not exist");
483 updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
485 LogInfo("Widget info exists. appid: " <<
486 update.existingWidgetInfo.tzAppid);
488 TizenAppId tzAppid = update.existingWidgetInfo.tzAppid;
490 LogInfo("Widget model exists. tizen app id: " << tzAppid);
492 // Check running state
493 int retval = APP_MANAGER_ERROR_NONE;
494 bool isRunning = false;
495 retval = app_manager_is_running(DPL::ToUTF8String(tzAppid).c_str(), &isRunning);
496 if (APP_MANAGER_ERROR_NONE != retval) {
497 LogError("Fail to get running state");
498 return ConfigureResult::Failed;
501 if (true == isRunning) {
502 // Must be deferred when update in progress
503 if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
505 "Widget is already running. Policy is update according to WAC");
507 return ConfigureResult::Deferred;
510 "Widget is already running. Policy is not update according to WAC");
512 return ConfigureResult::Failed;
516 m_installerContext.widgetConfig.tzAppid = tzAppid;
517 OptionalWidgetVersion existingVersion;
518 existingVersion = update.existingWidgetInfo.existingVersion;
519 OptionalWidgetVersion incomingVersion = update.incomingVersion;
521 updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
524 if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 ||
525 m_jobStruct.updateMode ==
526 WidgetUpdateMode::PolicyDirectoryForceInstall)
528 LogInfo("Whether widget policy allow proceed ok");
529 return ConfigureResult::Updated;
532 return ConfigureResult::Failed;
534 return ConfigureResult::Ok;
537 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
538 const OptionalWidgetVersion &existingVersion,
539 const OptionalWidgetVersion &incomingVersion) const
541 // Widget is installed, check versions
542 if (!existingVersion && !incomingVersion) {
543 return WidgetUpdateMode::ExistingVersionEqual;
544 } else if (!existingVersion && !!incomingVersion) {
545 return WidgetUpdateMode::ExistingVersionNewer;
546 } else if (!!existingVersion && !incomingVersion) {
547 return WidgetUpdateMode::ExistingVersionOlder;
549 LogInfo("Existing widget: version = '" << *existingVersion << "'");
551 if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
552 return WidgetUpdateMode::BothVersionsNotStd;
553 } else if (!existingVersion->IsWac()) {
554 return WidgetUpdateMode::ExistingVersionNotStd;
555 } else if (!incomingVersion->IsWac()) {
556 return WidgetUpdateMode::IncomingVersionNotStd;
558 // Both versions are WAC-comparable. Do compare.
559 if (*incomingVersion == *existingVersion) {
560 return WidgetUpdateMode::ExistingVersionEqual;
561 } else if (*incomingVersion > *existingVersion) {
562 return WidgetUpdateMode::ExistingVersionOlder;
564 return WidgetUpdateMode::ExistingVersionNewer;
570 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
571 const std::string &widgetSource,
572 const std::string &tempPath,
573 WrtDB::PackagingType pkgType,
578 ConfigParserData configInfo;
582 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
583 parser.Parse(widgetSource,
585 new RootParser<WidgetParser>(configInfo,
586 DPL::FromUTF32String(
588 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
589 parser.Parse(widgetSource + '/' + WITH_OSP_XML,
591 new RootParser<WidgetParser>(
593 DPL::FromUTF32String(L"widget"))));
596 std::unique_ptr<DPL::ZipInput> zipFile(
597 new DPL::ZipInput(widgetSource));
599 std::unique_ptr<DPL::ZipInput::File> configFile;
601 // Open config.xml file
602 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
603 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
605 configFile.reset(zipFile->OpenFile(CONFIG_XML));
609 DPL::BinaryQueue buffer;
610 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
611 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
612 DPL::Copy(&inputAdapter, &outputAdapter);
613 parser.Parse(&buffer,
615 new RootParser<WidgetParser>(configInfo,
616 DPL::FromUTF32String(
620 std::string configFile;
621 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
622 configFile = tempPath + "/" + WITH_OSP_XML;
624 configFile = tempPath + "/" + CONFIG_XML;
627 parser.Parse(configFile,
629 new RootParser<WidgetParser>(configInfo,
630 DPL::FromUTF32String(
635 Catch(DPL::ZipInput::Exception::OpenFailed)
637 LogError("Failed to open widget package");
638 return ConfigParserData();
640 Catch(DPL::ZipInput::Exception::OpenFileFailed)
642 LogError("Failed to open config.xml file");
643 return ConfigParserData();
645 Catch(DPL::CopyFailed)
647 LogError("Failed to extract config.xml file");
648 return ConfigParserData();
650 Catch(DPL::FileInput::Exception::OpenFailed)
652 LogError("Failed to open config.xml file");
653 return ConfigParserData();
655 Catch(ElementParser::Exception::ParseError)
657 LogError("Failed to parse config.xml file");
658 return ConfigParserData();
660 Catch(DPL::ZipInput::Exception::SeekFileFailed)
662 LogError("Failed to seek widget archive - corrupted package?");
663 return ConfigParserData();
668 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
669 const ConfigParserData &configInfo,
670 const WrtDB::WidgetType appType,
671 const WrtDB::TizenAppId &tizenId)
673 LogInfo("Checking up widget package for config.xml...");
675 DPL::OptionalString widgetGUID;
676 OptionalWidgetVersion widgetVersion;
679 widgetGUID = configInfo.widget_id;
681 if (widgetGUID.IsNull()) {
682 LogWarning("Installed widget has no GUID");
683 return WidgetUpdateInfo();
686 LogDebug("Installed widget GUID: " << *widgetGUID);
688 // Locate widget ID with this GUID
689 // Incoming widget version
690 if (!configInfo.version.IsNull()) {
692 DPL::Optional<WidgetVersion>(
693 WidgetVersion(*configInfo.version));
696 if (appType == APP_TYPE_WAC20) {
699 // Search widget handle by GUID
700 WidgetDAOReadOnly dao(widgetGUID);
701 return WidgetUpdateInfo(
704 WidgetUpdateInfo::ExistingWidgetInfo(
705 dao.getTzAppId(), dao.getVersion()));
707 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
709 // GUID isn't installed
710 return WidgetUpdateInfo(
713 WidgetUpdateInfo::ExistingWidgetInfo());
718 // Search widget handle by appId
719 WidgetDAOReadOnly dao(tizenId);
720 return WidgetUpdateInfo(
723 WidgetUpdateInfo::ExistingWidgetInfo(
724 dao.getTzAppId(), dao.getVersion()));
726 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
728 // GUID isn't installed
729 return WidgetUpdateInfo(
732 WidgetUpdateInfo::ExistingWidgetInfo());
738 void JobWidgetInstall::SendProgress()
740 using namespace PackageManager;
741 if (GetProgressFlag() != false) {
742 if (getInstallerStruct().progressCallback != NULL) {
743 // send progress signal of pkgmgr
744 std::ostringstream percent;
745 percent << static_cast<int>(GetProgressPercent());
746 getInstallerStruct().pkgmgrInterface->sendSignal(
750 LogDebug("Call widget install progressCallbak");
751 getInstallerStruct().progressCallback(getInstallerStruct().userParam,
752 GetProgressPercent(),GetProgressDescription());
757 void JobWidgetInstall::SendFinishedSuccess()
759 using namespace PackageManager;
760 // TODO : sync should move to separate task.
764 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
765 if (false == m_installerContext.existingWidgetInfo.isExist) {
766 WidgetInstallToExtSingleton::Instance().postInstallation(true);
768 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
770 WidgetInstallToExtSingleton::Instance().deinitialize();
773 // remove widget install information file
774 unlink(m_installerContext.installInfo.c_str());
777 JobWidgetInstall::displayWidgetInfo();
779 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
781 // send signal of pkgmgr
782 getInstallerStruct().pkgmgrInterface->sendSignal(
786 LogDebug("Call widget install successfinishedCallback");
787 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
788 DPL::ToUTF8String(tizenId), Exceptions::Success);
791 void JobWidgetInstall::SendFinishedFailure()
793 using namespace PackageManager;
794 // remove widget install information file
795 unlink(m_installerContext.installInfo.c_str());
797 LogError("Error in installation step: " << m_exceptionCaught);
798 LogError("Message: " << m_exceptionMessage);
799 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
801 LogDebug("Call widget install failure finishedCallback");
803 // send signal of pkgmgr
804 getInstallerStruct().pkgmgrInterface->sendSignal(
808 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
809 DPL::ToUTF8String(tizenId), m_exceptionCaught);
812 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
814 m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
815 m_exceptionMessage = e.GetMessage();
818 void JobWidgetInstall::displayWidgetInfo()
820 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
822 std::ostringstream out;
823 WidgetLocalizedInfo localizedInfo =
824 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
827 "===================================== INSTALLED WIDGET INFO ========="\
828 "============================";
829 out << std::endl << "Name: " << localizedInfo.name;
830 out << std::endl << "AppId: " << dao.getTzAppId();
831 WidgetSize size = dao.getPreferredSize();
832 out << std::endl << "Width: " << size.width;
833 out << std::endl << "Height: " << size.height;
834 out << std::endl << "Start File: " <<
835 W3CFileLocalization::getStartFile(dao.getTzAppId());
836 out << std::endl << "Version: " << dao.getVersion();
837 out << std::endl << "Licence: " <<
838 localizedInfo.license;
839 out << std::endl << "Licence Href: " <<
840 localizedInfo.licenseHref;
841 out << std::endl << "Description: " <<
842 localizedInfo.description;
843 out << std::endl << "Widget Id: " << dao.getGUID();
844 out << std::endl << "Widget recognized: " << dao.isRecognized();
845 out << std::endl << "Widget wac signed: " << dao.isWacSigned();
846 out << std::endl << "Widget distributor signed: " <<
847 dao.isDistributorSigned();
848 out << std::endl << "Widget trusted: " << dao.isTrusted();
850 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
851 DPL::OptionalString iconSrc = !!icon ? icon->src : DPL::OptionalString::Null;
852 out << std::endl << "Icon: " << iconSrc;
854 out << std::endl << "Preferences:";
856 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
859 out << std::endl << " Key: " <<
861 out << std::endl << " Readonly: " <<
866 out << std::endl << "Features:";
868 WidgetFeatureSet list = dao.getFeaturesList();
871 out << std::endl << " Name: " << it->name;
872 out << std::endl << " Required: " << it->required;
873 out << std::endl << " Params:";
882 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
883 const std::string &widgetSource,
884 const std::string &tempPath)
886 // Check installation type (direcotory/ or config.xml or widget.wgt)
887 if (WidgetUpdateMode::PolicyDirectoryForceInstall == m_jobStruct.updateMode)
889 LogDebug("Install directly from directory");
890 return PKG_TYPE_DIRECTORY_WEB_APP;
892 if (hasExtension(widgetSource, XML_EXTENSION)) {
893 LogInfo("Hosted app installation");
894 return PKG_TYPE_HOSTED_WEB_APP;
898 std::string configFile = tempPath + "/" + CONFIG_XML;
899 if (WrtUtilFileExists(configFile)) {
900 return PKG_TYPE_NOMAL_WEB_APP;
903 configFile = tempPath + "/" + WITH_OSP_XML;
904 if (WrtUtilFileExists(configFile)) {
905 return PKG_TYPE_HYBRID_WEB_APP;
908 std::unique_ptr<DPL::ZipInput> zipFile;
913 zipFile.reset(new DPL::ZipInput(widgetSource));
916 Catch(DPL::ZipInput::Exception::OpenFailed)
918 LogDebug("Failed to open widget package");
919 return PKG_TYPE_UNKNOWN;
921 Catch(DPL::ZipInput::Exception::SeekFileFailed)
923 LogError("Failed to seek widget package file");
924 return PKG_TYPE_UNKNOWN;
929 // Open config.xml file in package root
930 std::unique_ptr<DPL::ZipInput::File> configFile(
931 zipFile->OpenFile(CONFIG_XML));
932 return PKG_TYPE_NOMAL_WEB_APP;
934 Catch(DPL::ZipInput::Exception::OpenFileFailed)
936 LogDebug("Could not find config.xml");
941 // Open config.xml file in package root
942 std::unique_ptr<DPL::ZipInput::File> configFile(
943 zipFile->OpenFile(WITH_OSP_XML));
945 return PKG_TYPE_HYBRID_WEB_APP;
947 Catch(DPL::ZipInput::Exception::OpenFileFailed)
949 LogDebug("Could not find wgt/config.xml");
950 return PKG_TYPE_UNKNOWN;
954 return PKG_TYPE_UNKNOWN;
957 void JobWidgetInstall::setApplicationType(
958 const WrtDB::ConfigParserData &configInfo)
961 FOREACH(iterator, configInfo.nameSpaces) {
962 LogInfo("namespace = [" << *iterator << "]");
963 AppType currentAppType = APP_TYPE_UNKNOWN;
965 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
969 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
971 ConfigurationNamespace::WacWidgetNamespaceName)
973 currentAppType = APP_TYPE_WAC20;
974 } else if (*iterator ==
975 ConfigurationNamespace::TizenWebAppNamespaceName) {
976 currentAppType = APP_TYPE_TIZENWEBAPP;
979 if (m_installerContext.widgetConfig.webAppType ==
981 m_installerContext.widgetConfig.webAppType = currentAppType;
982 } else if (m_installerContext.widgetConfig.webAppType ==
986 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
987 "Config.xml has more than one namespace");
991 // If there is no define, type set to WAC 2.0
992 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
993 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
996 LogInfo("type = [" <<
997 m_installerContext.widgetConfig.webAppType.getApptypeToString() << "]");
1000 bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
1002 FOREACH(it, configData.settingsList)
1004 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1005 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
1006 LogDebug("resource need encryption");
1013 void JobWidgetInstall::setInstallLocationType(const
1014 WrtDB::ConfigParserData &configData)
1016 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1018 if (true == m_jobStruct.m_preload) {
1019 m_installerContext.locationType =
1020 INSTALL_LOCATION_TYPE_PRELOAD;
1022 FOREACH(it, configData.settingsList)
1024 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1026 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
1027 LogDebug("This widget will be installed to sd card");
1028 m_installerContext.locationType =
1029 INSTALL_LOCATION_TYPE_EXTERNAL;
1035 bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
1038 drm_bool_type_e is_drm_file = DRM_UNKNOWN;
1041 ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file);
1042 if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) {
1045 /* blow code temporary code for drm. */
1046 int ret = drm_oem_intel_isDrmFile(const_cast<char*>(widgetPath.c_str()));
1054 bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath,
1055 std::string destPath)
1058 drm_trusted_sapps_decrypt_package_info_s package_info;
1060 strncpy(package_info.sadcf_filepath, widgetPath.c_str(),
1061 sizeof(package_info.sadcf_filepath));
1062 strncpy(package_info.decrypt_filepath, destPath.c_str(),
1063 sizeof(package_info.decrypt_filepath));
1065 drm_trusted_request_type_e requestType =
1066 DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
1068 int ret = drm_trusted_handle_request(requestType,
1069 (void *)&package_info, NULL);
1070 if (DRM_TRUSTED_RETURN_SUCCESS == ret) {
1076 if (drm_oem_intel_decrypt_package(const_cast<char*>(widgetPath.c_str()),
1077 const_cast<char*>(destPath.c_str())) != 0) {
1084 } //namespace WidgetInstall