diff --git a/CHANGES.md b/CHANGES.md index 43507f59d9168902529ad403fdaa73d9ca409049..bfc60932cfdb64e959ceef31a3b9932d5ad604a4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ Please also refer to the Changelog of Element Android: https://github.com/vector-im/element-android/blob/main/CHANGES.md +Changes in Matrix-SDK 1.1.9 (2021-06-10) +=================================================== + +Fix error with Jitpack on 1.1.8 +Imported from Element 1.1.9. (https://github.com/vector-im/element-android/releases/tag/v1.1.9) + Changes in Matrix-SDK 1.1.8 (2021-05-26) =================================================== diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index b80affa308ef94226b0b7314ce3abefe127f0e76..fbd7f57ccdace83068848f2e894e9daf338f3f46 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -22,7 +22,7 @@ android { minSdkVersion 21 targetSdkVersion 30 versionCode 1 - versionName "1.1.8" + versionName "1.1.9" // Multidex is useful for tests multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -113,7 +113,7 @@ dependencies { def lifecycle_version = '2.2.0' def arch_version = '2.1.0' def markwon_version = '3.1.0' - def daggerVersion = '2.35.1' + def daggerVersion = '2.36' def work_version = '2.5.0' def retrofit_version = '2.9.0' @@ -122,7 +122,7 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation "androidx.appcompat:appcompat:1.3.0" - implementation "androidx.core:core-ktx:1.3.2" + implementation "androidx.core:core-ktx:1.5.0" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" @@ -156,7 +156,7 @@ dependencies { implementation "io.arrow-kt:arrow-instances-core:$arrow_version" // olm lib is now hosted by jitpack: https://jitpack.io/#org.matrix.gitlab.matrix-org/olm - implementation 'org.matrix.gitlab.matrix-org:olm:3.2.2' + implementation 'org.matrix.gitlab.matrix-org:olm:3.2.4' // DI implementation "com.google.dagger:dagger:$daggerVersion" @@ -170,7 +170,7 @@ dependencies { implementation 'com.otaliastudios:transcoder:0.10.3' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.23' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.24' testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.5.1' diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt index eb4773f3c86f1b13ef45e920d64949d8d66af30d..25c22bca57ddf74d1bc29b2326a99706ca4f1d7b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt @@ -33,7 +33,7 @@ import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorageService -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -73,12 +73,12 @@ class QuadSTests : InstrumentedTest { // Assert Account data is updated val accountDataLock = CountDownLatch(1) - var accountData: UserAccountDataEvent? = null + var accountData: AccountDataEvent? = null val liveAccountData = runBlocking(Dispatchers.Main) { - aliceSession.getLiveAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") + aliceSession.userAccountDataService().getLiveAccountDataEvent("${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") } - val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> + val accountDataObserver = Observer<Optional<AccountDataEvent>?> { t -> if (t?.getOrNull()?.type == "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$TEST_KEY_ID") { accountData = t.getOrNull() accountDataLock.countDown() @@ -100,13 +100,13 @@ class QuadSTests : InstrumentedTest { quadS.setDefaultKey(TEST_KEY_ID) } - var defaultKeyAccountData: UserAccountDataEvent? = null + var defaultKeyAccountData: AccountDataEvent? = null val defaultDataLock = CountDownLatch(1) val liveDefAccountData = runBlocking(Dispatchers.Main) { - aliceSession.getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID) + aliceSession.userAccountDataService().getLiveAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID) } - val accountDefDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> + val accountDefDataObserver = Observer<Optional<AccountDataEvent>?> { t -> if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) { defaultKeyAccountData = t.getOrNull()!! defaultDataLock.countDown() @@ -206,7 +206,7 @@ class QuadSTests : InstrumentedTest { ) } - val accountDataEvent = aliceSession.getAccountDataEvent("my.secret") + val accountDataEvent = aliceSession.userAccountDataService().getAccountDataEvent("my.secret") val encryptedContent = accountDataEvent?.content?.get("encrypted") as? Map<*, *> assertEquals("Content should contains two encryptions", 2, encryptedContent?.keys?.size ?: 0) @@ -275,14 +275,14 @@ class QuadSTests : InstrumentedTest { mTestHelper.signOutAndClose(aliceSession) } - private fun assertAccountData(session: Session, type: String): UserAccountDataEvent { + private fun assertAccountData(session: Session, type: String): AccountDataEvent { val accountDataLock = CountDownLatch(1) - var accountData: UserAccountDataEvent? = null + var accountData: AccountDataEvent? = null val liveAccountData = runBlocking(Dispatchers.Main) { - session.getLiveAccountDataEvent(type) + session.userAccountDataService().getLiveAccountDataEvent(type) } - val accountDataObserver = Observer<Optional<UserAccountDataEvent>?> { t -> + val accountDataObserver = Observer<Optional<AccountDataEvent>?> { t -> if (t?.getOrNull()?.type == type) { accountData = t.getOrNull() accountDataLock.countDown() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt index 64b3e180aac660ca16dbf6679f69b227d10988dd..a0733dda978263754d95b6b841864e356908243a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt @@ -51,12 +51,12 @@ data class SsoIdentityProvider( ) : Parcelable, Comparable<SsoIdentityProvider> { companion object { - const val BRAND_GOOGLE = "org.matrix.google" - const val BRAND_GITHUB = "org.matrix.github" - const val BRAND_APPLE = "org.matrix.apple" - const val BRAND_FACEBOOK = "org.matrix.facebook" - const val BRAND_TWITTER = "org.matrix.twitter" - const val BRAND_GITLAB = "org.matrix.gitlab" + const val BRAND_GOOGLE = "google" + const val BRAND_GITHUB = "github" + const val BRAND_APPLE = "apple" + const val BRAND_FACEBOOK = "facebook" + const val BRAND_TWITTER = "twitter" + const val BRAND_GITLAB = "gitlab" } override fun compareTo(other: SsoIdentityProvider): Int { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index b5f90e87ea92a4184e3f774fe8150442c7819b5f..e888e5d2de748027166540353478115574d7ca8a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -78,7 +78,6 @@ interface Session : InitialSyncProgressService, HomeServerCapabilitiesService, SecureStorageService, - AccountDataService, AccountService { /** @@ -239,6 +238,11 @@ interface Session : */ fun openIdService(): OpenIdService + /** + * Returns the user account data service associated with the session + */ + fun userAccountDataService(): AccountDataService + /** * Add a listener to the session. * @param listener the listener to add. @@ -262,12 +266,17 @@ interface Session : * A global session listener to get notified for some events. */ interface Listener : SessionLifecycleObserver { + /** + * Called when the session received new invites to room so the client can react to it once. + */ + fun onNewInvitedRoom(session: Session, roomId: String) = Unit + /** * Possible cases: * - The access token is not valid anymore, * - a M_CONSENT_NOT_GIVEN error has been received from the homeserver */ - fun onGlobalError(session: Session, globalError: GlobalError) + fun onGlobalError(session: Session, globalError: GlobalError) = Unit } val sharedSecretStorageService: SharedSecretStorageService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataEvent.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataEvent.kt index 744e3e5379829f1383969e743057e1105578b883..e5cbd07aafdeb3bab7b3790e6c5a9871b6933424 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/UserAccountDataEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataEvent.kt @@ -25,7 +25,7 @@ import org.matrix.android.sdk.api.session.events.model.Content * Currently used types are defined in [UserAccountDataTypes]. */ @JsonClass(generateAdapter = true) -data class UserAccountDataEvent( +data class AccountDataEvent( @Json(name = "type") val type: String, @Json(name = "content") val content: Content ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt index 5ebeaad3de6fb8a1819024b154973df3a80e9968..77f3eb0cd92f673619fe6fe8b528cc78e78b0111 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/accountdata/AccountDataService.kt @@ -20,28 +20,31 @@ import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.util.Optional +/** + * This service can be attached globally to the session so it represents user data or attached to a single room. + */ interface AccountDataService { /** * Retrieve the account data with the provided type or null if not found */ - fun getAccountDataEvent(type: String): UserAccountDataEvent? + fun getAccountDataEvent(type: String): AccountDataEvent? /** * Observe the account data with the provided type */ - fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> + fun getLiveAccountDataEvent(type: String): LiveData<Optional<AccountDataEvent>> /** * Retrieve the account data with the provided types. The return list can have a different size that * the size of the types set, because some AccountData may not exist. * If an empty set is provided, all the AccountData are retrieved */ - fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> + fun getAccountDataEvents(types: Set<String>): List<AccountDataEvent> /** * Observe the account data with the provided types. If an empty set is provided, all the AccountData are observed */ - fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> + fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<AccountDataEvent>> /** * Update the account data with the provided type and the provided account data content diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt new file mode 100644 index 0000000000000000000000000000000000000000..43e68725258283e732801538139480194a9c5029 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallIdGenerator.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.session.call + +import java.util.UUID + +object CallIdGenerator { + fun generate() = UUID.randomUUID().toString() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt index dc67aa536afd0a5b295ed52dae2255c181a7095d..c34744e75f5f7ef13a6fa8edb68349897a36c309 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt @@ -20,8 +20,6 @@ interface CallSignalingService { suspend fun getTurnServer(): TurnServerResponse - fun getPSTNProtocolChecker(): PSTNProtocolChecker - /** * Create an outgoing call */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt index 7533619eb074b111279a771e1b211b0357195b58..fcc9f7072dee4ae863648e7418bde20a633a3a16 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/MxCall.kt @@ -26,8 +26,12 @@ interface MxCallDetail { val callId: String val isOutgoing: Boolean val roomId: String - val opponentUserId: String val isVideoCall: Boolean + val ourPartyId: String + val opponentPartyId: Optional<String>? + val opponentVersion: Int + val opponentUserId: String + val capabilities: CallCapabilities? } /** @@ -39,12 +43,6 @@ interface MxCall : MxCallDetail { const val VOIP_PROTO_VERSION = 1 } - val ourPartyId: String - var opponentPartyId: Optional<String>? - var opponentVersion: Int - - var capabilities: CallCapabilities? - var state: CallState /** @@ -91,8 +89,12 @@ interface MxCall : MxCallDetail { /** * Send a m.call.replaces event to initiate call transfer. + * See [org.matrix.android.sdk.api.session.room.model.call.CallReplacesContent] for documentation about the parameters */ - suspend fun transfer(targetUserId: String, targetRoomId: String?) + suspend fun transfer(targetUserId: String, + targetRoomId: String?, + createCallId: String?, + awaitCallId: String?) fun addListener(listener: StateListener) fun removeListener(listener: StateListener) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt deleted file mode 100644 index 6627f62e24afff5b0685273986888cc2b082bba2..0000000000000000000000000000000000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/PSTNProtocolChecker.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. - * - * 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 org.matrix.android.sdk.api.session.call - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.session.thirdparty.GetThirdPartyProtocolsTask -import org.matrix.android.sdk.internal.task.TaskExecutor -import timber.log.Timber -import java.util.concurrent.atomic.AtomicBoolean -import javax.inject.Inject - -private const val PSTN_VECTOR_KEY = "im.vector.protocol.pstn" -private const val PSTN_MATRIX_KEY = "m.protocol.pstn" - -/** - * This class is responsible for checking if the HS support the PSTN protocol. - * As long as the request succeed, it'll check only once by session. - */ -@SessionScope -class PSTNProtocolChecker @Inject internal constructor(private val taskExecutor: TaskExecutor, - private val getThirdPartyProtocolsTask: GetThirdPartyProtocolsTask) { - - interface Listener { - fun onPSTNSupportUpdated() - } - - private var alreadyChecked = AtomicBoolean(false) - - private val pstnSupportListeners = mutableListOf<Listener>() - - fun addListener(listener: Listener) { - pstnSupportListeners.add(listener) - } - - fun removeListener(listener: Listener) { - pstnSupportListeners.remove(listener) - } - - var supportedPSTNProtocol: String? = null - private set - - fun checkForPSTNSupportIfNeeded() { - if (alreadyChecked.get()) return - taskExecutor.executorScope.checkForPSTNSupport() - } - - private fun CoroutineScope.checkForPSTNSupport() = launch { - try { - supportedPSTNProtocol = getSupportedPSTN(3) - alreadyChecked.set(true) - if (supportedPSTNProtocol != null) { - pstnSupportListeners.forEach { - tryOrNull { it.onPSTNSupportUpdated() } - } - } - } catch (failure: Throwable) { - Timber.v("Fail to get supported PSTN, will check again next time.") - } - } - - private suspend fun getSupportedPSTN(maxTries: Int): String? { - val thirdPartyProtocols: Map<String, ThirdPartyProtocol> = try { - getThirdPartyProtocolsTask.execute(Unit) - } catch (failure: Throwable) { - if (maxTries == 1) { - throw failure - } else { - // Wait for 10s before trying again - delay(10_000L) - return getSupportedPSTN(maxTries - 1) - } - } - return when { - thirdPartyProtocols.containsKey(PSTN_VECTOR_KEY) -> PSTN_VECTOR_KEY - thirdPartyProtocols.containsKey(PSTN_MATRIX_KEY) -> PSTN_MATRIX_KEY - else -> null - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt index d2befca1ee146e5a1c239320f9dcb875a30589c3..229a53fa9d71f231afe873a806f7d4fc6e72ab66 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt @@ -31,9 +31,7 @@ object EventType { const val TYPING = "m.typing" const val REDACTION = "m.room.redaction" const val RECEIPT = "m.receipt" - const val TAG = "m.tag" const val ROOM_KEY = "m.room_key" - const val FULLY_READ = "m.fully_read" const val PLUMBING = "m.room.plumbing" const val BOT_OPTIONS = "m.room.bot.options" const val PREVIEW_URLS = "org.matrix.room.preview_urls" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index ac1d726d0324eaafc7ba3f014e5f787c3bc51fab..a6d4583c76f788f2c0bd38ba45b49a059474b225 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -54,7 +54,7 @@ interface PermalinkService { * * @return the permalink, or null in case of error */ - fun createRoomPermalink(roomId: String): String? + fun createRoomPermalink(roomId: String, viaServers: List<String>? = null): String? /** * Creates a permalink for an event. If you have an event you can use [createPermalink] diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt index 8c434fc44016246de6cf3c867a226be9d8ad6bbd..41bcbf8ff6f7541974e6ce377cde5cb2cbf3705d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/Room.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.session.room import androidx.lifecycle.LiveData +import org.matrix.android.sdk.api.session.accountdata.AccountDataService import org.matrix.android.sdk.api.session.room.alias.AliasService import org.matrix.android.sdk.api.session.room.call.RoomCallService import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService @@ -55,7 +56,8 @@ interface Room : RoomCallService, RelationService, RoomCryptoService, - RoomPushRuleService { + RoomPushRuleService, + AccountDataService { /** * The roomId of this room @@ -86,12 +88,12 @@ interface Room : * @return The search result */ suspend fun search(searchTerm: String, - nextBatch: String?, - orderByRecent: Boolean, - limit: Int, - beforeLimit: Int, - afterLimit: Int, - includeProfile: Boolean): SearchResult + nextBatch: String?, + orderByRecent: Boolean, + limit: Int, + beforeLimit: Int, + afterLimit: Int, + includeProfile: Boolean): SearchResult /** * Use this room as a Space, if the type is correct. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt new file mode 100644 index 0000000000000000000000000000000000000000..0e80c307b4f9a7fb9bfb94101642fcc75eb9c849 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/accountdata/RoomAccountDataTypes.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.session.room.accountdata + +object RoomAccountDataTypes { + const val EVENT_TYPE_VIRTUAL_ROOM = "im.vector.is_virtual_room" + const val EVENT_TYPE_TAG = "m.tag" + const val EVENT_TYPE_FULLY_READ = "m.fully_read" +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt index 66293bcb8c6107bf88e4c0b8c0e07b15b7e4e171..8cd2a0538dc2a12504ffa0a045577869af2b866f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/SpaceChildInfo.kt @@ -32,5 +32,7 @@ data class SpaceChildInfo( val parentRoomId: String?, val suggested: Boolean?, val canonicalAlias: String?, - val aliases: List<String>? + val aliases: List<String>?, + val worldReadable: Boolean + ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt index 45a54bb379b58187445595641724fece2263a823..180b32db054229e57911525aae84e922a7df7265 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt @@ -44,7 +44,7 @@ data class CallAnswerContent( * Capability advertisement. */ @Json(name = "capabilities") val capabilities: CallCapabilities? = null -): CallSignallingContent { +): CallSignalingContent { @JsonClass(generateAdapter = true) data class Answer( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt index 7bfe7a97acbdd6260c8d3eb183d83ae9599863b5..dc0a1e3b2e3f69ce3173372926042cf6c8107c7d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt @@ -41,4 +41,4 @@ data class CallCandidatesContent( * Required. The version of the VoIP specification this messages adheres to. */ @Json(name = "version") override val version: String? -): CallSignallingContent +): CallSignalingContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt index 0acc409053d714d561e6077ee9f6820c4500560f..9d6e1a7eaeb09e39308235fdb543827a45694c70 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallHangupContent.kt @@ -44,7 +44,7 @@ data class CallHangupContent( * One of: ["ice_failed", "invite_timeout"] */ @Json(name = "reason") val reason: Reason? = null -) : CallSignallingContent { +) : CallSignalingContent { @JsonClass(generateAdapter = false) enum class Reason { @Json(name = "ice_failed") @@ -56,6 +56,9 @@ data class CallHangupContent( @Json(name = "user_hangup") USER_HANGUP, + @Json(name = "replaced") + REPLACED, + @Json(name = "user_media_failed") USER_MEDIA_FAILED, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt index 42489bc0ceb199000cf65471444f35ac4c81b111..e4332f0ea76fed180e4126b9e8d3282ef3892791 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt @@ -55,7 +55,7 @@ data class CallInviteContent( */ @Json(name = "capabilities") val capabilities: CallCapabilities? = null -): CallSignallingContent { +): CallSignalingContent { @JsonClass(generateAdapter = true) data class Offer( /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt index 040993bb51dda98cba50c5730173e9d43ba6d68a..68dd5ef043e12f97ff068efacf2e171cdf740a94 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt @@ -47,7 +47,7 @@ data class CallNegotiateContent( */ @Json(name = "version") override val version: String? - ): CallSignallingContent { + ): CallSignalingContent { @JsonClass(generateAdapter = true) data class Description( /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt index 1da229b1799715ca934bf6f4c7b28dda909061ea..ea412fbe3eba6fd353c671e6d3486020b79dfefd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallRejectContent.kt @@ -37,4 +37,4 @@ data class CallRejectContent( * Required. The version of the VoIP specification this message adheres to. */ @Json(name = "version") override val version: String? -) : CallSignallingContent +) : CallSignalingContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt index 97a3b8c7a72e576c5956852f1f2870e834275667..4559c5db6d5a6d57fd48381ec878118eb51e65a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt @@ -38,30 +38,30 @@ data class CallReplacesContent( */ @Json(name = "replacement_id") val replacementId: String? = null, /** - * Optional. If specified, the transferee client waits for an invite to this room and joins it - * (possibly waiting for user confirmation) and then continues the transfer in this room. - * If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing. + * Optional. If specified, the transferee client waits for an invite to this room and joins it + * (possibly waiting for user confirmation) and then continues the transfer in this room. + * If absent, the transferee contacts the Matrix User ID given in the target_user field in a room of its choosing. */ - @Json(name = "target_room") val targerRoomId: String? = null, + @Json(name = "target_room") val targetRoomId: String? = null, /** - * An object giving information about the transfer target + * An object giving information about the transfer target */ @Json(name = "target_user") val targetUser: TargetUser? = null, /** - * If specified, gives the call ID for the transferee's client to use when placing the replacement call. - * Mutually exclusive with await_call + * If specified, gives the call ID for the transferee's client to use when placing the replacement call. + * Mutually exclusive with await_call */ @Json(name = "create_call") val createCall: String? = null, /** - * If specified, gives the call ID that the transferee's client should wait for. - * Mutually exclusive with create_call. + * If specified, gives the call ID that the transferee's client should wait for. + * Mutually exclusive with create_call. */ @Json(name = "await_call") val awaitCall: String? = null, /** * Required. The version of the VoIP specification this messages adheres to. */ @Json(name = "version") override val version: String? -): CallSignallingContent { +): CallSignalingContent { @JsonClass(generateAdapter = true) data class TargetUser( @@ -77,6 +77,5 @@ data class CallReplacesContent( * Optional. The avatar URL of the transfer target. */ @Json(name = "avatar_url") val avatarUrl: String? - ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt index 6ea70ac990589b46bd456e3d37ed0a24a67df773..795f332711179121fdf8d40b24e7b2978ae09b90 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt @@ -41,4 +41,4 @@ data class CallSelectAnswerContent( * Required. The version of the VoIP specification this message adheres to. */ @Json(name = "version") override val version: String? -): CallSignallingContent +): CallSignalingContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt index f8d8c2a5e82d777f55cb33ca982c44eb4a2a0cab..92b43dd22ca01fade7c6cc949dc43500719b90e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignallingContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSignalingContent.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.room.model.call -interface CallSignallingContent { +interface CallSignalingContent { /** * Required. A unique identifier for the call. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt index c96a800ee586b32895bbd6bd9ebf3fcab8bb6890..1e8959afc3d6c0bcbe82f4ab2c2e3ccbcabdc806 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt @@ -35,5 +35,5 @@ object MessageType { const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" const val MSGTYPE_CONFETTI = "nic.custom.confetti" - const val MSGTYPE_SNOW = "io.element.effect.snowfall" + const val MSGTYPE_SNOWFALL = "io.element.effect.snowfall" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/thirdparty/RoomDirectoryData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/thirdparty/RoomDirectoryData.kt deleted file mode 100644 index 91f429d773cd0cf99ff8f9df331e0a006f3c6275..0000000000000000000000000000000000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/thirdparty/RoomDirectoryData.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * 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 org.matrix.android.sdk.api.session.room.model.thirdparty - -/** - * This class describes a rooms directory server. - */ -data class RoomDirectoryData( - - /** - * The server name (might be null) - * Set null when the server is the current user's home server. - */ - val homeServer: String? = null, - - /** - * The display name (the server description) - */ - val displayName: String = DEFAULT_HOME_SERVER_NAME, - - /** - * The third party server identifier - */ - val thirdPartyInstanceId: String? = null, - - /** - * Tell if all the federated servers must be included - */ - val includeAllNetworks: Boolean = false, - - /** - * the avatar url - */ - val avatarUrl: String? = null -) { - - companion object { - const val DEFAULT_HOME_SERVER_NAME = "Matrix" - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt index 888950dc126b118e64debae5c7f6e889a2ba2927..b78cd5e032225fe030fc20d71751451b060272b8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/peeking/PeekResult.kt @@ -28,7 +28,8 @@ sealed class PeekResult { val numJoinedMembers: Int?, val roomType: String?, val viaServers: List<String>, - val someMembers: List<MatrixItem.UserItem>? + val someMembers: List<MatrixItem.UserItem>?, + val isPublic: Boolean ) : PeekResult() data class PeekingNotAllowed( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt index d77dfcfe358e5ea79c1115ade71b0f42203750cf..246813a524a0f391037b71a655ba41623cee7a83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/thirdparty/model/ThirdPartyUser.kt @@ -22,16 +22,16 @@ import org.matrix.android.sdk.api.util.JsonDict @JsonClass(generateAdapter = true) data class ThirdPartyUser( - /* - Required. A Matrix User ID represting a third party user. + /** + * Required. A Matrix User ID representing a third party user. */ @Json(name = "userid") val userId: String, - /* - Required. The protocol ID that the third party location is a part of. + /** + * Required. The protocol ID that the third party location is a part of. */ @Json(name = "protocol") val protocol: String, - /* - Required. Information used to identify this third party location. + /** + * Required. Information used to identify this third party location. */ @Json(name = "fields") val fields: JsonDict ) 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 deb279eb95f063acf97575441ea68a2b122b10ae..3d2773fb4bef8294324e23998a56b785666d15b1 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 @@ -20,6 +20,7 @@ import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.sender.SenderInfo @@ -38,6 +39,8 @@ sealed class MatrixItem( init { if (BuildConfig.DEBUG) checkId() } + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } data class EventItem(override val id: String, @@ -47,6 +50,8 @@ sealed class MatrixItem( init { if (BuildConfig.DEBUG) checkId() } + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } data class RoomItem(override val id: String, @@ -56,6 +61,19 @@ sealed class MatrixItem( init { if (BuildConfig.DEBUG) checkId() } + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) + } + + data class SpaceItem(override val id: String, + override val displayName: String? = null, + override val avatarUrl: String? = null) + : MatrixItem(id, displayName, avatarUrl) { + init { + if (BuildConfig.DEBUG) checkId() + } + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } data class RoomAliasItem(override val id: String, @@ -68,6 +86,8 @@ sealed class MatrixItem( // Best name is the id, and we keep the displayName of the room for the case we need the first letter override fun getBestName() = id + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } data class GroupItem(override val id: String, @@ -80,6 +100,8 @@ sealed class MatrixItem( // Best name is the id, and we keep the displayName of the room for the case we need the first letter override fun getBestName() = id + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } open fun getBestName(): String { @@ -92,12 +114,15 @@ sealed class MatrixItem( } } + abstract fun updateAvatar(newAvatar: String?): MatrixItem + /** * Return the prefix as defined in the matrix spec (and not extracted from the id) */ fun getIdPrefix() = when (this) { is UserItem -> '@' is EventItem -> '$' + is SpaceItem, is RoomItem -> '!' is RoomAliasItem -> '#' is GroupItem -> '+' @@ -148,7 +173,11 @@ fun User.toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl) fun GroupSummary.toMatrixItem() = MatrixItem.GroupItem(groupId, displayName, avatarUrl) -fun RoomSummary.toMatrixItem() = MatrixItem.RoomItem(roomId, displayName, avatarUrl) +fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) { + MatrixItem.SpaceItem(roomId, displayName, avatarUrl) +} else { + MatrixItem.RoomItem(roomId, displayName, avatarUrl) +} fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl) @@ -159,4 +188,8 @@ fun RoomMemberSummary.toMatrixItem() = MatrixItem.UserItem(userId, displayName, fun SenderInfo.toMatrixItem() = MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) -fun SpaceChildInfo.toMatrixItem() = MatrixItem.RoomItem(childRoomId, name ?: canonicalAlias ?: "", avatarUrl) +fun SpaceChildInfo.toMatrixItem() = if (roomType == RoomType.SPACE) { + MatrixItem.SpaceItem(childRoomId, name ?: canonicalAlias, avatarUrl) +} else { + MatrixItem.RoomItem(childRoomId, name ?: canonicalAlias, avatarUrl) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt index e0c52cf9ca95a451b35c9703837846135e9fb435..3742a429d2de65422fa494a1fda16a127a1628cf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/Constants.kt @@ -33,7 +33,6 @@ internal const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/" * Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login */ internal const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect" -internal const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect" internal const val SSO_REDIRECT_URL_PARAM = "redirectUrl" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 46256f4b81fc05cb4f5735c2341cf0be24702a93..20ce438d8e8a44fb4fbb1a1201f95b0d43d1cad7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -88,11 +88,9 @@ internal class DefaultAuthenticationService @Inject constructor( return buildString { append(homeServerUrlBase) + append(SSO_REDIRECT_PATH) if (providerId != null) { - append(MSC2858_SSO_REDIRECT_PATH) append("/$providerId") - } else { - append(SSO_REDIRECT_PATH) } // Set the redirect url appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt index d0d17e2cd5378874e93335cfb0cf1392bbd59214..c718fae3906e6226a43efeb8e1fcf21c00ff6bb4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt @@ -42,7 +42,7 @@ internal data class LoginFlow( * the client can show a button for each of the supported providers * See MSC #2858 */ - @Json(name = "org.matrix.msc2858.identity_providers") + @Json(name = "identity_providers") val ssoIdentityProvider: List<SsoIdentityProvider>? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index d810c8b1a8bb85d47a0e9e38b0952bb38fab1026..2b3c3b28eebfca2f6da87efd999ca7cfadc51398 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database import io.realm.DynamicRealm import io.realm.FieldAttribute import io.realm.RealmMigration +import org.matrix.android.sdk.api.session.room.model.VersioningState import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent @@ -30,6 +31,7 @@ import org.matrix.android.sdk.internal.database.model.EventEntityFields import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields @@ -44,7 +46,7 @@ import javax.inject.Inject class RealmSessionStoreMigration @Inject constructor() : RealmMigration { companion object { - const val SESSION_STORE_SCHEMA_VERSION = 13L + const val SESSION_STORE_SCHEMA_VERSION = 14L } override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { @@ -63,6 +65,7 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { if (oldVersion <= 10) migrateTo11(realm) if (oldVersion <= 11) migrateTo12(realm) if (oldVersion <= 12) migrateTo13(realm) + if (oldVersion <= 13) migrateTo14(realm) } private fun migrateTo1(realm: DynamicRealm) { @@ -278,11 +281,29 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration { private fun migrateTo13(realm: DynamicRealm) { Timber.d("Step 12 -> 13") - // Fix issue with the nightly build. Eventually play again the migration which has been included in migrateTo12() realm.schema.get("SpaceChildSummaryEntity") ?.takeIf { !it.hasField(SpaceChildSummaryEntityFields.SUGGESTED) } ?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java) ?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true) } + + private fun migrateTo14(realm: DynamicRealm) { + Timber.d("Step 13 -> 14") + val roomAccountDataSchema = realm.schema.create("RoomAccountDataEntity") + .addField(RoomAccountDataEntityFields.CONTENT_STR, String::class.java) + .addField(RoomAccountDataEntityFields.TYPE, String::class.java, FieldAttribute.INDEXED) + + realm.schema.get("RoomEntity") + ?.addRealmListField(RoomEntityFields.ACCOUNT_DATA.`$`, roomAccountDataSchema) + + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, Boolean::class.java, FieldAttribute.INDEXED) + ?.transform { + val isHiddenFromUser = it.getString(RoomSummaryEntityFields.VERSIONING_STATE_STR) == VersioningState.UPGRADED_ROOM_JOINED.name + it.setBoolean(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, isHiddenFromUser) + } + + roomAccountDataSchema.isEmbedded = true + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt index 54315a183587d22eaf6bc0da61e82297d42e2a20..4edfdad8970e9a855eacf8aee26e5cca123f1c64 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/AccountDataMapper.kt @@ -17,17 +17,25 @@ package org.matrix.android.sdk.internal.database.mapper import com.squareup.moshi.Moshi +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntity import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import javax.inject.Inject internal class AccountDataMapper @Inject constructor(moshi: Moshi) { private val adapter = moshi.adapter<Map<String, Any>>(JSON_DICT_PARAMETERIZED_TYPE) - fun map(entity: UserAccountDataEntity): UserAccountDataEvent { - return UserAccountDataEvent( + fun map(entity: UserAccountDataEntity): AccountDataEvent { + return AccountDataEvent( + type = entity.type ?: "", + content = entity.contentStr?.let { adapter.fromJson(it) }.orEmpty() + ) + } + + fun map(entity: RoomAccountDataEntity): AccountDataEvent { + return AccountDataEvent( type = entity.type ?: "", content = entity.contentStr?.let { adapter.fromJson(it) }.orEmpty() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt index 3fea15bd3dd7facf9edb659156506b9a37b9b2b3..c32c019625e0be622aed19e296871ffb6ca3038d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.database.mapper +import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo @@ -92,7 +93,8 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa parentRoomId = roomSummaryEntity.roomId, suggested = it.suggested, canonicalAlias = it.childSummaryEntity?.canonicalAlias, - aliases = it.childSummaryEntity?.aliases?.toList() + aliases = it.childSummaryEntity?.aliases?.toList(), + worldReadable = it.childSummaryEntity?.joinRules == RoomJoinRules.PUBLIC ) }, flattenParentIds = roomSummaryEntity.flattenParentIds?.split("|") ?: emptyList() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt new file mode 100644 index 0000000000000000000000000000000000000000..40040b573826b8bbfa0bc7e4c91468e6a3dc595b --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomAccountDataEntity.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.database.model + +import io.realm.RealmObject +import io.realm.annotations.Index +import io.realm.annotations.RealmClass + +@RealmClass(embedded = true) +internal open class RoomAccountDataEntity( + @Index var type: String? = null, + var contentStr: String? = null +) : RealmObject() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt index 58297776f06b1f47189aee4cf22ad3ffa718abc1..65483e05bf65b622088e19923bdaaf0fced2a4e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt @@ -23,7 +23,8 @@ import io.realm.annotations.PrimaryKey internal open class RoomEntity(@PrimaryKey var roomId: String = "", var chunks: RealmList<ChunkEntity> = RealmList(), - var sendingTimelineEvents: RealmList<TimelineEventEntity> = RealmList() + var sendingTimelineEvents: RealmList<TimelineEventEntity> = RealmList(), + var accountData: RealmList<RoomAccountDataEntity> = RealmList() ) : RealmObject() { private var membershipStr: String = Membership.NONE.name diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt index 1001f9cd66ea11d0ae57d6cdd265478d6406c467..64dc08e8274d1e98bd201a363a8a3eda6d14f38d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt @@ -232,6 +232,12 @@ internal open class RoomSummaryEntity( } } + @Index + var isHiddenFromUser: Boolean = false + set(value) { + if (value != field) field = value + } + @Index private var versioningStateStr: String = VersioningState.NONE.name var versioningState: VersioningState diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt index 72ae512fa5a444529809da11b63028355ba4251e..19472e21d96838372b3fa283d3dee5ca23547b9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/SessionRealmModule.kt @@ -62,6 +62,7 @@ import io.realm.annotations.RealmModule UserAccountDataEntity::class, ScalarTokenEntity::class, WellknownIntegrationManagerConfigEntity::class, + RoomAccountDataEntity::class, SpaceChildSummaryEntity::class, SpaceParentSummaryEntity::class ]) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt index 27e8d9d8d1a0539bbb11bfd7b8e24db7e24e4261..a551f973793c8b9d91c88d1d296f676c68f59b0b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt @@ -29,6 +29,10 @@ internal fun RoomEntity.Companion.where(realm: Realm, roomId: String): RealmQuer .equalTo(RoomEntityFields.ROOM_ID, roomId) } +internal fun RoomEntity.Companion.getOrCreate(realm: Realm, roomId: String): RoomEntity { + return where(realm, roomId).findFirst() ?: realm.createObject(RoomEntity::class.java, roomId) +} + internal fun RoomEntity.Companion.where(realm: Realm, membership: Membership? = null): RealmQuery<RoomEntity> { val query = realm.where<RoomEntity>() if (membership != null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt index 9afdb40ed1559cd1aad9d46c2f7afc37ce23f1de..8be11e80f37a40d898f3c98dbe74e6d1e2cdedd0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/GlobalErrorHandler.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.network +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.task.TaskExecutor -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -44,7 +44,6 @@ internal class GlobalErrorHandler @Inject constructor( sessionParamsStore.setTokenInvalid(sessionId) } } - listener?.onGlobalError(globalError) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index b100a336a79b2c3cc909312bd1941391d47706db..1f4797819892a8455d862832d00b416b25323cf9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -74,6 +74,7 @@ import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService import org.matrix.android.sdk.internal.session.sync.SyncTokenStore import org.matrix.android.sdk.internal.session.sync.job.SyncThread import org.matrix.android.sdk.internal.session.sync.job.SyncWorker +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataService import org.matrix.android.sdk.internal.util.createUIHandler import timber.log.Timber import javax.inject.Inject @@ -117,7 +118,7 @@ internal class DefaultSession @Inject constructor( private val contentDownloadStateTracker: ContentDownloadStateTracker, private val initialSyncProgressService: Lazy<InitialSyncProgressService>, private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>, - private val accountDataService: Lazy<AccountDataService>, + private val accountDataService: Lazy<UserAccountDataService>, private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>, private val accountService: Lazy<AccountService>, private val eventService: Lazy<EventService>, @@ -130,6 +131,7 @@ internal class DefaultSession @Inject constructor( @UnauthenticatedWithCertificate private val unauthenticatedWithCertificateOkHttpClient: Lazy<OkHttpClient> ) : Session, + GlobalErrorHandler.Listener, RoomService by roomService.get(), RoomDirectoryService by roomDirectoryService.get(), GroupService by groupService.get(), @@ -144,9 +146,7 @@ internal class DefaultSession @Inject constructor( SecureStorageService by secureStorageService.get(), HomeServerCapabilitiesService by homeServerCapabilitiesService.get(), ProfileService by profileService.get(), - AccountDataService by accountDataService.get(), - AccountService by accountService.get(), - GlobalErrorHandler.Listener { + AccountService by accountService.get() { override val sharedSecretStorageService: SharedSecretStorageService get() = _sharedSecretStorageService.get() @@ -164,16 +164,16 @@ internal class DefaultSession @Inject constructor( override fun open() { assert(!isOpen) isOpen = true + globalErrorHandler.listener = this cryptoService.get().ensureDevice() uiHandler.post { lifecycleObservers.forEach { it.onSessionStarted(this) } - sessionListeners.dispatch { - it.onSessionStarted(this) + sessionListeners.dispatch { _, listener -> + listener.onSessionStarted(this) } } - globalErrorHandler.listener = this } override fun requireBackgroundSync() { @@ -213,13 +213,13 @@ internal class DefaultSession @Inject constructor( // timelineEventDecryptor.destroy() uiHandler.post { lifecycleObservers.forEach { it.onSessionStopped(this) } - sessionListeners.dispatch { - it.onSessionStopped(this) + sessionListeners.dispatch { _, listener -> + listener.onSessionStopped(this) } } cryptoService.get().close() - isOpen = false globalErrorHandler.listener = null + isOpen = false } override fun getSyncStateLive() = getSyncThread().liveState() @@ -243,8 +243,8 @@ internal class DefaultSession @Inject constructor( lifecycleObservers.forEach { it.onClearCache(this) } - sessionListeners.dispatch { - it.onClearCache(this) + sessionListeners.dispatch { _, listener -> + listener.onClearCache(this) } } withContext(NonCancellable) { @@ -254,8 +254,8 @@ internal class DefaultSession @Inject constructor( } override fun onGlobalError(globalError: GlobalError) { - sessionListeners.dispatch { - it.onGlobalError(this, globalError) + sessionListeners.dispatch { _, listener -> + listener.onGlobalError(this, globalError) } } @@ -293,6 +293,8 @@ internal class DefaultSession @Inject constructor( override fun openIdService(): OpenIdService = openIdService.get() + override fun userAccountDataService(): AccountDataService = accountDataService.get() + override fun getOkHttpClient(): OkHttpClient { return unauthenticatedWithCertificateOkHttpClient.get() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt index 563ff4ada322cb827702b3ef7612e1e25a99caad..d5c661b1e474d4f979df60103f7b147d2c75dfc6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionListeners.kt @@ -16,10 +16,17 @@ package org.matrix.android.sdk.internal.session +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.internal.SessionManager +import org.matrix.android.sdk.internal.di.SessionId +import timber.log.Timber import javax.inject.Inject -internal class SessionListeners @Inject constructor() { +@SessionScope +internal class SessionListeners @Inject constructor( + @SessionId private val sessionId: String, + private val sessionManager: SessionManager) { private val listeners = mutableSetOf<Session.Listener>() @@ -35,11 +42,18 @@ internal class SessionListeners @Inject constructor() { } } - fun dispatch(block: (Session.Listener) -> Unit) { + fun dispatch(block: (Session, Session.Listener) -> Unit) { synchronized(listeners) { + val session = getSession() ?: return Unit.also { + Timber.w("You don't have any attached session") + } listeners.forEach { - block(it) + tryOrNull { block(session, it) } } } } + + private fun getSession(): Session? { + return sessionManager.getSessionComponent(sessionId)?.session() + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index de74b3481822893085a9c3ed49e11ac318ba7f43..49ce92372e2381a984ab4516fc3efea1d811021f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -93,7 +93,7 @@ import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProces import org.matrix.android.sdk.internal.session.room.tombstone.RoomTombstoneEventProcessor import org.matrix.android.sdk.internal.session.securestorage.DefaultSecureStorageService import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker -import org.matrix.android.sdk.internal.session.user.accountdata.DefaultAccountDataService +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataService import org.matrix.android.sdk.internal.session.widgets.DefaultWidgetURLFormatter import org.matrix.android.sdk.internal.util.md5 import retrofit2.Retrofit @@ -364,7 +364,7 @@ internal abstract class SessionModule { abstract fun bindHomeServerCapabilitiesService(service: DefaultHomeServerCapabilitiesService): HomeServerCapabilitiesService @Binds - abstract fun bindAccountDataService(service: DefaultAccountDataService): AccountDataService + abstract fun bindAccountDataService(service: UserAccountDataService): AccountDataService @Binds abstract fun bindEventService(service: DefaultEventService): EventService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt index 8d7e9e819a7bc7a95590f85622108c8797e3fc84..61ea660b6045313708ca783a80078f9e74bb68ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallSignalingHandler.kt @@ -24,18 +24,15 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.call.CallAnswerContent import org.matrix.android.sdk.api.session.room.model.call.CallCandidatesContent -import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent -import org.matrix.android.sdk.api.session.room.model.call.CallSignallingContent -import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber -import java.math.BigDecimal import javax.inject.Inject @SessionScope @@ -192,6 +189,9 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa // Ignore remote echo return } + if (event.roomId == null || event.senderId == null) { + return + } if (event.senderId == userId) { // discard current call, it's answered by another of my session activeCallHandler.removeCall(call.callId) @@ -201,20 +201,16 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa Timber.v("Ignoring answer from party ID ${content.partyId} we already have an answer from ${call.opponentPartyId}") return } - call.apply { - opponentPartyId = Optional.from(content.partyId) - opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION - capabilities = content.capabilities ?: CallCapabilities() - } + mxCallFactory.updateOutgoingCallWithOpponentData(call, event.senderId, content, content.capabilities) callListenersDispatcher.onCallAnswerReceived(content) } } - private fun MxCall.partyIdsMatches(contentSignallingContent: CallSignallingContent): Boolean { - return opponentPartyId?.getOrNull() == contentSignallingContent.partyId + private fun MxCall.partyIdsMatches(contentSignalingContent: CallSignalingContent): Boolean { + return opponentPartyId?.getOrNull() == contentSignalingContent.partyId } - private fun CallSignallingContent.getCall(): MxCall? { + private fun CallSignalingContent.getCall(): MxCall? { val currentCall = callId?.let { activeCallHandler.getCallWithId(it) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt index 7d046cb6422e15e0028653e16fa395ed27770919..da1f84cc899f297a337de1c408af899f8c1ebf08 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.session.call import org.matrix.android.sdk.api.session.call.CallListener import org.matrix.android.sdk.api.session.call.CallSignalingService import org.matrix.android.sdk.api.session.call.MxCall -import org.matrix.android.sdk.api.session.call.PSTNProtocolChecker import org.matrix.android.sdk.api.session.call.TurnServerResponse import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber @@ -30,18 +29,13 @@ internal class DefaultCallSignalingService @Inject constructor( private val callSignalingHandler: CallSignalingHandler, private val mxCallFactory: MxCallFactory, private val activeCallHandler: ActiveCallHandler, - private val turnServerDataSource: TurnServerDataSource, - private val pstnProtocolChecker: PSTNProtocolChecker + private val turnServerDataSource: TurnServerDataSource ) : CallSignalingService { override suspend fun getTurnServer(): TurnServerResponse { return turnServerDataSource.getTurnServer() } - override fun getPSTNProtocolChecker(): PSTNProtocolChecker { - return pstnProtocolChecker - } - override fun createOutgoingCall(roomId: String, otherUserId: String, isVideoCall: Boolean): MxCall { return mxCallFactory.createOutgoingCall(roomId, otherUserId, isVideoCall).also { activeCallHandler.addCall(it) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt index b14cdca63c5c6e059600b8e635019afdc6248a82..547be2253f80d60c28d613c41be91872a4565f68 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/MxCallFactory.kt @@ -17,18 +17,17 @@ package org.matrix.android.sdk.internal.session.call import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.session.call.CallIdGenerator import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent -import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.call.model.MxCallImpl import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor -import java.math.BigDecimal -import java.util.UUID import javax.inject.Inject internal class MxCallFactory @Inject constructor( @@ -48,32 +47,38 @@ internal class MxCallFactory @Inject constructor( roomId = roomId, userId = userId, ourPartyId = deviceId ?: "", - opponentUserId = opponentUserId, isVideoCall = content.isVideo(), localEchoEventFactory = localEchoEventFactory, eventSenderProcessor = eventSenderProcessor, matrixConfiguration = matrixConfiguration, getProfileInfoTask = getProfileInfoTask ).apply { - opponentPartyId = Optional.from(content.partyId) - opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION - capabilities = content.capabilities ?: CallCapabilities() + updateOpponentData(opponentUserId, content, content.capabilities) } } fun createOutgoingCall(roomId: String, opponentUserId: String, isVideoCall: Boolean): MxCall { return MxCallImpl( - callId = UUID.randomUUID().toString(), + callId = CallIdGenerator.generate(), isOutgoing = true, roomId = roomId, userId = userId, ourPartyId = deviceId ?: "", - opponentUserId = opponentUserId, isVideoCall = isVideoCall, localEchoEventFactory = localEchoEventFactory, eventSenderProcessor = eventSenderProcessor, matrixConfiguration = matrixConfiguration, getProfileInfoTask = getProfileInfoTask - ) + ).apply { + // Setup with this userId, might be updated when processing the Answer event + this.opponentUserId = opponentUserId + } + } + + fun updateOutgoingCallWithOpponentData(call: MxCall, + userId: String, + content: CallSignalingContent, + callCapabilities: CallCapabilities?) { + (call as? MxCallImpl)?.updateOpponentData(userId, content, callCapabilities) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt index 88fba0ea859a3ed43c5fa91d73fbf159912a6303..f101685a4b46b6f6248d79e635956bf139d8dda6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/model/MxCallImpl.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.call.model import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.session.call.CallIdGenerator import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.MxCall import org.matrix.android.sdk.api.session.events.model.Content @@ -36,6 +37,7 @@ import org.matrix.android.sdk.api.session.room.model.call.CallNegotiateContent import org.matrix.android.sdk.api.session.room.model.call.CallRejectContent import org.matrix.android.sdk.api.session.room.model.call.CallReplacesContent import org.matrix.android.sdk.api.session.room.model.call.CallSelectAnswerContent +import org.matrix.android.sdk.api.session.room.model.call.CallSignalingContent import org.matrix.android.sdk.api.session.room.model.call.SdpType import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.session.call.DefaultCallSignalingService @@ -43,14 +45,13 @@ import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor import timber.log.Timber -import java.util.UUID +import java.math.BigDecimal internal class MxCallImpl( override val callId: String, override val isOutgoing: Boolean, override val roomId: String, private val userId: String, - override val opponentUserId: String, override val isVideoCall: Boolean, override val ourPartyId: String, private val localEchoEventFactory: LocalEchoEventFactory, @@ -61,8 +62,16 @@ internal class MxCallImpl( override var opponentPartyId: Optional<String>? = null override var opponentVersion: Int = MxCall.VOIP_PROTO_VERSION + override lateinit var opponentUserId: String override var capabilities: CallCapabilities? = null + fun updateOpponentData(userId: String, content: CallSignalingContent, callCapabilities: CallCapabilities?) { + opponentPartyId = Optional.from(content.partyId) + opponentVersion = content.version?.let { BigDecimal(it).intValueExact() } ?: MxCall.VOIP_PROTO_VERSION + opponentUserId = userId + capabilities = callCapabilities ?: CallCapabilities() + } + override var state: CallState = CallState.Idle set(value) { field = value @@ -202,7 +211,10 @@ internal class MxCallImpl( .also { eventSenderProcessor.postEvent(it) } } - override suspend fun transfer(targetUserId: String, targetRoomId: String?) { + override suspend fun transfer(targetUserId: String, + targetRoomId: String?, + createCallId: String?, + awaitCallId: String?) { val profileInfoParams = GetProfileInfoTask.Params(targetUserId) val profileInfo = try { getProfileInfoTask.execute(profileInfoParams) @@ -213,15 +225,16 @@ internal class MxCallImpl( CallReplacesContent( callId = callId, partyId = ourPartyId, - replacementId = UUID.randomUUID().toString(), + replacementId = CallIdGenerator.generate(), version = MxCall.VOIP_PROTO_VERSION.toString(), targetUser = CallReplacesContent.TargetUser( id = targetUserId, displayName = profileInfo?.get(ProfileService.DISPLAY_NAME_KEY) as? String, avatarUrl = profileInfo?.get(ProfileService.AVATAR_URL_KEY) as? String ), - targerRoomId = targetRoomId, - createCall = UUID.randomUUID().toString() + targetRoomId = targetRoomId, + awaitCall = awaitCallId, + createCall = createCallId ) .let { createEventAndLocalEcho(type = EventType.CALL_REPLACES, roomId = roomId, content = it.toContent()) } .also { eventSenderProcessor.postEvent(it) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt index c28668a53eb77074f077c62a87d8e826fd4a8ac7..82cd682eae0ecc50bd69db958e16f8685f1d9d03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/ThumbnailExtractor.kt @@ -23,8 +23,11 @@ import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.util.MimeTypes import timber.log.Timber import java.io.ByteArrayOutputStream +import javax.inject.Inject -internal object ThumbnailExtractor { +internal class ThumbnailExtractor @Inject constructor( + private val context: Context +) { class ThumbnailData( val width: Int, @@ -34,22 +37,22 @@ internal object ThumbnailExtractor { val mimeType: String ) - fun extractThumbnail(context: Context, attachment: ContentAttachmentData): ThumbnailData? { + fun extractThumbnail(attachment: ContentAttachmentData): ThumbnailData? { return if (attachment.type == ContentAttachmentData.Type.VIDEO) { - extractVideoThumbnail(context, attachment) + extractVideoThumbnail(attachment) } else { null } } - private fun extractVideoThumbnail(context: Context, attachment: ContentAttachmentData): ThumbnailData? { + private fun extractVideoThumbnail(attachment: ContentAttachmentData): ThumbnailData? { var thumbnailData: ThumbnailData? = null val mediaMetadataRetriever = MediaMetadataRetriever() try { mediaMetadataRetriever.setDataSource(context, attachment.queryUri) mediaMetadataRetriever.frameAtTime?.let { thumbnail -> val outputStream = ByteArrayOutputStream() - thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, outputStream) + thumbnail.compress(Bitmap.CompressFormat.JPEG, 80, outputStream) val thumbnailWidth = thumbnail.width val thumbnailHeight = thumbnail.height val thumbnailSize = outputStream.size() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index 06cbf1ba90241f7dd101e071ae92e3c0fbf0639b..237411db53d72f614b887eb30af833a5a000706e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -82,6 +82,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter @Inject lateinit var cancelSendTracker: CancelSendTracker @Inject lateinit var imageCompressor: ImageCompressor @Inject lateinit var videoCompressor: VideoCompressor + @Inject lateinit var thumbnailExtractor: ThumbnailExtractor @Inject lateinit var localEchoRepository: LocalEchoRepository @Inject lateinit var temporaryFileCreator: TemporaryFileCreator @@ -302,7 +303,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter * If appropriate, it will create and upload a thumbnail */ private suspend fun dealWithThumbnail(params: Params): UploadThumbnailResult? { - return ThumbnailExtractor.extractThumbnail(context, params.attachment) + return thumbnailExtractor.extractThumbnail(params.attachment) ?.let { thumbnailData -> val thumbnailProgressListener = object : ProgressRequestBody.Listener { override fun onProgress(current: Long, total: Long) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt index 475781ef017a4eda68f64f12ad6ec96620f074e7..4f88d8eb9507b1ca1eccd9cea549a90d74f8efe6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt @@ -44,7 +44,7 @@ import org.matrix.android.sdk.internal.session.profile.BindThreePidsTask import org.matrix.android.sdk.internal.session.profile.UnbindThreePidsTask import org.matrix.android.sdk.internal.session.sync.model.accountdata.IdentityServerContent import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes -import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.ensureProtocol @@ -77,7 +77,7 @@ internal class DefaultIdentityService @Inject constructor( private val submitTokenForBindingTask: IdentitySubmitTokenForBindingTask, private val unbindThreePidsTask: UnbindThreePidsTask, private val identityApiProvider: IdentityApiProvider, - private val accountDataDataSource: AccountDataDataSource, + private val accountDataDataSource: UserAccountDataDataSource, private val homeServerCapabilitiesService: HomeServerCapabilitiesService, private val sessionParams: SessionParams ) : IdentityService, SessionLifecycleObserver { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt index 3df9a00cc15fa494a95945c5ccd8b85889a98740..f79f8084a8e501d0f4a8bb1908d481ef18a9896e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt @@ -33,8 +33,8 @@ import org.matrix.android.sdk.internal.extensions.observeNotNull import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent -import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence @@ -57,7 +57,7 @@ import javax.inject.Inject internal class IntegrationManager @Inject constructor(matrixConfiguration: MatrixConfiguration, @SessionDatabase private val monarchy: Monarchy, private val updateUserAccountDataTask: UpdateUserAccountDataTask, - private val accountDataDataSource: AccountDataDataSource, + private val accountDataDataSource: UserAccountDataDataSource, private val widgetFactory: WidgetFactory) : SessionLifecycleObserver { @@ -240,7 +240,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri ) } - private fun UserAccountDataEvent.asIntegrationManagerWidgetContent(): WidgetContent? { + private fun AccountDataEvent.asIntegrationManagerWidgetContent(): WidgetContent? { return extractWidgetSequence(widgetFactory) .filter { WidgetType.IntegrationManager == it.type diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 7db9d8f68ae239e445fed97eb5e8d5483c460a75..134da4ce51b975135071a762acc06fd9864aac0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -33,8 +33,8 @@ internal class DefaultPermalinkService @Inject constructor( return permalinkFactory.createPermalink(id) } - override fun createRoomPermalink(roomId: String): String? { - return permalinkFactory.createRoomPermalink(roomId) + override fun createRoomPermalink(roomId: String, viaServers: List<String>?): String? { + return permalinkFactory.createRoomPermalink(roomId, viaServers) } override fun createPermalink(roomId: String, eventId: String): String { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 970752449aa04e00960327939be32ba09d4f2225..639e45582a07eaab79fa7cdafbebb556be3e4df2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -40,11 +40,18 @@ internal class PermalinkFactory @Inject constructor( } else MATRIX_TO_URL_BASE + escape(id) } - fun createRoomPermalink(roomId: String): String? { + fun createRoomPermalink(roomId: String, via: List<String>? = null): String? { return if (roomId.isEmpty()) { null } else { - MATRIX_TO_URL_BASE + escape(roomId) + viaParameterFinder.computeViaParams(userId, roomId) + buildString { + append(MATRIX_TO_URL_BASE) + append(escape(roomId)) + append( + via?.takeIf { it.isNotEmpty() }?.let { viaParameterFinder.asUrlViaParameters(it) } + ?: viaParameterFinder.computeViaParams(userId, roomId) + ) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt index 0da60e9ba2affa030270720565911884ab7ab36d..72fbfcced5ee6f6dbf608d623bebb8f238380a32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/ViaParameterFinder.kt @@ -39,8 +39,11 @@ internal class ViaParameterFinder @Inject constructor( * current user one. */ fun computeViaParams(userId: String, roomId: String): String { - return computeViaParams(userId, roomId, 3) - .joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") } + return asUrlViaParameters(computeViaParams(userId, roomId, 3)) + } + + fun asUrlViaParameters(viaList: List<String>): String { + return viaList.joinToString(prefix = "?via=", separator = "&via=") { URLEncoder.encode(it, "utf-8") } } fun computeViaParams(userId: String, roomId: String, max: Int): List<String> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt index a5e066dae80331f7c8601fcde66af626d69bedab..5a2eef7e8a3dbe5fa23a93cfb9bea6a29026f95d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room import androidx.lifecycle.LiveData +import org.matrix.android.sdk.api.session.accountdata.AccountDataService import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.Room @@ -41,34 +42,35 @@ import org.matrix.android.sdk.api.session.space.Space import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder +import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataService import org.matrix.android.sdk.internal.session.room.state.SendStateTask import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.search.SearchTask import org.matrix.android.sdk.internal.session.space.DefaultSpace import org.matrix.android.sdk.internal.util.awaitCallback import java.security.InvalidParameterException -import javax.inject.Inject -internal class DefaultRoom @Inject constructor(override val roomId: String, - private val roomSummaryDataSource: RoomSummaryDataSource, - private val timelineService: TimelineService, - private val sendService: SendService, - private val draftService: DraftService, - private val stateService: StateService, - private val uploadsService: UploadsService, - private val reportingService: ReportingService, - private val roomCallService: RoomCallService, - private val readService: ReadService, - private val typingService: TypingService, - private val aliasService: AliasService, - private val tagsService: TagsService, - private val cryptoService: CryptoService, - private val relationService: RelationService, - private val roomMembersService: MembershipService, - private val roomPushRuleService: RoomPushRuleService, - private val sendStateTask: SendStateTask, - private val viaParameterFinder: ViaParameterFinder, - private val searchTask: SearchTask) : +internal class DefaultRoom(override val roomId: String, + private val roomSummaryDataSource: RoomSummaryDataSource, + private val timelineService: TimelineService, + private val sendService: SendService, + private val draftService: DraftService, + private val stateService: StateService, + private val uploadsService: UploadsService, + private val reportingService: ReportingService, + private val roomCallService: RoomCallService, + private val readService: ReadService, + private val typingService: TypingService, + private val aliasService: AliasService, + private val tagsService: TagsService, + private val cryptoService: CryptoService, + private val relationService: RelationService, + private val roomMembersService: MembershipService, + private val roomPushRuleService: RoomPushRuleService, + private val roomAccountDataService: RoomAccountDataService, + private val sendStateTask: SendStateTask, + private val viaParameterFinder: ViaParameterFinder, + private val searchTask: SearchTask) : Room, TimelineService by timelineService, SendService by sendService, @@ -83,7 +85,8 @@ internal class DefaultRoom @Inject constructor(override val roomId: String, TagsService by tagsService, RelationService by relationService, MembershipService by roomMembersService, - RoomPushRuleService by roomPushRuleService { + RoomPushRuleService by roomPushRuleService, + AccountDataService by roomAccountDataService { override fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> { return roomSummaryDataSource.getRoomSummaryLive(roomId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 6fee630510b01624b9904d9ec7d576af895438a6..4f1260403938071011519252c458d94d53a2323e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -360,4 +360,13 @@ internal interface RoomAPI { suspend fun deleteTag(@Path("userId") userId: String, @Path("roomId") roomId: String, @Path("tag") tag: String) + + /** + * Set an AccountData event to the room. + */ + @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/rooms/{roomId}/account_data/{type}") + suspend fun setRoomAccountData(@Path("userId") userId: String, + @Path("roomId") roomId: String, + @Path("type") type: String, + @Body content: JsonDict) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt index 3f743c29229d4977adc881ca4ed0f80ba068443b..8efbf2360a27ad1bfed07660816ccffcb1d8c60a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomFactory.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataService import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder import org.matrix.android.sdk.internal.session.room.alias.DefaultAliasService import org.matrix.android.sdk.internal.session.room.call.DefaultRoomCallService @@ -60,6 +61,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService: private val relationServiceFactory: DefaultRelationService.Factory, private val membershipServiceFactory: DefaultMembershipService.Factory, private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory, + private val roomAccountDataServiceFactory: RoomAccountDataService.Factory, private val sendStateTask: SendStateTask, private val viaParameterFinder: ViaParameterFinder, private val searchTask: SearchTask) : @@ -84,6 +86,7 @@ internal class DefaultRoomFactory @Inject constructor(private val cryptoService: relationService = relationServiceFactory.create(roomId), roomMembersService = membershipServiceFactory.create(roomId), roomPushRuleService = roomPushRuleServiceFactory.create(roomId), + roomAccountDataService = roomAccountDataServiceFactory.create(roomId), sendStateTask = sendStateTask, searchTask = searchTask, viaParameterFinder = viaParameterFinder diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt index 8f3445bec384ea67ad43366f10dd1e968ec2c8dc..d88c1950560d3928a682b70f8694d165fcd4eefc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt @@ -28,6 +28,8 @@ import org.matrix.android.sdk.api.session.space.SpaceService import org.matrix.android.sdk.internal.session.DefaultFileService import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.directory.DirectoryAPI +import org.matrix.android.sdk.internal.session.room.accountdata.DefaultUpdateRoomAccountDataTask +import org.matrix.android.sdk.internal.session.room.accountdata.UpdateRoomAccountDataTask import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasTask import org.matrix.android.sdk.internal.session.room.alias.DefaultAddRoomAliasTask import org.matrix.android.sdk.internal.session.room.alias.DefaultDeleteRoomAliasTask @@ -236,6 +238,9 @@ internal abstract class RoomModule { @Binds abstract fun bindPeekRoomTask(task: DefaultPeekRoomTask): PeekRoomTask + @Binds + abstract fun bindUpdateRoomAccountDataTask(task: DefaultUpdateRoomAccountDataTask): UpdateRoomAccountDataTask + @Binds abstract fun bindGetEventTask(task: DefaultGetEventTask): GetEventTask } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt new file mode 100644 index 0000000000000000000000000000000000000000..0bcf9d7f386088e3c0624cfc3d712e4b7cbdc3a0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.room.accountdata + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.Transformations +import com.zhuinden.monarchy.Monarchy +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toOptional +import org.matrix.android.sdk.internal.database.RealmSessionProvider +import org.matrix.android.sdk.internal.database.mapper.AccountDataMapper +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields +import org.matrix.android.sdk.internal.database.model.RoomEntity +import org.matrix.android.sdk.internal.database.query.where +import org.matrix.android.sdk.internal.di.SessionDatabase +import javax.inject.Inject + +internal class RoomAccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy, + private val realmSessionProvider: RealmSessionProvider, + private val accountDataMapper: AccountDataMapper) { + + fun getAccountDataEvent(roomId: String, type: String): AccountDataEvent? { + return getAccountDataEvents(roomId, setOf(type)).firstOrNull() + } + + fun getLiveAccountDataEvent(roomId: String, type: String): LiveData<Optional<AccountDataEvent>> { + return Transformations.map(getLiveAccountDataEvents(roomId, setOf(type))) { + it.firstOrNull()?.toOptional() + } + } + + fun getAccountDataEvents(roomId: String, types: Set<String>): List<AccountDataEvent> { + return realmSessionProvider.withRealm { realm -> + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: return@withRealm emptyList() + roomEntity.accountDataEvents(types) + } + } + + fun getLiveAccountDataEvents(roomId: String, types: Set<String>): LiveData<List<AccountDataEvent>> { + val liveRoomEntity = monarchy.findAllManagedWithChanges { RoomEntity.where(it, roomId) } + val resultLiveData = MediatorLiveData<List<AccountDataEvent>>() + resultLiveData.addSource(liveRoomEntity) { + val roomEntity = it.realmResults.firstOrNull() + if (roomEntity == null) { + resultLiveData.postValue(emptyList()) + } else { + val mappedResult = roomEntity.accountDataEvents(types) + resultLiveData.postValue(mappedResult) + } + } + return resultLiveData + } + + private fun RoomEntity.accountDataEvents(types: Set<String>): List<AccountDataEvent> { + val query = accountData.where() + if (types.isNotEmpty()) { + query.`in`(RoomAccountDataEntityFields.TYPE, types.toTypedArray()) + } + return query.findAll().map { accountDataMapper.map(it) } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataService.kt new file mode 100644 index 0000000000000000000000000000000000000000..9e9e9dc322a4534c6d2b651f1f36a6f303a84a54 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataService.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.room.accountdata + +import androidx.lifecycle.LiveData +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataService +import org.matrix.android.sdk.api.session.events.model.Content +import org.matrix.android.sdk.api.util.Optional + +internal class RoomAccountDataService @AssistedInject constructor(@Assisted private val roomId: String, + private val dataSource: RoomAccountDataDataSource, + private val updateRoomAccountDataTask: UpdateRoomAccountDataTask +) : AccountDataService { + + @AssistedFactory + interface Factory { + fun create(roomId: String): RoomAccountDataService + } + + override fun getAccountDataEvent(type: String): AccountDataEvent? { + return dataSource.getAccountDataEvent(roomId, type) + } + + override fun getLiveAccountDataEvent(type: String): LiveData<Optional<AccountDataEvent>> { + return dataSource.getLiveAccountDataEvent(roomId, type) + } + + override fun getAccountDataEvents(types: Set<String>): List<AccountDataEvent> { + return dataSource.getAccountDataEvents(roomId, types) + } + + override fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<AccountDataEvent>> { + return dataSource.getLiveAccountDataEvents(roomId, types) + } + + override suspend fun updateAccountData(type: String, content: Content) { + val params = UpdateRoomAccountDataTask.Params(roomId, type, content) + return updateRoomAccountDataTask.execute(params) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/UpdateRoomAccountDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/UpdateRoomAccountDataTask.kt new file mode 100644 index 0000000000000000000000000000000000000000..db18c189089958c65abaa77d6fc52eea337f5f85 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/UpdateRoomAccountDataTask.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.room.accountdata + +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver +import org.matrix.android.sdk.internal.network.executeRequest +import org.matrix.android.sdk.internal.session.room.RoomAPI +import org.matrix.android.sdk.internal.task.Task +import javax.inject.Inject + +internal interface UpdateRoomAccountDataTask : Task<UpdateRoomAccountDataTask.Params, Unit> { + + data class Params( + val roomId: String, + val type: String, + val content: JsonDict + ) +} + +internal class DefaultUpdateRoomAccountDataTask @Inject constructor( + private val roomApi: RoomAPI, + @UserId private val userId: String, + private val globalErrorReceiver: GlobalErrorReceiver +) : UpdateRoomAccountDataTask { + + override suspend fun execute(params: UpdateRoomAccountDataTask.Params) { + return executeRequest(globalErrorReceiver) { + roomApi.setRoomAccountData(userId, params.roomId, params.type, params.content) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt index 95572c203cc19680a29098374cba1732b5fc33f6..cc66a0a2d2a7e148a030c5f4321556e95dd71d42 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt @@ -37,6 +37,7 @@ internal class RoomCreateEventProcessor @Inject constructor() : EventInsertLiveP val predecessorRoomSummary = RoomSummaryEntity.where(realm, predecessorRoomId).findFirst() ?: RoomSummaryEntity(predecessorRoomId) predecessorRoomSummary.versioningState = VersioningState.UPGRADED_ROOM_JOINED + predecessorRoomSummary.isHiddenFromUser = true realm.insertOrUpdate(predecessorRoomSummary) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt index c6f4bbb4e1a9fdd7cadb464acfd87ea4a42d5a31..219e9c903faecd05733e902cde31951637966141 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/peeking/PeekRoomTask.kt @@ -23,6 +23,8 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility +import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility +import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.RoomNameContent import org.matrix.android.sdk.api.session.room.model.RoomTopicContent @@ -105,7 +107,8 @@ internal class DefaultPeekRoomTask @Inject constructor( numJoinedMembers = publicRepoResult.numJoinedMembers, viaServers = serverList, roomType = null, // would be nice to get that from directory... - someMembers = null + someMembers = null, + isPublic = true ) } @@ -143,6 +146,11 @@ internal class DefaultPeekRoomTask @Inject constructor( } } + val historyVisibility = + stateEvents + .lastOrNull { it.type == EventType.STATE_ROOM_HISTORY_VISIBILITY && it.stateKey?.isNotEmpty() == true } + ?.let { it.content?.toModel<RoomHistoryVisibilityContent>()?.historyVisibility } + val roomType = stateEvents .lastOrNull { it.type == EventType.STATE_ROOM_CREATE } ?.content @@ -158,7 +166,8 @@ internal class DefaultPeekRoomTask @Inject constructor( numJoinedMembers = memberCount, roomType = roomType, viaServers = serverList, - someMembers = someMembers + someMembers = someMembers, + isPublic = historyVisibility == RoomHistoryVisibility.WORLD_READABLE ) } catch (failure: Throwable) { // Would be M_FORBIDDEN if cannot peek :/ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index c1ad6205c38c383b7d4d76e3c498605e524211fa..f505b13b337ee1325f4e3eacd544d4e6ccf87292 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -73,6 +73,7 @@ internal class LocalEchoEventFactory @Inject constructor( @UserId private val userId: String, private val markdownParser: MarkdownParser, private val textPillsUtils: TextPillsUtils, + private val thumbnailExtractor: ThumbnailExtractor, private val localEchoRepository: LocalEchoRepository, private val permalinkFactory: PermalinkFactory ) { @@ -261,7 +262,7 @@ internal class LocalEchoEventFactory @Inject constructor( val width = firstFrame?.width ?: 0 mediaDataRetriever.release() - val thumbnailInfo = ThumbnailExtractor.extractThumbnail(context, attachment)?.let { + val thumbnailInfo = thumbnailExtractor.extractThumbnail(attachment)?.let { ThumbnailInfo( width = it.width, height = it.height, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 126458b0820e175e874cedf429847bd332bc1228..bff1af60ca9af4c1e8f3df7f489592ba76c4c908 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -36,7 +36,6 @@ import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomType -import org.matrix.android.sdk.api.session.room.model.VersioningState import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount @@ -244,7 +243,7 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat query.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName) query.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias) query.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships) - query.notEqualTo(RoomSummaryEntityFields.VERSIONING_STATE_STR, VersioningState.UPGRADED_ROOM_JOINED.name) + query.equalTo(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, false) queryParams.roomCategoryFilter?.let { when (it) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index d488fdfc2a91fa07e400afd7a170715a355a5b1d..7cbcfee713565ecdd840f3c08d26201ef896ce4b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -21,6 +21,7 @@ import io.realm.kotlin.createObject import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomAliasesContent import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent @@ -28,6 +29,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent import org.matrix.android.sdk.api.session.room.model.RoomNameContent import org.matrix.android.sdk.api.session.room.model.RoomTopicContent import org.matrix.android.sdk.api.session.room.model.RoomType +import org.matrix.android.sdk.api.session.room.model.VersioningState import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.EventDecryptor @@ -55,10 +57,10 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.clearWith import org.matrix.android.sdk.internal.query.process import org.matrix.android.sdk.internal.session.room.RoomAvatarResolver +import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo -import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.sync.model.RoomSyncSummary import org.matrix.android.sdk.internal.session.sync.model.RoomSyncUnreadNotifications import timber.log.Timber @@ -71,7 +73,7 @@ internal class RoomSummaryUpdater @Inject constructor( private val roomAvatarResolver: RoomAvatarResolver, private val eventDecryptor: EventDecryptor, private val crossSigningService: DefaultCrossSigningService, - private val stateEventDataSource: StateEventDataSource) { + private val roomAccountDataDataSource: RoomAccountDataDataSource) { fun update(realm: Realm, roomId: String, @@ -100,6 +102,10 @@ internal class RoomSummaryUpdater @Inject constructor( roomSummaryEntity.membership = membership } + // Hard to filter from the app now we use PagedList... + roomSummaryEntity.isHiddenFromUser = roomSummaryEntity.versioningState == VersioningState.UPGRADED_ROOM_JOINED + || roomAccountDataDataSource.getAccountDataEvent(roomId, RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM) != null + val lastNameEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root val lastTopicEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_TOPIC, stateKey = "")?.root val lastCanonicalAliasEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root @@ -297,7 +303,7 @@ internal class RoomSummaryUpdater @Inject constructor( // Timber.v("## SPACES: lookup map ${lookupMap.map { it.key.name to it.value.map { it.name } }.toMap()}") lookupMap.entries - .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } + .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } .forEach { entry -> val parent = RoomSummaryEntity.where(realm, entry.key.roomId).findFirst() if (parent != null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt index d0ad19245f9860a2982b96a1eac15d865bd12637..9c6153b34969ce07357c80c73173c462b6ecc326 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt @@ -147,7 +147,8 @@ internal class DefaultSpaceService @Inject constructor( parentRoomId = childStateEv.roomId, suggested = childStateEvContent.suggested, canonicalAlias = childSummary.canonicalAlias, - aliases = childSummary.aliases + aliases = childSummary.aliases, + worldReadable = childSummary.worldReadable ) } }.orEmpty() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index 7cebbb0192279127bb463ece2a1da75604edd24e..c3586bcea7a545fd2e97d6065dc57d090ad71305 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent -import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM @@ -55,7 +54,6 @@ import org.matrix.android.sdk.internal.session.initsync.mapWithProgress import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberEventHandler -import org.matrix.android.sdk.internal.session.room.read.FullyReadContent import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput @@ -63,16 +61,15 @@ import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.internal.session.sync.model.RoomSync -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.internal.session.sync.parsing.RoomSyncAccountDataHandler import org.matrix.android.sdk.internal.util.computeBestChunkSize import timber.log.Timber import javax.inject.Inject internal class RoomSyncHandler @Inject constructor(private val readReceiptHandler: ReadReceiptHandler, private val roomSummaryUpdater: RoomSummaryUpdater, - private val roomTagHandler: RoomTagHandler, - private val roomFullyReadHandler: RoomFullyReadHandler, + private val roomAccountDataHandler: RoomSyncAccountDataHandler, private val cryptoService: DefaultCryptoService, private val roomMemberEventHandler: RoomMemberEventHandler, private val roomTypingUsersHandler: RoomTypingUsersHandler, @@ -198,11 +195,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle ?.takeIf { it.isNotEmpty() } ?.let { handleEphemeral(realm, roomId, it, insertType == EventInsertType.INITIAL_SYNC, aggregator) } - if (roomSync.accountData?.events?.isNotEmpty() == true) { - handleRoomAccountDataEvents(realm, roomId, roomSync.accountData) + if (roomSync.accountData != null) { + roomAccountDataHandler.handle(realm, roomId, roomSync.accountData) } - val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) + val roomEntity = RoomEntity.getOrCreate(realm, roomId) if (roomEntity.membership == Membership.INVITE) { roomEntity.chunks.deleteAllFromRealm() @@ -265,7 +262,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { Timber.v("Handle invited sync for room $roomId") - val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) + val roomEntity = RoomEntity.getOrCreate(realm, roomId) roomEntity.membership = Membership.INVITE if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { roomSync.inviteState.events.forEach { event -> @@ -294,7 +291,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle roomSync: RoomSync, insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { - val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) + val roomEntity = RoomEntity.getOrCreate(realm, roomId) for (event in roomSync.state?.events.orEmpty()) { if (event.eventId == null || event.stateKey == null || event.type == null) { continue @@ -460,17 +457,4 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle return result } - - private fun handleRoomAccountDataEvents(realm: Realm, roomId: String, accountData: RoomSyncAccountData) { - accountData.events?.forEach { event -> - val eventType = event.getClearType() - if (eventType == EventType.TAG) { - val content = event.getClearContent().toModel<RoomTagContent>() - roomTagHandler.handle(realm, roomId, content) - } else if (eventType == EventType.FULLY_READ) { - val content = event.getClearContent().toModel<FullyReadContent>() - roomFullyReadHandler.handle(realm, roomId, content) - } - } - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 157787c8cf1d4d989eb1f66edc8bd189e599989d..a4468a96c977eb491a247118f57773079f841cd5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -25,6 +25,7 @@ import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider +import org.matrix.android.sdk.internal.session.SessionListeners import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.reportSubtask @@ -44,6 +45,7 @@ private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER" internal class SyncResponseHandler @Inject constructor( @SessionDatabase private val monarchy: Monarchy, @SessionId private val sessionId: String, + private val sessionListeners: SessionListeners, private val workManagerProvider: WorkManagerProvider, private val roomSyncHandler: RoomSyncHandler, private val userAccountDataSyncHandler: UserAccountDataSyncHandler, @@ -125,6 +127,7 @@ internal class SyncResponseHandler @Inject constructor( syncResponse.rooms?.let { checkPushRules(it, isInitialSync) userAccountDataSyncHandler.synchronizeWithServerIfNeeded(it.invite) + dispatchInvitedRoom(it) } syncResponse.groups?.let { scheduleGroupDataFetchingIfNeeded(it) @@ -139,6 +142,13 @@ internal class SyncResponseHandler @Inject constructor( } } + private fun dispatchInvitedRoom(roomsSyncResponse: RoomsSyncResponse) { + roomsSyncResponse.invite.keys.forEach { roomId -> + sessionListeners.dispatch { session, listener -> + listener.onNewInvitedRoom(session, roomId) } + } + } + /** * At the moment we don't get any group data through the sync, so we poll where every hour. * You can also force to refetch group data using [Group] API. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt index b8d987d5009471f7a08b1ce7553dccdc01ea976a..3aebd90ed26d045c6a6b1d006959629d4c8766be 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt @@ -23,7 +23,7 @@ import io.realm.kotlin.where import org.matrix.android.sdk.api.pushrules.RuleScope import org.matrix.android.sdk.api.pushrules.RuleSetKey import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.toModel @@ -113,7 +113,7 @@ internal class UserAccountDataSyncHandler @Inject constructor( } } - private fun handlePushRules(realm: Realm, event: UserAccountDataEvent) { + private fun handlePushRules(realm: Realm, event: AccountDataEvent) { val pushRules = event.content.toModel<GetPushRulesResponse>() ?: return realm.where(PushRulesEntity::class.java) .findAll() @@ -155,7 +155,7 @@ internal class UserAccountDataSyncHandler @Inject constructor( realm.insertOrUpdate(underrides) } - private fun handleDirectChatRooms(realm: Realm, event: UserAccountDataEvent) { + private fun handleDirectChatRooms(realm: Realm, event: AccountDataEvent) { val content = event.content.toModel<DirectMessagesContent>() ?: return content.forEach { (userId, roomIds) -> roomIds.forEach { roomId -> @@ -181,7 +181,7 @@ internal class UserAccountDataSyncHandler @Inject constructor( } } - private fun handleIgnoredUsers(realm: Realm, event: UserAccountDataEvent) { + private fun handleIgnoredUsers(realm: Realm, event: AccountDataEvent) { val userIds = event.content.toModel<IgnoredUsersContent>()?.ignoredUsers?.keys ?: return realm.where(IgnoredUserEntity::class.java) .findAll() @@ -191,7 +191,7 @@ internal class UserAccountDataSyncHandler @Inject constructor( // TODO If not initial sync, we should execute a init sync } - private fun handleBreadcrumbs(realm: Realm, event: UserAccountDataEvent) { + private fun handleBreadcrumbs(realm: Realm, event: AccountDataEvent) { val recentRoomIds = event.content.toModel<BreadcrumbsContent>()?.recentRoomIds ?: return val entity = BreadcrumbsEntity.getOrCreate(realm) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt index 05b50ab2c5ee00be2f069b7c008721ea67c7d4d2..ddb71cd19f4344733f23b1a53ef800d9034fdb25 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.sync.model.accountdata import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent @JsonClass(generateAdapter = true) internal data class UserAccountDataSync( - @Json(name = "events") val list: List<UserAccountDataEvent> = emptyList() + @Json(name = "events") val list: List<AccountDataEvent> = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt new file mode 100644 index 0000000000000000000000000000000000000000..c8aab586a01048cfb19a5507552bd1f7ff2b5293 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.sync.parsing + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes +import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.database.mapper.ContentMapper +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntity +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields +import org.matrix.android.sdk.internal.database.model.RoomEntity +import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.session.room.read.FullyReadContent +import org.matrix.android.sdk.internal.session.sync.RoomFullyReadHandler +import org.matrix.android.sdk.internal.session.sync.RoomTagHandler +import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData +import javax.inject.Inject + +internal class RoomSyncAccountDataHandler @Inject constructor(private val roomTagHandler: RoomTagHandler, + private val roomFullyReadHandler: RoomFullyReadHandler) { + + fun handle(realm: Realm, roomId: String, accountData: RoomSyncAccountData) { + if (accountData.events.isNullOrEmpty()) { + return + } + val roomEntity = RoomEntity.getOrCreate(realm, roomId) + for (event in accountData.events) { + val eventType = event.getClearType() + handleGeneric(roomEntity, event.getClearContent(), eventType) + if (eventType == RoomAccountDataTypes.EVENT_TYPE_TAG) { + val content = event.getClearContent().toModel<RoomTagContent>() + roomTagHandler.handle(realm, roomId, content) + } else if (eventType == RoomAccountDataTypes.EVENT_TYPE_FULLY_READ) { + val content = event.getClearContent().toModel<FullyReadContent>() + roomFullyReadHandler.handle(realm, roomId, content) + } + } + } + + private fun handleGeneric(roomEntity: RoomEntity, content: JsonDict?, eventType: String) { + val existing = roomEntity.accountData.where().equalTo(RoomAccountDataEntityFields.TYPE, eventType).findFirst() + if (existing != null) { + // Update current value + existing.contentStr = ContentMapper.map(content) + } else { + val roomAccountData = RoomAccountDataEntity( + type = eventType, + contentStr = ContentMapper.map(content) + ) + roomEntity.accountData.add(roomAccountData) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt index bac725fad28f25cb3a495b62656ee3fea94f4815..2c7dc92dddcd58f4c3dbfe6765892a19c40ba9cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt @@ -30,7 +30,7 @@ import org.matrix.android.sdk.internal.session.identity.IdentityAuthAPI import org.matrix.android.sdk.internal.session.identity.IdentityRegisterTask import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask import org.matrix.android.sdk.internal.session.sync.model.accountdata.AcceptedTermsContent -import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask import org.matrix.android.sdk.internal.util.ensureTrailingSlash import javax.inject.Inject @@ -38,7 +38,7 @@ import javax.inject.Inject internal class DefaultTermsService @Inject constructor( @UnauthenticatedWithCertificate private val unauthenticatedOkHttpClient: Lazy<OkHttpClient>, - private val accountDataDataSource: AccountDataDataSource, + private val accountDataDataSource: UserAccountDataDataSource, private val termsAPI: TermsAPI, private val retrofitFactory: RetrofitFactory, private val getOpenIdTokenTask: GetOpenIdTokenTask, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt index 2e03bc7a869e76a8284cafe0ff016b3d20233c9d..3ecc39ac9484d0f371896b3f069e75292b7f64a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/ThirdPartyAPI.kt @@ -38,7 +38,7 @@ internal interface ThirdPartyAPI { * * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-user-protocol */ - @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/protocols/user/{protocol}") + @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "thirdparty/user/{protocol}") suspend fun getThirdPartyUser(@Path("protocol") protocol: String, @QueryMap params: Map<String, String>?): List<ThirdPartyUser> } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataDataSource.kt similarity index 79% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataDataSource.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataDataSource.kt index d145c008ba85d71b5a33457e89302efe7f407b89..f64b1bdd2ecc7db38fb446b96104f52a52b6f978 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataDataSource.kt @@ -21,7 +21,7 @@ import androidx.lifecycle.Transformations import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.RealmQuery -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.database.RealmSessionProvider @@ -31,27 +31,27 @@ import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityField import org.matrix.android.sdk.internal.di.SessionDatabase import javax.inject.Inject -internal class AccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy, - private val realmSessionProvider: RealmSessionProvider, - private val accountDataMapper: AccountDataMapper) { +internal class UserAccountDataDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy, + private val realmSessionProvider: RealmSessionProvider, + private val accountDataMapper: AccountDataMapper) { - fun getAccountDataEvent(type: String): UserAccountDataEvent? { + fun getAccountDataEvent(type: String): AccountDataEvent? { return getAccountDataEvents(setOf(type)).firstOrNull() } - fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> { + fun getLiveAccountDataEvent(type: String): LiveData<Optional<AccountDataEvent>> { return Transformations.map(getLiveAccountDataEvents(setOf(type))) { it.firstOrNull()?.toOptional() } } - fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> { + fun getAccountDataEvents(types: Set<String>): List<AccountDataEvent> { return realmSessionProvider.withRealm { accountDataEventsQuery(it, types).findAll().map(accountDataMapper::map) } } - fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> { + fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<AccountDataEvent>> { return monarchy.findAllMappedWithChanges( { accountDataEventsQuery(it, types) }, accountDataMapper::map diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultAccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataService.kt similarity index 87% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultAccountDataService.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataService.kt index 27db30f3b3dc6f9671d06ef4178d97c77318e192..b15d1d0f8bbe8f2cd737b36c57ecea11e616e134 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultAccountDataService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UserAccountDataService.kt @@ -23,33 +23,33 @@ import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.sync.UserAccountDataSyncHandler -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.util.awaitCallback import javax.inject.Inject -internal class DefaultAccountDataService @Inject constructor( +internal class UserAccountDataService @Inject constructor( @SessionDatabase private val monarchy: Monarchy, private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val userAccountDataSyncHandler: UserAccountDataSyncHandler, - private val accountDataDataSource: AccountDataDataSource, + private val accountDataDataSource: UserAccountDataDataSource, private val taskExecutor: TaskExecutor ) : AccountDataService { - override fun getAccountDataEvent(type: String): UserAccountDataEvent? { + override fun getAccountDataEvent(type: String): AccountDataEvent? { return accountDataDataSource.getAccountDataEvent(type) } - override fun getLiveAccountDataEvent(type: String): LiveData<Optional<UserAccountDataEvent>> { + override fun getLiveAccountDataEvent(type: String): LiveData<Optional<AccountDataEvent>> { return accountDataDataSource.getLiveAccountDataEvent(type) } - override fun getAccountDataEvents(types: Set<String>): List<UserAccountDataEvent> { + override fun getAccountDataEvents(types: Set<String>): List<AccountDataEvent> { return accountDataDataSource.getAccountDataEvents(types) } - override fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<UserAccountDataEvent>> { + override fun getLiveAccountDataEvents(types: Set<String>): LiveData<List<AccountDataEvent>> { return accountDataDataSource.getLiveAccountDataEvents(types) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt index d741dbc966446bc957b39b0c2ad7875763d249d8..ca1a129da79e262486fe5926df4bb9c847fb0f0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt @@ -23,7 +23,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event @@ -39,7 +39,7 @@ import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource -import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence import java.util.HashMap @@ -47,7 +47,7 @@ import javax.inject.Inject @SessionScope internal class WidgetManager @Inject constructor(private val integrationManager: IntegrationManager, - private val accountDataDataSource: AccountDataDataSource, + private val accountDataDataSource: UserAccountDataDataSource, private val stateEventDataSource: StateEventDataSource, private val createWidgetTask: CreateWidgetTask, private val widgetFactory: WidgetFactory, @@ -150,8 +150,8 @@ internal class WidgetManager @Inject constructor(private val integrationManager: return widgetsAccountData.mapToWidgets(widgetTypes, excludedTypes) } - private fun UserAccountDataEvent.mapToWidgets(widgetTypes: Set<String>? = null, - excludedTypes: Set<String>? = null): List<Widget> { + private fun AccountDataEvent.mapToWidgets(widgetTypes: Set<String>? = null, + excludedTypes: Set<String>? = null): List<Widget> { return extractWidgetSequence(widgetFactory) .filter { val widgetType = it.widgetContent.type ?: return@filter false diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt index 6f423b38a09ed42f3f4ed74f69761bf6ad869d29..5aa32d5a31751f5f928e6be47cab0d1da907340d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt @@ -19,10 +19,10 @@ package org.matrix.android.sdk.internal.session.widgets.helper import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.AccountDataEvent import org.matrix.android.sdk.api.session.widgets.model.Widget -internal fun UserAccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence<Widget> { +internal fun AccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence<Widget> { return content.asSequence() .mapNotNull { @Suppress("UNCHECKED_CAST")