Update UnifiedPush library (#4358)

* Upgrade `com.github.UnifiedPush:android-connector` from 2.4.0 to 3.0.4

* Do not use jitpack to get the unified push library

* implementation is ok

* Exclude com.google.crypto.tink to fix a compilation issue

* Fix tests.

* Update log.

* Revert "Exclude com.google.crypto.tink to fix a compilation issue"

This reverts commit f431ebe3b78a06282e0ee74c9f428702d463df45.

* Fix compilation issue after rebase.

* Exclude com.google.crypto.tink again.

* Try version 3.0.8

* Use latest version 3.0.9

* Replace tink exclusion with dependency resolution

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
Benoit Marty
2025-05-26 14:56:54 +02:00
committed by GitHub
parent df77dc873a
commit 819d9c7da0
8 changed files with 52 additions and 22 deletions

View File

@@ -354,3 +354,12 @@ fun Project.configureLicensesTasks(reportingExtension: ReportingExtension) {
}
}
}
configurations.all {
resolutionStrategy {
dependencySubstitution {
val tink = libs.google.tink.get()
substitute(module("com.google.crypto.tink:tink")).using(module("${tink.group}:${tink.name}:${tink.version}"))
}
}
}

View File

@@ -177,7 +177,7 @@ sqldelight-driver-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" }
sqlcipher = "net.zetetic:android-database-sqlcipher:4.5.4"
sqlite = "androidx.sqlite:sqlite-ktx:2.5.1"
unifiedpush = "com.github.UnifiedPush:android-connector:2.4.0"
unifiedpush = "org.unifiedpush.android:connector:3.0.9"
otaliastudios_transcoder = "com.otaliastudios:transcoder:0.11.2"
vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0"
telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" }

View File

