funkwhale-app-android/app/src/main/java/audio/funkwhale/ffa/playback/PinService.kt

100 lines
3.2 KiB
Kotlin

package audio.funkwhale.ffa.playback
import android.app.Notification
import android.content.Context
import android.content.Intent
import androidx.core.net.toUri
import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.model.DownloadInfo
import audio.funkwhale.ffa.model.Track
import audio.funkwhale.ffa.utils.*
import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager
import com.google.android.exoplayer2.offline.DownloadRequest
import com.google.android.exoplayer2.offline.DownloadService
import com.google.android.exoplayer2.scheduler.Scheduler
import com.google.android.exoplayer2.ui.DownloadNotificationHelper
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent
import java.util.*
class PinService : DownloadService(AppContext.NOTIFICATION_DOWNLOADS) {
private val scope: CoroutineScope = CoroutineScope(Job() + Main)
private val exoDownloadManager: DownloadManager by KoinJavaComponent.inject(DownloadManager::class.java)
companion object {
fun download(context: Context, track: Track) {
track.bestUpload()?.let { upload ->
val url = mustNormalizeUrl(upload.listen_url)
val data = Gson().toJson(
DownloadInfo(
track.id,
url,
track.title,
track.artist.name,
null
)
).toByteArray()
val request = DownloadRequest.Builder(track.id.toString(), url.toUri())
.setData(data)
.setStreamKeys(Collections.emptyList())
.build()
sendAddDownload(context, PinService::class.java, request, false)
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
buildResumeDownloadsIntent(this, PinService::class.java, true)
scope.launch(Main) {
RequestBus.get().collect { request ->
when (request) {
is Request.GetDownloads -> request.channel?.trySend(Response.Downloads(getDownloads()))?.isSuccess
}
}
}
return super.onStartCommand(intent, flags, startId)
}
override fun getDownloadManager() = exoDownloadManager.apply {
addListener(DownloadListener())
}
override fun getScheduler(): Scheduler? = null
override fun getForegroundNotification(downloads: MutableList<Download>): Notification {
val description =
resources.getQuantityString(R.plurals.downloads_description, downloads.size, downloads.size)
return DownloadNotificationHelper(
this,
AppContext.NOTIFICATION_CHANNEL_DOWNLOADS
).buildProgressNotification(this, R.drawable.downloads, null, description, downloads)
}
private fun getDownloads() = downloadManager.downloadIndex.getDownloads()
inner class DownloadListener : DownloadManager.Listener {
override fun onDownloadChanged(
downloadManager: DownloadManager,
download: Download,
finalException: Exception?
) {
super.onDownloadChanged(downloadManager, download, finalException)
EventBus.send(Event.DownloadChanged(download))
}
}
}