From a0da791b284ea7657bf5449b908b3cdb14ad32c5 Mon Sep 17 00:00:00 2001 From: tzugen Date: Sat, 18 Dec 2021 14:33:04 +0100 Subject: [PATCH] Minor fixes --- .../ultrasonic/adapters/TrackViewHolder.kt | 2 +- .../ultrasonic/fragment/SettingsFragment.kt | 4 ++ .../moire/ultrasonic/service/DownloadFile.kt | 30 ++++++------- .../ultrasonic/service/LocalMediaPlayer.kt | 16 +++---- .../org/moire/ultrasonic/util/CacheCleaner.kt | 19 ++++---- .../org/moire/ultrasonic/util/FileUtil.kt | 45 ++++--------------- .../org/moire/ultrasonic/util/Storage.kt | 9 ++++ .../main/res/layout/list_header_folder.xml | 2 +- ultrasonic/src/main/res/values-it/strings.xml | 2 +- ultrasonic/src/main/res/values/strings.xml | 2 +- 10 files changed, 57 insertions(+), 74 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/TrackViewHolder.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/TrackViewHolder.kt index bc1082fc..6c58d85a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/TrackViewHolder.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/TrackViewHolder.kt @@ -221,7 +221,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable progress.text = null } DownloadStatus.FAILED, - DownloadStatus.ABORTED -> { + DownloadStatus.CANCELLED -> { statusImage = imageHelper.errorImage progress.text = null } 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 462667b1..5603aa82 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt @@ -167,6 +167,10 @@ class SettingsFragment : update() } + /** + * This function will be called when we return from the file picker + * with a new custom cache location + */ override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { if ( requestCode != SELECT_CACHE_ACTIVITY || 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 ca9517c5..e6ca67ce 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt @@ -167,9 +167,9 @@ class DownloadFile( fun delete() { cancelDownload() - FileUtil.delete(partialFile) - FileUtil.delete(completeFile) - FileUtil.delete(saveFile) + Storage.delete(partialFile) + Storage.delete(completeFile) + Storage.delete(saveFile) status.postValue(DownloadStatus.IDLE) @@ -185,11 +185,11 @@ class DownloadFile( fun cleanup(): Boolean { var ok = true if (Storage.isPathExists(completeFile) || Storage.isPathExists(saveFile)) { - ok = FileUtil.delete(partialFile) + ok = Storage.delete(partialFile) } if (Storage.isPathExists(saveFile)) { - ok = ok and FileUtil.delete(completeFile) + ok = ok and Storage.delete(completeFile) } return ok @@ -204,14 +204,14 @@ class DownloadFile( private fun doPendingRename() { try { if (saveWhenDone) { - FileUtil.renameFile(completeFile, saveFile) + Storage.rename(completeFile, saveFile) saveWhenDone = false } else if (completeWhenDone) { if (shouldSave) { - FileUtil.renameFile(partialFile, saveFile) + Storage.rename(partialFile, saveFile) Util.scanMedia(saveFile) } else { - FileUtil.renameFile(partialFile, completeFile) + Storage.rename(partialFile, completeFile) } completeWhenDone = false } @@ -245,7 +245,7 @@ class DownloadFile( if (isPlaying) { saveWhenDone = true } else { - FileUtil.renameFile(completeFile, saveFile) + Storage.rename(completeFile, saveFile) newStatus = DownloadStatus.PINNED } } else { @@ -292,7 +292,7 @@ class DownloadFile( outputStream.close() if (isCancelled) { - status.postValue(DownloadStatus.ABORTED) + status.postValue(DownloadStatus.CANCELLED) throw Exception(String.format("Download of '%s' was cancelled", song)) } @@ -307,18 +307,18 @@ class DownloadFile( completeWhenDone = true } else { if (shouldSave) { - FileUtil.renameFile(partialFile, saveFile) + Storage.rename(partialFile, saveFile) status.postValue(DownloadStatus.PINNED) Util.scanMedia(saveFile) } else { - FileUtil.renameFile(partialFile, completeFile) + Storage.rename(partialFile, completeFile) status.postValue(DownloadStatus.DONE) } } } catch (all: Exception) { outputStream.safeClose() - FileUtil.delete(completeFile) - FileUtil.delete(saveFile) + Storage.delete(completeFile) + Storage.delete(saveFile) if (!isCancelled) { isFailed = true if (retryCount > 1) { @@ -412,5 +412,5 @@ class DownloadFile( } enum class DownloadStatus { - IDLE, DOWNLOADING, RETRYING, FAILED, ABORTED, DONE, PINNED, UNKNOWN + IDLE, DOWNLOADING, RETRYING, FAILED, CANCELLED, DONE, PINNED, UNKNOWN } 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 cb55c50f..6c0d96b2 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/LocalMediaPlayer.kt @@ -356,7 +356,7 @@ class LocalMediaPlayer : KoinComponent { setAudioAttributes(mediaPlayer) - var dataSource: String? = null + var streamUrl: String? = null if (partial) { if (proxy == null) { proxy = StreamProxy(object : Supplier() { @@ -366,11 +366,11 @@ class LocalMediaPlayer : KoinComponent { }) proxy!!.start() } - dataSource = String.format( + streamUrl = String.format( Locale.getDefault(), "http://127.0.0.1:%d/%s", proxy!!.port, URLEncoder.encode(file!!.path, Constants.UTF_8) ) - Timber.i("Data Source: %s", dataSource) + Timber.i("Data Source: %s", streamUrl) } else if (proxy != null) { proxy?.stop() proxy = null @@ -378,12 +378,12 @@ class LocalMediaPlayer : KoinComponent { Timber.i("Preparing media player") - if (dataSource != null) { - Timber.v("LocalMediaPlayer doPlay dataSource: %s", dataSource) - mediaPlayer.setDataSource(dataSource) + if (streamUrl != null) { + Timber.v("LocalMediaPlayer doPlay dataSource: %s", streamUrl) + mediaPlayer.setDataSource(streamUrl) } else { Timber.v("LocalMediaPlayer doPlay Path: %s", file!!.path) - val descriptor = file!!.getDocumentFileDescriptor("r")!! + val descriptor = file.getDocumentFileDescriptor("r")!! mediaPlayer.setDataSource(descriptor.fileDescriptor) descriptor.close() } @@ -468,7 +468,7 @@ class LocalMediaPlayer : KoinComponent { } Timber.v("LocalMediaPlayer setupNext Path: %s", file!!.path) - val descriptor = file!!.getDocumentFileDescriptor("r")!! + val descriptor = file.getDocumentFileDescriptor("r")!! nextMediaPlayer!!.setDataSource(descriptor.fileDescriptor) descriptor.close() 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 84e15810..9990ca7c 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.Storage.delete import org.moire.ultrasonic.util.Util.formatBytes import timber.log.Timber @@ -144,7 +144,7 @@ class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) { // No songs left in the folder if (children.size == 1 && children[0].path == getAlbumArtFile(dir.path)) { // Delete Artwork files - delete(getAlbumArtFile(dir.path)) + delete(children[0].path) children = dir.listFiles() } @@ -166,17 +166,14 @@ class CacheCleaner : CoroutineScope by CoroutineScope(Dispatchers.IO) { } // Ensure that file system is not more than 95% full. - val bytesUsedFs: Long - val minFsAvailability: Long - val bytesTotalFs: Long - val bytesAvailableFs: Long - val descriptor = files[0].getDocumentFileDescriptor("r")!! val stat = Os.fstatvfs(descriptor.fileDescriptor) - bytesTotalFs = stat.f_blocks * stat.f_bsize - bytesAvailableFs = stat.f_bfree * stat.f_bsize - bytesUsedFs = bytesTotalFs - bytesAvailableFs - minFsAvailability = bytesTotalFs - MIN_FREE_SPACE + + val bytesTotalFs: Long = stat.f_blocks * stat.f_bsize + val bytesAvailableFs: Long = stat.f_bfree * stat.f_bsize + val bytesUsedFs: Long = bytesTotalFs - bytesAvailableFs + val minFsAvailability: Long = bytesTotalFs - MIN_FREE_SPACE + descriptor.close() val bytesToDeleteCacheLimit = (bytesUsedBySubsonic - cacheSizeBytes).coerceAtLeast(0L) 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 54bedf93..b301135e 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/FileUtil.kt @@ -30,6 +30,10 @@ import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.util.Util.safeClose import timber.log.Timber +/** + * Provides Ultrasonic specific functions for managing the library files. + * Base storage functions like rename, create, delete should be handled in Storage.kt + */ @Suppress("TooManyFunctions") object FileUtil { @@ -89,6 +93,10 @@ object FileUtil { return playlistDir } + /** + * Get the directory where we store local copies of the playlists. + * It is always inside Ultrasonic base directory. + */ @JvmStatic fun getPlaylistDirectory(server: String? = null): File { val playlistDir: File = if (server != null) { @@ -186,7 +194,7 @@ object FileUtil { return albumArtDir } - fun getAlbumDirectory(entry: MusicDirectory.Child): String { + private fun getAlbumDirectory(entry: MusicDirectory.Child): String { val dir: String if (!TextUtils.isEmpty(entry.path) && getParentPath(entry.path!!) != null) { val f = fileSystemSafeDir(entry.path) @@ -318,10 +326,6 @@ object FileUtil { @JvmStatic fun listFiles(dir: AbstractFile): SortedSet { val files = dir.listFiles() - if (files == null) { - Timber.w("Failed to list children for %s", dir.path) - return TreeSet() - } return TreeSet(files.asList()) } @@ -486,35 +490,4 @@ object FileUtil { fw.safeClose() } } - - @JvmStatic - @Throws(IOException::class) - fun renameFile(from: String, to: String) { - Storage.rename(from, to) - } - - @JvmStatic - fun delete(file: File?): Boolean { - if (file != null && file.exists()) { - if (!file.delete()) { - Timber.w("Failed to delete file %s", file) - return false - } - Timber.i("Deleted file %s", file) - } - return true - } - - @JvmStatic - fun delete(file: String?): Boolean { - if (file != null) { - val storageFile = Storage.getFromPath(file) - if (storageFile != null && !storageFile.delete()) { - Timber.w("Failed to delete file %s", file) - return false - } - Timber.i("Deleted file %s", file) - } - return true - } } 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 27c9ea66..3ab71bd3 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Storage.kt @@ -60,6 +60,15 @@ object Storage { mediaRoot.value.rename(pathFrom, pathTo) } + fun delete(path: String): Boolean { + val storageFile = getFromPath(path) + if (storageFile != null && !storageFile.delete()) { + Timber.w("Failed to delete file %s", path) + return false + } + return true + } + private fun getRoot(): AbstractFile? { return if (Settings.cacheLocation.isUri()) { val documentFile = DocumentFile.fromTreeUri( diff --git a/ultrasonic/src/main/res/layout/list_header_folder.xml b/ultrasonic/src/main/res/layout/list_header_folder.xml index 3e245f43..61ae580f 100644 --- a/ultrasonic/src/main/res/layout/list_header_folder.xml +++ b/ultrasonic/src/main/res/layout/list_header_folder.xml @@ -16,7 +16,7 @@ a:layout_width="wrap_content" a:layout_height="wrap_content" a:layout_gravity="center_vertical" - a:contentDescription="@null" + a:importantForAccessibility="no" a:src="?attr/select_folder" /> 1 ora Ordina Canzoni secondo Disco Ordina lista canzoni secondo il numero disco e traccia - Visualizza Bitrate Ed Estensione FileAdapter + Visualizza Bitrate Ed Estensione File Aggiungi nome artista con bitrare ed estensione file Visualizza Download Durante Riproduzione Passa al download quando inizia riproduzione diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index cb9e5c31..1e744543 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -216,7 +216,7 @@ 1 hour Sort Songs By Disc Sort song list by disc number and track number - Display Bitrate and FileAdapter Suffix + Display Bitrate and File Suffix Append artist name with bitrate and file suffix Show Downloads on Play Transition to download activity when starting playback