From 66e7732ec2c0cbae33c88d2a7a67ab0758791fd8 Mon Sep 17 00:00:00 2001
From: Nite <shunite@gmail.com>
Date: Sun, 12 Dec 2021 17:06:11 +0100
Subject: [PATCH] Removed remaining DocumentFile uses Fixed lint issues

---
 detekt-config.yml                             |  2 +-
 .../ultrasonic/fragment/SettingsFragment.kt   |  2 +-
 .../ultrasonic/imageloader/BitmapUtils.kt     |  2 +-
 .../ultrasonic/imageloader/ImageLoader.kt     |  2 +-
 .../moire/ultrasonic/log/FileLoggerTree.kt    |  2 +-
 .../moire/ultrasonic/service/DownloadFile.kt  | 22 +++---
 .../moire/ultrasonic/service/Downloader.kt    |  1 -
 .../ultrasonic/service/LocalMediaPlayer.kt    |  2 +-
 .../ultrasonic/service/OfflineMusicService.kt |  9 +--
 .../org/moire/ultrasonic/util/AbstractFile.kt |  4 +-
 .../org/moire/ultrasonic/util/CacheCleaner.kt |  2 +-
 .../org/moire/ultrasonic/util/FileUtil.kt     | 12 +--
 .../org/moire/ultrasonic/util/JavaFile.kt     |  6 +-
 .../moire/ultrasonic/util/ResettableLazy.kt   |  2 +-
 .../org/moire/ultrasonic/util/Storage.kt      |  4 +-
 .../org/moire/ultrasonic/util/StorageFile.kt  | 74 +++++++++++++------
 .../util/UncaughtExceptionHandler.kt          |  2 +-
 .../kotlin/org/moire/ultrasonic/util/Util.kt  |  4 +-
 .../main/res/layout/list_header_folder.xml    |  1 +
 ultrasonic/src/main/res/values-cs/strings.xml |  1 -
 ultrasonic/src/main/res/values-de/strings.xml |  1 -
 ultrasonic/src/main/res/values-es/strings.xml |  1 -
 ultrasonic/src/main/res/values-fr/strings.xml |  1 -
 ultrasonic/src/main/res/values-hu/strings.xml |  1 -
 ultrasonic/src/main/res/values-nl/strings.xml |  1 -
 ultrasonic/src/main/res/values-pl/strings.xml |  1 -
 .../src/main/res/values-pt-rBR/strings.xml    |  1 -
 ultrasonic/src/main/res/values-pt/strings.xml |  1 -
 ultrasonic/src/main/res/values-ru/strings.xml |  1 -
 .../src/main/res/values-zh-rCN/strings.xml    |  1 -
 ultrasonic/src/main/res/values/strings.xml    |  1 -
 31 files changed, 93 insertions(+), 74 deletions(-)

diff --git a/detekt-config.yml b/detekt-config.yml
index 2bb90612..cdebb21a 100644
--- a/detekt-config.yml
+++ b/detekt-config.yml
@@ -76,7 +76,7 @@ style:
   UnnecessaryAbstractClass:
     active: false
   ReturnCount:
-    max: 3
+    max: 5
 
 comments:
   active: true
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt
index a321987e..462667b1 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt
@@ -20,6 +20,7 @@ import androidx.preference.ListPreference
 import androidx.preference.Preference
 import androidx.preference.PreferenceCategory
 import androidx.preference.PreferenceFragmentCompat
+import java.io.File
 import kotlin.math.ceil
 import org.koin.core.component.KoinComponent
 import org.koin.java.KoinJavaComponent.get
@@ -52,7 +53,6 @@ import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat
 import org.moire.ultrasonic.util.Util.toast
 import org.moire.ultrasonic.util.isUri
 import timber.log.Timber
