Push distributor: ensure the current UnifiedPush distributor is stored

This commit is contained in:
Benoit Marty
2024-05-06 18:20:49 +02:00
committed by Benoit Marty
parent ae9e489400
commit 3d5fdfc22e
8 changed files with 68 additions and 8 deletions

View File

@@ -55,10 +55,23 @@ class LoggedInPresenter @Inject constructor(
LaunchedEffect(isVerified) {
if (isVerified) {
// Ensure pusher is registered
// TODO Manually select push provider for now
val pushProvider = pushService.getAvailablePushProviders().firstOrNull() ?: return@LaunchedEffect
val distributor = pushProvider.getDistributors().firstOrNull() ?: return@LaunchedEffect
pushService.registerWith(matrixClient, pushProvider, distributor)
val currentPushProvider = pushService.getCurrentPushProvider()
if (currentPushProvider == null) {
// Register with the first available push provider
val pushProvider = pushService.getAvailablePushProviders().firstOrNull() ?: return@LaunchedEffect
val distributor = pushProvider.getDistributors().firstOrNull() ?: return@LaunchedEffect
pushService.registerWith(matrixClient, pushProvider, distributor)
} else {
val currentPushDistributor = currentPushProvider.getCurrentDistributor(matrixClient)
if (currentPushDistributor == null) {
// Register with the first available distributor
val distributor = currentPushProvider.getDistributors().firstOrNull() ?: return@LaunchedEffect
pushService.registerWith(matrixClient, currentPushProvider, distributor)
} else {
// Re-register with the current distributor
pushService.registerWith(matrixClient, currentPushProvider, currentPushDistributor)
}
}
}
}

View File

@@ -24,6 +24,11 @@ interface PushService {
// TODO Move away
fun notificationStyleChanged()
/**
* Return the current push provider, or null if none.
*/
suspend fun getCurrentPushProvider(): PushProvider?
/**
* Return the list of push providers, available at compile time, and
* available at runtime, sorted by index.

View File

@@ -39,6 +39,11 @@ class DefaultPushService @Inject constructor(
defaultNotificationDrawerManager.notificationStyleChanged()
}
override suspend fun getCurrentPushProvider(): PushProvider? {
val currentPushProvider = getCurrentPushProvider.getCurrentPushProvider()
return pushProviders.find { it.name == currentPushProvider }
}
override fun getAvailablePushProviders(): List<PushProvider> {
return pushProviders
.filter { it.isAvailable() }
@@ -51,7 +56,8 @@ class DefaultPushService @Inject constructor(
override suspend fun registerWith(matrixClient: MatrixClient, pushProvider: PushProvider, distributor: Distributor) {
val userPushStore = userPushStoreFactory.getOrCreate(matrixClient.sessionId)
val currentPushProviderName = userPushStore.getPushProviderName()
if (currentPushProviderName != pushProvider.name) {
val currentDistributorValue = pushProvider.getCurrentDistributor(matrixClient)?.value
if (currentPushProviderName != pushProvider.name || currentDistributorValue != distributor.value) {
// Unregister previous one if any
pushProviders.find { it.name == currentPushProviderName }?.unregister(matrixClient)
}
@@ -61,8 +67,7 @@ class DefaultPushService @Inject constructor(
}
override suspend fun testPush(): Boolean {
val currentPushProvider = getCurrentPushProvider.getCurrentPushProvider()
val pushProvider = pushProviders.find { it.name == currentPushProvider } ?: return false
val pushProvider = getCurrentPushProvider() ?: return false
val config = pushProvider.getCurrentUserPushConfig() ?: return false
pushersManager.testPush(config)
return true

View File

@@ -16,6 +16,14 @@
package io.element.android.libraries.pushproviders.api
/**
* Firebase does not have the concept of distributor. So for Firebase, there will be one distributor:
* Distributor("Firebase", "Firebase").
*
* For UnifiedPush, for instance, the Distributor can be:
* Distributor("io.heckel.ntfy", "ntfy").
* But other values are possible.
*/
data class Distributor(
val value: String,
val name: String,

View File

@@ -44,6 +44,11 @@ interface PushProvider {
*/
suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor)
/**
* Return the current distributor, or null if none.
*/
suspend fun getCurrentDistributor(matrixClient: MatrixClient): Distributor?
/**
* Unregister the pusher.
*/

View File

@@ -43,7 +43,7 @@ class FirebasePushProvider @Inject constructor(
}
override fun getDistributors(): List<Distributor> {
return listOf(Distributor("Firebase", "Firebase"))
return listOf(firebaseDistributor)
}
override suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor) {
@@ -53,6 +53,8 @@ class FirebasePushProvider @Inject constructor(
pusherSubscriber.registerPusher(matrixClient, pushKey, FirebaseConfig.PUSHER_HTTP_URL)
}
override suspend fun getCurrentDistributor(matrixClient: MatrixClient) = firebaseDistributor
override suspend fun unregister(matrixClient: MatrixClient) {
val pushKey = firebaseStore.getFcmToken() ?: return Unit.also {
Timber.tag(loggerTag.value).w("Unable to unregister pusher, Firebase token is not known.")
@@ -68,4 +70,8 @@ class FirebasePushProvider @Inject constructor(
)
}
}
companion object {
private val firebaseDistributor = Distributor("Firebase", "Firebase")
}
}

View File

@@ -61,6 +61,12 @@ class UnifiedPushProvider @Inject constructor(
override suspend fun registerWith(matrixClient: MatrixClient, distributor: Distributor) {
val clientSecret = pushClientSecret.getSecretForUser(matrixClient.sessionId)
registerUnifiedPushUseCase.execute(matrixClient, distributor, clientSecret)
unifiedPushStore.setDistributorValue(matrixClient.sessionId, distributor.value)
}
override suspend fun getCurrentDistributor(matrixClient: MatrixClient): Distributor? {
val distributorValue = unifiedPushStore.getDistributorValue(matrixClient.sessionId)
return getDistributors().find { it.value == distributorValue }
}
override suspend fun unregister(matrixClient: MatrixClient) {

View File

@@ -21,6 +21,7 @@ import android.content.SharedPreferences
import androidx.core.content.edit
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.di.DefaultPreferences
import io.element.android.libraries.matrix.api.core.UserId
import javax.inject.Inject
class UnifiedPushStore @Inject constructor(
@@ -71,8 +72,19 @@ class UnifiedPushStore @Inject constructor(
}
}
fun getDistributorValue(userId: UserId): String? {
return defaultPrefs.getString(PREFS_DISTRIBUTOR + userId, null)
}
fun setDistributorValue(userId: UserId, value: String) {
defaultPrefs.edit {
putString(PREFS_DISTRIBUTOR + userId, value)
}
}
companion object {
private const val PREFS_ENDPOINT_OR_TOKEN = "UP_ENDPOINT_OR_TOKEN"
private const val PREFS_PUSH_GATEWAY = "PUSH_GATEWAY"
private const val PREFS_DISTRIBUTOR = "DISTRIBUTOR"
}
}