mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-14 12:10:36 +01:00
Reattempt auth connection when network validated status changes.
This commit is contained in:
committed by
Greyson Parrelli
parent
3d39045d1b
commit
2fdb712b38
@@ -44,7 +44,7 @@ class NetworkConnectionListener(private val context: Context, private val onNetw
|
||||
networkCapabilities: NetworkCapabilities,
|
||||
callbackType: String,
|
||||
lastLogs: MutableMap<Network, String>
|
||||
) {
|
||||
): Boolean {
|
||||
val currentLog = buildString {
|
||||
append(callbackType)
|
||||
append(" onCapabilitiesChanged($network, ")
|
||||
@@ -56,7 +56,10 @@ class NetworkConnectionListener(private val context: Context, private val onNetw
|
||||
if (lastLogs[network] != currentLog) {
|
||||
Log.d(TAG, currentLog)
|
||||
lastLogs[network] = currentLog
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private val networkChangedCallback: ConnectivityManager.NetworkCallback = object : ConnectivityManager.NetworkCallback() {
|
||||
@@ -92,7 +95,9 @@ class NetworkConnectionListener(private val context: Context, private val onNetw
|
||||
|
||||
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
super.onCapabilitiesChanged(network, networkCapabilities)
|
||||
logCapabilitiesIfChanged(network, networkCapabilities, "ConnectivityManager.NetworkCallback", lastNetworkCapabilities)
|
||||
if (logCapabilitiesIfChanged(network, networkCapabilities, "ConnectivityManager.NetworkCallback", lastNetworkCapabilities)) {
|
||||
onNetworkLost { !networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package org.thoughtcrime.securesms.messages
|
||||
|
||||
import android.app.Application
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.containsExactly
|
||||
import io.mockk.mockk
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.util.ReflectionHelpers
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(manifest = Config.NONE, application = Application::class, sdk = [31])
|
||||
class NetworkConnectionListenerTest {
|
||||
|
||||
@Test
|
||||
fun `default network capability changes notify listener`() {
|
||||
val unavailableEvents = mutableListOf<Boolean>()
|
||||
val listener = NetworkConnectionListener(
|
||||
context = ApplicationProvider.getApplicationContext(),
|
||||
onNetworkLost = { isNetworkUnavailable -> unavailableEvents += isNetworkUnavailable() },
|
||||
onProxySettingsChanged = {}
|
||||
)
|
||||
val callback = ReflectionHelpers.getField<ConnectivityManager.NetworkCallback>(listener, "networkChangedCallback")
|
||||
val network = mockk<Network>()
|
||||
|
||||
callback.onCapabilitiesChanged(network, capabilities(hasInternet = true, validated = false))
|
||||
callback.onCapabilitiesChanged(network, capabilities(hasInternet = true, validated = false))
|
||||
callback.onCapabilitiesChanged(network, capabilities(hasInternet = true, validated = true))
|
||||
callback.onCapabilitiesChanged(network, capabilities(hasInternet = false, validated = false))
|
||||
|
||||
assertThat(unavailableEvents).containsExactly(false, false, true)
|
||||
}
|
||||
|
||||
private fun capabilities(hasInternet: Boolean, validated: Boolean): NetworkCapabilities {
|
||||
val capabilities = NetworkCapabilities()
|
||||
|
||||
if (hasInternet) {
|
||||
capabilities.addCapabilityReflectively(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
}
|
||||
|
||||
if (validated) {
|
||||
capabilities.addCapabilityReflectively(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
}
|
||||
|
||||
return capabilities
|
||||
}
|
||||
|
||||
private fun NetworkCapabilities.addCapabilityReflectively(capability: Int) {
|
||||
val method = NetworkCapabilities::class.java.getDeclaredMethod("addCapability", Int::class.javaPrimitiveType)
|
||||
method.isAccessible = true
|
||||
method.invoke(this, capability)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -461,7 +461,7 @@ class LibSignalChatConnection(
|
||||
},
|
||||
onFailure = { throwable ->
|
||||
Log.w(TAG, "$name [sendKeepAlive] Failure:", throwable)
|
||||
state.onNext(WebSocketConnectionState.DISCONNECTED)
|
||||
disconnect()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+10
-2
@@ -259,12 +259,13 @@ class LibSignalChatConnectionTest {
|
||||
}
|
||||
|
||||
// Test keepAlive that fails at the transport layer (send() throws),
|
||||
// which transitions from CONNECTED -> DISCONNECTED.
|
||||
// which disconnects the underlying chat connection before transitioning to DISCONNECTED.
|
||||
@Test
|
||||
fun keepAliveConnectionFailure() {
|
||||
val connectionFailure = RuntimeException("Sending keep-alive failed")
|
||||
|
||||
val keepAliveFailureLatch = CountDownLatch(1)
|
||||
disconnectLatch = CountDownLatch(1)
|
||||
|
||||
every { chatConnection.send(any()) } answers {
|
||||
delay {
|
||||
@@ -281,15 +282,22 @@ class LibSignalChatConnectionTest {
|
||||
connection.sendKeepAlive()
|
||||
|
||||
keepAliveFailureLatch.await(100, TimeUnit.MILLISECONDS)
|
||||
disconnectLatch!!.await(100, TimeUnit.MILLISECONDS)
|
||||
observer.awaitCount(3)
|
||||
|
||||
observer.assertNotComplete()
|
||||
observer.assertValues(
|
||||
// We start in the connected state
|
||||
WebSocketConnectionState.CONNECTED,
|
||||
// Disconnects as a result of keep-alive failure
|
||||
// Starts an underlying disconnect as a result of keep-alive failure
|
||||
WebSocketConnectionState.DISCONNECTING,
|
||||
// Disconnects once libsignal confirms the connection was interrupted
|
||||
WebSocketConnectionState.DISCONNECTED
|
||||
)
|
||||
observer.assertNoConsecutiveDuplicates()
|
||||
verify(exactly = 1) {
|
||||
chatConnection.disconnect()
|
||||
}
|
||||
verify(exactly = 0) {
|
||||
healthMonitor.onKeepAliveResponse(any(), any())
|
||||
healthMonitor.onMessageError(any(), any())
|
||||
|
||||
Reference in New Issue
Block a user