[Release] wrt-installer_0.1.37
[framework/web/wrt-installer.git] / src / jobs / widget_install / job_widget_install.cpp
index d31aa5a..e2b2086 100644 (file)
@@ -48,8 +48,6 @@
 #include <libiriwrapper.h>
 #include <pkg-manager/pkgmgr_signal.h>
 #include <app_manager.h>
-//#include <drm_client.h>
-#include <drm-oem-intel.h> //temporary code
 
 #include "root_parser.h"
 #include "widget_parser.h"
@@ -71,8 +69,7 @@
 #include <widget_install/task_certificates.h>
 #include <widget_install/task_unzip.h>
 #include <widget_install/task_commons.h>
-
-#include <widget_install/task_plugins_copy.h>
+#include <widget_install/task_prepare_reinstall.h>
 
 #include <widget_install/widget_install_errors.h>
 #include <widget_install/widget_install_context.h>
@@ -94,7 +91,7 @@ const size_t PACKAGE_ID_LENGTH = 10;
 static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
 static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
 const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
-    L"install-location-type";
+    L"install-location";
 const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
     L"prefer-external";
 
@@ -197,12 +194,6 @@ JobWidgetInstall::JobWidgetInstall(
         }
 
         AddTask(new TaskFileManipulation(m_installerContext));
-        // TODO: Update progress information for this task
-
-        //This is sort of quick solution, because ACE verdicts are based upon
-        //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
-        //task.
-        AddTask(new TaskSmack(m_installerContext));
 
         AddTask(new TaskManifestFile(m_installerContext));
         if (m_installerContext.widgetConfig.packagingType ==
@@ -211,13 +202,20 @@ JobWidgetInstall::JobWidgetInstall(
             AddTask(new TaskInstallOspsvc(m_installerContext));
         }
         AddTask(new TaskCertificates(m_installerContext));
-        AddTask(new TaskPluginsCopy(m_installerContext));
         AddTask(new TaskDatabase(m_installerContext));
         AddTask(new TaskAceCheck(m_installerContext));
+        AddTask(new TaskSmack(m_installerContext));
     } else if (result == ConfigureResult::Updated) {
         LogInfo("Configure installation updated");
         LogInfo("Widget Update");
         m_installerContext.job->SetProgressFlag(true);
+
+        if (m_jobStruct.m_installMode ==
+            InstallMode::REINSTALL_MODE_DIRECTORY)
+        {
+            AddTask(new TaskPrepareReinstall(m_installerContext));
+        }
+
         if (m_installerContext.widgetConfig.packagingType !=
             WrtDB::PKG_TYPE_HOSTED_WEB_APP &&
             m_installerContext.widgetConfig.packagingType !=
@@ -246,9 +244,6 @@ JobWidgetInstall::JobWidgetInstall(
             AddTask(new TaskUpdateFiles(m_installerContext));
         }
 
-        /* TODO : To backup file, save md5 values */
-        AddTask(new TaskSmack(m_installerContext));
-
         AddTask(new TaskManifestFile(m_installerContext));
         if (m_installerContext.widgetConfig.packagingType ==
             PKG_TYPE_HYBRID_WEB_APP)
@@ -260,12 +255,12 @@ JobWidgetInstall::JobWidgetInstall(
         {
             AddTask(new TaskRemoveBackupFiles(m_installerContext));
         }
-        AddTask(new TaskPluginsCopy(m_installerContext));
         AddTask(new TaskDatabase(m_installerContext));
         AddTask(new TaskAceCheck(m_installerContext));
         //TODO: remove widgetHandle from this task and move before database task
         // by now widget handle is needed in ace check
         // Any error in acecheck while update will break widget
+        AddTask(new TaskSmack(m_installerContext));
     } else if (result == ConfigureResult::Deferred) {
         // Installation is deferred
         LogInfo("Configure installation deferred");
@@ -290,8 +285,22 @@ ConfigureResult JobWidgetInstall::PrePareInstallation(
 
     Try
     {
-        std::string tempDir =
-            Jobs::WidgetInstall::createTempPath(m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_PRELOAD);
+        std::string tempDir;
+        if (m_jobStruct.m_installMode ==
+            InstallMode::REINSTALL_MODE_DIRECTORY)
+        {
+            std::ostringstream tempPathBuilder;
+            tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+            tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
+            tempPathBuilder << "/";
+            tempPathBuilder << widgetPath;
+            tempDir = tempPathBuilder.str();;
+        } else {
+            tempDir =
+                Jobs::WidgetInstall::createTempPath(
+                        m_jobStruct.m_installMode ==
+                            InstallMode::INSTALL_MODE_PRELOAD);
+        }
 
         m_isDRM = isDRMWidget(widgetPath);
         if (true == m_isDRM) {
@@ -310,7 +319,9 @@ ConfigureResult JobWidgetInstall::PrePareInstallation(
                 widgetPath,
                 tempDir,
                 m_installerContext.widgetConfig.packagingType,
-                m_isDRM);
+                m_isDRM,
+                m_jobStruct.m_installMode ==
+                    InstallMode::REINSTALL_MODE_DIRECTORY);
         LogDebug("widget packaging type : " <<
                  m_installerContext.widgetConfig.packagingType.pkgType);
 
@@ -438,12 +449,24 @@ void JobWidgetInstall::setTizenId(
 void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath,
                                                const std::string& tempPath)
 {
-    m_installerContext.locations =
-        WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
-                                             tzPkgid),
-                       widgetPath, tempPath,
-                       m_installerContext.widgetConfig.packagingType,
-                       m_installerContext.locationType);
+    if (m_jobStruct.m_installMode ==
+         InstallMode::REINSTALL_MODE_DIRECTORY)
+    {
+        // replace widget path to installed path
+        m_installerContext.locations =
+            WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
+                                                 tzPkgid),
+                           widgetPath, tempPath,
+                           m_installerContext.widgetConfig.packagingType,
+                           m_installerContext.locationType);
+    } else {
+        m_installerContext.locations =
+            WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
+                                                 tzPkgid),
+                           widgetPath, tempPath,
+                           m_installerContext.widgetConfig.packagingType,
+                           m_installerContext.locationType);
+    }
     m_installerContext.locations->registerAppid(
         DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
 
@@ -552,20 +575,73 @@ 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 =
+    int ret =
         app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(),
                                &isRunning);
