Skip to content

Commit 3ac6ac2

Browse files
committed
feat(vpn): pre-compile session retry backoff regex, track and display warning in connection status card dynamically during connecting phase
1 parent 8711b74 commit 3ac6ac2

3 files changed

Lines changed: 52 additions & 3 deletions

File tree

android/app/src/main/java/com/masterdns/vpn/ui/home/HomeScreen.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ fun HomeScreen(
7171
val scanStatus by VpnManager.scanStatus.collectAsState()
7272
val selectedProfile by viewModel.selectedProfile.collectAsState()
7373
val error by VpnManager.errorMessage.collectAsState()
74+
val connectionWarning by VpnManager.connectionWarning.collectAsState()
7475
val context = LocalContext.current
7576

7677
val advanced = remember(selectedProfile?.advancedJson) {
@@ -239,7 +240,8 @@ fun HomeScreen(
239240
socksAuthEnabled = socksAuthEnabled,
240241
socksUser = socksUser,
241242
socksPass = socksPass,
242-
isConnecting = isConnecting
243+
isConnecting = isConnecting,
244+
connectionWarning = connectionWarning
243245
)
244246
Spacer(modifier = Modifier.height(MdvSpace.S3))
245247
MdvProfileSelectorCard(
@@ -311,7 +313,8 @@ fun HomeScreen(
311313
socksAuthEnabled = socksAuthEnabled,
312314
socksUser = socksUser,
313315
socksPass = socksPass,
314-
isConnecting = isConnecting
316+
isConnecting = isConnecting,
317+
connectionWarning = connectionWarning
315318
)
316319

317320
Spacer(modifier = Modifier.height(MdvSpace.S3))

android/app/src/main/java/com/masterdns/vpn/ui/home/HomeStatusCards.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ fun MdvConnectionTelemetryCard(
4545
socksAuthEnabled: Boolean,
4646
socksUser: String,
4747
socksPass: String,
48-
isConnecting: Boolean
48+
isConnecting: Boolean,
49+
connectionWarning: String? = null
4950
) {
5051
MdvCardLow(modifier = Modifier.fillMaxWidth()) {
5152
Column(
@@ -186,6 +187,35 @@ fun MdvConnectionTelemetryCard(
186187
}
187188
}
188189

190+
// Connection Warning Section
191+
if (connectionWarning != null && vpnState == VpnManager.VpnState.CONNECTING) {
192+
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(MdvSpace.S3))
193+
androidx.compose.material3.Surface(
194+
shape = androidx.compose.foundation.shape.RoundedCornerShape(12.dp),
195+
color = ConnectingAmber.copy(alpha = 0.12f),
196+
border = androidx.compose.foundation.BorderStroke(1.dp, ConnectingAmber.copy(alpha = 0.4f)),
197+
modifier = Modifier.fillMaxWidth()
198+
) {
199+
Row(
200+
modifier = Modifier.padding(horizontal = MdvSpace.S3, vertical = 10.dp),
201+
verticalAlignment = Alignment.CenterVertically
202+
) {
203+
Text(
204+
text = "",
205+
style = MaterialTheme.typography.titleMedium,
206+
color = ConnectingAmber,
207+
modifier = Modifier.padding(end = 8.dp)
208+
)
209+
Text(
210+
text = connectionWarning,
211+
style = MaterialTheme.typography.bodySmall,
212+
color = ConnectingAmber,
213+
fontWeight = FontWeight.SemiBold
214+
)
215+
}
216+
}
217+
}
218+
189219
// Network Traffic Grid
190220
if (downloadTotalBytes > 0 || uploadTotalBytes > 0 || downBps > 0 || upBps > 0) {
191221
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(MdvSpace.S3))

android/app/src/main/java/com/masterdns/vpn/util/VpnManager.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ object VpnManager {
5656
private val _errorMessage = MutableStateFlow<String?>(null)
5757
val errorMessage: StateFlow<String?> = _errorMessage.asStateFlow()
5858

59+
private val _connectionWarning = MutableStateFlow<String?>(null)
60+
val connectionWarning: StateFlow<String?> = _connectionWarning.asStateFlow()
61+
5962
private val _activeResolvers = MutableStateFlow<List<String>>(emptyList())
6063
val activeResolvers: StateFlow<List<String>> = _activeResolvers.asStateFlow()
6164

@@ -130,6 +133,10 @@ object VpnManager {
130133
"DNS Resolver disabled.*?(\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+|\\[[a-fA-F0-9:]+\\]:\\d+)",
131134
RegexOption.IGNORE_CASE
132135
)
136+
private val SESSION_INIT_BACKOFF_REGEX = Regex(
137+
"Session init retry backoff:\\s*(.*)",
138+
RegexOption.IGNORE_CASE
139+
)
133140
private val TIMESTAMP_CANDIDATES = listOf(
134141
TimestampCandidate(
135142
Regex("^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)(.*)$"),
@@ -170,6 +177,10 @@ object VpnManager {
170177
_connectedDurationSeconds.value = 0L
171178
_uploadTotalBytes.value = 0L
172179
_downloadTotalBytes.value = 0L
180+
_connectionWarning.value = null
181+
}
182+
if (newState == VpnState.CONNECTED || newState == VpnState.DISCONNECTED || newState == VpnState.ERROR) {
183+
_connectionWarning.value = null
173184
}
174185
if (newState == VpnState.CONNECTED) {
175186
_scanStatus.value = _scanStatus.value.copy(
@@ -427,6 +438,11 @@ object VpnManager {
427438
) {
428439
_scanStatus.value = _scanStatus.value.copy(scanning = false)
429440
}
441+
442+
SESSION_INIT_BACKOFF_REGEX.find(line)?.let { match ->
443+
val backoff = match.groupValues[1].trim()
444+
_connectionWarning.value = "Session init retry backoff: $backoff"
445+
}
430446
}
431447

432448
private fun normalizeLogTimestampToLocal(line: String): String {

0 commit comments

Comments
 (0)