Wait for UnifiedPush pusher to be registered before returning Result.
This commit is contained in:
parent
b3793169e9
commit
5734050e88
4 changed files with 87 additions and 8 deletions
|
|
@ -67,13 +67,13 @@ class DefaultPushService @Inject constructor(
|
||||||
pushProviders.find { it.name == currentPushProviderName }?.unregister(matrixClient)
|
pushProviders.find { it.name == currentPushProviderName }?.unregister(matrixClient)
|
||||||
?.onFailure {
|
?.onFailure {
|
||||||
Timber.w(it, "Failed to unregister previous push provider")
|
Timber.w(it, "Failed to unregister previous push provider")
|
||||||
|
return Result.failure(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Store new value
|
||||||
|
userPushStore.setPushProviderName(pushProvider.name)
|
||||||
|
// Then try to register
|
||||||
return pushProvider.registerWith(matrixClient, distributor)
|
return pushProvider.registerWith(matrixClient, distributor)
|
||||||
.onSuccess {
|
|
||||||
// Store new value
|
|
||||||
userPushStore.setPushProviderName(pushProvider.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun testPush(): Boolean {
|
override suspend fun testPush(): Boolean {
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,41 @@ package io.element.android.libraries.pushproviders.unifiedpush
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
import io.element.android.libraries.pushproviders.api.Distributor
|
import io.element.android.libraries.pushproviders.api.Distributor
|
||||||
|
import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
import org.unifiedpush.android.connector.UnifiedPush
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
class RegisterUnifiedPushUseCase @Inject constructor(
|
class RegisterUnifiedPushUseCase @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
|
private val endpointRegistrationHandler: EndpointRegistrationHandler,
|
||||||
|
private val coroutineScope: CoroutineScope,
|
||||||
) {
|
) {
|
||||||
fun execute(distributor: Distributor, clientSecret: String): Result<Unit> {
|
suspend fun execute(distributor: Distributor, clientSecret: String): Result<Unit> {
|
||||||
UnifiedPush.saveDistributor(context, distributor.value)
|
UnifiedPush.saveDistributor(context, distributor.value)
|
||||||
|
val completable = CompletableDeferred<Result<Unit>>()
|
||||||
|
val job = coroutineScope.launch {
|
||||||
|
val result = endpointRegistrationHandler.state
|
||||||
|
.filter { it.clientSecret == clientSecret }
|
||||||
|
.first()
|
||||||
|
.result
|
||||||
|
completable.complete(result)
|
||||||
|
}
|
||||||
// This will trigger the callback
|
// This will trigger the callback
|
||||||
// VectorUnifiedPushMessagingReceiver.onNewEndpoint
|
// VectorUnifiedPushMessagingReceiver.onNewEndpoint
|
||||||
UnifiedPush.registerApp(context = context, instance = clientSecret)
|
UnifiedPush.registerApp(context = context, instance = clientSecret)
|
||||||
return Result.success(Unit)
|
// Wait for VectorUnifiedPushMessagingReceiver.onNewEndpoint to proceed
|
||||||
|
return withTimeout(30.seconds) {
|
||||||
|
completable.await()
|
||||||
|
}
|
||||||
|
.onFailure {
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ import android.content.Intent
|
||||||
import io.element.android.libraries.architecture.bindings
|
import io.element.android.libraries.architecture.bindings
|
||||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||||
import io.element.android.libraries.pushproviders.api.PushHandler
|
import io.element.android.libraries.pushproviders.api.PushHandler
|
||||||
|
import io.element.android.libraries.pushproviders.unifiedpush.registration.EndpointRegistrationHandler
|
||||||
|
import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -37,6 +39,7 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
@Inject lateinit var unifiedPushStore: UnifiedPushStore
|
||||||
@Inject lateinit var unifiedPushGatewayResolver: UnifiedPushGatewayResolver
|
@Inject lateinit var unifiedPushGatewayResolver: UnifiedPushGatewayResolver
|
||||||
@Inject lateinit var newGatewayHandler: UnifiedPushNewGatewayHandler
|
@Inject lateinit var newGatewayHandler: UnifiedPushNewGatewayHandler
|
||||||
|
@Inject lateinit var endpointRegistrationHandler: EndpointRegistrationHandler
|
||||||
|
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob())
|
private val coroutineScope = CoroutineScope(SupervisorJob())
|
||||||
|
|
||||||
|
|
@ -73,14 +76,28 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
val gateway = unifiedPushGatewayResolver.getGateway(endpoint)
|
val gateway = unifiedPushGatewayResolver.getGateway(endpoint)
|
||||||
unifiedPushStore.storePushGateway(gateway, instance)
|
unifiedPushStore.storePushGateway(gateway, instance)
|
||||||
gateway?.let { pushGateway ->
|
if (gateway == null) {
|
||||||
newGatewayHandler.handle(endpoint, pushGateway, instance)
|
Timber.tag(loggerTag.value).w("No gateway found for endpoint $endpoint")
|
||||||
|
endpointRegistrationHandler.registrationDone(
|
||||||
|
RegistrationResult(
|
||||||
|
clientSecret = instance,
|
||||||
|
result = Result.failure(IllegalStateException("No gateway found for endpoint $endpoint")),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val result = newGatewayHandler.handle(endpoint, gateway, instance)
|
||||||
.onFailure {
|
.onFailure {
|
||||||
Timber.tag(loggerTag.value).e(it, "Failed to handle new gateway")
|
Timber.tag(loggerTag.value).e(it, "Failed to handle new gateway")
|
||||||
}
|
}
|
||||||
.onSuccess {
|
.onSuccess {
|
||||||
unifiedPushStore.storeUpEndpoint(endpoint, instance)
|
unifiedPushStore.storeUpEndpoint(endpoint, instance)
|
||||||
}
|
}
|
||||||
|
endpointRegistrationHandler.registrationDone(
|
||||||
|
RegistrationResult(
|
||||||
|
clientSecret = instance,
|
||||||
|
result = result,
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
guardServiceStarter.stop()
|
guardServiceStarter.stop()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.pushproviders.unifiedpush.registration
|
||||||
|
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
|
import io.element.android.libraries.di.SingleIn
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
data class RegistrationResult(
|
||||||
|
val clientSecret: String,
|
||||||
|
val result: Result<Unit>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@SingleIn(AppScope::class)
|
||||||
|
class EndpointRegistrationHandler @Inject constructor() {
|
||||||
|
private val _state = MutableSharedFlow<RegistrationResult>()
|
||||||
|
val state: SharedFlow<RegistrationResult> = _state
|
||||||
|
|
||||||
|
suspend fun registrationDone(result: RegistrationResult) {
|
||||||
|
_state.emit(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue