[Install Location: Part 1] Separate parsing config.xml before unzip wgt file
authorSoyoung Kim <sy037.kim@samsung.com>
Thu, 17 Oct 2013 10:47:35 +0000 (19:47 +0900)
committerGerrit Code Review <gerrit@gerrit.vlan144.tizendev.org>
Thu, 31 Oct 2013 10:41:36 +0000 (10:41 +0000)
[Issue#]   P130919-00555
[Problem]  web app install to internal storage even if install location is set
           "SD card" from setting menu.
[Cause]    There is an issue to process getting install location.
           (Before parsing config.xml, installer cannot get install location info.)
[Solution] - Parsing config.xml should be done before unzip wgt.
           - So parsing config.xml is separated before unzip.
[Remarks] Installer, therefore, should implement below install location spec.
    * Auto: Get setting value about default storage at setting menu.
      - If user set "Device memory" try internal storage.
        If fails, try external storage.
      - If user set "SD card" try SD card.
        If fails, try internal storage.
    * Internal-only: Try internal storage.
      - If there is no space in internal memory, installation is failed.
    * Prefer-external: Try external storage.
      - If SD card is not available, try internal storage.

    There are three parts for implementation.
     * Part 1: This patch is for separating parse config.xml before unzipping wgt file.
     * Part 2: WGT file unzip to directory package directory
               (/opt/usr/apps/[pkgid]) instead of temporary directory.
     * Part 3: Implement about install location (auto, internal only prefer-external)

[Verification]
    SD card should be attached in the device for this feature.
    -  First> Normal and Hybrid web app can be installed without error.
    - Second> WebApp should be installed into device memory or SD card depending
              on install-location

    1. Install-location: internal-only
          => should be installed into device memory
    2. Install-location: prefer-external
          1) SD card is enabled => into SD card.
          2) SD card is disabled => into device memory.
    3. Install-location:
       * Auto and default storage is "Device Memory"
          1) into device memory.
          2) If device Memory is full = > into SD card.
       * Auto and default storage is "SD card"
          1) into SD card
          2) If SD card isn't available => into device memory.
[SCMRequest] N/A

Change-Id: I93c4811ab06babaafbe09a1feefb41323d43b656

src/jobs/widget_install/task_configuration.cpp
src/jobs/widget_install/task_configuration.h
src/jobs/widget_install/widget_unzip.cpp
src/jobs/widget_install/widget_unzip.h

index bec432c..2835558 100644 (file)
@@ -100,9 +100,10 @@ TaskConfiguration::TaskConfiguration(InstallerContext& context) :
     AddStep(&TaskConfiguration::StartStep);
 
     AddStep(&TaskConfiguration::SetupTempDirStep);
-    AddStep(&TaskConfiguration::CheckPackageTypeStep);
-
+    AddStep(&TaskConfiguration::UnzipConfigurationStep);
     AddStep(&TaskConfiguration::ParseXMLConfigStep);
+    AddStep(&TaskConfiguration::UnzipWidgetFileStep);
+    AddStep(&TaskConfiguration::CheckPackageTypeStep);
 
     AddStep(&TaskConfiguration::TizenIdStep);
     AddStep(&TaskConfiguration::CheckAppRunningStateStep);
@@ -172,6 +173,48 @@ void TaskConfiguration::SetupTempDirStep()
             Jobs::WidgetInstall::createTempPath(
                     m_context.mode.rootPath ==
                         InstallMode::RootPath::RO);
