[Release] wrt-installer_0.1.114
[framework/web/wrt-installer.git] / src / jobs / widget_uninstall / task_remove_files.cpp
index a9eaebb..0a8f5c3 100644 (file)
  * @brief   Implementation file for uninstaller task for removing widget files
  */
 
+#include <unistd.h>
 #include <widget_uninstall/task_remove_files.h>
 #include <widget_uninstall/job_widget_uninstall.h>
 #include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
 #include <dpl/wrt-dao-rw/widget_dao.h>
 #include <dpl/wrt-dao-ro/widget_config.h>
-#include <errno.h>
 #include <dpl/assert.h>
+#include <dpl/exception.h>
 #include <dpl/utils/wrt_utility.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
+#include <dpl/utils/path.h>
 #include <ail.h>
-#include <dpl/utils/wrt_utility.h>
 #include <pkgmgr/pkgmgr_parser.h>
+#include <errno.h>
+#include <string.h>
+#include <widget_install_to_external.h>
 
 namespace Jobs {
 namespace WidgetUninstall {
-
 using namespace WrtDB;
 
-void TaskRemoveFiles::ReadDir(const std::string& path,
-        std::list<std::string>& filesList)
-{
-    LogInfo("Reading directory " << path);
-    DIR* dir = NULL;
-    struct dirent* ptr = NULL;
-    dir = opendir(path.c_str());
-    std::string delim = "";
-
-    // adding / for path to directory to build a proper path to file under directory
-    if (path[path.size() - 1] != '/') {
-        delim = "/";
-    }
-
-    if (dir) {
-        while ((ptr = readdir(dir)) != NULL) {
-            if ((!strcmp(ptr->d_name, ".")) || (!strcmp(ptr->d_name, ".."))) {
-                LogPedantic("Omiting " << ptr->d_name);
-                continue;
-            }
-            std::string childPath = path + delim + ptr->d_name;
-
-            struct stat st;
-            if (0 != lstat(childPath.c_str(), &st)) {
-                switch (errno) {
-                case EACCES:
-                    LogWarning(
-                        "EACCESS Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case EBADF:
-                    LogWarning(
-                        "EBADF Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case ENOENT:
-                    LogWarning(
-                        "ENOENT Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case ENOTDIR:
-                    LogWarning(
-                        "ENOTDIR Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                default:
-                    LogWarning(
-                        "Unknown Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                }
-            } else {
-                if (S_ISDIR(st.st_mode)) {
-                    LogPedantic(
-                        "Calling ReadDir in recursive way " << childPath);
-                    ReadDir(childPath, filesList);
-                } else if (S_ISREG(st.st_mode) ||
-                           S_ISCHR(st.st_mode) ||
-                           S_ISBLK(st.st_mode) ||
-                           S_ISFIFO(st.st_mode) ||
-                           S_ISLNK(st.st_mode) ||
-                           S_ISSOCK(st.st_mode)) {
-                    LogPedantic("Adding to list  " << childPath);
-                    filesList.push_front(childPath);
-                } else {
-                    LogWarning("Uknown file type ??");
-                }
-            }
-        }
-        closedir(dir);
-    } else if (errno == ENOTDIR) {
-        LogDebug("Adding to list " << path);
-        filesList.push_front(path);
-    } else {
-        LogWarning("Unknown error");
-    }
-}
-
 TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) :
     DPL::TaskDecl<TaskRemoveFiles>(this),
     m_context(context)
 {
-    AddStep(&TaskRemoveFiles::StepPrepare);
-    AddStep(&TaskRemoveFiles::StepRemoveOneFile);
-    AddStep(&TaskRemoveFiles::StepRemoveDirectories);
-    //AddStep(&TaskRemoveFiles::StepRemoveDesktop);
+    AddStep(&TaskRemoveFiles::StartStep);
+    AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
     AddStep(&TaskRemoveFiles::StepRemoveManifest);
     AddStep(&TaskRemoveFiles::StepRemoveExternalLocations);
     AddStep(&TaskRemoveFiles::StepRemoveFinished);
+    AddStep(&TaskRemoveFiles::EndStep);
 }
 
 TaskRemoveFiles::~TaskRemoveFiles()
-{
-}
-
-void TaskRemoveFiles::StepPrepare()
-{
-    LogInfo("StepPrepare started");
-
-    std::ostringstream widgetDir;
-
-    widgetDir << m_context.locations->getPackageInstallationDir() << "/";
-
-    uninstRootDir = widgetDir.str();
-    ReadDir(uninstRootDir, filesList);
+{}
 
-    LogInfo("StepPrepare finished");
-
-    m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_PREPARE,
-        "Widget remove prepare Finished");
-    m_context.removeStarted = true;
-}
-
-void TaskRemoveFiles::StepRemoveOneFile()
+void TaskRemoveFiles::StepRemoveInstallationDirectory()
 {
-    if (filesList.size() > 0) {
-        LogDebug("Removing " << filesList.front());
-        if (0 != unlink(filesList.front().c_str())) {
-            LogWarning("Failed to remove file" << filesList.front());
+    LogDebug("StepRemoveInstallationDirectory started");
+    Try {
+        int ret = app2ext_get_app_location(m_context.tzPkgid.c_str());
+
+        if (APP2EXT_INTERNAL_MEM == ret) {
+            LogDebug("Removing directory");
+            m_context.removeStarted = true;
+            DPL::Utils::Path widgetDir= m_context.installedPath;
+            Try{
+                DPL::Utils::Remove(widgetDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                LogError("Removing widget installation directory failed : " <<
+                        widgetDir.Fullpath());
+            }
+            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 if (APP2EXT_SD_CARD == ret) {
+            LogDebug("Removing sdcard directory");
+            Try {
+                WidgetInstallToExtSingleton::Instance().initialize(m_context.tzPkgid);
+                WidgetInstallToExtSingleton::Instance().uninstallation();
+                WidgetInstallToExtSingleton::Instance().deinitialize();
+            }
+            Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
+            {
+                Throw(Jobs::WidgetUninstall::TaskRemoveFiles::Exception::
+                        RemoveFilesFailed);
+            }
+        } else {
+            LogError("app is not installed");
+            ThrowMsg(Exceptions::WidgetNotExist, "failed to get app location");
         }
-        filesList.pop_front();
-        SwitchToStep(&TaskRemoveFiles::StepRemoveOneFile);
-    } else {
-        m_context.removeFinished = true;
+    } Catch(Exception::RemoveFilesFailed) {
+        ThrowMsg(Exceptions::RemoveFileFailure, "Cann't remove directory");
     }
-
     m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_ONEFILE,
-        "Widget remove onefile Finished");
-}
-
-void TaskRemoveFiles::StepRemoveDirectories()
-{
-    using namespace WrtDB;
-    LogInfo("StepRemoveDirectories started");
-
-    if (!WrtUtilRemove(uninstRootDir)) {
-        LogWarning("Failed to remove directory" << uninstRootDir);
-    }
-    LogInfo("StepRemoveDirectories finished");
-
-    m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_DIRECTORIES,
-        "Widget remove directories Finished");
+        UninstallerContext::UNINSTALL_REMOVE_WIDGETDIR,
+        "Widget INstallation Directory Removal Finished");
 }
 
 void TaskRemoveFiles::StepRemoveFinished()
 {
-    LogInfo("StepRemoveFinished finished");
+    LogDebug("StepRemoveFinished finished");
 
     m_context.job->UpdateProgress(
         UninstallerContext::UNINSTALL_REMOVE_FINISHED,
         "Widget remove steps Finished");
 }
 
-void TaskRemoveFiles::StepRemoveDesktop()
-{
-    std::ostringstream desktopFile;
-
-    desktopFile << GlobalConfig::GetUserWidgetDesktopPath() << "/";
-    desktopFile << m_context.pkgname << ".desktop";
-
-    unlink(desktopFile.str().c_str());
-
-    ail_appinfo_h ai = NULL;
-    ail_error_e ret;
-
-    const char* package = m_context.pkgname.c_str();
-    LogDebug("ail delete : " << package);
-
-    ret = ail_package_get_appinfo(package, &ai);
-    if (ai) {
-        ail_package_destroy_appinfo(ai);
-    }
-
-    if (AIL_ERROR_OK == ret) {
-        if ( 0 > ail_desktop_remove(package)) {
-            LogWarning("Failed to remove ail information : " << package);
-        }
-    }
-
-    m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_DESKTOP,
-        "Widget remove desktop Finished");
-}
-
 void TaskRemoveFiles::StepRemoveManifest()
 {
     std::ostringstream manifest_name;
-    manifest_name << m_context.pkgname << ".xml";
-    std::ostringstream destFile;
-    destFile << "/opt/share/packages" << "/"; //TODO constant with path
-    destFile << manifest_name.str();
-    int ret1 = pkgmgr_parser_parse_manifest_for_uninstallation(destFile.str().c_str(), NULL);
-    int ret2 = unlink(destFile.str().c_str());
-    if(ret1 != 0)
-    {
-        LogWarning("Manifest file failed to parse for uninstallation");
+    manifest_name << m_context.tzPkgid << ".xml";
+    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_PACKAGES_PATH;
     }
-    if(ret2 != 0)
-    {
-        LogWarning("No manifest file found: " << destFile.str());
+    destFile /= manifest_name.str();
+    DPL::Utils::Path pre_manifest = USR_PACKAGES_PATH;
+    pre_manifest /= manifest_name.str();
+
+    if (!(destFile.Exists() == 0 && pre_manifest.Exists())) {
+        int ret1 = pkgmgr_parser_parse_manifest_for_uninstallation(
+                destFile.Fullpath().c_str(), NULL);
+        if (ret1 != 0) {
+            LogWarning("Manifest file failed to parse for uninstallation");
+        }
     }
-    else
-    {
-        LogDebug("Manifest file removed: " << destFile.str());
+    if (!DPL::Utils::TryRemove(destFile)) {
+        LogWarning("No manifest file found: " << destFile.Fullpath());
+    } else {
+        LogDebug("Manifest file removed: " << destFile.Fullpath());
     }
 }
 
 void TaskRemoveFiles::StepRemoveExternalLocations()
 {
-    WidgetDAO dao(m_context.widgetHandle);
-    LogDebug("Removing external locations:");
-    WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
-    FOREACH(path, externalPaths)
-    {
-        if(WrtUtilFileExists(*path))
-        {
-            LogDebug("  -> " << *path);
-            remove(path->c_str());
-        }
-        else if(WrtUtilDirExists(*path))
+    if (!m_context.removeAbnormal) {
+        WidgetDAO dao(DPL::FromUTF8String(m_context.tzAppid));
+        LogDebug("Removing external locations:");
+        WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
+        FOREACH(file, externalPaths)
         {
-            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.Fullpath() << "(no such a path)");
             }
         }
-        else
-        {
-            LogWarning("  -> " << *path << "(no such a path)");
-        }
+        dao.unregisterAllExternalLocations();
     }
-    dao.unregisterAllExternalLocations();
 }
 
+void TaskRemoveFiles::StartStep()
+{
+    LogDebug("--------- <TaskRemoveFiles> : START ----------");
+}
+
+void TaskRemoveFiles::EndStep()
+{
+    LogDebug("--------- <TaskRemoveFiles> : END ----------");
+}
 } //namespace WidgetUninstall
 } //namespace Jobs