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.tzPkgid),
418 widgetPath, tempPath,
419 m_installerContext.widgetConfig.packagingType,
420 m_installerContext.locationType);
421 m_installerContext.locations->registerAppid(
422 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
424 LogInfo("widgetSource " << widgetPath);
427 JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
428 const std::string &widgetSource,
429 const WrtDB::ConfigParserData &configData,
430 const std::string &tempPath)
432 WidgetUpdateInfo update = detectWidgetUpdate(configData,
433 m_installerContext.widgetConfig.webAppType,
434 m_installerContext.widgetConfig.tzAppid);
435 ConfigureResult result = checkWidgetUpdate(update);
439 if(regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
440 LogDebug("Regcomp failed");
444 DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid).c_str(),
445 static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
446 (checkTizenPkgIdExist(DPL::ToUTF8String(m_installerContext.widgetConfig.tzPkgid)) &&
447 result != ConfigureResult::Updated))
449 //it is true when tizenId does not fit REG_TIZENID_PATTERN
450 LogError("tizen_id provided but not proper.");
452 return ConfigureResult::Failed;
456 configureWidgetLocation(widgetSource, tempPath);
458 // Init installer context
459 m_installerContext.installStep = InstallerContext::INSTALL_START;
460 m_installerContext.job = this;
461 m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
462 m_installerContext.widgetConfig.shareHref = std::string();
467 JobWidgetInstall::ConfigureResult JobWidgetInstall::checkWidgetUpdate(
468 const WidgetUpdateInfo &update)
471 "Widget install/update: incoming guid = '" <<
472 update.incomingGUID << "'");
474 "Widget install/update: incoming version = '" <<
475 update.incomingVersion << "'");
478 WidgetUpdateMode::Type updateTypeCheckBit;
480 if (update.existingWidgetInfo.isExist == false) {
481 LogInfo("Widget info does not exist");
482 updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
484 LogInfo("Widget info exists. appid: " <<
485 update.existingWidgetInfo.tzAppid);
487 TizenAppId tzAppid = update.existingWidgetInfo.tzAppid;
489 LogInfo("Widget model exists. tizen app id: " << tzAppid);
491 // Check running state
492 int retval = APP_MANAGER_ERROR_NONE;
493 bool isRunning = false;
494 retval = app_manager_is_running(DPL::ToUTF8String(tzAppid).c_str(), &isRunning);
495 if (APP_MANAGER_ERROR_NONE != retval) {
496 LogError("Fail to get running state");
497 return ConfigureResult::Failed;
500 if (true == isRunning) {
501 // Must be deferred when update in progress
502 if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
504 "Widget is already running. Policy is update according to WAC");
506 return ConfigureResult::Deferred;
509 "Widget is already running. Policy is not update according to WAC");
511 return ConfigureResult::Failed;
515 m_installerContext.widgetConfig.tzAppid = tzAppid;
516 OptionalWidgetVersion existingVersion;
517 existingVersion = update.existingWidgetInfo.existingVersion;
518 OptionalWidgetVersion incomingVersion = update.incomingVersion;
520 updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
523 if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 ||
524 m_jobStruct.updateMode ==
525 WidgetUpdateMode::PolicyDirectoryForceInstall)
527 LogInfo("Whether widget policy allow proceed ok");
528 return ConfigureResult::Updated;
531 return ConfigureResult::Failed;
533 return ConfigureResult::Ok;
536 WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
537 const OptionalWidgetVersion &existingVersion,
538 const OptionalWidgetVersion &incomingVersion) const
540 // Widget is installed, check versions
541 if (!existingVersion && !incomingVersion) {
542 return WidgetUpdateMode::ExistingVersionEqual;
543 } else if (!existingVersion && !!incomingVersion) {
544 return WidgetUpdateMode::ExistingVersionNewer;
545 } else if (!!existingVersion && !incomingVersion) {
546 return WidgetUpdateMode::ExistingVersionOlder;
548 LogInfo("Existing widget: version = '" << *existingVersion << "'");
550 if (!existingVersion->IsWac() && !incomingVersion->IsWac()) {
551 return WidgetUpdateMode::BothVersionsNotStd;
552 } else if (!existingVersion->IsWac()) {
553 return WidgetUpdateMode::ExistingVersionNotStd;
554 } else if (!incomingVersion->IsWac()) {
555 return WidgetUpdateMode::IncomingVersionNotStd;
557 // Both versions are WAC-comparable. Do compare.
558 if (*incomingVersion == *existingVersion) {
559 return WidgetUpdateMode::ExistingVersionEqual;
560 } else if (*incomingVersion > *existingVersion) {
561 return WidgetUpdateMode::ExistingVersionOlder;
563 return WidgetUpdateMode::ExistingVersionNewer;
569 ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
570 const std::string &widgetSource,
571 const std::string &tempPath,
572 WrtDB::PackagingType pkgType,
577 ConfigParserData configInfo;
581 if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
582 parser.Parse(widgetSource,
584 new RootParser<WidgetParser>(configInfo,
585 DPL::FromUTF32String(
587 } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
588 parser.Parse(widgetSource + '/' + WITH_OSP_XML,
590 new RootParser<WidgetParser>(
592 DPL::FromUTF32String(L"widget"))));
595 std::unique_ptr<DPL::ZipInput> zipFile(
596 new DPL::ZipInput(widgetSource));
598 std::unique_ptr<DPL::ZipInput::File> configFile;
600 // Open config.xml file
601 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
602 configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
604 configFile.reset(zipFile->OpenFile(CONFIG_XML));
608 DPL::BinaryQueue buffer;
609 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
610 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
611 DPL::Copy(&inputAdapter, &outputAdapter);
612 parser.Parse(&buffer,
614 new RootParser<WidgetParser>(configInfo,
615 DPL::FromUTF32String(
619 std::string configFile;
620 if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
621 configFile = tempPath + "/" + WITH_OSP_XML;
623 configFile = tempPath + "/" + CONFIG_XML;
626 parser.Parse(configFile,
628 new RootParser<WidgetParser>(configInfo,
629 DPL::FromUTF32String(
634 Catch(DPL::ZipInput::Exception::OpenFailed)
636 LogError("Failed to open widget package");
637 return ConfigParserData();
639 Catch(DPL::ZipInput::Exception::OpenFileFailed)
641 LogError("Failed to open config.xml file");
642 return ConfigParserData();
644 Catch(DPL::CopyFailed)
646 LogError("Failed to extract config.xml file");
647 return ConfigParserData();
649 Catch(DPL::FileInput::Exception::OpenFailed)
651 LogError("Failed to open config.xml file");
652 return ConfigParserData();
654 Catch(ElementParser::Exception::ParseError)
656 LogError("Failed to parse config.xml file");
657 return ConfigParserData();
659 Catch(DPL::ZipInput::Exception::SeekFileFailed)
661 LogError("Failed to seek widget archive - corrupted package?");
662 return ConfigParserData();
667 WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
668 const ConfigParserData &configInfo,
669 const WrtDB::WidgetType appType,
670 const WrtDB::TizenAppId &tizenId)
672 LogInfo("Checking up widget package for config.xml...");
674 DPL::OptionalString widgetGUID;
675 OptionalWidgetVersion widgetVersion;
678 widgetGUID = configInfo.widget_id;
680 if (widgetGUID.IsNull()) {
681 LogWarning("Installed widget has no GUID");
682 return WidgetUpdateInfo();
685 LogDebug("Installed widget GUID: " << *widgetGUID);
687 // Locate widget ID with this GUID
688 // Incoming widget version
689 if (!configInfo.version.IsNull()) {
691 DPL::Optional<WidgetVersion>(
692 WidgetVersion(*configInfo.version));
695 if (appType == APP_TYPE_WAC20) {
698 // Search widget handle by GUID
699 WidgetDAOReadOnly dao(widgetGUID);
700 return WidgetUpdateInfo(
703 WidgetUpdateInfo::ExistingWidgetInfo(
704 dao.getTzAppId(), dao.getVersion()));
706 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
708 // GUID isn't installed
709 return WidgetUpdateInfo(
712 WidgetUpdateInfo::ExistingWidgetInfo());
717 // Search widget handle by appId
718 WidgetDAOReadOnly dao(tizenId);
719 return WidgetUpdateInfo(
722 WidgetUpdateInfo::ExistingWidgetInfo(
723 dao.getTzAppId(), dao.getVersion()));
725 Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
727 // GUID isn't installed
728 return WidgetUpdateInfo(
731 WidgetUpdateInfo::ExistingWidgetInfo());
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(getInstallerStruct().userParam,
751 GetProgressPercent(),GetProgressDescription());
756 void JobWidgetInstall::SendFinishedSuccess()
758 using namespace PackageManager;
759 // TODO : sync should move to separate task.
763 if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
764 if (false == m_installerContext.existingWidgetInfo.isExist) {
765 WidgetInstallToExtSingleton::Instance().postInstallation(true);
767 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
769 WidgetInstallToExtSingleton::Instance().deinitialize();
772 // remove widget install information file
773 unlink(m_installerContext.installInfo.c_str());
776 JobWidgetInstall::displayWidgetInfo();
778 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
780 // send signal of pkgmgr
781 getInstallerStruct().pkgmgrInterface->sendSignal(
785 LogDebug("Call widget install successfinishedCallback");
786 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
787 DPL::ToUTF8String(tizenId), Exceptions::Success);
790 void JobWidgetInstall::SendFinishedFailure()
792 using namespace PackageManager;
793 // remove widget install information file
794 unlink(m_installerContext.installInfo.c_str());
796 LogError("Error in installation step: " << m_exceptionCaught);
797 LogError("Message: " << m_exceptionMessage);
798 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
800 LogDebug("Call widget install failure finishedCallback");
802 // send signal of pkgmgr
803 getInstallerStruct().pkgmgrInterface->sendSignal(
807 getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
808 DPL::ToUTF8String(tizenId), m_exceptionCaught);
811 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
813 m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
814 m_exceptionMessage = e.GetMessage();
817 void JobWidgetInstall::displayWidgetInfo()
819 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
821 std::ostringstream out;
822 WidgetLocalizedInfo localizedInfo =
823 W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
826 "===================================== INSTALLED WIDGET INFO ========="\
827 "============================";
828 out << std::endl << "Name: " << localizedInfo.name;
829 out << std::endl << "AppId: " << dao.getTzAppId();
830 WidgetSize size = dao.getPreferredSize();
831 out << std::endl << "Width: " << size.width;
832 out << std::endl << "Height: " << size.height;
833 out << std::endl << "Start File: " <<
834 W3CFileLocalization::getStartFile(dao.getTzAppId());
835 out << std::endl << "Version: " << dao.getVersion();
836 out << std::endl << "Licence: " <<
837 localizedInfo.license;
838 out << std::endl << "Licence Href: " <<
839 localizedInfo.licenseHref;
840 out << std::endl << "Description: " <<
841 localizedInfo.description;
842 out << std::endl << "Widget Id: " << dao.getGUID();
843 out << std::endl << "Widget recognized: " << dao.isRecognized();
844 out << std::endl << "Widget wac signed: " << dao.isWacSigned();
845 out << std::endl << "Widget distributor signed: " <<
846 dao.isDistributorSigned();
847 out << std::endl << "Widget trusted: " << dao.isTrusted();
849 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
850 DPL::OptionalString iconSrc = !!icon ? icon->src : DPL::OptionalString::Null;
851 out << std::endl << "Icon: " << iconSrc;
853 out << std::endl << "Preferences:";
855 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
858 out << std::endl << " Key: " <<
860 out << std::endl << " Readonly: " <<
865 out << std::endl << "Features:";
867 WidgetFeatureSet list = dao.getFeaturesList();
870 out << std::endl << " Name: " << it->name;
871 out << std::endl << " Required: " << it->required;
872 out << std::endl << " Params:";
881 WrtDB::PackagingType JobWidgetInstall::checkPackageType(
882 const std::string &widgetSource,
883 const std::string &tempPath)
885 // Check installation type (direcotory/ or config.xml or widget.wgt)
886 if (WidgetUpdateMode::PolicyDirectoryForceInstall == m_jobStruct.updateMode)
888 LogDebug("Install directly from directory");
889 return PKG_TYPE_DIRECTORY_WEB_APP;
891 if (hasExtension(widgetSource, XML_EXTENSION)) {
892 LogInfo("Hosted app installation");
893 return PKG_TYPE_HOSTED_WEB_APP;
897 std::string configFile = tempPath + "/" + CONFIG_XML;
898 if (WrtUtilFileExists(configFile)) {
899 return PKG_TYPE_NOMAL_WEB_APP;
902 configFile = tempPath + "/" + WITH_OSP_XML;
903 if (WrtUtilFileExists(configFile)) {
904 return PKG_TYPE_HYBRID_WEB_APP;
907 std::unique_ptr<DPL::ZipInput> zipFile;
912 zipFile.reset(new DPL::ZipInput(widgetSource));
915 Catch(DPL::ZipInput::Exception::OpenFailed)
917 LogDebug("Failed to open widget package");
918 return PKG_TYPE_UNKNOWN;
920 Catch(DPL::ZipInput::Exception::SeekFileFailed)
922 LogError("Failed to seek widget package file");
923 return PKG_TYPE_UNKNOWN;
928 // Open config.xml file in package root
929 std::unique_ptr<DPL::ZipInput::File> configFile(
930 zipFile->OpenFile(CONFIG_XML));
931 return PKG_TYPE_NOMAL_WEB_APP;
933 Catch(DPL::ZipInput::Exception::OpenFileFailed)
935 LogDebug("Could not find config.xml");
940 // Open config.xml file in package root
941 std::unique_ptr<DPL::ZipInput::File> configFile(
942 zipFile->OpenFile(WITH_OSP_XML));
944 return PKG_TYPE_HYBRID_WEB_APP;
946 Catch(DPL::ZipInput::Exception::OpenFileFailed)
948 LogDebug("Could not find wgt/config.xml");
949 return PKG_TYPE_UNKNOWN;
953 return PKG_TYPE_UNKNOWN;
956 void JobWidgetInstall::setApplicationType(
957 const WrtDB::ConfigParserData &configInfo)
960 FOREACH(iterator, configInfo.nameSpaces) {
961 LogInfo("namespace = [" << *iterator << "]");
962 AppType currentAppType = APP_TYPE_UNKNOWN;
964 if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) {
968 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement ||
970 ConfigurationNamespace::WacWidgetNamespaceName)
972 currentAppType = APP_TYPE_WAC20;
973 } else if (*iterator ==
974 ConfigurationNamespace::TizenWebAppNamespaceName) {
975 currentAppType = APP_TYPE_TIZENWEBAPP;
978 if (m_installerContext.widgetConfig.webAppType ==
980 m_installerContext.widgetConfig.webAppType = currentAppType;
981 } else if (m_installerContext.widgetConfig.webAppType ==
985 ThrowMsg(Exceptions::WidgetConfigFileInvalid,
986 "Config.xml has more than one namespace");
990 // If there is no define, type set to WAC 2.0
991 if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) {
992 m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20;
995 LogInfo("type = [" <<
996 m_installerContext.widgetConfig.webAppType.getApptypeToString() << "]");
999 bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
1001 FOREACH(it, configData.settingsList)
1003 if (it->m_name == SETTING_VALUE_ENCRYPTION &&
1004 it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
1005 LogDebug("resource need encryption");
1012 void JobWidgetInstall::setInstallLocationType(const
1013 WrtDB::ConfigParserData &configData)
1015 m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
1017 if (true == m_jobStruct.m_preload) {
1018 m_installerContext.locationType =
1019 INSTALL_LOCATION_TYPE_PRELOAD;
1021 FOREACH(it, configData.settingsList)
1023 if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
1025 SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
1026 LogDebug("This widget will be installed to sd card");
1027 m_installerContext.locationType =
1028 INSTALL_LOCATION_TYPE_EXTERNAL;
1034 bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
1037 drm_bool_type_e is_drm_file = DRM_UNKNOWN;
1040 ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file);
1041 if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) {
1044 /* blow code temporary code for drm. */
1045 int ret = drm_oem_intel_isDrmFile(const_cast<char*>(widgetPath.c_str()));
1053 bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath,
1054 std::string destPath)
1057 drm_trusted_sapps_decrypt_package_info_s package_info;
1059 strncpy(package_info.sadcf_filepath, widgetPath.c_str(),
1060 sizeof(package_info.sadcf_filepath));
1061 strncpy(package_info.decrypt_filepath, destPath.c_str(),
1062 sizeof(package_info.decrypt_filepath));
1064 drm_trusted_request_type_e requestType =
1065 DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
1067 int ret = drm_trusted_handle_request(requestType,
1068 (void *)&package_info, NULL);
1069 if (DRM_TRUSTED_RETURN_SUCCESS == ret) {
1075 if (drm_oem_intel_decrypt_package(const_cast<char*>(widgetPath.c_str()),
1076 const_cast<char*>(destPath.c_str())) != 0) {
1083 } //namespace WidgetInstall