Skip to content

Commit

Permalink
pause/resume/cancel from notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
alexch33 committed Dec 27, 2024
1 parent b56167b commit e30342f
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 83 deletions.
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@
tools:node="remove" />

<receiver
android:name="com.myAllVideoBrowser.util.downloaders.generic_downloader.NotificationReceiver"
android:name="com.myAllVideoBrowser.util.downloaders.NotificationReceiver"
android:enabled="true" />
<receiver android:name="com.myAllVideoBrowser.util.downloaders.youtubedl_downloader.CancelReceiver" />
</application>

<queries>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import android.app.Application
import android.content.Context
import com.myAllVideoBrowser.DLApplication
import com.myAllVideoBrowser.di.qualifier.ApplicationContext
import com.myAllVideoBrowser.util.downloaders.NotificationReceiver
import com.myAllVideoBrowser.util.scheduler.BaseSchedulers
import com.myAllVideoBrowser.util.scheduler.BaseSchedulersImpl
import dagger.Binds
import dagger.Module
import dagger.android.ContributesAndroidInjector
import javax.inject.Singleton

@Module
Expand All @@ -23,4 +25,7 @@ abstract class AppModule {
@Singleton
@Binds
abstract fun bindBaseSchedulers(baseSchedulers: BaseSchedulersImpl): BaseSchedulers

@ContributesAndroidInjector
abstract fun contributesNotificationReceiver(): NotificationReceiver
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.os.Build
import androidx.core.app.NotificationCompat
import com.myAllVideoBrowser.R
import com.myAllVideoBrowser.ui.main.home.MainActivity
import com.myAllVideoBrowser.util.downloaders.NotificationReceiver
import com.myAllVideoBrowser.util.downloaders.generic_downloader.models.VideoTaskItem
import com.myAllVideoBrowser.util.downloaders.generic_downloader.models.VideoTaskState
import com.myAllVideoBrowser.util.downloaders.youtubedl_downloader.YoutubeDlDownloaderWorker
Expand Down Expand Up @@ -43,22 +44,30 @@ class NotificationsHelper(private val context: Context) {
VideoTaskState.PREPARE -> {
builder.setSubText("prepare").setProgress(0, 0, true)
builder.setOngoing(false).setSmallIcon(android.R.drawable.stat_sys_download_done)
builder.addAction(createPauseBroadcastMessage(task.mId))
builder.addAction(createCancelBroadcastMessage(task.mId))
}

VideoTaskState.PENDING -> {
builder.setSubText("pending").setProgress(0, 0, true)
builder.setOngoing(false).setSmallIcon(android.R.drawable.stat_sys_download_done)
builder.addAction(createPauseBroadcastMessage(task.mId))
builder.addAction(createCancelBroadcastMessage(task.mId))
}

VideoTaskState.DOWNLOADING -> {
builder.setSubText("downloading...").setProgress(100, taskPercent.toInt(), false)
builder.setOngoing(false).setSmallIcon(android.R.drawable.stat_sys_download)
builder.addAction(createPauseBroadcastMessage(task.mId))
builder.addAction(createCancelBroadcastMessage(task.mId))
}

VideoTaskState.PAUSE -> {
builder.setSubText("pause")
builder.setProgress(100, taskPercent.toInt(), false)
builder.setOngoing(false).setSmallIcon(android.R.drawable.stat_sys_download)
builder.addAction(createResumeBroadcastMessage(task.mId))
builder.addAction(createCancelBroadcastMessage(task.mId))
}

VideoTaskState.SUCCESS -> {
Expand All @@ -82,6 +91,7 @@ class NotificationsHelper(private val context: Context) {
.setProgress(100, taskPercent.toInt(), false)
builder.setOngoing(false).setSmallIcon(android.R.drawable.stat_sys_download_done)
builder.addAction(action)
builder.addAction(createResumeBroadcastMessage(task.mId))
}

VideoTaskState.CANCELED -> {
Expand Down Expand Up @@ -164,8 +174,54 @@ class NotificationsHelper(private val context: Context) {
context, 777, intent, PendingIntent.FLAG_UPDATE_CURRENT
)
}
}

private fun createCancelBroadcastMessage(taskId: String): NotificationCompat.Action {
val intent = Intent(context, NotificationReceiver::class.java)
intent.putExtra(NotificationReceiver.TASK_ID, taskId)
intent.action = NotificationReceiver.ACTION_CANCEL

return NotificationCompat.Action(
android.R.drawable.stat_sys_download_done,
context.resources.getString(R.string.progress_menu_cancel),
createActionIntent(intent, taskId.hashCode())
)
}

private fun createPauseBroadcastMessage(taskId: String): NotificationCompat.Action {
val intent = Intent(context, NotificationReceiver::class.java)
intent.putExtra(NotificationReceiver.TASK_ID, taskId)
intent.action = NotificationReceiver.ACTION_PAUSE

return NotificationCompat.Action(
android.R.drawable.stat_sys_download_done,
context.resources.getString(R.string.progress_menu_pause),
createActionIntent(intent, taskId.hashCode())!!
)
}

private fun createResumeBroadcastMessage(taskId: String): NotificationCompat.Action {
val intent = Intent(context, NotificationReceiver::class.java)
intent.putExtra(NotificationReceiver.TASK_ID, taskId)
intent.action = NotificationReceiver.ACTION_RESUME

return NotificationCompat.Action(
android.R.drawable.stat_sys_download_done,
context.resources.getString(R.string.progress_menu_resume),
createActionIntent(intent, taskId.hashCode())!!
)
}

private fun createActionIntent(actionIntent: Intent, requestCode: Int): PendingIntent? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getBroadcast(
context, requestCode, actionIntent, PendingIntent.FLAG_MUTABLE
)
} else {
PendingIntent.getBroadcast(
context, requestCode, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
}
}

private fun createChannel(appContext: Context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package com.myAllVideoBrowser.util.downloaders

import android.content.Context
import android.content.Intent
import com.myAllVideoBrowser.data.local.room.entity.ProgressInfo
import com.myAllVideoBrowser.data.local.room.entity.VideoInfo
import com.myAllVideoBrowser.data.repository.ProgressRepository
import com.myAllVideoBrowser.util.AppLogger
import com.myAllVideoBrowser.util.downloaders.custom_downloader.CustomRegularDownloader
import com.myAllVideoBrowser.util.downloaders.youtubedl_downloader.YoutubeDlDownloader
import dagger.android.DaggerBroadcastReceiver
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import javax.inject.Inject

class NotificationReceiver : DaggerBroadcastReceiver() {
@Inject
lateinit var progressRepository: ProgressRepository

private val receiverScope = CoroutineScope(Dispatchers.IO + SupervisorJob())

override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)

val taskId = intent.extras?.getString(TASK_ID)
receiverScope.launch {
val progressInfo = progressRepository.getProgressInfos().blockingFirst()
.firstOrNull { it.id == taskId }

AppLogger.d("----------------------------------- $taskId $progressInfo")

if (progressInfo == null) {
return@launch
}

when (intent.action) {
ACTION_PAUSE -> {
handlePause(context, progressInfo)
}

ACTION_RESUME -> {
handleResume(context, progressInfo)
}

ACTION_CANCEL -> {
handleCancel(context, progressInfo)
}

else -> {
AppLogger.d("ACTION NOT SUPPORTED ${intent.action}")
}
}
}
}

private fun handleCancel(context: Context, task: ProgressInfo) {
AppLogger.d("HANDLE CANCEL $task")
when (val downloaderType = getTaskType(task.videoInfo)) {
DOWNLOADER_YOUTUBE_DL -> {
YoutubeDlDownloader.cancelDownload(context, task, true)
progressRepository.deleteProgressInfo(task)
}

DOWNLOADER_REGULAR -> {
CustomRegularDownloader.cancelDownload(context, task, true)
progressRepository.deleteProgressInfo(task)
}

else -> {
AppLogger.d("Unexpected downloader type: $downloaderType")
}
}
}

private fun handleResume(context: Context, task: ProgressInfo) {
AppLogger.d("HANDLE RESUME $task")
when (val downloaderType = getTaskType(task.videoInfo)) {
DOWNLOADER_YOUTUBE_DL -> {
YoutubeDlDownloader.resumeDownload(context, task)
}

DOWNLOADER_REGULAR -> {
CustomRegularDownloader.resumeDownload(context, task)
}

else -> {
AppLogger.d("Unexpected downloader type: $downloaderType")
}
}
}

private fun handlePause(context: Context, task: ProgressInfo) {
AppLogger.d("HANDLE PAUSE $task")
when (val downloaderType = getTaskType(task.videoInfo)) {
DOWNLOADER_YOUTUBE_DL -> {
YoutubeDlDownloader.pauseDownload(context, task)
}

DOWNLOADER_REGULAR -> {
CustomRegularDownloader.pauseDownload(context, task)
}

else -> {
AppLogger.d("Unexpected downloader type: $downloaderType")
}
}
}

private fun getTaskType(videoInfo: VideoInfo): String {
return if (videoInfo.isRegularDownload) {
DOWNLOADER_REGULAR
} else {
DOWNLOADER_YOUTUBE_DL
}
}

companion object {
const val DOWNLOADER_YOUTUBE_DL = "DOWNLOADER_YOUTUBE_DL"
const val DOWNLOADER_REGULAR = "DOWNLOADER_REGULAR"
const val TASK_ID = "TASK_ID"
const val ACTION_PAUSE = "ACTION_PAUSE"
const val ACTION_RESUME = "ACTION_RESUME"
const val ACTION_CANCEL = "ACTION_CANCEL"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package com.myAllVideoBrowser.util.downloaders.generic_downloader.workers

import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.myAllVideoBrowser.data.repository.ProgressRepository
import com.myAllVideoBrowser.util.AppLogger
import com.myAllVideoBrowser.util.FileUtil
import com.myAllVideoBrowser.util.NotificationsHelper
import com.myAllVideoBrowser.util.SharedPrefHelper
import com.myAllVideoBrowser.util.downloaders.generic_downloader.GenericDownloader
import com.myAllVideoBrowser.util.downloaders.generic_downloader.NotificationReceiver
import com.myAllVideoBrowser.util.downloaders.generic_downloader.models.VideoTaskItem
import com.myAllVideoBrowser.util.downloaders.generic_downloader.models.VideoTaskState
import com.myAllVideoBrowser.util.proxy_utils.CustomProxyController
import com.myAllVideoBrowser.util.proxy_utils.OkHttpProxyClient
import io.reactivex.rxjava3.disposables.Disposable
import javax.inject.Inject
import kotlin.coroutines.resume

open class GenericDownloadWorkerWrapper(
appContext: Context, workerParams: WorkerParameters
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.myAllVideoBrowser.util.downloaders.youtubedl_downloader

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Base64
import androidx.work.*
import com.google.gson.Gson
Expand Down Expand Up @@ -69,26 +67,3 @@ object YoutubeDlDownloader : GenericDownloader() {
}
}

class CancelReceiver : BroadcastReceiver() {
companion object {
const val TASK_ID = "taskId"
const val NOTIFICATION_ID = "notificationId"
}

override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null) return

val taskId = intent.getStringExtra(TASK_ID)
val notificationId = intent.getIntExtra(NOTIFICATION_ID, 0)

if (taskId.isNullOrEmpty()) return

YoutubeDlDownloader.cancelDownload(
context!!, ProgressInfo(
id = taskId,
downloadId = taskId.hashCode().toLong(),
videoInfo = VideoInfo(id = taskId)
), false
)
}
}

0 comments on commit e30342f

Please sign in to comment.