+    }
+}
+
+void TaskConfiguration::UnzipConfigurationStep()
+{
+    _D("UnzipConfigurationStep");
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR) {
+        if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files
+        {
+            WidgetUnzip wgtUnzip;
+            wgtUnzip.unzipConfiguration(m_context.requestedPath, m_tempDir);
+            m_configuration += m_tempDir + "/" + CONFIG_XML;
+        } else{
+            m_configuration += m_context.requestedPath;
+        }
+    } else {
+        if (m_context.mode.command == InstallMode::Command::REINSTALL) {
+            std::string configFile = m_tempDir + "/" + CONFIG_XML;
+            if (!WrtUtilFileExists(configFile)) {
+                configFile = m_tempDir + "/" + WITH_OSP_XML;
+                if (!WrtUtilFileExists(configFile)) {
+                    std::string tzAppId = m_context.requestedPath.
+                        substr(m_context.requestedPath.find_last_of("/")+1);
+                    WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(
+                                DPL::FromUTF8String(tzAppId)));
+                    configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+                    configFile += "/";
+                    configFile += WITH_OSP_XML;
+                }
+            }
+            m_configuration = configFile;
+        } else {
+            m_configuration = m_tempDir + "/" + WITH_OSP_XML;
+        }
+    }
+    _D("m_configuration : %s", m_configuration.c_str());
+}
+
+void TaskConfiguration::UnzipWidgetFileStep()
+{
+    _D("UnzipWidgetFileStep");
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR) {
         if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files
         {
             WidgetUnzip wgtUnzip;
@@ -186,11 +229,49 @@ void TaskConfiguration::SetupTempDirStep()
 
 void TaskConfiguration::ParseXMLConfigStep()
 {
-    parseWidgetXMLConfig(
-            m_context.requestedPath, m_tempDir,
-            m_context.widgetConfig.packagingType,
-            m_context.mode.command == InstallMode::Command::REINSTALL);
-    _D("widget packaging type : %d", static_cast<WrtDB::PkgType>(m_context.widgetConfig.packagingType.pkgType));
+    _D("ParseXMLConfigStep");
+    // Parse config
+    ParserRunner parser;
+    Try
+    {
+        if(!DPL::Utils::Path(m_configuration).Exists())
+        {
+            ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
+        }
+
+#ifdef SCHEMA_VALIDATION_ENABLED
+        if(!parser.Validate(configFilePath, WRT_WIDGETS_XML_SCHEMA))
+        {
+            _E("Invalid configuration file - schema validation failed");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Failed to parse config.xml file");
+        }
+#endif
+        parser.Parse(m_configuration,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(m_widgetConfig,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        _E("Failed to parse config.xml file");
+        ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        _E("Failed to find installed widget - give proper tizenId");
+        ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
+    }
+    Catch(Exceptions::WidgetConfigFileNotFound){
+        _E("Failed to find config.xml");
+        ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
+    }
+
+    if (!WrtUtilRemove(m_configuration)) {
+        _E("Error occurs during removing %s", m_configuration.c_str());
+    }
+
 }
 
 void TaskConfiguration::TizenIdStep()
@@ -479,77 +560,6 @@ bool TaskConfiguration::checkWidgetUpdate(
     return false;
 }
 
-void TaskConfiguration::parseWidgetXMLConfig(
-    const std::string &widgetSource,
-    const std::string &tempPath,
-    WrtDB::PackagingType pkgType,
-    bool isReinstall)
-{
-    // Parse config
-    ParserRunner parser;
-    Try
-    {
-        if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
-            parser.Parse(widgetSource,
-                         ElementParserPtr(
-                             new RootParser<WidgetParser>(m_widgetConfig,
-                                                          DPL::FromUTF32String(
-                                                              L"widget"))));
-        } else {
-            std::string configFile;
-            configFile = tempPath + "/" + CONFIG_XML;
-            if (!WrtUtilFileExists(configFile)) {
-                configFile = tempPath + "/" + WITH_OSP_XML;
-            }
-
-            if (isReinstall) {
-                // checking RDS data directory
-                if (access(configFile.c_str(), F_OK) != 0) {
-                    std::string tzAppId =
-                        widgetSource.substr(widgetSource.find_last_of("/")+1);
-                    WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId)));
-                    configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
-                    configFile += "/";
-                    configFile += WITH_OSP_XML;
-                }
-            }
-
-            if(!DPL::Utils::Path(configFile).Exists())
-            {
-                ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
-            }
-
-#ifdef SCHEMA_VALIDATION_ENABLED
-            if(!parser.Validate(configFilePath, WRT_WIDGETS_XML_SCHEMA))
-            {
-                _E("Invalid configuration file - schema validation failed");
-                ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Failed to parse config.xml file");
-            }
-#endif
-            parser.Parse(configFile,
-                    ElementParserPtr(
-                        new RootParser<WidgetParser>(m_widgetConfig,
-                            DPL::
-                            FromUTF32String(
-                                L"widget"))));
-        }
-    }
-    Catch(ElementParser::Exception::ParseError)
-    {
-        _E("Failed to parse config.xml file");
-        ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
-    }
-    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
-    {
-        _E("Failed to find installed widget - give proper tizenId");
-        ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
-    }
-    Catch(Exceptions::WidgetConfigFileNotFound){
-        _E("Failed to find config.xml");
-        ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
-    }
-}
-
 WidgetUpdateInfo TaskConfiguration::detectWidgetUpdate(
     const ConfigParserData &configInfo,
     const WrtDB::TizenAppId &tizenId)
