Skip to content

Commit

Permalink
fix: avoid duplicate connectivity breadcrumb
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Dec 1, 2021
1 parent d85d6a8 commit 529f320
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import android.net.Network
import android.net.NetworkCapabilities
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.annotation.VisibleForTesting
import com.bugsnag.android.UnknownConnectivity.retrieveNetworkAccessState
import java.util.concurrent.atomic.AtomicBoolean

internal typealias NetworkChangeCallback = (hasConnection: Boolean, networkState: String) -> Unit

Expand Down Expand Up @@ -89,8 +92,10 @@ internal class ConnectivityLegacy(
}
}

private inner class ConnectivityChangeReceiver(private val cb: NetworkChangeCallback?) :
BroadcastReceiver() {
private inner class ConnectivityChangeReceiver(
private val cb: NetworkChangeCallback?
) : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
cb?.invoke(hasNetworkConnection(), retrieveNetworkAccessState())
}
Expand Down Expand Up @@ -122,22 +127,38 @@ internal class ConnectivityApi24(
}
}

private inner class ConnectivityTrackerCallback(private val cb: NetworkChangeCallback?) :
ConnectivityManager.NetworkCallback() {
@VisibleForTesting
internal class ConnectivityTrackerCallback(
private val cb: NetworkChangeCallback?
) : ConnectivityManager.NetworkCallback() {

private val receivedFirstCallback = AtomicBoolean(false)

override fun onUnavailable() {
super.onUnavailable()
cb?.invoke(false, retrieveNetworkAccessState())
invokeNetworkCallback(false)
}

override fun onAvailable(network: Network) {
super.onAvailable(network)
cb?.invoke(true, retrieveNetworkAccessState())
invokeNetworkCallback(true)
}

/**
* Invokes the network callback, as long as the ConnectivityManager callback has been
* triggered at least once before (when setting a NetworkCallback Android always
* invokes the callback with the current network state).
*/
private fun invokeNetworkCallback(hasConnection: Boolean) {
if (receivedFirstCallback.getAndSet(true)) {
cb?.invoke(hasConnection, retrieveNetworkAccessState())
}
}
}
}

/**
* Connectivity used in cases where we cannot access the system ConnectivityManager.
* Connectivity used in cases where we cannot access the system ConnectivityManager.
* We assume that there is some sort of network and do not attempt to report any network changes.
*/
internal object UnknownConnectivity : Connectivity {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION")

package com.bugsnag.android

import android.content.Context
Expand Down Expand Up @@ -31,15 +29,15 @@ class ConnectivityApi24Test {
lateinit var capabilities: NetworkCapabilities

@Test
fun connectivityLegacyHasConnection() {
fun connectivityApi24HasConnection() {
val conn = ConnectivityApi24(cm, null)
assertFalse(conn.hasNetworkConnection())
Mockito.`when`(cm.activeNetwork).thenReturn(info)
assertTrue(conn.hasNetworkConnection())
}

@Test
fun connectivityLegacyNetworkState() {
fun connectivityApi24NetworkState() {
val conn = ConnectivityApi24(cm, null)
Mockito.`when`(cm.activeNetwork).thenReturn(info)

Expand All @@ -50,4 +48,40 @@ class ConnectivityApi24Test {
Mockito.`when`(capabilities.hasTransport(0)).thenReturn(true)
assertEquals("cellular", conn.retrieveNetworkAccessState())
}

@Test
fun connectivityApi24OnAvailable() {
var count = 0
val tracker = ConnectivityApi24.ConnectivityTrackerCallback { _, _ ->
count++
}
assertEquals(0, count)

tracker.onAvailable(info)
assertEquals(0, count)

tracker.onAvailable(info)
assertEquals(1, count)

tracker.onAvailable(info)
assertEquals(2, count)
}

@Test
fun connectivityApi24OnUnvailable() {
var count = 0
val tracker = ConnectivityApi24.ConnectivityTrackerCallback { _, _ ->
count++
}
assertEquals(0, count)

tracker.onUnavailable()
assertEquals(0, count)

tracker.onUnavailable()
assertEquals(1, count)

tracker.onUnavailable()
assertEquals(2, count)
}
}

0 comments on commit 529f320

Please sign in to comment.