UnifiedPush: emit error when registration fails.

Note that I did not manage to have the method `onRegistrationFailed` invoked. If the network is not available for instance, unregistering the previous pusher will fail first.
This commit is contained in:
Benoit Marty 2025-11-13 12:34:40 +01:00
parent 6b7e8f72f5
commit f9c0b9e8bb
16 changed files with 208 additions and 23 deletions

View file

@ -12,6 +12,7 @@ import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.core.extensions.flatMap
import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
import timber.log.Timber
@ -20,7 +21,7 @@ private val loggerTag = LoggerTag("UnifiedPushRemovedGatewayHandler", LoggerTag.
/**
* Handle new endpoint received from UnifiedPush. Will update the session matching the client secret.
*/
interface UnifiedPushRemovedGatewayHandler {
fun interface UnifiedPushRemovedGatewayHandler {
suspend fun handle(clientSecret: String): Result<Unit>
}
@ -29,9 +30,10 @@ class DefaultUnifiedPushRemovedGatewayHandler(
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
private val pushClientSecret: PushClientSecret,
private val matrixClientProvider: MatrixClientProvider,
private val pushService: PushService,
) : UnifiedPushRemovedGatewayHandler {
override suspend fun handle(clientSecret: String): Result<Unit> {
// Unregister the pusher for the session with this client secret, if is it using UnifiedPush.
// Unregister the pusher for the session with this client secret.
val userId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
IllegalStateException("Unable to retrieve session")
).also {
@ -39,15 +41,42 @@ class DefaultUnifiedPushRemovedGatewayHandler(
}
return matrixClientProvider
.getOrRestore(userId)
.onFailure {
Timber.tag(loggerTag.value).w(it, "Fails to restore client")
}
.flatMap { client ->
unregisterUnifiedPushUseCase.unregister(
matrixClient = client,
clientSecret = clientSecret,
unregisterUnifiedPush = false,
)
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher")
}
.flatMap {
val pushProvider = pushService.getCurrentPushProvider(userId)
val distributor = pushProvider?.getCurrentDistributor(userId)
// Attempt to register again
if (pushProvider != null && distributor != null) {
pushService.registerWith(
client,
pushProvider,
distributor,
)
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to register with current data")
}
} else {
Result.failure(IllegalStateException("Unable to register again"))
}
}
.onFailure {
// Let the user know
pushService.onServiceUnregistered(userId)
}
}
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher")
Timber.tag(loggerTag.value).w(it, "Issue during pusher unregistration / re registration")
}
}
}

View file

@ -106,12 +106,14 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
*/
override fun onRegistrationFailed(context: Context, reason: FailedReason, instance: String) {
Timber.tag(loggerTag.value).e("onRegistrationFailed for $instance, reason: $reason")
/*
Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show()
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
pushDataStore.setFdroidSyncBackgroundMode(mode)
guardServiceStarter.start()
*/
coroutineScope.launch {
endpointRegistrationHandler.registrationDone(
RegistrationResult(
clientSecret = instance,
result = Result.failure(Exception("Registration failed. Reason: $reason")),
)
)
}
}
/**