diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt index 313f4aafe0..838780edc8 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt @@ -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) + } + } } } diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt index abfc328e9f..fdb1d939ae 100644 --- a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt +++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/PushService.kt @@ -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. diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt index cff18cfb3d..fe4d24882b 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt @@ -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 { 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 diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/Distributor.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/Distributor.kt index 7eda80fed9..1db3dc2610 100644 --- a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/Distributor.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/Distributor.kt @@ -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, diff --git a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt index 4e9b818dd4..a1c99df3fb 100644 --- a/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt +++ b/libraries/pushproviders/api/src/main/kotlin/io/element/android/libraries/pushproviders/api/PushProvider.kt @@ -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. */ diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt index 317d49f3b6..c53b2815fe 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/FirebasePushProvider.kt @@ -43,7 +43,7 @@ class FirebasePushProvider @Inject constructor( } override fun getDistributors(): List { - 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") + } } diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt index e7ea1841c5..9c9d9b034b 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushProvider.kt @@ -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) { diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt index d063dfce3e..7b6ee5ef37 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushStore.kt @@ -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" } }