diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt index be998a37289e..59357d052742 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt +++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt @@ -168,7 +168,7 @@ class ConnectScreenTest { ) // Assert - onNodeWithText("DISCONNECTED").assertExists() + onNodeWithText("DISCONNECTING...").assertExists() onNodeWithText(mockLocationName).assertExists() onNodeWithText("Disconnect").assertExists() } @@ -310,7 +310,7 @@ class ConnectScreenTest { ) // Assert - onNodeWithText("CONNECTED").assertExists() + onNodeWithText("BLOCKING...").assertExists() onNodeWithText(mockLocationName).assertExists() onNodeWithText("Disconnect").assertExists() onNodeWithText("BLOCKING INTERNET").assertExists() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt index 535dcf2bb825..a5b1cff000e6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt @@ -47,8 +47,8 @@ private fun TunnelState.text() = is TunnelState.Disconnected -> textResource(id = R.string.disconnected) is TunnelState.Disconnecting -> when (actionAfterDisconnect) { - ActionAfterDisconnect.Nothing -> textResource(id = R.string.disconnected) - ActionAfterDisconnect.Block -> textResource(id = R.string.connected) + ActionAfterDisconnect.Nothing -> textResource(id = R.string.disconnecting) + ActionAfterDisconnect.Block -> textResource(id = R.string.blocking) ActionAfterDisconnect.Reconnect -> textResource(id = R.string.connecting) } is TunnelState.Error -> diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt index 0c885989233e..e0fa1d29b44f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt @@ -5,6 +5,7 @@ package net.mullvad.mullvadvpn.util import kotlinx.coroutines.Deferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow inline fun combine( flow: Flow, @@ -61,3 +62,11 @@ fun Deferred.getOrDefault(default: T) = } catch (e: IllegalStateException) { default } + +fun Flow.withPrev(): Flow> = flow { + var prev: T? = null + collect { curr -> + emit(curr to prev) + prev = curr + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt index 42838d75d625..5fb08bcc4855 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.map @@ -36,6 +35,7 @@ import net.mullvad.mullvadvpn.usecase.SelectedLocationTitleUseCase import net.mullvad.mullvadvpn.util.combine import net.mullvad.mullvadvpn.util.daysFromNow import net.mullvad.mullvadvpn.util.isSuccess +import net.mullvad.mullvadvpn.util.withPrev @Suppress("LongParameterList") class ConnectViewModel( @@ -62,14 +62,14 @@ class ConnectViewModel( combine( selectedLocationTitleUseCase(), inAppNotificationController.notifications, - connectionProxy.tunnelState, + connectionProxy.tunnelState.withPrev(), lastKnownLocationUseCase.lastKnownDisconnectedLocation, accountRepository.accountData, deviceRepository.deviceState.map { it?.displayName() }, ) { selectedRelayItemTitle, notifications, - tunnelState, + (tunnelState, prevTunnelState), lastKnownDisconnectedLocation, accountData, deviceName -> @@ -80,14 +80,22 @@ class ConnectViewModel( tunnelState.location ?: lastKnownDisconnectedLocation is TunnelState.Connecting -> tunnelState.location is TunnelState.Connected -> tunnelState.location - is TunnelState.Disconnecting -> lastKnownDisconnectedLocation + is TunnelState.Disconnecting -> + when (tunnelState.actionAfterDisconnect) { + ActionAfterDisconnect.Nothing -> lastKnownDisconnectedLocation + ActionAfterDisconnect.Block -> lastKnownDisconnectedLocation + // Keep the previous connected location when reconnecting, after + // this state we will reach Connecting with the new relay + // location + ActionAfterDisconnect.Reconnect -> prevTunnelState?.location() + } is TunnelState.Error -> lastKnownDisconnectedLocation }, selectedRelayItemTitle = selectedRelayItemTitle, tunnelState = tunnelState, showLocation = when (tunnelState) { - is TunnelState.Disconnected -> true + is TunnelState.Disconnected -> tunnelState.location != null is TunnelState.Disconnecting -> { when (tunnelState.actionAfterDisconnect) { ActionAfterDisconnect.Nothing -> false @@ -105,7 +113,6 @@ class ConnectViewModel( isPlayBuild = isPlayBuild, ) } - .debounce(UI_STATE_DEBOUNCE_DURATION_MILLIS) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), ConnectUiState.INITIAL) init { diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt index 0d61b3e300f8..1dab9a456535 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt @@ -171,12 +171,11 @@ class ConnectViewModelTest { fun `given RelayListUseCase returns new selectedRelayItem uiState should emit new selectedRelayItem`() = runTest { val selectedRelayItemTitle = "Item" - selectedRelayItemFlow.value = selectedRelayItemTitle - viewModel.uiState.test { assertEquals(ConnectUiState.INITIAL, awaitItem()) - val result = awaitItem() - assertEquals(selectedRelayItemTitle, result.selectedRelayItemTitle) + + selectedRelayItemFlow.value = selectedRelayItemTitle + assertEquals(selectedRelayItemTitle, awaitItem().selectedRelayItemTitle) } } @@ -196,7 +195,6 @@ class ConnectViewModelTest { // Act, Assert viewModel.uiState.test { - assertEquals(ConnectUiState.INITIAL, awaitItem()) tunnelState.emit(TunnelState.Disconnected(null)) // Start of with no location @@ -215,12 +213,7 @@ class ConnectViewModelTest { val locationTestItem = null // Act, Assert - viewModel.uiState.test { - assertEquals(ConnectUiState.INITIAL, awaitItem()) - expectNoEvents() - val result = awaitItem() - assertEquals(locationTestItem, result.location) - } + viewModel.uiState.test { assertEquals(locationTestItem, awaitItem().location) } } @Test @@ -278,15 +271,12 @@ class ConnectViewModelTest { val mockErrorState: ErrorState = mockk() val expectedConnectNotificationState = InAppNotification.TunnelStateError(mockErrorState) - val tunnelStateError = TunnelState.Error(mockErrorState) - notifications.value = listOf(expectedConnectNotificationState) // Act, Assert viewModel.uiState.test { assertEquals(ConnectUiState.INITIAL, awaitItem()) - tunnelState.emit(tunnelStateError) - val result = awaitItem() - assertEquals(expectedConnectNotificationState, result.inAppNotification) + notifications.value = listOf(expectedConnectNotificationState) + assertEquals(expectedConnectNotificationState, awaitItem().inAppNotification) } } @@ -315,7 +305,6 @@ class ConnectViewModelTest { viewModel.uiState.test { awaitItem() outOfTimeViewFlow.value = true - awaitItem() } // Assert @@ -328,12 +317,13 @@ class ConnectViewModelTest { // Arrange val tunnel = TunnelState.Error(mockk(relaxed = true)) val lastKnownLocation: GeoIpLocation = mockk(relaxed = true) - lastKnownLocationFlow.emit(lastKnownLocation) - tunnelState.emit(tunnel) // Act, Assert viewModel.uiState.test { assertEquals(ConnectUiState.INITIAL, awaitItem()) + lastKnownLocationFlow.emit(lastKnownLocation) + tunnelState.emit(tunnel) + awaitItem() val result = awaitItem() assertEquals(lastKnownLocation, result.location) } diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt index 3ca573a839ca..4c24c87068d0 100644 --- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt @@ -7,14 +7,14 @@ sealed interface NotificationTunnelState { data object Connected : NotificationTunnelState - data object Reconnecting : NotificationTunnelState + data object Blocking : NotificationTunnelState data object Disconnecting : NotificationTunnelState sealed interface Error : NotificationTunnelState { data object DeviceOffline : Error - data object Blocking : Error + data object Blocked : Error data object VpnPermissionDenied : Error diff --git a/android/lib/resource/src/main/res/values-da/strings.xml b/android/lib/resource/src/main/res/values-da/strings.xml index 28dbb865ed7b..13aaf95f087b 100644 --- a/android/lib/resource/src/main/res/values-da/strings.xml +++ b/android/lib/resource/src/main/res/values-da/strings.xml @@ -287,7 +287,6 @@ Det gør den ved at udføre en ekstra nøgleudveksling ved hjælp af en kvantesikker algoritme og blande resultatet med WireGuards almindelige kryptering. Dette ekstra trin bruger cirka 500 kB trafik, hver gang en ny tunnel etableres. Kvante-modstandsdygtig tunnel Genopret forbindelse - Genopretter forbindelse... Indløs Indløs kupon Fjern diff --git a/android/lib/resource/src/main/res/values-de/strings.xml b/android/lib/resource/src/main/res/values-de/strings.xml index 56e95535ff0b..24001a5e1ee3 100644 --- a/android/lib/resource/src/main/res/values-de/strings.xml +++ b/android/lib/resource/src/main/res/values-de/strings.xml @@ -287,7 +287,6 @@ Dazu wird ein zusätzlicher Schlüsselaustausch mit einem quantensicheren Algorithmus durchgeführt und das Ergebnis mit der regulären Verschlüsselung von WireGuard vermischt. Dieser zusätzliche Schritt verbraucht jedes Mal, wenn ein neuer Tunnel aufgebaut wird, etwa 500 KiB an Datenverkehr. Quantenresistenter Tunnel Erneut verbinden - Wiederherstellen der Verbindung … Einlösen Gutschein einlösen Entfernen diff --git a/android/lib/resource/src/main/res/values-es/strings.xml b/android/lib/resource/src/main/res/values-es/strings.xml index 77d6bf6f0c27..c181585b8e65 100644 --- a/android/lib/resource/src/main/res/values-es/strings.xml +++ b/android/lib/resource/src/main/res/values-es/strings.xml @@ -287,7 +287,6 @@ Lo hace al realizar un intercambio de claves adicional usando un algoritmo cuántico seguro y combinando el resultado en el cifrado normal de WireGuard. Este paso extra utiliza aproximadamente 500 kiB de tráfico cada vez que se establece un nuevo túnel. Túnel con resistencia cuántica Reconectar - Volviendo a establecer la conexión... Canjear Canjear cupón Quitar diff --git a/android/lib/resource/src/main/res/values-fi/strings.xml b/android/lib/resource/src/main/res/values-fi/strings.xml index 0c896026c03c..e61ba4dbb4db 100644 --- a/android/lib/resource/src/main/res/values-fi/strings.xml +++ b/android/lib/resource/src/main/res/values-fi/strings.xml @@ -287,7 +287,6 @@ Tunneli torjuu hyökkäykset suorittamalla ylimääräisen avaimenvaihdon käyttämällä ensin kvanttiturvallista algoritmia, jonka tuloksen se sekoittaa WireGuardin tavalliseen salaukseen. Tämä ylimääräinen vaihe käyttää noin 500 kiB liikennettä joka kerta, kun uusi tunneli luodaan. Kvanttihyökkäyksiä kestävä tunneli Yhdistä uudelleen - Yhdistetään uudelleen... Lunasta Lunasta kuponki Poista diff --git a/android/lib/resource/src/main/res/values-fr/strings.xml b/android/lib/resource/src/main/res/values-fr/strings.xml index b41118246624..57c276a287f2 100644 --- a/android/lib/resource/src/main/res/values-fr/strings.xml +++ b/android/lib/resource/src/main/res/values-fr/strings.xml @@ -287,7 +287,6 @@ Pour ce faire, il effectue un échange de clés supplémentaire à l\'aide d\'un algorithme à sécurité quantique et mélange le résultat au chiffrement habituel de WireGuard. Cette étape supplémentaire utilise environ 500 kiB de trafic chaque fois qu\'un nouveau tunnel est établi. Tunnel résistant aux attaques quantiques Reconnexion - Reconnexion en cours... Échanger Échanger un bon Supprimer diff --git a/android/lib/resource/src/main/res/values-it/strings.xml b/android/lib/resource/src/main/res/values-it/strings.xml index 68506035c1ae..85d399b3f72b 100644 --- a/android/lib/resource/src/main/res/values-it/strings.xml +++ b/android/lib/resource/src/main/res/values-it/strings.xml @@ -287,7 +287,6 @@ L\'operazione viene effettuata eseguendo uno scambio di chiavi aggiuntivo con un algoritmo di sicurezza quantistica e mescolando il risultato nella normale crittografia di WireGuard. Questo passaggio aggiuntivo utilizza circa 500 kiB di traffico ogni volta che viene stabilito un nuovo tunnel. Tunnel resistente agli attacchi quantistici Riconnetti - Riconnessione... Riscatta Riscatta voucher Rimuovi diff --git a/android/lib/resource/src/main/res/values-ja/strings.xml b/android/lib/resource/src/main/res/values-ja/strings.xml index c9d076909f15..e3922b12e982 100644 --- a/android/lib/resource/src/main/res/values-ja/strings.xml +++ b/android/lib/resource/src/main/res/values-ja/strings.xml @@ -287,7 +287,6 @@ 耐量子アルゴリズムで追加の鍵の交換を実行し、結果をWireGuardの通常の暗号化に混合させることで行われます。この追加ステップでは、新しいトンネルが確立されるたびに約500kiBのトラフィックが使用されます。 耐量子トンネル 再接続 - 再接続中… 使用する バウチャーを使用する 削除 diff --git a/android/lib/resource/src/main/res/values-ko/strings.xml b/android/lib/resource/src/main/res/values-ko/strings.xml index 694fdf634bc6..09f899d08365 100644 --- a/android/lib/resource/src/main/res/values-ko/strings.xml +++ b/android/lib/resource/src/main/res/values-ko/strings.xml @@ -287,7 +287,6 @@ 이를 위해 양자 안전 알고리즘을 사용하여 추가 키 교환을 수행하고 결과를 WireGuard의 일반 암호화에 혼합하는 방법이 이용됩니다. 이 추가 단계는 새 터널이 설정될 때마다 약 500kiB의 트래픽을 사용합니다. 양자 저항 터널 다시 연결 - 다시 연결 중... 사용 바우처 사용 제거 diff --git a/android/lib/resource/src/main/res/values-my/strings.xml b/android/lib/resource/src/main/res/values-my/strings.xml index 372ece1f6163..789af576cfaf 100644 --- a/android/lib/resource/src/main/res/values-my/strings.xml +++ b/android/lib/resource/src/main/res/values-my/strings.xml @@ -287,7 +287,6 @@ Quantum Safe အယ်လဂိုရီသမ်တစ်ခုကို သုံး၍ ထပ်ဆောင်း ကီးဖလှယ်မှုတစ်ခုကို ဆောင်ရွက်ပြီး WireGuard ၏ ပုံမှန် ကုဒ်ပြောင်းဝှက်မှုအတွင်း ရလဒ်ကို ရောနှောခြင်းအားဖြင့် ဤသည်ကို လုပ်ဆောင်ပါသည်။ ဤထပ်ဆောင်းအဆင့်သည် Tunnel အသစ်တစ်ခု တည်ဆောက်တိုင်း ဒေတာ 500 kiB ခန့်ကို သုံးပါသည်။ Quantum-resistant Tunnel ပြန်ချိတ်ဆက်ရန် - ပြန်ချိတ်ဆက်နေသည်... လဲယူရန် ဘောက်ချာဖြင့် လဲယူရန် ဖယ်ရှားရန် diff --git a/android/lib/resource/src/main/res/values-nb/strings.xml b/android/lib/resource/src/main/res/values-nb/strings.xml index 9c358bb4a9ca..e842f655a61a 100644 --- a/android/lib/resource/src/main/res/values-nb/strings.xml +++ b/android/lib/resource/src/main/res/values-nb/strings.xml @@ -287,7 +287,6 @@ Det gjøres ved at å utføre en ekstra nøkkelutveksling med en kvantesikker algoritme og kombinere resultatet med WireGuard sin vanlige kryptering. Dette ekstratrinnet bruker omtrent 500 kiB trafikk hver gang det opprettes en ny tunnel. Kvantebestandig tunnel Koble til på nytt - Kobler til på nytt ... Løs inn Løs inn kupong Fjern diff --git a/android/lib/resource/src/main/res/values-nl/strings.xml b/android/lib/resource/src/main/res/values-nl/strings.xml index baf0ea8cd7d6..a7a5732edacf 100644 --- a/android/lib/resource/src/main/res/values-nl/strings.xml +++ b/android/lib/resource/src/main/res/values-nl/strings.xml @@ -287,7 +287,6 @@ Het doet dit door een extra sleuteluitwisseling uit te voeren met een kwantumveilig algoritme en het resultaat te mengen met de reguliere versleuteling van WireGuard. Deze extra stap gebruikt ongeveer 500 kiB aan verkeer elke keer dat een nieuwe tunnel wordt opgezet. Kwantumbestendige tunnel Opnieuw verbinden - Opnieuw verbinden... Inwisselen Voucher inwisselen Verwijderen diff --git a/android/lib/resource/src/main/res/values-pl/strings.xml b/android/lib/resource/src/main/res/values-pl/strings.xml index c28ff45293ce..80fa36e5bd13 100644 --- a/android/lib/resource/src/main/res/values-pl/strings.xml +++ b/android/lib/resource/src/main/res/values-pl/strings.xml @@ -287,7 +287,6 @@ Jest to wykonywane poprzez dodatkową wymianę kluczy przy użyciu algorytmu odpornego na ataki z użyciem komputerów kwantowych i zmieszanie wyniku ze zwykłym szyfrowaniem WireGuard. Ten dodatkowy krok zużywa około 500 kB ruchu za każdym razem, gdy ustanawiany jest nowy tunel. Tunel odporny na ataki z użyciem komputerów kwantowych Połącz ponownie - Ponowne łączenie... Zrealizuj Zrealizuj kupon Usuń diff --git a/android/lib/resource/src/main/res/values-pt/strings.xml b/android/lib/resource/src/main/res/values-pt/strings.xml index c6f197e89a55..d1c940560cac 100644 --- a/android/lib/resource/src/main/res/values-pt/strings.xml +++ b/android/lib/resource/src/main/res/values-pt/strings.xml @@ -287,7 +287,6 @@ Fá-lo ao realizar uma troca de chaves adicional utilizando um algoritmo de segurança quântica e misturando o resultado na encriptação regular do WireGuard. Este passo adicional utiliza aproximadamente 500 kiB de tráfego sempre que um novo túnel é estabelecido. Túnel com resistência quântica Religar - A religar... Reclamar Reclamar voucher Remover diff --git a/android/lib/resource/src/main/res/values-ru/strings.xml b/android/lib/resource/src/main/res/values-ru/strings.xml index 9699880d972b..b93e21062d8b 100644 --- a/android/lib/resource/src/main/res/values-ru/strings.xml +++ b/android/lib/resource/src/main/res/values-ru/strings.xml @@ -287,7 +287,6 @@ Для этого функция выполняет дополнительный обмен ключами с использованием квантово-устойчивого алгоритма и добавляет результат к обычному шифрованию WireGuard. Эта дополнительная мера использует примерно 500 КиБ трафика при каждом создании нового туннеля. Квантово-устойчивый туннель Переподключить - Идет переподключение... Погасить Погасить ваучер Удалить diff --git a/android/lib/resource/src/main/res/values-sv/strings.xml b/android/lib/resource/src/main/res/values-sv/strings.xml index 1f1f15d1639d..215df1e8e1ec 100644 --- a/android/lib/resource/src/main/res/values-sv/strings.xml +++ b/android/lib/resource/src/main/res/values-sv/strings.xml @@ -287,7 +287,6 @@ Den gör det genom att göra ett extra nyckelutbyte med en kvantsäker algoritm och kombinera resultatet med WireGuards vanliga kryptering. Det här extra steget använder ungefär 500 KiB i trafik varje gång en ny tunnel upprättas. Kvantresistent tunnel Återanslut - Återansluter ... Lös in Lös in kupong Ta bort diff --git a/android/lib/resource/src/main/res/values-th/strings.xml b/android/lib/resource/src/main/res/values-th/strings.xml index f82e49a3e63e..7aafd7be05ce 100644 --- a/android/lib/resource/src/main/res/values-th/strings.xml +++ b/android/lib/resource/src/main/res/values-th/strings.xml @@ -287,7 +287,6 @@ ระบบจะดำเนินการสิ่งนี้ผ่านการแลกเปลี่ยนคีย์เพิ่มเติม โดยการใช้อัลกอริทึมแบบควอนตัมที่ปลอดภัย และผสมผลลัพธ์เข้ากับการเข้ารหัสตามปกติของ WireGuard และขั้นตอนพิเศษนี้ใช้การรับส่งข้อมูลประมาณ 500 kiB ในทุกครั้งที่สร้างช่องทางใหม่ ช่องทางการสกัดกั้นควอนตัม เชื่อมต่อใหม่ - กำลังเชื่อมต่อใหม่... แลกรับ แลกบัตรกำนัล ลบ diff --git a/android/lib/resource/src/main/res/values-tr/strings.xml b/android/lib/resource/src/main/res/values-tr/strings.xml index 32979c266c01..b076839b103d 100644 --- a/android/lib/resource/src/main/res/values-tr/strings.xml +++ b/android/lib/resource/src/main/res/values-tr/strings.xml @@ -287,7 +287,6 @@ Bu işlemi, bir kuantum güvenlik algoritmasıyla ekstra bir anahtar değişimi gerçekleştirdikten sonra sonucu WireGuard\'ın normal şifrelemesiyle karıştırarak yapar. Bu ekstra adım, her yeni tünel kurulduğunda yaklaşık 500 kiB trafik kullanır. Kuantuma dayanıklı tünel Yeniden Bağlan - Yeniden bağlanılıyor... Kullan Kuponu kullan Kaldır diff --git a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml index 6e8f6f87ce63..5d253f81bae5 100644 --- a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml +++ b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml @@ -287,7 +287,6 @@ 实现方法是使用量子安全算法执行额外的密钥交换,并将结果混合到 WireGuard 的常规加密中。每次建立新隧道时,这一额外步骤都会使用约 500 kiB 的流量。 抗量子隧道 重新连接 - 正在重新连接… 兑换 兑换优惠券 移除 diff --git a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml index 0bb60e77b579..15b40db2edde 100644 --- a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml +++ b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml @@ -287,7 +287,6 @@ 實現方法是使用量子安全演算法執行額外的金鑰交換,並將結果混合至 WireGuard 的常規加密。每次建立新通道時,這一額外步驟都會使用約 500 kiB 流量。 抗量子通道 重新連線 - 正在重新連線… 兌換 兌換憑證 移除 diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml index c19faafd54d9..49b5481a7ab3 100644 --- a/android/lib/resource/src/main/res/values/strings.xml +++ b/android/lib/resource/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ Connecting... - Reconnecting... Disconnecting... + Blocking... Critical error (your attention is required) VPN tunnel status Shows current VPN tunnel status diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationAction.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationAction.kt index f836cbcd1b68..2cb11744c127 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationAction.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationAction.kt @@ -48,8 +48,8 @@ private fun NotificationTunnelState.contentTitleResourceId(context: Context): St } } NotificationTunnelState.Disconnecting -> context.getString(R.string.disconnecting) - NotificationTunnelState.Reconnecting -> context.getString(R.string.reconnecting) - NotificationTunnelState.Error.Blocking -> context.getString(R.string.blocking_internet) + NotificationTunnelState.Blocking -> context.getString(R.string.blocking) + NotificationTunnelState.Error.Blocked -> context.getString(R.string.blocking_internet) is NotificationTunnelState.Error.Critical -> context.getString(R.string.critical_error) NotificationTunnelState.Error.DeviceOffline -> context.getString(R.string.blocking_internet_device_offline) diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationProvider.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationProvider.kt index cb589096d974..0f30f9ee78e4 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationProvider.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/tunnelstate/TunnelStateNotificationProvider.kt @@ -1,14 +1,9 @@ package net.mullvad.mullvadvpn.service.notifications.tunnelstate import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filterIsInstance -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.DeviceState @@ -36,22 +31,16 @@ class TunnelStateNotificationProvider( internal val notificationId = NotificationId(2) override val notifications: StateFlow> = - combine( - connectionProxy.tunnelState, - connectionProxy.tunnelState.actionAfterDisconnect().distinctUntilChanged(), - deviceRepository.deviceState, - ) { tunnelState, actionAfterDisconnect, deviceState -> + combine(connectionProxy.tunnelState, deviceRepository.deviceState) { + tunnelState, + deviceState -> if ( deviceState is DeviceState.LoggedOut && tunnelState is TunnelState.Disconnected ) { return@combine NotificationUpdate.Cancel(notificationId) } val notificationTunnelState = - tunnelState( - tunnelState, - actionAfterDisconnect, - vpnPermissionRepository.invoke().leftOrNull(), - ) + tunnelState(tunnelState, vpnPermissionRepository.invoke().leftOrNull()) return@combine NotificationUpdate.Notify( notificationId, @@ -67,36 +56,19 @@ class TunnelStateNotificationProvider( private fun tunnelState( tunnelState: TunnelState, - actionAfterDisconnect: ActionAfterDisconnect?, prepareError: PrepareError?, - ): NotificationTunnelState = - tunnelState.toNotificationTunnelState(actionAfterDisconnect, prepareError) + ): NotificationTunnelState = tunnelState.toNotificationTunnelState(prepareError) - private fun Flow.actionAfterDisconnect(): Flow = - filterIsInstance() - .map { it.actionAfterDisconnect } - .onStart { emit(null) } - - private fun TunnelState.toNotificationTunnelState( - actionAfterDisconnect: ActionAfterDisconnect?, - prepareError: PrepareError?, - ) = + private fun TunnelState.toNotificationTunnelState(prepareError: PrepareError?) = when (this) { is TunnelState.Disconnected -> NotificationTunnelState.Disconnected(prepareError) - is TunnelState.Connecting -> { - if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) { - NotificationTunnelState.Reconnecting - } else { - NotificationTunnelState.Connecting - } - } - is TunnelState.Disconnecting -> { - if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) { - NotificationTunnelState.Reconnecting - } else { - NotificationTunnelState.Disconnecting + is TunnelState.Connecting -> NotificationTunnelState.Connecting + is TunnelState.Disconnecting -> + when (actionAfterDisconnect) { + ActionAfterDisconnect.Reconnect -> NotificationTunnelState.Connecting + ActionAfterDisconnect.Block -> NotificationTunnelState.Blocking + ActionAfterDisconnect.Nothing -> NotificationTunnelState.Disconnecting } - } is TunnelState.Connected -> NotificationTunnelState.Connected is TunnelState.Error -> toNotificationTunnelState() } @@ -106,14 +78,14 @@ class TunnelStateNotificationProvider( return when { cause is ErrorStateCause.IsOffline && errorState.isBlocking -> NotificationTunnelState.Error.DeviceOffline - cause is ErrorStateCause.InvalidDnsServers -> NotificationTunnelState.Error.Blocking + cause is ErrorStateCause.InvalidDnsServers -> NotificationTunnelState.Error.Blocked cause is ErrorStateCause.OtherLegacyAlwaysOnApp -> NotificationTunnelState.Error.LegacyLockdown cause is ErrorStateCause.NotPrepared -> NotificationTunnelState.Error.VpnPermissionDenied cause is ErrorStateCause.OtherAlwaysOnApp -> NotificationTunnelState.Error.AlwaysOnVpn(cause.appName) - errorState.isBlocking -> NotificationTunnelState.Error.Blocking + errorState.isBlocking -> NotificationTunnelState.Error.Blocked else -> NotificationTunnelState.Error.Critical } } @@ -129,12 +101,12 @@ class TunnelStateNotificationProvider( } } NotificationTunnelState.Disconnecting -> NotificationAction.Tunnel.Connect - NotificationTunnelState.Connected, - NotificationTunnelState.Error.Blocking -> NotificationAction.Tunnel.Disconnect + NotificationTunnelState.Error.Blocked, + NotificationTunnelState.Blocking, + NotificationTunnelState.Error.DeviceOffline, + NotificationTunnelState.Connected -> NotificationAction.Tunnel.Disconnect NotificationTunnelState.Connecting -> NotificationAction.Tunnel.Cancel - NotificationTunnelState.Reconnecting -> NotificationAction.Tunnel.Cancel is NotificationTunnelState.Error.Critical, - NotificationTunnelState.Error.DeviceOffline, NotificationTunnelState.Error.VpnPermissionDenied, is NotificationTunnelState.Error.AlwaysOnVpn, NotificationTunnelState.Error.LegacyLockdown -> NotificationAction.Tunnel.Dismiss diff --git a/desktop/packages/mullvad-vpn/locales/messages.pot b/desktop/packages/mullvad-vpn/locales/messages.pot index 2f18fac26b4c..2a50198bf099 100644 --- a/desktop/packages/mullvad-vpn/locales/messages.pot +++ b/desktop/packages/mullvad-vpn/locales/messages.pot @@ -2361,6 +2361,9 @@ msgstr "" msgid "Blocking internet (device offline)" msgstr "" +msgid "Blocking..." +msgstr "" + msgid "Changelog" msgstr "" @@ -2598,9 +2601,6 @@ msgstr "" msgid "Privacy policy" msgstr "" -msgid "Reconnecting..." -msgstr "" - msgid "Recursion limit" msgstr ""