@@ -42,8 +42,7 @@ dependencies {
implementation(libs.serialization.json)
// UnifiedPush library
api(libs.unifiedpush)
implementation(libs.unifiedpush)
testImplementation(libs.coroutines.test)
testImplementation(libs.test.junit)
testImplementation(libs.test.robolectric)

View File

@@ -33,7 +33,7 @@ class DefaultRegisterUnifiedPushUseCase @Inject constructor(
UnifiedPush.saveDistributor(context, distributor.value)
// This will trigger the callback
// VectorUnifiedPushMessagingReceiver.onNewEndpoint
UnifiedPush.registerApp(context = context, instance = clientSecret)
UnifiedPush.register(context = context, instance = clientSecret)
// Wait for VectorUnifiedPushMessagingReceiver.onNewEndpoint to proceed
return runCatching {
withTimeout(30.seconds) {

View File

@@ -53,6 +53,6 @@ class DefaultUnregisterUnifiedPushUseCase @Inject constructor(
override fun cleanup(clientSecret: String) {
unifiedPushStore.storeUpEndpoint(clientSecret, null)
unifiedPushStore.storePushGateway(clientSecret, null)
UnifiedPush.unregisterApp(context, clientSecret)
UnifiedPush.unregister(context, clientSecret)
}
}

View File

@@ -16,7 +16,10 @@ import io.element.android.libraries.pushproviders.unifiedpush.registration.Endpo
import io.element.android.libraries.pushproviders.unifiedpush.registration.RegistrationResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.unifiedpush.android.connector.FailedReason
import org.unifiedpush.android.connector.MessagingReceiver
import org.unifiedpush.android.connector.data.PushEndpoint
import org.unifiedpush.android.connector.data.PushMessage
import timber.log.Timber
import javax.inject.Inject
@@ -45,15 +48,15 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
* @param message the message
* @param instance connection, for multi-account
*/
override fun onMessage(context: Context, message: ByteArray, instance: String) {
Timber.tag(loggerTag.value).w("New message")
override fun onMessage(context: Context, message: PushMessage, instance: String) {
Timber.tag(loggerTag.value).d("New message, decrypted: ${message.decrypted}")
coroutineScope.launch {
val pushData = pushParser.parse(message, instance)
val pushData = pushParser.parse(message.content, instance)
if (pushData == null) {
Timber.tag(loggerTag.value).w("Invalid data received from UnifiedPush")
pushHandler.handleInvalid(
providerInfo = "${UnifiedPushConfig.NAME} - $instance",
data = String(message),
data = String(message.content),
)
} else {
pushHandler.handle(
@@ -68,20 +71,20 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
* Called when a new endpoint is to be used for sending push messages.
* You should send the endpoint to your application server and sync for missing notifications.
*/
override fun onNewEndpoint(context: Context, endpoint: String, instance: String) {
override fun onNewEndpoint(context: Context, endpoint: PushEndpoint, instance: String) {
Timber.tag(loggerTag.value).w("onNewEndpoint: $endpoint")
coroutineScope.launch {
val gateway = unifiedPushGatewayResolver.getGateway(endpoint)
val gateway = unifiedPushGatewayResolver.getGateway(endpoint.url)
.let { gatewayResult ->
unifiedPushGatewayUrlResolver.resolve(gatewayResult, instance)
}
unifiedPushStore.storePushGateway(instance, gateway)
val result = newGatewayHandler.handle(endpoint, gateway, instance)
val result = newGatewayHandler.handle(endpoint.url, gateway, instance)
.onFailure {
Timber.tag(loggerTag.value).e(it, "Failed to handle new gateway")
}
.onSuccess {
unifiedPushStore.storeUpEndpoint(instance, endpoint)
unifiedPushStore.storeUpEndpoint(instance, endpoint.url)
}
endpointRegistrationHandler.registrationDone(
RegistrationResult(
@@ -96,8 +99,8 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() {
/**
* Called when the registration is not possible, eg. no network.
*/
override fun onRegistrationFailed(context: Context, instance: String) {
Timber.tag(loggerTag.value).e("onRegistrationFailed for $instance")
override fun onRegistrationFailed(context: Context, reason: FailedReason, instance: String) {
Timber.tag(loggerTag.value).e("onRegistrationFailed for $instance, reason: $reason")
/*
Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show()
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
@@ -110,7 +113,7 @@ 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")
Timber.tag(loggerTag.value).w("UnifiedPush: Unregistered")
/*
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
pushDataStore.setFdroidSyncBackgroundMode(mode)

View File

@@ -32,6 +32,10 @@ import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.unifiedpush.android.connector.FailedReason
import org.unifiedpush.android.connector.data.PublicKeySet
import org.unifiedpush.android.connector.data.PushEndpoint
import org.unifiedpush.android.connector.data.PushMessage
@RunWith(RobolectricTestRunner::class)
class VectorUnifiedPushMessagingReceiverTest {
@@ -56,7 +60,7 @@ class VectorUnifiedPushMessagingReceiverTest {
fun `onRegistrationFailed does nothing`() = runTest {
val context = InstrumentationRegistry.getInstrumentation().context
val vectorUnifiedPushMessagingReceiver = createVectorUnifiedPushMessagingReceiver()
vectorUnifiedPushMessagingReceiver.onRegistrationFailed(context, A_SECRET)
vectorUnifiedPushMessagingReceiver.onRegistrationFailed(context, FailedReason.NETWORK, A_SECRET)
}
@Test
@@ -68,7 +72,7 @@ class VectorUnifiedPushMessagingReceiverTest {
handleResult = pushHandlerResult
),
)
vectorUnifiedPushMessagingReceiver.onMessage(context, UnifiedPushParserTest.UNIFIED_PUSH_DATA.toByteArray(), A_SECRET)
vectorUnifiedPushMessagingReceiver.onMessage(context, aPushMessage(), A_SECRET)
advanceUntilIdle()
pushHandlerResult.assertions()
.isCalledOnce()
@@ -96,7 +100,7 @@ class VectorUnifiedPushMessagingReceiverTest {
handleInvalidResult = handleInvalidResult,
),
)
vectorUnifiedPushMessagingReceiver.onMessage(context, "".toByteArray(), A_SECRET)
vectorUnifiedPushMessagingReceiver.onMessage(context, aPushMessage(""), A_SECRET)
advanceUntilIdle()
handleInvalidResult.assertions().isCalledOnce()
}
@@ -127,7 +131,7 @@ class VectorUnifiedPushMessagingReceiverTest {
unifiedPushNewGatewayHandler = unifiedPushNewGatewayHandler,
)
endpointRegistrationHandler.state.test {
vectorUnifiedPushMessagingReceiver.onNewEndpoint(context, "anEndpoint", A_SECRET)
vectorUnifiedPushMessagingReceiver.onNewEndpoint(context, aPushEndpoint("anEndpoint"), A_SECRET)
advanceUntilIdle()
assertThat(awaitItem()).isEqualTo(
RegistrationResult(
@@ -170,7 +174,7 @@ class VectorUnifiedPushMessagingReceiverTest {
unifiedPushNewGatewayHandler = unifiedPushNewGatewayHandler,
)
endpointRegistrationHandler.state.test {
vectorUnifiedPushMessagingReceiver.onNewEndpoint(context, "anEndpoint", A_SECRET)
vectorUnifiedPushMessagingReceiver.onNewEndpoint(context, aPushEndpoint(), A_SECRET)
advanceUntilIdle()
assertThat(awaitItem()).isEqualTo(
RegistrationResult(
@@ -207,3 +211,19 @@ class VectorUnifiedPushMessagingReceiverTest {
}
}
}
private fun aPushMessage(
data: String = UnifiedPushParserTest.UNIFIED_PUSH_DATA,
decrypted: Boolean = true,
) = PushMessage(
content = data.toByteArray(),
decrypted = decrypted,
)
private fun aPushEndpoint(
url: String = "anEndpoint",
pubKeySet: PublicKeySet? = null,
) = PushEndpoint(
url = url,
pubKeySet = pubKeySet,
)

View File

@@ -39,7 +39,6 @@ dependencyResolutionManagement {
maven {
url = URI("https://www.jitpack.io")
content {
includeModule("com.github.UnifiedPush", "android-connector")
includeModule("com.github.matrix-org", "matrix-analytics-events")
}
}