[Release] wrt-installer_0.1.85
authorJihoon Chung <jihoon.chung@samsung.com>
Sat, 22 Jun 2013 12:17:07 +0000 (21:17 +0900)
committerJihoon Chung <jihoon.chung@samsung.com>
Sat, 22 Jun 2013 12:23:50 +0000 (21:23 +0900)
Change-Id: I543a7fb595d9a3eea4c064bf427ebae65d27ad97

40 files changed:
configuration/config.xml
configuration/validate-config.xml.sh [new file with mode: 0755]
configuration/widgets.tizen.xsd [changed mode: 0755->0644]
etc/CMakeLists.txt
etc/default_icon_tizen.png [new file with mode: 0644]
packaging/wrt-installer.spec
packaging/wrt-preinstall-widgets.service
src/configuration_parser/widget_parser.cpp [changed mode: 0755->0644]
src/jobs/plugin_install/job_plugin_install.cpp
src/jobs/plugin_install/job_plugin_install.h
src/jobs/plugin_install/plugin_install_task.cpp
src/jobs/plugin_install/plugin_installer_context.h
src/jobs/plugin_install/plugin_metafile_reader.h
src/jobs/widget_install/directory_api.cpp
src/jobs/widget_install/job_widget_install.cpp
src/jobs/widget_install/manifest.cpp [changed mode: 0755->0644]
src/jobs/widget_install/manifest.h [changed mode: 0755->0644]
src/jobs/widget_install/task_certify.cpp
src/jobs/widget_install/task_certify.h
src/jobs/widget_install/task_file_manipulation.cpp
src/jobs/widget_install/task_install_ospsvc.cpp
src/jobs/widget_install/task_manifest_file.cpp
src/jobs/widget_install/task_remove_backup.cpp
src/jobs/widget_install/task_widget_config.cpp
src/jobs/widget_install/widget_unzip.cpp
src/jobs/widget_uninstall/job_widget_uninstall.cpp
src/jobs/widget_uninstall/task_remove_files.cpp [changed mode: 0755->0644]
src/jobs/widget_uninstall/uninstaller_context.h
src/logic/installer_logic.cpp
src/logic/installer_logic.h
src/misc/widget_location.cpp
src/misc/widget_location.h
tests/general/CMakeLists.txt
tests/general/WidgetUpdateTests.cpp [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer100Signed.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer100Unsigned.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220Signed.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220Unsigned.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt [new file with mode: 0644]

index 038ec52..f33ce7e 100644 (file)
@@ -7,7 +7,7 @@
   <tizen:application id="GfeI4eyhBG.1" package="GfeI4eyhBG" required_version="2.1"/>
 
   <!-- tizen setting element -->
-  <tizen:setting screen-orientation="landscape" context-menu="disable" background-support="enable" encryption="enable" install-location="internal-only"/>
+  <tizen:setting screen-orientation="landscape" context-menu="disable" background-support="enable" encryption="enable" hwkey-event="enable"/>
 
   <!-- tizen app-control element -->
   <tizen:app-control>
 
   <!-- tizen metadata -->
   <tizen:metadata key="key_1" value="value_1"/>
+  <tizen:metadata key="key_2"/>
+
+  <tizen:app-widget id="jNZe0gZhHG.Dynmic.default" primary="true">
+    <tizen:box-label xml:lang="en">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-label xml:lang="ef">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-label xml:lang="tc">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-icon src="icon.png"/>
+    <tizen:box-content src="box/index.html">
+      <tizen:box-size>1x1</tizen:box-size>
+      <tizen:box-size>2x1</tizen:box-size>
+      <tizen:box-size>2x2</tizen:box-size>
+      <tizen:pd src="pd/index.html" width="720" height="200"/>
+   </tizen:box-content>
+ </tizen:app-widget>
+
+  <!-- splash screen -->
+  <tizen:splash src="splash.jpg" />
 </widget>
diff --git a/configuration/validate-config.xml.sh b/configuration/validate-config.xml.sh
new file mode 100755 (executable)
index 0000000..a242910
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+xmllint --schema widgets.xsd config.xml
old mode 100755 (executable)
new mode 100644 (file)
index 238d216..1b7c8c6
@@ -77,6 +77,7 @@
             <xs:attribute name="indicator-persence" type="tizen:data.boolean" use="optional"/>
             <xs:attribute name="backbutton-persence" type="tizen:data.boolean" use="optional"/>
             <xs:attribute name="user-agent" use="optional"/>
+            <xs:attribute name="hwkey-event" type="tizen:activationType" use="optional"/> <!-- default: true -->
         </xs:complexType>
     </xs:element>
 
 
     <xs:element name="app-widget">
         <xs:complexType mixed="true">
-            <xs:all>
-                <xs:element ref="tizen:box-label"/>
-                <xs:element ref="tizen:box-icon"/>
-                <xs:element ref="tizen:box-content"/>
-            </xs:all>
+            <xs:sequence>
+                <xs:element ref="tizen:box-label" minOccurs="1" maxOccurs="unbounded"/>
+                <xs:element ref="tizen:box-icon" minOccurs="1" maxOccurs="1"/>
+                <xs:element ref="tizen:box-content" minOccurs="1" maxOccurs="1"/>
+            </xs:sequence>
             <xs:attribute name="id" type="tizen:appWidgetIdType" use="required"/>
             <xs:attribute name="primary" type="tizen:data.boolean" use="required"/>
             <xs:attribute name="auto-launch" type="tizen:data.boolean" use="optional"/>
 
     <xs:element name="box-label">
         <xs:complexType mixed="true">
-            <xs:attribute ref="xml:lang" minOccurs="1"/>
+            <xs:attribute ref="xml:lang"/>
         </xs:complexType>
     </xs:element>
 
     <xs:element name="box-size">
         <xs:complexType mixed="true">
         <xs:attribute name="preview" use="optional" type="xs:anyURI"/>
+        <xs:attribute name="use-decoration" use="optional" type="tizen:data.boolean"/>
         </xs:complexType>
     </xs:element>
 
     <xs:element name="metadata">
         <xs:complexType>
             <xs:attribute name="key" type="xs:string" use="required"/>
-            <xs:attribute name="value" type="xs:string" use="required"/>
+            <xs:attribute name="value" type="xs:string"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="splash">
+        <xs:complexType>
+            <xs:attribute name="src" type="xs:string" use="required"/>
         </xs:complexType>
     </xs:element>
 </xs:schema>
index c48caa4..372dcbe 100644 (file)
@@ -1,3 +1,5 @@
 SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc)
 
 INSTALL(PROGRAMS ${ETC_DIR}/wrt_preinstall_widgets.sh DESTINATION /usr/bin/)
+INSTALL(FILES ${ETC_DIR}/default_icon_tizen.png DESTINATION share/wrt-engine/)
+
diff --git a/etc/default_icon_tizen.png b/etc/default_icon_tizen.png
new file mode 100644 (file)
index 0000000..1c3ecd6
Binary files /dev/null and b/etc/default_icon_tizen.png differ
index 7a28830..598b3fd 100644 (file)
@@ -1,7 +1,7 @@
 #git:framework/web/wrt-installer
 Name:       wrt-installer
 Summary:    Installer for tizen Webruntime
