Unregister the pusher when the topic is deleted (unregistered)

This commit is contained in:
Benoit Marty
2025-11-13 12:26:35 +01:00
parent 29889ad9ec
commit 5864c055d5
3 changed files with 77 additions and 18 deletions

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.pushproviders.unifiedpush
import dev.zacsweers.metro.AppScope
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.pushstore.api.clientsecret.PushClientSecret
import timber.log.Timber
private val loggerTag = LoggerTag("UnifiedPushRemovedGatewayHandler", LoggerTag.PushLoggerTag)
/**
* Handle new endpoint received from UnifiedPush. Will update the session matching the client secret.
*/
interface UnifiedPushRemovedGatewayHandler {
suspend fun handle(clientSecret: String): Result<Unit>
}
@ContributesBinding(AppScope::class)
class DefaultUnifiedPushRemovedGatewayHandler(
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
private val pushClientSecret: PushClientSecret,
private val matrixClientProvider: MatrixClientProvider,
) : UnifiedPushRemovedGatewayHandler {
override suspend fun handle(clientSecret: String): Result<Unit> {
// Unregister the pusher for the session with this client secret, if is it using UnifiedPush.
val userId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
IllegalStateException("Unable to retrieve session")
).also {
Timber.tag(loggerTag.value).w("Unable to retrieve session")
}
return matrixClientProvider
.getOrRestore(userId)
.flatMap { client ->
unregisterUnifiedPushUseCase.unregister(
matrixClient = client,
clientSecret = clientSecret,
unregisterUnifiedPush = false,
)
}
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher")
}
}
}

View File

@@ -21,12 +21,19 @@ interface UnregisterUnifiedPushUseCase {
/**
* Unregister the app from the homeserver, then from UnifiedPush.
*/
suspend fun unregister(matrixClient: MatrixClient, clientSecret: String): Result<Unit>
suspend fun unregister(
matrixClient: MatrixClient,
clientSecret: String,
unregisterUnifiedPush: Boolean = true,
): Result<Unit>
/**
* Cleanup any remaining data for the given client secret and unregister the app from UnifiedPush.
*/
fun cleanup(clientSecret: String)
fun cleanup(
clientSecret: String,
unregisterUnifiedPush: Boolean = true,
)
}
@ContributesBinding(AppScope::class)
@@ -35,7 +42,11 @@ class DefaultUnregisterUnifiedPushUseCase(
private val unifiedPushStore: UnifiedPushStore,
private val pusherSubscriber: PusherSubscriber,
) : UnregisterUnifiedPushUseCase {
override suspend fun unregister(matrixClient: MatrixClient, clientSecret: String): Result<Unit> {
override suspend fun unregister(
matrixClient: MatrixClient,
clientSecret: String,
unregisterUnifiedPush: Boolean,
): Result<Unit> {
val endpoint = unifiedPushStore.getEndpoint(clientSecret)
val gateway = unifiedPushStore.getPushGateway(clientSecret)
if (endpoint == null || gateway == null) {
@@ -46,13 +57,15 @@ class DefaultUnregisterUnifiedPushUseCase(
}
return pusherSubscriber.unregisterPusher(matrixClient, endpoint, gateway)
.onSuccess {
cleanup(clientSecret)
cleanup(clientSecret, unregisterUnifiedPush)
}
}
override fun cleanup(clientSecret: String) {
override fun cleanup(clientSecret: String, unregisterUnifiedPush: Boolean) {
unifiedPushStore.storeUpEndpoint(clientSecret, null)
unifiedPushStore.storePushGateway(clientSecret, null)
UnifiedPush.unregister(context, clientSecret)
if (unregisterUnifiedPush) {
UnifiedPush.unregister(context, clientSecret)
}
}
}

View File

@@ -35,7 +35,9 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
@Inject lateinit var unifiedPushGatewayResolver: UnifiedPushGatewayResolver
@Inject lateinit var unifiedPushGatewayUrlResolver: UnifiedPushGatewayUrlResolver
@Inject lateinit var newGatewayHandler: UnifiedPushNewGatewayHandler
@Inject lateinit var removedGatewayHandler: UnifiedPushRemovedGatewayHandler
@Inject lateinit var endpointRegistrationHandler: EndpointRegistrationHandler
@AppCoroutineScope
@Inject lateinit var coroutineScope: CoroutineScope
@@ -116,18 +118,9 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
* Called when this application is unregistered from receiving push messages.
*/
override fun onUnregistered(context: Context, instance: String) {
Timber.tag(loggerTag.value).w("UnifiedPush: Unregistered")
/*
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
pushDataStore.setFdroidSyncBackgroundMode(mode)
guardServiceStarter.start()
runBlocking {
try {
pushersManager.unregisterPusher(unifiedPushHelper.getEndpointOrToken().orEmpty())
} catch (e: Exception) {
Timber.tag(loggerTag.value).d("Probably unregistering a non existing pusher")
}
Timber.tag(loggerTag.value).w("onUnregistered $instance")
coroutineScope.launch {
removedGatewayHandler.handle(instance)
}
*/
}
}