mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 22:25:19 +00:00
fix review
This commit is contained in:
@@ -101,20 +101,9 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
}
|
||||
)
|
||||
|
||||
// Wire sync manager delegate
|
||||
gossipSyncManager.delegate = object : GossipSyncManager.Delegate {
|
||||
override fun sendPacket(packet: BitchatPacket) {
|
||||
broadcastRoutedPacket(RoutedPacket(packet))
|
||||
}
|
||||
override fun sendPacketToPeer(peerID: String, packet: BitchatPacket) {
|
||||
sendPacketToPeerAcrossTransports(peerID, packet)
|
||||
}
|
||||
override fun signPacketForBroadcast(packet: BitchatPacket): BitchatPacket {
|
||||
return signPacketBeforeBroadcast(packet)
|
||||
}
|
||||
com.bitchat.android.service.MeshServiceHolder.setGossipManager(gossipSyncManager) { packet ->
|
||||
signPacketBeforeBroadcast(packet)
|
||||
}
|
||||
|
||||
com.bitchat.android.service.MeshServiceHolder.setGossipManager(gossipSyncManager)
|
||||
if (isBleTransportEnabled()) {
|
||||
TransportBridgeService.register("BLE", this)
|
||||
}
|
||||
@@ -144,13 +133,6 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
TransportBridgeService.broadcast("BLE", routed)
|
||||
}
|
||||
|
||||
private fun sendPacketToPeerAcrossTransports(peerID: String, packet: BitchatPacket): Boolean {
|
||||
if (!isBleTransportEnabled()) return false
|
||||
val sentOverBle = connectionManager.sendPacketToPeer(peerID, packet)
|
||||
TransportBridgeService.sendToPeer("BLE", peerID, packet)
|
||||
return sentOverBle
|
||||
}
|
||||
|
||||
private fun isBleTransportEnabled(): Boolean {
|
||||
return try {
|
||||
com.bitchat.android.ui.debug.DebugSettingsManager.getInstance().bleEnabled.value
|
||||
@@ -670,8 +652,9 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
Log.i(TAG, "BLE transport disabled by debug settings; not starting mesh service")
|
||||
connectionManager.disableTransport()
|
||||
TransportBridgeService.unregister("BLE")
|
||||
com.bitchat.android.service.MeshServiceHolder.stopSharedGossip("BLE")
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportPeers("BLE") } catch (_: Exception) { }
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportDirectPeers("BLE") } catch (_: Exception) { }
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportDirectPeers("BLE") } catch (_: Exception) { }
|
||||
return
|
||||
}
|
||||
if (terminated) {
|
||||
@@ -690,7 +673,7 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
sendPeriodicBroadcastAnnounce()
|
||||
Log.d(TAG, "Started periodic broadcast announcements (every 30 seconds)")
|
||||
// Start periodic syncs
|
||||
gossipSyncManager.start()
|
||||
com.bitchat.android.service.MeshServiceHolder.startSharedGossip("BLE")
|
||||
Log.d(TAG, "GossipSyncManager started")
|
||||
} else {
|
||||
Log.e(TAG, "Failed to start Bluetooth services")
|
||||
@@ -713,7 +696,7 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
isActive = false
|
||||
announceJob?.cancel()
|
||||
announceJob = null
|
||||
try { gossipSyncManager.stop() } catch (_: Exception) { }
|
||||
com.bitchat.android.service.MeshServiceHolder.stopSharedGossip("BLE")
|
||||
TransportBridgeService.unregister("BLE")
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportPeers("BLE") } catch (_: Exception) { }
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportDirectPeers("BLE") } catch (_: Exception) { }
|
||||
@@ -746,7 +729,7 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
|
||||
delay(200) // Give leave message time to send
|
||||
|
||||
// Stop all components
|
||||
gossipSyncManager.stop()
|
||||
com.bitchat.android.service.MeshServiceHolder.stopSharedGossip("BLE")
|
||||
Log.d(TAG, "GossipSyncManager stopped")
|
||||
connectionManager.stopServices()
|
||||
Log.d(TAG, "BluetoothConnectionManager stop requested")
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.bitchat.android.service
|
||||
import android.content.Context
|
||||
import com.bitchat.android.mesh.BluetoothMeshService
|
||||
import com.bitchat.android.mesh.UnifiedMeshService
|
||||
import com.bitchat.android.model.RoutedPacket
|
||||
import com.bitchat.android.protocol.BitchatPacket
|
||||
import com.bitchat.android.sync.GossipSyncManager
|
||||
|
||||
/**
|
||||
* Process-wide holder to share a single BluetoothMeshService instance
|
||||
@@ -11,10 +14,59 @@ import com.bitchat.android.mesh.UnifiedMeshService
|
||||
object MeshServiceHolder {
|
||||
private const val TAG = "MeshServiceHolder"
|
||||
@Volatile
|
||||
var sharedGossipSyncManager: com.bitchat.android.sync.GossipSyncManager? = null
|
||||
var sharedGossipSyncManager: GossipSyncManager? = null
|
||||
private set
|
||||
|
||||
fun setGossipManager(mgr: com.bitchat.android.sync.GossipSyncManager) { sharedGossipSyncManager = mgr }
|
||||
private val activeGossipOwners = mutableSetOf<String>()
|
||||
|
||||
@Synchronized
|
||||
fun setGossipManager(
|
||||
mgr: GossipSyncManager,
|
||||
signer: (BitchatPacket) -> BitchatPacket
|
||||
) {
|
||||
val previous = sharedGossipSyncManager
|
||||
if (previous !== mgr) {
|
||||
try { previous?.stop() } catch (_: Exception) { }
|
||||
}
|
||||
sharedGossipSyncManager = mgr
|
||||
mgr.delegate = TransportGossipDelegate(signer)
|
||||
if (activeGossipOwners.isNotEmpty()) {
|
||||
mgr.start()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun startSharedGossip(owner: String) {
|
||||
val wasIdle = activeGossipOwners.isEmpty()
|
||||
activeGossipOwners.add(owner)
|
||||
if (wasIdle) {
|
||||
sharedGossipSyncManager?.start()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun stopSharedGossip(owner: String) {
|
||||
activeGossipOwners.remove(owner)
|
||||
if (activeGossipOwners.isEmpty()) {
|
||||
sharedGossipSyncManager?.stop()
|
||||
}
|
||||
}
|
||||
|
||||
private class TransportGossipDelegate(
|
||||
private val signer: (BitchatPacket) -> BitchatPacket
|
||||
) : GossipSyncManager.Delegate {
|
||||
override fun sendPacket(packet: BitchatPacket) {
|
||||
TransportBridgeService.broadcastFromLocal(RoutedPacket(packet))
|
||||
}
|
||||
|
||||
override fun sendPacketToPeer(peerID: String, packet: BitchatPacket) {
|
||||
TransportBridgeService.sendToPeerFromLocal(peerID, packet)
|
||||
}
|
||||
|
||||
override fun signPacketForBroadcast(packet: BitchatPacket): BitchatPacket {
|
||||
return signer(packet)
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
var meshService: BluetoothMeshService? = null
|
||||
@@ -84,6 +136,9 @@ object MeshServiceHolder {
|
||||
@Synchronized
|
||||
fun clear() {
|
||||
android.util.Log.d(TAG, "Clearing BluetoothMeshService from holder")
|
||||
try { sharedGossipSyncManager?.stop() } catch (_: Exception) { }
|
||||
sharedGossipSyncManager = null
|
||||
activeGossipOwners.clear()
|
||||
meshService = null
|
||||
unifiedMeshService = null
|
||||
}
|
||||
|
||||
@@ -105,6 +105,40 @@ object TransportBridgeService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a locally originated packet to every active transport without applying relay TTL
|
||||
* handling. This is used for neighbor-only packets such as REQUEST_SYNC whose TTL is
|
||||
* intentionally zero on the first radio hop.
|
||||
*/
|
||||
fun broadcastFromLocal(packet: RoutedPacket) {
|
||||
val targets = transports.toMap()
|
||||
if (targets.isEmpty()) return
|
||||
|
||||
targets.forEach { (id, layer) ->
|
||||
try {
|
||||
layer.send(packet)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to send local packet to $id: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a locally originated packet directly to a peer on every active transport.
|
||||
*/
|
||||
fun sendToPeerFromLocal(peerID: String, packet: BitchatPacket) {
|
||||
val targets = transports.toMap()
|
||||
if (targets.isEmpty()) return
|
||||
|
||||
targets.forEach { (id, layer) ->
|
||||
try {
|
||||
layer.sendToPeer(peerID, packet)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to send local peer packet to $id: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareForwardedPacket(kind: String, packet: BitchatPacket): BitchatPacket? {
|
||||
if (packet.ttl == 0u.toUByte()) {
|
||||
Log.d(TAG, "Dropping bridged packet type ${packet.type}: TTL expired")
|
||||
|
||||
@@ -492,12 +492,13 @@ class WifiAwareMeshService(private val context: Context) : MeshService, Transpor
|
||||
}
|
||||
}, Handler(Looper.getMainLooper()))
|
||||
|
||||
meshCore.startCore()
|
||||
startPeriodicConnectionMaintenance()
|
||||
connectionTracker.start()
|
||||
|
||||
// Register with cross-layer transport bridge
|
||||
TransportBridgeService.register("WIFI", this)
|
||||
|
||||
meshCore.startCore()
|
||||
com.bitchat.android.service.MeshServiceHolder.startSharedGossip("WIFI")
|
||||
startPeriodicConnectionMaintenance()
|
||||
connectionTracker.start()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,6 +512,7 @@ class WifiAwareMeshService(private val context: Context) : MeshService, Transpor
|
||||
|
||||
// Unregister from bridge
|
||||
TransportBridgeService.unregister("WIFI")
|
||||
com.bitchat.android.service.MeshServiceHolder.stopSharedGossip("WIFI")
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportPeers("WIFI") } catch (_: Exception) { }
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportDirectPeers("WIFI") } catch (_: Exception) { }
|
||||
|
||||
@@ -554,6 +556,7 @@ class WifiAwareMeshService(private val context: Context) : MeshService, Transpor
|
||||
recoveryInProgress = true
|
||||
isActive = false
|
||||
TransportBridgeService.unregister("WIFI")
|
||||
com.bitchat.android.service.MeshServiceHolder.stopSharedGossip("WIFI")
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportPeers("WIFI") } catch (_: Exception) { }
|
||||
try { com.bitchat.android.services.AppStateStore.clearTransportDirectPeers("WIFI") } catch (_: Exception) { }
|
||||
val oldPublishSession = publishSession
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.bitchat.android.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.bitchat.android.mesh.BluetoothMeshService
|
||||
import com.bitchat.android.mesh.MeshService
|
||||
import com.bitchat.android.model.BitchatMessage
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -34,7 +34,7 @@ class CommandProcessorTest() {
|
||||
coroutineScope = testScope
|
||||
)
|
||||
|
||||
private val meshService: BluetoothMeshService = mock()
|
||||
private val meshService: MeshService = mock()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
|
||||
Reference in New Issue
Block a user