Convert DownloadService and BackgroundMode to lifecycle services.

This commit is contained in:
Isira Seneviratne 2023-02-06 07:13:38 +05:30
parent 0173ace37e
commit 5e6d171675
2 changed files with 28 additions and 37 deletions

View File

@ -3,7 +3,6 @@ package com.github.libretube.services
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.Build
@ -13,10 +12,11 @@ import android.os.Looper
import android.util.Log
import android.widget.Toast
import androidx.core.app.ServiceCompat
import androidx.lifecycle.LifecycleService
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.api.JsonHelper
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.Segment
import com.github.libretube.api.obj.SegmentData
import com.github.libretube.api.obj.Streams
import com.github.libretube.constants.BACKGROUND_CHANNEL_ID
@ -37,15 +37,15 @@ import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.PlaybackException
import com.google.android.exoplayer2.Player
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.encodeToString
/**
* Loads the selected videos audio in background mode with a notification area.
*/
class BackgroundMode : Service() {
class BackgroundMode : LifecycleService() {
/**
* VideoId of the video
*/
@ -171,7 +171,7 @@ class BackgroundMode : Service() {
seekToPosition: Long = 0,
keepQueue: Boolean = false
) {
CoroutineScope(Dispatchers.IO).launch {
lifecycleScope.launch(Dispatchers.IO) {
streams = runCatching {
RetrofitInstance.api.getStreams(videoId)
}.getOrNull() ?: return@launch
@ -186,7 +186,7 @@ class BackgroundMode : Service() {
PlayingQueue.updateCurrent(it)
}
handler.post {
withContext(Dispatchers.Main) {
playAudio(seekToPosition)
}
}
@ -292,18 +292,12 @@ class BackgroundMode : Service() {
* Sets the [MediaItem] with the [streams] into the [player]
*/
private fun setMediaItem() {
val streams = streams
streams ?: return
val uri = if (streams!!.audioStreams.orEmpty().isNotEmpty()) {
PlayerHelper.getAudioSource(
this,
streams!!.audioStreams!!
)
} else if (streams!!.hls != null) {
streams!!.hls
} else {
return
}
val uri = if (streams.audioStreams.isNotEmpty()) {
PlayerHelper.getAudioSource(this, streams.audioStreams)
} else streams.hls ?: return
val mediaItem = MediaItem.Builder()
.setUri(uri)
@ -315,7 +309,7 @@ class BackgroundMode : Service() {
* fetch the segments for SponsorBlock
*/
private fun fetchSponsorBlockSegments() {
CoroutineScope(Dispatchers.IO).launch {
lifecycleScope.launch(Dispatchers.IO) {
runCatching {
val categories = PlayerHelper.getSponsorBlockCategories()
if (categories.isEmpty()) return@runCatching
@ -336,7 +330,7 @@ class BackgroundMode : Service() {
if (segmentData == null || segmentData!!.segments.isEmpty()) return
segmentData!!.segments.forEach { segment: Segment ->
segmentData!!.segments.forEach { segment ->
val segmentStart = (segment.segment[0] * 1000f).toLong()
val segmentEnd = (segment.segment[1] * 1000f).toLong()
val currentPosition = player?.currentPosition
@ -399,7 +393,8 @@ class BackgroundMode : Service() {
fun getService(): BackgroundMode = this@BackgroundMode
}
override fun onBind(p0: Intent?): IBinder {
override fun onBind(intent: Intent): IBinder {
super.onBind(intent)
return binder
}

View File

@ -2,7 +2,6 @@ package com.github.libretube.services
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
@ -11,6 +10,8 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.ServiceCompat
import androidx.core.util.set
import androidx.core.util.valueIterator
import androidx.lifecycle.LifecycleService
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.api.CronetHelper
import com.github.libretube.api.RetrofitInstance
@ -40,13 +41,9 @@ import java.io.File
import java.net.HttpURLConnection
import java.net.SocketTimeoutException
import java.net.URL
import java.util.concurrent.Executors
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
@ -59,12 +56,8 @@ import okio.source
/**
* Download service with custom implementation of downloading using [HttpURLConnection].
*/
class DownloadService : Service() {
class DownloadService : LifecycleService() {
private val binder = LocalBinder()
private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
private val jobMain = SupervisorJob()
private val scope = CoroutineScope(dispatcher + jobMain)
private lateinit var notificationManager: NotificationManager
private lateinit var summaryNotificationBuilder: NotificationCompat.Builder
@ -81,6 +74,7 @@ class DownloadService : Service() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
when (intent?.action) {
ACTION_DOWNLOAD_RESUME -> resume(intent.getIntExtra("id", -1))
ACTION_DOWNLOAD_PAUSE -> pause(intent.getIntExtra("id", -1))
@ -94,9 +88,11 @@ class DownloadService : Service() {
val audioQuality = intent.getStringExtra(IntentData.audioQuality)
val subtitleCode = intent.getStringExtra(IntentData.subtitleCode)
scope.launch {
lifecycleScope.launch {
try {
val streams = RetrofitInstance.api.getStreams(videoId)
val streams = withContext(Dispatchers.IO) {
RetrofitInstance.api.getStreams(videoId)
}
val thumbnailTargetFile = getDownloadFile(DownloadHelper.THUMBNAIL_DIR, fileName)
@ -153,7 +149,7 @@ class DownloadService : Service() {
Database.downloadDao().insertDownloadItem(item)
}.toInt()
scope.launch {
lifecycleScope.launch {
downloadFile(item)
}
}
@ -297,7 +293,7 @@ class DownloadService : Service() {
val downloadCount = downloadQueue.valueIterator().asSequence().count { it }
if (downloadCount >= DownloadHelper.getMaxConcurrentDownloads()) {
toastFromMainThread(getString(R.string.concurrent_downloads_limit_reached))
scope.launch {
lifecycleScope.launch {
_downloadFlow.emit(id to DownloadStatus.Paused)
}
return
@ -306,7 +302,7 @@ class DownloadService : Service() {
val downloadItem = awaitQuery {
Database.downloadDao().findDownloadItemById(id)
}
scope.launch {
lifecycleScope.launch {
downloadFile(downloadItem)
}
}
@ -468,9 +464,9 @@ class DownloadService : Service() {
super.onDestroy()
}
override fun onBind(intent: Intent?): IBinder {
val ids = intent?.getIntArrayExtra("ids")
ids?.forEach { id -> resume(id) }
override fun onBind(intent: Intent): IBinder {
super.onBind(intent)
intent.getIntArrayExtra("ids")?.forEach { resume(it) }
return binder
}