From bbfefbf239f3c70e178f8b7fa09426f5556d2ee6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 23 Mar 2022 18:37:44 +0100 Subject: [PATCH 01/23] Removes user entity change during room nickname change --- .../session/room/membership/RoomMemberEventHandler.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 25c124bd6be..d3f20e39ad8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -26,7 +26,6 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator -import org.matrix.android.sdk.internal.session.user.UserEntityFactory import javax.inject.Inject internal class RoomMemberEventHandler @Inject constructor( @@ -58,10 +57,6 @@ internal class RoomMemberEventHandler @Inject constructor( // but we want to preserve presence record value and not replace it with null getExistingPresenceState(realm, roomId, userId)) realm.insertOrUpdate(roomMemberEntity) - if (roomMember.membership.isActive()) { - val userEntity = UserEntityFactory.create(userId, roomMember) - realm.insertOrUpdate(userEntity) - } // check whether this new room member event may be used to update the directs dictionary in account data // this is required to handle correctly invite by email in DM From 4c1e651af482a007a540ffa89f9ce5cf08e145a4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 23 Mar 2022 18:55:19 +0100 Subject: [PATCH 02/23] Adds changelog file --- changelog.d/5618.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5618.bugfix diff --git a/changelog.d/5618.bugfix b/changelog.d/5618.bugfix new file mode 100644 index 00000000000..8a839a2b4e1 --- /dev/null +++ b/changelog.d/5618.bugfix @@ -0,0 +1 @@ +Fixes display name being changed when using /myroomnick From 927eeb3dc604e61302bf553468752915d4e9051a Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 30 Mar 2022 17:43:55 +0200 Subject: [PATCH 03/23] Refactors RoomMemberEventHandler with change to only save the user locally if its not a display name change --- .../room/membership/RoomMemberEventHandler.kt | 58 +++++++++++++++---- .../sync/handler/room/RoomSyncHandler.kt | 5 +- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index d3f20e39ad8..d266efd49c0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -26,29 +26,42 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator +import org.matrix.android.sdk.internal.session.user.UserEntityFactory import javax.inject.Inject internal class RoomMemberEventHandler @Inject constructor( @UserId private val myUserId: String ) { - fun handle(realm: Realm, roomId: String, event: Event, aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { + fun handle(realm: Realm, + roomId: String, + event: Event, + aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { return false } + val roomMember = event.getFixedRoomMemberContent() ?: return false val userId = event.stateKey ?: return false - val roomMember = event.getFixedRoomMemberContent() - return handle(realm, roomId, userId, roomMember, aggregator) + + return handle(realm, roomId, userId, roomMember, event.resolvedPrevContent(), aggregator) } - fun handle(realm: Realm, - roomId: String, - userId: String, - roomMember: RoomMemberContent?, - aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { - if (roomMember == null) { - return false - } + private fun handle(realm: Realm, + roomId: String, + userId: String, + roomMember: RoomMemberContent, + prevContent: Map?, + aggregator: SyncResponsePostTreatmentAggregator?): Boolean { + saveRoomMemberEntityLocally(realm, roomId, userId, roomMember) + saveUserEntityLocallyIfNecessary(realm, userId, roomMember, prevContent) + updateDirectChatsIfNecessary(roomId, roomMember, aggregator) + return true + } + + private fun saveRoomMemberEntityLocally(realm: Realm, + roomId: String, + userId: String, + roomMember: RoomMemberContent) { val roomMemberEntity = RoomMemberEntityFactory.create( roomId, userId, @@ -57,14 +70,35 @@ internal class RoomMemberEventHandler @Inject constructor( // but we want to preserve presence record value and not replace it with null getExistingPresenceState(realm, roomId, userId)) realm.insertOrUpdate(roomMemberEntity) + } + + private fun saveUserEntityLocallyIfNecessary(realm: Realm, + userId: String, + roomMember: RoomMemberContent, + prevContent: Map?) { + val previousDisplayName = prevContent?.get("displayname") + val shouldLocallySaveUser = roomMember.membership.isActive() + && (previousDisplayName == null || previousDisplayName == roomMember.displayName) + + if (shouldLocallySaveUser) { + saveUserLocally(realm, userId, roomMember) + } + } + private fun saveUserLocally(realm: Realm, userId: String, roomMember: RoomMemberContent) { + val userEntity = UserEntityFactory.create(userId, roomMember) + realm.insertOrUpdate(userEntity) + } + + private fun updateDirectChatsIfNecessary(roomId: String, + roomMember: RoomMemberContent, + aggregator: SyncResponsePostTreatmentAggregator?) { // check whether this new room member event may be used to update the directs dictionary in account data // this is required to handle correctly invite by email in DM val mxId = roomMember.thirdPartyInvite?.signed?.mxid if (mxId != null && mxId != myUserId) { aggregator?.directChatsToCheck?.put(roomId, mxId) } - return true } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 8fe85f0d318..98f2dea9eea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -404,9 +404,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (event.type == EventType.STATE_ROOM_MEMBER) { - val fixedContent = event.getFixedRoomMemberContent() - roomMemberContentsByUser[event.stateKey] = fixedContent - roomMemberEventHandler.handle(realm, roomEntity.roomId, event.stateKey, fixedContent, aggregator) + roomMemberContentsByUser[event.stateKey] = event.getFixedRoomMemberContent() + roomMemberEventHandler.handle(realm, roomEntity.roomId, event, aggregator) } } From 0200f489b09a2bf445f11b99686fa7113546fe95 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 30 Mar 2022 18:50:35 +0200 Subject: [PATCH 04/23] Fixes lint error --- .../session/room/membership/RoomMemberEventHandler.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index d266efd49c0..89c31f414f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -77,8 +77,8 @@ internal class RoomMemberEventHandler @Inject constructor( roomMember: RoomMemberContent, prevContent: Map?) { val previousDisplayName = prevContent?.get("displayname") - val shouldLocallySaveUser = roomMember.membership.isActive() - && (previousDisplayName == null || previousDisplayName == roomMember.displayName) + val shouldLocallySaveUser = roomMember.membership.isActive() && + (previousDisplayName == null || previousDisplayName == roomMember.displayName) if (shouldLocallySaveUser) { saveUserLocally(realm, userId, roomMember) From 6c1f6dca71644cfc669c773bcbc56ff9848c1013 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 31 Mar 2022 17:35:31 +0200 Subject: [PATCH 05/23] Uses aggregator to handle room name change events --- .../room/membership/LoadRoomMembersTask.kt | 2 +- .../room/membership/RoomMemberEventHandler.kt | 87 +++++++++++++------ .../SyncResponsePostTreatmentAggregator.kt | 3 + ...cResponsePostTreatmentAggregatorHandler.kt | 39 ++++++++- .../sync/handler/room/RoomSyncHandler.kt | 41 ++++++--- .../session/user/UserEntityFactory.kt | 13 ++- 6 files changed, 141 insertions(+), 44 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 3d0f51b831c..0a01f30dbc0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -123,7 +123,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( eventId = roomMemberEvent.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, roomMemberEvent) + roomMemberEventHandler.handleIncrementalSync(roomId, roomMemberEvent) } roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 89c31f414f1..7505c09b4e0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -33,27 +33,31 @@ internal class RoomMemberEventHandler @Inject constructor( @UserId private val myUserId: String ) { - fun handle(realm: Realm, - roomId: String, - event: Event, - aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { + fun handleInitialSync(realm: Realm, + roomId: String, + currentUserId: String, + event: Event, + aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { return false } val roomMember = event.getFixedRoomMemberContent() ?: return false - val userId = event.stateKey ?: return false + val eventUserId = event.stateKey ?: return false - return handle(realm, roomId, userId, roomMember, event.resolvedPrevContent(), aggregator) + return handleInitialSync(realm, roomId, currentUserId, eventUserId, roomMember, aggregator) } - private fun handle(realm: Realm, - roomId: String, - userId: String, - roomMember: RoomMemberContent, - prevContent: Map?, - aggregator: SyncResponsePostTreatmentAggregator?): Boolean { - saveRoomMemberEntityLocally(realm, roomId, userId, roomMember) - saveUserEntityLocallyIfNecessary(realm, userId, roomMember, prevContent) + private fun handleInitialSync(realm: Realm, + roomId: String, + currentUserId: String, + eventUserId: String, + roomMember: RoomMemberContent, + aggregator: SyncResponsePostTreatmentAggregator?): Boolean { + if (currentUserId != eventUserId) { + saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) + saveUserEntityLocallyIfNecessary(realm, eventUserId, roomMember) + } + updateDirectChatsIfNecessary(roomId, roomMember, aggregator) return true } @@ -72,15 +76,18 @@ internal class RoomMemberEventHandler @Inject constructor( realm.insertOrUpdate(roomMemberEntity) } + /** + * Get the already existing presence state for a specific user & room in order NOT to be replaced in RoomMemberSummaryEntity + * by NULL value. + */ + private fun getExistingPresenceState(realm: Realm, roomId: String, userId: String): UserPresenceEntity? { + return RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()?.userPresenceEntity + } + private fun saveUserEntityLocallyIfNecessary(realm: Realm, userId: String, - roomMember: RoomMemberContent, - prevContent: Map?) { - val previousDisplayName = prevContent?.get("displayname") - val shouldLocallySaveUser = roomMember.membership.isActive() && - (previousDisplayName == null || previousDisplayName == roomMember.displayName) - - if (shouldLocallySaveUser) { + roomMember: RoomMemberContent) { + if (roomMember.membership.isActive()) { saveUserLocally(realm, userId, roomMember) } } @@ -101,12 +108,38 @@ internal class RoomMemberEventHandler @Inject constructor( } } - /** - * Get the already existing presence state for a specific user & room in order NOT to be replaced in RoomMemberSummaryEntity - * by NULL value. - */ + fun handleIncrementalSync(roomId: String, + event: Event, + aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { + if (event.type != EventType.STATE_ROOM_MEMBER) { + return false + } + val roomMember = event.getFixedRoomMemberContent() ?: return false + val eventUserId = event.stateKey ?: return false - private fun getExistingPresenceState(realm: Realm, roomId: String, userId: String): UserPresenceEntity? { - return RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()?.userPresenceEntity + return handleIncrementalSync(roomId, eventUserId, roomMember, event.resolvedPrevContent(), aggregator) + } + + private fun handleIncrementalSync(roomId: String, + eventUserId: String, + roomMember: RoomMemberContent, + prevContent: Map?, + aggregator: SyncResponsePostTreatmentAggregator?): Boolean { + val previousDisplayName = prevContent?.get("displayname") + val previousAvatar = prevContent?.get("avatar_url") + + if (previousDisplayName.isDifferentFrom(roomMember.displayName) || + previousAvatar.isDifferentFrom(roomMember.avatarUrl)) { + aggregator?.usersToFetch?.add(eventUserId) + } + + // At the end of the sync, fetch all the profiles from the aggregator + updateDirectChatsIfNecessary(roomId, roomMember, aggregator) + return true + } + + private fun Any?.isDifferentFrom(value: Any?) = when { + this == null || this == value -> false + else -> true } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt index fe44531390b..2ba7c8133b4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt @@ -22,4 +22,7 @@ internal class SyncResponsePostTreatmentAggregator { // Map of roomId to directUserId val directChatsToCheck = mutableMapOf() + + // List of userIds to fetch and update at the end of incremental syncs + val usersToFetch = mutableListOf() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 1e0e87a450e..ad6de713a77 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -16,10 +16,15 @@ package org.matrix.android.sdk.internal.session.sync.handler +import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.session.profile.ProfileService +import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator import org.matrix.android.sdk.internal.session.sync.model.accountdata.toMutable +import org.matrix.android.sdk.internal.session.user.UserEntityFactory import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask import javax.inject.Inject @@ -27,11 +32,14 @@ import javax.inject.Inject internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private val directChatsHelper: DirectChatsHelper, private val ephemeralTemporaryStore: RoomSyncEphemeralTemporaryStore, - private val updateUserAccountDataTask: UpdateUserAccountDataTask + private val updateUserAccountDataTask: UpdateUserAccountDataTask, + private val profileService: ProfileService, + @SessionDatabase private val monarchy: Monarchy, ) { - suspend fun handle(synResHaResponsePostTreatmentAggregator: SyncResponsePostTreatmentAggregator) { - cleanupEphemeralFiles(synResHaResponsePostTreatmentAggregator.ephemeralFilesToDelete) - updateDirectUserIds(synResHaResponsePostTreatmentAggregator.directChatsToCheck) + suspend fun handle(aggregator: SyncResponsePostTreatmentAggregator) { + cleanupEphemeralFiles(aggregator.ephemeralFilesToDelete) + updateDirectUserIds(aggregator.directChatsToCheck) + fetchAndUpdateUsers(aggregator.usersToFetch) } private fun cleanupEphemeralFiles(ephemeralFilesToDelete: List) { @@ -68,4 +76,27 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( updateUserAccountDataTask.execute(UpdateUserAccountDataTask.DirectChatParams(directMessages = directChats)) } } + + private suspend fun fetchAndUpdateUsers(usersToFetch: MutableList) { + val userProfiles = fetchUsers(usersToFetch) + userProfiles.forEach { saveUserLocally(monarchy, it) } + usersToFetch.clear() + } + + private fun saveUserLocally(monarchy: Monarchy, userItem: MatrixItem.UserItem) { + val userEntity = UserEntityFactory.create(userItem) + monarchy.doWithRealm { + it.insertOrUpdate(userEntity) + } + } + + private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { + val profileJson = profileService.getProfile(it) + + MatrixItem.UserItem( + id = it, + displayName = profileJson[ProfileService.DISPLAY_NAME_KEY] as? String, + avatarUrl = profileJson[ProfileService.AVATAR_URL_KEY] as? String + ) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 98f2dea9eea..aebbc37f556 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -206,7 +206,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle insertType: EventInsertType, syncLocalTimestampMillis: Long, aggregator: SyncResponsePostTreatmentAggregator): RoomEntity { - Timber.v("Handle join sync for room $roomId") + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed) ?._roomSyncEphemeral @@ -241,7 +241,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } // Give info to crypto module cryptoService.onStateEvent(roomId, event) - roomMemberEventHandler.handle(realm, roomId, event, aggregator) + if (isInitialSync) { + roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event, aggregator) + } else { + roomMemberEventHandler.handleIncrementalSync(roomId, event, aggregator) + } } } if (roomSync.timeline?.events?.isNotEmpty() == true) { @@ -282,7 +286,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle roomSync: InvitedRoomSync, insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { - Timber.v("Handle invited sync for room $roomId") + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val roomEntity = RoomEntity.getOrCreate(realm, roomId) roomEntity.membership = Membership.INVITE if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { @@ -296,7 +300,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = eventEntity.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, event) + if (isInitialSync) { + roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) + } else { + roomMemberEventHandler.handleIncrementalSync(roomId, event) + } } } val inviterEvent = roomSync.inviteState?.events?.lastOrNull { @@ -312,6 +320,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle roomSync: RoomSync, insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val roomEntity = RoomEntity.getOrCreate(realm, roomId) for (event in roomSync.state?.events.orEmpty()) { if (event.eventId == null || event.stateKey == null || event.type == null) { @@ -323,7 +332,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = event.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, event) + if (isInitialSync) { + roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) + } else { + roomMemberEventHandler.handleIncrementalSync(roomId, event) + } } for (event in roomSync.timeline?.events.orEmpty()) { if (event.eventId == null || event.senderId == null || event.type == null) { @@ -337,7 +350,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (event.type == EventType.STATE_ROOM_MEMBER) { - roomMemberEventHandler.handle(realm, roomEntity.roomId, event) + if (isInitialSync) { + roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event) + } else { + roomMemberEventHandler.handleIncrementalSync(roomEntity.roomId, event) + } } } } @@ -381,11 +398,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle continue } - eventIds.add(event.eventId) - liveEventService.get().dispatchLiveEventReceived(event, roomId, insertType == EventInsertType.INITIAL_SYNC) - val isInitialSync = insertType == EventInsertType.INITIAL_SYNC + eventIds.add(event.eventId) + liveEventService.get().dispatchLiveEventReceived(event, roomId, isInitialSync) + if (event.isEncrypted() && !isInitialSync) { runBlocking { decryptIfNeeded(event, roomId) @@ -405,7 +422,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } if (event.type == EventType.STATE_ROOM_MEMBER) { roomMemberContentsByUser[event.stateKey] = event.getFixedRoomMemberContent() - roomMemberEventHandler.handle(realm, roomEntity.roomId, event, aggregator) + if (isInitialSync) { + roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event, aggregator) + } else { + roomMemberEventHandler.handleIncrementalSync(roomEntity.roomId, event, aggregator) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt index 9a9458e84bd..ce235da553c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.user import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.database.model.UserEntity internal object UserEntityFactory { @@ -24,8 +25,16 @@ internal object UserEntityFactory { fun create(userId: String, roomMember: RoomMemberContent): UserEntity { return UserEntity( userId = userId, - displayName = roomMember.displayName ?: "", - avatarUrl = roomMember.avatarUrl ?: "" + displayName = roomMember.displayName.orEmpty(), + avatarUrl = roomMember.avatarUrl.orEmpty() + ) + } + + fun create(userItem: MatrixItem.UserItem): UserEntity { + return UserEntity( + userId = userItem.id, + displayName = userItem.displayName.orEmpty(), + avatarUrl = userItem.avatarUrl.orEmpty() ) } } From 7f64c62566c8c386ef1cb79ca95cb0801b966b92 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 31 Mar 2022 18:24:13 +0200 Subject: [PATCH 06/23] Adds missing room member update call during incremental syncs --- .../room/membership/LoadRoomMembersTask.kt | 2 +- .../room/membership/RoomMemberEventHandler.kt | 20 ++++++++++++++----- .../sync/handler/room/RoomSyncHandler.kt | 10 +++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 0a01f30dbc0..3cd4ea75801 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -123,7 +123,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( eventId = roomMemberEvent.eventId root = eventEntity } - roomMemberEventHandler.handleIncrementalSync(roomId, roomMemberEvent) + roomMemberEventHandler.handleIncrementalSync(realm, roomId, roomMemberEvent) } roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 7505c09b4e0..add8c294e5b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -108,7 +108,8 @@ internal class RoomMemberEventHandler @Inject constructor( } } - fun handleIncrementalSync(roomId: String, + fun handleIncrementalSync(realm: Realm, + roomId: String, event: Event, aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { @@ -117,10 +118,18 @@ internal class RoomMemberEventHandler @Inject constructor( val roomMember = event.getFixedRoomMemberContent() ?: return false val eventUserId = event.stateKey ?: return false - return handleIncrementalSync(roomId, eventUserId, roomMember, event.resolvedPrevContent(), aggregator) + return handleIncrementalSync( + realm, + roomId, + eventUserId, + roomMember, + event.resolvedPrevContent(), + aggregator + ) } - private fun handleIncrementalSync(roomId: String, + private fun handleIncrementalSync(realm: Realm, + roomId: String, eventUserId: String, roomMember: RoomMemberContent, prevContent: Map?, @@ -130,9 +139,10 @@ internal class RoomMemberEventHandler @Inject constructor( if (previousDisplayName.isDifferentFrom(roomMember.displayName) || previousAvatar.isDifferentFrom(roomMember.avatarUrl)) { - aggregator?.usersToFetch?.add(eventUserId) + aggregator?.usersToFetch?.add(eventUserId) } + saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) // At the end of the sync, fetch all the profiles from the aggregator updateDirectChatsIfNecessary(roomId, roomMember, aggregator) return true @@ -140,6 +150,6 @@ internal class RoomMemberEventHandler @Inject constructor( private fun Any?.isDifferentFrom(value: Any?) = when { this == null || this == value -> false - else -> true + else -> true } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index aebbc37f556..ce3111a3881 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -244,7 +244,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (isInitialSync) { roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event, aggregator) } else { - roomMemberEventHandler.handleIncrementalSync(roomId, event, aggregator) + roomMemberEventHandler.handleIncrementalSync(realm, roomId, event, aggregator) } } } @@ -303,7 +303,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (isInitialSync) { roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) } else { - roomMemberEventHandler.handleIncrementalSync(roomId, event) + roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) } } } @@ -335,7 +335,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (isInitialSync) { roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) } else { - roomMemberEventHandler.handleIncrementalSync(roomId, event) + roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) } } for (event in roomSync.timeline?.events.orEmpty()) { @@ -353,7 +353,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (isInitialSync) { roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event) } else { - roomMemberEventHandler.handleIncrementalSync(roomEntity.roomId, event) + roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event) } } } @@ -425,7 +425,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (isInitialSync) { roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event, aggregator) } else { - roomMemberEventHandler.handleIncrementalSync(roomEntity.roomId, event, aggregator) + roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event, aggregator) } } } From 25ca68413de1ecc078a6c9a25568e60751909206 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 6 Apr 2022 07:47:51 +0100 Subject: [PATCH 07/23] Improves code reuse and readability --- .../android/sdk/api/session/user/model/User.kt | 15 ++++++++++++++- .../matrix/android/sdk/api/util/MatrixItem.kt | 12 +++++++++++- .../room/membership/RoomMemberEventHandler.kt | 6 ++---- ...yncResponsePostTreatmentAggregatorHandler.kt | 7 +------ .../internal/session/user/DefaultUserService.kt | 17 ++++------------- .../RoomMemberProfileViewModel.kt | 13 +++---------- .../features/userdirectory/UserListViewModel.kt | 6 +----- 7 files changed, 36 insertions(+), 40 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt index 54ae9e54f6a..79c86f3f231 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt @@ -16,6 +16,9 @@ package org.matrix.android.sdk.api.session.user.model +import org.matrix.android.sdk.api.session.profile.ProfileService +import org.matrix.android.sdk.api.util.JsonDict + /** * Data class which holds information about a user. * It can be retrieved with [org.matrix.android.sdk.api.session.user.UserService] @@ -27,4 +30,14 @@ data class User( */ val displayName: String? = null, val avatarUrl: String? = null -) +) { + + companion object { + + fun fromJson(userId: String, json: JsonDict) = User( + userId = userId, + displayName = json[ProfileService.DISPLAY_NAME_KEY] as? String, + avatarUrl = json[ProfileService.AVATAR_URL_KEY] as? String + ) + } +} 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 650b8cc26db..6e403b3569f 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 @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.util import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.group.model.GroupSummary +import org.matrix.android.sdk.api.session.profile.ProfileService 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 @@ -37,11 +38,20 @@ sealed class MatrixItem( override val displayName: String? = null, override val avatarUrl: String? = null) : MatrixItem(id, displayName?.removeSuffix(IRC_PATTERN), avatarUrl) { + init { if (BuildConfig.DEBUG) checkId() } override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) + + companion object { + fun fromJson(userId: String, profileJson: JsonDict) = UserItem( + id = userId, + displayName = profileJson[ProfileService.DISPLAY_NAME_KEY] as? String, + avatarUrl = profileJson[ProfileService.AVATAR_URL_KEY] as? String + ) + } } data class EveryoneInRoomItem(override val id: String, @@ -200,7 +210,7 @@ fun RoomMemberSummary.toMatrixItem() = MatrixItem.UserItem(userId, displayName, fun SenderInfo.toMatrixItem() = MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) -fun SenderInfo.toMatrixItemOrNull() = tryOrNull { MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) } +fun SenderInfo.toMatrixItemOrNull() = tryOrNull { MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) } fun SpaceChildInfo.toMatrixItem() = if (roomType == RoomType.SPACE) { MatrixItem.SpaceItem(childRoomId, name ?: canonicalAlias, avatarUrl) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index add8c294e5b..f197f780ba7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -35,7 +35,6 @@ internal class RoomMemberEventHandler @Inject constructor( fun handleInitialSync(realm: Realm, roomId: String, - currentUserId: String, event: Event, aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { @@ -44,7 +43,7 @@ internal class RoomMemberEventHandler @Inject constructor( val roomMember = event.getFixedRoomMemberContent() ?: return false val eventUserId = event.stateKey ?: return false - return handleInitialSync(realm, roomId, currentUserId, eventUserId, roomMember, aggregator) + return handleInitialSync(realm, roomId, myUserId, eventUserId, roomMember, aggregator) } private fun handleInitialSync(realm: Realm, @@ -54,10 +53,9 @@ internal class RoomMemberEventHandler @Inject constructor( roomMember: RoomMemberContent, aggregator: SyncResponsePostTreatmentAggregator?): Boolean { if (currentUserId != eventUserId) { - saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) saveUserEntityLocallyIfNecessary(realm, eventUserId, roomMember) } - + saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) updateDirectChatsIfNecessary(roomId, roomMember, aggregator) return true } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index ad6de713a77..9723142ea0b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -92,11 +92,6 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { val profileJson = profileService.getProfile(it) - - MatrixItem.UserItem( - id = it, - displayName = profileJson[ProfileService.DISPLAY_NAME_KEY] as? String, - avatarUrl = profileJson[ProfileService.AVATAR_URL_KEY] as? String - ) + MatrixItem.UserItem.fromJson(it, profileJson) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt index 52b8cc36892..42c81d3592d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.user import androidx.lifecycle.LiveData import androidx.paging.PagedList -import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.user.UserService import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.Optional @@ -36,18 +35,10 @@ internal class DefaultUserService @Inject constructor(private val userDataSource return userDataSource.getUser(userId) } - override suspend fun resolveUser(userId: String): User { - val known = getUser(userId) - if (known != null) { - return known - } else { - val params = GetProfileInfoTask.Params(userId) - val data = getProfileInfoTask.execute(params) - return User( - userId, - data[ProfileService.DISPLAY_NAME_KEY] as? String, - data[ProfileService.AVATAR_URL_KEY] as? String) - } + override suspend fun resolveUser(userId: String) = getUser(userId) ?: run { + val params = GetProfileInfoTask.Params(userId) + val json = getProfileInfoTask.execute(params) + User.fromJson(userId, json) } override fun getUserLive(userId: String): LiveData> { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index db54f279103..a721c7a264e 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -48,7 +48,6 @@ import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.model.Membership @@ -113,8 +112,8 @@ class RoomMemberProfileViewModel @AssistedInject constructor( session.flow().liveUserCryptoDevices(initialState.userId) .map { Pair( - it.fold(true, { prev, dev -> prev && dev.isVerified }), - it.fold(true, { prev, dev -> prev && (dev.trustLevel?.crossSigningVerified == true) }) + it.fold(true) { prev, dev -> prev && dev.isVerified }, + it.fold(true) { prev, dev -> prev && (dev.trustLevel?.crossSigningVerified == true) } ) } .execute { it -> @@ -329,13 +328,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor( private suspend fun fetchProfileInfo() { val result = runCatchingToAsync { session.getProfile(initialState.userId) - .let { - MatrixItem.UserItem( - id = initialState.userId, - displayName = it[ProfileService.DISPLAY_NAME_KEY] as? String, - avatarUrl = it[ProfileService.AVATAR_URL_KEY] as? String - ) - } + .let { MatrixItem.UserItem.fromJson(initialState.userId, it) } } setState { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index 039c7041b05..4bb3cd6d0d9 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -216,11 +216,7 @@ class UserListViewModel @AssistedInject constructor( val json = session.getProfile(foundThreePid.matrixId) ThreePidUser( email = search, - user = User( - userId = foundThreePid.matrixId, - displayName = json[ProfileService.DISPLAY_NAME_KEY] as? String, - avatarUrl = json[ProfileService.AVATAR_URL_KEY] as? String - ) + user = User.fromJson(foundThreePid.matrixId, json) ) } catch (failure: Throwable) { ThreePidUser(email = search, user = User(foundThreePid.matrixId)) From 981d15771765f928e48ace45a5206bd7e4b27ef4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 10:10:50 +0100 Subject: [PATCH 08/23] Fixes errors in RoomSyncHandler --- .../session/sync/handler/room/RoomSyncHandler.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index ce3111a3881..c88d8a89c42 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -242,7 +242,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle // Give info to crypto module cryptoService.onStateEvent(roomId, event) if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event, aggregator) + roomMemberEventHandler.handleInitialSync(realm, roomId, event, aggregator) } else { roomMemberEventHandler.handleIncrementalSync(realm, roomId, event, aggregator) } @@ -301,7 +301,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) + roomMemberEventHandler.handleInitialSync(realm, roomId, event) } else { roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) } @@ -333,7 +333,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, userId, event) + roomMemberEventHandler.handleInitialSync(realm, roomId, event) } else { roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) } @@ -351,7 +351,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } if (event.type == EventType.STATE_ROOM_MEMBER) { if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event) + roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, event) } else { roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event) } @@ -423,7 +423,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle if (event.type == EventType.STATE_ROOM_MEMBER) { roomMemberContentsByUser[event.stateKey] = event.getFixedRoomMemberContent() if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, userId, event, aggregator) + roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, event, aggregator) } else { roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event, aggregator) } From c1b13862783b843b7f6ff87fcad38f78614c90e4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 16:05:03 +0100 Subject: [PATCH 09/23] Replaces MatrixItem fromJson with User.toMatrixItem --- .../matrix/android/sdk/api/session/user/model/User.kt | 3 +++ .../java/org/matrix/android/sdk/api/util/MatrixItem.kt | 9 --------- .../SyncResponsePostTreatmentAggregatorHandler.kt | 3 ++- .../roommemberprofile/RoomMemberProfileViewModel.kt | 3 ++- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt index 79c86f3f231..5de54a3a5ec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.user.model import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.api.util.MatrixItem /** * Data class which holds information about a user. @@ -32,6 +33,8 @@ data class User( val avatarUrl: String? = null ) { + fun toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl) + companion object { fun fromJson(userId: String, json: JsonDict) = User( 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 6e403b3569f..4f5f4f82d93 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 @@ -19,7 +19,6 @@ package org.matrix.android.sdk.api.util import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.group.model.GroupSummary -import org.matrix.android.sdk.api.session.profile.ProfileService 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 @@ -44,14 +43,6 @@ sealed class MatrixItem( } override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) - - companion object { - fun fromJson(userId: String, profileJson: JsonDict) = UserItem( - id = userId, - displayName = profileJson[ProfileService.DISPLAY_NAME_KEY] as? String, - avatarUrl = profileJson[ProfileService.AVATAR_URL_KEY] as? String - ) - } } data class EveryoneInRoomItem(override val id: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 9723142ea0b..379b3d21047 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.handler import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.profile.ProfileService +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore @@ -92,6 +93,6 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { val profileJson = profileService.getProfile(it) - MatrixItem.UserItem.fromJson(it, profileJson) + User.fromJson(it, profileJson).toMatrixItem() } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index a721c7a264e..96e423fdad6 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -55,6 +55,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.Role +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toOptional @@ -328,7 +329,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor( private suspend fun fetchProfileInfo() { val result = runCatchingToAsync { session.getProfile(initialState.userId) - .let { MatrixItem.UserItem.fromJson(initialState.userId, it) } + .let { User.fromJson(initialState.userId, it).toMatrixItem() } } setState { From 6c3c309989356aeb0213a89f316b3f5393ad9fd5 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 16:13:19 +0100 Subject: [PATCH 10/23] Combines public initial and incremental handle sync methods into one --- .../room/membership/LoadRoomMembersTask.kt | 2 +- .../room/membership/RoomMemberEventHandler.kt | 42 ++++++++----------- .../sync/handler/room/RoomSyncHandler.kt | 30 +++---------- 3 files changed, 23 insertions(+), 51 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 3cd4ea75801..70ba9287a2a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -123,7 +123,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( eventId = roomMemberEvent.eventId root = eventEntity } - roomMemberEventHandler.handleIncrementalSync(realm, roomId, roomMemberEvent) + roomMemberEventHandler.handle(realm, roomId, roomMemberEvent, false) } roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index f197f780ba7..31124a816d4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -33,17 +33,29 @@ internal class RoomMemberEventHandler @Inject constructor( @UserId private val myUserId: String ) { - fun handleInitialSync(realm: Realm, - roomId: String, - event: Event, - aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { + fun handle(realm: Realm, + roomId: String, + event: Event, + isInitialSync: Boolean, + aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { return false } val roomMember = event.getFixedRoomMemberContent() ?: return false val eventUserId = event.stateKey ?: return false - return handleInitialSync(realm, roomId, myUserId, eventUserId, roomMember, aggregator) + return if (isInitialSync) { + handleInitialSync(realm, roomId, myUserId, eventUserId, roomMember, aggregator) + } else { + handleIncrementalSync( + realm, + roomId, + eventUserId, + roomMember, + event.resolvedPrevContent(), + aggregator + ) + } } private fun handleInitialSync(realm: Realm, @@ -106,26 +118,6 @@ internal class RoomMemberEventHandler @Inject constructor( } } - fun handleIncrementalSync(realm: Realm, - roomId: String, - event: Event, - aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { - if (event.type != EventType.STATE_ROOM_MEMBER) { - return false - } - val roomMember = event.getFixedRoomMemberContent() ?: return false - val eventUserId = event.stateKey ?: return false - - return handleIncrementalSync( - realm, - roomId, - eventUserId, - roomMember, - event.resolvedPrevContent(), - aggregator - ) - } - private fun handleIncrementalSync(realm: Realm, roomId: String, eventUserId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index c88d8a89c42..ff55b9efeab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -241,11 +241,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } // Give info to crypto module cryptoService.onStateEvent(roomId, event) - if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, event, aggregator) - } else { - roomMemberEventHandler.handleIncrementalSync(realm, roomId, event, aggregator) - } + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync, aggregator) } } if (roomSync.timeline?.events?.isNotEmpty() == true) { @@ -300,11 +296,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = eventEntity.eventId root = eventEntity } - if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, event) - } else { - roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) - } + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync) } } val inviterEvent = roomSync.inviteState?.events?.lastOrNull { @@ -332,11 +324,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = event.eventId root = eventEntity } - if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomId, event) - } else { - roomMemberEventHandler.handleIncrementalSync(realm, roomId, event) - } + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync) } for (event in roomSync.timeline?.events.orEmpty()) { if (event.eventId == null || event.senderId == null || event.type == null) { @@ -350,11 +338,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (event.type == EventType.STATE_ROOM_MEMBER) { - if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, event) - } else { - roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event) - } + roomMemberEventHandler.handle(realm, roomEntity.roomId, event, isInitialSync) } } } @@ -422,11 +406,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } if (event.type == EventType.STATE_ROOM_MEMBER) { roomMemberContentsByUser[event.stateKey] = event.getFixedRoomMemberContent() - if (isInitialSync) { - roomMemberEventHandler.handleInitialSync(realm, roomEntity.roomId, event, aggregator) - } else { - roomMemberEventHandler.handleIncrementalSync(realm, roomEntity.roomId, event, aggregator) - } + roomMemberEventHandler.handle(realm, roomEntity.roomId, event, isInitialSync, aggregator) } } From 304e2f145a2e51f354dad7d29012bb79e3ce8d21 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 16:15:45 +0100 Subject: [PATCH 11/23] Improves code readability --- .../session/sync/handler/room/RoomSyncHandler.kt | 1 + .../sdk/internal/session/user/DefaultUserService.kt | 10 ++++++---- .../roommemberprofile/RoomMemberProfileViewModel.kt | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index ff55b9efeab..c45f58d38dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -206,6 +206,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle insertType: EventInsertType, syncLocalTimestampMillis: Long, aggregator: SyncResponsePostTreatmentAggregator): RoomEntity { + Timber.v("Handle join sync for room $roomId") val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt index 42c81d3592d..4ffc42e714e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt @@ -35,10 +35,12 @@ internal class DefaultUserService @Inject constructor(private val userDataSource return userDataSource.getUser(userId) } - override suspend fun resolveUser(userId: String) = getUser(userId) ?: run { - val params = GetProfileInfoTask.Params(userId) - val json = getProfileInfoTask.execute(params) - User.fromJson(userId, json) + override suspend fun resolveUser(userId: String): User { + return getUser(userId) ?: run { + val params = GetProfileInfoTask.Params(userId) + val json = getProfileInfoTask.execute(params) + User.fromJson(userId, json) + } } override fun getUserLive(userId: String): LiveData> { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 96e423fdad6..136f2303bad 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -329,7 +329,8 @@ class RoomMemberProfileViewModel @AssistedInject constructor( private suspend fun fetchProfileInfo() { val result = runCatchingToAsync { session.getProfile(initialState.userId) - .let { User.fromJson(initialState.userId, it).toMatrixItem() } + .let { User.fromJson(initialState.userId, it) } + .toMatrixItem() } setState { From 669af4df1c95929b46f7939bd1be15991068a5b6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 16:19:59 +0100 Subject: [PATCH 12/23] Removes unneeded method --- .../java/org/matrix/android/sdk/api/session/user/model/User.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt index 5de54a3a5ec..79c86f3f231 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.user.model import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.api.util.MatrixItem /** * Data class which holds information about a user. @@ -33,8 +32,6 @@ data class User( val avatarUrl: String? = null ) { - fun toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl) - companion object { fun fromJson(userId: String, json: JsonDict) = User( From 44655254032a513d4d9b0d16b804948ab75715d6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 17:13:34 +0100 Subject: [PATCH 13/23] Fixes import error --- .../sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 379b3d21047..00b2e349b80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator From de8cc07c3d17d233a04ce582a285a2d886696465 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 7 Apr 2022 17:20:34 +0100 Subject: [PATCH 14/23] Removes unused import --- .../app/features/roommemberprofile/RoomMemberProfileViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 136f2303bad..4bcf9ef55de 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -56,7 +56,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.session.user.model.User -import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.flow.flow From b88eaf1e593f516a3a491a4555ed97d55fd7bef4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 8 Apr 2022 10:40:13 +0100 Subject: [PATCH 15/23] Removes usage of MatrixItem.UserItem internally --- ...SyncResponsePostTreatmentAggregatorHandler.kt | 16 +++++++--------- .../internal/session/user/UserEntityFactory.kt | 10 +++++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 00b2e349b80..01137d16a12 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -20,8 +20,6 @@ import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.user.model.User -import org.matrix.android.sdk.api.util.MatrixItem -import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator @@ -85,15 +83,15 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( usersToFetch.clear() } - private fun saveUserLocally(monarchy: Monarchy, userItem: MatrixItem.UserItem) { - val userEntity = UserEntityFactory.create(userItem) + private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { + val profileJson = profileService.getProfile(it) + User.fromJson(it, profileJson) + } + + private fun saveUserLocally(monarchy: Monarchy, user: User) { + val userEntity = UserEntityFactory.create(user) monarchy.doWithRealm { it.insertOrUpdate(userEntity) } } - - private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { - val profileJson = profileService.getProfile(it) - User.fromJson(it, profileJson).toMatrixItem() - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt index ce235da553c..46ea7547b03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.session.user import org.matrix.android.sdk.api.session.room.model.RoomMemberContent -import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.internal.database.model.UserEntity internal object UserEntityFactory { @@ -30,11 +30,11 @@ internal object UserEntityFactory { ) } - fun create(userItem: MatrixItem.UserItem): UserEntity { + fun create(user: User): UserEntity { return UserEntity( - userId = userItem.id, - displayName = userItem.displayName.orEmpty(), - avatarUrl = userItem.avatarUrl.orEmpty() + userId = user.userId, + displayName = user.displayName.orEmpty(), + avatarUrl = user.avatarUrl.orEmpty() ) } } From e80386ba5ddeaf24d8e7618fae9f22b65b1fb223 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 13:19:18 +0200 Subject: [PATCH 16/23] Removes clearing usersToFetch in aggregator --- .../handler/SyncResponsePostTreatmentAggregatorHandler.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 01137d16a12..760d70f77ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -77,13 +77,12 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } } - private suspend fun fetchAndUpdateUsers(usersToFetch: MutableList) { + private suspend fun fetchAndUpdateUsers(usersToFetch: List) { val userProfiles = fetchUsers(usersToFetch) userProfiles.forEach { saveUserLocally(monarchy, it) } - usersToFetch.clear() } - private suspend fun fetchUsers(usersToFetch: MutableList) = usersToFetch.map { + private suspend fun fetchUsers(usersToFetch: List) = usersToFetch.map { val profileJson = profileService.getProfile(it) User.fromJson(it, profileJson) } From f103d468791d3b61cc42ca8a9130a3c061d67be1 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 15:27:16 +0200 Subject: [PATCH 17/23] Adds exception safety to fetch users and makes it a single transaction --- .../room/membership/RoomMemberEventHandler.kt | 2 +- .../SyncResponsePostTreatmentAggregator.kt | 2 +- ...cResponsePostTreatmentAggregatorHandler.kt | 26 ++++++++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 31124a816d4..0c938c7049b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -129,7 +129,7 @@ internal class RoomMemberEventHandler @Inject constructor( if (previousDisplayName.isDifferentFrom(roomMember.displayName) || previousAvatar.isDifferentFrom(roomMember.avatarUrl)) { - aggregator?.usersToFetch?.add(eventUserId) + aggregator?.userIdsToFetch?.add(eventUserId) } saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt index 2ba7c8133b4..e9452c59fcd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt @@ -24,5 +24,5 @@ internal class SyncResponsePostTreatmentAggregator { val directChatsToCheck = mutableMapOf() // List of userIds to fetch and update at the end of incremental syncs - val usersToFetch = mutableListOf() + val userIdsToFetch = mutableListOf() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 760d70f77ab..f8d6c5270aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -18,9 +18,10 @@ package org.matrix.android.sdk.internal.session.sync.handler import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns -import org.matrix.android.sdk.api.session.profile.ProfileService +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator import org.matrix.android.sdk.internal.session.sync.model.accountdata.toMutable @@ -33,13 +34,13 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private val directChatsHelper: DirectChatsHelper, private val ephemeralTemporaryStore: RoomSyncEphemeralTemporaryStore, private val updateUserAccountDataTask: UpdateUserAccountDataTask, - private val profileService: ProfileService, + private val getProfileInfoTask: GetProfileInfoTask, @SessionDatabase private val monarchy: Monarchy, ) { suspend fun handle(aggregator: SyncResponsePostTreatmentAggregator) { cleanupEphemeralFiles(aggregator.ephemeralFilesToDelete) updateDirectUserIds(aggregator.directChatsToCheck) - fetchAndUpdateUsers(aggregator.usersToFetch) + fetchAndUpdateUsers(aggregator.userIdsToFetch) } private fun cleanupEphemeralFiles(ephemeralFilesToDelete: List) { @@ -77,20 +78,21 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } } - private suspend fun fetchAndUpdateUsers(usersToFetch: List) { - val userProfiles = fetchUsers(usersToFetch) - userProfiles.forEach { saveUserLocally(monarchy, it) } + private suspend fun fetchAndUpdateUsers(userIdsToFetch: List) { + fetchUsers(userIdsToFetch)?.saveLocally() } - private suspend fun fetchUsers(usersToFetch: List) = usersToFetch.map { - val profileJson = profileService.getProfile(it) - User.fromJson(it, profileJson) + private suspend fun fetchUsers(userIdsToFetch: List) = tryOrNull { + userIdsToFetch.map { + val profileJson = getProfileInfoTask.execute(GetProfileInfoTask.Params(it)) + User.fromJson(it, profileJson) + } } - private fun saveUserLocally(monarchy: Monarchy, user: User) { - val userEntity = UserEntityFactory.create(user) + private fun List.saveLocally() { + val userEntities = map { user -> UserEntityFactory.create(user) } monarchy.doWithRealm { - it.insertOrUpdate(userEntity) + it.insertOrUpdate(userEntities) } } } From 5d5a06b941688b3a494d5fcb464e35c5f686a740 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 16:04:07 +0200 Subject: [PATCH 18/23] Changes null check timing when fetching users --- .../SyncResponsePostTreatmentAggregatorHandler.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index f8d6c5270aa..f3ead1de4bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -68,9 +68,9 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } // remove roomId from currentDirectUserId entry - hasUpdate = hasUpdate or(directChats[currentDirectUserId]?.remove(roomId) == true) + hasUpdate = hasUpdate or (directChats[currentDirectUserId]?.remove(roomId) == true) // remove currentDirectUserId entry if there is no attached room anymore - hasUpdate = hasUpdate or(directChats.takeIf { it[currentDirectUserId].isNullOrEmpty() }?.remove(currentDirectUserId) != null) + hasUpdate = hasUpdate or (directChats.takeIf { it[currentDirectUserId].isNullOrEmpty() }?.remove(currentDirectUserId) != null) } } if (hasUpdate) { @@ -79,11 +79,11 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } private suspend fun fetchAndUpdateUsers(userIdsToFetch: List) { - fetchUsers(userIdsToFetch)?.saveLocally() + fetchUsers(userIdsToFetch).saveLocally() } - private suspend fun fetchUsers(userIdsToFetch: List) = tryOrNull { - userIdsToFetch.map { + private suspend fun fetchUsers(userIdsToFetch: List) = userIdsToFetch.mapNotNull { + tryOrNull { val profileJson = getProfileInfoTask.execute(GetProfileInfoTask.Params(it)) User.fromJson(it, profileJson) } From 2337b1875b50e3c396dee5cfb0c4d019e2cda187 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 16:07:02 +0200 Subject: [PATCH 19/23] Reorders val declaration of eventUserId and roomMember --- .../internal/session/room/membership/RoomMemberEventHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 0c938c7049b..1a7e68e083c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -41,8 +41,8 @@ internal class RoomMemberEventHandler @Inject constructor( if (event.type != EventType.STATE_ROOM_MEMBER) { return false } - val roomMember = event.getFixedRoomMemberContent() ?: return false val eventUserId = event.stateKey ?: return false + val roomMember = event.getFixedRoomMemberContent() ?: return false return if (isInitialSync) { handleInitialSync(realm, roomId, myUserId, eventUserId, roomMember, aggregator) From 8964b55508f3774bc4e1eeae9c14258002ab0ab7 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 16:08:33 +0200 Subject: [PATCH 20/23] Adds empty check before saving user entities --- .../handler/SyncResponsePostTreatmentAggregatorHandler.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index f3ead1de4bb..225097f6c83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -91,8 +91,11 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private fun List.saveLocally() { val userEntities = map { user -> UserEntityFactory.create(user) } - monarchy.doWithRealm { - it.insertOrUpdate(userEntities) + + if (userEntities.isNotEmpty()) { + monarchy.doWithRealm { + it.insertOrUpdate(userEntities) + } } } } From 5f949e98c20c37a8429c141b17af46351687befa Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 16:09:23 +0200 Subject: [PATCH 21/23] Reformats not empty check --- .../SyncResponsePostTreatmentAggregatorHandler.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 225097f6c83..25de05602a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -79,7 +79,9 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } private suspend fun fetchAndUpdateUsers(userIdsToFetch: List) { - fetchUsers(userIdsToFetch).saveLocally() + fetchUsers(userIdsToFetch) + .takeIf { it.isNotEmpty() } + ?.saveLocally() } private suspend fun fetchUsers(userIdsToFetch: List) = userIdsToFetch.mapNotNull { @@ -91,11 +93,8 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private fun List.saveLocally() { val userEntities = map { user -> UserEntityFactory.create(user) } - - if (userEntities.isNotEmpty()) { - monarchy.doWithRealm { - it.insertOrUpdate(userEntities) - } + monarchy.doWithRealm { + it.insertOrUpdate(userEntities) } } } From dd988d094ba1ec84103ec23c4670ec4be5073623 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 16:38:56 +0200 Subject: [PATCH 22/23] Simplifies handleIncrementalSync logic --- .../room/membership/RoomMemberEventHandler.kt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 1a7e68e083c..85300fa3518 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.membership import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent @@ -122,14 +123,15 @@ internal class RoomMemberEventHandler @Inject constructor( roomId: String, eventUserId: String, roomMember: RoomMemberContent, - prevContent: Map?, + prevContent: Content?, aggregator: SyncResponsePostTreatmentAggregator?): Boolean { - val previousDisplayName = prevContent?.get("displayname") - val previousAvatar = prevContent?.get("avatar_url") + if (aggregator != null) { + val previousDisplayName = prevContent?.get("displayname") as? String + val previousAvatar = prevContent?.get("avatar_url") as? String - if (previousDisplayName.isDifferentFrom(roomMember.displayName) || - previousAvatar.isDifferentFrom(roomMember.avatarUrl)) { - aggregator?.userIdsToFetch?.add(eventUserId) + if (previousDisplayName != roomMember.displayName || previousAvatar != roomMember.avatarUrl) { + aggregator.userIdsToFetch.add(eventUserId) + } } saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) @@ -137,9 +139,4 @@ internal class RoomMemberEventHandler @Inject constructor( updateDirectChatsIfNecessary(roomId, roomMember, aggregator) return true } - - private fun Any?.isDifferentFrom(value: Any?) = when { - this == null || this == value -> false - else -> true - } } From 8b80cf090cbcedbb9528305e08d47f3dc1b0f186 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 13 Apr 2022 17:49:55 +0200 Subject: [PATCH 23/23] Restores debug log --- .../sdk/internal/session/sync/handler/room/RoomSyncHandler.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index c45f58d38dc..3d15663d177 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -283,6 +283,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle roomSync: InvitedRoomSync, insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { + Timber.v("Handle invited sync for room $roomId") val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val roomEntity = RoomEntity.getOrCreate(realm, roomId) roomEntity.membership = Membership.INVITE