-import java.io.File
 
 /**
  * Shows main app settings.
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/BitmapUtils.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/BitmapUtils.kt
index 20fa626c..27f53635 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/BitmapUtils.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/BitmapUtils.kt
@@ -3,11 +3,11 @@ package org.moire.ultrasonic.imageloader
 import android.graphics.Bitmap
 import android.graphics.BitmapFactory
 import android.os.Build
+import java.io.File
 import org.moire.ultrasonic.domain.MusicDirectory
 import org.moire.ultrasonic.util.FileUtil
 import org.moire.ultrasonic.util.Util
 import timber.log.Timber
-import java.io.File
 
 @Suppress("UtilityClassWithPublicConstructor")
 class BitmapUtils {
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/ImageLoader.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/ImageLoader.kt
index 9b68e33b..de3db8c4 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/ImageLoader.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/imageloader/ImageLoader.kt
@@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat
 import com.squareup.picasso.LruCache
 import com.squareup.picasso.Picasso
 import com.squareup.picasso.RequestCreator
+import java.io.File
 import java.io.FileOutputStream
 import java.io.InputStream
 import java.io.OutputStream
@@ -22,7 +23,6 @@ import org.moire.ultrasonic.domain.MusicDirectory
 import org.moire.ultrasonic.util.FileUtil
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
-import java.io.File
 
 /**
  * Our new image loader which uses Picasso as a backend.
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/log/FileLoggerTree.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/log/FileLoggerTree.kt
index 54f3f436..ab1bac3d 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/log/FileLoggerTree.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/log/FileLoggerTree.kt
@@ -1,5 +1,6 @@
 package org.moire.ultrasonic.log
 
+import java.io.File
 import java.io.FileWriter
 import java.text.SimpleDateFormat
 import java.util.Date
@@ -7,7 +8,6 @@ import java.util.Locale
 import org.moire.ultrasonic.util.FileUtil
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
-import java.io.File
 
 /**
  * A Timber Tree which can be used to log to a file
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt
index 642b50ef..9760fc5e 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt
@@ -22,9 +22,9 @@ import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
 import org.moire.ultrasonic.subsonic.ImageLoaderProvider
 import org.moire.ultrasonic.util.CacheCleaner
 import org.moire.ultrasonic.util.CancellableTask
-import org.moire.ultrasonic.util.Storage
 import org.moire.ultrasonic.util.FileUtil
 import org.moire.ultrasonic.util.Settings
+import org.moire.ultrasonic.util.Storage
 import org.moire.ultrasonic.util.Util
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
@@ -73,8 +73,10 @@ class DownloadFile(
     init {
         val state: DownloadStatus
 
-        partialFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
-        completeFile = FileUtil.getParentPath(saveFile) + "/" + FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
+        partialFile = FileUtil.getParentPath(saveFile) + "/" +
+            FileUtil.getPartialFile(FileUtil.getNameFromPath(saveFile))
+        completeFile = FileUtil.getParentPath(saveFile) + "/" +
+            FileUtil.getCompleteFile(FileUtil.getNameFromPath(saveFile))
 
         when {
             Storage.isPathExists(saveFile) -> {
@@ -146,11 +148,11 @@ class DownloadFile(
 
     @get:Synchronized
     val isDownloading: Boolean
-    get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning)
+        get() = downloadPrepared || (downloadTask != null && downloadTask!!.isRunning)
 
     @get:Synchronized
     val isDownloadCancelled: Boolean
-    get() = downloadTask != null && downloadTask!!.isCancelled
+        get() = downloadTask != null && downloadTask!!.isCancelled
 
     fun shouldRetry(): Boolean {
         return (retryCount > 0)
@@ -254,9 +256,8 @@ class DownloadFile(
                 val fileLength = Storage.getFromPath(partialFile)?.length ?: 0
 
                 needsDownloading = (
-                        desiredBitRate == 0 || duration == null ||
-                                duration == 0 || fileLength == 0L
-                        )
+                    desiredBitRate == 0 || duration == null || duration == 0 || fileLength == 0L
+                    )
 
                 if (needsDownloading) {
                     // Attempt partial HTTP GET, appending to the file if it exists.
@@ -270,7 +271,8 @@ class DownloadFile(
                         Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength)
                     }
 
-                    outputStream = Storage.getOrCreateFileFromPath(partialFile).getFileOutputStream(isPartial)
+                    outputStream = Storage.getOrCreateFileFromPath(partialFile)
+                        .getFileOutputStream(isPartial)
 
                     val len = inputStream.copyTo(outputStream) { totalBytesCopied ->
                         setProgress(totalBytesCopied)
@@ -395,7 +397,7 @@ class DownloadFile(
     }
 
     override val id: String
-    get() = song.id
+        get() = song.id
 
     companion object {
         const val MAX_RETRIES = 5
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt
index 52b304c8..52143fd0 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/Downloader.kt
@@ -187,7 +187,6 @@ class Downloader(
         if (listChanged) {
             updateLiveData()
         }
-
     }
 
     private fun updateLiveData() {
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt
index 9c727e08..cb55c50f 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt
@@ -19,7 +19,6 @@ import android.os.PowerManager
 import android.os.PowerManager.PARTIAL_WAKE_LOCK
 import android.os.PowerManager.WakeLock
 import androidx.lifecycle.MutableLiveData
-import org.moire.ultrasonic.util.Storage
 import java.net.URLEncoder
 import java.util.Locale
 import kotlin.math.abs
@@ -33,6 +32,7 @@ import org.moire.ultrasonic.domain.PlayerState
 import org.moire.ultrasonic.util.CancellableTask
 import org.moire.ultrasonic.util.Constants
 import org.moire.ultrasonic.util.Settings
+import org.moire.ultrasonic.util.Storage
 import org.moire.ultrasonic.util.StreamProxy
 import org.moire.ultrasonic.util.Util
 import timber.log.Timber
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt
index 98e782d1..3fc586dd 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt
@@ -9,7 +9,9 @@ package org.moire.ultrasonic.service
 import android.media.MediaMetadataRetriever
 import java.io.BufferedReader
 import java.io.BufferedWriter
-import org.moire.ultrasonic.util.Storage
+import java.io.File
+import java.io.FileReader
+import java.io.FileWriter
 import java.io.InputStream
 import java.io.Reader
 import java.util.ArrayList
@@ -40,11 +42,9 @@ import org.moire.ultrasonic.domain.UserInfo
 import org.moire.ultrasonic.util.AbstractFile
 import org.moire.ultrasonic.util.Constants
 import org.moire.ultrasonic.util.FileUtil
+import org.moire.ultrasonic.util.Storage
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
-import java.io.File
-import java.io.FileReader
-import java.io.FileWriter
 
 @Suppress("TooManyFunctions")
 class OfflineMusicService : MusicService, KoinComponent {
@@ -502,7 +502,6 @@ class OfflineMusicService : MusicService, KoinComponent {
         return FileUtil.getBaseName(name)
     }
 
-
     private fun createEntry(file: AbstractFile, name: String?): MusicDirectory.Entry {
         val entry = MusicDirectory.Entry(file.path)
         entry.populateWithDataFrom(file, name)
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/AbstractFile.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/AbstractFile.kt
index 1bfc2612..10e374e8 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/AbstractFile.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/AbstractFile.kt
@@ -12,7 +12,7 @@ import java.io.IOException
 import java.io.InputStream
 import java.io.OutputStream
 
-abstract class AbstractFile: Comparable<AbstractFile> {
+abstract class AbstractFile : Comparable<AbstractFile> {
     abstract val name: String
     abstract val isDirectory: Boolean
     abstract val isFile: Boolean
@@ -53,4 +53,4 @@ abstract class AbstractFile: Comparable<AbstractFile> {
     }
 
     abstract fun rename(pathFrom: AbstractFile, pathTo: String)
-}
\ No newline at end of file
+}
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CacheCleaner.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CacheCleaner.kt
index b9c4abe8..d2b5b5c3 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CacheCleaner.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CacheCleaner.kt
@@ -11,13 +11,13 @@ import org.koin.java.KoinJavaComponent.inject
 import org.moire.ultrasonic.data.ActiveServerProvider
 import org.moire.ultrasonic.domain.Playlist
 import org.moire.ultrasonic.service.Downloader
+import org.moire.ultrasonic.util.FileUtil.delete
 import org.moire.ultrasonic.util.FileUtil.getAlbumArtFile
 import org.moire.ultrasonic.util.FileUtil.getPlaylistDirectory
 import org.moire.ultrasonic.util.FileUtil.getPlaylistFile
 import org.moire.ultrasonic.util.FileUtil.listFiles
 import org.moire.ultrasonic.util.FileUtil.musicDirectory
 import org.moire.ultrasonic.util.Settings.cacheSizeMB
-import org.moire.ultrasonic.util.FileUtil.delete
 import org.moire.ultrasonic.util.Util.formatBytes
 import timber.log.Timber
 
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt
index 3c0ae36e..dbd1472c 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt
@@ -13,6 +13,7 @@ import android.os.Environment
 import android.text.TextUtils
 import android.util.Pair
 import java.io.BufferedWriter
+import java.io.File
 import java.io.FileInputStream
 import java.io.FileOutputStream
 import java.io.FileWriter
@@ -28,7 +29,6 @@ import org.moire.ultrasonic.app.UApp
 import org.moire.ultrasonic.domain.MusicDirectory
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
-import java.io.File
 
 @Suppress("TooManyFunctions")
 object FileUtil {
@@ -191,11 +191,11 @@ object FileUtil {
         if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) {
             val f = fileSystemSafeDir(entry.path)
             dir = String.format(
-                    Locale.ROOT,
-                    "%s/%s",
-                    musicDirectory.path,
-                    if (entry.isDirectory) f else getParentPath(f) ?: ""
-                )
+                Locale.ROOT,
+                "%s/%s",
+                musicDirectory.path,
+                if (entry.isDirectory) f else getParentPath(f) ?: ""
+            )
         } else {
             val artist = fileSystemSafe(entry.artist)
             var album = fileSystemSafe(entry.album)
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/JavaFile.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/JavaFile.kt
index b3cb6e6a..9cfc32a6 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/JavaFile.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/JavaFile.kt
@@ -9,14 +9,14 @@ package org.moire.ultrasonic.util
 
 import android.content.res.AssetFileDescriptor
 import androidx.documentfile.provider.DocumentFile
-import org.moire.ultrasonic.app.UApp
 import java.io.File
 import java.io.FileInputStream
 import java.io.FileOutputStream
 import java.io.InputStream
 import java.io.OutputStream
+import org.moire.ultrasonic.app.UApp
 
-class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile() {
+class JavaFile(override val parent: AbstractFile?, val file: File) : AbstractFile() {
     override val name: String = file.name
     override val isDirectory: Boolean = file.isDirectory
     override val isFile: Boolean = file.isFile
@@ -33,7 +33,7 @@ class JavaFile(override val parent: AbstractFile?, val file: File): AbstractFile
 
     override fun listFiles(): Array<AbstractFile> {
         val fileList = file.listFiles()
-        return fileList?.map { file ->  JavaFile(this, file) }?.toTypedArray() ?: emptyArray()
+        return fileList?.map { file -> JavaFile(this, file) }?.toTypedArray() ?: emptyArray()
     }
 
     override fun getFileOutputStream(append: Boolean): OutputStream {
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ResettableLazy.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ResettableLazy.kt
index 6159f573..9d77b8d9 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ResettableLazy.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ResettableLazy.kt
@@ -22,4 +22,4 @@ class ResettableLazy<T>(private val initializer: () -> T) {
     fun reset() {
         lazyRef.set(lazy(initializer))
     }
-}
\ No newline at end of file
+}
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt
index 7f1c4158..64c5c4e0 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt
@@ -9,8 +9,8 @@ package org.moire.ultrasonic.util
 
 import android.net.Uri
 import androidx.documentfile.provider.DocumentFile
-import org.moire.ultrasonic.R
 import java.io.File
+import org.moire.ultrasonic.R
 import org.moire.ultrasonic.app.UApp
 import timber.log.Timber
 
@@ -21,7 +21,7 @@ import timber.log.Timber
 object Storage {
 
     val mediaRoot: ResettableLazy<AbstractFile> = ResettableLazy {
-            getRoot()!!
+        getRoot()!!
     }
 
     private fun getRoot(): AbstractFile? {
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/StorageFile.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/StorageFile.kt
index 7bc97643..e3c7159a 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/StorageFile.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/StorageFile.kt
@@ -1,32 +1,54 @@
+/*
+ * StorageFile.kt
+ * Copyright (C) 2009-2021 Ultrasonic developers
+ *
+ * Distributed under terms of the GNU GPLv3 license.
+ */
+
 package org.moire.ultrasonic.util
 
 import android.content.res.AssetFileDescriptor
 import android.net.Uri
 import android.provider.DocumentsContract
 import android.webkit.MimeTypeMap
