From f4341ae1c189a601ecd9b93cb8194dd3327a722d Mon Sep 17 00:00:00 2001
From: callebtc <93376500+callebtc@users.noreply.github.com>
Date: Tue, 21 Oct 2025 22:24:55 +0200
Subject: [PATCH] wifi aware wip
---
app/src/main/AndroidManifest.xml | 9 +
.../com/bitchat/android/BitchatApplication.kt | 6 +
.../onboarding/OnboardingCoordinator.kt | 1 +
.../onboarding/PermissionExplanationScreen.kt | 2 +
.../android/onboarding/PermissionManager.kt | 20 +
.../bitchat/android/ui/SidebarComponents.kt | 16 +-
.../ui/debug/DebugPreferenceManager.kt | 26 +
.../android/ui/debug/DebugSettingsManager.kt | 45 +
.../android/ui/debug/DebugSettingsSheet.kt | 93 ++
.../android/wifi-aware/WifiAwareController.kt | 111 ++
.../wifi-aware/WifiAwareMeshServiceLatest.kt | 1163 +++++++++++++++++
11 files changed, 1490 insertions(+), 2 deletions(-)
create mode 100644 app/src/main/java/com/bitchat/android/wifi-aware/WifiAwareController.kt
create mode 100644 app/src/main/java/com/bitchat/android/wifi-aware/WifiAwareMeshServiceLatest.kt
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8e953323..e99bb2ce 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
@@ -19,6 +20,12 @@
+
+
+
+
+
+
@@ -38,6 +45,8 @@
+
+
"Bluetooth/Nearby Devices"
permission.contains("LOCATION") -> "Location (for Bluetooth scanning)"
+ permission.contains("NEARBY_WIFI") -> "Nearby Wi‑Fi Devices (for Wi‑Fi Aware)"
permission.contains("NOTIFICATION") -> "Notifications"
else -> permission.substringAfterLast(".")
}
diff --git a/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt
index 2b84aefa..c00f35f3 100644
--- a/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt
+++ b/app/src/main/java/com/bitchat/android/onboarding/PermissionExplanationScreen.kt
@@ -11,6 +11,7 @@ import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Power
import androidx.compose.material.icons.filled.Mic
import androidx.compose.material.icons.filled.Security
+import androidx.compose.material.icons.filled.Wifi
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material3.*
@@ -242,6 +243,7 @@ private fun getPermissionIcon(permissionType: PermissionType): ImageVector {
PermissionType.PRECISE_LOCATION -> Icons.Filled.LocationOn
PermissionType.MICROPHONE -> Icons.Filled.Mic
PermissionType.NOTIFICATIONS -> Icons.Filled.Notifications
+ PermissionType.WIFI_AWARE -> Icons.Filled.Wifi
PermissionType.BATTERY_OPTIMIZATION -> Icons.Filled.Power
PermissionType.OTHER -> Icons.Filled.Settings
}
diff --git a/app/src/main/java/com/bitchat/android/onboarding/PermissionManager.kt b/app/src/main/java/com/bitchat/android/onboarding/PermissionManager.kt
index ff0a160f..aedf85f8 100644
--- a/app/src/main/java/com/bitchat/android/onboarding/PermissionManager.kt
+++ b/app/src/main/java/com/bitchat/android/onboarding/PermissionManager.kt
@@ -67,6 +67,11 @@ class PermissionManager(private val context: Context) {
Manifest.permission.ACCESS_FINE_LOCATION
))
+ // Wi‑Fi Aware: Android 13+ requires NEARBY_WIFI_DEVICES runtime permission
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ permissions.add(Manifest.permission.NEARBY_WIFI_DEVICES)
+ }
+
// Notification permission intentionally excluded to keep it optional
return permissions
@@ -177,6 +182,20 @@ class PermissionManager(private val context: Context) {
)
)
+ // Wi‑Fi Aware category (Android 13+)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ val wifiAwarePermissions = listOf(Manifest.permission.NEARBY_WIFI_DEVICES)
+ categories.add(
+ PermissionCategory(
+ type = PermissionType.WIFI_AWARE,
+ description = "Enable Wi‑Fi Aware to discover and connect to nearby bitchat users over Wi‑Fi.",
+ permissions = wifiAwarePermissions,
+ isGranted = wifiAwarePermissions.all { isPermissionGranted(it) },
+ systemDescription = "Allow bitchat to discover nearby Wi‑Fi devices"
+ )
+ )
+ }
+
// Notifications category (if applicable)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
categories.add(
@@ -262,6 +281,7 @@ enum class PermissionType(val nameValue: String) {
PRECISE_LOCATION("Precise Location"),
MICROPHONE("Microphone"),
NOTIFICATIONS("Notifications"),
+ WIFI_AWARE("Wi‑Fi Aware"),
BATTERY_OPTIMIZATION("Battery Optimization"),
OTHER("Other")
}
diff --git a/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt b/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt
index a8c59ef7..2a6b2035 100644
--- a/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt
+++ b/app/src/main/java/com/bitchat/android/ui/SidebarComponents.kt
@@ -576,9 +576,21 @@ private fun PeerItem(
tint = Color.Gray
)
} else {
+ val wifiAwarePeers by com.bitchat.android.wifiaware.WifiAwareController.connectedPeers.collectAsState()
+ val isWifiAware = wifiAwarePeers.containsKey(peerID)
+ val icon = when {
+ isWifiAware -> Icons.Filled.Wifi
+ isDirect -> Icons.Outlined.SettingsInputAntenna
+ else -> Icons.Filled.Route
+ }
+ val cd = when {
+ isWifiAware -> "Direct Wi‑Fi Aware"
+ isDirect -> "Direct Bluetooth"
+ else -> "Routed"
+ }
Icon(
- imageVector = if (isDirect) Icons.Outlined.SettingsInputAntenna else Icons.Filled.Route,
- contentDescription = if (isDirect) "Direct Bluetooth" else "Routed",
+ imageVector = icon,
+ contentDescription = cd,
modifier = Modifier.size(16.dp),
tint = colorScheme.onSurface.copy(alpha = 0.8f)
)
diff --git a/app/src/main/java/com/bitchat/android/ui/debug/DebugPreferenceManager.kt b/app/src/main/java/com/bitchat/android/ui/debug/DebugPreferenceManager.kt
index e2f9d966..2d734c14 100644
--- a/app/src/main/java/com/bitchat/android/ui/debug/DebugPreferenceManager.kt
+++ b/app/src/main/java/com/bitchat/android/ui/debug/DebugPreferenceManager.kt
@@ -20,6 +20,10 @@ object DebugPreferenceManager {
// GCS keys (no migration/back-compat)
private const val KEY_GCS_MAX_BYTES = "gcs_max_filter_bytes"
private const val KEY_GCS_FPR = "gcs_filter_fpr_percent"
+ // Transport master toggles
+ private const val KEY_BLE_ENABLED = "ble_enabled"
+ private const val KEY_WIFI_AWARE_ENABLED = "wifi_aware_enabled"
+ private const val KEY_WIFI_AWARE_VERBOSE = "wifi_aware_verbose"
private lateinit var prefs: SharedPreferences
@@ -100,4 +104,26 @@ object DebugPreferenceManager {
fun setGcsFprPercent(value: Double) {
if (ready()) prefs.edit().putLong(KEY_GCS_FPR, java.lang.Double.doubleToRawLongBits(value)).apply()
}
+
+ // Transport toggles
+ fun getBleEnabled(default: Boolean = true): Boolean =
+ if (ready()) prefs.getBoolean(KEY_BLE_ENABLED, default) else default
+
+ fun setBleEnabled(value: Boolean) {
+ if (ready()) prefs.edit().putBoolean(KEY_BLE_ENABLED, value).apply()
+ }
+
+ fun getWifiAwareEnabled(default: Boolean = false): Boolean =
+ if (ready()) prefs.getBoolean(KEY_WIFI_AWARE_ENABLED, default) else default
+
+ fun setWifiAwareEnabled(value: Boolean) {
+ if (ready()) prefs.edit().putBoolean(KEY_WIFI_AWARE_ENABLED, value).apply()
+ }
+
+ fun getWifiAwareVerbose(default: Boolean = false): Boolean =
+ if (ready()) prefs.getBoolean(KEY_WIFI_AWARE_VERBOSE, default) else default
+
+ fun setWifiAwareVerbose(value: Boolean) {
+ if (ready()) prefs.edit().putBoolean(KEY_WIFI_AWARE_VERBOSE, value).apply()
+ }
}
diff --git a/app/src/main/java/com/bitchat/android/ui/debug/DebugSettingsManager.kt b/app/src/main/java/com/bitchat/android/ui/debug/DebugSettingsManager.kt
index 6e37286f..2749e58b 100644
--- a/app/src/main/java/com/bitchat/android/ui/debug/DebugSettingsManager.kt
+++ b/app/src/main/java/com/bitchat/android/ui/debug/DebugSettingsManager.kt
@@ -36,6 +36,16 @@ class DebugSettingsManager private constructor() {
private val _packetRelayEnabled = MutableStateFlow(true)
val packetRelayEnabled: StateFlow = _packetRelayEnabled.asStateFlow()
+ // Master transport toggles
+ private val _bleEnabled = MutableStateFlow(true)
+ val bleEnabled: StateFlow = _bleEnabled.asStateFlow()
+
+ private val _wifiAwareEnabled = MutableStateFlow(false)
+ val wifiAwareEnabled: StateFlow = _wifiAwareEnabled.asStateFlow()
+
+ private val _wifiAwareVerbose = MutableStateFlow(false)
+ val wifiAwareVerbose: StateFlow = _wifiAwareVerbose.asStateFlow()
+
// Connection limit overrides (debug)
private val _maxConnectionsOverall = MutableStateFlow(8)
val maxConnectionsOverall: StateFlow = _maxConnectionsOverall.asStateFlow()
@@ -54,6 +64,10 @@ class DebugSettingsManager private constructor() {
_maxConnectionsOverall.value = DebugPreferenceManager.getMaxConnectionsOverall(8)
_maxServerConnections.value = DebugPreferenceManager.getMaxConnectionsServer(8)
_maxClientConnections.value = DebugPreferenceManager.getMaxConnectionsClient(8)
+ // Transport toggles
+ _bleEnabled.value = DebugPreferenceManager.getBleEnabled(true)
+ _wifiAwareEnabled.value = DebugPreferenceManager.getWifiAwareEnabled(false)
+ _wifiAwareVerbose.value = DebugPreferenceManager.getWifiAwareVerbose(false)
} catch (_: Exception) {
// Preferences not ready yet; keep defaults. They will be applied on first change.
}
@@ -140,6 +154,27 @@ class DebugSettingsManager private constructor() {
))
}
+ fun setBleEnabled(enabled: Boolean) {
+ DebugPreferenceManager.setBleEnabled(enabled)
+ _bleEnabled.value = enabled
+ addDebugMessage(DebugMessage.SystemMessage(if (enabled) "🟢 BLE enabled" else "🔴 BLE disabled"))
+ }
+
+ fun setWifiAwareEnabled(enabled: Boolean) {
+ DebugPreferenceManager.setWifiAwareEnabled(enabled)
+ _wifiAwareEnabled.value = enabled
+ addDebugMessage(DebugMessage.SystemMessage(if (enabled) "🟢 Wi‑Fi Aware enabled" else "🔴 Wi‑Fi Aware disabled"))
+ try {
+ com.bitchat.android.wifiaware.WifiAwareController.setEnabled(enabled)
+ } catch (_: Exception) { }
+ }
+
+ fun setWifiAwareVerbose(enabled: Boolean) {
+ DebugPreferenceManager.setWifiAwareVerbose(enabled)
+ _wifiAwareVerbose.value = enabled
+ addDebugMessage(DebugMessage.SystemMessage(if (enabled) "🔊 Wi‑Fi Aware verbose logging enabled" else "🔇 Wi‑Fi Aware verbose logging disabled"))
+ }
+
fun setMaxConnectionsOverall(value: Int) {
val clamped = value.coerceIn(1, 32)
DebugPreferenceManager.setMaxConnectionsOverall(clamped)
@@ -197,6 +232,16 @@ class DebugSettingsManager private constructor() {
fun updateConnectedDevices(devices: List) {
_connectedDevices.value = devices
}
+
+ // Wi‑Fi Aware debug collections
+ private val _wifiAwareDiscovered = MutableStateFlow