DownloadJob: Network check changes (#10242)
Mostly pulled from WorkManager
This commit is contained in:
parent
387159b5af
commit
f9b57800b1
2 changed files with 101 additions and 19 deletions
|
@ -13,13 +13,17 @@ import androidx.work.WorkManager
|
|||
import androidx.work.WorkerParameters
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
||||
import eu.kanade.tachiyomi.util.system.isOnline
|
||||
import eu.kanade.tachiyomi.util.system.NetworkState
|
||||
import eu.kanade.tachiyomi.util.system.activeNetworkState
|
||||
import eu.kanade.tachiyomi.util.system.networkStateFlow
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import eu.kanade.tachiyomi.util.system.setForegroundSafely
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combineTransform
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import tachiyomi.domain.download.service.DownloadPreferences
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -50,7 +54,11 @@ class DownloadJob(context: Context, workerParams: WorkerParameters) : CoroutineW
|
|||
}
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
var active = checkConnectivity() && downloadManager.downloaderStart()
|
||||
var networkCheck = checkNetworkState(
|
||||
applicationContext.activeNetworkState(),
|
||||
downloadPreferences.downloadOnlyOverWifi().get(),
|
||||
)
|
||||
var active = networkCheck && downloadManager.downloaderStart()
|
||||
|
||||
if (!active) {
|
||||
return Result.failure()
|
||||
|
@ -58,29 +66,36 @@ class DownloadJob(context: Context, workerParams: WorkerParameters) : CoroutineW
|
|||
|
||||
setForegroundSafely()
|
||||
|
||||
coroutineScope {
|
||||
combineTransform(
|
||||
applicationContext.networkStateFlow(),
|
||||
downloadPreferences.downloadOnlyOverWifi().changes(),
|
||||
transform = { a, b -> emit(checkNetworkState(a, b)) },
|
||||
)
|
||||
.onEach { networkCheck = it }
|
||||
.launchIn(this)
|
||||
}
|
||||
|
||||
// Keep the worker running when needed
|
||||
while (active) {
|
||||
delay(100)
|
||||
active = !isStopped && downloadManager.isRunning && checkConnectivity()
|
||||
active = !isStopped && downloadManager.isRunning && networkCheck
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private fun checkConnectivity(): Boolean {
|
||||
return with(applicationContext) {
|
||||
if (isOnline()) {
|
||||
val noWifi = downloadPreferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()
|
||||
if (noWifi) {
|
||||
downloadManager.downloaderStop(
|
||||
applicationContext.getString(R.string.download_notifier_text_only_wifi),
|
||||
)
|
||||
}
|
||||
!noWifi
|
||||
} else {
|
||||
downloadManager.downloaderStop(applicationContext.getString(R.string.download_notifier_no_network))
|
||||
false
|
||||
private fun checkNetworkState(state: NetworkState, requireWifi: Boolean): Boolean {
|
||||
return if (state.isOnline) {
|
||||
val noWifi = requireWifi && !state.isWifi
|
||||
if (noWifi) {
|
||||
downloadManager.downloaderStop(
|
||||
applicationContext.getString(R.string.download_notifier_text_only_wifi),
|
||||
)
|
||||
}
|
||||
!noWifi
|
||||
} else {
|
||||
downloadManager.downloaderStop(applicationContext.getString(R.string.download_notifier_no_network))
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package eu.kanade.tachiyomi.util.system
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
|
||||
data class NetworkState(
|
||||
val isConnected: Boolean,
|
||||
val isValidated: Boolean,
|
||||
val isWifi: Boolean,
|
||||
) {
|
||||
val isOnline = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
isConnected && isValidated
|
||||
} else {
|
||||
isConnected
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun Context.activeNetworkState(): NetworkState {
|
||||
val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
|
||||
return NetworkState(
|
||||
isConnected = connectivityManager.activeNetworkInfo?.isConnected ?: false,
|
||||
isValidated = capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) ?: false,
|
||||
isWifi = wifiManager.isWifiEnabled && capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ?: false,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun Context.networkStateFlow() = callbackFlow {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val networkCallback = object : NetworkCallback() {
|
||||
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
trySend(activeNetworkState())
|
||||
}
|
||||
override fun onLost(network: Network) {
|
||||
trySend(activeNetworkState())
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerDefaultNetworkCallback(networkCallback)
|
||||
awaitClose {
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}
|
||||
} else {
|
||||
val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
|
||||
trySend(activeNetworkState())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
|
||||
awaitClose {
|
||||
unregisterReceiver(receiver)
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue