mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 23:45:19 +00:00
dynamic direct connection detection
This commit is contained in:
@@ -111,6 +111,13 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
return signPacketBeforeBroadcast(packet)
|
return signPacketBeforeBroadcast(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inject dynamic direct connection check into PeerManager
|
||||||
|
// Matches iOS logic: checks if we have an active hardware mapping for this peer
|
||||||
|
peerManager.isPeerDirectlyConnected = { peerID ->
|
||||||
|
connectionManager.addressPeerMap.containsValue(peerID)
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Delegates set up; GossipSyncManager initialized")
|
Log.d(TAG, "Delegates set up; GossipSyncManager initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,8 +485,8 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
connectionManager.addressPeerMap[deviceAddress] = pid
|
connectionManager.addressPeerMap[deviceAddress] = pid
|
||||||
Log.d(TAG, "Mapped device $deviceAddress to peer $pid (TTL=${routed.packet.ttl})")
|
Log.d(TAG, "Mapped device $deviceAddress to peer $pid (TTL=${routed.packet.ttl})")
|
||||||
|
|
||||||
// Mark as directly connected
|
// Mark as directly connected - refresh UI state
|
||||||
try { peerManager.setDirectConnection(pid, true) } catch (_: Exception) { }
|
try { peerManager.refreshPeerList() } catch (_: Exception) { }
|
||||||
|
|
||||||
// Initial sync for this direct peer
|
// Initial sync for this direct peer
|
||||||
try { gossipSyncManager.scheduleInitialSyncToPeer(pid, 1_000) } catch (_: Exception) { }
|
try { gossipSyncManager.scheduleInitialSyncToPeer(pid, 1_000) } catch (_: Exception) { }
|
||||||
@@ -584,8 +591,8 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
if (peer != null) {
|
if (peer != null) {
|
||||||
val stillMapped = connectionManager.addressPeerMap.values.any { it == peer }
|
val stillMapped = connectionManager.addressPeerMap.values.any { it == peer }
|
||||||
if (!stillMapped) {
|
if (!stillMapped) {
|
||||||
// Peer might still be reachable indirectly; mark as not-direct
|
// Peer might still be reachable indirectly; refresh to update state
|
||||||
try { peerManager.setDirectConnection(peer, false) } catch (_: Exception) { }
|
try { peerManager.refreshPeerList() } catch (_: Exception) { }
|
||||||
}
|
}
|
||||||
// Verbose debug: device disconnected
|
// Verbose debug: device disconnected
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ class PeerManager {
|
|||||||
// Delegate for callbacks
|
// Delegate for callbacks
|
||||||
var delegate: PeerManagerDelegate? = null
|
var delegate: PeerManagerDelegate? = null
|
||||||
|
|
||||||
|
// Callback to check if a peer is directly connected (injected by BluetoothMeshService)
|
||||||
|
var isPeerDirectlyConnected: ((String) -> Boolean)? = null
|
||||||
|
|
||||||
// Coroutines
|
// Coroutines
|
||||||
private val managerScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
private val managerScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||||
|
|
||||||
@@ -145,10 +148,18 @@ class PeerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get peer info
|
* Get peer info with dynamic direct connection status
|
||||||
*/
|
*/
|
||||||
fun getPeerInfo(peerID: String): PeerInfo? {
|
fun getPeerInfo(peerID: String): PeerInfo? {
|
||||||
return peers[peerID]
|
return peers[peerID]?.let { info ->
|
||||||
|
// Dynamically check direct connection status from ConnectionManager
|
||||||
|
val isDirect = isPeerDirectlyConnected?.invoke(peerID) ?: false
|
||||||
|
if (info.isDirectConnection != isDirect) {
|
||||||
|
info.copy(isDirectConnection = isDirect)
|
||||||
|
} else {
|
||||||
|
info
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,28 +170,21 @@ class PeerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all verified peers
|
* Get all verified peers with dynamic direct connection status
|
||||||
*/
|
*/
|
||||||
fun getVerifiedPeers(): Map<String, PeerInfo> {
|
fun getVerifiedPeers(): Map<String, PeerInfo> {
|
||||||
return peers.filterValues { it.isVerifiedNickname }
|
return peers.filterValues { it.isVerifiedNickname }.mapValues { (_, info) ->
|
||||||
|
val isDirect = isPeerDirectlyConnected?.invoke(info.id) ?: false
|
||||||
|
if (info.isDirectConnection != isDirect) info.copy(isDirectConnection = isDirect) else info
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether a peer is directly connected over Bluetooth.
|
* Force a peer list update notification.
|
||||||
* Triggers a peer list update to refresh UI badges.
|
* Call this when connection state changes to refresh UI badges.
|
||||||
*/
|
*/
|
||||||
fun setDirectConnection(peerID: String, isDirect: Boolean) {
|
fun refreshPeerList() {
|
||||||
peers[peerID]?.let { existing ->
|
notifyPeerListUpdate()
|
||||||
if (existing.isDirectConnection != isDirect) {
|
|
||||||
peers[peerID] = existing.copy(isDirectConnection = isDirect)
|
|
||||||
notifyPeerListUpdate()
|
|
||||||
// NEW: notify UI state (if available via delegate path) about directness change
|
|
||||||
try {
|
|
||||||
// Best-effort: delegate path flows up to ChatViewModel via didUpdatePeerList
|
|
||||||
// No direct reference to UI layer here by design.
|
|
||||||
} catch (_: Exception) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Legacy Methods (maintained for compatibility)
|
// MARK: - Legacy Methods (maintained for compatibility)
|
||||||
@@ -364,7 +368,11 @@ class PeerManager {
|
|||||||
return buildString {
|
return buildString {
|
||||||
appendLine("=== Peer Manager Debug Info ===")
|
appendLine("=== Peer Manager Debug Info ===")
|
||||||
appendLine("Active Peers: ${activeIds.size}")
|
appendLine("Active Peers: ${activeIds.size}")
|
||||||
peers.forEach { (peerID, info) ->
|
peers.forEach { (peerID, storedInfo) ->
|
||||||
|
// Use dynamic direct status for debug log accuracy
|
||||||
|
val isDirect = isPeerDirectlyConnected?.invoke(peerID) ?: false
|
||||||
|
val info = if (storedInfo.isDirectConnection != isDirect) storedInfo.copy(isDirectConnection = isDirect) else storedInfo
|
||||||
|
|
||||||
val timeSince = (now - info.lastSeen) / 1000
|
val timeSince = (now - info.lastSeen) / 1000
|
||||||
val rssi = peerRSSI[peerID]?.let { "${it} dBm" } ?: "No RSSI"
|
val rssi = peerRSSI[peerID]?.let { "${it} dBm" } ?: "No RSSI"
|
||||||
val deviceAddress = addressPeerMap?.entries?.find { it.value == peerID }?.key
|
val deviceAddress = addressPeerMap?.entries?.find { it.value == peerID }?.key
|
||||||
|
|||||||
Reference in New Issue
Block a user