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}.[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 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);
171 if (result == ConfigureResult::Ok) {
172 LogInfo("Configure installation succeeded");
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 AddTask(new TaskCertificates(m_installerContext));
207 if (m_installerContext.widgetConfig.packagingType ==
208 PKG_TYPE_HYBRID_WEB_APP) {
209 AddTask(new TaskInstallOspsvc(m_installerContext));
211 AddTask(new TaskPluginsCopy(m_installerContext));
212 AddTask(new TaskDatabase(m_installerContext));
213 AddTask(new TaskAceCheck(m_installerContext));
214 } else if (result == ConfigureResult::Updated) {
215 LogInfo("Configure installation updated");
216 LogInfo("Widget Update");
217 if (m_installerContext.widgetConfig.packagingType !=
218 WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
219 m_installerContext.widgetConfig.packagingType !=
220 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP &&
223 AddTask(new TaskUnzip(m_installerContext));
226 AddTask(new TaskWidgetConfig(m_installerContext));
228 if (m_installerContext.widgetConfig.packagingType ==
229 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
231 AddTask(new TaskPrepareFiles(m_installerContext));
234 AddTask(new TaskCertify(m_installerContext));
235 if (m_installerContext.widgetConfig.packagingType !=
236 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
238 AddTask(new TaskUpdateFiles(m_installerContext));
241 /* TODO : To backup file, save md5 values */
242 AddTask(new TaskSmack(m_installerContext));
244 AddTask(new TaskManifestFile(m_installerContext));
245 if (m_installerContext.widgetConfig.packagingType ==
246 PKG_TYPE_HYBRID_WEB_APP) {
247 AddTask(new TaskInstallOspsvc(m_installerContext));
249 if (m_installerContext.widgetConfig.packagingType !=
250 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
252 AddTask(new TaskRemoveBackupFiles(m_installerContext));
254 AddTask(new TaskPluginsCopy(m_installerContext));
255 AddTask(new TaskDatabase(m_installerContext));
256 AddTask(new TaskAceCheck(m_installerContext));
257 //TODO: remove widgetHandle from this task and move before database task
258 // by now widget handle is needed in ace check
259 // Any error in acecheck while update will break widget
261 } else if (result == ConfigureResult::Deferred) {
262 // Installation is deferred
263 LogInfo("Configure installation deferred");
265 AddTask(new InstallerTaskFail(true));
266 } else if (result == ConfigureResult::Failed) {
267 // Installation is not allowed to proceed due to widget update policy
268 LogWarning("Configure installation failed!");
270 AddTask(new InstallerTaskFail(false));
272 Assert(false && "Invalid configure result!");
276 JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation(
277 const std::string &widgetPath)
279 ConfigureResult result;
280 m_needEncryption = false;
284 std::string tempDir =
285 Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload);
287 m_isDRM = isDRMWidget(widgetPath);
288 if (true == m_isDRM) {
289 LogDebug("decrypt DRM widget");
290 if(DecryptDRMWidget(widgetPath, tempDir)) {
291 LogDebug("Failed decrypt DRM widget");
292 return ConfigureResult::Failed;
296 LogDebug("widgetPath:" << widgetPath);
298 m_installerContext.widgetConfig.packagingType =
299 checkPackageType(widgetPath, tempDir);
300 ConfigParserData configData = getWidgetDataFromXML(
303 m_installerContext.widgetConfig.packagingType,
305 LogDebug("widget packaging type : " <<
306 m_installerContext.widgetConfig.packagingType.pkgType);
308 setTizenId(configData);
309 setApplicationType(configData);
310 m_needEncryption = detectResourceEncryption(configData);
311 setInstallLocationType(configData);
313 // Configure installation
314 result = ConfigureInstallation(widgetPath, configData, tempDir);
316 Catch(Exceptions::ExtractFileFailed)
318 LogError("Failed to create temporary path for widget");
319 result = ConfigureResult::Failed;
325 void JobWidgetInstall::setTizenId(
326 const WrtDB::ConfigParserData &configInfo)
328 bool shouldMakeAppid = false;
329 using namespace PackageManager;
330 if(!!configInfo.tizenAppId) {
331 LogDebug("Setting tizenAppId provided in config.xml: " <<
332 configInfo.tizenAppId);
334 m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId;
336 if(!!configInfo.tizenPkgId) {
337 LogDebug("Setting tizenPkgId provided in config.xml: " <<
338 configInfo.tizenPkgId);
340 m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
342 std::string appid = DPL::ToUTF8String(*configInfo.tizenAppId);
343 if(appid.length() > PACKAGE_ID_LENGTH) {
344 m_installerContext.widgetConfig.tzPkgid =
345 DPL::FromUTF8String(appid.substr(PACKAGE_ID_LENGTH));
347 m_installerContext.widgetConfig.tzPkgid =
348 *configInfo.tizenAppId;
350 shouldMakeAppid = true;
353 shouldMakeAppid = true;
354 TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
355 LogDebug("Checking if pkg id is unique");
357 if (checkTizenPkgIdExist(DPL::ToUTF8String(pkgId))) {
358 //path exist, chose another one
359 pkgId = WidgetDAOReadOnly::generatePkgId();
364 m_installerContext.widgetConfig.tzPkgid = pkgId;
365 LogInfo("tizen_id name was generated by WRT: " <<
366 m_installerContext.widgetConfig.tzPkgid);
370 if(shouldMakeAppid == true) {
371 DPL::OptionalString name;
372 DPL::OptionalString defaultLocale = configInfo.defaultlocale;
374 FOREACH(localizedData, configInfo.localizedDataSet)
376 Locale i = localizedData->first;
377 if (!!defaultLocale) {
378 if (defaultLocale == i) {
379 name = localizedData->second.name;
384 name = localizedData->second.name;
389 LogDebug("Name : " << name);
390 std::ostringstream appid;
391 appid << m_installerContext.widgetConfig.tzPkgid << "." << name;
392 LogDebug("tizen appid was generated by WRT : " << appid.str());
393 m_installerContext.widgetConfig.tzAppid =
394 DPL::FromUTF8String(appid.str());
396 m_installerContext.widgetConfig.tzAppid =
397 m_installerContext.widgetConfig.tzPkgid;
401 // send start signal of pkgmgr
402 getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
403 m_installerContext.widgetConfig.tzAppid));
404 getInstallerStruct().pkgmgrInterface->sendSignal(
406 PKGMGR_START_INSTALL);
408 LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid);
409 LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid);
410 LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
413 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
414 const std::string& tempPath)
416 m_installerContext.locations =
417 WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid),
418 widgetPath, tempPath,
419 m_installerContext.widgetConfig.packagingType,
420 m_installerContext.locationType);
422 LogInfo("widgetSource " << widgetPath);
425 JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
426 const std::string &widgetSource,
427 const WrtDB::ConfigParserData &configData,
428 const std::string &tempPath)
430 WidgetUpdateInfo update = detectWidgetUpdate(configData,
431 m_installerContext.widgetConfig.webAppType,
432 m_installerContext.widgetConfig.tzAppid);
433 ConfigureResult result = checkWidgetUpdate(update);
437 if(regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
438 LogDebug("Regcomp failed");
442 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid).c_str(),
443 static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
444 (checkTizenPkgIdExist(DPL::ToUTF8String(m_installerContext.widgetConfig.tzPkgid)) &&
445 result != ConfigureResult::Updated))
447 //it is true when tizenId does not fit REG_TIZENID_PATTERN
448 LogError("tizen_id provided but not proper.");
450 return ConfigureResult::Failed;
454 configureWidgetLocation(widgetSource, tempPath);
456 // Init installer context
457 m_installerContext.installStep = InstallerContext::INSTALL_START;
458 m_installerContext.job = this;
459 m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
460 m_installerContext.widgetConfig.shareHref = std::string();
465 JobWidgetInstall::ConfigureResult JobWidgetInstall::checkWidgetUpdate(
466 const WidgetUpdateInfo &update)
469 "Widget install/update: incoming guid = '" <<
470 update.incomingGUID << "'");
472 "Widget install/update: incoming version = '" <<
473 update.incomingVersion << "'");
476 WidgetUpdateMode::Type updateTypeCheckBit;
478 if (update.existingWidgetInfo.isExist == false) {
479 LogInfo("Widget info does not exist");
480 updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
482 LogInfo("Widget info exists. appid: " <<
483 update.existingWidgetInfo.tzAppid);
485 TizenAppId tzAppid = update.existingWidgetInfo.tzAppid;
487 LogInfo("Widget model exists. tizen app id: " << tzAppid);
489 // Check running state
490 int retval = APP_MANAGER_ERROR_NONE;
491 bool isRunning = false;
492 retval = app_manager_is_running(DPL::ToUTF8String(tzAppid).c_str(), &isRunning);
493 if (APP_MANAGER_ERROR_NONE != retval) {
494 LogError("Fail to get running state");
495 return ConfigureResult::Failed;
498 if (true == isRunning) {
499 // Must be deferred when update in progress
500 if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
502 "Widget is already running. Policy is update according to WAC");
504 return ConfigureResult::Deferred;
507 "Widget is already running. Policy is not update according to WAC");
509 return ConfigureResult::Failed;
513 m_installerContext.widgetConfig.tzAppid = tzAppid;
514 OptionalWidgetVersion existingVersion;
515 existingVersion = update.existingWidgetInfo.existingVersion;
516 OptionalWidgetVersion incomingVersion = update.incomingVersion;
518 updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
521 if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 ||
522 m_jobStruct.updateMode ==
523 WidgetUpdateMode::PolicyDirectoryForceInstall)
525 LogInfo("Whether widget policy allow proceed ok");
526 return ConfigureResult::Updated;
529 return ConfigureResult::Failed;
531 return ConfigureResult::Ok;
534 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
535 const OptionalWidgetVersion &existingVersion,
536 const OptionalWidgetVersion &incomingVersion) const
538 // Widget is installed, check versions
539 if (!existingVersion && !incomingVersion) {
540 return WidgetUpdateMode::ExistingVersionEqual;
541 } else if (!existingVersion && !!incomingVersion) {
542 return WidgetUpdateMode::ExistingVersionNewer;
543 } else if (!!existingVersion && !incomingVersion) {
544 return WidgetUpdateMode::ExistingVersionOlder;
546 LogInfo("Existing widget: version = '" << *existingVersion << "'");
548 if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
549 return WidgetUpdateMode::BothVersionsNotStd;
550 } else if (!existingVersion->IsWac()) {
551 return WidgetUpdateMode::ExistingVersionNotStd;
552 } else if (!incomingVersion->IsWac()) {
553 return WidgetUpdateMode::IncomingVersionNotStd;
555 // Both versions are WAC-comparable. Do compare.
556 if (*incomingVersion == *existingVersion) {
557 return WidgetUpdateMode::ExistingVersionEqual;
558 } else if (*incomingVersion > *existingVersion) {
559 return WidgetUpdateMode::ExistingVersionOlder;
561 return WidgetUpdateMode::ExistingVersionNewer;
567 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
568 const std::string &widgetSource,
569 const std::string &tempPath,
570 WrtDB::PackagingType pkgType,
575 ConfigParserData configInfo;
579 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
580 parser.Parse(widgetSource,
582 new RootParser<WidgetParser>(configInfo,
583 DPL::FromUTF32String(
585 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
586 parser.Parse(widgetSource + '/' + WITH_OSP_XML,
588 new RootParser<WidgetParser>(
590 DPL::FromUTF32String(L"widget"))));
593 std::unique_ptr<DPL::ZipInput> zipFile(
594 new DPL::ZipInput(widgetSource));
596 std::unique_ptr<DPL::ZipInput::File> configFile;
598 // Open config.xml file
599 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
600 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
602 configFile.reset(zipFile->OpenFile(CONFIG_XML));
606 DPL::BinaryQueue buffer;
607 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
608 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
609 DPL::Copy(&inputAdapter, &outputAdapter);
610 parser.Parse(&buffer,
612 new RootParser<WidgetParser>(configInfo,
613 DPL::FromUTF32String(
617 std::string configFile;
618 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
619 configFile = tempPath + "/" + WITH_OSP_XML;
621 configFile = tempPath + "/" + CONFIG_XML;
624 parser.Parse(configFile,
626 new RootParser<WidgetParser>(configInfo,
627 DPL::FromUTF32String(
632 Catch(DPL::ZipInput::Exception::OpenFailed)
634 LogError("Failed to open widget package");
635 return ConfigParserData();
637 Catch(DPL::ZipInput::Exception::OpenFileFailed)
639 LogError("Failed to open config.xml file");
640 return ConfigParserData();
642 Catch(DPL::CopyFailed)
644 LogError("Failed to extract config.xml file");
645 return ConfigParserData();
647 Catch(DPL::FileInput::Exception::OpenFailed)
649 LogError("Failed to open config.xml file");
650 return ConfigParserData();
652 Catch(ElementParser::Exception::ParseError)
654 LogError("Failed to parse config.xml file");
655 return ConfigParserData();
657 Catch(DPL::ZipInput::Exception::SeekFileFailed)
659 LogError("Failed to seek widget archive - corrupted package?");
660 return ConfigParserData();
665 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
666 const ConfigParserData &configInfo,
667 const WrtDB::WidgetType appType,
668 const WrtDB::TizenAppId &tizenId)
670 LogInfo("Checking up widget package for config.xml...");
672 DPL::OptionalString widgetGUID;
673 OptionalWidgetVersion widgetVersion;
676 widgetGUID = configInfo.widget_id;
678 if (widgetGUID.IsNull()) {
679 LogWarning("Installed widget has no GUID");
680 return WidgetUpdateInfo();
683 LogDebug("Installed widget GUID: " << *widgetGUID);
685 // Locate widget ID with this GUID
686 // Incoming widget version
687 if (!configInfo.version.IsNull()) {
689 DPL::Optional<WidgetVersion>(
690 WidgetVersion(*configInfo.version));
693 if (appType == APP_TYPE_WAC20) {
696 // Search widget handle by GUID
697 WidgetDAOReadOnly dao(widgetGUID);
698 return WidgetUpdateInfo(
701 WidgetUpdateInfo::ExistingWidgetInfo(
702 dao.getTzAppId(), dao.getVersion()));
704 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
706 // GUID isn't installed
707 return WidgetUpdateInfo(
710 WidgetUpdateInfo::ExistingWidgetInfo());
715 // Search widget handle by appId
716 WidgetDAOReadOnly dao(tizenId);
717 return WidgetUpdateInfo(
720 WidgetUpdateInfo::ExistingWidgetInfo(
721 dao.getTzAppId(), dao.getVersion()));
723 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
725 // GUID isn't installed
726 return WidgetUpdateInfo(
729 WidgetUpdateInfo::ExistingWidgetInfo());
735 void JobWidgetInstall::SendProgress()
737 using namespace PackageManager;
738 if (GetProgressFlag() != false) {
739 if (getInstallerStruct().progressCallback != NULL) {
740 // send progress signal of pkgmgr
741 std::ostringstream percent;
742 percent << static_cast<int>(GetProgressPercent());
743 getInstallerStruct().pkgmgrInterface->sendSignal(
747 LogDebug("Call widget install progressCallbak");
748 getInstallerStruct().progressCallback(getInstallerStruct().userParam,
749 GetProgressPercent(),GetProgressDescription());
754 void JobWidgetInstall::SendFinishedSuccess()
756 using namespace PackageManager;
757 // TODO : sync should move to separate task.
761 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
762 if (false == m_installerContext.existingWidgetInfo.isExist) {
763 WidgetInstallToExtSingleton::Instance().postInstallation(true);
765 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
767 WidgetInstallToExtSingleton::Instance().deinitialize();
770 // remove widget install information file
771 unlink(m_installerContext.installInfo.c_str());
774 JobWidgetInstall::displayWidgetInfo();
776 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
778 // send signal of pkgmgr
779 getInstallerStruct().pkgmgrInterface->sendSignal(
783 LogDebug("Call widget install successfinishedCallback");
784 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
785 DPL::ToUTF8String(tizenId), Exceptions::Success);
788 void JobWidgetInstall::SendFinishedFailure()
790 using namespace PackageManager;
791 // remove widget install information file
792 unlink(m_installerContext.installInfo.c_str());
794 LogError("Error in installation step: " << m_exceptionCaught);
795 LogError("Message: " << m_exceptionMessage);
796 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
798 LogDebug("Call widget install failure finishedCallback");
800 // send signal of pkgmgr
801 getInstallerStruct().pkgmgrInterface->sendSignal(
805 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
806 DPL::ToUTF8String(tizenId), m_exceptionCaught);
809 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
811 m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
812 m_exceptionMessage = e.GetMessage();
815 void JobWidgetInstall::displayWidgetInfo()
817 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
819 std::ostringstream out;
820 WidgetLocalizedInfo localizedInfo =
821 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
824 "===================================== INSTALLED WIDGET INFO ========="\
825 "============================";
826 out << std::endl << "Name: " << localizedInfo.name;
827 out << std::endl << "AppId: " << dao.getTzAppId();
828 WidgetSize size = dao.getPreferredSize();
829 out << std::endl << "Width: " << size.width;
830 out << std::endl << "Height: " << size.height;
831 out << std::endl << "Start File: " <<
832 W3CFileLocalization::getStartFile(dao.getTzAppId());
833 out << std::endl << "Version: " << dao.getVersion();
834 out << std::endl << "Licence: " <<
835 localizedInfo.license;
836 out << std::endl << "Licence Href: " <<
837 localizedInfo.licenseHref;
838 out << std::endl << "Description: " <<
839 localizedInfo.description;
840 out << std::endl << "Widget Id: " << dao.getGUID();
841 out << std::endl << "Widget recognized: " << dao.isRecognized();
842 out << std::endl << "Widget wac signed: " << dao.isWacSigned();
843 out << std::endl << "Widget distributor signed: " <<
844 dao.isDistributorSigned();
845 out << std::endl << "Widget trusted: " << dao.isTrusted();
847 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
848 DPL::OptionalString iconSrc = !!icon ? icon->src : DPL::OptionalString::Null;
849 out << std::endl << "Icon: " << iconSrc;
851 out << std::endl << "Preferences:";
853 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
856 out << std::endl << " Key: " <<
858 out << std::endl << " Readonly: " <<
863 out << std::endl << "Features:";
865 WidgetFeatureSet list = dao.getFeaturesList();
868 out << std::endl << " Name: " << it->name;
869 out << std::endl << " Required: " << it->required;
870 out << std::endl << " Params:";
879 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
880 const std::string &widgetSource,
881 const std::string &tempPath)
883 // Check installation type (direcotory/ or config.xml or widget.wgt)
884 if (WidgetUpdateMode::PolicyDirectoryForceInstall == m_jobStruct.updateMode)
886 LogDebug("Install directly from directory");
887 return PKG_TYPE_DIRECTORY_WEB_APP;
889 if (hasExtension(widgetSource, XML_EXTENSION)) {
890 LogInfo("Hosted app installation");
891 return PKG_TYPE_HOSTED_WEB_APP;
895 std::string configFile = tempPath + "/" + CONFIG_XML;
896 if (WrtUtilFileExists(configFile)) {
897 return PKG_TYPE_NOMAL_WEB_APP;
900 configFile = tempPath + "/" + WITH_OSP_XML;
901 if (WrtUtilFileExists(configFile)) {
902 return PKG_TYPE_HYBRID_WEB_APP;
905 std::unique_ptr<DPL::ZipInput> zipFile;
910 zipFile.reset(new DPL::ZipInput(widgetSource));
913 Catch(DPL::ZipInput::Exception::OpenFailed)
915 LogDebug("Failed to open widget package");
916 return PKG_TYPE_UNKNOWN;
918 Catch(DPL::ZipInput::Exception::SeekFileFailed)
920 LogError("Failed to seek widget package file");
921 return PKG_TYPE_UNKNOWN;
926 // Open config.xml file in package root
927 std::unique_ptr<DPL::ZipInput::File> configFile(
928 zipFile->OpenFile(CONFIG_XML));
929 return PKG_TYPE_NOMAL_WEB_APP;
931 Catch(DPL::ZipInput::Exception::OpenFileFailed)
933 LogDebug("Could not find config.xml");
938 // Open config.xml file in package root
939 std::unique_ptr<DPL::ZipInput::File> configFile(
940 zipFile->OpenFile(WITH_OSP_XML));
942 return PKG_TYPE_HYBRID_WEB_APP;
944 Catch(DPL::ZipInput::Exception::OpenFileFailed)
946 LogDebug("Could not find wgt/config.xml");
947 return PKG_TYPE_UNKNOWN;
951 return PKG_TYPE_UNKNOWN;
954 void JobWidgetInstall::setApplicationType(
955 const WrtDB::ConfigParserData &configInfo)
958 FOREACH(iterator, configInfo.nameSpaces) {
959 LogInfo("namespace = [" << *iterator << "]");
960 AppType currentAppType = APP_TYPE_UNKNOWN;
962 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
966 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
968 ConfigurationNamespace::WacWidgetNamespaceName)
970 currentAppType = APP_TYPE_WAC20;
971 } else if (*iterator ==
972 ConfigurationNamespace::TizenWebAppNamespaceName) {
973 currentAppType = APP_TYPE_TIZENWEBAPP;
976 if (m_installerContext.widgetConfig.webAppType ==
978 m_installerContext.widgetConfig.webAppType = currentAppType;
979 } else if (m_installerContext.widgetConfig.webAppType ==
983 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
984 "Config.xml has more than one namespace");
988 // If there is no define, type set to WAC 2.0
989 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
990 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
993 LogInfo("type = [" <<
994 m_installerContext.widgetConfig.webAppType.getApptypeToString() << "]");
997 bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
999 FOREACH(it, configData.settingsList)
1001 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1002 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
1003 LogDebug("resource need encryption");
1010 void JobWidgetInstall::setInstallLocationType(const
1011 WrtDB::ConfigParserData &configData)
1013 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1015 if (true == m_jobStruct.m_preload) {
1016 m_installerContext.locationType =
1017 INSTALL_LOCATION_TYPE_PRELOAD;
1019 FOREACH(it, configData.settingsList)
1021 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1023 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
1024 LogDebug("This widget will be installed to sd card");
1025 m_installerContext.locationType =
1026 INSTALL_LOCATION_TYPE_EXTERNAL;
1032 bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
1035 drm_bool_type_e is_drm_file = DRM_UNKNOWN;
1038 ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file);
1039 if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) {
1042 /* blow code temporary code for drm. */
1043 int ret = drm_oem_intel_isDrmFile(const_cast<char*>(widgetPath.c_str()));
1051 bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath,
1052 std::string destPath)
1055 drm_trusted_sapps_decrypt_package_info_s package_info;
1057 strncpy(package_info.sadcf_filepath, widgetPath.c_str(),
1058 sizeof(package_info.sadcf_filepath));
1059 strncpy(package_info.decrypt_filepath, destPath.c_str(),
1060 sizeof(package_info.decrypt_filepath));
1062 drm_trusted_request_type_e requestType =
1063 DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
1065 int ret = drm_trusted_handle_request(requestType,
1066 (void *)&package_info, NULL);
1067 if (DRM_TRUSTED_RETURN_SUCCESS == ret) {
1073 if (drm_oem_intel_decrypt_package(const_cast<char*>(widgetPath.c_str()),
1074 const_cast<char*>(destPath.c_str())) != 0) {
1081 } //namespace WidgetInstall