mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-14 16:37:16 +03:00
Merge branch 'fixCrashes' into 'develop'
Fix crashes Closes #832 and #823 See merge request ultrasonic/ultrasonic!851
This commit is contained in:
commit
4b35a4bcbf
@ -22,7 +22,6 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -221,8 +220,6 @@ class NavigationActivity : AppCompatActivity() {
|
||||
cachedServerCount = count ?: 0
|
||||
updateNavigationHeaderForServer()
|
||||
}
|
||||
|
||||
onBackPressedDispatcher.addCallback(this, callback)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@ -340,16 +337,13 @@ class NavigationActivity : AppCompatActivity() {
|
||||
setupActionBarWithNavController(navController, appBarConfig)
|
||||
}
|
||||
|
||||
val callback: OnBackPressedCallback = object : OnBackPressedCallback(
|
||||
true
|
||||
) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) {
|
||||
drawerLayout?.closeDrawer(GravityCompat.START)
|
||||
} else {
|
||||
val currentFragment = host!!.childFragmentManager.fragments.last()
|
||||
if (currentFragment is OnBackPressedHandler) currentFragment.onBackPressed()
|
||||
}
|
||||
override fun onBackPressed() {
|
||||
if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) {
|
||||
this.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||
} else {
|
||||
val currentFragment = host!!.childFragmentManager.fragments.last()
|
||||
if (currentFragment is OnBackPressedHandler) currentFragment.onBackPressed()
|
||||
else super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,11 +775,12 @@ class PlayerFragment :
|
||||
Util.toast(context, resources.getString(R.string.download_playlist_saving, playlistName))
|
||||
mediaPlayerController.suggestedPlaylistName = playlistName
|
||||
|
||||
ioScope.launch {
|
||||
// The playlist can be acquired only from the main thread
|
||||
val entries = mediaPlayerController.playlist.map {
|
||||
it.toTrack()
|
||||
}
|
||||
|
||||
val entries = mediaPlayerController.playlist.map {
|
||||
it.toTrack()
|
||||
}
|
||||
ioScope.launch {
|
||||
val musicService = getMusicService()
|
||||
musicService.createPlaylist(null, playlistName, entries)
|
||||
}.invokeOnCompletion {
|
||||
|
@ -266,7 +266,7 @@ class DownloadService : Service(), KoinComponent {
|
||||
return notificationBuilder.build()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Suppress("MagicNumber", "NestedBlockDepth")
|
||||
companion object {
|
||||
|
||||
private var startFuture: SettableFuture<DownloadService>? = null
|
||||
@ -291,7 +291,12 @@ class DownloadService : Service(), KoinComponent {
|
||||
if (save) {
|
||||
tracks.filter { Storage.isPathExists(it.getCompleteFile()) }.forEach { track ->
|
||||
Storage.getFromPath(track.getCompleteFile())?.let {
|
||||
Storage.rename(it, track.getPinnedFile())
|
||||
try {
|
||||
Storage.rename(it, track.getPinnedFile())
|
||||
} catch (ignored: FileAlreadyExistsException) {
|
||||
// Play console has revealed a crash when for some reason both files exist
|
||||
Storage.delete(it.path)
|
||||
}
|
||||
postState(track, DownloadState.PINNED)
|
||||
}
|
||||
}
|
||||
@ -299,7 +304,12 @@ class DownloadService : Service(), KoinComponent {
|
||||
} else {
|
||||
tracks.filter { Storage.isPathExists(it.getPinnedFile()) }.forEach { track ->
|
||||
Storage.getFromPath(track.getPinnedFile())?.let {
|
||||
Storage.rename(it, track.getCompleteFile())
|
||||
try {
|
||||
Storage.rename(it, track.getCompleteFile())
|
||||
} catch (ignored: FileAlreadyExistsException) {
|
||||
// Play console has revealed a crash when for some reason both files exist
|
||||
Storage.delete(it.path)
|
||||
}
|
||||
postState(track, DownloadState.DONE)
|
||||
}
|
||||
}
|
||||
@ -367,7 +377,12 @@ class DownloadService : Service(), KoinComponent {
|
||||
val pinnedFile = track.getPinnedFile()
|
||||
if (!Storage.isPathExists(pinnedFile)) return
|
||||
val file = Storage.getFromPath(track.getPinnedFile()) ?: return
|
||||
Storage.rename(file, track.getCompleteFile())
|
||||
try {
|
||||
Storage.rename(file, track.getCompleteFile())
|
||||
} catch (ignored: FileAlreadyExistsException) {
|
||||
// Play console has revealed a crash when for some reason both files exist
|
||||
Storage.delete(file.path)
|
||||
}
|
||||
postState(track, DownloadState.DONE)
|
||||
}
|
||||
|
||||
|
@ -81,73 +81,66 @@ class DownloadTask(
|
||||
|
||||
stateChangedCallback(item, DownloadState.DOWNLOADING, null)
|
||||
|
||||
// Some devices seem to throw error on partial file which doesn't exist
|
||||
val needsDownloading: Boolean
|
||||
val duration = item.track.duration
|
||||
val fileLength = Storage.getFromPath(item.partialFile)?.length ?: 0
|
||||
|
||||
needsDownloading = (duration == null || duration == 0 || fileLength == 0L)
|
||||
// Attempt partial HTTP GET, appending to the file if it exists.
|
||||
val (inStream, isPartial) = musicService.getDownloadInputStream(
|
||||
item.track, fileLength,
|
||||
Settings.maxBitRate,
|
||||
item.pinned
|
||||
)
|
||||
|
||||
if (needsDownloading) {
|
||||
// Attempt partial HTTP GET, appending to the file if it exists.
|
||||
val (inStream, isPartial) = musicService.getDownloadInputStream(
|
||||
item.track, fileLength,
|
||||
Settings.maxBitRate,
|
||||
item.pinned
|
||||
)
|
||||
inputStream = inStream
|
||||
|
||||
inputStream = inStream
|
||||
if (isPartial) {
|
||||
Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength)
|
||||
}
|
||||
|
||||
if (isPartial) {
|
||||
Timber.i("Executed partial HTTP GET, skipping %d bytes", fileLength)
|
||||
}
|
||||
outputStream = Storage.getOrCreateFileFromPath(item.partialFile)
|
||||
.getFileOutputStream(isPartial)
|
||||
|
||||
outputStream = Storage.getOrCreateFileFromPath(item.partialFile)
|
||||
.getFileOutputStream(isPartial)
|
||||
var lastPostTime: Long = 0
|
||||
val len = inputStream.copyTo(outputStream) { totalBytesCopied ->
|
||||
// Manual throttling to avoid overloading Rx
|
||||
if (SystemClock.elapsedRealtime() - lastPostTime > REFRESH_INTERVAL) {
|
||||
lastPostTime = SystemClock.elapsedRealtime()
|
||||
|
||||
var lastPostTime: Long = 0
|
||||
val len = inputStream.copyTo(outputStream) { totalBytesCopied ->
|
||||
// Manual throttling to avoid overloading Rx
|
||||
if (SystemClock.elapsedRealtime() - lastPostTime > REFRESH_INTERVAL) {
|
||||
lastPostTime = SystemClock.elapsedRealtime()
|
||||
|
||||
// If the file size is unknown we can only provide null as the progress
|
||||
val size = item.track.size ?: 0
|
||||
val progress = if (size <= 0) {
|
||||
null
|
||||
} else {
|
||||
(totalBytesCopied * 100 / (size)).toInt()
|
||||
}
|
||||
|
||||
stateChangedCallback(
|
||||
item,
|
||||
DownloadState.DOWNLOADING,
|
||||
progress
|
||||
)
|
||||
// If the file size is unknown we can only provide null as the progress
|
||||
val size = item.track.size ?: 0
|
||||
val progress = if (size <= 0) {
|
||||
null
|
||||
} else {
|
||||
(totalBytesCopied * 100 / (size)).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
Timber.i("Downloaded %d bytes to %s", len, item.partialFile)
|
||||
|
||||
inputStream.close()
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
|
||||
if (isCancelled) {
|
||||
stateChangedCallback(item, DownloadState.CANCELLED, null)
|
||||
throw RuntimeException(
|
||||
String.format(
|
||||
Locale.ROOT, "Download of '%s' was cancelled",
|
||||
item
|
||||
)
|
||||
stateChangedCallback(
|
||||
item,
|
||||
DownloadState.DOWNLOADING,
|
||||
progress
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
item.track.cacheMetadataAndArtwork()
|
||||
} catch (ignore: Exception) {
|
||||
Timber.w(ignore)
|
||||
}
|
||||
Timber.i("Downloaded %d bytes to %s", len, item.partialFile)
|
||||
|
||||
inputStream.close()
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
|
||||
if (isCancelled) {
|
||||
stateChangedCallback(item, DownloadState.CANCELLED, null)
|
||||
throw RuntimeException(
|
||||
String.format(
|
||||
Locale.ROOT, "Download of '%s' was cancelled",
|
||||
item
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
item.track.cacheMetadataAndArtwork()
|
||||
} catch (ignore: Exception) {
|
||||
Timber.w(ignore)
|
||||
}
|
||||
|
||||
if (item.pinned) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user