mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
Revert "feat(network): enhance connectivity monitoring with request reporting"
This reverts commit 56a2b42434.
This commit is contained in:
@@ -4,8 +4,4 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
|
|
||||||
interface NetworkMonitor {
|
interface NetworkMonitor {
|
||||||
val isOnline: Flow<Boolean>
|
val isOnline: Flow<Boolean>
|
||||||
|
|
||||||
fun reportRequestSucceeded()
|
|
||||||
|
|
||||||
fun reportRequestFailed(error: Throwable)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,54 +7,28 @@ import android.net.NetworkCapabilities
|
|||||||
import android.net.NetworkRequest
|
import android.net.NetworkRequest
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import hu.bbara.purefin.core.data.NetworkMonitor
|
import hu.bbara.purefin.core.data.NetworkMonitor
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.stateIn
|
|
||||||
import java.net.ConnectException
|
|
||||||
import java.net.NoRouteToHostException
|
|
||||||
import java.net.SocketTimeoutException
|
|
||||||
import java.net.UnknownHostException
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class ConnectivityNetworkMonitor @Inject constructor(
|
class ConnectivityNetworkMonitor @Inject constructor(
|
||||||
@param:ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
) : NetworkMonitor {
|
) : NetworkMonitor {
|
||||||
|
|
||||||
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
override val isOnline: Flow<Boolean> = callbackFlow {
|
||||||
private val connectivityManager = context.getSystemService(ConnectivityManager::class.java)
|
val connectivityManager = context.getSystemService(ConnectivityManager::class.java)
|
||||||
private val isServerReachable = MutableStateFlow(true)
|
|
||||||
|
|
||||||
private val isDeviceOnline: Flow<Boolean> = callbackFlow {
|
|
||||||
var wasDeviceOnline = connectivityManager.isCurrentlyConnected()
|
|
||||||
|
|
||||||
val callback = object : ConnectivityManager.NetworkCallback() {
|
val callback = object : ConnectivityManager.NetworkCallback() {
|
||||||
override fun onCapabilitiesChanged(
|
override fun onAvailable(network: Network) {
|
||||||
network: Network,
|
trySend(true)
|
||||||
networkCapabilities: NetworkCapabilities
|
|
||||||
) {
|
|
||||||
val isCurrentlyConnected = connectivityManager.isCurrentlyConnected()
|
|
||||||
if (isCurrentlyConnected && !wasDeviceOnline) {
|
|
||||||
isServerReachable.value = true
|
|
||||||
}
|
|
||||||
wasDeviceOnline = isCurrentlyConnected
|
|
||||||
trySend(isCurrentlyConnected)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
val isCurrentlyConnected = connectivityManager.isCurrentlyConnected()
|
trySend(connectivityManager.isCurrentlyConnected())
|
||||||
wasDeviceOnline = isCurrentlyConnected
|
|
||||||
trySend(isCurrentlyConnected)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,51 +36,14 @@ class ConnectivityNetworkMonitor @Inject constructor(
|
|||||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
trySend(wasDeviceOnline)
|
trySend(connectivityManager.isCurrentlyConnected())
|
||||||
connectivityManager.registerNetworkCallback(request, callback)
|
connectivityManager.registerNetworkCallback(request, callback)
|
||||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||||
}.distinctUntilChanged()
|
}.distinctUntilChanged()
|
||||||
|
|
||||||
override val isOnline: StateFlow<Boolean> = combine(
|
|
||||||
isDeviceOnline,
|
|
||||||
isServerReachable
|
|
||||||
) { isDeviceOnline, isServerReachable ->
|
|
||||||
isDeviceOnline && isServerReachable
|
|
||||||
}.distinctUntilChanged()
|
|
||||||
.stateIn(
|
|
||||||
scope = scope,
|
|
||||||
started = SharingStarted.Eagerly,
|
|
||||||
initialValue = connectivityManager.isCurrentlyConnected() && isServerReachable.value
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun reportRequestSucceeded() {
|
|
||||||
isServerReachable.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reportRequestFailed(error: Throwable) {
|
|
||||||
if (error.isConnectivityFailure()) {
|
|
||||||
isServerReachable.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConnectivityManager.isCurrentlyConnected(): Boolean {
|
private fun ConnectivityManager.isCurrentlyConnected(): Boolean {
|
||||||
val network = activeNetwork ?: return false
|
val network = activeNetwork ?: return false
|
||||||
val caps = getNetworkCapabilities(network) ?: return false
|
val caps = getNetworkCapabilities(network) ?: return false
|
||||||
return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
|
return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Throwable.isConnectivityFailure(): Boolean {
|
|
||||||
var current: Throwable? = this
|
|
||||||
while (current != null) {
|
|
||||||
when (current) {
|
|
||||||
is UnknownHostException,
|
|
||||||
is ConnectException,
|
|
||||||
is NoRouteToHostException,
|
|
||||||
is SocketTimeoutException -> return true
|
|
||||||
}
|
|
||||||
current = current.cause
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.content.Context
|
|||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import hu.bbara.purefin.core.data.JellyfinServerCandidate
|
import hu.bbara.purefin.core.data.JellyfinServerCandidate
|
||||||
import hu.bbara.purefin.core.data.NetworkMonitor
|
|
||||||
import hu.bbara.purefin.core.data.PlaybackMethod
|
import hu.bbara.purefin.core.data.PlaybackMethod
|
||||||
import hu.bbara.purefin.core.data.PlaybackReportContext
|
import hu.bbara.purefin.core.data.PlaybackReportContext
|
||||||
import hu.bbara.purefin.core.data.QuickConnectSession
|
import hu.bbara.purefin.core.data.QuickConnectSession
|
||||||
@@ -65,9 +64,8 @@ import javax.inject.Singleton
|
|||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class JellyfinApiClient @Inject constructor(
|
class JellyfinApiClient @Inject constructor(
|
||||||
@param:ApplicationContext private val applicationContext: Context,
|
@ApplicationContext private val applicationContext: Context,
|
||||||
private val userSessionRepository: UserSessionRepository,
|
private val userSessionRepository: UserSessionRepository,
|
||||||
private val networkMonitor: NetworkMonitor,
|
|
||||||
) {
|
) {
|
||||||
private val jellyfin = createJellyfin {
|
private val jellyfin = createJellyfin {
|
||||||
context = applicationContext
|
context = applicationContext
|
||||||
@@ -585,14 +583,12 @@ class JellyfinApiClient @Inject constructor(
|
|||||||
val startedAt = SystemClock.elapsedRealtime()
|
val startedAt = SystemClock.elapsedRealtime()
|
||||||
return try {
|
return try {
|
||||||
val result = block()
|
val result = block()
|
||||||
networkMonitor.reportRequestSucceeded()
|
|
||||||
val elapsedMs = SystemClock.elapsedRealtime() - startedAt
|
val elapsedMs = SystemClock.elapsedRealtime() - startedAt
|
||||||
Timber.tag(TAG).d("$functionName took ${elapsedMs}ms")
|
Timber.tag(TAG).d("$functionName took ${elapsedMs}ms")
|
||||||
result
|
result
|
||||||
} catch (error: CancellationException) {
|
} catch (error: CancellationException) {
|
||||||
throw error
|
throw error
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
networkMonitor.reportRequestFailed(error)
|
|
||||||
val elapsedMs = SystemClock.elapsedRealtime() - startedAt
|
val elapsedMs = SystemClock.elapsedRealtime() - startedAt
|
||||||
Timber.tag(TAG).e(error, "$functionName failed after ${elapsedMs}ms")
|
Timber.tag(TAG).e(error, "$functionName failed after ${elapsedMs}ms")
|
||||||
throw error
|
throw error
|
||||||
|
|||||||
Reference in New Issue
Block a user