-Version:    0.1.74
+Version:    0.1.85
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
@@ -110,3 +110,4 @@ mkdir -p /opt/share/icons/default/small
     %attr(755,root,root) %{_bindir}/wrt-installer-tests-*
     /opt/share/widget/tests/installer/widgets/*
 %endif
+%{_datadir}/wrt-engine/default_icon_tizen.png
index 2a66867..0fe2781 100644 (file)
@@ -1,7 +1,7 @@
 [Unit]
 Description=WRT Preinstall Widgets
-After=tizen-system.target
-Requires=tizen-system.target
+After=tizen-runtime.target
+Requires=tizen-runtime.target
 
 [Service]
 Type=forking
old mode 100755 (executable)
new mode 100644 (file)
index 5a56c0f..00c9fc3
@@ -724,7 +724,7 @@ class ContentParser : public ElementParser
 
     virtual void Verify()
     {
-        if(!!m_data.startFile)
+        if(!!m_data.startFileEncountered)
         {
             if(m_data.startFileNamespace == m_namespace
                 || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
@@ -734,6 +734,7 @@ class ContentParser : public ElementParser
             //else continue -> if previous item was not in tizen namespace
         }
 
+        m_data.startFileEncountered = true;
         m_data.startFileNamespace = m_namespace;
 
         //we're consciously setting startFile even if m_src is null or invalid.
@@ -1373,24 +1374,33 @@ class SplashParser : public ElementParser
 
     virtual void Accept(const XmlAttribute& attribute)
     {
-        if (attribute.name == L"src") {
-            if (attribute.value.size() > 0) {
-                m_src = attribute.value;
+        if (m_properNamespace)
+        {
+            if (attribute.name == L"src") {
+                if (attribute.value.size() > 0) {
+                    m_src = attribute.value;
+                }
             }
         }
     }
 
-    virtual void Accept(const Element& /*element*/)
-    {}
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
 
     virtual void Accept(const Text& /*text*/)
     {}
 
     virtual void Verify()
     {
-        if (m_src.IsNull()) {
-            LogWarning(
-                "src attribute of splash element is mandatory - ignoring");
+        if (m_src.IsNull())
+        {
+            LogWarning("src attribute of splash element is mandatory - ignoring");
             return;
         }
 
@@ -1399,12 +1409,14 @@ class SplashParser : public ElementParser
 
     SplashParser(ConfigParserData& data) :
         ElementParser(),
-        m_data(data)
+        m_data(data),
+        m_properNamespace(false)
     {}
 
   private:
     DPL::OptionalString m_src;
     ConfigParserData& m_data;
+    bool m_properNamespace;
 };
 
 class BackgroundParser : public ElementParser
@@ -1616,14 +1628,18 @@ class AppWidgetParser : public ElementParser
 
         virtual void Verify()
         {
+            std::pair<DPL::String, DPL::String> boxLabel;
             if (m_label.empty()) {
-                ThrowMsg(Exception::ParseError,
-                        "box-label element cannot be empty - ignoring");
+                LogWarning("box-label element is empty");
+                boxLabel.first = DPL::FromUTF8String("");
+                boxLabel.second = DPL::FromUTF8String("");
+                m_data.m_label.push_back(boxLabel);
+            }
+            else {
+                boxLabel.first = m_lang;
+                boxLabel.second = m_label;
+                m_data.m_label.push_back(boxLabel);
             }
-            std::pair<DPL::String, DPL::String> boxLabel;
-            boxLabel.first = m_lang;
-            boxLabel.second = m_label;
-            m_data.m_label.push_back(boxLabel);
         }
 
         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
@@ -1705,6 +1721,9 @@ class AppWidgetParser : public ElementParser
                     if (attribute.name == L"preview") {
                         m_preview = attribute.value;
                     }
+                    if (attribute.name == L"use-decoration") {
+                        m_useDecoration = attribute.value;
+                    }
                 }
             }
 
@@ -1731,10 +1750,11 @@ class AppWidgetParser : public ElementParser
                         "size is mandatory - ignoring");
                 }
 
-                std::pair<DPL::String, DPL::String> boxSize;
-                boxSize.first = m_size;
-                boxSize.second = m_preview;
-                m_data.m_boxSize.push_back(boxSize);
+                ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
+                boxSizeInfo.m_size = m_size;
+                boxSizeInfo.m_preview = m_preview;
+                boxSizeInfo.m_useDecoration = m_useDecoration;
+                m_data.m_boxSize.push_back(boxSizeInfo);
             }
 
             explicit BoxSizeParser(
@@ -1747,6 +1767,7 @@ class AppWidgetParser : public ElementParser
           private:
             DPL::String m_size;
             DPL::String m_preview;
+            DPL::String m_useDecoration;
             bool m_properNamespace;
             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
         };
@@ -2615,9 +2636,9 @@ class MetadataParser : public ElementParser
         }
         NormalizeString(m_key);
         NormalizeString(m_value);
