mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 04:05:21 +00:00
simplify (#346)
This commit is contained in:
@@ -124,9 +124,7 @@ object TorManager {
|
|||||||
}
|
}
|
||||||
bindRetryAttempts = 0
|
bindRetryAttempts = 0
|
||||||
lifecycleState = LifecycleState.STARTING
|
lifecycleState = LifecycleState.STARTING
|
||||||
// For OFF->ON, no delay needed
|
startArti(application, useDelay = false)
|
||||||
val needsDelay = s.mode == TorMode.ISOLATION
|
|
||||||
startArti(application, isolation = false, useDelay = needsDelay)
|
|
||||||
_status.value = _status.value.copy(mode = TorMode.ON)
|
_status.value = _status.value.copy(mode = TorMode.ON)
|
||||||
// Defer enabling proxy until bootstrap completes
|
// Defer enabling proxy until bootstrap completes
|
||||||
appScope.launch {
|
appScope.launch {
|
||||||
@@ -139,29 +137,6 @@ object TorManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TorMode.ISOLATION -> {
|
|
||||||
Log.i(TAG, "applyMode: ISOLATION -> starting arti")
|
|
||||||
// Reset port to default unless we're already using a higher port
|
|
||||||
if (currentSocksPort < DEFAULT_SOCKS_PORT) {
|
|
||||||
currentSocksPort = DEFAULT_SOCKS_PORT
|
|
||||||
}
|
|
||||||
bindRetryAttempts = 0
|
|
||||||
lifecycleState = LifecycleState.STARTING
|
|
||||||
// For ON->ISOLATION, immediate status change and delay
|
|
||||||
_status.value = _status.value.copy(running = false, bootstrapPercent = 0)
|
|
||||||
val needsDelay = s.mode == TorMode.ON
|
|
||||||
startArti(application, isolation = true, useDelay = needsDelay)
|
|
||||||
_status.value = _status.value.copy(mode = TorMode.ISOLATION)
|
|
||||||
appScope.launch {
|
|
||||||
waitUntilBootstrapped()
|
|
||||||
if (_status.value.running && desiredMode == TorMode.ISOLATION) {
|
|
||||||
socksAddr = InetSocketAddress("127.0.0.1", currentSocksPort)
|
|
||||||
Log.i(TAG, "Arti ISOLATION: proxy set to ${socksAddr}")
|
|
||||||
OkHttpProvider.reset()
|
|
||||||
try { com.bitchat.android.nostr.NostrRelayManager.shared.resetAllConnections() } catch (_: Throwable) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to apply Arti mode: ${e.message}")
|
Log.e(TAG, "Failed to apply Arti mode: ${e.message}")
|
||||||
@@ -169,7 +144,7 @@ object TorManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun startArti(application: Application, isolation: Boolean, useDelay: Boolean = false) {
|
private suspend fun startArti(application: Application, useDelay: Boolean = false) {
|
||||||
try {
|
try {
|
||||||
stopArtiInternal()
|
stopArtiInternal()
|
||||||
|
|
||||||
@@ -219,14 +194,14 @@ object TorManager {
|
|||||||
currentSocksPort++
|
currentSocksPort++
|
||||||
Log.w(TAG, "Port bind failed (attempt $bindRetryAttempts/$MAX_RETRY_ATTEMPTS), retrying with port $currentSocksPort")
|
Log.w(TAG, "Port bind failed (attempt $bindRetryAttempts/$MAX_RETRY_ATTEMPTS), retrying with port $currentSocksPort")
|
||||||
// Immediate retry with incremented port, no exponential backoff for bind errors
|
// Immediate retry with incremented port, no exponential backoff for bind errors
|
||||||
startArti(application, isolation, useDelay = false)
|
startArti(application, useDelay = false)
|
||||||
} else if (isBindError) {
|
} else if (isBindError) {
|
||||||
Log.e(TAG, "Max bind retry attempts reached ($MAX_RETRY_ATTEMPTS), giving up")
|
Log.e(TAG, "Max bind retry attempts reached ($MAX_RETRY_ATTEMPTS), giving up")
|
||||||
lifecycleState = LifecycleState.STOPPED
|
lifecycleState = LifecycleState.STOPPED
|
||||||
_status.value = _status.value.copy(running = false, bootstrapPercent = 0)
|
_status.value = _status.value.copy(running = false, bootstrapPercent = 0)
|
||||||
} else {
|
} else {
|
||||||
// For non-bind errors, use the existing retry mechanism
|
// For non-bind errors, use the existing retry mechanism
|
||||||
scheduleRetry(application, isolation)
|
scheduleRetry(application)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,11 +238,11 @@ object TorManager {
|
|||||||
_status.value = _status.value.copy(running = false, bootstrapPercent = 0)
|
_status.value = _status.value.copy(running = false, bootstrapPercent = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun restartArti(application: Application, isolation: Boolean) {
|
private suspend fun restartArti(application: Application) {
|
||||||
Log.i(TAG, "Restarting Arti (keeping SOCKS proxy enabled)...")
|
Log.i(TAG, "Restarting Arti (keeping SOCKS proxy enabled)...")
|
||||||
stopArtiInternal()
|
stopArtiInternal()
|
||||||
delay(RESTART_DELAY_MS)
|
delay(RESTART_DELAY_MS)
|
||||||
startArti(application, isolation, useDelay = false) // Already delayed above
|
startArti(application, useDelay = false) // Already delayed above
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startInactivityMonitoring() {
|
private fun startInactivityMonitoring() {
|
||||||
@@ -281,13 +256,13 @@ object TorManager {
|
|||||||
|
|
||||||
if (timeSinceLastActivity > INACTIVITY_TIMEOUT_MS) {
|
if (timeSinceLastActivity > INACTIVITY_TIMEOUT_MS) {
|
||||||
val currentMode = _status.value.mode
|
val currentMode = _status.value.mode
|
||||||
if (currentMode == TorMode.ON || currentMode == TorMode.ISOLATION) {
|
if (currentMode == TorMode.ON) {
|
||||||
val bootstrapPercent = _status.value.bootstrapPercent
|
val bootstrapPercent = _status.value.bootstrapPercent
|
||||||
if (bootstrapPercent < 100) {
|
if (bootstrapPercent < 100) {
|
||||||
Log.w(TAG, "Inactivity detected (${timeSinceLastActivity}ms), restarting Arti")
|
Log.w(TAG, "Inactivity detected (${timeSinceLastActivity}ms), restarting Arti")
|
||||||
currentApplication?.let { app ->
|
currentApplication?.let { app ->
|
||||||
appScope.launch {
|
appScope.launch {
|
||||||
restartArti(app, currentMode == TorMode.ISOLATION)
|
restartArti(app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -303,7 +278,7 @@ object TorManager {
|
|||||||
inactivityJob = null
|
inactivityJob = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scheduleRetry(application: Application, isolation: Boolean) {
|
private fun scheduleRetry(application: Application) {
|
||||||
retryJob?.cancel()
|
retryJob?.cancel()
|
||||||
if (retryAttempts < MAX_RETRY_ATTEMPTS) {
|
if (retryAttempts < MAX_RETRY_ATTEMPTS) {
|
||||||
retryAttempts++
|
retryAttempts++
|
||||||
@@ -312,9 +287,9 @@ object TorManager {
|
|||||||
retryJob = appScope.launch {
|
retryJob = appScope.launch {
|
||||||
delay(delayMs)
|
delay(delayMs)
|
||||||
val currentMode = _status.value.mode
|
val currentMode = _status.value.mode
|
||||||
if (currentMode == TorMode.ON || currentMode == TorMode.ISOLATION) {
|
if (currentMode == TorMode.ON) {
|
||||||
Log.i(TAG, "Retrying Arti start (attempt $retryAttempts)")
|
Log.i(TAG, "Retrying Arti start (attempt $retryAttempts)")
|
||||||
restartArti(application, currentMode == TorMode.ISOLATION)
|
restartArti(application)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.bitchat.android.net
|
|||||||
|
|
||||||
enum class TorMode {
|
enum class TorMode {
|
||||||
OFF,
|
OFF,
|
||||||
ON,
|
ON
|
||||||
ISOLATION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ fun AboutSheet(
|
|||||||
FeatureCard(
|
FeatureCard(
|
||||||
icon = Icons.Filled.Public,
|
icon = Icons.Filled.Public,
|
||||||
iconColor = standardGreen,
|
iconColor = standardGreen,
|
||||||
title = "geohash channels",
|
title = "online geohash channels",
|
||||||
description = "internet-based location channels using coarse geohash coordinates. connect with people in your area while preserving privacy.",
|
description = "connect with people in your area using geohash-based channels. extend the mesh using public internet relays.",
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,39 +128,12 @@ fun AboutSheet(
|
|||||||
icon = Icons.Filled.Lock,
|
icon = Icons.Filled.Lock,
|
||||||
iconColor = if (isDark) Color(0xFFFFD60A) else Color(0xFFF5A623),
|
iconColor = if (isDark) Color(0xFFFFD60A) else Color(0xFFF5A623),
|
||||||
title = "end-to-end encryption",
|
title = "end-to-end encryption",
|
||||||
description = "all direct messages use noise protocol encryption. channel messages are protected with optional passwords.",
|
description = "private messages are encrypted. channel messages are public.",
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional features
|
|
||||||
item {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
color = colorScheme.surfaceVariant.copy(alpha = 0.3f),
|
|
||||||
shape = RoundedCornerShape(12.dp)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "additional features",
|
|
||||||
fontSize = 12.sp,
|
|
||||||
fontFamily = FontFamily.Monospace,
|
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
color = colorScheme.onSurface.copy(alpha = 0.8f)
|
|
||||||
)
|
|
||||||
|
|
||||||
FeatureItem("store-and-forward messaging for offline peers")
|
|
||||||
FeatureItem("ephemeral messaging with automatic cleanup")
|
|
||||||
FeatureItem("peer discovery and identity verification")
|
|
||||||
FeatureItem("minimal metadata leakage")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Appearance section (theme toggle)
|
// Appearance section (theme toggle)
|
||||||
item {
|
item {
|
||||||
val themePref by com.bitchat.android.ui.theme.ThemePreferenceManager.themeFlow.collectAsState()
|
val themePref by com.bitchat.android.ui.theme.ThemePreferenceManager.themeFlow.collectAsState()
|
||||||
@@ -226,17 +199,13 @@ fun AboutSheet(
|
|||||||
torMode.value = com.bitchat.android.net.TorMode.ON
|
torMode.value = com.bitchat.android.net.TorMode.ON
|
||||||
com.bitchat.android.net.TorPreferenceManager.set(ctx, torMode.value)
|
com.bitchat.android.net.TorPreferenceManager.set(ctx, torMode.value)
|
||||||
},
|
},
|
||||||
label = { Text("tor on", fontFamily = FontFamily.Monospace) }
|
label = {
|
||||||
)
|
Row(
|
||||||
FilterChip(
|
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
selected = torMode.value == com.bitchat.android.net.TorMode.ISOLATION,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
onClick = {
|
) {
|
||||||
torMode.value = com.bitchat.android.net.TorMode.ISOLATION
|
Text("tor on", fontFamily = FontFamily.Monospace)
|
||||||
com.bitchat.android.net.TorPreferenceManager.set(ctx, torMode.value)
|
// Status indicator (red/orange/green) moved inside the "tor on" button
|
||||||
},
|
|
||||||
label = { Text("isolation mode", fontFamily = FontFamily.Monospace) }
|
|
||||||
)
|
|
||||||
// Status indicator (red/orange/green) shown to the right of buttons
|
|
||||||
val statusColor = when {
|
val statusColor = when {
|
||||||
torStatus.running && torStatus.bootstrapPercent < 100 -> Color(0xFFFF9500)
|
torStatus.running && torStatus.bootstrapPercent < 100 -> Color(0xFFFF9500)
|
||||||
torStatus.running && torStatus.bootstrapPercent >= 100 -> if (isDark) Color(0xFF32D74B) else Color(0xFF248A3D)
|
torStatus.running && torStatus.bootstrapPercent >= 100 -> if (isDark) Color(0xFF32D74B) else Color(0xFF248A3D)
|
||||||
@@ -245,10 +214,13 @@ fun AboutSheet(
|
|||||||
Surface(
|
Surface(
|
||||||
color = statusColor,
|
color = statusColor,
|
||||||
shape = RoundedCornerShape(50)
|
shape = RoundedCornerShape(50)
|
||||||
) { Box(Modifier.size(10.dp)) }
|
) { Box(Modifier.size(8.dp)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = "route internet over tor. isolation uses separate circuits per relay.",
|
text = "route internet over tor for enhanced privacy.",
|
||||||
fontSize = 10.sp,
|
fontSize = 10.sp,
|
||||||
fontFamily = FontFamily.Monospace,
|
fontFamily = FontFamily.Monospace,
|
||||||
color = colorScheme.onSurface.copy(alpha = 0.6f)
|
color = colorScheme.onSurface.copy(alpha = 0.6f)
|
||||||
|
|||||||
Reference in New Issue
Block a user