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 e70a44aa2b..e780770b8b 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 @@ -113,14 +113,21 @@ class LoggedInPresenter @Inject constructor( Timber.tag(pusherTag.value).d("Ensure pusher is registered") val currentPushProvider = pushService.getCurrentPushProvider() val result = if (currentPushProvider == null) { - Timber.tag(pusherTag.value).d("Register with the first available push provider") - val pushProvider = pushService.getAvailablePushProviders().firstOrNull() + Timber.tag(pusherTag.value).d("Register with the first available push provider with at least one distributor") + val pushProvider = pushService.getAvailablePushProviders() + .firstOrNull { it.getDistributors().isNotEmpty() } + // Else fallback to the first available push provider (the list should never be empty) + ?: pushService.getAvailablePushProviders().firstOrNull() ?: return Unit .also { Timber.tag(pusherTag.value).w("No push providers available") } .also { pusherRegistrationState.value = AsyncData.Failure(PusherRegistrationFailure.NoProvidersAvailable()) } val distributor = pushProvider.getDistributors().firstOrNull() ?: return Unit .also { Timber.tag(pusherTag.value).w("No distributors available") } + .also { + // In this case, consider the push provider is chosen. + pushService.selectPushProvider(matrixClient, pushProvider) + } .also { pusherRegistrationState.value = AsyncData.Failure(PusherRegistrationFailure.NoDistributorsAvailable()) } pushService.registerWith(matrixClient, pushProvider, distributor) } else { 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 af21bd1168..e48ba81d2a 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 @@ -44,6 +44,15 @@ interface PushService { distributor: Distributor, ): Result + /** + * Store the given push provider as the current one, but do not register. + * To be used when there is no distributor available. + */ + suspend fun selectPushProvider( + matrixClient: MatrixClient, + pushProvider: PushProvider, + ) + fun ignoreRegistrationError(sessionId: SessionId): Flow suspend fun setIgnoreRegistrationError(sessionId: SessionId, ignore: Boolean) 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 46105a68db..fa2f1977f4 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 @@ -73,6 +73,15 @@ class DefaultPushService @Inject constructor( return pushProvider.registerWith(matrixClient, distributor) } + override suspend fun selectPushProvider( + matrixClient: MatrixClient, + pushProvider: PushProvider, + ) { + Timber.d("Select ${pushProvider.name}") + val userPushStore = userPushStoreFactory.getOrCreate(matrixClient.sessionId) + userPushStore.setPushProviderName(pushProvider.name) + } + override fun ignoreRegistrationError(sessionId: SessionId): Flow { return userPushStoreFactory.getOrCreate(sessionId).ignoreRegistrationError() } diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt index d9e5f0d2b6..8f3e45c4ce 100644 --- a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt +++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/FakePushService.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.push.api.PushService import io.element.android.libraries.pushproviders.api.Distributor import io.element.android.libraries.pushproviders.api.PushProvider +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.simulateLongTask import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -32,6 +33,7 @@ class FakePushService( Result.success(Unit) }, private val currentPushProvider: () -> PushProvider? = { availablePushProviders.firstOrNull() }, + private val selectPushProviderLambda: suspend (MatrixClient, PushProvider) -> Unit = { _, _ -> lambdaError() } ) : PushService { override suspend fun getCurrentPushProvider(): PushProvider? { return registeredPushProvider ?: currentPushProvider() @@ -56,6 +58,10 @@ class FakePushService( } } + override suspend fun selectPushProvider(matrixClient: MatrixClient, pushProvider: PushProvider) { + selectPushProviderLambda(matrixClient, pushProvider) + } + private val ignoreRegistrationError = MutableStateFlow(false) override fun ignoreRegistrationError(sessionId: SessionId): Flow {