mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 12:25:20 +00:00
Fix wifi aware socket binding 2 (#536)
* Background persistence (#505) * persistence step 1 * fix build * messages in the background work, notifications not yet * app state store * DM icon shows up * notification launches when app is closed! * keep ui updated * lifecycle fixes * extensive logging, maybe revert later * send nickname in announcement * quit in notification * setting in about sheet * fix quit bitchat * lifecycle fixes * power mode based on background state * stats for both direciotns * fix graph persistence * better counting * count per device * only compute when debug sheet is open? untested * fix read receipts * fix read receipts fully * fix unread badge if messages have been read in focus * foreground promotion fix * fix app kill in notification * adjust to new tor * nice * about sheet design * bump version 1.6.0 (#524) * Automated update of relay data - Sun Dec 14 06:06:53 UTC 2025 * bump targetSdk (#526) * Automated update of relay data - Sun Dec 21 06:06:56 UTC 2025 * Automated update of relay data - Sun Dec 28 06:07:12 UTC 2025 * Prevent quit notification from reappearing (#530) * shutdown sequence * Prevent quit notification from reappearing * Restrict force-finish broadcast * Cancel quit shutdown on relaunch * fix(wifi-aware): use bindSocket and scoped IPv6 instead of bindProcessToNetwork * Merge branch 'upstream/main' into fix/wifi-aware-socket-binding * Fix Wi-Fi Aware connectivity and UI integration post-merge - Replace bindProcessToNetwork with bindSocket for VPN compatibility. - Implement Scoped IPv6 address resolution (aware0) for mesh routing. - Bridge Wi-Fi Aware incoming messages to AppStateStore for UI visibility. - Fix syntax errors and variable name conflicts in Debug UI. * Enhance Wi-Fi Aware robustness and debug UI display - Clean up transport resources (sockets, server sockets, network callbacks) immediately on peer disconnection. - Implement resolveScopedAddress to show scoped IPv6 (e.g., %aware0) in Debug UI. - Fix Map type mismatch warning in ChatViewModel bridge. - Filter self-ID from peer cleanup tables to prevent recursive self-removal. * Share GossipSyncManager across transports to prevent redundant message synchronization - Registered BluetoothMeshService's GossipSyncManager as a singleton in MeshServiceHolder. - Modified WifiAwareMeshService to use the shared GossipSyncManager if available. - Added background cleanup for peer mappings on socket disconnection. - Fixed Kotlin type mismatch during nickname map merging. * Restore VPN acquisition logic and improve peer cleanup - Revert removal of NET_CAPABILITY_NOT_VPN to allow hardware handle acquisition while VPN is active. - Refactor handlePeerDisconnection to more reliably cleanup initial and routed IDs. - Switch cleanup logging to debug level to reduce log noise. --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: aidenvalue <>
This commit is contained in:
co-authored by
GitHub Action
aidenvalue <>
parent
ecc7e93930
commit
463600a6c3
@@ -51,7 +51,7 @@ class MainActivity : OrientationAwareActivity() {
|
||||
private lateinit var locationStatusManager: LocationStatusManager
|
||||
private lateinit var batteryOptimizationManager: BatteryOptimizationManager
|
||||
|
||||
// Core mesh service - managed at app level
|
||||
// Core mesh service - provided by the foreground service holder
|
||||
private lateinit var meshService: BluetoothMeshService
|
||||
private val mainViewModel: MainViewModel by viewModels()
|
||||
private val chatViewModel: ChatViewModel by viewModels {
|
||||
@@ -63,16 +63,55 @@ class MainActivity : OrientationAwareActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private val forceFinishReceiver = object : android.content.BroadcastReceiver() {
|
||||
override fun onReceive(context: android.content.Context, intent: android.content.Intent) {
|
||||
if (intent.action == com.bitchat.android.util.AppConstants.UI.ACTION_FORCE_FINISH) {
|
||||
android.util.Log.i("MainActivity", "Received force finish broadcast, closing UI")
|
||||
finishAffinity()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// Register receiver for force finish signal from shutdown coordinator
|
||||
val filter = android.content.IntentFilter(com.bitchat.android.util.AppConstants.UI.ACTION_FORCE_FINISH)
|
||||
if (android.os.Build.VERSION.SDK_INT >= 33) {
|
||||
registerReceiver(
|
||||
forceFinishReceiver,
|
||||
filter,
|
||||
com.bitchat.android.util.AppConstants.UI.PERMISSION_FORCE_FINISH,
|
||||
null,
|
||||
android.content.Context.RECEIVER_NOT_EXPORTED
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
registerReceiver(
|
||||
forceFinishReceiver,
|
||||
filter,
|
||||
com.bitchat.android.util.AppConstants.UI.PERMISSION_FORCE_FINISH,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
// Check if this is a quit request from the notification
|
||||
if (intent.getBooleanExtra("ACTION_QUIT_APP", false)) {
|
||||
android.util.Log.d("MainActivity", "Quit request received in onCreate, finishing activity")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
com.bitchat.android.service.AppShutdownCoordinator.cancelPendingShutdown()
|
||||
|
||||
// Enable edge-to-edge display for modern Android look
|
||||
enableEdgeToEdge()
|
||||
|
||||
// Initialize permission management
|
||||
permissionManager = PermissionManager(this)
|
||||
// Initialize core mesh service first
|
||||
meshService = BluetoothMeshService(this)
|
||||
// Ensure foreground service is running and get mesh instance from holder
|
||||
try { com.bitchat.android.service.MeshForegroundService.start(applicationContext) } catch (_: Exception) { }
|
||||
meshService = com.bitchat.android.service.MeshServiceHolder.getOrCreate(applicationContext)
|
||||
// Expose BLE mesh to Wi‑Fi Aware controller for cross-transport relays
|
||||
try { com.bitchat.android.wifiaware.WifiAwareController.setBleMeshService(meshService) } catch (_: Exception) { }
|
||||
bluetoothStatusManager = BluetoothStatusManager(
|
||||
@@ -131,6 +170,13 @@ class MainActivity : OrientationAwareActivity() {
|
||||
if (running && svc != null) {
|
||||
svc.delegate = object : com.bitchat.android.wifiaware.WifiAwareMeshDelegate {
|
||||
override fun didReceiveMessage(message: com.bitchat.android.model.BitchatMessage) {
|
||||
if (message.isPrivate) {
|
||||
message.senderPeerID?.let { pid -> com.bitchat.android.services.AppStateStore.addPrivateMessage(pid, message) }
|
||||
} else if (message.channel != null) {
|
||||
com.bitchat.android.services.AppStateStore.addChannelMessage(message.channel, message)
|
||||
} else {
|
||||
com.bitchat.android.services.AppStateStore.addPublicMessage(message)
|
||||
}
|
||||
chatViewModel.didReceiveMessage(message)
|
||||
}
|
||||
override fun didUpdatePeerList(peers: List<String>) {
|
||||
@@ -678,6 +724,17 @@ class MainActivity : OrientationAwareActivity() {
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
|
||||
// Check if this is a quit request from the notification
|
||||
if (intent.getBooleanExtra("ACTION_QUIT_APP", false)) {
|
||||
android.util.Log.d("MainActivity", "Quit request received, finishing activity")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
com.bitchat.android.service.AppShutdownCoordinator.cancelPendingShutdown()
|
||||
|
||||
// Handle notification intents when app is already running
|
||||
if (mainViewModel.onboardingState.value == OnboardingState.COMPLETE) {
|
||||
handleNotificationIntent(intent)
|
||||
@@ -688,6 +745,8 @@ class MainActivity : OrientationAwareActivity() {
|
||||
super.onResume()
|
||||
// Check Bluetooth and Location status on resume and handle accordingly
|
||||
if (mainViewModel.onboardingState.value == OnboardingState.COMPLETE) {
|
||||
// Reattach mesh delegate to new ChatViewModel instance after Activity recreation
|
||||
try { meshService.delegate = chatViewModel } catch (_: Exception) { }
|
||||
// Set app foreground state
|
||||
meshService.connectionManager.setAppBackgroundState(false)
|
||||
chatViewModel.setAppBackgroundState(false)
|
||||
@@ -713,13 +772,15 @@ class MainActivity : OrientationAwareActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
// Only set background state if app is fully initialized
|
||||
if (mainViewModel.onboardingState.value == OnboardingState.COMPLETE) {
|
||||
// Set app background state
|
||||
meshService.connectionManager.setAppBackgroundState(true)
|
||||
chatViewModel.setAppBackgroundState(true)
|
||||
// Detach UI delegate so the foreground service can own DM notifications while UI is closed
|
||||
try { meshService.delegate = null } catch (_: Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -786,6 +847,8 @@ class MainActivity : OrientationAwareActivity() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
try { unregisterReceiver(forceFinishReceiver) } catch (_: Exception) { }
|
||||
|
||||
// Cleanup location status manager
|
||||
try {
|
||||
locationStatusManager.cleanup()
|
||||
@@ -794,14 +857,6 @@ class MainActivity : OrientationAwareActivity() {
|
||||
Log.w("MainActivity", "Error cleaning up location status manager: ${e.message}")
|
||||
}
|
||||
|
||||
// Stop mesh services if app was fully initialized
|
||||
if (mainViewModel.onboardingState.value == OnboardingState.COMPLETE) {
|
||||
try {
|
||||
meshService.stopServices()
|
||||
Log.d("MainActivity", "Mesh services stopped successfully")
|
||||
} catch (e: Exception) {
|
||||
Log.w("MainActivity", "Error stopping mesh services in onDestroy: ${e.message}")
|
||||
}
|
||||
}
|
||||
// Do not stop mesh here; ForegroundService owns lifecycle for background reliability
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user