index 0540ab7..d239b54 100644 (file)
@@ -42,6 +42,7 @@ class TaskConfiguration : public DPL::TaskDecl<TaskConfiguration>
     InstallerContext& m_context;
     std::string m_tempDir;
     WrtDB::ConfigParserData &m_widgetConfig;
+    std::string m_configuration;
 
     WidgetUpdateInfo m_widgetUpdateInfo;
 
@@ -69,8 +70,10 @@ class TaskConfiguration : public DPL::TaskDecl<TaskConfiguration>
     void StartStep();
 
     void SetupTempDirStep();
-    void CheckPackageTypeStep();
+    void UnzipConfigurationStep();
     void ParseXMLConfigStep();
+    void UnzipWidgetFileStep();
+    void CheckPackageTypeStep();
 
     void TizenIdStep();
     void CheckAppRunningStateStep();
index d744b21..7c9e5c6 100644 (file)
@@ -38,6 +38,8 @@ using namespace WrtDB;
 namespace {
 const char *const DRM_LIB_PATH = "/usr/lib/libdrm-service-core-tizen.so";
 const size_t SPACE_SIZE = 1024 * 1024;
+const char *const WEB_APP_CONFIG_XML= "config.xml";
+const char *const HYBRID_CONFIG_XML = "res/wgt/config.xml";
 
 struct PathAndFilePair
 {
@@ -321,5 +323,40 @@ void WidgetUnzip::checkAvailableSpace(const std::string &destination)
     }
 }
 
+void WidgetUnzip::unzipConfiguration(const std::string &source,
+        const std::string &destination)
+{
+    _D("unzipConfiguration");
+    Try {
+        std::string wgtFile = getDecryptedPackage(source);
+        _D("wgtFile : %s", wgtFile.c_str());
+
+        std::unique_ptr<DPL::ZipInput> zipFile(new DPL::ZipInput(source));
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        Try {
+            configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
+        } Catch(DPL::ZipInput::Exception::OpenFileFailed) {
+            configFile.reset(zipFile->OpenFile(WEB_APP_CONFIG_XML));
+        }
+
+        std::string extractPath = destination + "/" + WEB_APP_CONFIG_XML;
+        ExtractFile(configFile.get(), extractPath);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, source);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        ThrowMsg(Exceptions::ExtractFileFailed, "config.xml");
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, source);
+    }
+}
+
 } //namespace WidgetInstall
 } //namespace Jobs
index f9c0d6d..2de8f99 100644 (file)
@@ -32,6 +32,7 @@ class WidgetUnzip
 {
   public:
       void unzipWgtFile(const std::string &source, const std::string &destination);
+      void unzipConfiguration(const std::string &source, const std::string &destination);
 
   private:
     // Unzip state