Check if network access if blocked when fetching notifications (#6247)

* Add `NetworkMonitor.isNetworkBlocked()`, use it to check if Doze prevented us from loading notifications

* Only check if network is blocked after checking if we have a network available, otherwise it's always `true`

* Extract `NetworkBlockedChecker` to handle deprecations more carefully
This commit is contained in:
Jorge Martin Espinosa
2026-02-25 13:04:07 +01:00
committed by GitHub
parent dc11430a73
commit fe4554703c
5 changed files with 72 additions and 14 deletions

View File

@@ -20,4 +20,9 @@ interface NetworkMonitor {
* A flow containing the current network connectivity status.
*/
val connectivity: StateFlow<NetworkStatus>
/**
* Checks if the active network is being blocked by Doze, even if it's available.
*/
fun isNetworkBlocked(): Boolean
}

View File

@@ -43,6 +43,9 @@ class DefaultNetworkMonitor(
appCoroutineScope: CoroutineScope,
) : NetworkMonitor {
private val connectivityManager: ConnectivityManager = context.getSystemService(ConnectivityManager::class.java)
private val blockedNetworkBlockedChecker = NetworkBlockedChecker(connectivityManager)
override fun isNetworkBlocked(): Boolean = blockedNetworkBlockedChecker.isNetworkBlocked()
override val connectivity: StateFlow<NetworkStatus> = callbackFlow {

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
@file:Suppress("DEPRECATION")
package io.element.android.features.networkmonitor.impl
import android.annotation.SuppressLint
import android.net.ConnectivityManager
import android.net.NetworkInfo
/**
* Helper to check if the active network in [ConnectivityManager] is blocked.
*
* This is extracted to its own class because it uses deprecated APIs (but the only ones that are reliable)
* and we don't want to suppress deprecations everywhere.
*/
class NetworkBlockedChecker(
private val connectivityManager: ConnectivityManager,
) {
// The permission is granted by the manifest, false positive
@SuppressLint("MissingPermission")
fun isNetworkBlocked(): Boolean {
// This call is deprecated, but it seems like it's the only reliable way to tell if doze has blocked network access
return connectivityManager.activeNetworkInfo?.detailedState == NetworkInfo.DetailedState.BLOCKED
}
}

View File

@@ -12,6 +12,10 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus
import kotlinx.coroutines.flow.MutableStateFlow
class FakeNetworkMonitor(initialStatus: NetworkStatus = NetworkStatus.Connected) : NetworkMonitor {
class FakeNetworkMonitor(
initialStatus: NetworkStatus = NetworkStatus.Connected,
private val isNetworkBlockedLambda: () -> Boolean = { false },
) : NetworkMonitor {
override val connectivity = MutableStateFlow(initialStatus)
override fun isNetworkBlocked(): Boolean = isNetworkBlockedLambda()
}