Updated custom cache location handling to remove isUri

Fixed DownloadFileCache contained DownloadFiles with old cache path
This commit is contained in:
Nite 2021-12-20 13:15:45 +01:00
parent adf72d6460
commit 17e49ff49e
No known key found for this signature in database
GPG Key ID: 1D1AD59B1C6386C1
5 changed files with 65 additions and 53 deletions

View File

@ -50,7 +50,6 @@ import org.moire.ultrasonic.util.Storage
import org.moire.ultrasonic.util.TimeSpanPreference import org.moire.ultrasonic.util.TimeSpanPreference
import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat import org.moire.ultrasonic.util.TimeSpanPreferenceDialogFragmentCompat
import org.moire.ultrasonic.util.Util.toast import org.moire.ultrasonic.util.Util.toast
import org.moire.ultrasonic.util.isUri
import timber.log.Timber import timber.log.Timber
/** /**
@ -171,31 +170,36 @@ class SettingsFragment :
*/ */
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if ( if (
requestCode != SELECT_CACHE_ACTIVITY || requestCode == SELECT_CACHE_ACTIVITY &&
resultCode != Activity.RESULT_OK || resultCode == Activity.RESULT_OK &&
resultData == null resultData != null
) return ) {
val read = (resultData.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0
val write = (resultData.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
val persist = (resultData.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0
val read = (resultData.flags and Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0 if (read && write && persist) {
val write = (resultData.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0 if (resultData.data != null) {
val persist = (resultData.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0 // The result data contains a URI for the document or directory that
// the user selected.
val uri = resultData.data!!
val contentResolver = UApp.applicationContext().contentResolver
if (!read || !write || !persist) { contentResolver.takePersistableUriPermission(uri, RW_FLAG)
setCacheLocation(uri.toString())
setupCacheLocationPreference()
return
}
}
ErrorDialog.Builder(context) ErrorDialog.Builder(context)
.setMessage(R.string.settings_cache_location_error) .setMessage(R.string.settings_cache_location_error)
.show() .show()
return
} }
// The result data contains a URI for the document or directory that if (Settings.cacheLocationUri == "") {
// the user selected. Settings.customCacheLocation = false
resultData.data?.also { uri -> customCacheLocation?.isChecked = false
// Perform operations on the document using its URI. setupCacheLocationPreference()
val contentResolver = UApp.applicationContext().contentResolver
contentResolver.takePersistableUriPermission(uri, RW_FLAG)
setCacheLocation(uri.toString())
} }
} }
@ -234,7 +238,12 @@ class SettingsFragment :
RxBus.themeChangedEventPublisher.onNext(Unit) RxBus.themeChangedEventPublisher.onNext(Unit)
} }
Constants.PREFERENCES_KEY_CUSTOM_CACHE_LOCATION -> { Constants.PREFERENCES_KEY_CUSTOM_CACHE_LOCATION -> {
setupCacheLocationPreference() if (Settings.customCacheLocation) {
selectCacheLocation()
} else {
if (Settings.cacheLocationUri != "") setCacheLocation("")
setupCacheLocationPreference()
}
} }
} }
} }
@ -259,34 +268,32 @@ class SettingsFragment :
} }
private fun setupCacheLocationPreference() { private fun setupCacheLocationPreference() {
val isDefault = Settings.cacheLocation == defaultMusicDirectory.path
if (!Settings.customCacheLocation) { if (!Settings.customCacheLocation) {
cacheLocation?.isVisible = false cacheLocation?.isVisible = false
if (!isDefault) setCacheLocation(defaultMusicDirectory.path)
return return
} }
cacheLocation?.isVisible = true cacheLocation?.isVisible = true
val uri = Uri.parse(Settings.cacheLocation) val uri = Uri.parse(Settings.cacheLocationUri)
cacheLocation!!.summary = uri.path cacheLocation!!.summary = uri.path
cacheLocation!!.onPreferenceClickListener = cacheLocation!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
Preference.OnPreferenceClickListener { selectCacheLocation()
true
}
}
// Choose a directory using the system's file picker. private fun selectCacheLocation() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) // Choose a directory using the system's file picker.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
if (!isDefault && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Settings.cacheLocationUri != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, defaultMusicDirectory.path) intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, defaultMusicDirectory.path)
} }
intent.addFlags(RW_FLAG) intent.addFlags(RW_FLAG)
intent.addFlags(PERSISTABLE_FLAG) intent.addFlags(PERSISTABLE_FLAG)
startActivityForResult(intent, SELECT_CACHE_ACTIVITY) startActivityForResult(intent, SELECT_CACHE_ACTIVITY)
true
}
} }
private fun setupBluetoothDevicePreferences() { private fun setupBluetoothDevicePreferences() {
@ -393,7 +400,6 @@ class SettingsFragment :
sharingDefaultExpiration!!.summary = sharingDefaultExpiration!!.text sharingDefaultExpiration!!.summary = sharingDefaultExpiration!!.text
sharingDefaultDescription!!.summary = sharingDefaultDescription!!.text sharingDefaultDescription!!.summary = sharingDefaultDescription!!.text
sharingDefaultGreeting!!.summary = sharingDefaultGreeting!!.text sharingDefaultGreeting!!.summary = sharingDefaultGreeting!!.text
cacheLocation!!.summary = Settings.cacheLocation
if (!mediaButtonsEnabled!!.isChecked) { if (!mediaButtonsEnabled!!.isChecked) {
lockScreenEnabled!!.isChecked = false lockScreenEnabled!!.isChecked = false
lockScreenEnabled!!.isEnabled = false lockScreenEnabled!!.isEnabled = false
@ -438,15 +444,16 @@ class SettingsFragment :
} }
private fun setCacheLocation(path: String) { private fun setCacheLocation(path: String) {
if (path.isUri()) { if (path != "") {
val uri = Uri.parse(path) val uri = Uri.parse(path)
cacheLocation!!.summary = uri.path ?: "" cacheLocation!!.summary = uri.path ?: ""
} }
Settings.cacheLocation = path Settings.cacheLocationUri = path
// Clear download queue. // Clear download queue.
mediaPlayerControllerLazy.value.clear() mediaPlayerControllerLazy.value.clear()
mediaPlayerControllerLazy.value.clearCaches()
Storage.reset() Storage.reset()
} }

View File

@ -44,6 +44,7 @@ class Downloader(
private val jukeboxMediaPlayer: JukeboxMediaPlayer by inject() private val jukeboxMediaPlayer: JukeboxMediaPlayer by inject()
// TODO is this cache necessary?
private val downloadFileCache = LRUCache<MusicDirectory.Entry, DownloadFile>(100) private val downloadFileCache = LRUCache<MusicDirectory.Entry, DownloadFile>(100)
private var executorService: ScheduledExecutorService? = null private var executorService: ScheduledExecutorService? = null
@ -281,6 +282,11 @@ class Downloader(
@Synchronized @Synchronized
fun getPlaylist(): List<DownloadFile> = playlist fun getPlaylist(): List<DownloadFile> = playlist
@Synchronized
fun clearDownloadFileCache() {
downloadFileCache.clear()
}
@Synchronized @Synchronized
fun clearPlaylist() { fun clearPlaylist() {
playlist.clear() playlist.clear()

View File

@ -280,6 +280,11 @@ class MediaPlayerController(
jukeboxMediaPlayer.updatePlaylist() jukeboxMediaPlayer.updatePlaylist()
} }
@Synchronized
fun clearCaches() {
downloader.clearDownloadFileCache()
}
@Synchronized @Synchronized
fun clearIncomplete() { fun clearIncomplete() {
reset() reset()

View File

@ -112,9 +112,8 @@ object Settings {
) )
@JvmStatic @JvmStatic
var cacheLocation by StringSetting( var cacheLocationUri by StringSetting(
Constants.PREFERENCES_KEY_CACHE_LOCATION, Constants.PREFERENCES_KEY_CACHE_LOCATION, ""
FileUtil.defaultMusicDirectory.path
) )
@JvmStatic @JvmStatic

View File

@ -31,7 +31,8 @@ object Storage {
Timber.i("StorageFile caches were reset") Timber.i("StorageFile caches were reset")
val root = getRoot() val root = getRoot()
if (root == null) { if (root == null) {
Settings.cacheLocation = FileUtil.defaultMusicDirectory.path Settings.customCacheLocation = false
Settings.cacheLocationUri = ""
Util.toast(UApp.applicationContext(), R.string.settings_cache_location_error) Util.toast(UApp.applicationContext(), R.string.settings_cache_location_error)
} }
} }
@ -70,22 +71,16 @@ object Storage {
} }
private fun getRoot(): AbstractFile? { private fun getRoot(): AbstractFile? {
return if (Settings.cacheLocation.isUri()) { return if (Settings.customCacheLocation) {
val documentFile = DocumentFile.fromTreeUri( val documentFile = DocumentFile.fromTreeUri(
UApp.applicationContext(), UApp.applicationContext(),
Uri.parse(Settings.cacheLocation) Uri.parse(Settings.cacheLocationUri)
) ?: return null ) ?: return null
if (!documentFile.exists()) return null if (!documentFile.exists()) return null
StorageFile(null, documentFile.uri, documentFile.name!!, documentFile.isDirectory) StorageFile(null, documentFile.uri, documentFile.name!!, documentFile.isDirectory)
} else { } else {
val file = File(Settings.cacheLocation) val file = File(FileUtil.defaultMusicDirectory.path)
if (!file.exists()) return null
JavaFile(null, file) JavaFile(null, file)
} }
} }
} }
fun String.isUri(): Boolean {
// TODO is there a better way to tell apart a path and an URI?
return this.contains(':')
}