-import androidx.documentfile.provider.DocumentFile
-import org.moire.ultrasonic.app.UApp
-import timber.log.Timber
 import java.io.IOException
 import java.io.InputStream
 import java.io.OutputStream
 import java.util.concurrent.ConcurrentHashMap
+import org.moire.ultrasonic.app.UApp
+import timber.log.Timber
 
 class StorageFile(
     override val parent: StorageFile?,
     var uri: Uri,
     override val name: String,
     override val isDirectory: Boolean
-): AbstractFile() {
-    private val documentFile: DocumentFile = DocumentFile.fromSingleUri(UApp.applicationContext(), uri)!!
-
+) : AbstractFile() {
     override val isFile: Boolean = !isDirectory
 
     override val length: Long
-        get() = documentFile.length()
+        get() {
+            val resolver = UApp.applicationContext().contentResolver
+            val column = arrayOf(DocumentsContract.Document.COLUMN_SIZE)
+            resolver.query(uri, column, null, null, null)?.use { cursor ->
+                if (cursor.moveToFirst()) {
+                    return cursor.getLong(0)
+                }
+            }
+            return 0
+        }
 
     override val lastModified: Long
-        get() = documentFile.lastModified()
+        get() {
+            val resolver = UApp.applicationContext().contentResolver
+            val column = arrayOf(DocumentsContract.Document.COLUMN_LAST_MODIFIED)
+            resolver.query(uri, column, null, null, null)?.use { cursor ->
+                if (cursor.moveToFirst()) {
+                    return cursor.getLong(0)
+                }
+            }
+            return 0
+        }
 
     override val path: String
         get() {
@@ -94,7 +116,6 @@ class StorageFile(
     }
 
     override fun getFromPath(path: String): StorageFile? {
-
         if (storageFilePathDictionary.containsKey(path))
             return storageFilePathDictionary[path]!!
         if (notExistingPathDictionary.contains(path)) return null
@@ -108,7 +129,7 @@ class StorageFile(
         val fileName = FileUtil.getNameFromPath(path)
         var file: StorageFile? = null
 
-        Timber.v("StorageFile getFromPath path: $path")
+        Timber.v("StorageFile getFromPath listing files on path: $path")
         parent.listFiles().forEach {
             if (it.name == fileName) file = it as StorageFile
             storageFilePathDictionary[it.path] = it as StorageFile
@@ -149,18 +170,28 @@ class StorageFile(
 
     @Synchronized
     override fun rename(pathFrom: AbstractFile, pathTo: String) {
-        val storagePathFrom = pathFrom as StorageFile
-        if (!storagePathFrom.documentFile.exists()) throw IOException("File to rename doesn't exist")
-        Timber.d("Renaming from %s to %s", storagePathFrom.path, pathTo)
+        val fileFrom = pathFrom as StorageFile
+        if (!fileFrom.exists()) throw IOException("File to rename doesn't exist")
+        Timber.d("Renaming from %s to %s", fileFrom.path, pathTo)
 
-        val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!) ?: throw IOException("Destination folder doesn't exist")
+        val parentTo = getFromPath(FileUtil.getParentPath(pathTo)!!)
+            ?: throw IOException("Destination folder doesn't exist")
         val fileTo = getFromParentAndName(parentTo, FileUtil.getNameFromPath(pathTo))
 
-        copyFileContents(storagePathFrom.documentFile, fileTo.documentFile)
-        storagePathFrom.delete()
+        copyFileContents(fileFrom, fileTo)
+        fileFrom.delete()
 
         notExistingPathDictionary.remove(pathTo)
-        storageFilePathDictionary.remove(storagePathFrom.path)
+        storageFilePathDictionary.remove(fileFrom.path)
+    }
+
+    private fun exists(): Boolean {
+        val resolver = UApp.applicationContext().contentResolver
+        val column = arrayOf(DocumentsContract.Document.COLUMN_DISPLAY_NAME)
+        resolver.query(uri, column, null, null, null)?.use { cursor ->
+            if (cursor.count != 0) return true
+        }
+        return false
     }
 
     private fun getChildren(): List<StorageFile> {
@@ -209,9 +240,9 @@ class StorageFile(
             DocumentsContract.Document.COLUMN_MIME_TYPE
         )
 
-        private fun copyFileContents(sourceFile: DocumentFile, destinationFile: DocumentFile) {
-            UApp.applicationContext().contentResolver.openInputStream(sourceFile.uri)?.use { inputStream ->
-                UApp.applicationContext().contentResolver.openOutputStream(destinationFile.uri)?.use { outputStream ->
+        private fun copyFileContents(sourceFile: AbstractFile, destinationFile: AbstractFile) {
+            sourceFile.getFileInputStream().use { inputStream ->
+                destinationFile.getFileOutputStream(false).use { outputStream ->
                     inputStream.copyInto(outputStream)
                 }
             }
@@ -238,9 +269,7 @@ class StorageFile(
                 return storageFilePathDictionary[parentPath]!!
             if (notExistingPathDictionary.contains(parentPath)) return null
 
-            val start = System.currentTimeMillis()
             val parent = findStorageFileForParentDirectory(parentPath)
-            val end = System.currentTimeMillis()
 
             if (parent == null) {
                 storageFilePathDictionary.remove(parentPath)
@@ -253,6 +282,7 @@ class StorageFile(
             return parent
         }
 
+        @Suppress("NestedBlockDepth")
         private fun findStorageFileForParentDirectory(path: String): StorageFile? {
             val segments = getUriSegments(path)
                 ?: throw IOException("Can't get path because the root has changed")
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/UncaughtExceptionHandler.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/UncaughtExceptionHandler.kt
index dd06f788..b6315d5e 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/UncaughtExceptionHandler.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/UncaughtExceptionHandler.kt
@@ -2,10 +2,10 @@ package org.moire.ultrasonic.util
 
 import android.content.Context
 import android.os.Build
+import java.io.File
 import java.io.PrintWriter
 import org.moire.ultrasonic.util.Util.safeClose
 import timber.log.Timber
-import java.io.File
 
 /**
  * Logs the stack trace of uncaught exceptions to a file on the SD card.
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt
index 7a6592ac..9df82e61 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt
@@ -52,7 +52,6 @@ import kotlin.math.max
 import kotlin.math.min
 import kotlin.math.roundToInt
 import org.moire.ultrasonic.R
-import org.moire.ultrasonic.app.UApp
 import org.moire.ultrasonic.app.UApp.Companion.applicationContext
 import org.moire.ultrasonic.domain.Bookmark
 import org.moire.ultrasonic.domain.MusicDirectory
@@ -757,7 +756,8 @@ object Util {
         // TODO this doesn't work for URIs
         MediaScannerConnection.scanFile(
             applicationContext(), arrayOf(file),
-            null, null)
+            null, null
+        )
     }
 
     fun getResourceFromAttribute(context: Context, resId: Int): Int {
diff --git a/ultrasonic/src/main/res/layout/list_header_folder.xml b/ultrasonic/src/main/res/layout/list_header_folder.xml
index 6eefae31..3e245f43 100644
--- a/ultrasonic/src/main/res/layout/list_header_folder.xml
+++ b/ultrasonic/src/main/res/layout/list_header_folder.xml
@@ -16,6 +16,7 @@
         a:layout_width="wrap_content"
         a:layout_height="wrap_content"
         a:layout_gravity="center_vertical"
+        a:contentDescription="@null"
         a:src="?attr/select_folder" />
 
     <LinearLayout
diff --git a/ultrasonic/src/main/res/values-cs/strings.xml b/ultrasonic/src/main/res/values-cs/strings.xml
index a120386b..d4819465 100644
--- a/ultrasonic/src/main/res/values-cs/strings.xml
+++ b/ultrasonic/src/main/res/values-cs/strings.xml
@@ -348,7 +348,6 @@
     <string name="share_default_greeting">Mrkni na hudbu sdílenou z %s</string>
     <string name="share_via">Sdílet skladby přes</string>
     <string name="menu.share">Sdílení</string>
-    <string name="select_album_all_songs">Všechny skladby od %s</string>
     <string name="settings.show_all_songs_by_artist">Zobrazit všechny skladby umělce</string>
     <string name="settings.show_all_songs_by_artist_summary">Přidat nový zápis v náhledu umělců pro přístup ke všem skladbám umělce</string>
     <string name="download.menu_show_artist">Zobrazit umělce</string>
diff --git a/ultrasonic/src/main/res/values-de/strings.xml b/ultrasonic/src/main/res/values-de/strings.xml
index 878f130d..03b7b4a1 100644
--- a/ultrasonic/src/main/res/values-de/strings.xml
+++ b/ultrasonic/src/main/res/values-de/strings.xml
@@ -343,7 +343,6 @@
     <string name="share_default_greeting">Hör dir mal die Musik an, die ich mit dir über %s geteilt habe.</string>
     <string name="share_via">Titel teilen über</string>
     <string name="menu.share">Freigabe</string>
-    <string name="select_album_all_songs">Alle Titel von %s</string>
     <string name="settings.show_all_songs_by_artist">Alle Titel nach Künstler sortieren</string>
     <string name="settings.show_all_songs_by_artist_summary">Einen neuen Eintrag in der Künstleransicht hinzufügen, um auf alle Lieder eines Künstlers zuzugreifen</string>
     <string name="download.menu_show_artist">Künstler zeigen</string>
diff --git a/ultrasonic/src/main/res/values-es/strings.xml b/ultrasonic/src/main/res/values-es/strings.xml
index d0d77262..75ef533d 100644
--- a/ultrasonic/src/main/res/values-es/strings.xml
+++ b/ultrasonic/src/main/res/values-es/strings.xml
@@ -371,7 +371,6 @@
     <string name="share_default_greeting">Echa un vistazo a esta música que te comparto desde %s</string>
     <string name="share_via">Compartir canciones vía</string>
     <string name="menu.share">Compartir</string>
-    <string name="select_album_all_songs">Todas las canciones por %s</string>
     <string name="settings.show_all_songs_by_artist">Mostrar todas las canciones por artista</string>
     <string name="settings.show_all_songs_by_artist_summary">Añadir nueva entrada en la vista de artista para acceder a todas las canciones de un artista</string>
     <string name="download.menu_show_artist">Mostrar artista</string>
diff --git a/ultrasonic/src/main/res/values-fr/strings.xml b/ultrasonic/src/main/res/values-fr/strings.xml
index fa8c6a49..d59744f2 100644
--- a/ultrasonic/src/main/res/values-fr/strings.xml
+++ b/ultrasonic/src/main/res/values-fr/strings.xml
@@ -362,7 +362,6 @@
     <string name="share_default_greeting">Regardez cette musique que j\'ai partagée depuis %s</string>
     <string name="share_via">Partager des titres via</string>
     <string name="menu.share">Partager</string>
-    <string name="select_album_all_songs">Tous les titres de %s</string>
     <string name="settings.show_all_songs_by_artist">Voir tous les titres par artiste</string>
     <string name="settings.show_all_songs_by_artist_summary">Ajouter une nouvelle entrée dans la vue artiste pour accéder à toutes les titres d\'un artiste</string>
     <string name="download.menu_show_artist">Afficher l\'artiste</string>
diff --git a/ultrasonic/src/main/res/values-hu/strings.xml b/ultrasonic/src/main/res/values-hu/strings.xml
index 2bf172ba..d8f35055 100644
--- a/ultrasonic/src/main/res/values-hu/strings.xml
+++ b/ultrasonic/src/main/res/values-hu/strings.xml
@@ -360,7 +360,6 @@
     <string name="share_default_greeting">Hallgasd meg ezt a zenét, megosztottam innen: %s</string>
     <string name="share_via">Dalok megosztása ezzel</string>
     <string name="menu.share">Megosztás</string>
-    <string name="select_album_all_songs">%s minden dala</string>
     <string name="settings.show_all_songs_by_artist">Az előadó összes dalának megjelenítése</string>
     <string name="settings.show_all_songs_by_artist_summary">Új bejegyzés hozzáadása az előadóhoz, az előadó összes dalának eléréséhez.</string>
     <string name="download.menu_show_artist">Ugrás az előadóhoz</string>
diff --git a/ultrasonic/src/main/res/values-nl/strings.xml b/ultrasonic/src/main/res/values-nl/strings.xml
index 9b55a8f9..5478b41b 100644
--- a/ultrasonic/src/main/res/values-nl/strings.xml
+++ b/ultrasonic/src/main/res/values-nl/strings.xml
@@ -371,7 +371,6 @@
     <string name="share_default_greeting">Hé, luister eens naar de muziek die ik heb gedeeld via %s</string>
     <string name="share_via">Nummers delen via</string>
     <string name="menu.share">Delen</string>
-    <string name="select_album_all_songs">Alle nummers van %s</string>
     <string name="settings.show_all_songs_by_artist">Alle nummers van artiest tonen</string>
     <string name="settings.show_all_songs_by_artist_summary">Item toevoegen in artiestweergave om alle nummers van een artiest te bekijken</string>
     <string name="download.menu_show_artist">Artiest tonen</string>
diff --git a/ultrasonic/src/main/res/values-pl/strings.xml b/ultrasonic/src/main/res/values-pl/strings.xml
index 7985499f..1651e37e 100644
--- a/ultrasonic/src/main/res/values-pl/strings.xml
+++ b/ultrasonic/src/main/res/values-pl/strings.xml
@@ -343,7 +343,6 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
     <string name="share_default_greeting">Sprawdź muzykę, którą udostępniam na %s</string>
     <string name="share_via">Udostępnij utwory za pomocą</string>
     <string name="menu.share">Udostępnianie</string>
-    <string name="select_album_all_songs">Wszystkie utwory %s</string>
     <string name="settings.show_all_songs_by_artist">Wyświetlaj wszystkie utwory artysty</string>
     <string name="settings.show_all_songs_by_artist_summary">Dodaje nową pozycję w widoku artysty z wszystkimi jego utworami</string>
     <string name="download.menu_show_artist">Wyświetlaj artystę</string>
diff --git a/ultrasonic/src/main/res/values-pt-rBR/strings.xml b/ultrasonic/src/main/res/values-pt-rBR/strings.xml
index 97fdd7b8..781e6ec3 100644
--- a/ultrasonic/src/main/res/values-pt-rBR/strings.xml
+++ b/ultrasonic/src/main/res/values-pt-rBR/strings.xml
@@ -364,7 +364,6 @@
     <string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
     <string name="share_via">Compartilhar músicas via</string>
     <string name="menu.share">Compartilhar</string>
-    <string name="select_album_all_songs">Todas as Músicas de %s</string>
     <string name="settings.show_all_songs_by_artist">Mostrar Todas as Músicas por Artista</string>
     <string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para acessar todas as músicas do artista</string>
     <string name="download.menu_show_artist">Mostrar Artista</string>
diff --git a/ultrasonic/src/main/res/values-pt/strings.xml b/ultrasonic/src/main/res/values-pt/strings.xml
index 13217978..21d56dae 100644
--- a/ultrasonic/src/main/res/values-pt/strings.xml
+++ b/ultrasonic/src/main/res/values-pt/strings.xml
@@ -343,7 +343,6 @@
     <string name="share_default_greeting">Confira esta música que compartilhei do %s</string>
     <string name="share_via">Compartilhar músicas via</string>
     <string name="menu.share">Compartilhar</string>
-    <string name="select_album_all_songs">Todas as Músicas de %s</string>
     <string name="settings.show_all_songs_by_artist">Todas as Músicas do Artista</string>
     <string name="settings.show_all_songs_by_artist_summary">Adicionar nova entrada em artista para ver todas as músicas do artista</string>
     <string name="download.menu_show_artist">Mostrar Artista</string>
diff --git a/ultrasonic/src/main/res/values-ru/strings.xml b/ultrasonic/src/main/res/values-ru/strings.xml
index 9533ad00..9be7d70b 100644
--- a/ultrasonic/src/main/res/values-ru/strings.xml
+++ b/ultrasonic/src/main/res/values-ru/strings.xml
@@ -362,7 +362,6 @@
     <string name="share_default_greeting">Проверьте эту музыку, с которой я поделился %s</string>
     <string name="share_via">Поделиться треками через</string>
     <string name="menu.share">Поделиться</string>
-    <string name="select_album_all_songs">Все треки %s</string>
     <string name="settings.show_all_songs_by_artist">Показать все треки исполнителя</string>
     <string name="settings.show_all_songs_by_artist_summary">Добавить новую запись в представлении исполнителя, чтобы получить доступ ко всем песням для исполнителя</string>
     <string name="download.menu_show_artist">Показать исполнителей</string>
diff --git a/ultrasonic/src/main/res/values-zh-rCN/strings.xml b/ultrasonic/src/main/res/values-zh-rCN/strings.xml
index 024a18fd..7e4a1e04 100644
--- a/ultrasonic/src/main/res/values-zh-rCN/strings.xml
+++ b/ultrasonic/src/main/res/values-zh-rCN/strings.xml
@@ -360,7 +360,6 @@
     <string name="share_default_greeting">看看我从 %s 分享的这首音乐</string>
     <string name="share_via">分享歌曲通过</string>
     <string name="menu.share">分享</string>
-    <string name="select_album_all_songs">%s 的所有歌曲</string>
     <string name="settings.show_all_songs_by_artist">按艺术家显示所有歌曲</string>
     <string name="settings.show_all_songs_by_artist_summary">在艺术家视图中添加新条目以访问艺术家的所有歌曲</string>
     <string name="download.menu_show_artist">显示艺术家</string>
diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml
index 15b21c89..cb9e5c31 100644
--- a/ultrasonic/src/main/res/values/strings.xml
+++ b/ultrasonic/src/main/res/values/strings.xml
@@ -379,7 +379,6 @@
     <string name="share_default_greeting">Check out this music I shared from %s</string>
     <string name="share_via">Share songs via</string>
     <string name="menu.share">Share</string>
-    <string name="select_album_all_songs">All Songs by %s</string>
     <string name="settings.show_all_songs_by_artist">Show All Songs By Artist</string>
     <string name="settings.show_all_songs_by_artist_summary">Add new entry in artist view to access all songs for an artist</string>
     <string name="download.menu_show_artist">Show Artist</string>