From c7efd1feb99179585e865affa866d680a96fefe2 Mon Sep 17 00:00:00 2001 From: aqulu Date: Tue, 8 Dec 2020 19:04:30 +0900 Subject: [PATCH 1/6] Convert StateService to suspend functions Signed-off-by: aqulu --- CHANGES.md | 2 +- matrix-sdk-android-rx/build.gradle | 1 + .../java/org/matrix/android/sdk/rx/RxRoom.kt | 35 +++--- .../api/session/room/state/StateService.kt | 16 +-- .../session/room/state/DefaultStateService.kt | 110 +++++++----------- .../home/room/detail/RoomDetailViewModel.kt | 25 ++-- .../RoomMemberProfileViewModel.kt | 4 +- .../roomprofile/alias/RoomAliasViewModel.kt | 11 +- .../members/RoomMemberListViewModel.kt | 3 +- .../features/widgets/WidgetPostAPIHandler.kt | 39 +++++-- 10 files changed, 124 insertions(+), 122 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b16a6690bc..b8ed81efb7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ Translations 🗣: - SDK API changes ⚠️: - - + - StateService now exposes suspendable function instead of using MatrixCallback. Build 🧱: - Upgrade some dependencies and Kotlin version diff --git a/matrix-sdk-android-rx/build.gradle b/matrix-sdk-android-rx/build.gradle index 37f41d0a2a..a99b5856ba 100644 --- a/matrix-sdk-android-rx/build.gradle +++ b/matrix-sdk-android-rx/build.gradle @@ -38,6 +38,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlin_coroutines_version" // Paging implementation "androidx.paging:paging-runtime-ktx:2.1.2" diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt index bf4bcacc31..b938f60e39 100644 --- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt +++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxRoom.kt @@ -17,14 +17,20 @@ package org.matrix.android.sdk.rx import android.net.Uri +import io.reactivex.Completable +import io.reactivex.Observable +import io.reactivex.Single +import kotlinx.coroutines.rx2.rxCompletable import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.identity.ThreePid 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.EventAnnotationsSummary +import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.ReadReceipt import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility +import org.matrix.android.sdk.api.session.room.model.RoomJoinRules 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.notification.RoomNotificationState @@ -32,11 +38,6 @@ import org.matrix.android.sdk.api.session.room.send.UserDraft import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional -import io.reactivex.Completable -import io.reactivex.Observable -import io.reactivex.Single -import org.matrix.android.sdk.api.session.room.model.GuestAccess -import org.matrix.android.sdk.api.session.room.model.RoomJoinRules class RxRoom(private val room: Room) { @@ -121,28 +122,28 @@ class RxRoom(private val room: Room) { room.invite3pid(threePid, it) } - fun updateTopic(topic: String): Completable = completableBuilder { - room.updateTopic(topic, it) + fun updateTopic(topic: String): Completable = rxCompletable { + room.updateTopic(topic) } - fun updateName(name: String): Completable = completableBuilder { - room.updateName(name, it) + fun updateName(name: String): Completable = rxCompletable { + room.updateName(name) } - fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = completableBuilder { - room.updateHistoryReadability(readability, it) + fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = rxCompletable { + room.updateHistoryReadability(readability) } - fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?): Completable = completableBuilder { - room.updateJoinRule(joinRules, guestAccess, it) + fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?): Completable = rxCompletable { + room.updateJoinRule(joinRules, guestAccess) } - fun updateAvatar(avatarUri: Uri, fileName: String): Completable = completableBuilder { - room.updateAvatar(avatarUri, fileName, it) + fun updateAvatar(avatarUri: Uri, fileName: String): Completable = rxCompletable { + room.updateAvatar(avatarUri, fileName) } - fun deleteAvatar(): Completable = completableBuilder { - room.deleteAvatar(it) + fun deleteAvatar(): Completable = rxCompletable { + room.deleteAvatar() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index 74e3faf38a..98dde5839f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -33,41 +33,41 @@ interface StateService { /** * Update the topic of the room */ - fun updateTopic(topic: String, callback: MatrixCallback): Cancelable + suspend fun updateTopic(topic: String) /** * Update the name of the room */ - fun updateName(name: String, callback: MatrixCallback): Cancelable + suspend fun updateName(name: String) /** * Update the canonical alias of the room * @param alias the canonical alias, or null to reset the canonical alias of this room * @param altAliases the alternative aliases for this room. It should include the canonical alias if any. */ - fun updateCanonicalAlias(alias: String?, altAliases: List, callback: MatrixCallback): Cancelable + suspend fun updateCanonicalAlias(alias: String?, altAliases: List) /** * Update the history readability of the room */ - fun updateHistoryReadability(readability: RoomHistoryVisibility, callback: MatrixCallback): Cancelable + suspend fun updateHistoryReadability(readability: RoomHistoryVisibility) /** * Update the join rule and/or the guest access */ - fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?, callback: MatrixCallback): Cancelable + suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?) /** * Update the avatar of the room */ - fun updateAvatar(avatarUri: Uri, fileName: String, callback: MatrixCallback): Cancelable + suspend fun updateAvatar(avatarUri: Uri, fileName: String) /** * Delete the avatar of the room */ - fun deleteAvatar(callback: MatrixCallback): Cancelable + suspend fun deleteAvatar() - fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict, callback: MatrixCallback): Cancelable + suspend fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict) fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event? diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt index 6015d945c4..607784b48f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt @@ -20,7 +20,7 @@ import android.net.Uri import androidx.lifecycle.LiveData import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject -import org.matrix.android.sdk.api.MatrixCallback +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -32,20 +32,14 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent import org.matrix.android.sdk.api.session.room.state.StateService -import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.session.content.FileUploader import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasTask -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.task.configureWith -import org.matrix.android.sdk.internal.task.launchToCallback import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import org.matrix.android.sdk.internal.util.awaitCallback internal class DefaultStateService @AssistedInject constructor(@Assisted private val roomId: String, private val stateEventDataSource: StateEventDataSource, - private val taskExecutor: TaskExecutor, private val sendStateTask: SendStateTask, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val fileUploader: FileUploader, @@ -73,45 +67,41 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private return stateEventDataSource.getStateEventsLive(roomId, eventTypes, stateKey) } - override fun sendStateEvent( + override suspend fun sendStateEvent( eventType: String, stateKey: String?, - body: JsonDict, - callback: MatrixCallback - ): Cancelable { - val params = SendStateTask.Params( - roomId = roomId, - stateKey = stateKey, - eventType = eventType, - body = body - ) - return sendStateTask - .configureWith(params) { - this.callback = callback - } - .executeBy(taskExecutor) + body: JsonDict + ) { + withContext(coroutineDispatchers.main) { + val params = SendStateTask.Params( + roomId = roomId, + stateKey = stateKey, + eventType = eventType, + body = body + ) + + sendStateTask.execute(params) + } } - override fun updateTopic(topic: String, callback: MatrixCallback): Cancelable { - return sendStateEvent( + override suspend fun updateTopic(topic: String) { + sendStateEvent( eventType = EventType.STATE_ROOM_TOPIC, body = mapOf("topic" to topic), - callback = callback, stateKey = null ) } - override fun updateName(name: String, callback: MatrixCallback): Cancelable { - return sendStateEvent( + override suspend fun updateName(name: String) { + sendStateEvent( eventType = EventType.STATE_ROOM_NAME, body = mapOf("name" to name), - callback = callback, stateKey = null ) } - override fun updateCanonicalAlias(alias: String?, altAliases: List, callback: MatrixCallback): Cancelable { - return sendStateEvent( + override suspend fun updateCanonicalAlias(alias: String?, altAliases: List) { + sendStateEvent( eventType = EventType.STATE_ROOM_CANONICAL_ALIAS, body = RoomCanonicalAliasContent( canonicalAlias = alias, @@ -123,64 +113,52 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private // Sort for the cleanup .sorted() ).toContent(), - callback = callback, stateKey = null ) } - override fun updateHistoryReadability(readability: RoomHistoryVisibility, callback: MatrixCallback): Cancelable { - return sendStateEvent( + override suspend fun updateHistoryReadability(readability: RoomHistoryVisibility) { + sendStateEvent( eventType = EventType.STATE_ROOM_HISTORY_VISIBILITY, body = mapOf("history_visibility" to readability), - callback = callback, stateKey = null ) } - override fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?, callback: MatrixCallback): Cancelable { - return taskExecutor.executorScope.launchToCallback(coroutineDispatchers.main, callback) { + override suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?) { + withContext(coroutineDispatchers.main) { if (joinRules != null) { - awaitCallback { - sendStateEvent( - eventType = EventType.STATE_ROOM_JOIN_RULES, - body = RoomJoinRulesContent(joinRules).toContent(), - callback = it, - stateKey = null - ) - } + sendStateEvent( + eventType = EventType.STATE_ROOM_JOIN_RULES, + body = RoomJoinRulesContent(joinRules).toContent(), + stateKey = null + ) } if (guestAccess != null) { - awaitCallback { - sendStateEvent( - eventType = EventType.STATE_ROOM_GUEST_ACCESS, - body = RoomGuestAccessContent(guestAccess).toContent(), - callback = it, - stateKey = null - ) - } - } - } - } - - override fun updateAvatar(avatarUri: Uri, fileName: String, callback: MatrixCallback): Cancelable { - return taskExecutor.executorScope.launchToCallback(coroutineDispatchers.main, callback) { - val response = fileUploader.uploadFromUri(avatarUri, fileName, "image/jpeg") - awaitCallback { sendStateEvent( - eventType = EventType.STATE_ROOM_AVATAR, - body = mapOf("url" to response.contentUri), - callback = it, + eventType = EventType.STATE_ROOM_GUEST_ACCESS, + body = RoomGuestAccessContent(guestAccess).toContent(), stateKey = null ) } } } - override fun deleteAvatar(callback: MatrixCallback): Cancelable { - return sendStateEvent( + override suspend fun updateAvatar(avatarUri: Uri, fileName: String) { + withContext(coroutineDispatchers.main) { + val response = fileUploader.uploadFromUri(avatarUri, fileName, "image/jpeg") + sendStateEvent( + eventType = EventType.STATE_ROOM_AVATAR, + body = mapOf("url" to response.contentUri), + stateKey = null + ) + } + } + + override suspend fun deleteAvatar() { + sendStateEvent( eventType = EventType.STATE_ROOM_AVATAR, body = emptyMap(), - callback = callback, stateKey = null ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index a83dddc9ac..5e414422f7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -292,9 +292,7 @@ class RoomDetailViewModel @AssistedInject constructor( private fun handleSetNewAvatar(action: RoomDetailAction.SetAvatarAction) { viewModelScope.launch(Dispatchers.IO) { try { - awaitCallback { - room.updateAvatar(action.newAvatarUri, action.newAvatarFileName, it) - } + room.updateAvatar(action.newAvatarUri, action.newAvatarFileName) _viewEvents.post(RoomDetailViewEvents.ActionSuccess(action)) } catch (failure: Throwable) { _viewEvents.post(RoomDetailViewEvents.ActionFailure(action, failure)) @@ -854,8 +852,8 @@ class RoomDetailViewModel @AssistedInject constructor( } private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) { - launchSlashCommandFlow { - room.updateTopic(changeTopic.topic, it) + launchSlashCommandFlowSuspendable { + room.updateTopic(changeTopic.topic) } } @@ -876,9 +874,9 @@ class RoomDetailViewModel @AssistedInject constructor( ?.content ?.toModel() ?: return - launchSlashCommandFlow { + launchSlashCommandFlowSuspendable { currentPowerLevelsContent.setUserPowerLevel(setUserPowerLevel.userId, setUserPowerLevel.powerLevel) - room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent(), it) + room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent()) } } @@ -920,6 +918,19 @@ class RoomDetailViewModel @AssistedInject constructor( lambda.invoke(matrixCallback) } + private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { + _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) + viewModelScope.launch { + val event = try { + block() + RoomDetailViewEvents.SlashCommandResultOk + } catch (failure: Exception) { + RoomDetailViewEvents.SlashCommandResultError(failure) + } + _viewEvents.post(event) + } + } + private fun handleSendReaction(action: RoomDetailAction.SendReaction) { room.sendReaction(action.targetEventId, action.reaction) } 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 78562ea351..39b5884308 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 @@ -166,9 +166,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private v viewModelScope.launch { _viewEvents.post(RoomMemberProfileViewEvents.Loading()) try { - awaitCallback { - room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent(), it) - } + room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, currentPowerLevelsContent.toContent()) _viewEvents.post(RoomMemberProfileViewEvents.OnSetPowerLevelSuccess) } catch (failure: Throwable) { _viewEvents.post(RoomMemberProfileViewEvents.Failure(failure)) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt index 5873d9ce8a..af0972913a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt @@ -301,21 +301,20 @@ class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: Roo private fun updateCanonicalAlias(canonicalAlias: String?, alternativeAliases: List, closeForm: Boolean) { postLoading(true) - room.updateCanonicalAlias(canonicalAlias, alternativeAliases, object : MatrixCallback { - override fun onSuccess(data: Unit) { + viewModelScope.launch { + try { + room.updateCanonicalAlias(canonicalAlias, alternativeAliases) setState { copy( isLoading = false, publishManuallyState = if (closeForm) RoomAliasViewState.AddAliasState.Closed else publishManuallyState ) } - } - - override fun onFailure(failure: Throwable) { + } catch (failure: Throwable) { postLoading(false) _viewEvents.post(RoomAliasViewEvents.Failure(failure)) } - }) + } } private fun handleAddLocalAlias() = withState { state -> diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index 9e402c675b..fe8ed63cce 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -197,8 +197,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState room.sendStateEvent( eventType = EventType.STATE_ROOM_THIRD_PARTY_INVITE, stateKey = action.stateKey, - body = emptyMap(), - callback = NoOpMatrixCallback() + body = emptyMap() ) } } diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt index a4d759250d..fbd08b0c9f 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt @@ -21,6 +21,8 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.resources.StringProvider +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes @@ -310,12 +312,19 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo val params = HashMap() params["status"] = status - room.sendStateEvent( - eventType = EventType.PLUMBING, - stateKey = null, - body = params, - callback = createWidgetAPICallback(widgetPostAPIMediator, eventData) - ) + + GlobalScope.launch { + try { + room.sendStateEvent( + eventType = EventType.PLUMBING, + stateKey = null, + body = params + ) + widgetPostAPIMediator.sendSuccess(eventData) + } catch (failure: Exception) { + widgetPostAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData) + } + } } /** @@ -333,12 +342,18 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo Timber.d(description) val content = eventData["content"] as JsonDict val stateKey = "_$userId" - room.sendStateEvent( - eventType = EventType.BOT_OPTIONS, - stateKey = stateKey, - body = content, - callback = createWidgetAPICallback(widgetPostAPIMediator, eventData) - ) + GlobalScope.launch { + try { + room.sendStateEvent( + eventType = EventType.BOT_OPTIONS, + stateKey = stateKey, + body = content + ) + widgetPostAPIMediator.sendSuccess(eventData) + } catch (failure: Exception) { + widgetPostAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData) + } + } } /** From 416f57b1d791e71722d0847ba4549c328e0bab5e Mon Sep 17 00:00:00 2001 From: aqulu Date: Tue, 8 Dec 2020 22:02:00 +0900 Subject: [PATCH 2/6] Fix failing test compilation Signed-off-by: aqulu --- .../crypto/encryption/EncryptionTest.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt index e42059c639..da5e90abdd 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt @@ -17,13 +17,13 @@ package org.matrix.android.sdk.internal.crypto.encryption import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.runBlocking import org.amshove.kluent.shouldBe import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.NoOpMatrixCallback 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.room.Room @@ -57,13 +57,14 @@ class EncryptionTest : InstrumentedTest { @Test fun test_EncryptionStateEvent() { performTest(roomShouldBeEncrypted = true) { room -> - // Send an encryption Event as a State Event - room.sendStateEvent( - eventType = EventType.STATE_ROOM_ENCRYPTION, - stateKey = null, - body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent(), - callback = NoOpMatrixCallback() - ) + runBlocking { + // Send an encryption Event as a State Event + room.sendStateEvent( + eventType = EventType.STATE_ROOM_ENCRYPTION, + stateKey = null, + body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent() + ) + } } } From c889deaab1dccd2207612a00b2c9b0112a4bb6f5 Mon Sep 17 00:00:00 2001 From: aqulu Date: Tue, 8 Dec 2020 22:02:49 +0900 Subject: [PATCH 3/6] Remove unused imports Signed-off-by: aqulu --- .../matrix/android/sdk/api/session/room/state/StateService.kt | 2 -- .../vector/app/features/roomprofile/alias/RoomAliasViewModel.kt | 1 - .../app/features/roomprofile/members/RoomMemberListViewModel.kt | 1 - 3 files changed, 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index 98dde5839f..444366e912 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -18,13 +18,11 @@ package org.matrix.android.sdk.api.session.room.state import android.net.Uri import androidx.lifecycle.LiveData -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomJoinRules -import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.Optional diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt index af0972913a..f470eeefc2 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt @@ -30,7 +30,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.powerlevel.PowerLevelsObservableFactory import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.EventType diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index fe8ed63cce..9f15e62b3b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -30,7 +30,6 @@ import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.BiFunction import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue From 19d421df84485effcdc6d5f3ec9fc018f5185f35 Mon Sep 17 00:00:00 2001 From: aqulu Date: Tue, 8 Dec 2020 22:06:21 +0900 Subject: [PATCH 4/6] Remove coroutine context change for sendStateEvent Signed-off-by: aqulu --- .../session/room/state/DefaultStateService.kt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt index 607784b48f..f71b8868ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt @@ -72,16 +72,13 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private stateKey: String?, body: JsonDict ) { - withContext(coroutineDispatchers.main) { - val params = SendStateTask.Params( - roomId = roomId, - stateKey = stateKey, - eventType = eventType, - body = body - ) - - sendStateTask.execute(params) - } + val params = SendStateTask.Params( + roomId = roomId, + stateKey = stateKey, + eventType = eventType, + body = body + ) + sendStateTask.execute(params) } override suspend fun updateTopic(topic: String) { From 40b9f031325cac0a7474a3706341318e62d48dc4 Mon Sep 17 00:00:00 2001 From: aqulu Date: Tue, 8 Dec 2020 22:11:35 +0900 Subject: [PATCH 5/6] Remove explicit coroutine context changes Signed-off-by: aqulu --- .../session/room/state/DefaultStateService.kt | 45 ++++++++----------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt index f71b8868ed..78663e8ce2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt @@ -20,7 +20,6 @@ import android.net.Uri import androidx.lifecycle.LiveData import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject -import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -36,12 +35,10 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.session.content.FileUploader import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasTask -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers internal class DefaultStateService @AssistedInject constructor(@Assisted private val roomId: String, private val stateEventDataSource: StateEventDataSource, private val sendStateTask: SendStateTask, - private val coroutineDispatchers: MatrixCoroutineDispatchers, private val fileUploader: FileUploader, private val addRoomAliasTask: AddRoomAliasTask ) : StateService { @@ -123,33 +120,29 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private } override suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?) { - withContext(coroutineDispatchers.main) { - if (joinRules != null) { - sendStateEvent( - eventType = EventType.STATE_ROOM_JOIN_RULES, - body = RoomJoinRulesContent(joinRules).toContent(), - stateKey = null - ) - } - if (guestAccess != null) { - sendStateEvent( - eventType = EventType.STATE_ROOM_GUEST_ACCESS, - body = RoomGuestAccessContent(guestAccess).toContent(), - stateKey = null - ) - } + if (joinRules != null) { + sendStateEvent( + eventType = EventType.STATE_ROOM_JOIN_RULES, + body = RoomJoinRulesContent(joinRules).toContent(), + stateKey = null + ) + } + if (guestAccess != null) { + sendStateEvent( + eventType = EventType.STATE_ROOM_GUEST_ACCESS, + body = RoomGuestAccessContent(guestAccess).toContent(), + stateKey = null + ) } } override suspend fun updateAvatar(avatarUri: Uri, fileName: String) { - withContext(coroutineDispatchers.main) { - val response = fileUploader.uploadFromUri(avatarUri, fileName, "image/jpeg") - sendStateEvent( - eventType = EventType.STATE_ROOM_AVATAR, - body = mapOf("url" to response.contentUri), - stateKey = null - ) - } + val response = fileUploader.uploadFromUri(avatarUri, fileName, "image/jpeg") + sendStateEvent( + eventType = EventType.STATE_ROOM_AVATAR, + body = mapOf("url" to response.contentUri), + stateKey = null + ) } override suspend fun deleteAvatar() { From ed822becc68c16e03330b0139a7287861ccf72de Mon Sep 17 00:00:00 2001 From: aqulu Date: Wed, 9 Dec 2020 08:39:00 +0900 Subject: [PATCH 6/6] Fix try-catch behavior of sendStateEvent actions Signed-off-by: aqulu --- .../features/widgets/WidgetPostAPIHandler.kt | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt index fbd08b0c9f..3906ea687c 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt @@ -22,6 +22,7 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.resources.StringProvider import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session @@ -312,18 +313,12 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo val params = HashMap() params["status"] = status - - GlobalScope.launch { - try { - room.sendStateEvent( - eventType = EventType.PLUMBING, - stateKey = null, - body = params - ) - widgetPostAPIMediator.sendSuccess(eventData) - } catch (failure: Exception) { - widgetPostAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData) - } + launchWidgetAPIAction(widgetPostAPIMediator, eventData) { + room.sendStateEvent( + eventType = EventType.PLUMBING, + stateKey = null, + body = params + ) } } @@ -342,17 +337,13 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo Timber.d(description) val content = eventData["content"] as JsonDict val stateKey = "_$userId" - GlobalScope.launch { - try { - room.sendStateEvent( - eventType = EventType.BOT_OPTIONS, - stateKey = stateKey, - body = content - ) - widgetPostAPIMediator.sendSuccess(eventData) - } catch (failure: Exception) { - widgetPostAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData) - } + + launchWidgetAPIAction(widgetPostAPIMediator, eventData) { + room.sendStateEvent( + eventType = EventType.BOT_OPTIONS, + stateKey = stateKey, + body = content + ) } } @@ -471,4 +462,19 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo private fun createWidgetAPICallback(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict): WidgetAPICallback { return WidgetAPICallback(widgetPostAPIMediator, eventData, stringProvider) } + + private fun launchWidgetAPIAction(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict, block: suspend () -> Unit): Job { + return GlobalScope.launch { + kotlin.runCatching { + block() + }.fold( + onSuccess = { + widgetPostAPIMediator.sendSuccess(eventData) + }, + onFailure = { + widgetPostAPIMediator.sendError(stringProvider.getString(R.string.widget_integration_failed_to_send_request), eventData) + } + ) + } + } }