fix: pause geohash heartbeat (kind 20001) sampling when backgrounded (#660)

This commit is contained in:
a1denvalu3
2026-02-01 13:25:36 +01:00
committed by GitHub
parent 73d8ce56a2
commit 43029e88e6
@@ -3,6 +3,10 @@ package com.bitchat.android.ui
import android.app.Application import android.app.Application
import android.util.Log import android.util.Log
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.bitchat.android.nostr.GeohashMessageHandler import com.bitchat.android.nostr.GeohashMessageHandler
import com.bitchat.android.nostr.GeohashRepository import com.bitchat.android.nostr.GeohashRepository
@@ -31,7 +35,7 @@ class GeohashViewModel(
private val meshDelegateHandler: MeshDelegateHandler, private val meshDelegateHandler: MeshDelegateHandler,
private val dataManager: DataManager, private val dataManager: DataManager,
private val notificationManager: NotificationManager private val notificationManager: NotificationManager
) : AndroidViewModel(application) { ) : AndroidViewModel(application), DefaultLifecycleObserver {
companion object { private const val TAG = "GeohashViewModel" } companion object { private const val TAG = "GeohashViewModel" }
@@ -68,6 +72,10 @@ class GeohashViewModel(
fun initialize() { fun initialize() {
subscriptionManager.connect() subscriptionManager.connect()
// Observe process lifecycle to manage background sampling
kotlin.runCatching {
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
val identity = NostrIdentityBridge.getCurrentNostrIdentity(getApplication()) val identity = NostrIdentityBridge.getCurrentNostrIdentity(getApplication())
if (identity != null) { if (identity != null) {
// Use global chat-messages only for full account DMs (mesh context). For geohash DMs, subscribe per-geohash below. // Use global chat-messages only for full account DMs (mesh context). For geohash DMs, subscribe per-geohash below.
@@ -235,15 +243,11 @@ class GeohashViewModel(
} }
// Add new subscriptions // Add new subscriptions
activeSamplingGeohashes.addAll(toAdd)
if (isAppInForeground()) {
toAdd.forEach { geohash -> toAdd.forEach { geohash ->
subscriptionManager.subscribeGeohash( performSubscribeSampling(geohash)
geohash = geohash, }
sinceMs = System.currentTimeMillis() - 86400000L,
limit = 200,
id = "sampling-$geohash",
handler = { event -> geohashMessageHandler.onEvent(event, geohash) }
)
activeSamplingGeohashes.add(geohash)
} }
} }
@@ -379,4 +383,35 @@ class GeohashViewModel(
} }
} }
} }
override fun onCleared() {
super.onCleared()
kotlin.runCatching {
ProcessLifecycleOwner.get().lifecycle.removeObserver(this)
}
}
override fun onStart(owner: LifecycleOwner) {
Log.d(TAG, "🌍 App foregrounded: Resuming sampling for ${activeSamplingGeohashes.size} geohashes")
activeSamplingGeohashes.forEach { performSubscribeSampling(it) }
}
override fun onStop(owner: LifecycleOwner) {
Log.d(TAG, "🌍 App backgrounded: Pausing sampling for ${activeSamplingGeohashes.size} geohashes")
activeSamplingGeohashes.forEach { subscriptionManager.unsubscribe("sampling-$it") }
}
private fun performSubscribeSampling(geohash: String) {
subscriptionManager.subscribeGeohash(
geohash = geohash,
sinceMs = System.currentTimeMillis() - 86400000L,
limit = 200,
id = "sampling-$geohash",
handler = { event -> geohashMessageHandler.onEvent(event, geohash) }
)
}
private fun isAppInForeground(): Boolean {
return ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
}
} }