-        ConfigParserData::Metadata metaData(*m_key, *m_value);
+        ConfigParserData::Metadata metaData(m_key, m_value);
         FOREACH(it, m_data.metadataList) {
-            if (!DPL::StringCompare(it->key, *m_key)) {
+            if (!DPL::StringCompare(*it->key, *m_key)) {
                 LogError("Key isn't unique");
                 return;
             }
index 38c0aef..811c049 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace Jobs {
 namespace PluginInstall {
-JobPluginInstall::JobPluginInstall(std::string const &pluginPath,
+JobPluginInstall::JobPluginInstall(DPL::Utils::Path const &pluginPath,
                                    const PluginInstallerStruct &installerStruct)
     :
     Job(PluginInstallation),
index 0af9c04..c4a59ee 100644 (file)
@@ -31,6 +31,7 @@
 #include <job_base.h>
 #include <plugin_install/plugin_installer_struct.h>
 #include <plugin_install/plugin_installer_context.h>
+#include <dpl/utils/path.h>
 
 namespace Jobs {
 namespace PluginInstall {
@@ -47,7 +48,7 @@ class JobPluginInstall :
     /**
      * @brief Automaticaly sets installation process
      */
-    JobPluginInstall(std::string const &pluginPath,
+    JobPluginInstall(DPL::Utils::Path const &pluginPath,
                      const PluginInstallerStruct &installerStruct);
 
     WrtDB::DbPluginHandle getNewPluginHandle() const
@@ -56,7 +57,7 @@ class JobPluginInstall :
     }
     std::string getFilePath() const
     {
-        return m_context.pluginFilePath;
+        return m_context.pluginFilePath.Fullpath();
     }
     bool isReadyToInstall() const
     {
index 65333ba..861dbc2 100644 (file)
@@ -87,16 +87,9 @@ void PluginInstallTask::stepCheckPluginPath()
 {
     LogInfo("Plugin installation: step CheckPluginPath");
 
-    struct stat tmp;
-
-    if (-1 == stat(m_context->pluginFilePath.c_str(), &tmp)) {
+    if(!m_context->pluginFilePath.Exists()){
         ThrowMsg(Exceptions::PluginPathFailed,
-                 "Stat function failed");
-    }
-
-    if (!S_ISDIR(tmp.st_mode)) {
-        ThrowMsg(Exceptions::PluginPathFailed,
-                 "Invalid Directory");
+                 "No such path");
     }
 
     SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified");
@@ -106,17 +99,15 @@ void PluginInstallTask::stepParseConfigFile()
 {
     LogInfo("Plugin installation: step parse config file");
 
-    struct stat tmp;
-
-    std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
-        std::string(GlobalConfig::GetPluginMetafileName());
+    DPL::Utils::Path filename = m_context->pluginFilePath;
+    filename /= GlobalConfig::GetPluginMetafileName();
 
-    if (-1 == stat(filename.c_str(), &tmp)) {
+    if(!filename.Exists()){
         m_dataFromConfigXML = false;
         return;
     }
 
-    LogInfo("Plugin Config file::" << filename);
+    LogInfo("Plugin Config file::" << filename.Filename());
 
     Try
     {
@@ -136,7 +127,7 @@ void PluginInstallTask::stepParseConfigFile()
     }
     Catch(ValidationCore::ParserSchemaException::Base)
     {
-        LogError("Error during file processing " << filename);
+        LogError("Error during file processing " << filename.Filename());
         ThrowMsg(Exceptions::PluginMetafileFailed,
                  "Metafile error");
     }
@@ -148,8 +139,8 @@ void PluginInstallTask::stepFindPluginLibrary()
         return;
     }
     LogDebug("Plugin installation: step find plugin library");
-    std::string pluginPath = m_context->pluginFilePath;
-    size_t indexpos = pluginPath.find_last_of('/');
+    DPL::Utils::Path pluginPath = m_context->pluginFilePath;
+    size_t indexpos = pluginPath.Fullpath().find_last_of('/');
 
     if (std::string::npos == indexpos) {
         indexpos = 0;
@@ -157,7 +148,7 @@ void PluginInstallTask::stepFindPluginLibrary()
         indexpos += 1;  // move after '/'
     }
 
-    std::string libName = pluginPath.substr(indexpos);
+    std::string libName = pluginPath.Fullpath().substr(indexpos);
     libName = GlobalConfig::GetPluginPrefix() + libName +
         GlobalConfig::GetPluginSuffix();
     LogDebug("Plugin .so: " << libName);
@@ -180,16 +171,16 @@ void PluginInstallTask::stepLoadPluginLibrary()
 
     DISABLE_IF_PLUGIN_WITHOUT_LIB()
 
-    std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
-        m_pluginInfo.m_libraryName;
+    DPL::Utils::Path filename = m_context->pluginFilePath;
+    filename /= m_pluginInfo.m_libraryName;
 
-    LogDebug("Loading plugin: " << filename);
+    LogDebug("Loading plugin: " << filename.Filename());
 
-    void *dlHandle = dlopen(filename.c_str(), RTLD_LAZY);
+    void *dlHandle = dlopen(filename.Fullpath().c_str(), RTLD_LAZY);
     if (dlHandle == NULL) {
         const char* error = (const char*)dlerror();
         LogError(
-            "Failed to load plugin: " << filename <<
+            "Failed to load plugin: " << filename.Filename() <<
             ". Reason: " << (error != NULL ? error : "unknown"));
         ThrowMsg(Exceptions::PluginLibraryError, "Library error");
     }
@@ -211,7 +202,7 @@ void PluginInstallTask::stepLoadPluginLibrary()
 
     if (rawEntityList == NULL) {
         dlclose(dlHandle);
-        LogError("Failed to read class name" << filename);
+        LogError("Failed to read class name" << filename.Filename());
         ThrowMsg(Exceptions::PluginLibraryError, "Library error");
     }
 
@@ -222,7 +213,7 @@ void PluginInstallTask::stepLoadPluginLibrary()
 
         if (NULL == onWidgetInitProc) {
             dlclose(dlHandle);
-            LogError("Failed to read onWidgetInit symbol" << filename);
+            LogError("Failed to read onWidgetInit symbol" << filename.Filename());
             ThrowMsg(Exceptions::PluginLibraryError, "Library error");
         }
 
@@ -274,7 +265,7 @@ void PluginInstallTask::stepLoadPluginLibrary()
     const js_entity_definition_t *rawEntityListIterator = rawEntityList;
 
     LogInfo("#####");
-    LogInfo("##### Plugin: " << filename << " supports new plugin API");
+    LogInfo("##### Plugin: " << filename.Filename() << " supports new plugin API");
     LogInfo("#####");
 
     while (rawEntityListIterator->parent_name != NULL &&
@@ -308,7 +299,7 @@ void PluginInstallTask::stepRegisterPlugin()
     LogInfo("Plugin installation: step register Plugin");
 
     m_pluginHandle =
-        PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath);
+        PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath.Fullpath());
 
     SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered");
 }
index 026074a..fbf2db5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <string>
 #include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <dpl/utils/path.h>
 //#include <plugin_model.h>
 
 using namespace WrtDB;
@@ -50,7 +51,7 @@ struct PluginInstallerContext
         PLUGIN_INSTALL_END
     };
 
-    std::string pluginFilePath;           ///< plugin directory
+    DPL::Utils::Path pluginFilePath;           ///< plugin directory
     WrtDB::DbPluginHandle pluginHandle;
     // if this value is true the plugin model may be created
     // if not plugin installation has failed from some reason
index b0c88f0..6a7734f 100644 (file)
@@ -24,6 +24,7 @@
 #define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_METAFILE_READER_H_
 
 #include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/utils/path.h>
 #include <vcore/ParserSchema.h>
 
 class PluginMetafileReader
@@ -31,9 +32,9 @@ class PluginMetafileReader
   public:
     PluginMetafileReader();
 
-    void initialize(const std::string &filename)
+    void initialize(const DPL::Utils::Path &filename)
     {
-        m_parserSchema.initialize(filename,
+        m_parserSchema.initialize(filename.Fullpath(),
                                   true,
                                   ValidationCore::SaxReader::VALIDATION_DTD,
                                   std::string());
index 678ec1d..a43b24c 100644 (file)
@@ -71,6 +71,8 @@ bool DirectoryCopy(std::string source, std::string dest)
             outfile << infile.rdbuf();
             outfile.close();
             infile.close();
+
+            chown(destFile.c_str(), statInfo.st_uid, statInfo.st_gid);
         }
     } while (dEntryResult != NULL && return_code == 0);
     closedir(dir);
index c10e6e8..9757223 100644 (file)
@@ -38,6 +38,7 @@
 #include <dpl/sstream.h>
 #include <dpl/file_input.h>
 #include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
 #include <dpl/wrt-dao-ro/common_dao_types.h>
 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
 #include <dpl/wrt-dao-ro/global_config.h>
@@ -82,6 +83,7 @@ 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,}$";
@@ -224,9 +226,8 @@ JobWidgetInstall::JobWidgetInstall(
             AddTask(new TaskEncryptResource(m_installerContext));
         }
 
-        if (m_installerContext.widgetConfig.packagingType !=
-            WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
-        {
+        if (m_installerContext.mode.extension !=
+                InstallMode::ExtensionType::DIR) {
             AddTask(new TaskUpdateFiles(m_installerContext));
             AddTask(new TaskFileManipulation(m_installerContext));
         }
@@ -436,7 +437,8 @@ void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
                        widgetPath, tempPath,
                        m_installerContext.widgetConfig.packagingType,
                        m_installerContext.mode.rootPath ==
-                           InstallMode::RootPath::RO);
+                           InstallMode::RootPath::RO,
+                           m_installerContext.mode.extension);
     m_installerContext.locations->registerAppid(
         DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
 
@@ -627,7 +629,6 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
     // Parse config
     ParserRunner parser;
     ConfigParserData configInfo;
-
     Try
     {
         if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
@@ -636,35 +637,24 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
                              new RootParser<WidgetParser>(configInfo,
                                                           DPL::FromUTF32String(
                                                               L"widget"))));
-        } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
-            std::string configPath;
-            configPath = tempPath;
-            configPath += "/";
-            configPath += WITH_OSP_XML;
+        } else {
+            std::string configFile;
+            configFile = tempPath + "/" + CONFIG_XML;
+            if (!WrtUtilFileExists(configFile)) {
+                configFile = tempPath + "/" + WITH_OSP_XML;
+            }
 
             if (isReinstall) {
                 // checking RDS data directory
-                if (access(configPath.c_str(), F_OK) != 0) {
+                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)));
-                    configPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
-                    configPath += "/";
-                    configPath += WITH_OSP_XML;
+                    configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+                    configFile += "/";
+                    configFile += WITH_OSP_XML;
                 }
             }
-            parser.Parse(configPath,
-                         ElementParserPtr(
-                             new RootParser<WidgetParser>(
-                                 configInfo,
-                                 DPL::FromUTF32String(L"widget"))));
-        } else {
-            std::string configFile;
-            if (pkgType == PKG_TYPE_HYBRID_WEB_APP) {
-                configFile = tempPath + "/" + WITH_OSP_XML;
-            } else {
-                configFile = tempPath + "/" + CONFIG_XML;
-            }
 
             parser.Parse(configFile,
                     ElementParserPtr(
@@ -684,6 +674,10 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
         LogError("Failed to find installed widget - give proper tizenId");
         return ConfigParserData();
     }
+    Catch(Exceptions::WidgetConfigFileNotFound){
+        LogError("Failed to find config.xml");
+        return ConfigParserData();
+    }
 
     return configInfo;
 }
@@ -883,27 +877,17 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType(
     const std::string &widgetSource,
     const std::string &tempPath)
 {
-    // Check installation type (direcotory/ or config.xml or widget.wgt)
-    if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) {
-        LogDebug("Install directly from directory");
-        return PKG_TYPE_DIRECTORY_WEB_APP;
-    }
     if (hasExtension(widgetSource, XML_EXTENSION)) {
         LogInfo("Hosted app installation");
         return PKG_TYPE_HOSTED_WEB_APP;
     }
 
-    std::string configFile = tempPath + "/" + CONFIG_XML;
-    if (WrtUtilFileExists(configFile)) {
-        return PKG_TYPE_NOMAL_WEB_APP;
-    }
-
-    configFile = tempPath + "/" + WITH_OSP_XML;
+    std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
     if (WrtUtilFileExists(configFile)) {
         return PKG_TYPE_HYBRID_WEB_APP;
     }
 
-    return PKG_TYPE_UNKNOWN;
+    return PKG_TYPE_NOMAL_WEB_APP;
 }
 
 void JobWidgetInstall::setApplicationType(
old mode 100755 (executable)
new mode 100644 (file)
index 9688ee2..7a8bea6
@@ -407,14 +407,20 @@ void LiveBox::serialize(xmlTextWriterPtr writer)
         writeAttribute(writer, "mouse_event", this->box.boxMouseEvent);
         writeAttribute(writer, "touch_effect", this->box.boxTouchEffect);
 
-        FOREACH(m, this->box.boxSize)
+        FOREACH(it, this->box.boxSize)
         {
-            std::pair<DPL::String, DPL::String> boxSize = *m;
             startElement(writer, "size");
-            if (!boxSize.second.empty()) {
-                writeAttribute(writer, "preview", boxSize.second);
+            if (!(*it).m_preview.empty()) {
+                writeAttribute(writer, "preview", (*it).m_preview);
             }
-            writeText(writer, boxSize.first);
+            if (!(*it).m_useDecoration.empty()) {
+                writeAttribute(writer, "need_frame", (*it).m_useDecoration);
+            } else {
+                // default value of use-decoration is "true"
+                writeAttribute(writer, "need_frame", DPL::String(L"true"));
+            }
+
+            writeText(writer, (*it).m_size);
             endElement(writer);
         }
 
@@ -498,8 +504,10 @@ void Privilege::serialize(xmlTextWriterPtr writer)
 void Metadata::serialize(xmlTextWriterPtr writer)
 {
     startElement(writer, "metadata");
-    writeAttribute(writer, "key", this->key);
-    writeAttribute(writer, "value", this->value);
+    writeAttribute(writer, "key", *this->key);
+    if (!this->value.IsNull()) {
+        writeAttribute(writer, "value", *this->value);
+    }
     endElement(writer);
 }
 } //namespace Jobs
old mode 100755 (executable)
new mode 100644 (file)
index 30a849d..1729716
@@ -29,6 +29,7 @@
 #include <dpl/string.h>
 #include <dpl/optional_typedefs.h>
 #include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
 
 namespace Jobs {
 namespace WidgetInstall {
@@ -77,7 +78,7 @@ typedef DPL::String NcnameType, NmtokenType, AnySimpleType, LangType;
 typedef DPL::String OperationType, MimeType, UriType, TypeType, PackageType;
 typedef DPL::OptionalString InstallLocationType, CategoriesType;
 typedef DPL::String AppCategoryType;
-typedef DPL::String KeyType, ValueType;
+typedef DPL::OptionalString KeyType, ValueType;
 
 /**
  * xmllib2 wrappers
@@ -405,15 +406,15 @@ typedef UiApplication UiApplicationType;
 /**
  * @brief LiveBox element
  */
-typedef std::list<std::pair<DPL::String, DPL::String> > boxSizeType;
-typedef std::list<std::pair<DPL::String, DPL::String> > boxLabelType;
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxSizeList BoxSizeType;
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxLabelList BoxLabelType;
 
 struct BoxInfo
 {
     NcnameType boxSrc;
     NcnameType boxMouseEvent;
     NcnameType boxTouchEffect;
-    boxSizeType boxSize;
+    BoxSizeType boxSize;
     NcnameType pdSrc;
     NcnameType pdWidth;
     NcnameType pdHeight;
@@ -436,7 +437,7 @@ class LiveBox
     {
         this->updatePeriod = x;
     }
-    void setLabel(const boxLabelType &x)
+    void setLabel(const BoxLabelType &x)
     {
         this->label = x;
     }
@@ -457,7 +458,7 @@ class LiveBox
     NcnameType autoLaunch;
     NcnameType updatePeriod;
     NcnameType timeout;
-    boxLabelType label;
+    BoxLabelType label;
     NcnameType icon;
     NcnameType lang;
     BoxInfoType box;
index 68189ac..6223426 100644 (file)
@@ -23,6 +23,7 @@
 //SYSTEM INCLUDES
 #include <cstring>
 #include <string>
+#include <sstream>
 #include <dpl/assert.h>
 #include <appcore-common.h> //TODO is it necessary here?
 #include <pcrecpp.h>
@@ -196,25 +197,38 @@ void TaskCertify::processAuthorSignature(const SignatureData &data)
     }
 }
 
+void TaskCertify::getSignatureFiles(std::string path, SignatureFileInfoSet& file)
+{
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(path);
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
+        LogError("Error in Signature Finder : " << path);
+        ThrowMsg(Exceptions::SignatureNotFound,
+                "Error openig temporary widget directory");
+    }
+}
+
 void TaskCertify::stepSignature()
 {
     LogInfo("================ Step: <<Signature>> ENTER ===============");
 
     std::string widgetPath;
-    if (m_contextData.widgetConfig.packagingType ==
-        WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
-    {
-        widgetPath = m_contextData.locations->getSourceDir() + "/";
-    } else {
-        widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
-    }
+    widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/";
 
     SignatureFileInfoSet signatureFiles;
-    SignatureFinder signatureFinder(widgetPath);
-    if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
-        LogError("Error in Signature Finder");
-        ThrowMsg(Exceptions::SignatureNotFound,
-                 "Error openig temporary widget directory");
+
+    Try {
+        getSignatureFiles(widgetPath, signatureFiles);
+
+        if (signatureFiles.size() <= 0) {
+            widgetPath = m_contextData.locations->getTemporaryPackageDir() +
+                WrtDB::GlobalConfig::GetWidgetSrcPath() + "/";
+            if (0 == access(widgetPath.c_str(), F_OK)) {
+                getSignatureFiles(widgetPath, signatureFiles);
+            }
+        }
+    } Catch(Exceptions::SignatureNotFound) {
+        ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
     }
 
     SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
index 6c42853..955b8ff 100644 (file)
@@ -25,6 +25,7 @@
 //SYSTEM INCLUDES
 #include <string>
 #include <libxml/c14n.h>
+#include <vcore/SignatureFinder.h>
 
 //WRT INCLUDES
 #include <dpl/task.h>
@@ -54,6 +55,8 @@ class TaskCertify :
 
     void processDistributorSignature(const ValidationCore::SignatureData &data);
     void processAuthorSignature(const ValidationCore::SignatureData &data);
+    void getSignatureFiles(std::string path,
+            ValidationCore::SignatureFileInfoSet& file);
 
     bool isTizenWebApp() const;
 };
index fa229cd..181e85e 100644 (file)
@@ -150,8 +150,7 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
             m_context.locationType)
     {
         AddStep(&TaskFileManipulation::StepCreateDirs);
-        if (m_context.widgetConfig.packagingType !=
-            WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
+        if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
         {
             AddStep(&TaskFileManipulation::StepRenamePath);
             AddAbortStep(&TaskFileManipulation::StepAbortRenamePath);
@@ -206,17 +205,17 @@ void TaskFileManipulation::StepCreatePrivateStorageDir()
     LogDebug("Create private storage directory : " <<
             m_context.locations->getPrivateStorageDir());
 
+    changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE);
+
     if (m_context.isUpdateMode) { //update
         std::string backData = m_context.locations->getBackupPrivateDir();
         LogDebug("copy private storage " << backData << " to " << storagePath);
-        WrtUtilMakeDir(storagePath);
         if (!DirectoryApi::DirectoryCopy(backData, storagePath)) {
             LogError("Failed to rename " << backData << " to " << storagePath);
             ThrowMsg(Exceptions::BackupFailed,
                     "Error occurs copy private strage files");
         }
     }
-    changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE);
 
     std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir();
     LogDebug("Create temp private storage directory : " << tempStoragePath);
@@ -253,17 +252,16 @@ void TaskFileManipulation::StepRenamePath()
 void TaskFileManipulation::StepLinkForPreload()
 {
     if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
-        std::string srcDir = m_context.locations->getUserDataRootDir() +
-            WrtDB::GlobalConfig::GetWidgetSrcPath();
+        std::string optRes = m_context.locations->getUserDataRootDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
+        std::string usrRes = m_context.locations->getPackageInstallationDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
 
-        if (0 != access(srcDir.c_str(), F_OK)) {
+        if (0 != access(optRes.c_str(), F_OK)) {
             LogDebug("Make symbolic name for preaload app" <<
-                    m_context.locations->getSourceDir() << " to " << srcDir);
-            std::string resDir = m_context.locations->getUserDataRootDir() +
-                "/res";
+                    usrRes << " to " << optRes);
 
-            WrtUtilMakeDir(resDir);
-            if (symlink(m_context.locations->getSourceDir().c_str(), srcDir.c_str()) != 0)
+            if (symlink(usrRes.c_str(), optRes.c_str()) != 0)
             {
                 int error = errno;
                 if (error)
@@ -317,22 +315,18 @@ void TaskFileManipulation::StepAbortRenamePath()
 {
     LogDebug("[Rename Widget Path] Aborting.... (Rename path)");
     std::string widgetPath;
-    if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) {
-        widgetPath = m_context.locations->getPackageInstallationDir();
-        if (!WrtUtilRemove(widgetPath)) {
-            ThrowMsg(Exceptions::RemovingFolderFailure,
-                     "Error occurs during removing existing folder");
-        }
-        // Remove user data directory if preload web app.
-        std::string userData = m_context.locations->getUserDataRootDir();
-        if (0 == access(userData.c_str(), F_OK)) {
-            if (!WrtUtilRemove(userData)) {
-                ThrowMsg(Exceptions::RemovingFolderFailure,
-                         "Error occurs during removing user data directory");
-            }
+    widgetPath = m_context.locations->getPackageInstallationDir();
+    if (!WrtUtilRemove(widgetPath)) {
+        LogError("Error occurs during removing existing folder");
+    }
+    // Remove user data directory if preload web app.
+    std::string userData = m_context.locations->getUserDataRootDir();
+    if (0 == access(userData.c_str(), F_OK)) {
+        if (!WrtUtilRemove(userData)) {
+            LogError("Error occurs during removing user data directory");
         }
-
     }
+
     LogDebug("Rename widget path sucessful!");
 }
 
index 30c8101..0ef8990 100644 (file)
@@ -116,14 +116,7 @@ void TaskInstallOspsvc::StepUpdateManifestFile()
         manifest_file << ".xml";
         LogDebug("manifest file : " << manifest_file.str());
 
-        int ret = pkgmgr_parser_parse_manifest_for_uninstallation(
-                manifest_file.str().c_str(), NULL);
-
-        if (ret != 0) {
-            LogError("Manifest parser error: " << ret);
-        }
-
-        int code = pkgmgr_parser_parse_manifest_for_installation(
+        int code = pkgmgr_parser_parse_manifest_for_upgrade(
                 manifest_file.str().c_str(), NULL);
 
         if (code != 0) {
index d9cfeaa..99b34a1 100755 (executable)
@@ -36,6 +36,7 @@
 #include <web_provider_livebox_info.h>
 #include <web_provider_plugin_info.h>
 #include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
 #include <dpl/log/log.h>
 #include <dpl/file_input.h>
 #include <dpl/errno_string.h>
@@ -315,9 +316,10 @@ void TaskManifestFile::stepCopyLiveboxFiles()
     std::ostringstream targetFile;
 
     FOREACH (boxIt, liveBoxList) {
-        boxSizeType boxSizeList = (**boxIt).m_boxInfo.m_boxSize;
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**boxIt).m_boxInfo.m_boxSize;
         FOREACH (sizeIt, boxSizeList) {
-            std::string preview = DPL::ToUTF8String((*sizeIt).second);
+            std::string preview = DPL::ToUTF8String((*sizeIt).m_preview);
             if (preview.empty()) {
                 continue;
             }
@@ -326,7 +328,7 @@ void TaskManifestFile::stepCopyLiveboxFiles()
             sourceFile << preview;
             targetFile << m_context.locations->getSharedDataDir() << "/";
             targetFile << (**boxIt).m_liveboxId << ".";
-            targetFile << DPL::ToUTF8String((*sizeIt).first) << ".preview.png";
+            targetFile << DPL::ToUTF8String((*sizeIt).m_size) << ".preview.png";
 
             DPL::FileInput input(sourceFile.str());
             DPL::FileOutput output(targetFile.str());
@@ -585,7 +587,6 @@ void TaskManifestFile::stepGenerateManifest()
 void TaskManifestFile::stepParseManifest()
 {
     int code = 0;
-
     char* updateTags[3] = {NULL, };
 
     if (!m_context.mode.removable) {
@@ -595,20 +596,14 @@ void TaskManifestFile::stepParseManifest()
 
     }
 
-    if (!access(commit_manifest.c_str(), F_OK) == 0) {
-        commitManifest();
-        code = pkgmgr_parser_parse_manifest_for_installation(
-                commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
+    commitManifest();
 
-        if (code != 0) {
-            LogError("Manifest parser error: " << code);
-            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
-        }
-    } else {
-        if (m_context.widgetConfig.packagingType !=
-                PKG_TYPE_HYBRID_WEB_APP)
-        {
-            commitManifest();
+    if (m_context.isUpdateMode || (
+                m_context.mode.rootPath == InstallMode::RootPath::RO
+                && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+
+        if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) {
             code = pkgmgr_parser_parse_manifest_for_upgrade(
                     commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
 
@@ -616,7 +611,14 @@ void TaskManifestFile::stepParseManifest()
                 LogError("Manifest parser error: " << code);
                 ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
             }
+        }
+    } else {
+        code = pkgmgr_parser_parse_manifest_for_installation(
+                commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
 
+        if (code != 0) {
+            LogError("Manifest parser error: " << code);
+            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
         }
     }
 
@@ -1149,18 +1151,17 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
                 box.boxTouchEffect= L"false";
             }
 
-            std::list<std::pair<DPL::String, DPL::String> > BoxSizeList
-                = ConfigInfo->m_boxInfo.m_boxSize;
-            FOREACH(im, BoxSizeList) {
-                std::pair<DPL::String, DPL::String> boxSize = *im;
-                if (!boxSize.second.empty()) {
-                    boxSize.second =
+            ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+                ConfigInfo->m_boxInfo.m_boxSize;
+            FOREACH(it, boxSizeList) {
+                if (!(*it).m_preview.empty()) {
+                    (*it).m_preview =
                         DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
                         DPL::String(L"/") +
                         ConfigInfo->m_liveboxId + DPL::String(L".") +
-                        boxSize.first + DPL::String(L".preview.png");
+                        (*it).m_size + DPL::String(L".preview.png");
                 }
-                box.boxSize.push_back(boxSize);
+                box.boxSize.push_back((*it));
             }
 
             if (!ConfigInfo->m_boxInfo.m_pdSrc.empty()
index 47e9cf4..e4cc1f0 100644 (file)
@@ -42,8 +42,7 @@ TaskRemoveBackupFiles::TaskRemoveBackupFiles(InstallerContext& context) :
     DPL::TaskDecl<TaskRemoveBackupFiles>(this),
     m_context(context)
 {
-    if (m_context.widgetConfig.packagingType !=
-            WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
     {
         AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles);
     }
index f77a8b7..00c5fa0 100755 (executable)
@@ -34,6 +34,7 @@
 #include <dpl/utils/wrt_global_settings.h>
 #include <dpl/utils/wrt_utility.h>
 #include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
 #include <dpl/wrt-dao-rw/feature_dao.h>
 
 #include <libiriwrapper.h>
@@ -122,8 +123,6 @@ void TaskWidgetConfig::ReadLocaleFolders()
         return;
     }
 
-
-
     struct stat statStruct;
     struct dirent dirent;
     struct dirent *result;
@@ -537,13 +536,14 @@ void TaskWidgetConfig::StepVerifyLivebox()
 
         LogInfo("livebox type: " << boxType);
 
-        boxSizeType boxSizeList = (**it).m_boxInfo.m_boxSize;
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**it).m_boxInfo.m_boxSize;
         char** boxSize = static_cast<char**>(
             malloc(sizeof(char*)* boxSizeList.size()));
 
         int boxSizeCnt = 0;
         FOREACH (m, boxSizeList) {
-            boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).first).c_str());
+            boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str());
         }
 
         bool chkSize = web_provider_plugin_check_supported_size(
index bcf29e8..e78cdba 100644 (file)
@@ -34,6 +34,8 @@
 using namespace WrtDB;
 
 namespace {
+const char* const NPRUNTIME_PLUGINS_DIR = "plugins/";
+
 struct PathAndFilePair
 {
     std::string path;
@@ -60,6 +62,34 @@ PathAndFilePair SplitFileAndPath(const std::string &filePath)
                                            position),
                            filePath.substr(position + 1));
 }
+
+inline bool isNPPlugin(const std::string& filePath)
+{
+    std::string::size_type pos = filePath.find(NPRUNTIME_PLUGINS_DIR);
+    // Not specified if a plug-in name MUST end with a specific extension
+    // (e.g. .so)
+    return ((std::string::npos != pos) &&
+            ('/' != filePath[filePath.length() - 1]));
+}
+
+// precondition: isNPPlugin(filePath) == true
+inline bool isValidNPPlugin(const std::string& filePath)
+{
+    return (filePath.find(GlobalConfig::GetNPRuntimePluginsPath()) == 0);
+}
+
+bool shouldBeInstalled(const std::string& filePath)
+{
+    if (isNPPlugin(filePath))
+    {
+        if (!isValidNPPlugin(filePath))
+        {
+            LogDebug("Not a valid NPRuntime plug-in: " << filePath);
+            return false;
+        }
+    }
+    return true;
+}
 }
 
 namespace Jobs {
@@ -98,44 +128,51 @@ void WidgetUnzip::unzipProgress(const std::string &destination)
     // Extract file or path
     std::string fileName = m_zipIterator->name;
 
-    if (fileName[fileName.size() - 1] == '/') {
-        // This is path
-        std::string newPath = destination + "/" +
-            fileName.substr(0, fileName.size() - 1);
-        LogPedantic("Path to extract: " << newPath);
-
-        // Create path in case of it is empty
-        createTempPath(newPath);
-    } else {
-        // This is regular file
-        std::string fileExtractPath = destination + "/" + fileName;
-
-        LogPedantic("File to extract: " << fileExtractPath);
-
-        // Split into pat & file pair
-        PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath);
-
-        LogPedantic("Path and file: " <<
-                    pathAndFile.path <<
-                    " : " << pathAndFile.file);
-
-        // First, ensure that path exists
-        createTempPath(pathAndFile.path);
-
-        Try
-        {
-            // Open file
-            std::unique_ptr<DPL::ZipInput::File> file(
-                m_zip->OpenFile(fileName));
-
-            // Extract single file
-            ExtractFile(file.get(), fileExtractPath);
-        }
-        Catch(DPL::ZipInput::Exception::OpenFileFailed)
-        {
-            ThrowMsg(Exceptions::ExtractFileFailed, fileName);
+    if (shouldBeInstalled(m_zipIterator->name))
+    {
+        if (fileName[fileName.size() - 1] == '/') {
+            // This is path
+            std::string newPath = destination + "/" +
+                fileName.substr(0, fileName.size() - 1);
+            LogPedantic("Path to extract: " << newPath);
+
+            // Create path in case of it is empty
+            createTempPath(newPath);
+        } else {
+            // This is regular file
+            std::string fileExtractPath = destination + "/" + fileName;
+
+            LogPedantic("File to extract: " << fileExtractPath);
+
+            // Split into pat & file pair
+            PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath);
+
+            LogPedantic("Path and file: " <<
+                        pathAndFile.path <<
+                        " : " << pathAndFile.file);
+
+            // First, ensure that path exists
+            createTempPath(pathAndFile.path);
+
+            Try
+            {
+                // Open file
+                std::unique_ptr<DPL::ZipInput::File> file(
+                    m_zip->OpenFile(fileName));
+
+                // Extract single file
+                ExtractFile(file.get(), fileExtractPath);
+            }
+            Catch(DPL::ZipInput::Exception::OpenFileFailed)
+            {
+                ThrowMsg(Exceptions::ExtractFileFailed, fileName);
+            }
         }
     }
+    else
+    {
+        LogDebug("Skipping file: " << m_zipIterator->name);
+    }
 
     // Check whether there are more files to extract
     if (++m_zipIterator == m_zip->end()) {
index 986ee29..70c6340 100644 (file)
 #include <dpl/wrt-dao-ro/global_config.h>
 #include <pkg-manager/pkgmgr_signal.h>
 #include <app2ext_interface.h>
+#include <dpl/utils/path.h>
 
 using namespace WrtDB;
 
 namespace { //anonymous
 const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
 const int PKGID_LENTH = 10;
-const std::string PRELOAD_INSTALLED_PATH = "/usr/apps";
+const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps");
 
 bool checkDirectoryExist(const std::string& pkgId)
 {
-    std::string installPath =
-        std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
-        "/" + pkgId;
-
-    struct stat dirStat;
-    if ((stat(installPath.c_str(), &dirStat) == 0)) {
-        return true;
-    }
-    return false;
+    DPL::Utils::Path installPath(GlobalConfig::GetUserInstalledWidgetPath());
+    installPath /= pkgId;
+    return installPath.Exists();
 }
 }
 
@@ -106,7 +101,7 @@ JobWidgetUninstall::JobWidgetUninstall(
             m_context.locations = WidgetLocation(m_context.tzPkgid);
             m_context.locations->registerAppid(m_context.tzAppid);
             m_context.installedPath =
-                DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+                DPL::Utils::Path(*dao.getWidgetInstalledPath());
 
             LogInfo("Widget model exists. App id : " << m_context.tzAppid);
 
@@ -150,7 +145,7 @@ WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
         LogDebug("Regcomp failed");
     }
     std::string pkgId;
-    std::string installPath;
+    DPL::Utils::Path installPath;
 
     Try {
         if ((regexec(&regx, id.c_str(),
@@ -163,16 +158,14 @@ WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
             LogDebug("Get appid from pkgid : " << appid);
             m_context.tzAppid = DPL::ToUTF8String(appid);
             WrtDB::WidgetDAOReadOnly dao(appid);
-            installPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+            installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath());
         } else {
             pkgId = id.substr(0, PKGID_LENTH);
             WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id));
             m_context.tzAppid = id;
-            installPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+            installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath());
         }
-
-        if (0 == installPath.compare(0, PRELOAD_INSTALLED_PATH.length(),
-                    PRELOAD_INSTALLED_PATH)) {
+        if(installPath.isSubPath(PRELOAD_INSTALLED_PATH)){
             LogDebug("This widget is prealoded.");
         }
     } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
old mode 100755 (executable)
new mode 100644 (file)
index 7404a74..4a5122f
@@ -30,6 +30,7 @@
 #include <dpl/assert.h>
 #include <dpl/exception.h>
 #include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
 #include <ail.h>
 #include <pkgmgr/pkgmgr_parser.h>
 #include <errno.h>
@@ -62,13 +63,18 @@ void TaskRemoveFiles::StepRemoveInstallationDirectory()
         {
             LogDebug("Removing directory");
             m_context.removeStarted = true;
-            if (!WrtUtilRemove(m_context.installedPath)) {
+            DPL::Utils::Path widgetDir= m_context.installedPath;
+            Try{
+                DPL::Utils::Remove(widgetDir);
+            } Catch(DPL::Utils::Path::BaseException){
                 LogError("Removing widget installation directory failed : " <<
-                        m_context.installedPath);
+                        widgetDir.Fullpath());
             }
-            std::string dataDir = m_context.locations->getUserDataRootDir();
-            if (!WrtUtilRemove(dataDir)) {
-                LogWarning(dataDir + " is already removed");
+            DPL::Utils::Path dataDir(m_context.locations->getUserDataRootDir());
+            Try{
+                DPL::Utils::Remove(dataDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                LogWarning(dataDir.Fullpath() << " is already removed");
             }
         } else {
             LogDebug("Removing sdcard directory");
@@ -105,32 +111,33 @@ void TaskRemoveFiles::StepRemoveManifest()
 {
     std::ostringstream manifest_name;
     manifest_name << m_context.tzPkgid << ".xml";
-    std::ostringstream destFile;
-    const std::string PRELOAD_INSTALLED_PATH = "/usr/apps";
-    if (0 == (m_context.installedPath).compare(0, PRELOAD_INSTALLED_PATH.length(),
-                PRELOAD_INSTALLED_PATH)) {
-        LogDebug("This widget is prealoded.");
-        destFile << "/usr/share/packages" << "/"; //TODO constant with path
+    DPL::Utils::Path destFile;
+    const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps");
+    const DPL::Utils::Path USR_PACKAGES_PATH("/usr/share/packages");
+    const DPL::Utils::Path OPT_PACKAGES_PATH("/opt/share/packages");
+    if (0 == (m_context.installedPath.Fullpath()).compare(0,
+            PRELOAD_INSTALLED_PATH.Fullpath().length(),
+            PRELOAD_INSTALLED_PATH.Fullpath())) {
+        LogDebug("This widget is preloaded.");
+        destFile = USR_PACKAGES_PATH;
     } else {
-        destFile << "/opt/share/packages" << "/"; //TODO constant with path
+        destFile = OPT_PACKAGES_PATH;
     }
-    destFile << manifest_name.str();
-    std::string pre_manifest = "/usr/share/packages/" + manifest_name.str();
+    destFile /= manifest_name.str();
+    DPL::Utils::Path pre_manifest = USR_PACKAGES_PATH;
+    pre_manifest /= manifest_name.str();
 
-    if (!(access(destFile.str().c_str(), F_OK) == 0 &&
-            access(pre_manifest.c_str(), F_OK) == 0)) {
+    if (!(destFile.Exists() == 0 && pre_manifest.Exists())) {
         int ret1 = pkgmgr_parser_parse_manifest_for_uninstallation(
-                destFile.str().c_str(), NULL);
+                destFile.Fullpath().c_str(), NULL);
         if (ret1 != 0) {
             LogWarning("Manifest file failed to parse for uninstallation");
         }
     }
-
-    int ret2 = unlink(destFile.str().c_str());
-    if (ret2 != 0) {
-        LogWarning("No manifest file found: " << destFile.str());
+    if (!DPL::Utils::TryRemove(destFile)) {
+        LogWarning("No manifest file found: " << destFile.Fullpath());
     } else {
-        LogDebug("Manifest file removed: " << destFile.str());
+        LogDebug("Manifest file removed: " << destFile.Fullpath());
     }
 }
 
@@ -140,25 +147,28 @@ void TaskRemoveFiles::StepRemoveExternalLocations()
         WidgetDAO dao(DPL::FromUTF8String(m_context.tzAppid));
         LogDebug("Removing external locations:");
         WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
-        FOREACH(path, externalPaths)
+        FOREACH(file, externalPaths)
         {
-            if (WrtUtilFileExists(*path)) {
-                LogDebug("  -> " << *path);
-                int ret = remove(path->c_str());
-                if (ret != 0) {
-                    LogError(
-                            "Failed to remove the file: " << path->c_str() <<
-                            " with error: " << strerror(errno));
-                }
-            } else if (WrtUtilDirExists(*path)) {
-                LogDebug("  -> " << *path);
-                if (!WrtUtilRemove(*path)) {
-                    Throw(
-                            Jobs::WidgetUninstall::TaskRemoveFiles::Exception::
-                            RemoveFilesFailed);
+            DPL::Utils::Path path(*file);
+            if(path.Exists()){
+                if(path.IsFile()){
+                    LogDebug("  -> " << path.Fullpath());
+                    Try{
+                        DPL::Utils::Remove(path);
+                    }Catch(DPL::Utils::Path::BaseException){
+                        LogError("Failed to remove the file: " << path.Fullpath());
+                    }
+                } else if (path.IsDir()){
+                    LogDebug("  -> " << path.Fullpath());
+                    Try{
+                        DPL::Utils::Remove(path);
+                    }Catch(DPL::Utils::Path::BaseException){
+                        Throw(Jobs::WidgetUninstall::TaskRemoveFiles::
+                                Exception::RemoveFilesFailed);
+                    }
                 }
-            } else {
-                LogWarning("  -> " << *path << "(no such a path)");
+            }else{
+                LogWarning("  -> " << path.Fullpath() << "(no such a path)");
             }
         }
         dao.unregisterAllExternalLocations();
index 3d9fe28..25c25e3 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include <widget_uninstall/widget_uninstaller_struct.h>
 #include <widget_location.h>
+#include <dpl/utils/path.h>
 
 namespace Jobs {
 namespace WidgetUninstall {
@@ -62,7 +63,7 @@ struct UninstallerContext
     std::string tzAppid;
     std::string tzPkgid;
     bool removeAbnormal;
-    std::string installedPath;
+    DPL::Utils::Path installedPath;
 };
 
 #endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_
index 10cda89..6b3f06c 100644 (file)
@@ -29,12 +29,12 @@ using namespace WrtDB;
 
 namespace Logic {
 InstallerLogic::InstallerLogic() :
-    m_NextHandle(0)
+    m_NextHandle(0),m_job(0)
 {}
 
 InstallerLogic::~InstallerLogic()
 {
-    Assert(m_jobs.empty() && "There are still running jobs");
+        Assert(!m_job && "There are still running job");
     //FIXME what should be done here?
 }
 
@@ -46,24 +46,19 @@ void InstallerLogic::Initialize()
 void InstallerLogic::Terminate()
 {
     //TODO how to delete, if it is still running, paused and so on
-    FOREACH(it, m_jobs)
-    {
-        it->second->SetPaused(true); //FIXME this is not enough!
-    }
+    if(m_job)
+        m_job->SetPaused(true);
 
     LogDebug("Done");
 }
 
-Jobs::JobHandle InstallerLogic::AddAndStartJob(Jobs::Job *job)
+Jobs::JobHandle InstallerLogic::AddAndStartJob()
 {
     Jobs::JobHandle handle = GetNewJobHandle();
-    job->SetJobHandle(handle);
-
-    m_jobs.insert(std::make_pair(handle, job));
-
+    m_job->SetJobHandle(handle);
     //Start job
     CONTROLLER_POST_EVENT(InstallerController,
-                          InstallerControllerEvents::NextStepEvent(job));
+                          InstallerControllerEvents::NextStepEvent(m_job));
 
     return handle;
 }
@@ -75,12 +70,19 @@ Jobs::JobHandle InstallerLogic::InstallWidget(
     const WidgetInstallationStruct &
     installerStruct)
 {
+    if(m_job)
+    {
+        LogError("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
     LogDebug("New Widget Installation:");
 
-    Jobs::Job *job =
+    m_job =
         new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, installerStruct);
 
-    return AddAndStartJob(job);
+
+    return AddAndStartJob();
 }
 
 Jobs::JobHandle InstallerLogic::UninstallWidget(
@@ -88,13 +90,19 @@ Jobs::JobHandle InstallerLogic::UninstallWidget(
     const
     WidgetUninstallationStruct &uninstallerStruct)
 {
+    if(m_job)
+    {
+        LogError("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
     LogDebug("New Widget Uninstallation");
 
-    Jobs::Job *job =
+    m_job  =
         new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
                                                       uninstallerStruct);
 
-    return AddAndStartJob(job);
+      return AddAndStartJob();
 }
 
 Jobs::JobHandle InstallerLogic::InstallPlugin(
@@ -102,14 +110,23 @@ Jobs::JobHandle InstallerLogic::InstallPlugin(
     const PluginInstallerStruct &
     installerStruct)
 {
+    if(m_job)
+    {
+        LogError("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
     LogDebug("New Plugin Installation");
 
-    Jobs::Job *job =
-        new Jobs::PluginInstall::JobPluginInstall(pluginPath, installerStruct);
+    //Conversion to DPL::Utils::Path is temporary
+    m_job =
+        new Jobs::PluginInstall::JobPluginInstall(DPL::Utils::Path(pluginPath), installerStruct);
+
     // before start install plugin, reset plugin data which is stopped
     // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
     ResetProgressPlugins();
-    return AddAndStartJob(job);
+
+    return AddAndStartJob();
 }
 
 #define TRANSLATE_JOB_EXCEPTION() \
@@ -148,8 +165,8 @@ bool InstallerLogic::NextStep(Jobs::Job *job)
         }
 
         //clean job
-        m_jobs.erase(job->GetJobHandle());
         delete job;
+        m_job=0;
 
         return false;
     } catch (Jobs::JobExceptionBase &exc) {
@@ -165,8 +182,8 @@ bool InstallerLogic::NextStep(Jobs::Job *job)
             job->SendFinishedFailure();
 
             //clean job
-            m_jobs.erase(job->GetJobHandle());
             delete job;
+            m_job=0;
         }
         return hasAbortSteps;
     }
index 496e967..0d3463e 100644 (file)
@@ -27,8 +27,7 @@
 namespace Logic {
 class InstallerLogic
 {
-    typedef std::map<Jobs::JobHandle, Jobs::Job*> JobsContainer;
-    JobsContainer m_jobs;
+    Jobs::Job* m_job;
 
     void ResetProgressPlugins();
     void InstallWaitingPlugins();
@@ -39,7 +38,7 @@ class InstallerLogic
     {
         return m_NextHandle++;
     }
-    Jobs::JobHandle AddAndStartJob(Jobs::Job *job);
+    Jobs::JobHandle AddAndStartJob();
 
   public:
     virtual ~InstallerLogic();
index 4c93057..71f8b28 100644 (file)
@@ -62,12 +62,14 @@ WidgetLocation::~WidgetLocation()
 WidgetLocation::WidgetLocation(const std::string & widgetname,
                                std::string sourcePath,
                                WrtDB::PackagingType t,
-                               bool isReadonly) :
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
     m_pkgid(widgetname),
     m_widgetSource(sourcePath),
     m_type(t),
     m_temp(
-        new WidgetLocation::DirectoryDeletor(isReadonly))
+        new WidgetLocation::DirectoryDeletor(isReadonly)),
+    m_extensionType(eType)
 {
     if (isReadonly) {
         m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
@@ -84,11 +86,13 @@ WidgetLocation::WidgetLocation(const std::string & widgetname,
                                std::string sourcePath,
                                std::string dirPath,
                                WrtDB::PackagingType t,
-                               bool isReadonly) :
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
     m_pkgid(widgetname),
     m_widgetSource(sourcePath),
     m_type(t),
-    m_temp(new WidgetLocation::DirectoryDeletor(dirPath))
+    m_temp(new WidgetLocation::DirectoryDeletor(dirPath)),
+    m_extensionType(eType)
 {
     if (isReadonly) {
         m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
@@ -187,7 +191,7 @@ std::string WidgetLocation::getTemporaryPackageDir() const
 
 std::string WidgetLocation::getTemporaryRootDir() const
 {
-    if (m_type == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) {
+    if (m_extensionType == InstallMode::ExtensionType::DIR) {
         return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath();
     }
     if (m_type == WrtDB::PKG_TYPE_HYBRID_WEB_APP) {
@@ -206,8 +210,6 @@ std::string WidgetLocation::getConfigurationDir() const
             path = m_widgetSource.substr(0, index);
         }
         return path;
-    } else if (m_type == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) {
-        return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath();
     } else {
         return getTemporaryRootDir();
     }
index 2b44d4d..c3f8c39 100644 (file)
@@ -26,6 +26,7 @@
 #include <dpl/wrt-dao-ro/common_dao_types.h>
 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
 #include <wrt_common_types.h>
+#include <wrt_install_mode.h>
 
 /**
  * @brief The WidgetLocation class
@@ -101,12 +102,16 @@ class WidgetLocation
      */
     WidgetLocation(const std::string & widgetname, std::string sourcePath,
                    WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
-                   bool isReadonly = false);
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
 
     WidgetLocation(const std::string & widgetname, std::string sourcePath,
                    std::string dirPath,
                    WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
-                   bool isReadonly = false);
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
 
     ~WidgetLocation();
 
@@ -215,6 +220,7 @@ class WidgetLocation
     std::shared_ptr<DirectoryDeletor> m_temp;      //directory
     WrtDB::ExternalLocationList m_externals;
     std::string m_installedPath;
+    InstallMode::ExtensionType m_extensionType;
 };
 
 #endif // WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
index 8e67a1a..0eca7ea 100644 (file)
@@ -66,6 +66,7 @@ SET(INSTALLER_TESTS_SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/NonRootUserTests.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/NPluginsInstallTests.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/ParsingTizenAppcontrolTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/WidgetUpdateTests.cpp
 )
 
 SET(INSTALLER_TESTS_TARGET "wrt-installer-tests-general")
@@ -129,13 +130,6 @@ target_link_libraries(${INSTALLER_TESTS_TARGET}
 )
 
 #widgets
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/manifest.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-00-with_bg.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-01-missing_file.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-02-without_bg.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/nonroot.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_1.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_2.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_3.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_4.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/app-control.wgt DESTINATION /opt/share/widget/tests/installer/widgets/)
+FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/widgets/*.wgt")
+INSTALL(FILES ${files} DESTINATION /opt/share/widget/tests/installer/widgets/)
+
diff --git a/tests/general/WidgetUpdateTests.cpp b/tests/general/WidgetUpdateTests.cpp
new file mode 100644 (file)
index 0000000..064e545
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * 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    WidgetUpdateTests.cpp
+ * @author  Grzegorz Rynkowski (g.rynkowski@samsung.com)
+ * @version 1.0
+ * @brief   Test a process of updating web applications.
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <fstream>
+
+using namespace InstallerWrapper;
+
+#define RUNNER_ASSERT_MSG_SAFE(test, message)                                  \
+    {                                                                          \
+        DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();            \
+                                                                               \
+        if (!(test))                                                           \
+        {                                                                      \
+            uninstall(tizenId);                                                \
+            std::ostringstream assertMsg;                                      \
+            assertMsg << message;                                              \
+            throw DPL::Test::TestRunner::TestFailed(#test,                     \
+                                                    __FILE__,                  \
+                                                    __LINE__,                  \
+                                                    assertMsg.str());          \
+        }                                                                      \
+    }
+
+RUNNER_TEST_GROUP_INIT(WidgetUpdate)
+
+/*
+Name: validUpdateOfSigned
+Description: Tests update the web app where origin and a new one are signed.
+Expected: Widget should be successfully installed.
+*/
+RUNNER_TEST(validUpdateOfSigned)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+    RUNNER_ASSERT_MSG_SAFE(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed update in case both programs are signed");
+    uninstall(tizenId);
+}
+
+/*
+Name: validUpdateOfUnsigned
+Description: Tests update the web app where origin and a new one are unsigned.
+Expected: Widget should be successfully updated.
+*/
+RUNNER_TEST(validUpdateOfUnsigned)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed update in case both programs are signed");
+    uninstall(tizenId);
+}
+
+/*
+ * Information:
+ * These tests are incompatible to the specification 2.1
+ *      (but compatible to the specification 3.0).
+ */
+///*
+//Name: unupdateOfSigned
+//Description: Tests update that signed web app could be downgraded.
+//Expected: Widget should not be updated.
+//*/
+//RUNNER_TEST(unupdateOfSigned)
+//{
+//    std::string tizenId;
+//    std::string wgtPath;
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+//    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+//            "Failed to install widget");
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+//    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+//            "Unupdate should be prohibited.");
+//    uninstall(tizenId);
+//}
+//
+///*
+//Name: unupdateOfSigned
+//Description: Tests update that unsigned web app could be downgraded.
+//Expected: Widget should not be updated.
+//*/
+//RUNNER_TEST(unupdateOfUnsigned)
+//{
+//    std::string tizenId;
+//    std::string wgtPath;
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+//    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+//            "Failed to install widget");
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+//    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+//            "Unupdate should be prohibited.");
+//    uninstall(tizenId);
+//}
+
+/*
+Name: validUpdateOfCrossSigned
+Description: Tests update the web app where one of widgets are signed and second not.
+Expected: Widget should not be updated.
+*/
+RUNNER_TEST(updateOfCrossSignedWidgets)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    {
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+        RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed to install widget");
+
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+        RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+                "The update unsigned app by the signed app should not be possible");
+        uninstall(tizenId);
+    }
+    {
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+        RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed to install widget");
+
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+        RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+                "The update signed app by the unsigned app should not be possible");
+        uninstall(tizenId);
+    }
+}
+
+
+/*
+Name: updateAnotherAuthor
+Description: Tests update the web app by the widget signed by another author.
+Expected: Widget should not be updated.
+*/
+RUNNER_TEST(updateAnotherAuthor)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220SignedAnotherAuthor.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+            "The update by another author should not be possible");
+    uninstall(tizenId);
+}
+
+
+/*
+Name: updateWidgetDataRemember
+Description: Tests of keeping app data during widget updating.
+Expected: App data should be kept.
+*/
+RUNNER_TEST(updateWidgetDataRemember)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    // Installation of the widget
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install widget");
+
+    // Creating a file
+    std::string filePath = "/opt/usr/apps/HAdisUJ4Kn/data/test";
+    std::string text = "slonce swieci dzisiaj wyjatkowo wysoko";
+    std::string command = "echo " + text + " > " + filePath;
+    system(command.c_str());
+
+    // Second installation of the widget
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed update in case both programs are signed");
+
+
+    // Checking of the file created before
+    std::stringstream ss;
+    std::ifstream file(filePath);
+    RUNNER_ASSERT_MSG_SAFE(file.good(), "File is gone");
+
+    for( std::string line; getline( file, line ); ss << line);
+    file.close();
+    RUNNER_ASSERT_MSG_SAFE(text == ss.str(), "Content of file is not the same");
+    uninstall(tizenId);
+}
diff --git a/tests/general/widgets/widgetUpdateVer100Signed.wgt b/tests/general/widgets/widgetUpdateVer100Signed.wgt
new file mode 100644 (file)
index 0000000..b3ff8bf
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer100Signed.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer100Unsigned.wgt b/tests/general/widgets/widgetUpdateVer100Unsigned.wgt
new file mode 100644 (file)
index 0000000..751aed0
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer100Unsigned.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220Signed.wgt b/tests/general/widgets/widgetUpdateVer220Signed.wgt
new file mode 100644 (file)
index 0000000..5ef42af
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220Signed.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt b/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt
new file mode 100644 (file)
index 0000000..c1aeaa3
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220Unsigned.wgt b/tests/general/widgets/widgetUpdateVer220Unsigned.wgt
new file mode 100644 (file)
index 0000000..181447d
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220Unsigned.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt b/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt
new file mode 100644 (file)
index 0000000..8fb6c19
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt differ