From 78338604c94129800ce72f615e181e2a27c47020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 11 Apr 2023 12:16:07 +0200 Subject: [PATCH 1/3] Setting version for the release 1.5.30 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1c1b76ba1b..8ace02205a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,7 +26,7 @@ vector.httpLogLevel=NONE # Ref: https://github.com/vanniktech/gradle-maven-publish-plugin GROUP=org.matrix.android POM_ARTIFACT_ID=matrix-android-sdk2 -VERSION_NAME=1.5.26 +VERSION_NAME=1.5.30 POM_PACKAGING=aar From 1e2a38e819578c4c70e11a7404ac00a098964efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 11 Apr 2023 12:21:57 +0200 Subject: [PATCH 2/3] Import v1.5.30 from Element Android --- dependencies.gradle | 36 ++++--- dependencies_groups.gradle | 3 +- .../matrix/android/sdk/api/MatrixPatterns.kt | 23 ++--- .../session/crypto/model/CryptoDeviceInfo.kt | 3 + .../sdk/api/session/events/model/Event.kt | 2 +- .../api/session/permalinks/MatrixLinkify.kt | 15 ++- .../session/pushrules/EventMatchCondition.kt | 13 ++- .../room/members/RoomMemberQueryParams.kt | 7 +- .../matrix/android/sdk/api/util/MatrixItem.kt | 8 +- .../sdk/internal/crypto/EventDecryptor.kt | 5 +- .../database/helper/ThreadEventsHelper.kt | 2 +- .../database/query/ChunkEntityQueries.kt | 7 +- .../internal/database/query/ReadQueries.kt | 6 +- .../sdk/internal/di/WorkManagerProvider.kt | 2 +- .../pushrules/ProcessEventForPushTask.kt | 8 +- .../room/create/CreateRoomBodyBuilder.kt | 4 +- .../membership/DefaultMembershipService.kt | 11 ++- .../membership/RoomDisplayNameResolver.kt | 7 +- .../timeline/FetchTokenAndPaginateTask.kt | 2 +- .../room/timeline/LoadTimelineStrategy.kt | 2 +- .../sync/handler/room/RoomSyncHandler.kt | 4 + .../pushrules/PushRulesConditionTest.kt | 95 ++++++++++++++++++- .../sdk/test/fakes/FakeWorkManagerProvider.kt | 1 + 23 files changed, 195 insertions(+), 71 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 7120789e10..56b81653ca 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -6,30 +6,28 @@ ext.versions = [ 'targetCompat' : JavaVersion.VERSION_11, ] -def gradle = "7.4.1" +def gradle = "7.4.2" // Ref: https://kotlinlang.org/releases.html def kotlin = "1.8.10" def kotlinCoroutines = "1.6.4" def dagger = "2.45" -def firebaseBom = "31.2.1" -def appDistribution = "16.0.0-beta05" +def firebaseBom = "31.4.0" +def appDistribution = "16.0.0-beta06" def retrofit = "2.9.0" def markwon = "4.6.2" def moshi = "1.14.0" def lifecycle = "2.5.1" def flowBinding = "1.2.0" -def flipper = "0.178.1" +def flipper = "0.188.0" def epoxy = "5.0.0" -def mavericks = "3.0.1" -def glide = "4.14.2" +def mavericks = "3.0.2" +def glide = "4.15.1" def bigImageViewer = "1.8.1" def jjwt = "0.11.5" -// Temporary version to unblock #6929. Once 0.16.0 is released we should use it, and revert -// the whole commit which set version 0.16.0-SNAPSHOT -def vanniktechEmoji = "0.16.0-SNAPSHOT" -def sentry = "6.14.0" +def vanniktechEmoji = "0.16.0" +def sentry = "6.17.0" // Use 1.6.0 alpha to fix issue with test -def fragment = "1.6.0-alpha04" +def fragment = "1.6.0-alpha08" // Testing def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819 def espresso = "3.5.1" @@ -49,17 +47,17 @@ ext.libs = [ 'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines" ], androidx : [ - 'activity' : "androidx.activity:activity-ktx:1.6.1", + 'activity' : "androidx.activity:activity-ktx:1.7.0", 'appCompat' : "androidx.appcompat:appcompat:1.6.1", 'biometric' : "androidx.biometric:biometric:1.1.0", 'core' : "androidx.core:core-ktx:1.9.0", - 'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1", + 'recyclerview' : "androidx.recyclerview:recyclerview:1.3.0", 'exifinterface' : "androidx.exifinterface:exifinterface:1.3.6", 'fragmentKtx' : "androidx.fragment:fragment-ktx:$fragment", 'fragmentTesting' : "androidx.fragment:fragment-testing:$fragment", 'fragmentTestingManifest' : "androidx.fragment:fragment-testing-manifest:$fragment", 'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.4", - 'work' : "androidx.work:work-runtime-ktx:2.7.1", + 'work' : "androidx.work:work-runtime-ktx:2.8.0", 'autoFill' : "androidx.autofill:autofill:1.1.0", 'preferenceKtx' : "androidx.preference:preference-ktx:1.2.0", 'junit' : "androidx.test.ext:junit:1.1.5", @@ -70,7 +68,7 @@ ext.libs = [ 'datastore' : "androidx.datastore:datastore:1.0.0", 'datastorepreferences' : "androidx.datastore:datastore-preferences:1.0.0", 'pagingRuntimeKtx' : "androidx.paging:paging-runtime-ktx:2.1.2", - 'coreTesting' : "androidx.arch.core:core-testing:2.1.0", + 'coreTesting' : "androidx.arch.core:core-testing:2.2.0", 'testCore' : "androidx.test:core:$androidxTest", 'orchestrator' : "androidx.test:orchestrator:$androidxOrchestrator", 'testRunner' : "androidx.test:runner:$androidxTest", @@ -79,7 +77,7 @@ ext.libs = [ 'espressoContrib' : "androidx.test.espresso:espresso-contrib:$espresso", 'espressoIntents' : "androidx.test.espresso:espresso-intents:$espresso", 'viewpager2' : "androidx.viewpager2:viewpager2:1.0.0", - 'transition' : "androidx.transition:transition:1.2.0", + 'transition' : "androidx.transition:transition:1.4.1", ], google : [ 'material' : "com.google.android.material:material:1.8.0", @@ -88,7 +86,7 @@ ext.libs = [ 'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution", 'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution", // Phone number https://github.com/google/libphonenumber - 'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.13.6" + 'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.13.8" ], dagger : [ 'dagger' : "com.google.dagger:dagger:$dagger", @@ -103,7 +101,7 @@ ext.libs = [ ], element : [ 'opusencoder' : "io.element.android:opusencoder:1.1.0", - 'wysiwyg' : "io.element.android:wysiwyg:1.0.0" + 'wysiwyg' : "io.element.android:wysiwyg:1.2.2" ], squareup : [ 'moshi' : "com.squareup.moshi:moshi:$moshi", @@ -134,7 +132,7 @@ ext.libs = [ 'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks" ], maplibre : [ - 'androidSdk' : "org.maplibre.gl:android-sdk:9.6.0", + 'androidSdk' : "org.maplibre.gl:android-sdk:10.0.2", 'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:1.0.0" ], mockk : [ diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index 8d488ba2f8..67893b50cf 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -42,7 +42,6 @@ ext.groups = [ regex: [ ], group: [ - 'com.vanniktech', ] ], mavenCentral: [ @@ -128,7 +127,7 @@ ext.groups = [ 'com.sun.xml.bind.mvn', 'com.sun.xml.fastinfoset', 'com.thoughtworks.qdox', - // 'com.vanniktech', + 'com.vanniktech', 'commons-cli', 'commons-codec', 'commons-io', diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt index bae4b06a05..2de95850b0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt @@ -65,27 +65,14 @@ object MatrixPatterns { private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/" const val SEP_REGEX = "/" - private const val LINK_TO_ROOM_ID_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX - private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID = LINK_TO_ROOM_ID_REGEXP.toRegex(RegexOption.IGNORE_CASE) - - private const val LINK_TO_ROOM_ALIAS_REGEXP = PERMALINK_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX - private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS = LINK_TO_ROOM_ALIAS_REGEXP.toRegex(RegexOption.IGNORE_CASE) - - private const val LINK_TO_APP_ROOM_ID_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_IDENTIFIER_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX - private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID = LINK_TO_APP_ROOM_ID_REGEXP.toRegex(RegexOption.IGNORE_CASE) - - private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX - private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = LINK_TO_APP_ROOM_ALIAS_REGEXP.toRegex(RegexOption.IGNORE_CASE) + private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK = PERMALINK_BASE_REGEX.toRegex(RegexOption.IGNORE_CASE) + private val PATTERN_CONTAIN_APP_PERMALINK = APP_BASE_REGEX.toRegex(RegexOption.IGNORE_CASE) // ascii characters in the range \x20 (space) to \x7E (~) val ORDER_STRING_REGEX = "[ -~]+".toRegex() // list of patterns to find some matrix item. val MATRIX_PATTERNS = listOf( - PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID, - PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ALIAS, - PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ID, - PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS, PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER, PATTERN_CONTAIN_MATRIX_ALIAS, PATTERN_CONTAIN_MATRIX_ROOM_IDENTIFIER, @@ -146,6 +133,12 @@ object MatrixPatterns { return str != null && str matches PATTERN_CONTAIN_MATRIX_GROUP_IDENTIFIER } + fun isPermalink(str: String?): Boolean { + return str != null && + (PATTERN_CONTAIN_MATRIX_TO_PERMALINK.containsMatchIn(str) || + PATTERN_CONTAIN_APP_PERMALINK.containsMatchIn(str)) + } + /** * Extract server name from a matrix id. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt index 418b1e6ce3..a1c5866fff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt @@ -34,6 +34,9 @@ data class CryptoDeviceInfo( val isVerified: Boolean get() = trustLevel?.isVerified() == true + val isCrossSigningVerified: Boolean + get() = trustLevel?.isCrossSigningVerified() == true + val isUnknown: Boolean get() = trustLevel == null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 40c69ceb66..ae3e3a63c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -488,7 +488,7 @@ fun Event.getPollContent(): MessagePollContent? { } fun Event.supportsNotification() = - this.getClearType() in EventType.MESSAGE + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values + this.getClearType() in EventType.MESSAGE + EventType.POLL_START.values + EventType.POLL_END.values + EventType.STATE_ROOM_BEACON_INFO.values fun Event.isContentReportable() = this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO.values diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt index c428e40203..060b93ed0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.session.permalinks import android.text.Spannable +import android.util.Patterns import org.matrix.android.sdk.api.MatrixPatterns /** @@ -44,22 +45,26 @@ object MatrixLinkify { } val text = spannable.toString() var hasMatch = false - for (pattern in MatrixPatterns.MATRIX_PATTERNS) { + for (pattern in listOf(Patterns.WEB_URL.toRegex()).plus(MatrixPatterns.MATRIX_PATTERNS)) { for (match in pattern.findAll(spannable)) { hasMatch = true val startPos = match.range.first if (startPos == 0 || text[startPos - 1] != '/') { val endPos = match.range.last + 1 var url = text.substring(match.range) - if (MatrixPatterns.isUserId(url) || + val isPermalink = MatrixPatterns.isPermalink(url) + if (isPermalink || + MatrixPatterns.isUserId(url) || MatrixPatterns.isRoomAlias(url) || MatrixPatterns.isRoomId(url) || MatrixPatterns.isGroupId(url) || MatrixPatterns.isEventId(url)) { - url = PermalinkService.MATRIX_TO_URL_BASE + url + if (!isPermalink) { + url = PermalinkService.MATRIX_TO_URL_BASE + url + } + val span = MatrixPermalinkSpan(url, callback) + spannable.setSpan(span, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } - val span = MatrixPermalinkSpan(url, callback) - spannable.setSpan(span, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/EventMatchCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/EventMatchCondition.kt index 15d5cd3153..c3ddbf14b3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/EventMatchCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/EventMatchCondition.kt @@ -39,8 +39,17 @@ class EventMatchCondition( override fun technicalDescription() = "'$key' matches '$pattern'" fun isSatisfied(event: Event): Boolean { - // TODO encrypted events? - val rawJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *> + val rawJson: Map<*, *> = (MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *>) + ?.let { rawJson -> + val decryptedRawJson = event.mxDecryptionResult?.payload + if (decryptedRawJson != null) { + rawJson + .toMutableMap() + .apply { putAll(decryptedRawJson) } + } else { + rawJson + } + } ?: return false val value = extractField(rawJson, key) ?: return false diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/RoomMemberQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/RoomMemberQueryParams.kt index dd83066dbb..2ccb7f7ba1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/RoomMemberQueryParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/RoomMemberQueryParams.kt @@ -30,7 +30,8 @@ data class RoomMemberQueryParams( val displayName: QueryStringValue, val memberships: List, val userId: QueryStringValue, - val excludeSelf: Boolean + val excludeSelf: Boolean, + val displayNameOrUserId: QueryStringValue, ) { class Builder { @@ -39,12 +40,14 @@ data class RoomMemberQueryParams( var displayName: QueryStringValue = QueryStringValue.IsNotEmpty var memberships: List = Membership.all() var excludeSelf: Boolean = false + var displayNameOrUserId: QueryStringValue = QueryStringValue.NoCondition fun build() = RoomMemberQueryParams( displayName = displayName, memberships = memberships, userId = userId, - excludeSelf = excludeSelf + excludeSelf = excludeSelf, + displayNameOrUserId = displayNameOrUserId ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 974f1cfcbe..0fd96798c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -76,7 +76,8 @@ sealed class MatrixItem( data class RoomItem( override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null + override val avatarUrl: String? = null, + val roomDisplayName: String? = null ) : MatrixItem(id, displayName, avatarUrl) { init { @@ -102,7 +103,8 @@ sealed class MatrixItem( data class RoomAliasItem( override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null + override val avatarUrl: String? = null, + val roomDisplayName: String? = null ) : MatrixItem(id, displayName, avatarUrl) { init { @@ -136,6 +138,8 @@ sealed class MatrixItem( val displayName = when (this) { // use the room display name for the notify everyone item is EveryoneInRoomItem -> roomDisplayName + is RoomItem -> roomDisplayName ?: displayName + is RoomAliasItem -> roomDisplayName ?: displayName else -> displayName } return (displayName?.takeIf { it.isNotBlank() } ?: id) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index 03672ae81c..ac9c61a32a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -94,7 +94,10 @@ internal class EventDecryptor @Inject constructor( * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. */ suspend fun decryptEventAndSaveResult(event: Event, timeline: String) { - tryOrNull(message = "Unable to decrypt the event") { + // event is not encrypted or already decrypted + if (event.getClearType() != EventType.ENCRYPTED) return + + tryOrNull(message = "decryptEventAndSaveResult | Unable to decrypt the event") { decryptEvent(event, timeline) } ?.let { result -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt index 7999a2ea14..a100741452 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt @@ -297,7 +297,7 @@ internal fun updateThreadNotifications(roomId: String, realm: Realm, currentUser val readReceipt = findMyReadReceipt(realm, roomId, currentUserId, threadId = rootThreadEventId) ?: return val readReceiptChunk = ChunkEntity - .findIncludingEvent(realm, readReceipt) ?: return + .findIncludingEvent(realm, roomId, readReceipt) ?: return val readReceiptChunkThreadEvents = readReceiptChunk .timelineEvents diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt index 1e5d96b496..08c8bcf86e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt @@ -72,15 +72,16 @@ internal fun ChunkEntity.Companion.findEventInThreadChunk(realm: Realm, roomId: .findFirst() } -internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, eventIds: List): RealmResults { +internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, roomId: String, eventIds: List): RealmResults { return realm.where() + .equalTo(ChunkEntityFields.ROOM.ROOM_ID, roomId) .`in`(ChunkEntityFields.TIMELINE_EVENTS.EVENT_ID, eventIds.toTypedArray()) .isNull(ChunkEntityFields.ROOT_THREAD_EVENT_ID) .findAll() } -internal fun ChunkEntity.Companion.findIncludingEvent(realm: Realm, eventId: String): ChunkEntity? { - return findAllIncludingEvents(realm, listOf(eventId)).firstOrNull() +internal fun ChunkEntity.Companion.findIncludingEvent(realm: Realm, roomId: String, eventId: String): ChunkEntity? { + return findAllIncludingEvents(realm, roomId, listOf(eventId)).firstOrNull() } internal fun ChunkEntity.Companion.create( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt index ebfe23105e..0cc4abcb3d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt @@ -76,11 +76,11 @@ private fun hasReadMissingEvent(realm: Realm, userId: String, eventId: String, threadId: String? = ReadService.THREAD_ID_MAIN): Boolean { - return realm.doesEventExistInChunkHistory(eventId) && realm.hasReadReceiptInLatestChunk(latestChunkEntity, roomId, userId, threadId) + return realm.doesEventExistInChunkHistory(roomId, eventId) && realm.hasReadReceiptInLatestChunk(latestChunkEntity, roomId, userId, threadId) } -private fun Realm.doesEventExistInChunkHistory(eventId: String): Boolean { - return ChunkEntity.findIncludingEvent(this, eventId) != null +private fun Realm.doesEventExistInChunkHistory(roomId: String, eventId: String): Boolean { + return ChunkEntity.findIncludingEvent(this, roomId, eventId) != null } private fun Realm.hasReadReceiptInLatestChunk(latestChunkEntity: ChunkEntity, roomId: String, userId: String, threadId: String?): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/WorkManagerProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/WorkManagerProvider.kt index ad28286a84..d8cdd162f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/WorkManagerProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/WorkManagerProvider.kt @@ -41,7 +41,7 @@ internal class WorkManagerProvider @Inject constructor( private val coroutineDispatchers: MatrixCoroutineDispatchers, private val sessionScope: CoroutineScope ) { - private val tag = MATRIX_SDK_TAG_PREFIX + sessionId + val tag = MATRIX_SDK_TAG_PREFIX + sessionId val workManager = WorkManager.getInstance(context) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt index 3dfac694ed..d000d709a9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushrules/ProcessEventForPushTask.kt @@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.session.events.model.isInvitation import org.matrix.android.sdk.api.session.pushrules.PushEvents import org.matrix.android.sdk.api.session.pushrules.rest.PushRule import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.internal.crypto.EventDecryptor import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task import timber.log.Timber @@ -36,21 +37,22 @@ internal interface ProcessEventForPushTask : Task value.timeline?.events?.mapNotNull { - it.takeIf { !it.isInvitation() }?.copy(roomId = key) + it.takeIf { !it.isInvitation() }?.copyAll(roomId = key) } } .flatten() val inviteEvents = params.syncResponse.invite .mapNotNull { (key, value) -> - value.inviteState?.events?.map { it.copy(roomId = key) } + value.inviteState?.events?.map { it.copyAll(roomId = key) } } .flatten() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 4105c77cc8..92081885af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -190,10 +190,8 @@ internal class CreateRoomBodyBuilder @Inject constructor( private suspend fun canEnableEncryption(params: CreateRoomParams): Boolean { return params.enableEncryptionIfInvitedUsersSupportIt && // Parity with web, enable if users have encryption ready devices - // for now remove checks on cross signing and 3pid invites + // for now remove checks on cross signing // && crossSigningService.isCrossSigningVerified() - params.invite3pids.isEmpty() && - params.invitedUserIds.isNotEmpty() && params.invitedUserIds.let { userIds -> val keys = deviceListManager.downloadKeys(userIds, forceDownload = false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt index 20708b3814..2b69821b60 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt @@ -17,14 +17,13 @@ package org.matrix.android.sdk.internal.session.room.membership import androidx.lifecycle.LiveData -import com.otaliastudios.opengl.core.use import com.zhuinden.monarchy.Monarchy import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.realm.Realm import io.realm.RealmQuery -import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.room.members.MembershipService @@ -58,7 +57,6 @@ internal class DefaultMembershipService @AssistedInject constructor( private val cryptoService: CryptoService, @UserId private val userId: String, - private val matrixConfiguration: MatrixConfiguration, private val queryStringValueProcessor: QueryStringValueProcessor ) : MembershipService { @@ -120,6 +118,13 @@ internal class DefaultMembershipService @AssistedInject constructor( if (queryParams.excludeSelf) { notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId) } + if (queryParams.displayNameOrUserId != QueryStringValue.NoCondition) { + beginGroup() + process(RoomMemberSummaryEntityFields.USER_ID, queryParams.displayNameOrUserId) + or() + process(RoomMemberSummaryEntityFields.DISPLAY_NAME, queryParams.displayNameOrUserId) + endGroup() + } } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt index 4645bb05ab..7497ecf21b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -115,7 +115,12 @@ internal class RoomDisplayNameResolver @Inject constructor( val leftMembersNames = roomMembers.queryLeftRoomMembersEvent() .findAll() .map { displayNameResolver.getBestName(it.toMatrixItem()) } - roomDisplayNameFallbackProvider.getNameForEmptyRoom(roomSummary?.isDirect.orFalse(), leftMembersNames) + val directUserId = roomSummary?.directUserId + if (!directUserId.isNullOrBlank() && leftMembersNames.isEmpty()) { + directUserId + } else { + roomDisplayNameFallbackProvider.getNameForEmptyRoom(roomSummary?.isDirect.orFalse(), leftMembersNames) + } } 1 -> { roomDisplayNameFallbackProvider.getNameFor1member( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt index 9d8d8ecbf1..b73dd8160b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/FetchTokenAndPaginateTask.kt @@ -59,7 +59,7 @@ internal class DefaultFetchTokenAndPaginateTask @Inject constructor( ?: throw IllegalStateException("No token found") monarchy.awaitTransaction { realm -> - val chunkToUpdate = ChunkEntity.findIncludingEvent(realm, params.lastKnownEventId) + val chunkToUpdate = ChunkEntity.findIncludingEvent(realm, params.roomId, params.lastKnownEventId) if (params.direction == PaginationDirection.FORWARDS) { chunkToUpdate?.nextToken = fromToken } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index 6654eeadfc..2143ac1d21 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -278,7 +278,7 @@ internal class LoadTimelineStrategy constructor( .findAll() } is Mode.Permalink -> { - ChunkEntity.findAllIncludingEvents(realm, listOf(mode.originEventId)) + ChunkEntity.findAllIncludingEvents(realm, roomId, listOf(mode.originEventId)) } is Mode.Thread -> { recreateThreadChunkEntity(realm, mode.rootThreadEventId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 5e4886ce1e..f37e384b51 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -437,6 +437,10 @@ internal class RoomSyncHandler @Inject constructor( if (event.isEncrypted() && !isInitialSync) { try { decryptIfNeeded(event, roomId) + // share the decryption result with the rawEvent because the decryption is done on a copy containing the roomId, see previous comment + rawEvent.mxDecryptionResult = event.mxDecryptionResult + rawEvent.mCryptoError = event.mCryptoError + rawEvent.mCryptoErrorReason = event.mCryptoErrorReason } catch (e: InterruptedException) { Timber.i("Decryption got interrupted") } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/pushrules/PushRulesConditionTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/pushrules/PushRulesConditionTest.kt index 3ddf940241..50d084755b 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/pushrules/PushRulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/session/pushrules/PushRulesConditionTest.kt @@ -23,7 +23,11 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test import org.matrix.android.sdk.MatrixTest +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.members.MembershipService @@ -38,15 +42,40 @@ class PushRulesConditionTest : MatrixTest { * Test EventMatchCondition * ========================================================================================== */ + private fun createFakeEncryptedEvent() = Event( + type = EventType.ENCRYPTED, + eventId = "mx0", + roomId = "!fakeRoom", + content = EncryptedEventContent( + algorithm = MXCRYPTO_ALGORITHM_MEGOLM, + ciphertext = "AwgBEpACQEKOkd4Gp0+gSXG4M+btcrnPgsF23xs/lUmS2I4YjmqF...", + sessionId = "TO2G4u2HlnhtbIJk", + senderKey = "5e3EIqg3JfooZnLQ2qHIcBarbassQ4qXblai0", + deviceId = "FAKEE" + ).toContent() + ) + private fun createSimpleTextEvent(text: String): Event { return Event( - type = "m.room.message", + type = EventType.MESSAGE, eventId = "mx0", content = MessageTextContent("m.text", text).toContent(), - originServerTs = 0 + originServerTs = 0, ) } + private fun createSimpleTextEventEncrypted(text: String): Event { + return createFakeEncryptedEvent().apply { + mxDecryptionResult = OlmDecryptionResult( + payload = mapOf( + "type" to EventType.MESSAGE, + "content" to MessageTextContent("m.text", text).toContent(), + ), + senderKey = "the_real_sender_key", + ) + } + } + @Test fun test_eventmatch_type_condition() { val condition = EventMatchCondition("type", "m.room.message") @@ -70,6 +99,26 @@ class PushRulesConditionTest : MatrixTest { assertFalse(condition.isSatisfied(simpleRoomMemberEvent)) } + @Test + fun test_decrypted_eventmatch_type_condition() { + val condition = EventMatchCondition("type", "m.room.message") + + val simpleDecryptedTextEvent = createSimpleTextEventEncrypted("Yo wtf?") + + val encryptedDummyEvent = createFakeEncryptedEvent().apply { + mxDecryptionResult = OlmDecryptionResult( + payload = mapOf( + "type" to EventType.DUMMY, + ) + ) + } + val encryptedEvent = createFakeEncryptedEvent() + + assert(condition.isSatisfied(simpleDecryptedTextEvent)) + assertFalse(condition.isSatisfied(encryptedDummyEvent)) + assertFalse(condition.isSatisfied(encryptedEvent)) + } + @Test fun test_eventmatch_path_condition() { val condition = EventMatchCondition("content.msgtype", "m.text") @@ -125,6 +174,22 @@ class PushRulesConditionTest : MatrixTest { assert(condition.isSatisfied(createSimpleTextEvent("BEN"))) } + @Test + fun test_encrypted_eventmatch_words_only_condition() { + val condition = EventMatchCondition("content.body", "ben") + + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("benoit"))) + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("Hello benoit"))) + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("superben"))) + + assert(condition.isSatisfied(createSimpleTextEventEncrypted("ben"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("hello ben"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("ben is there"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("hello ben!"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("hello Ben!"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("BEN"))) + } + @Test fun test_eventmatch_at_room_condition() { val condition = EventMatchCondition("content.body", "@room") @@ -140,6 +205,21 @@ class PushRulesConditionTest : MatrixTest { assert(condition.isSatisfied(createSimpleTextEvent("Don't ping @room!"))) } + @Test + fun test_encrypted_eventmatch_at_room_condition() { + val condition = EventMatchCondition("content.body", "@room") + + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("@roomba"))) + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("room benoit"))) + assertFalse(condition.isSatisfied(createSimpleTextEventEncrypted("abc@roomba"))) + + assert(condition.isSatisfied(createSimpleTextEventEncrypted("@room"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("@room, ben"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("@ROOM"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("Use:@room"))) + assert(condition.isSatisfied(createSimpleTextEventEncrypted("Don't ping @room!"))) + } + @Test fun test_notice_condition() { val conditionEqual = EventMatchCondition("content.msgtype", "m.notice") @@ -155,6 +235,17 @@ class PushRulesConditionTest : MatrixTest { } } + @Test + fun test_eventmatch_encrypted_type_condition() { + val condition = EventMatchCondition("type", "m.room.encrypted") + + val simpleDecryptedTextEvent = createSimpleTextEventEncrypted("Yo wtf?") + val encryptedEvent = createFakeEncryptedEvent() + + assertFalse(condition.isSatisfied(simpleDecryptedTextEvent)) + assert(condition.isSatisfied(encryptedEvent)) + } + /* ========================================================================================== * Test RoomMemberCountCondition * ========================================================================================== */ diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt index 51ff24c01d..437fda65e4 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt @@ -26,5 +26,6 @@ internal class FakeWorkManagerProvider( val instance = mockk().also { every { it.workManager } returns fakeWorkManager.instance + every { it.tag } returns "Tag" } } From c8341e63c2b553ee3f0e694a59731234b9673c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 11 Apr 2023 12:23:32 +0200 Subject: [PATCH 3/3] Changelog for version 1.5.30 --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 2de2e6e64d..5e1ba9071f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ Please also refer to the Changelog of Element Android: https://github.com/vector-im/element-android/blob/main/CHANGES.md +Changes in Matrix-SDK v1.5.30 (2023-04-11) +========================================= + +Imported from Element 1.5.30. (https://github.com/vector-im/element-android/releases/tag/v1.5.30) + Changes in Matrix-SDK v1.5.26 (2023-03-08) =========================================