From df7b007c93bbec244392ef29d3a244cba9f9a781 Mon Sep 17 00:00:00 2001 From: Jihoon Chung Date: Sat, 13 Apr 2013 16:55:06 +0900 Subject: [PATCH] [Release] wrt-installer_0.1.26 --- CMakeLists.txt | 8 ++ packaging/wrt-installer.spec | 4 +- src/configuration_parser/widget_parser.cpp | 58 +++++++- src/jobs/widget_install/job_widget_install.cpp | 13 +- src/jobs/widget_install/manifest.h | 12 ++ src/jobs/widget_install/task_manifest_file.cpp | 192 ++++++++++++++++++++----- src/jobs/widget_install/task_manifest_file.h | 17 ++- src/jobs/widget_install/task_widget_config.cpp | 82 +++-------- 8 files changed, 276 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a23ce2..fdb5f18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,8 @@ SET(CMAKE_CXX_FLAGS_CCOV "-O0 -std=c++0x -g --coverage") OPTION(DPL_LOG "DPL logs status" ON) OPTION(WITH_TESTS "Build tests" OFF) +OPTION(MULTIPROCESS_SERVICE_SUPPORT "Process per service" OFF) +OPTION(MULTIPROCESS_SERVICE_SUPPORT_INLINE "Process per service - inline mode support" OFF) IF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") MESSAGE(STATUS "Logging enabled for DPL") ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") @@ -61,6 +63,12 @@ ELSE(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") MESSAGE(STATUS "Logging disabled for DPL") ENDIF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling") MESSAGE(STATUS "WITH_TESTS: " ${WITH_TESTS}) +IF(MULTIPROCESS_SERVICE_SUPPORT) + ADD_DEFINITIONS("-DMULTIPROCESS_SERVICE_SUPPORT") + IF (MULTIPROCESS_SERVICE_SUPPORT_INLINE) + ADD_DEFINITIONS("-DMULTIPROCESS_SERVICE_SUPPORT_INLINE") + ENDIF(MULTIPROCESS_SERVICE_SUPPORT_INLINE) +ENDIF(MULTIPROCESS_SERVICE_SUPPORT) # If supported for the target machine, emit position-independent code,suitable # for dynamic linking and avoiding any limit on the size of the global offset diff --git a/packaging/wrt-installer.spec b/packaging/wrt-installer.spec index ce45cf0..aa7361e 100644 --- a/packaging/wrt-installer.spec +++ b/packaging/wrt-installer.spec @@ -1,7 +1,7 @@ -#git:framework/web/wrt-installer wrt-installer 0.1.25 +#git:framework/web/wrt-installer wrt-installer 0.1.26 Name: wrt-installer Summary: Installer for tizen Webruntime -Version: 0.1.25 +Version: 0.1.26 Release: 1 Group: Development/Libraries License: Apache License, Version 2.0 diff --git a/src/configuration_parser/widget_parser.cpp b/src/configuration_parser/widget_parser.cpp index 39b139c..2f12265 100644 --- a/src/configuration_parser/widget_parser.cpp +++ b/src/configuration_parser/widget_parser.cpp @@ -702,7 +702,8 @@ class ContentParser : public ElementParser m_type = value; MimeTypeUtils::MimeAttributes mimeAttributes = MimeTypeUtils::getMimeAttributes(value); - if (mimeAttributes.count(L"charset") > 0) { + if ((mimeAttributes.count(L"charset") > 0) && m_encoding.IsNull()) + { m_encoding = mimeAttributes[L"charset"]; } } else if (attribute.name == L"encoding") { @@ -1251,6 +1252,53 @@ class AppControlParser : public ElementParser ConfigParserData::AppControlInfo& m_data; }; + struct DispositionParser : public ElementParser + { + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const Text& /*text*/) + {} + + virtual void Accept(const Element& /*element*/) + {} + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"disposition") { + if (attribute.value.size() > 0) { + m_value = attribute.value; + NormalizeString(m_value); + } + } + } + + virtual void Verify() + { + if (m_value.IsNull() || *m_value != L"inline") { + m_data.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW; + } + else { + m_data.m_disposition = ConfigParserData::AppControlInfo::Disposition::INLINE; + } + } + + DispositionParser(ConfigParserData::AppControlInfo& data) : + ElementParser(), + m_properNamespace(false), + m_data(data) + {} + + private: + bool m_properNamespace; + DPL::OptionalString m_value; + ConfigParserData::AppControlInfo& m_data; + }; + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, const DPL::String& name) { @@ -1263,6 +1311,9 @@ class AppControlParser : public ElementParser return DPL::MakeDelegate(this, &AppControlParser::OnUriElement); } else if (name == L"mime") { return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement); + } else if (name == L"disposition") { + return DPL::MakeDelegate(this, + &AppControlParser::OnDispositionElement); } else { return &IgnoringParser::Create; } @@ -1320,6 +1371,11 @@ class AppControlParser : public ElementParser return ElementParserPtr(new MimeParser(m_appControl)); } + ElementParserPtr OnDispositionElement() + { + return ElementParserPtr(new DispositionParser(m_appControl)); + } + AppControlParser(ConfigParserData& data) : ElementParser(), m_data(data), diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index 8579e9a..fe6103f 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -585,6 +585,10 @@ ConfigureResult JobWidgetInstall::checkWidgetUpdate( LogInfo("incoming version = '" << update.incomingVersion); LogInfo("Tizen AppID = " << update.tzAppId); + if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) { + return ConfigureResult::Failed; + } + // Check running state bool isRunning = false; int retval = @@ -769,9 +773,16 @@ WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( } WidgetDAOReadOnly dao(tizenId); + + OptionalWidgetVersion optVersion; + DPL::OptionalString version = dao.getVersion(); + if (!version.IsNull()) { + optVersion = OptionalWidgetVersion(WidgetVersion(*version)); + } + return WidgetUpdateInfo( dao.getTzAppId(), - WidgetVersion(*dao.getVersion()), + optVersion, incomingVersion); } diff --git a/src/jobs/widget_install/manifest.h b/src/jobs/widget_install/manifest.h index e6f7827..d30ef15 100644 --- a/src/jobs/widget_install/manifest.h +++ b/src/jobs/widget_install/manifest.h @@ -53,6 +53,11 @@ class StringWithLang { return !this->lang.empty(); } + int operator==(const StringWithLang &other) + { + return (DPL::ToUTF8String(other.string) == DPL::ToUTF8String(string)) && + (DPL::ToUTF8String(other.lang) == DPL::ToUTF8String(lang)); + } private: DPL::String string; @@ -449,7 +454,14 @@ class Manifest void addLabel(const LabelType &x) { +#ifdef MULTIPROCESS_SERVICE_SUPPORT + auto pos = std::find(label.begin(), label.end(), x); + if (pos == label.end()) { + this->label.push_back(x); + } +#else this->label.push_back(x); +#endif } void addIcon(const IconType &x) { diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp index a5124a0..009b315 100644 --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -133,18 +133,43 @@ void TaskManifestFile::stepCreateExecFile() std::string exec = m_context.locations->getExecFile(); std::string clientExeStr = GlobalConfig::GetWrtClientExec(); + //default widget LogInfo("link -s " << clientExeStr << " " << exec); - errno = 0; - if (symlink(clientExeStr.c_str(), exec.c_str()) != 0) + if (symlink(clientExeStr.c_str(), exec.c_str()) != 0) { int error = errno; - if(error) + if (error) LogPedantic("Failed to make a symbolic name for a file " << "[" << DPL::GetErrnoString(error) << "]"); ThrowMsg(Exceptions::FileOperationFailed, "Symbolic link creating is not done."); } + +#ifdef MULTIPROCESS_SERVICE_SUPPORT + //services + std::size_t serviceCount = + m_context.widgetConfig.configInfo.appControlList.size(); + serviceCount += m_context.widgetConfig.configInfo.appServiceList.size(); + for (std::size_t i = 0; i < serviceCount; ++i) { + std::stringstream postfix; + postfix << "-__SERVICE_PROCESS__" << i; + std::string serviceExec = exec; + serviceExec.append(postfix.str()); + errno = 0; + if (symlink(clientExeStr.c_str(), serviceExec.c_str()) != 0) + { + int error = errno; + if (error) + LogPedantic("Failed to make a symbolic name for a file " + << "[" << DPL::GetErrnoString(error) << "]"); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + + } +#endif + m_context.job->UpdateProgress( InstallerContext::INSTALL_CREATE_EXECFILE, "Widget execfile creation Finished"); @@ -572,29 +597,100 @@ void TaskManifestFile::writeManifest(const DPL::String & path) Manifest manifest; UiApplication uiApp; + //default widget content setWidgetExecPath(uiApp); setWidgetName(manifest, uiApp); + setWidgetIds(manifest, uiApp); setWidgetIcons(uiApp); setWidgetManifest(manifest); setWidgetOtherInfo(uiApp); - setAppServiceInfo(uiApp); - setAppControlInfo(uiApp); +#ifndef MULTIPROCESS_SERVICE_SUPPORT + setAppServicesInfo(uiApp); + setAppControlsInfo(uiApp); +#endif setAppCategory(uiApp); setLiveBoxInfo(manifest); setAccount(manifest); setPrivilege(manifest); manifest.addUiApplication(uiApp); +#ifdef MULTIPROCESS_SERVICE_SUPPORT + //services AppControl tag + ConfigParserData::AppControlInfoList appControlList = + m_context.widgetConfig.configInfo.appControlList; + unsigned count = 0; + + FOREACH(it, appControlList) { + it->m_index = count; + UiApplication uiApp; + + uiApp.setTaskmanage(true); + uiApp.setNodisplay(true); +#ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE + uiApp.setTaskmanage(ConfigParserData::AppControlInfo::Disposition::INLINE != it->m_disposition); + uiApp.setMultiple(ConfigParserData::AppControlInfo::Disposition::INLINE == it->m_disposition); +#endif + std::stringstream postfix; + postfix << "-__SERVICE_PROCESS__" << count++; + + setWidgetExecPath(uiApp, postfix.str()); + setWidgetName(manifest, uiApp); + setWidgetIds(manifest, uiApp, postfix.str()); + setWidgetIcons(uiApp); + setAppControlInfo(uiApp, *it); + setAppCategory(uiApp); + setAccount(manifest); + setPrivilege(manifest); + + manifest.addUiApplication(uiApp); + } + //TODO: AppService tag will be removed + //services AppService tag + WrtDB::ConfigParserData::ServiceInfoList appServiceList = + m_context.widgetConfig.configInfo.appServiceList; + FOREACH(it, appServiceList) { + it->m_index = count; + UiApplication uiApp; + + uiApp.setTaskmanage(true); + uiApp.setNodisplay(true); +#ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE + uiApp.setTaskmanage(ConfigParserData::ServiceInfo::Disposition::INLINE != it->m_disposition); + uiApp.setMultiple(ConfigParserData::ServiceInfo::Disposition::INLINE == it->m_disposition); +#endif + + std::stringstream postfix; + postfix << "-__SERVICE_PROCESS__" << count++; + + setWidgetExecPath(uiApp, postfix.str()); + setWidgetName(manifest, uiApp); + setWidgetIds(manifest, uiApp, postfix.str()); + setWidgetIcons(uiApp); + setAppServiceInfo(uiApp, *it); + setAppCategory(uiApp); + setAccount(manifest); + setPrivilege(manifest); + + manifest.addUiApplication(uiApp); + } +#endif manifest.generate(path); LogDebug("Manifest file serialized"); } -void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp) +void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp, + const std::string &postfix) { - uiApp.setExec(DPL::FromASCIIString(m_context.locations->getExecFile())); + std::string exec = m_context.locations->getExecFile(); + if (!postfix.empty()) { + exec.append(postfix); + } + LogDebug("exec = " << exec); + uiApp.setExec(DPL::FromASCIIString(exec)); } -void TaskManifestFile::setWidgetName(Manifest & manifest, UiApplication & uiApp) +void TaskManifestFile::setWidgetName(Manifest & manifest, + UiApplication & uiApp) { bool defaultNameSaved = false; @@ -627,8 +723,17 @@ void TaskManifestFile::setWidgetName(Manifest & manifest, UiApplication & uiApp) name, defaultNameSaved); } +} + +void TaskManifestFile::setWidgetIds(Manifest & manifest, + UiApplication & uiApp, + const std::string &postfix) +{ //appid TizenAppId appid = m_context.widgetConfig.tzAppid; + if (!postfix.empty()) { + appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix)); + } uiApp.setAppid(appid); //extraid @@ -781,7 +886,7 @@ void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp) //that were in desktop file } -void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp) +void TaskManifestFile::setAppServicesInfo(UiApplication & uiApp) { WrtDB::ConfigParserData::ServiceInfoList appServiceList = m_context.widgetConfig.configInfo.appServiceList; @@ -793,21 +898,11 @@ void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp) // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image; FOREACH(it, appServiceList) { - AppControl appControl; - if (!it->m_operation.empty()) { - appControl.addOperation(it->m_operation); //TODO: encapsulation? - } - if (!it->m_scheme.empty()) { - appControl.addUri(it->m_scheme); - } - if (!it->m_mime.empty()) { - appControl.addMime(it->m_mime); - } - uiApp.addAppControl(appControl); - } -} + setAppServiceInfo(uiApp, *it); + } + } -void TaskManifestFile::setAppControlInfo(UiApplication & uiApp) +void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp) { WrtDB::ConfigParserData::AppControlInfoList appControlList = m_context.widgetConfig.configInfo.appControlList; @@ -817,24 +912,47 @@ void TaskManifestFile::setAppControlInfo(UiApplication & uiApp) return; } - // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image; + // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image; FOREACH(it, appControlList) { - AppControl appControl; - if (!it->m_operation.empty()) { - appControl.addOperation(it->m_operation); //TODO: encapsulation? - } - if (!it->m_uriList.empty()) { - FOREACH(uri, it->m_uriList) { - appControl.addUri(*uri); - } + setAppControlInfo(uiApp, *it); + } +} + +void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp, + const ConfigParserData::ServiceInfo & service) +{ + AppControl appControl; + if (!service.m_operation.empty()) { + appControl.addOperation(service.m_operation); //TODO: encapsulation? + } + if (!service.m_scheme.empty()) { + appControl.addUri(service.m_scheme); + } + if (!service.m_mime.empty()) { + appControl.addMime(service.m_mime); + } + uiApp.addAppControl(appControl); +} + +void TaskManifestFile::setAppControlInfo(UiApplication & uiApp, + const WrtDB::ConfigParserData::AppControlInfo & service) +{ + // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image; + AppControl appControl; + if (!service.m_operation.empty()) { + appControl.addOperation(service.m_operation); //TODO: encapsulation? + } + if (!service.m_uriList.empty()) { + FOREACH(uri, service.m_uriList) { + appControl.addUri(*uri); } - if (!it->m_mimeList.empty()) { - FOREACH(mime, it->m_mimeList) { - appControl.addMime(*mime); - } + } + if (!service.m_mimeList.empty()) { + FOREACH(mime, service.m_mimeList) { + appControl.addMime(*mime); } - uiApp.addAppControl(appControl); } + uiApp.addAppControl(appControl); } void TaskManifestFile::setAppCategory(UiApplication &uiApp) diff --git a/src/jobs/widget_install/task_manifest_file.h b/src/jobs/widget_install/task_manifest_file.h index 0cdbe61..36a1c92 100644 --- a/src/jobs/widget_install/task_manifest_file.h +++ b/src/jobs/widget_install/task_manifest_file.h @@ -89,14 +89,23 @@ class TaskManifestFile : void writeManifest(const DPL::String & path); void commitManifest(); - void setWidgetExecPath(UiApplication & uiApp); - void setWidgetName(Manifest & manifest, UiApplication & uiApp); + void setWidgetExecPath(UiApplication & uiApp, + const std::string &postfix = std::string()); + void setWidgetName(Manifest & manifest, + UiApplication & uiApp); + void setWidgetIds(Manifest & manifest, + UiApplication & uiApp, + const std::string &postfix = std::string()); void setWidgetIcons(UiApplication & uiApp); void setWidgetManifest(Manifest & manifest); void setWidgetOtherInfo(UiApplication & uiApp); /* please use AppControl. this function will be removed. */ - void setAppServiceInfo(UiApplication & uiApp); - void setAppControlInfo(UiApplication & uiApp); + void setAppServicesInfo(UiApplication & uiApp); + void setAppControlsInfo(UiApplication & uiApp); + void setAppServiceInfo(UiApplication & uiApp, + const WrtDB::ConfigParserData::ServiceInfo & service); + void setAppControlInfo(UiApplication & uiApp, + const WrtDB::ConfigParserData::AppControlInfo & service); void setAppCategory(UiApplication & uiApp); void setLiveBoxInfo(Manifest& manifest); void setAccount(Manifest& uiApp); diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp index cbf6590..d7c3640 100644 --- a/src/jobs/widget_install/task_widget_config.cpp +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -650,78 +650,30 @@ bool TaskWidgetConfig::parseConfigurationFileWidget( WrtDB::ConfigParserData& configInfo, const std::string& _currentPath) { - ParserRunner parser; - - //TODO: rewrite this madness - std::string cfgAbsPath; - DIR* dir = NULL; - - dir = opendir(_currentPath.c_str()); - if (dir == NULL) { + std::string configFilePath; + WrtUtilJoinPaths(configFilePath, _currentPath, WRT_WIDGET_CONFIG_FILE_NAME); + if (!WrtUtilFileExists(configFilePath)) + { + LogError("Archive does not contain configuration file"); return false; } - bool has_config_xml = false; - struct dirent ptr; - struct dirent *result; - int return_code; - errno = 0; - //Find configuration file, based on its name - for (return_code = readdir_r(dir, &ptr, &result); - result != NULL && return_code == 0; - return_code = readdir_r(dir, &ptr, &result)) - { - if (ptr.d_type == DT_REG) { - if (!strcmp(ptr.d_name, WRT_WIDGET_CONFIG_FILE_NAME)) { - std::string dName(ptr.d_name); - WrtUtilJoinPaths(cfgAbsPath, _currentPath, dName); - - //Parse widget configuration file - LogDebug("Found config: " << cfgAbsPath); - - Try - { - parser.Parse(cfgAbsPath, ElementParserPtr(new - RootParser< - WidgetParser>( - configInfo, - DPL - :: - FromUTF32String( - L"widget")))); - } - Catch(ElementParser::Exception::Base) - { - LogError("Invalid widget configuration file!"); - if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { - LogError( - "Failed to close dir: " << _currentPath << - " with error: " - << DPL::GetErrnoString()); - } - return false; - } + LogDebug("Configuration file: " << configFilePath); - has_config_xml = true; - break; - } - } - } - if (errno != 0) { - LogError("readdir_r() failed with " << DPL::GetErrnoString()); - } - errno = 0; - if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { - LogError("Failed to close dir: " << _currentPath << " with error: " - << DPL::GetErrnoString()); + Try + { + ParserRunner parser; + parser.Parse(configFilePath, + ElementParserPtr(new RootParser( + configInfo, + DPL::FromUTF32String(L"widget")))); + return true; } - - //We must have config.xml so leaveing if we doesn't - if (!has_config_xml) { - LogError("Invalid archive"); + Catch (ElementParser::Exception::Base) + { + LogError("Invalid configuration file!"); return false; } - return true; } bool TaskWidgetConfig::locateAndParseConfigurationFile( -- 2.7.4