fix: show the new-mail notification when the connection kept from the foreground has died #94

This commit is contained in:
Linus Rath
2026-11-05 22:28:57 +01:00
parent 8d03f5c442
commit e3525a0583
5 changed files with 104 additions and 3 deletions
@@ -66,7 +66,12 @@ class BulwarkMessagingService : FirebaseMessagingService() {
fun startTaskUnlessInForeground(context: Context, data: Map<String, String>, mail: Boolean) {
val foreground = MainActivity.isInForeground
Log.i(TAG, "Push: mail=$mail foreground=$foreground importance=${processImportance()}")
if (mail && !foreground) startHeadlessTask(context, data)
if (mail && !foreground) {
// The task opens its own connection rather than one left
// over from the foreground, which may be dead (#94).
HttpConnections.dropIdle()
startHeadlessTask(context, data)
}
}
/** For the log only. */
@@ -0,0 +1,41 @@
package com.anonymous.bulwarkmobile
import android.content.Context
import com.facebook.react.modules.network.OkHttpClientFactory
import com.facebook.react.modules.network.OkHttpClientProvider
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
/**
* One connection pool for every OkHttp client React Native builds (fetch,
* XMLHttpRequest and the event stream on top of it), so the push path can
* drop the connections the app kept from the foreground.
*
* React Native's client has no connect or read timeout. A connection that
* died silently while the app was in the background (a mobile network's NAT
* forgot it, the server closed it and the FIN never arrived) stays in the
* pool, and the push task's first request was sent down it and waited until
* the task's 30 s timeout: no request reached the server and no
* notification appeared (#94). A fresh connection costs one TLS handshake.
*/
object HttpConnections {
private val pool = ConnectionPool()
/** Call before React Native creates its first network module. */
fun install(context: Context) {
val app = context.applicationContext
OkHttpClientProvider.setOkHttpClientFactory(
object : OkHttpClientFactory {
override fun createNewNetworkModuleClient(): OkHttpClient =
OkHttpClientProvider.createClientBuilder(app)
.connectionPool(pool)
.build()
},
)
}
/** Closes every pooled connection no request is using. */
fun dropIdle() {
pool.evictAll()
}
}
@@ -40,6 +40,7 @@ class MainApplication : Application(), ReactApplication {
override fun onCreate() {
super.onCreate()
HttpConnections.install(this)
DefaultNewArchitectureEntryPoint.releaseLevel = try {
ReleaseLevel.valueOf(BuildConfig.REACT_NATIVE_RELEASE_LEVEL.uppercase())
} catch (e: IllegalArgumentException) {