-    if (APP_MANAGER_ERROR_NONE != retval || isRunning) {
+    if (APP_MANAGER_ERROR_NONE != ret) {
         LogError("Fail to get running state");
         return ConfigureResult::Failed_WidgetRunning;
     }
 
+    if (true == isRunning) {
+        // get app_context for running application
+        // app_context must be released with app_context_destroy
+        app_context_h appCtx = NULL;
+        ret =
+            app_manager_get_app_context(
+                DPL::ToUTF8String(update.tzAppId).c_str(),
+                &appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            LogError("Fail to get app_context");
+            return ConfigureResult::Failed_WidgetRunning;
+        }
+
+        // terminate app_context_h
+        ret = app_manager_terminate_app(appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            LogError("Fail to terminate running application");
+            app_context_destroy(appCtx);
+            return ConfigureResult::Failed_WidgetRunning;
+        } else {
+            app_context_destroy(appCtx);
+            // app_manager_terminate_app isn't sync API
+            // wait until application isn't running (50ms * 100)
+            bool isStillRunning = true;
+            int checkingloop = 100;
+            struct timespec duration = { 0, 50 * 1000 * 1000 };
+            while (--checkingloop >= 0) {
+                nanosleep(&duration, NULL);
+                int ret =
+                    app_manager_is_running(
+                        DPL::ToUTF8String(update.tzAppId).c_str(),
+                        &isStillRunning);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    LogError("Fail to get running state");
+                    return ConfigureResult::Failed_WidgetRunning;
+                }
+                if (!isStillRunning) {
+                    break;
+                }
+            }
+            if (isStillRunning) {
+                LogError("Fail to terminate running application");
+                return ConfigureResult::Failed_WidgetRunning;
+            }
+            LogInfo("terminate application");
+        }
+    }
+
     m_installerContext.widgetConfig.tzAppid = update.tzAppId;
 
     if (isUpperVersion(update.existingVersion, update.incomingVersion) ||
-        m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY)
+        (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY) ||
+        (m_jobStruct.m_installMode == InstallMode::REINSTALL_MODE_DIRECTORY))
     {
         LogInfo("Whether widget policy allow proceed ok");
         return ConfigureResult::Updated;
@@ -608,7 +684,8 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
     const std::string &widgetSource,
     const std::string &tempPath,
     WrtDB::PackagingType pkgType,
-    bool isDRM)
+    bool isDRM,
+    bool isReinstall)
 {
     // Parse config
     ParserRunner parser;
@@ -623,7 +700,23 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
                                                           DPL::FromUTF32String(
                                                               L"widget"))));
         } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) {
-            parser.Parse(widgetSource + '/' + WITH_OSP_XML,
+            std::string configPath;
+            configPath = tempPath;
+            configPath += "/";
+            configPath += WITH_OSP_XML;
+
+            if (isReinstall) {
+                // checking RDS data directory
+                if (access(configPath.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;
+                }
+            }
+            parser.Parse(configPath,
                          ElementParserPtr(
                              new RootParser<WidgetParser>(
                                  configInfo,
@@ -718,9 +811,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);
 }
 
@@ -893,7 +993,8 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType(
     const std::string &tempPath)
 {
     // Check installation type (direcotory/ or config.xml or widget.wgt)
-    if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY)
+    if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY ||
+         m_jobStruct.m_installMode == InstallMode::REINSTALL_MODE_DIRECTORY)
     {
         LogDebug("Install directly from directory");
         return PKG_TYPE_DIRECTORY_WEB_APP;
@@ -1048,54 +1149,17 @@ void JobWidgetInstall::setInstallLocationType(
     }
 }
 
-bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
+bool JobWidgetInstall::isDRMWidget(std::string /*widgetPath*/)
 {
-    /* TODO :
-     * drm_bool_type_e is_drm_file = DRM_UNKNOWN;
-     * int ret = -1;
-     *
-     * ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file);
-     * if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) {
-     */
-
-    /* blow code temporary code for drm. */
-    int ret = drm_oem_intel_isDrmFile(const_cast<char*>(widgetPath.c_str()));
-    if (1 == ret) {
-        return true;
-    } else {
-        return false;
-    }
+    /* TODO */
+    return false;
 }
 
-bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath,
-                                        std::string destPath)
+bool JobWidgetInstall::DecryptDRMWidget(std::string /*widgetPath*/,
+                                        std::string /*destPath*/)
 {
-    /* TODO :
-     * drm_trusted_sapps_decrypt_package_info_s package_info;
-     *
-     * strncpy(package_info.sadcf_filepath, widgetPath.c_str(),
-     *      sizeof(package_info.sadcf_filepath));
-     * strncpy(package_info.decrypt_filepath, destPath.c_str(),
-     *      sizeof(package_info.decrypt_filepath));
-     *
-     * drm_trusted_request_type_e requestType =
-     *  DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE;
-     *
-     * int ret = drm_trusted_handle_request(requestType,
-     *                                   (void *)&package_info, NULL);
-     * if (DRM_TRUSTED_RETURN_SUCCESS == ret) {
-     *  return true;
-     * } else {
-     *  return false;
-     * }
-     */
-    if (drm_oem_intel_decrypt_package(const_cast<char*>(widgetPath.c_str()),
-                                      const_cast<char*>(destPath.c_str())) != 0)
-    {
-        return true;
-    } else {
-        return false;
-    }
+    /* TODO */
+    return false;
 }
 } //namespace WidgetInstall
 } //namespace Jobs