[Release] wrt-installer_0.1.26
authorJihoon Chung <jihoon.chung@samsung.com>
Sat, 13 Apr 2013 07:55:06 +0000 (16:55 +0900)
committerJihoon Chung <jihoon.chung@samsung.com>
Sat, 13 Apr 2013 07:55:06 +0000 (16:55 +0900)
CMakeLists.txt
packaging/wrt-installer.spec
src/configuration_parser/widget_parser.cpp
src/jobs/widget_install/job_widget_install.cpp
src/jobs/widget_install/manifest.h
src/jobs/widget_install/task_manifest_file.cpp
src/jobs/widget_install/task_manifest_file.h
src/jobs/widget_install/task_widget_config.cpp

index 5a23ce2..fdb5f18 100644 (file)
@@ -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
index ce45cf0..aa7361e 100644 (file)
@@ -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
index 39b139c..2f12265 100644 (file)
@@ -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),
index 8579e9a..fe6103f 100644 (file)
@@ -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);
 }
 
index e6f7827..d30ef15 100644 (file)
@@ -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)
     {
index a5124a0..009b315 100644 (file)
@@ -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)
index 0cdbe61..36a1c92 100644 (file)
@@ -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);
index cbf6590..d7c3640 100644 (file)
@@ -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<WidgetParser>(
+                                          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(