From eadb5d73d23166181551d7c8dd6fc300ab6360bb Mon Sep 17 00:00:00 2001 From: "sung-su.kim" Date: Wed, 4 Sep 2013 19:55:03 +0900 Subject: [PATCH] [Release] wrt-installer_0.1.121 Change-Id: Id70b7fbe18114e66b82011a31c1121b23877ceb8 --- packaging/wrt-installer.spec | 2 +- src/CMakeLists.txt | 3 + src/jobs/job.h | 4 +- src/jobs/plugin_install/job_plugin_install.cpp | 2 +- src/jobs/plugin_install/job_plugin_install.h | 4 +- src/jobs/plugin_install/plugin_install_task.cpp | 57 +- src/jobs/plugin_install/plugin_installer_context.h | 7 +- src/jobs/plugin_install/plugin_metafile_reader.cpp | 14 + src/jobs/plugin_install/plugin_metafile_reader.h | 18 +- src/jobs/widget_install/job_widget_install.cpp | 799 ++------------------- src/jobs/widget_install/job_widget_install.h | 60 +- src/jobs/widget_install/task_configuration.cpp | 729 +++++++++++++++++++ src/jobs/widget_install/task_configuration.h | 84 +++ src/jobs/widget_install/task_file_manipulation.cpp | 11 +- src/jobs/widget_install/task_installer_fail.cpp | 71 ++ src/jobs/widget_install/task_installer_fail.h | 44 ++ src/jobs/widget_install/task_manifest_file.cpp | 56 +- src/jobs/widget_install/task_manifest_file.h | 5 +- src/jobs/widget_install/task_widget_config.cpp | 3 +- src/jobs/widget_install/widget_install_context.h | 21 + src/logic/installer_logic.cpp | 6 +- src/misc/plugin_path.cpp | 53 ++ src/misc/plugin_path.h | 62 ++ src/pkg-manager/backendlib.cpp | 72 +- .../installer_callbacks_translate.cpp | 4 +- 25 files changed, 1294 insertions(+), 897 deletions(-) create mode 100644 src/jobs/widget_install/task_configuration.cpp create mode 100644 src/jobs/widget_install/task_configuration.h create mode 100644 src/jobs/widget_install/task_installer_fail.cpp create mode 100644 src/jobs/widget_install/task_installer_fail.h mode change 100644 => 100755 src/jobs/widget_install/task_widget_config.cpp create mode 100644 src/misc/plugin_path.cpp create mode 100644 src/misc/plugin_path.h diff --git a/packaging/wrt-installer.spec b/packaging/wrt-installer.spec index 1bb2dc6..dde259b 100644 --- a/packaging/wrt-installer.spec +++ b/packaging/wrt-installer.spec @@ -1,7 +1,7 @@ #git:framework/web/wrt-installer Name: wrt-installer Summary: Installer for tizen Webruntime -Version: 0.1.118 +Version: 0.1.121 Release: 1 Group: Development/Libraries License: Apache License, Version 2.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb7e367..794e7f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -64,6 +64,8 @@ SET(INSTALLER_SOURCES ${INSTALLER_JOBS}/widget_install/task_commons.cpp ${INSTALLER_JOBS}/widget_install/task_widget_config.cpp ${INSTALLER_JOBS}/widget_install/task_database.cpp + ${INSTALLER_JOBS}/widget_install/task_installer_fail.cpp + ${INSTALLER_JOBS}/widget_install/task_configuration.cpp ${INSTALLER_JOBS}/widget_install/ace_registration.cpp ${INSTALLER_JOBS}/widget_install/task_file_manipulation.cpp ${INSTALLER_JOBS}/widget_install/task_smack.cpp @@ -98,6 +100,7 @@ SET(INSTALLER_SOURCES ${INSTALLER_SRC_DIR}/misc/libxml_utils.cpp ${INSTALLER_SRC_DIR}/misc/widget_location.cpp ${INSTALLER_SRC_DIR}/misc/widget_install_to_external.cpp + ${INSTALLER_SRC_DIR}/misc/plugin_path.cpp ${INSTALLER_SRC_DIR}/pkg-manager/pkgmgr_signal.cpp ) diff --git a/src/jobs/job.h b/src/jobs/job.h index 1050cbc..df81e5f 100644 --- a/src/jobs/job.h +++ b/src/jobs/job.h @@ -16,7 +16,7 @@ #ifndef INSTALLER_MODEL_H #define INSTALLER_MODEL_H -#include +#include namespace Jobs { class JobExceptionBase; @@ -33,7 +33,7 @@ enum InstallationType typedef int JobHandle; class Job : - public DPL::TaskList + public DPL::MutableTaskList { public: Job(InstallationType installType); diff --git a/src/jobs/plugin_install/job_plugin_install.cpp b/src/jobs/plugin_install/job_plugin_install.cpp index 6cc3c3f..f26e3f1 100644 --- a/src/jobs/plugin_install/job_plugin_install.cpp +++ b/src/jobs/plugin_install/job_plugin_install.cpp @@ -28,7 +28,7 @@ namespace Jobs { namespace PluginInstall { -JobPluginInstall::JobPluginInstall(DPL::Utils::Path const &pluginPath, +JobPluginInstall::JobPluginInstall(PluginPath const &pluginPath, const PluginInstallerStruct &installerStruct) : Job(PluginInstallation), diff --git a/src/jobs/plugin_install/job_plugin_install.h b/src/jobs/plugin_install/job_plugin_install.h index c4a59ee..68a4e11 100644 --- a/src/jobs/plugin_install/job_plugin_install.h +++ b/src/jobs/plugin_install/job_plugin_install.h @@ -31,8 +31,6 @@ #include #include #include -#include - namespace Jobs { namespace PluginInstall { class JobPluginInstall : @@ -48,7 +46,7 @@ class JobPluginInstall : /** * @brief Automaticaly sets installation process */ - JobPluginInstall(DPL::Utils::Path const &pluginPath, + JobPluginInstall(PluginPath const &pluginPath, const PluginInstallerStruct &installerStruct); WrtDB::DbPluginHandle getNewPluginHandle() const diff --git a/src/jobs/plugin_install/plugin_install_task.cpp b/src/jobs/plugin_install/plugin_install_task.cpp index 2b90704..55f4105 100644 --- a/src/jobs/plugin_install/plugin_install_task.cpp +++ b/src/jobs/plugin_install/plugin_install_task.cpp @@ -41,13 +41,10 @@ #include #include "plugin_objects.h" #include +#include using namespace WrtDB; -namespace { -const std::string DIRECTORY_SEPARATOR = std::string("/"); -} - #define SET_PLUGIN_INSTALL_PROGRESS(step, desc) \ m_context->installerTask->UpdateProgress( \ PluginInstallerContext::step, desc); @@ -99,20 +96,17 @@ void PluginInstallTask::stepParseConfigFile() { LogDebug("Plugin installation: step parse config file"); - DPL::Utils::Path filename = m_context->pluginFilePath; - filename /= GlobalConfig::GetPluginMetafileName(); - - if(!filename.Exists()){ + if(!m_context->pluginFilePath.getMetaFile().Exists()){ m_dataFromConfigXML = false; return; } - LogDebug("Plugin Config file::" << filename.Filename()); + LogInfo("Plugin Config file::" << m_context->pluginFilePath.getMetaFile()); Try { PluginMetafileReader reader; - reader.initialize(filename); + reader.initialize(m_context->pluginFilePath.getMetaFile()); reader.read(m_pluginInfo); FOREACH(it, m_pluginInfo.m_featureContainer) @@ -127,7 +121,8 @@ void PluginInstallTask::stepParseConfigFile() } Catch(ValidationCore::ParserSchemaException::Base) { - LogError("Error during file processing " << filename.Filename()); + LogError("Error during file processing " << + m_context->pluginFilePath.getMetaFile()); ThrowMsg(Exceptions::PluginMetafileFailed, "Metafile error"); } @@ -139,20 +134,8 @@ void PluginInstallTask::stepFindPluginLibrary() return; } LogDebug("Plugin installation: step find plugin library"); - DPL::Utils::Path pluginPath = m_context->pluginFilePath; - size_t indexpos = pluginPath.Fullpath().find_last_of('/'); - - if (std::string::npos == indexpos) { - indexpos = 0; - } else { - indexpos += 1; // move after '/' - } - - std::string libName = pluginPath.Fullpath().substr(indexpos); - libName = GlobalConfig::GetPluginPrefix() + libName + - GlobalConfig::GetPluginSuffix(); - LogDebug("Plugin .so: " << libName); - m_pluginInfo.m_libraryName = libName; + LogDebug("Plugin .so: " << m_context->pluginFilePath.getLibraryName()); + m_pluginInfo.m_libraryName = m_context->pluginFilePath.getLibraryName(); } void PluginInstallTask::stepCheckIfAlreadyInstalled() @@ -171,20 +154,24 @@ void PluginInstallTask::stepLoadPluginLibrary() DISABLE_IF_PLUGIN_WITHOUT_LIB() - DPL::Utils::Path filename = m_context->pluginFilePath; - filename /= m_pluginInfo.m_libraryName; + LogDebug("Loading plugin: " << m_context->pluginFilePath.getLibraryName()); - LogDebug("Loading plugin: " << filename.Filename()); + fprintf(stderr, " - Try to dlopen() : [%s] ", m_context->pluginFilePath.getLibraryPath().Fullpath().c_str()); - void *dlHandle = dlopen(filename.Fullpath().c_str(), RTLD_LAZY); + void *dlHandle = dlopen( m_context->pluginFilePath.getLibraryPath().Fullpath().c_str(), RTLD_LAZY); if (dlHandle == NULL) { const char* error = (const char*)dlerror(); + fprintf(stderr, + "-> Failed!\n %s\n", + (error != NULL ? error : "unknown")); LogError( - "Failed to load plugin: " << filename.Filename() << + "Failed to load plugin: " << m_context->pluginFilePath.getLibraryName() << ". Reason: " << (error != NULL ? error : "unknown")); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } + fprintf(stderr, "-> Done.\n"); + const js_entity_definition_t *rawEntityList = NULL; get_widget_entity_map_proc *getWidgetEntityMapProcPtr = NULL; @@ -202,7 +189,7 @@ void PluginInstallTask::stepLoadPluginLibrary() if (rawEntityList == NULL) { dlclose(dlHandle); - LogError("Failed to read class name" << filename.Filename()); + LogError("Failed to read class name" << m_context->pluginFilePath.getLibraryName()); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } @@ -213,7 +200,7 @@ void PluginInstallTask::stepLoadPluginLibrary() if (NULL == onWidgetInitProc) { dlclose(dlHandle); - LogError("Failed to read onWidgetInit symbol" << filename.Filename()); + LogError("Failed to read onWidgetInit symbol" << m_context->pluginFilePath.getLibraryName()); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } @@ -265,7 +252,9 @@ void PluginInstallTask::stepLoadPluginLibrary() const js_entity_definition_t *rawEntityListIterator = rawEntityList; LogDebug("#####"); - LogDebug("##### Plugin: " << filename.Filename() << " supports new plugin API"); + LogDebug("##### Plugin: " + << m_context->pluginFilePath.getLibraryName() + << " supports new plugin API"); LogDebug("#####"); while (rawEntityListIterator->parent_name != NULL && @@ -310,7 +299,7 @@ void PluginInstallTask::stepRegisterFeatures() FOREACH(it, m_pluginInfo.m_featureContainer) { - LogError("PluginHandle: " << m_pluginHandle); + LogDebug("PluginHandle: " << m_pluginHandle); FeatureDAO::RegisterFeature(*it, m_pluginHandle); } SET_PLUGIN_INSTALL_PROGRESS(REGISTER_FEATURES, "Features registered"); diff --git a/src/jobs/plugin_install/plugin_installer_context.h b/src/jobs/plugin_install/plugin_installer_context.h index fbf2db5..1efd504 100644 --- a/src/jobs/plugin_install/plugin_installer_context.h +++ b/src/jobs/plugin_install/plugin_installer_context.h @@ -24,7 +24,7 @@ #include #include -#include +#include //#include using namespace WrtDB; @@ -51,7 +51,9 @@ struct PluginInstallerContext PLUGIN_INSTALL_END }; - DPL::Utils::Path pluginFilePath; ///< plugin directory + PluginPath pluginFilePath; ///< plugin directory + PluginPath metaFilePath; + bool m_dataFromConfigXML; WrtDB::DbPluginHandle pluginHandle; // if this value is true the plugin model may be created // if not plugin installation has failed from some reason @@ -60,5 +62,4 @@ struct PluginInstallerContext //used to set installation progress Jobs::PluginInstall::JobPluginInstall* installerTask; }; - #endif // WRT_SRC_INSTALLERCORE_PLUGININSTALLERTASKS_PLUGININSTALLERCONTEXT_H_ diff --git a/src/jobs/plugin_install/plugin_metafile_reader.cpp b/src/jobs/plugin_install/plugin_metafile_reader.cpp index b65c2e3..c7df516 100644 --- a/src/jobs/plugin_install/plugin_metafile_reader.cpp +++ b/src/jobs/plugin_install/plugin_metafile_reader.cpp @@ -21,6 +21,7 @@ */ #include "plugin_metafile_reader.h" +#include using namespace WrtDB; @@ -56,6 +57,19 @@ PluginMetafileReader::PluginMetafileReader() : m_parserSchema(this) &PluginMetafileReader::tokenEndDeviceCapability); } +void PluginMetafileReader::initialize(const PluginPath &filename) +{ + m_parserSchema.initialize(filename.Fullpath(), + true, + ValidationCore::SaxReader::VALIDATION_DTD, + std::string()); +} + +void PluginMetafileReader::read(WrtDB::PluginMetafileData &data) +{ + m_parserSchema.read(data); +} + void PluginMetafileReader::blankFunction(PluginMetafileData & /* data */) {} diff --git a/src/jobs/plugin_install/plugin_metafile_reader.h b/src/jobs/plugin_install/plugin_metafile_reader.h index 6a7734f..a3a3068 100644 --- a/src/jobs/plugin_install/plugin_metafile_reader.h +++ b/src/jobs/plugin_install/plugin_metafile_reader.h @@ -24,26 +24,18 @@ #define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_METAFILE_READER_H_ #include -#include #include +class PluginPath; + class PluginMetafileReader { public: PluginMetafileReader(); - void initialize(const DPL::Utils::Path &filename) - { - m_parserSchema.initialize(filename.Fullpath(), - true, - ValidationCore::SaxReader::VALIDATION_DTD, - std::string()); - } - - void read(WrtDB::PluginMetafileData &data) - { - m_parserSchema.read(data); - } + void initialize(const PluginPath &filename); + + void read(WrtDB::PluginMetafileData &data); private: void blankFunction(WrtDB::PluginMetafileData &data); diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index 7af1fb0..53cf66b 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -20,7 +20,6 @@ * @version 1.0 * @brief Implementation file for main installer task */ -#include #include #include #include @@ -28,7 +27,6 @@ #include #include -#include #include #include #include @@ -71,6 +69,8 @@ #include #include #include +#include +#include #include #include @@ -80,89 +80,8 @@ using namespace WrtDB; using namespace Jobs::Exceptions; -namespace // anonymous -{ -const char * const CONFIG_XML = "config.xml"; -const char * const WITH_OSP_XML = "res/wgt/config.xml"; -const char * const OSP_MANIFEST_XML = "info/manifest.xml"; - -//allowed: a-z, A-Z, 0-9 -const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$"; -const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$"; -const size_t PACKAGE_ID_LENGTH = 10; - -static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption"; -static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable"; -static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable"; -const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = - L"install-location"; -const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = - L"prefer-external"; - -const std::string XML_EXTENSION = ".xml"; - -bool hasExtension(const std::string& filename, const std::string& extension) -{ - LogDebug("Looking for extension " << extension << " in: " << filename); - size_t fileLen = filename.length(); - size_t extLen = extension.length(); - if (fileLen < extLen) { - LogError("Filename " << filename << " is shorter than extension " - << extension); - false; - } - return (0 == filename.compare(fileLen - extLen, extLen, extension)); -} -} // namespace anonymous - namespace Jobs { namespace WidgetInstall { -class InstallerTaskFail : - public DPL::TaskDecl -{ - private: - ConfigureResult m_result; - - void StepFail() - { - if (m_result == ConfigureResult::Failed_InvalidConfig) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid, - "invalid config"); - } else if (m_result == ConfigureResult::Failed_OpenZipError) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::OpenZipFailed, - "can't open wgt file"); - } else if (m_result == ConfigureResult::Failed_UnzipError) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::ExtractFileFailed, - "can't extract wgt file"); - } else if (m_result == ConfigureResult::Failed_LowerVersion) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion, - "package version is lower than installed version"); - } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled, - "package is already installed"); - } else if (m_result == ConfigureResult::Failed_WidgetRunning) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError, - "widget is running"); - } else if (m_result == ConfigureResult::Failed_DrmError) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::DrmDecryptFailed, - "drm failed"); - } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate, - "RDS update failed"); - } else { - ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed, - "widget installation or update not allowed!"); - } - } - - public: - InstallerTaskFail(ConfigureResult result) : - DPL::TaskDecl(this), - m_result(result) - { - AddStep(&InstallerTaskFail::StepFail); - } -}; JobWidgetInstall::JobWidgetInstall( std::string const &widgetPath, @@ -173,572 +92,109 @@ JobWidgetInstall::JobWidgetInstall( m_exceptionCaught(Jobs::Exceptions::Success) { m_installerContext.mode = m_jobStruct.m_installMode; - ConfigureResult result = prepareInstallation(widgetPath); - - if (result == ConfigureResult::Ok) { - LogDebug("Configure installation succeeded"); - m_installerContext.job->SetProgressFlag(true); - - AddTask(new TaskRecovery(m_installerContext)); - - AddTask(new TaskWidgetConfig(m_installerContext)); - if (m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_HOSTED_WEB_APP) - { - AddTask(new TaskPrepareFiles(m_installerContext)); - } - AddTask(new TaskCertify(m_installerContext)); - AddTask(new TaskCertifyLevel(m_installerContext)); - if (m_needEncryption) { - AddTask(new TaskEncryptResource(m_installerContext)); - } - AddTask(new TaskFileManipulation(m_installerContext)); - AddTask(new TaskManifestFile(m_installerContext)); - if (m_installerContext.widgetConfig.packagingType == - PKG_TYPE_HYBRID_WEB_APP) - { - AddTask(new TaskInstallOspsvc(m_installerContext)); - } - AddTask(new TaskDatabase(m_installerContext)); - AddTask(new TaskAceCheck(m_installerContext)); - AddTask(new TaskSmack(m_installerContext)); - AddTask(new TaskPkgInfoUpdate(m_installerContext)); - } else if (result == ConfigureResult::Updated) { - LogDebug("Configure installation updated"); - LogDebug("Widget Update"); - m_installerContext.job->SetProgressFlag(true); - - if (m_installerContext.mode.command == - InstallMode::Command::REINSTALL) - { - AddTask(new TaskPrepareReinstall(m_installerContext)); - } - - AddTask(new TaskWidgetConfig(m_installerContext)); - - if (m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_HOSTED_WEB_APP) - { - AddTask(new TaskPrepareFiles(m_installerContext)); - } - - AddTask(new TaskCertify(m_installerContext)); - AddTask(new TaskCertifyLevel(m_installerContext)); - if (m_needEncryption) { - AddTask(new TaskEncryptResource(m_installerContext)); - } - if (m_installerContext.mode.extension != - InstallMode::ExtensionType::DIR) { - AddTask(new TaskUpdateFiles(m_installerContext)); - AddTask(new TaskFileManipulation(m_installerContext)); - } - - AddTask(new TaskManifestFile(m_installerContext)); - if (m_installerContext.widgetConfig.packagingType == - PKG_TYPE_HYBRID_WEB_APP) - { - AddTask(new TaskInstallOspsvc(m_installerContext)); - } - AddTask(new TaskDatabase(m_installerContext)); - AddTask(new TaskAceCheck(m_installerContext)); - //TODO: remove widgetHandle from this task and move before database task - // by now widget handle is needed in ace check - // Any error in acecheck while update will break widget - AddTask(new TaskSmack(m_installerContext)); - AddTask(new TaskRemoveBackupFiles(m_installerContext)); - AddTask(new TaskPkgInfoUpdate(m_installerContext)); - } else { - // Installation is not allowed to proceed due to widget update policy - LogWarning("Configure installation failed!"); - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_INSTALL); - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_PROGRESS_KEY, - PKGMGR_START_VALUE); - - AddTask(new InstallerTaskFail(result)); - } -} - -ConfigureResult JobWidgetInstall::prepareInstallation( - const std::string &widgetPath) -{ - ConfigureResult result; - m_needEncryption = false; - Try - { - std::string tempDir; - if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) { - if (m_installerContext.mode.command == - InstallMode::Command::REINSTALL) { - std::ostringstream tempPathBuilder; - tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); - tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath(); - tempPathBuilder << "/"; - tempPathBuilder << widgetPath; - tempDir = tempPathBuilder.str();; - } else { - tempDir = widgetPath; - } - } else { - tempDir = - Jobs::WidgetInstall::createTempPath( - m_installerContext.mode.rootPath == - InstallMode::RootPath::RO); - WidgetUnzip wgtUnzip; - wgtUnzip.unzipWgtFile(widgetPath, tempDir); - } - - LogDebug("widgetPath:" << widgetPath); - LogDebug("tempPath:" << tempDir); - - m_installerContext.widgetConfig.packagingType = - checkPackageType(widgetPath, tempDir); - ConfigParserData configData = getWidgetDataFromXML( - widgetPath, - tempDir, - m_installerContext.widgetConfig.packagingType, - m_installerContext.mode.command == InstallMode::Command::REINSTALL); - LogDebug("widget packaging type : " << - m_installerContext.widgetConfig.packagingType.pkgType); - - setTizenId(configData); - setApplicationType(configData); - m_needEncryption = detectResourceEncryption(configData); - setInstallLocationType(configData); - m_installerContext.callerPkgId = - DPL::FromUTF8String(getInstallerStruct().pkgmgrInterface->getCallerId()); - LogDebug("Caller Package Id : " << m_installerContext.callerPkgId); - - // Configure installation - result = ConfigureInstallation(widgetPath, configData, tempDir); - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_PROGRESS_KEY, - PKGMGR_START_VALUE); - } - Catch(Exceptions::OpenZipFailed) - { - LogError("Failed to unzip for widget"); - result = ConfigureResult::Failed_OpenZipError; - } - Catch(Exceptions::ExtractFileFailed) - { - LogError("Failed to unzip for widget"); - result = ConfigureResult::Failed_UnzipError; - } - Catch(Exceptions::DrmDecryptFailed) - { - LogError("Failed to unzip for widget"); - result = ConfigureResult::Failed_DrmError; - } - Catch(Exceptions::MissingConfig) - { - LogError("Failed to localize config.xml"); - result = ConfigureResult::Failed_InvalidConfig; - } - Catch(Exceptions::WidgetConfigFileInvalid) - { - LogError("Invalid configuration file"); - result = ConfigureResult::Failed_InvalidConfig; - } - Catch(DPL::Exception) - { - LogError("Unknown exception"); - result = ConfigureResult::Failed; - } - - return result; -} - -void JobWidgetInstall::setTizenId( - const WrtDB::ConfigParserData &configInfo) -{ - bool shouldMakeAppid = false; - using namespace PackageManager; - if (!!configInfo.tizenAppId) { - LogDebug("Setting tizenAppId provided in config.xml: " << - configInfo.tizenAppId); - - m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId; - //check package id. - if (!!configInfo.tizenPkgId) { - LogDebug("Setting tizenPkgId provided in config.xml: " << - configInfo.tizenPkgId); - - m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId; - } else { - DPL::String appid = *configInfo.tizenAppId; - if (appid.length() > PACKAGE_ID_LENGTH) { - m_installerContext.widgetConfig.tzPkgid = - appid.substr(0, PACKAGE_ID_LENGTH); - } else { - //old version appid only has 10byte random character is able to install for a while. - //this case appid equal pkgid. - m_installerContext.widgetConfig.tzPkgid = - *configInfo.tizenAppId; - shouldMakeAppid = true; - } - } - } else { - shouldMakeAppid = true; - TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId(); - LogDebug("Checking if pkg id is unique"); - while (true) { - if (!validateTizenPackageID(pkgId)) { - //path exist, chose another one - pkgId = WidgetDAOReadOnly::generatePkgId(); - continue; - } - break; - } - m_installerContext.widgetConfig.tzPkgid = pkgId; - LogDebug("tizen_id name was generated by WRT: " << - m_installerContext.widgetConfig.tzPkgid); - } - - if (shouldMakeAppid == true) { - DPL::OptionalString name; - DPL::OptionalString defaultLocale = configInfo.defaultlocale; - - FOREACH(localizedData, configInfo.localizedDataSet) - { - Locale i = localizedData->first; - if (!!defaultLocale) { - if (defaultLocale == i) { - name = localizedData->second.name; - break; - } - } else { - name = localizedData->second.name; - break; - } - } - regex_t regx; - if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { - LogDebug("Regcomp failed"); - } - - LogDebug("Name : " << name); - if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(), - static_cast(0), NULL, 0) != REG_NOERROR)) - { - // TODO : generate name move to wrt-commons - std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - std::ostringstream genName; - struct timeval tv; - gettimeofday(&tv, NULL); - unsigned int seed = time(NULL) + tv.tv_usec; - - genName << "_" << allowedString[rand_r(&seed) % allowedString.length()]; - name = DPL::FromUTF8String(genName.str()); - LogDebug("name was generated by WRT"); - } - regfree(®x); - LogDebug("Name : " << name); - std::ostringstream genid; - genid << m_installerContext.widgetConfig.tzPkgid << "." << name; - LogDebug("tizen appid was generated by WRT : " << genid.str()); - - DPL::OptionalString appid = DPL::FromUTF8String(genid.str()); - NormalizeAndTrimSpaceString(appid); - m_installerContext.widgetConfig.tzAppid = *appid; - } - - // send start signal of pkgmgr - getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String( - m_installerContext. - widgetConfig. - tzPkgid)); - LogDebug("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid); - LogDebug("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid); - LogDebug("W3C Widget GUID : " << m_installerContext.widgetConfig.guid); -} - -void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, - const std::string& tempPath) -{ - m_installerContext.locations = - WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig. - tzPkgid), - widgetPath, tempPath, - m_installerContext.widgetConfig.packagingType, - m_installerContext.mode.rootPath == - InstallMode::RootPath::RO, - m_installerContext.mode.extension); - m_installerContext.locations->registerAppid( - DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid)); - - LogDebug("widgetSource " << widgetPath); -} + m_installerContext.requestedPath = widgetPath; -ConfigureResult JobWidgetInstall::ConfigureInstallation( - const std::string &widgetSource, - const WrtDB::ConfigParserData &configData, - const std::string &tempPath) -{ - ConfigureResult result = ConfigureResult::Failed; - WidgetUpdateInfo update; - - // checking installed web application - Try { - // checking existing application is installed - WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid); - // no excpetion means, it isn't update mode - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_UPDATE); - - update = detectWidgetUpdate(configData, - m_installerContext.widgetConfig.tzAppid); - result = checkWidgetUpdate(update); - if (result != ConfigureResult::Updated) { - // Already installed TizenAppId. return failed - return ConfigureResult::Failed_AlreadyInstalled; - } - if (!checkSupportRDSUpdate(configData)) { - return ConfigureResult::Failed_NotSupportRDSUpdate; - } - m_installerContext.isUpdateMode = true; - } - Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_INSTALL); - result = ConfigureResult::Ok; - m_installerContext.isUpdateMode = false; - - if (!validateTizenApplicationID( - m_installerContext.widgetConfig.tzAppid)) - { - LogError("tizen application ID is already used"); - return ConfigureResult::Failed_InvalidConfig; - } - if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) { - LogError("tizen package ID is already used"); - return ConfigureResult::Failed_AlreadyInstalled; - } - } - - configureWidgetLocation(widgetSource, tempPath); + //start configuration of installation + AddTask(new TaskConfiguration(m_installerContext)); // Init installer context m_installerContext.installStep = InstallerContext::INSTALL_START; m_installerContext.job = this; m_installerContext.widgetConfig.shareHref = std::string(); - - return result; } -bool JobWidgetInstall::validateTizenApplicationID( - const WrtDB::TizenAppId &tizenAppId) +void JobWidgetInstall::appendNewInstallationTaskList() { - LogDebug("tizen application ID = [" << tizenAppId << "]"); + LogDebug("Configure installation succeeded"); + m_installerContext.job->SetProgressFlag(true); - regex_t reg; - if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { - LogDebug("Regcomp failed"); - } + AddTask(new TaskRecovery(m_installerContext)); - if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0) - == REG_NOMATCH) + AddTask(new TaskWidgetConfig(m_installerContext)); + if (m_installerContext.widgetConfig.packagingType == + WrtDB::PKG_TYPE_HOSTED_WEB_APP) { - regfree(®); - return false; + AddTask(new TaskPrepareFiles(m_installerContext)); } - regfree(®); - return true; -} - -bool JobWidgetInstall::validateTizenPackageID( - const WrtDB::TizenPkgId &tizenPkgId) -{ - std::string pkgId = DPL::ToUTF8String(tizenPkgId); - - std::string installPath = - std::string(GlobalConfig::GetUserInstalledWidgetPath()) + - "/" + pkgId; - - struct stat dirStat; - if ((stat(installPath.c_str(), &dirStat) == 0)) + AddTask(new TaskCertify(m_installerContext)); + AddTask(new TaskCertifyLevel(m_installerContext)); + if (m_installerContext.needEncryption) { + AddTask(new TaskEncryptResource(m_installerContext)); + } + AddTask(new TaskFileManipulation(m_installerContext)); + AddTask(new TaskManifestFile(m_installerContext)); + if (m_installerContext.widgetConfig.packagingType == + PKG_TYPE_HYBRID_WEB_APP) { - return false; + AddTask(new TaskInstallOspsvc(m_installerContext)); } - return true; + AddTask(new TaskDatabase(m_installerContext)); + AddTask(new TaskAceCheck(m_installerContext)); + AddTask(new TaskSmack(m_installerContext)); + AddTask(new TaskPkgInfoUpdate(m_installerContext)); } -ConfigureResult JobWidgetInstall::checkWidgetUpdate( - const WidgetUpdateInfo &update) +void JobWidgetInstall::appendUpdateInstallationTaskList() { - if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) { - return ConfigureResult::Failed; - } + LogDebug("Configure installation updated"); + LogDebug("Widget Update"); + m_installerContext.job->SetProgressFlag(true); - LogDebug("existing version = '" << update.existingVersion); - LogDebug("incoming version = '" << update.incomingVersion); - LogDebug("Tizen AppID = " << update.tzAppId); - - // Check running state - bool isRunning = false; - int ret = - app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(), - &isRunning); - if (APP_MANAGER_ERROR_NONE != ret) { - LogError("Fail to get running state"); - return ConfigureResult::Failed_WidgetRunning; + if (m_installerContext.mode.command == + InstallMode::Command::REINSTALL) + { + AddTask(new TaskPrepareReinstall(m_installerContext)); } - if (true == isRunning) { - // get app_context for running application - // app_context must be released with app_context_destroy - app_context_h appCtx = NULL; - ret = - app_manager_get_app_context( - DPL::ToUTF8String(update.tzAppId).c_str(), - &appCtx); - if (APP_MANAGER_ERROR_NONE != ret) { - LogError("Fail to get app_context"); - return ConfigureResult::Failed_WidgetRunning; - } + AddTask(new TaskWidgetConfig(m_installerContext)); - // terminate app_context_h - ret = app_manager_terminate_app(appCtx); - if (APP_MANAGER_ERROR_NONE != ret) { - LogError("Fail to terminate running application"); - app_context_destroy(appCtx); - return ConfigureResult::Failed_WidgetRunning; - } else { - app_context_destroy(appCtx); - // app_manager_terminate_app isn't sync API - // wait until application isn't running (50ms * 100) - bool isStillRunning = true; - int checkingloop = 100; - struct timespec duration = { 0, 50 * 1000 * 1000 }; - while (--checkingloop >= 0) { - nanosleep(&duration, NULL); - int ret = - app_manager_is_running( - DPL::ToUTF8String(update.tzAppId).c_str(), - &isStillRunning); - if (APP_MANAGER_ERROR_NONE != ret) { - LogError("Fail to get running state"); - return ConfigureResult::Failed_WidgetRunning; - } - if (!isStillRunning) { - break; - } - } - if (isStillRunning) { - LogError("Fail to terminate running application"); - return ConfigureResult::Failed_WidgetRunning; - } - LogDebug("terminate application"); - } + if (m_installerContext.widgetConfig.packagingType == + WrtDB::PKG_TYPE_HOSTED_WEB_APP) + { + AddTask(new TaskPrepareFiles(m_installerContext)); } - m_installerContext.widgetConfig.tzAppid = update.tzAppId; + AddTask(new TaskCertify(m_installerContext)); + AddTask(new TaskCertifyLevel(m_installerContext)); + if (m_installerContext.needEncryption) { + AddTask(new TaskEncryptResource(m_installerContext)); + } - if (!!update.existingVersion || - m_installerContext.mode.extension == + if (m_installerContext.mode.extension != InstallMode::ExtensionType::DIR) { - return ConfigureResult::Updated; + AddTask(new TaskUpdateFiles(m_installerContext)); + AddTask(new TaskFileManipulation(m_installerContext)); } - return ConfigureResult::Failed; -} - -ConfigParserData JobWidgetInstall::getWidgetDataFromXML( - const std::string &widgetSource, - const std::string &tempPath, - WrtDB::PackagingType pkgType, - bool isReinstall) -{ - // Parse config - ParserRunner parser; - ConfigParserData configInfo; - Try + AddTask(new TaskManifestFile(m_installerContext)); + if (m_installerContext.widgetConfig.packagingType == + PKG_TYPE_HYBRID_WEB_APP) { - if (pkgType == PKG_TYPE_HOSTED_WEB_APP) { - parser.Parse(widgetSource, - ElementParserPtr( - new RootParser(configInfo, - DPL::FromUTF32String( - L"widget")))); - } else { - std::string configFile; - configFile = tempPath + "/" + CONFIG_XML; - if (!WrtUtilFileExists(configFile)) { - configFile = tempPath + "/" + WITH_OSP_XML; - } - - if (isReinstall) { - // checking RDS data directory - if (access(configFile.c_str(), F_OK) != 0) { - std::string tzAppId = - widgetSource.substr(widgetSource.find_last_of("/")+1); - WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId))); - configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); - configFile += "/"; - configFile += WITH_OSP_XML; - } - } - - if(!DPL::Utils::Path(configFile).Exists()) - { - ThrowMsg(Exceptions::MissingConfig, "Config file not exists"); - } - - parser.Parse(configFile, - ElementParserPtr( - new RootParser(configInfo, - DPL:: - FromUTF32String( - L"widget")))); - } - } - Catch(ElementParser::Exception::ParseError) - { - LogError("Failed to parse config.xml file"); - return ConfigParserData(); - } - Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) - { - LogError("Failed to find installed widget - give proper tizenId"); - return ConfigParserData(); - } - Catch(Exceptions::WidgetConfigFileNotFound){ - LogError("Failed to find config.xml"); - return ConfigParserData(); + AddTask(new TaskInstallOspsvc(m_installerContext)); } - return configInfo; + AddTask(new TaskDatabase(m_installerContext)); + AddTask(new TaskAceCheck(m_installerContext)); + //TODO: remove widgetHandle from this task and move before database task + // by now widget handle is needed in ace check + // Any error in acecheck while update will break widget + AddTask(new TaskSmack(m_installerContext)); + AddTask(new TaskRemoveBackupFiles(m_installerContext)); + AddTask(new TaskPkgInfoUpdate(m_installerContext)); } -WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( - const ConfigParserData &configInfo, - const WrtDB::TizenAppId &tizenId) +void JobWidgetInstall::appendFailureTaskList() { - LogDebug("Checking up widget package for config.xml..."); - OptionalWidgetVersion incomingVersion; - - if (!configInfo.version.IsNull()) { - incomingVersion = - DPL::Optional( - WidgetVersion(*configInfo.version)); - } - - WidgetDAOReadOnly dao(tizenId); - - OptionalWidgetVersion optVersion; - DPL::OptionalString version = dao.getVersion(); - if (!version.IsNull()) { - optVersion = OptionalWidgetVersion(WidgetVersion(*version)); - } + // Installation is not allowed to proceed due to widget update policy + LogWarning("Configure installation failed!"); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_PROGRESS_KEY, + PKGMGR_START_VALUE); - return WidgetUpdateInfo( - dao.getTzAppId(), - optVersion, - incomingVersion); + AddTask(new InstallerTaskFail(m_installerContext.confResult)); } void JobWidgetInstall::SendProgress() @@ -753,7 +209,7 @@ void JobWidgetInstall::SendProgress() PKGMGR_PROGRESS_KEY, percent.str()); - LogDebug("Call widget install progressCallbak"); + LogPedantic("Call widget install progressCallback"); getInstallerStruct().progressCallback( getInstallerStruct().userParam, GetProgressPercent(), @@ -904,118 +360,5 @@ void JobWidgetInstall::displayWidgetInfo() LogDebug(out.str()); } - -WrtDB::PackagingType JobWidgetInstall::checkPackageType( - const std::string &widgetSource, - const std::string &tempPath) -{ - if (hasExtension(widgetSource, XML_EXTENSION)) { - LogDebug("Hosted app installation"); - return PKG_TYPE_HOSTED_WEB_APP; - } - - std::string configFile = tempPath + "/" + OSP_MANIFEST_XML; - if (WrtUtilFileExists(configFile)) { - return PKG_TYPE_HYBRID_WEB_APP; - } - - return PKG_TYPE_NOMAL_WEB_APP; -} - -void JobWidgetInstall::setApplicationType( - const WrtDB::ConfigParserData &configInfo) -{ - AppType widgetAppType = APP_TYPE_UNKNOWN; - FOREACH(iterator, configInfo.nameSpaces) { - LogDebug("namespace = [" << *iterator << "]"); - - if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) { - if (widgetAppType != APP_TYPE_UNKNOWN && - widgetAppType != APP_TYPE_TIZENWEBAPP) - { - LogError("To many namespaces declared in configuration fileA."); - ThrowMsg(Exceptions::WidgetConfigFileInvalid, - "Config.xml has more than one valid namespace"); - } - widgetAppType = APP_TYPE_TIZENWEBAPP; - } else { - LogDebug("Namespace ignored."); - } - } - - m_installerContext.widgetConfig.webAppType = widgetAppType; - - LogDebug("type = [" << - m_installerContext.widgetConfig.webAppType.getApptypeToString() << - "]"); -} - -bool JobWidgetInstall::detectResourceEncryption( - const WrtDB::ConfigParserData &configData) -{ - FOREACH(it, configData.settingsList) - { - if (it->m_name == SETTING_VALUE_ENCRYPTION && - it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) - { - LogDebug("resource need encryption"); - return true; - } - } - return false; -} - -void JobWidgetInstall::setInstallLocationType( - const WrtDB::ConfigParserData & configData) -{ - m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL; - if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) { - FOREACH(it, configData.settingsList) { - if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME && - it->m_value == - SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) - { - LogDebug("This widget will be installed to sd card"); - m_installerContext.locationType = - INSTALL_LOCATION_TYPE_EXTERNAL; - } - } - } -} - -bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData - &configInfo) -{ - if (m_installerContext.mode.command == - InstallMode::Command::REINSTALL) - { - DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE; - DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE; - - WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid); - WrtDB::WidgetSettings widgetSettings; - dao.getWidgetSettings(widgetSettings); - - FOREACH(it, widgetSettings) { - if (it->settingName == SETTING_VALUE_ENCRYPTION) { - dbValue = it->settingValue; - } - } - - FOREACH(data, configInfo.settingsList) - { - if (data->m_name == SETTING_VALUE_ENCRYPTION) - { - configValue = data->m_value; - } - } - if (configValue != dbValue) { - LogError("Not Support RDS mode because of encryption setting"); - return false; - } - } - - return true; -} } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/job_widget_install.h b/src/jobs/widget_install/job_widget_install.h index 1eebc7b..62f8c6c 100644 --- a/src/jobs/widget_install/job_widget_install.h +++ b/src/jobs/widget_install/job_widget_install.h @@ -23,34 +23,16 @@ #ifndef WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_ #define WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_ -#include -#include #include #include #include -#include -#include -#include #include "widget_installer_struct.h" +#include using namespace Jobs::Exceptions; namespace Jobs { namespace WidgetInstall { -enum class ConfigureResult -{ - Ok, - Updated, - Failed, - Failed_InvalidConfig, - Failed_LowerVersion, - Failed_AlreadyInstalled, - Failed_WidgetRunning, - Failed_DrmError, - Failed_NotSupportRDSUpdate, - Failed_OpenZipError, - Failed_UnzipError, -}; class JobWidgetInstall : public Job, @@ -61,41 +43,8 @@ class JobWidgetInstall : private: InstallerContext m_installerContext; - //TODO move it to base class of all jobs -> make it base template class?? Jobs::Exceptions::Type m_exceptionCaught; std::string m_exceptionMessage; - WidgetUpdateInfo m_widgetUpdateInfo; - bool m_needEncryption; - - ConfigureResult ConfigureInstallation(const std::string &widgetSource, - const WrtDB::ConfigParserData - &configData, - const std::string &tempPath); - static WrtDB::ConfigParserData getWidgetDataFromXML( - const std::string &widgetSource, - const std::string &tempPath, - WrtDB::PackagingType pkgType, - bool isReinstall); - static WidgetUpdateInfo detectWidgetUpdate( - const WrtDB::ConfigParserData &configInfo, - const WrtDB::TizenAppId &tizenId); - void setTizenId(const WrtDB::ConfigParserData &configInfo); - void displayWidgetInfo(); - void configureWidgetLocation(const std::string & widgetPath, - const std::string &tempPath); - - WrtDB::PackagingType checkPackageType( - const std::string &widgetSource, - const std::string &tempPath); - bool detectResourceEncryption(const WrtDB::ConfigParserData &configData); - void setInstallLocationType(const WrtDB::ConfigParserData - &configData); - ConfigureResult prepareInstallation(const std::string &widgetPath); - bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId); - bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId); - ConfigureResult checkWidgetUpdate(const WidgetUpdateInfo &update); - void setApplicationType(const WrtDB::ConfigParserData &configInfo); - bool checkSupportRDSUpdate(const WrtDB::ConfigParserData &configInfo); public: /** @@ -109,7 +58,14 @@ class JobWidgetInstall : void SendFinishedSuccess(); void SendFinishedFailure(); void SendProgressIconPath(const std::string &path); + void SaveExceptionData(const Jobs::JobExceptionBase&); + void displayWidgetInfo(); + + //execution paths + void appendNewInstallationTaskList(); + void appendUpdateInstallationTaskList(); + void appendFailureTaskList(); }; } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/task_configuration.cpp b/src/jobs/widget_install/task_configuration.cpp new file mode 100644 index 0000000..5bdae02 --- /dev/null +++ b/src/jobs/widget_install/task_configuration.cpp @@ -0,0 +1,729 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file task_configuration.cpp + * @version 1.0 + * @author Tomasz Iwanek + * @brief implementation file for configuration task + */ +#include "task_configuration.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "root_parser.h" +#include "widget_parser.h" +#include "parser_runner.h" + +#include +#include +#include +#include +#include +#include + +using namespace WrtDB; + +namespace { +const char* const CONFIG_XML = "config.xml"; +const char* const WITH_OSP_XML = "res/wgt/config.xml"; +const char* const OSP_MANIFEST_XML = "info/manifest.xml"; + +//allowed: a-z, A-Z, 0-9 +const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$"; +const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$"; +const size_t PACKAGE_ID_LENGTH = 10; + +static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption"; +static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable"; +static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = + L"install-location"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = + L"prefer-external"; + +const std::string XML_EXTENSION = ".xml"; + +bool hasExtension(const std::string& filename, const std::string& extension) +{ + LogDebug("Looking for extension " << extension << " in: " << filename); + size_t fileLen = filename.length(); + size_t extLen = extension.length(); + if (fileLen < extLen) { + LogError("Filename " << filename << " is shorter than extension " + << extension); + return false; + } + return (0 == filename.compare(fileLen - extLen, extLen, extension)); +} +} // namespace anonymous + +namespace Jobs { +namespace WidgetInstall { + +TaskConfiguration::TaskConfiguration(InstallerContext& context) : + DPL::TaskDecl(this), + m_context(context), + m_result(ConfigureResult::Unknown) +{ + AddStep(&TaskConfiguration::StartStep); + AddStep(&TaskConfiguration::PrepareInstallationStep); + AddStep(&TaskConfiguration::AppendTasklistStep); + AddStep(&TaskConfiguration::EndStep); +} + +void TaskConfiguration::StartStep() +{ + LogDebug("--------- : START ----------"); +} + +void TaskConfiguration::EndStep() +{ + LogDebug("--------- : END ----------"); +} + +void TaskConfiguration::AppendTasklistStep() +{ + // TODO: (job_install_refactoring) do not store config result anywhere + m_context.confResult = m_result; + + if (m_result == ConfigureResult::Ok) { + LogInfo("TaskConfiguration -> new installation task list"); + m_context.job->appendNewInstallationTaskList(); + } else if (m_result == ConfigureResult::Updated) { + LogInfo("TaskConfiguration -> update installation task list"); + m_context.job->appendUpdateInstallationTaskList(); + } else { + LogInfo("TaskConfiguration -> failure task list"); + m_context.job->appendFailureTaskList(); + } +} + +void TaskConfiguration::PrepareInstallationStep() +{ + // TODO: (job_install_refactoring) clean up this task + std::string widgetPath = m_context.requestedPath; + ConfigureResult result; + m_context.needEncryption = false; + Try + { + std::string tempDir; + if (m_context.mode.extension == InstallMode::ExtensionType::DIR) { + if (m_context.mode.command == + InstallMode::Command::REINSTALL) { + std::ostringstream tempPathBuilder; + tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath(); + tempPathBuilder << "/"; + tempPathBuilder << widgetPath; + tempDir = tempPathBuilder.str(); + } else { + tempDir = widgetPath; + } + } else { + tempDir = + Jobs::WidgetInstall::createTempPath( + m_context.mode.rootPath == + InstallMode::RootPath::RO); + WidgetUnzip wgtUnzip; + wgtUnzip.unzipWgtFile(widgetPath, tempDir); + } + + LogDebug("widgetPath:" << widgetPath); + LogDebug("tempPath:" << tempDir); + + m_context.widgetConfig.packagingType = + checkPackageType(widgetPath, tempDir); + ConfigParserData configData = getWidgetDataFromXML( + widgetPath, + tempDir, + m_context.widgetConfig.packagingType, + m_context.mode.command == InstallMode::Command::REINSTALL); + LogDebug("widget packaging type : " << + m_context.widgetConfig.packagingType.pkgType); + + setTizenId(configData); + setApplicationType(configData); + m_context.needEncryption = detectResourceEncryption(configData); + setInstallLocationType(configData); + // TODO: (job_install_refactoring) hide this call + m_context.callerPkgId = + DPL::FromUTF8String(m_context.job->getInstallerStruct().pkgmgrInterface->getCallerId()); + LogDebug("Caller Package Id : " << m_context.callerPkgId); + + // Configure installation + result = ConfigureInstallation(widgetPath, configData, tempDir); + // TODO: (job_install_refactoring) hide this call + m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_PROGRESS_KEY, + PKGMGR_START_VALUE); + } + Catch(Exceptions::OpenZipFailed) + { + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_OpenZipError; + } + Catch(Exceptions::ExtractFileFailed) + { + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_UnzipError; + } + Catch(Exceptions::DrmDecryptFailed) + { + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_DrmError; + } + Catch(Exceptions::MissingConfig) + { + LogError("Failed to localize config.xml"); + result = ConfigureResult::Failed_InvalidConfig; + } + Catch(Exceptions::WidgetConfigFileInvalid) + { + LogError("Invalid configuration file"); + result = ConfigureResult::Failed_InvalidConfig; + } + Catch(DPL::Exception) + { + LogError("Unknown exception"); + result = ConfigureResult::Failed; + } + + m_result = result; +} + +void TaskConfiguration::setTizenId( + const WrtDB::ConfigParserData &configInfo) +{ + bool shouldMakeAppid = false; + using namespace PackageManager; + if (!!configInfo.tizenAppId) { + LogDebug("Setting tizenAppId provided in config.xml: " << + configInfo.tizenAppId); + + m_context.widgetConfig.tzAppid = *configInfo.tizenAppId; + //check package id. + if (!!configInfo.tizenPkgId) { + LogDebug("Setting tizenPkgId provided in config.xml: " << + configInfo.tizenPkgId); + + m_context.widgetConfig.tzPkgid = *configInfo.tizenPkgId; + } else { + DPL::String appid = *configInfo.tizenAppId; + if (appid.length() > PACKAGE_ID_LENGTH) { + m_context.widgetConfig.tzPkgid = + appid.substr(0, PACKAGE_ID_LENGTH); + } else { + //old version appid only has 10byte random character is able to install for a while. + //this case appid equal pkgid. + m_context.widgetConfig.tzPkgid = + *configInfo.tizenAppId; + shouldMakeAppid = true; + } + } + } else { + shouldMakeAppid = true; + TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId(); + LogDebug("Checking if pkg id is unique"); + while (true) { + if (!validateTizenPackageID(pkgId)) { + //path exist, chose another one + pkgId = WidgetDAOReadOnly::generatePkgId(); + continue; + } + break; + } + m_context.widgetConfig.tzPkgid = pkgId; + LogDebug("tizen_id name was generated by WRT: " << + m_context.widgetConfig.tzPkgid); + } + + if (shouldMakeAppid == true) { + DPL::OptionalString name; + DPL::OptionalString defaultLocale = configInfo.defaultlocale; + + FOREACH(localizedData, configInfo.localizedDataSet) + { + Locale i = localizedData->first; + if (!!defaultLocale) { + if (defaultLocale == i) { + name = localizedData->second.name; + break; + } + } else { + name = localizedData->second.name; + break; + } + } + regex_t regx; + if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } + + LogDebug("Name : " << name); + if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(), + static_cast(0), NULL, 0) != REG_NOERROR)) + { + // TODO : (job_install_refactoring) generate name move to wrt-commons + std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + std::ostringstream genName; + struct timeval tv; + gettimeofday(&tv, NULL); + unsigned int seed = time(NULL) + tv.tv_usec; + + genName << "_" << allowedString[rand_r(&seed) % allowedString.length()]; + name = DPL::FromUTF8String(genName.str()); + LogDebug("name was generated by WRT"); + } + regfree(®x); + LogDebug("Name : " << name); + std::ostringstream genid; + genid << m_context.widgetConfig.tzPkgid << "." << name; + LogDebug("tizen appid was generated by WRT : " << genid.str()); + + DPL::OptionalString appid = DPL::FromUTF8String(genid.str()); + NormalizeAndTrimSpaceString(appid); + m_context.widgetConfig.tzAppid = *appid; + } + + // send start signal of pkgmgr + // TODO: (job_install_refactoring) hide this call + m_context.job->getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String( + m_context. + widgetConfig. + tzPkgid)); + LogDebug("Tizen App Id : " << m_context.widgetConfig.tzAppid); + LogDebug("Tizen Pkg Id : " << m_context.widgetConfig.tzPkgid); + LogDebug("W3C Widget GUID : " << m_context.widgetConfig.guid); +} + +void TaskConfiguration::configureWidgetLocation(const std::string & widgetPath, + const std::string& tempPath) +{ + m_context.locations = + WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig. + tzPkgid), + widgetPath, tempPath, + m_context.widgetConfig.packagingType, + m_context.mode.rootPath == + InstallMode::RootPath::RO, + m_context.mode.extension); + m_context.locations->registerAppid( + DPL::ToUTF8String(m_context.widgetConfig.tzAppid)); + + LogDebug("widgetSource " << widgetPath); +} + +ConfigureResult TaskConfiguration::ConfigureInstallation( + const std::string &widgetSource, + const WrtDB::ConfigParserData &configData, + const std::string &tempPath) +{ + ConfigureResult result = ConfigureResult::Failed; + WidgetUpdateInfo update; + + // checking installed web application + Try { + // checking existing application is installed + WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid); + // no excpetion means, it isn't update mode + // TODO: (job_install_refactoring) hide this call/ + m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_UPDATE); + + update = detectWidgetUpdate(configData, + m_context.widgetConfig.tzAppid); + result = checkWidgetUpdate(update); + if (result != ConfigureResult::Updated) { + // Already installed TizenAppId. return failed + return ConfigureResult::Failed_AlreadyInstalled; + } + if (!checkSupportRDSUpdate(configData)) { + return ConfigureResult::Failed_NotSupportRDSUpdate; + } + m_context.isUpdateMode = true; + } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { + // TODO: (job_install_refactoring) hide this call + m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); + result = ConfigureResult::Ok; + m_context.isUpdateMode = false; + + if (!validateTizenApplicationID( + m_context.widgetConfig.tzAppid)) + { + LogError("tizen application ID is already used"); + return ConfigureResult::Failed_InvalidConfig; + } + if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) { + LogError("tizen package ID is already used"); + return ConfigureResult::Failed_AlreadyInstalled; + } + } + + configureWidgetLocation(widgetSource, tempPath); + + return result; +} + +bool TaskConfiguration::validateTizenApplicationID( + const WrtDB::TizenAppId &tizenAppId) +{ + LogDebug("tizen application ID = [" << tizenAppId << "]"); + + regex_t reg; + if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } + + if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0) + == REG_NOMATCH) + { + regfree(®); + return false; + } + regfree(®); + return true; +} + +bool TaskConfiguration::validateTizenPackageID( + const WrtDB::TizenPkgId &tizenPkgId) +{ + std::string pkgId = DPL::ToUTF8String(tizenPkgId); + + std::string installPath = + std::string(GlobalConfig::GetUserInstalledWidgetPath()) + + "/" + pkgId; + + struct stat dirStat; + if ((stat(installPath.c_str(), &dirStat) == 0)) + { + return false; + } + return true; +} + +ConfigureResult TaskConfiguration::checkWidgetUpdate( + const WidgetUpdateInfo &update) +{ + if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) { + return ConfigureResult::Failed; + } + + LogDebug("existing version = '" << update.existingVersion); + LogDebug("incoming version = '" << update.incomingVersion); + LogDebug("Tizen AppID = " << update.tzAppId); + + // Check running state + bool isRunning = false; + int ret = + app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(), + &isRunning); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get running state"); + return ConfigureResult::Failed_WidgetRunning; + } + + if (true == isRunning) { + // get app_context for running application + // app_context must be released with app_context_destroy + app_context_h appCtx = NULL; + ret = + app_manager_get_app_context( + DPL::ToUTF8String(update.tzAppId).c_str(), + &appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get app_context"); + return ConfigureResult::Failed_WidgetRunning; + } + + // terminate app_context_h + ret = app_manager_terminate_app(appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to terminate running application"); + app_context_destroy(appCtx); + return ConfigureResult::Failed_WidgetRunning; + } else { + app_context_destroy(appCtx); + // app_manager_terminate_app isn't sync API + // wait until application isn't running (50ms * 100) + bool isStillRunning = true; + int checkingloop = 100; + struct timespec duration = { 0, 50 * 1000 * 1000 }; + while (--checkingloop >= 0) { + nanosleep(&duration, NULL); + int ret = + app_manager_is_running( + DPL::ToUTF8String(update.tzAppId).c_str(), + &isStillRunning); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get running state"); + return ConfigureResult::Failed_WidgetRunning; + } + if (!isStillRunning) { + break; + } + } + if (isStillRunning) { + LogError("Fail to terminate running application"); + return ConfigureResult::Failed_WidgetRunning; + } + LogDebug("terminate application"); + } + } + + m_context.widgetConfig.tzAppid = update.tzAppId; + + if (!!update.existingVersion || + m_context.mode.extension == + InstallMode::ExtensionType::DIR) { + return ConfigureResult::Updated; + } + + return ConfigureResult::Failed; +} + +ConfigParserData TaskConfiguration::getWidgetDataFromXML( + const std::string &widgetSource, + const std::string &tempPath, + WrtDB::PackagingType pkgType, + bool isReinstall) +{ + // Parse config + ParserRunner parser; + ConfigParserData configInfo; + Try + { + if (pkgType == PKG_TYPE_HOSTED_WEB_APP) { + parser.Parse(widgetSource, + ElementParserPtr( + new RootParser(configInfo, + DPL::FromUTF32String( + L"widget")))); + } else { + std::string configFile; + configFile = tempPath + "/" + CONFIG_XML; + if (!WrtUtilFileExists(configFile)) { + configFile = tempPath + "/" + WITH_OSP_XML; + } + + if (isReinstall) { + // checking RDS data directory + if (access(configFile.c_str(), F_OK) != 0) { + std::string tzAppId = + widgetSource.substr(widgetSource.find_last_of("/")+1); + WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId))); + configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + configFile += "/"; + configFile += WITH_OSP_XML; + } + } + + if(!DPL::Utils::Path(configFile).Exists()) + { + ThrowMsg(Exceptions::MissingConfig, "Config file not exists"); + } + + parser.Parse(configFile, + ElementParserPtr( + new RootParser(configInfo, + DPL:: + FromUTF32String( + L"widget")))); + } + } + Catch(ElementParser::Exception::ParseError) + { + LogError("Failed to parse config.xml file"); + return ConfigParserData(); + } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) + { + LogError("Failed to find installed widget - give proper tizenId"); + return ConfigParserData(); + } + Catch(Exceptions::WidgetConfigFileNotFound){ + LogError("Failed to find config.xml"); + return ConfigParserData(); + } + + return configInfo; +} + +WidgetUpdateInfo TaskConfiguration::detectWidgetUpdate( + const ConfigParserData &configInfo, + const WrtDB::TizenAppId &tizenId) +{ + LogDebug("Checking up widget package for config.xml..."); + OptionalWidgetVersion incomingVersion; + + if (!configInfo.version.IsNull()) { + incomingVersion = + DPL::Optional( + WidgetVersion(*configInfo.version)); + } + + WidgetDAOReadOnly dao(tizenId); + + OptionalWidgetVersion optVersion; + DPL::OptionalString version = dao.getVersion(); + if (!version.IsNull()) { + optVersion = OptionalWidgetVersion(WidgetVersion(*version)); + } + + return WidgetUpdateInfo( + dao.getTzAppId(), + optVersion, + incomingVersion); +} + + +WrtDB::PackagingType TaskConfiguration::checkPackageType( + const std::string &widgetSource, + const std::string &tempPath) +{ + if (hasExtension(widgetSource, XML_EXTENSION)) { + LogDebug("Hosted app installation"); + return PKG_TYPE_HOSTED_WEB_APP; + } + + std::string configFile = tempPath + "/" + OSP_MANIFEST_XML; + if (WrtUtilFileExists(configFile)) { + return PKG_TYPE_HYBRID_WEB_APP; + } + + return PKG_TYPE_NOMAL_WEB_APP; +} + +void TaskConfiguration::setApplicationType( + const WrtDB::ConfigParserData &configInfo) +{ + AppType widgetAppType = APP_TYPE_UNKNOWN; + FOREACH(iterator, configInfo.nameSpaces) { + LogDebug("namespace = [" << *iterator << "]"); + + if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) { + if (widgetAppType != APP_TYPE_UNKNOWN && + widgetAppType != APP_TYPE_TIZENWEBAPP) + { + LogError("To many namespaces declared in configuration fileA."); + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Config.xml has more than one valid namespace"); + } + widgetAppType = APP_TYPE_TIZENWEBAPP; + } else { + LogDebug("Namespace ignored."); + } + } + + m_context.widgetConfig.webAppType = widgetAppType; + + LogDebug("type = [" << + m_context.widgetConfig.webAppType.getApptypeToString() << + "]"); +} + +bool TaskConfiguration::detectResourceEncryption( + const WrtDB::ConfigParserData &configData) +{ + FOREACH(it, configData.settingsList) + { + if (it->m_name == SETTING_VALUE_ENCRYPTION && + it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) + { + LogDebug("resource need encryption"); + return true; + } + } + return false; +} + +void TaskConfiguration::setInstallLocationType( + const WrtDB::ConfigParserData & configData) +{ + m_context.locationType = INSTALL_LOCATION_TYPE_NOMAL; + if (m_context.mode.installTime != InstallMode::InstallTime::PRELOAD) { + FOREACH(it, configData.settingsList) { + if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME && + it->m_value == + SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) + { + LogDebug("This widget will be installed to sd card"); + m_context.locationType = + INSTALL_LOCATION_TYPE_EXTERNAL; + } + } + } +} + +bool TaskConfiguration::checkSupportRDSUpdate(const WrtDB::ConfigParserData + &configInfo) +{ + if (m_context.mode.command == + InstallMode::Command::REINSTALL) + { + DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE; + DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE; + + WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid); + WrtDB::WidgetSettings widgetSettings; + dao.getWidgetSettings(widgetSettings); + + FOREACH(it, widgetSettings) { + if (it->settingName == SETTING_VALUE_ENCRYPTION) { + dbValue = it->settingValue; + } + } + + FOREACH(data, configInfo.settingsList) + { + if (data->m_name == SETTING_VALUE_ENCRYPTION) + { + configValue = data->m_value; + } + } + if (configValue != dbValue) { + LogError("Not Support RDS mode because of encryption setting"); + return false; + } + } + + return true; +} + +} +} diff --git a/src/jobs/widget_install/task_configuration.h b/src/jobs/widget_install/task_configuration.h new file mode 100644 index 0000000..7f74410 --- /dev/null +++ b/src/jobs/widget_install/task_configuration.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file task_configuration.h + * @version 1.0 + * @author Tomasz Iwanek + * @brief header file for configuration task + */ +#ifndef TASK_CONFIGURATION_H +#define TASK_CONFIGURATION_H + +#include +#include + +#include +#include + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { + +class TaskConfiguration : public DPL::TaskDecl +{ + InstallerContext& m_context; + ConfigureResult m_result; + WidgetUpdateInfo m_widgetUpdateInfo; + + ConfigureResult ConfigureInstallation(const std::string &widgetSource, + const WrtDB::ConfigParserData + &configData, + const std::string &tempPath); + static WrtDB::ConfigParserData getWidgetDataFromXML( + const std::string &widgetSource, + const std::string &tempPath, + WrtDB::PackagingType pkgType, + bool isReinstall); + static WidgetUpdateInfo detectWidgetUpdate( + const WrtDB::ConfigParserData &configInfo, + const WrtDB::TizenAppId &tizenId); + void setTizenId(const WrtDB::ConfigParserData &configInfo); + void configureWidgetLocation(const std::string & widgetPath, + const std::string &tempPath); + + WrtDB::PackagingType checkPackageType( + const std::string &widgetSource, + const std::string &tempPath); + bool detectResourceEncryption(const WrtDB::ConfigParserData &configData); + void setInstallLocationType(const WrtDB::ConfigParserData + &configData); + + bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId); + bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId); + ConfigureResult checkWidgetUpdate(const WidgetUpdateInfo &update); + void setApplicationType(const WrtDB::ConfigParserData &configInfo); + bool checkSupportRDSUpdate(const WrtDB::ConfigParserData &configInfo); + + void PrepareInstallationStep(); + void AppendTasklistStep(); + + void StartStep(); + void EndStep(); + +public: + TaskConfiguration(InstallerContext& context); +}; + +} +} + +#endif // TASK_CONFIGURATION_H diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index 7b1da06..3ac463b 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -422,11 +422,15 @@ void TaskFileManipulation::StepCreateSharedFolder() WrtUtilMakeDir(sharedPath); WrtUtilMakeDir(m_context.locations->getSharedResourceDir()); + changeOwnerForDirectory(m_context.locations->getSharedDataDir(), + SHARED_STORAGE_MODE); + changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(), + SHARED_STORAGE_MODE); + if (m_context.isUpdateMode) { //update std::string backSharedData = m_context.locations->getBackupSharedDir(); std::string BackSharedTrusted = m_context.locations->getBackupSharedDir(); - /* Restore /shared/data */ LogDebug("copy " << m_context.locations->getBackupSharedDataDir() << " to " << m_context.locations->getSharedDataDir()); @@ -452,11 +456,6 @@ void TaskFileManipulation::StepCreateSharedFolder() ThrowMsg(Exceptions::BackupFailed, "Error occurs copy shared strage files"); } - } else { - changeOwnerForDirectory(m_context.locations->getSharedDataDir(), - SHARED_STORAGE_MODE); - changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(), - SHARED_STORAGE_MODE); } } diff --git a/src/jobs/widget_install/task_installer_fail.cpp b/src/jobs/widget_install/task_installer_fail.cpp new file mode 100644 index 0000000..3cf73fc --- /dev/null +++ b/src/jobs/widget_install/task_installer_fail.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file task_installer_fail.cpp + * @version 1.0 + * @brief implementation file for failure task + */ +#include "task_installer_fail.h" + +#include + +using namespace WrtDB; +using namespace Jobs::Exceptions; + +namespace Jobs { +namespace WidgetInstall { + +void InstallerTaskFail::StepFail() +{ + if (m_result == ConfigureResult::Failed_InvalidConfig) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid, + "invalid config"); + } else if (m_result == ConfigureResult::Failed_OpenZipError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::OpenZipFailed, + "can't open wgt file"); + } else if (m_result == ConfigureResult::Failed_UnzipError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::ExtractFileFailed, + "can't extract wgt file"); + } else if (m_result == ConfigureResult::Failed_LowerVersion) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion, + "package version is lower than installed version"); + } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled, + "package is already installed"); + } else if (m_result == ConfigureResult::Failed_WidgetRunning) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError, + "widget is running"); + } else if (m_result == ConfigureResult::Failed_DrmError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::DrmDecryptFailed, + "drm failed"); + } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate, + "RDS update failed"); + } else { + ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed, + "widget installation or update not allowed!"); + } +} + +InstallerTaskFail::InstallerTaskFail(ConfigureResult result) : + DPL::TaskDecl(this), + m_result(result) +{ + AddStep(&InstallerTaskFail::StepFail); +} + +} +} diff --git a/src/jobs/widget_install/task_installer_fail.h b/src/jobs/widget_install/task_installer_fail.h new file mode 100644 index 0000000..14fc7d0 --- /dev/null +++ b/src/jobs/widget_install/task_installer_fail.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file task_installer_fail.h + * @version 1.0 + * @brief header file for failure task + */ +#ifndef TASK_INSTALLER_FAIL_H +#define TASK_INSTALLER_FAIL_H + +#include +#include + +namespace Jobs { +namespace WidgetInstall { +class InstallerTaskFail : + public DPL::TaskDecl +{ + private: + ConfigureResult m_result; + + void StepFail(); + + public: + InstallerTaskFail(ConfigureResult result); +}; + +} +} + +#endif // TASK_INSTALLER_FAIL_H diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp index 37d856e..8308125 100644 --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #define DEFAULT_ICON_NAME "icon.png" #define DEFAULT_PREVIEW_NAME "preview.png" @@ -219,53 +220,37 @@ void TaskManifestFile::stepCopyIconFiles() if (std::find(generatedLocales.begin(), generatedLocales.end(), *locale) != generatedLocales.end()) { - if (icon->src == L"icon.jpg") { - generatedLocales.push_back(*locale); - } else if (icon->src == L"icon.gif") { - generatedLocales.push_back(*locale); - } else if (icon->src == L"icon.png") { - generatedLocales.push_back(*locale); - } else if (icon->src == L"icon.ico") { - generatedLocales.push_back(*locale); - } else if (icon->src == L"icon.svg") { - generatedLocales.push_back(*locale); - } LogDebug("Skipping - has that locale"); continue; } else { generatedLocales.push_back(*locale); } - std::ostringstream sourceFile; - std::ostringstream targetFile; - - sourceFile << m_context.locations->getSourceDir() << "/"; - + DPL::Utils::Path sourceFile(m_context.locations->getSourceDir()); if (!locale->empty()) { - sourceFile << "locales/" << *locale << "/"; + sourceFile /= "locales"; + sourceFile /= *locale; } + sourceFile /= src; - sourceFile << src; - - targetFile << GlobalConfig::GetUserWidgetDesktopIconPath() << "/"; - targetFile << getIconTargetFilename(*locale); + DPL::Utils::Path targetFile(GlobalConfig::GetUserWidgetDesktopIconPath()); + targetFile /= getIconTargetFilename(*locale, sourceFile.Extension()); if (m_context.widgetConfig.packagingType == WrtDB::PKG_TYPE_HOSTED_WEB_APP) { m_context.locations->setIconTargetFilenameForLocale( - targetFile.str()); + targetFile.Fullpath()); } - LogDebug("Copying icon: " << sourceFile.str() << - " -> " << targetFile.str()); + LogDebug("Copying icon: " << sourceFile << " -> " << targetFile); - icon_list.push_back(targetFile.str()); + icon_list.push_back(targetFile.Fullpath()); Try { - DPL::FileInput input(sourceFile.str()); - DPL::FileOutput output(targetFile.str()); + DPL::FileInput input(sourceFile.Fullpath()); + DPL::FileOutput output(targetFile.Fullpath()); DPL::Copy(&input, &output); } @@ -442,7 +427,7 @@ void TaskManifestFile::stepAbortIconFiles() } DPL::String TaskManifestFile::getIconTargetFilename( - const DPL::String& languageTag) const + const DPL::String& languageTag, const std::string & ext) const { DPL::OStringStream filename; TizenAppId appid = m_context.widgetConfig.tzAppid; @@ -465,7 +450,10 @@ DPL::String TaskManifestFile::getIconTargetFilename( } } - filename << L".png"; + if(!ext.empty()) + { + filename << L"." + DPL::FromUTF8String(ext); + } return filename.str(); } @@ -826,12 +814,13 @@ void TaskManifestFile::setWidgetIcons(UiApplication & uiApp) tag = *locale; } - generateWidgetIcon(uiApp, tag, *locale, defaultIconSaved); + generateWidgetIcon(uiApp, tag, *locale, DPL::Utils::Path(icon->src).Extension(), defaultIconSaved); } } if (!!defaultLocale && !defaultIconSaved) { generateWidgetIcon(uiApp, DPL::OptionalString::Null, DPL::String(), + std::string(), defaultIconSaved); } } @@ -839,6 +828,7 @@ void TaskManifestFile::setWidgetIcons(UiApplication & uiApp) void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp, const DPL::OptionalString& tag, const DPL::String& language, + const std::string & extension, bool & defaultIconSaved) { DPL::String locale; @@ -849,7 +839,7 @@ void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp, } DPL::String iconText; - iconText += getIconTargetFilename(language); + iconText += getIconTargetFilename(language, extension); if (!locale.empty()) { uiApp.addIcon(IconType(iconText, locale)); @@ -858,8 +848,8 @@ void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp, } std::ostringstream iconPath; iconPath << GlobalConfig::GetUserWidgetDesktopIconPath() << "/"; - iconPath << getIconTargetFilename(locale); - m_context.job->SendProgressIconPath(iconPath.str()); + iconPath << getIconTargetFilename(locale, extension); + m_context.job->SendProgressIconPath(iconPath.str()); } void TaskManifestFile::setWidgetDescription(Manifest & manifest) diff --git a/src/jobs/widget_install/task_manifest_file.h b/src/jobs/widget_install/task_manifest_file.h index a318fc8..98c3d23 100644 --- a/src/jobs/widget_install/task_manifest_file.h +++ b/src/jobs/widget_install/task_manifest_file.h @@ -118,7 +118,7 @@ class TaskManifestFile : DPL::OptionalString description); void generateWidgetIcon(UiApplication & uiApp, const DPL::OptionalString& tag, - const DPL::String& language, + const DPL::String& language, const std::string &extension, bool & defaultIconSaved); void DynamicBoxFileCopy(const std::string& sourceFile, const std::string& targetFile); @@ -126,7 +126,8 @@ class TaskManifestFile : //for widget update void backupIconFiles(); void getFileList(const char* path, std::list &list); - DPL::String getIconTargetFilename(const DPL::String& languageTag) const; + DPL::String getIconTargetFilename(const DPL::String& languageTag, + const std::string & ext) const; static void saveLocalizedKey(std::ofstream &file, const DPL::String& key, diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp old mode 100644 new mode 100755 index 221fd1c..161c5e0 --- a/src/jobs/widget_install/task_widget_config.cpp +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -82,6 +82,7 @@ TaskWidgetConfig::TaskWidgetConfig(InstallerContext& installContext) : AddStep(&TaskWidgetConfig::ProcessAppControlInfo); AddStep(&TaskWidgetConfig::ProcessSecurityModel); AddStep(&TaskWidgetConfig::StepVerifyFeatures); + AddStep(&TaskWidgetConfig::StepVerifyLivebox); AddStep(&TaskWidgetConfig::StepCheckMinVersionInfo); AddStep(&TaskWidgetConfig::EndStep); } @@ -293,7 +294,7 @@ void TaskWidgetConfig::ProcessBackgroundPageFile() void TaskWidgetConfig::ProcessLocalizedIcons() { using namespace WrtDB; - FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList) + FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList) { ProcessIcon(*i); } diff --git a/src/jobs/widget_install/widget_install_context.h b/src/jobs/widget_install/widget_install_context.h index 0c118e9..a293b14 100644 --- a/src/jobs/widget_install/widget_install_context.h +++ b/src/jobs/widget_install/widget_install_context.h @@ -42,6 +42,23 @@ class WidgetModel; typedef std::map RequestedDevCapsMap; +//TODO: move it elsewhere +enum class ConfigureResult +{ + Ok, + Updated, + Failed, + Failed_InvalidConfig, + Failed_LowerVersion, + Failed_AlreadyInstalled, + Failed_WidgetRunning, + Failed_DrmError, + Failed_NotSupportRDSUpdate, + Failed_OpenZipError, + Failed_UnzipError, + Unknown +}; + struct InstallerContext { typedef enum InstallStepEnum @@ -98,6 +115,10 @@ struct InstallerContext bool isUpdateMode; InstallMode mode; DPL::String callerPkgId; + + std::string requestedPath; + bool needEncryption; // TODO: (job_install_refactoring) place into wisily not here + ConfigureResult confResult; //configuration result - TODO: (job_install_refactoring) get rid of this }; #endif // INSTALLER_CONTEXT_H diff --git a/src/logic/installer_logic.cpp b/src/logic/installer_logic.cpp index a151125..a7927ce 100644 --- a/src/logic/installer_logic.cpp +++ b/src/logic/installer_logic.cpp @@ -106,7 +106,7 @@ Jobs::JobHandle InstallerLogic::UninstallWidget( } Jobs::JobHandle InstallerLogic::InstallPlugin( - std::string const & pluginPath, + std::string const & pluginPath, // TODO change type to PluginPath const PluginInstallerStruct & installerStruct) { @@ -118,9 +118,9 @@ Jobs::JobHandle InstallerLogic::InstallPlugin( LogDebug("New Plugin Installation"); - //Conversion to DPL::Utils::Path is temporary + // TODO Conversion to PluginPath is temporary m_job = - new Jobs::PluginInstall::JobPluginInstall(DPL::Utils::Path(pluginPath), installerStruct); + new Jobs::PluginInstall::JobPluginInstall(PluginPath(pluginPath), installerStruct); // before start install plugin, reset plugin data which is stopped // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS) diff --git a/src/misc/plugin_path.cpp b/src/misc/plugin_path.cpp new file mode 100644 index 0000000..2b2ebdb --- /dev/null +++ b/src/misc/plugin_path.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_path_builder.cpp + * @author Kamil Nować (k.nowac@partner.samgsung.com) + * @version + * @brief + */ + +#include +#include +#include + +using namespace DPL::Utils; + +PluginPath::PluginPath(const Path& fullPath) : Path(fullPath.Fullpath()) +{ + setLibraryCombinedName( + WrtDB::GlobalConfig::GetPluginPrefix(), + WrtDB::GlobalConfig::GetPluginSuffix()); +}; +PluginPath::PluginPath(const std::string& fullPath) : Path(fullPath) +{ + setLibraryCombinedName( + WrtDB::GlobalConfig::GetPluginPrefix(), + WrtDB::GlobalConfig::GetPluginSuffix()); +}; +PluginPath::PluginPath(const DPL::String& fullPath) : Path(fullPath) +{ + setLibraryCombinedName( + WrtDB::GlobalConfig::GetPluginPrefix(), + WrtDB::GlobalConfig::GetPluginSuffix()); +}; +PluginPath::PluginPath(){} + +PluginPath PluginPath::getMetaFile() const +{ + PluginPath metaFile = *this; + return metaFile /= WrtDB::GlobalConfig::GetPluginMetafileName(); +} \ No newline at end of file diff --git a/src/misc/plugin_path.h b/src/misc/plugin_path.h new file mode 100644 index 0000000..8ada790 --- /dev/null +++ b/src/misc/plugin_path.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file plugin_path_builder.cpp + * @author Kamil Nować (k.nowac@partner.samgsung.com) + * @version + * @brief + */ + +#ifndef PLUGIN_PATH_H +#define PLUGIN_PATH_H + +#include +#include +#include + +class PluginPath: public DPL::Utils::Path{ +private: + std::string m_library; + +public: + PluginPath(const DPL::Utils::Path& fullPath); + PluginPath(const std::string& fullPath); + PluginPath(const DPL::String& fullPath); + PluginPath(); + + //getMetafile() this function adds metafile to current path. + PluginPath getMetaFile() const; + + //setLibraryCombinedName This function creates name for library by adding + //prefix and suffix to PluginPath object filename. + void setLibraryCombinedName(const std::string& prefix, const std::string& sufix) + { + this->m_library = prefix + this->Filename() + sufix; + } + + //getLibraryName returns library name + const std::string& getLibraryName() const + { + return m_library; + } + //getLibraryPath returns full path to the library + const PluginPath getLibraryPath() const + { + return this->operator /(m_library); + } +}; + +#endif // PLUGIN_PATH_H diff --git a/src/pkg-manager/backendlib.cpp b/src/pkg-manager/backendlib.cpp index 7995119..40665f5 100644 --- a/src/pkg-manager/backendlib.cpp +++ b/src/pkg-manager/backendlib.cpp @@ -319,8 +319,8 @@ int getConfigParserData(const std::string &widgetPath, ConfigParserData& configI return TRUE; } -char* getIconInfo(const std::string widgetPath, - const std::string icon_name, int &icon_size) +char* getIconInfo(const std::string &widgetPath, + const std::string &icon_name, int &icon_size) { Try { std::unique_ptr zipFile( @@ -349,16 +349,62 @@ char* getIconInfo(const std::string widgetPath, } Catch(DPL::ZipInput::Exception::OpenFailed) { - LogError("Failed to open widget package"); + LogDebug("Failed to open widget package"); return NULL; } Catch(DPL::ZipInput::Exception::OpenFileFailed) { - LogError("Failed to open icon file"); + LogDebug("Not found icon file " << icon_name); return NULL; } } +char* getIconForLocale(const std::string& bp, const std::string& tag, + const std::string& icon, int & size) +{ + std::string iconPath; + if (!tag.empty()) { + iconPath += std::string("locales/") + tag; + } + if (!iconPath.empty()) { + iconPath += "/"; + } + + iconPath += icon; + return getIconInfo(bp, iconPath, size); +} + +char* getIcon(const std::string & basepath, const WrtDB::ConfigParserData & config, int & size) +{ + const std::list defaultIcons{ "icon.svg", "icon.ico", "icon.png", "icon.gif", "icon.jpg" }; + LanguageTags tagsList = + LanguageTagsProviderSingleton::Instance().getLanguageTags(); + + char * result = NULL; + + //for each locale tag - searching for icon presence and returning raw data + //first found is best as locale tags are ordered + FOREACH(tag, tagsList) + { + FOREACH(icon, config.iconsList) + { + std::string src = DPL::ToUTF8String(icon->src); + result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), src, size); + if(result) { + return result; + } + } + FOREACH(i, defaultIcons) + { + result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), *i, size); + if(result) { + return result; + } + } + } + return NULL; +} + int getWidgetDetailInfoFromPackage(const char* pkgPath, package_manager_pkg_detail_info_t* pkg_detail_info) { @@ -463,16 +509,16 @@ int getWidgetDetailInfoFromPackage(const char* pkgPath, g_list_append(pkg_detail_info->privilege_list, privilege); } - std::string icon_name; - FOREACH(i, configInfo.iconsList) { - LogDebug("icon name: " << i->src); - icon_name = DPL::ToUTF8String(i->src); - break; - } + char* icon_buf = getIcon(widget_path, configInfo, pkg_detail_info->icon_size); - pkg_detail_info->icon_buf = getIconInfo(widget_path, icon_name, - pkg_detail_info->icon_size); - LogDebug("icon size : " << pkg_detail_info->icon_size); + if (icon_buf) { + LogDebug("icon size : " << pkg_detail_info->icon_size); + pkg_detail_info->icon_buf = icon_buf; + } else { + LogDebug("No icon"); + pkg_detail_info->icon_size = 0; + pkg_detail_info->icon_buf = NULL; + } return TRUE; } diff --git a/src/wrt-installer/installer_callbacks_translate.cpp b/src/wrt-installer/installer_callbacks_translate.cpp index 5e415d2..5e067e9 100644 --- a/src/wrt-installer/installer_callbacks_translate.cpp +++ b/src/wrt-installer/installer_callbacks_translate.cpp @@ -249,12 +249,12 @@ void installProgressCallback(void *userParam, if (apiStr->progress_callback) { //CALLBACK EXEC - LogDebug("Entered " << percent << "% " << description); + LogPedantic("Entered " << percent << "% " << description); apiStr->progress_callback(static_cast(percent), description.c_str(), apiStr->userdata); } else { - LogDebug("installProgressCallback: ignoring NULL callback pointer"); + LogPedantic("installProgressCallback: ignoring NULL callback pointer"); } } } //namespace -- 2.7.4