From af338b06078d790d7cf22a56deda510f285f3645 Mon Sep 17 00:00:00 2001 From: ganfra Date: Sun, 26 May 2019 19:21:45 +0200 Subject: [PATCH] Crypto: decryption is working (but still a lot to do) --- .../android/api/session/events/model/Event.kt | 49 ++++----- .../room/model/create/CreateRoomParams.kt | 2 +- .../session/room/timeline/TimelineEvent.kt | 2 +- .../vector/matrix/android/api/util/Types.kt | 5 + .../android/internal/crypto/CryptoManager.kt | 96 ++++++++++------- .../android/internal/crypto/CryptoModule.kt | 56 +++++----- .../internal/crypto/IncomingRoomKeyRequest.kt | 3 +- .../crypto/IncomingRoomKeyRequestManager.kt | 2 +- .../crypto/MXEventDecryptionResult.kt | 4 +- .../android/internal/crypto/MXOlmDevice.kt | 10 +- .../crypto/algorithms/MXDecryptionResult.kt | 4 +- .../algorithms/megolm/MXMegolmDecryption.kt | 7 +- .../algorithms/megolm/MXMegolmEncryption.kt | 8 +- .../crypto/algorithms/olm/MXOlmDecryption.kt | 28 +++-- .../crypto/live/EnableEncryptionWorker.kt | 102 ------------------ .../live/RealmLiveEncryptionObserver.kt | 59 ---------- .../crypto/model/MXOlmInboundGroupSession2.kt | 5 +- .../DefaultSasVerificationService.kt | 12 +-- .../database/helper/ChunkEntityHelper.kt | 2 +- .../internal/database/mapper/ContentMapper.kt | 4 +- .../internal/database/mapper/EventMapper.kt | 2 +- .../android/internal/session/SessionModule.kt | 4 +- .../internal/session/room/RoomFactory.kt | 3 +- .../session/room/send/DefaultSendService.kt | 4 +- .../session/room/send/EncryptEventWorker.kt | 26 +++-- .../session/room/send/SendEventWorker.kt | 4 +- .../room/timeline/TimelineEventFactory.kt | 21 +++- .../session/sync/CryptoSyncHandler.kt | 2 +- .../internal/session/sync/RoomSyncHandler.kt | 4 +- .../core/services/EventStreamServiceX.kt | 2 +- .../timeline/TimelineEventController.kt | 2 +- .../timeline/action/MessageMenuViewModel.kt | 12 +-- .../timeline/factory/CallItemFactory.kt | 6 +- .../timeline/factory/DefaultItemFactory.kt | 2 +- .../timeline/factory/EncryptedItemFactory.kt | 10 +- .../timeline/factory/EncryptionItemFactory.kt | 2 +- .../timeline/factory/MessageItemFactory.kt | 4 +- .../timeline/factory/TimelineItemFactory.kt | 2 +- .../helper/TimelineDisplayableEvents.kt | 6 +- .../notifications/NotifiableEventResolver.kt | 6 +- 40 files changed, 233 insertions(+), 351 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/EnableEncryptionWorker.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/RealmLiveEncryptionObserver.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt index 4ef996c6..5f8ee397 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt @@ -19,13 +19,11 @@ package im.vector.matrix.android.api.session.events.model import android.text.TextUtils import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import com.squareup.moshi.Types import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.di.MoshiProvider import timber.log.Timber -import java.lang.reflect.ParameterizedType import java.util.* typealias Content = JsonDict @@ -77,11 +75,7 @@ data class Event( * @return true if event is state event. */ fun isStateEvent(): Boolean { - return EventType.isStateEvent(type) - } - - companion object { - internal val CONTENT_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java) + return EventType.isStateEvent(getClearType()) } //============================================================================================================== @@ -138,24 +132,18 @@ data class Event( * * @param decryptionResult the decryption result, including the plaintext and some key info. */ - fun setClearData(decryptionResult: MXEventDecryptionResult?) { + internal fun setClearData(decryptionResult: MXEventDecryptionResult?) { mClearEvent = null + if (decryptionResult != null) { + if (decryptionResult.mClearEvent != null) { + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + mClearEvent = adapter.fromJsonValue(decryptionResult.mClearEvent) - if (null != decryptionResult) { - if (null != decryptionResult.mClearEvent) { - mClearEvent = decryptionResult.mClearEvent } - - if (null != mClearEvent) { - mClearEvent!!.mSenderCurve25519Key = decryptionResult.mSenderCurve25519Key - mClearEvent!!.mClaimedEd25519Key = decryptionResult.mClaimedEd25519Key - - if (null != decryptionResult.mForwardingCurve25519KeyChain) { - mClearEvent!!.mForwardingCurve25519KeyChain = decryptionResult.mForwardingCurve25519KeyChain - } else { - mClearEvent!!.mForwardingCurve25519KeyChain = ArrayList() - } - + mClearEvent?.apply { + mSenderCurve25519Key = decryptionResult.mSenderCurve25519Key + mClaimedEd25519Key = decryptionResult.mClaimedEd25519Key + mForwardingCurve25519KeyChain = decryptionResult.mForwardingCurve25519KeyChain try { // Add "m.relates_to" data from e2e event to the unencrypted event // TODO @@ -166,11 +154,9 @@ data class Event( } catch (e: Exception) { Timber.e(e, "Unable to restore 'm.relates_to' the clear event") } - } - - mCryptoError = null } + mCryptoError = null } /** @@ -203,11 +189,14 @@ data class Event( * @return the event type */ fun getClearType(): String { - return if (null != mClearEvent) { - mClearEvent!!.type - } else { - type - } + return mClearEvent?.type ?: type + } + + /** + * @return the event type + */ + fun getClearContent(): Content? { + return mClearEvent?.content ?: content } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt index 8347d0af..77055ec2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/model/create/CreateRoomParams.kt @@ -149,7 +149,7 @@ class CreateRoomParams { if (initialStates != null && !initialStates!!.isEmpty()) { val newInitialStates = ArrayList() for (event in initialStates!!) { - if (event.type != EventType.STATE_HISTORY_VISIBILITY) { + if (event.getClearType() != EventType.STATE_HISTORY_VISIBILITY) { newInitialStates.add(event) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt index 7c73d761..280a3565 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineEvent.kt @@ -62,6 +62,6 @@ data class TimelineEvent( } fun isEncrypted() : Boolean { - return EventType.ENCRYPTED == root.type + return EventType.ENCRYPTED == root.getClearType() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt index 601b3cb0..c2f710df 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/util/Types.kt @@ -16,4 +16,9 @@ package im.vector.matrix.android.api.util +import com.squareup.moshi.Types +import java.lang.reflect.ParameterizedType + typealias JsonDict = Map + +internal val JSON_DICT_PARAMETERIZED_TYPE: ParameterizedType = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt index b8ff9eaf..cd1efe84 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt @@ -21,6 +21,7 @@ package im.vector.matrix.android.internal.crypto import android.content.Context import android.os.Handler import android.text.TextUtils +import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.failure.Failure @@ -46,30 +47,25 @@ import im.vector.matrix.android.internal.crypto.algorithms.IMXEncrypting import im.vector.matrix.android.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory import im.vector.matrix.android.internal.crypto.algorithms.olm.MXOlmEncryptionFactory import im.vector.matrix.android.internal.crypto.keysbackup.KeysBackup -import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult -import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo -import im.vector.matrix.android.internal.crypto.model.MXEncryptEventContentResult -import im.vector.matrix.android.internal.crypto.model.MXOlmSessionResult -import im.vector.matrix.android.internal.crypto.model.MXUsersDevicesMap +import im.vector.matrix.android.internal.crypto.model.* import im.vector.matrix.android.internal.crypto.model.event.RoomKeyContent import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody import im.vector.matrix.android.internal.crypto.repository.WarnOnUnknownDeviceRepository import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore -import im.vector.matrix.android.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask -import im.vector.matrix.android.internal.crypto.tasks.DeleteDeviceTask -import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask -import im.vector.matrix.android.internal.crypto.tasks.GetKeyChangesTask -import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask -import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask -import im.vector.matrix.android.internal.crypto.tasks.UploadKeysTask +import im.vector.matrix.android.internal.crypto.tasks.* import im.vector.matrix.android.internal.crypto.verification.DefaultSasVerificationService import im.vector.matrix.android.internal.di.MoshiProvider +import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask +import im.vector.matrix.android.internal.session.room.members.RoomMembers import im.vector.matrix.android.internal.session.sync.model.SyncResponse import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskThread import im.vector.matrix.android.internal.task.configureWith +import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.matrix.olm.OlmManager import timber.log.Timber import java.util.* @@ -128,6 +124,9 @@ internal class CryptoManager( private val mSendToDeviceTask: SendToDeviceTask, private val mSetDeviceNameTask: SetDeviceNameTask, private val mUploadKeysTask: UploadKeysTask, + private val loadRoomMembersTask: LoadRoomMembersTask, + private val monarchy: Monarchy, + private val coroutineDispatchers: MatrixCoroutineDispatchers, // TaskExecutor private val mTaskExecutor: TaskExecutor ) : CryptoService { @@ -152,22 +151,18 @@ internal class CryptoManager( //} fun onStateEvent(roomId: String, event: Event) { - if (event.type == EventType.ENCRYPTION) { - // TODO Remove onRoomEncryptionEvent(roomId, event) - } else if (event.type == EventType.STATE_ROOM_MEMBER) { - onRoomMembershipEvent(roomId, event) - } else if (event.type == EventType.STATE_HISTORY_VISIBILITY) { - onRoomHistoryVisibilityEvent(roomId, event) + when { + event.getClearType() == EventType.ENCRYPTION -> onRoomEncryptionEvent(roomId, event) + event.getClearType() == EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) + event.getClearType() == EventType.STATE_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) } } fun onLiveEvent(roomId: String, event: Event) { - if (event.type == EventType.ENCRYPTION) { - // TODO Remove onRoomEncryptionEvent(roomId, event) - } else if (event.type == EventType.STATE_ROOM_MEMBER) { - onRoomMembershipEvent(roomId, event) - } else if (event.type == EventType.STATE_HISTORY_VISIBILITY) { - onRoomHistoryVisibilityEvent(roomId, event) + when { + event.getClearType() == EventType.ENCRYPTION -> onRoomEncryptionEvent(roomId, event) + event.getClearType() == EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) + event.getClearType() == EventType.STATE_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) } } @@ -265,11 +260,11 @@ internal class CryptoManager( uploadDeviceKeys(object : MatrixCallback { private fun onError() { Handler().postDelayed({ - if (!isStarted()) { - mIsStarting = false - start(isInitialSync) - } - }, 1000) + if (!isStarted()) { + mIsStarting = false + start(isInitialSync) + } + }, 1000) } override fun onSuccess(data: KeysUploadResponse) { @@ -657,11 +652,11 @@ internal class CryptoManager( } else { val algorithm = room.encryptionAlgorithm() val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, - algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON) + algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON) Timber.e("## encryptEventContent() : $reason") callback.onFailure(Failure.CryptoError(MXCryptoError(MXCryptoError.UNABLE_TO_ENCRYPT_ERROR_CODE, - MXCryptoError.UNABLE_TO_ENCRYPT, reason))) + MXCryptoError.UNABLE_TO_ENCRYPT, reason))) } } @@ -691,7 +686,7 @@ internal class CryptoManager( val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, eventContent["algorithm"] as String) Timber.e("## decryptEvent() : $reason") exceptions.add(MXDecryptionException(MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, - MXCryptoError.UNABLE_TO_DECRYPT, reason))) + MXCryptoError.UNABLE_TO_DECRYPT, reason))) } else { try { result = alg.decryptEvent(event, timeline) @@ -728,9 +723,9 @@ internal class CryptoManager( * @param event the event */ fun onToDeviceEvent(event: Event) { - if (event.type == EventType.ROOM_KEY || event.type == EventType.FORWARDED_ROOM_KEY) { + if (event.getClearType() == EventType.ROOM_KEY || event.getClearType() == EventType.FORWARDED_ROOM_KEY) { onRoomKeyEvent(event) - } else if (event.type == EventType.ROOM_KEY_REQUEST) { + } else if (event.getClearType() == EventType.ROOM_KEY_REQUEST) { mIncomingRoomKeyRequestManager.onRoomKeyRequestEvent(event) } } @@ -742,7 +737,7 @@ internal class CryptoManager( * @param event the key event. */ private fun onRoomKeyEvent(event: Event) { - val roomKeyContent = event.content.toModel()!! + val roomKeyContent = event.getClearContent().toModel()!! if (TextUtils.isEmpty(roomKeyContent.roomId) || TextUtils.isEmpty(roomKeyContent.algorithm)) { Timber.e("## onRoomKeyEvent() : missing fields") @@ -764,8 +759,29 @@ internal class CryptoManager( * * @param event the encryption event. */ - fun onRoomEncryptionEvent(event: Event, userIds: List) { - setEncryptionInRoom(event.roomId!!, event.content!!["algorithm"] as String, true, userIds) + private fun onRoomEncryptionEvent(roomId: String, event: Event) { + CoroutineScope(coroutineDispatchers.encryption).launch { + val params = LoadRoomMembersTask.Params(roomId) + loadRoomMembersTask + .execute(params) + .map { allLoaded -> + var userIds: List = emptyList() + monarchy.doWithRealm { realm -> + // Check whether the event content must be encrypted for the invited members. + val encryptForInvitedMembers = isEncryptionEnabledForInvitedUser() + && shouldEncryptForInvitedMembers(roomId) + + userIds = if (encryptForInvitedMembers) { + RoomMembers(realm, roomId).getActiveRoomMemberIds() + } else { + RoomMembers(realm, roomId).getJoinedRoomMemberIds() + } + + } + setEncryptionInRoom(roomId, event.content!!["algorithm"] as String, true, userIds) + allLoaded + } + } } /** @@ -791,8 +807,8 @@ internal class CryptoManager( // make sure we are tracking the deviceList for this user. deviceListManager.startTrackingDeviceList(Arrays.asList(userId)) } else if (membership == Membership.INVITE - && shouldEncryptForInvitedMembers(roomId) - && mCryptoConfig.mEnableEncryptionForInvitedMembers) { + && shouldEncryptForInvitedMembers(roomId) + && mCryptoConfig.mEnableEncryptionForInvitedMembers) { // track the deviceList for this invited user. // Caution: there's a big edge case here in that federated servers do not // know what other servers are in the room at the time they've been invited. @@ -960,7 +976,7 @@ internal class CryptoManager( // trigger an an unknown devices exception callback.onFailure( Failure.CryptoError(MXCryptoError(MXCryptoError.UNKNOWN_DEVICES_CODE, - MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices))) + MXCryptoError.UNABLE_TO_ENCRYPT, MXCryptoError.UNKNOWN_DEVICES_REASON, unknownDevices))) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt index 72f7fdc3..3b85ca52 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoModule.kt @@ -99,7 +99,6 @@ internal class CryptoModule { scope(DefaultSession.SCOPE) { // Ensure OlmManager is loaded first get() - MXOlmDevice(get()) } @@ -172,31 +171,38 @@ internal class CryptoModule { // CryptoManager scope(DefaultSession.SCOPE) { CryptoManager( - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - get(), - // Actions - get(), - get(), - get(), - // Factory - get(), get(), + mCredentials = get(), + mMyDeviceInfoHolder = get(), + mCryptoStore = get(), + mOlmDevice = get(), + mCryptoConfig = get(), + deviceListManager = get(), + mKeysBackup = get(), + mObjectSigner = get(), + mOneTimeKeysUploader = get(), + roomDecryptorProvider = get(), + mSasVerificationService = get(), + mIncomingRoomKeyRequestManager = get(), + mOutgoingRoomKeyRequestManager = get(), + mOlmManager = get(), + mSetDeviceVerificationAction = get(), + mMegolmSessionDataImporter = get(), + mEnsureOlmSessionsForDevicesAction = get(), + mWarnOnUnknownDevicesRepository = get(), + mMXMegolmEncryptionFactory = get(), + mMXOlmEncryptionFactory = get(), + mClaimOneTimeKeysForUsersDeviceTask = get(), // Tasks - get(), get(), get(), get(), get(), get(), get(), - // Task executor - get() + mDeleteDeviceTask = get(), + mGetDevicesTask = get(), + mGetKeyChangesTask = get(), + mSendToDeviceTask = get(), + mSetDeviceNameTask = get(), + mUploadKeysTask = get(), + loadRoomMembersTask = get(), + monarchy = get(), + coroutineDispatchers = get(), + mTaskExecutor = get() ) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt index 63394349..2cd491d1 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequest.kt @@ -66,8 +66,7 @@ open class IncomingRoomKeyRequest { */ constructor(event: Event) { mUserId = event.sender - - val roomKeyShareRequest = event.content.toModel()!! + val roomKeyShareRequest = event.getClearContent().toModel()!! mDeviceId = roomKeyShareRequest.requestingDeviceId mRequestId = roomKeyShareRequest.requestId mRequestBody = if (null != roomKeyShareRequest.body) roomKeyShareRequest.body else RoomKeyRequestBody() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt index 755280d8..d3842d2f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingRoomKeyRequestManager.kt @@ -51,7 +51,7 @@ internal class IncomingRoomKeyRequestManager( * @param event the announcement event. */ fun onRoomKeyRequestEvent(event: Event) { - val roomKeyShare = event.content.toModel() + val roomKeyShare = event.getClearContent().toModel() when (roomKeyShare?.action) { RoomKeyShare.ACTION_SHARE_REQUEST -> synchronized(mReceivedRoomKeyRequests) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXEventDecryptionResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXEventDecryptionResult.kt index f8b5f6b6..6c3bc657 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXEventDecryptionResult.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXEventDecryptionResult.kt @@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.crypto -import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.util.JsonDict import java.util.* /** @@ -28,7 +28,7 @@ data class MXEventDecryptionResult( /** * The plaintext payload for the event (typically containing "type" and "content" fields). */ - var mClearEvent: Event? = null, + var mClearEvent: JsonDict? = null, /** * Key owned by the sender of this event. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt index 76d490de..c24fed74 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/MXOlmDevice.kt @@ -19,7 +19,8 @@ package im.vector.matrix.android.internal.crypto import android.text.TextUtils import im.vector.matrix.android.api.session.crypto.MXCryptoError -import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE +import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.algorithms.MXDecryptionResult import im.vector.matrix.android.internal.crypto.model.MXOlmInboundGroupSession2 import im.vector.matrix.android.internal.crypto.model.MXOlmSession @@ -677,9 +678,10 @@ internal class MXOlmDevice( mStore.storeInboundGroupSessions(listOf(session)) try { - val moshi = MoshiProvider.providesMoshi() - val adapter = moshi.adapter(Map::class.java) - result.mPayload = adapter.fromJson(convertFromUTF8(decryptResult.mDecryptedMessage)) as Event? + val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) + val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) + val payload = adapter.fromJson(payloadString) + result.mPayload = payload } catch (e: Exception) { Timber.e(e, "## decryptGroupMessage() : RLEncoder.encode failed " + e.message) return null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/MXDecryptionResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/MXDecryptionResult.kt index 186d7459..2cf7973c 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/MXDecryptionResult.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/MXDecryptionResult.kt @@ -16,7 +16,7 @@ package im.vector.matrix.android.internal.crypto.algorithms -import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.util.JsonDict /** * This class represents the decryption result. @@ -25,7 +25,7 @@ data class MXDecryptionResult( /** * The decrypted payload (with properties 'type', 'content') */ - var mPayload: Event? = null, + var mPayload: JsonDict? = null, /** * keys that the sender of the event claims ownership of: diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index 9af2b5f2..92776d8b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -195,7 +195,7 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials, */ override fun onRoomKeyEvent(event: Event, keysBackup: KeysBackup) { var exportFormat = false - val roomKeyContent = event.content.toModel()!! + val roomKeyContent = event.getClearContent().toModel()!! var senderKey: String? = event.getSenderKey() var keysClaimed: MutableMap = HashMap() @@ -206,10 +206,10 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials, return } - if (event.type == EventType.FORWARDED_ROOM_KEY) { + if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) { Timber.v("## onRoomKeyEvent(), forward adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId + " sessionKey " + roomKeyContent.sessionKey) // from " + event); - val forwardedRoomKeyContent = event.content.toModel()!! + val forwardedRoomKeyContent = event.getClearContent().toModel()!! if (null == forwardedRoomKeyContent.forwardingCurve25519KeyChain) { forwarding_curve25519_key_chain = ArrayList() @@ -297,7 +297,6 @@ internal class MXMegolmDecryption(private val mCredentials: Credentials, val fResut = result CryptoAsyncHelper.getUiHandler().post { event.setClearData(fResut) - TODO() //mSession!!.onEventDecrypted(event) } Timber.v("## onNewSession() : successful re-decryption of " + event.eventId) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index b3d432f0..e10a2a46 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -25,7 +25,6 @@ import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.api.session.events.model.toContent import im.vector.matrix.android.internal.crypto.CryptoAsyncHelper import im.vector.matrix.android.internal.crypto.DeviceListManager import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM @@ -62,7 +61,7 @@ internal class MXMegolmEncryption( private val mTaskExecutor: TaskExecutor, private val mMessageEncrypter: MessageEncrypter, private val mWarnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository - ) : IMXEncrypting { +) : IMXEncrypting { // OutboundSessionInfo. Null if we haven't yet started setting one up. Note @@ -422,9 +421,8 @@ internal class MXMegolmEncryption( payloadJson["content"] = queuedEncryption.mEventContent!! // Get canonical Json from - val content = payloadJson.toContent()!! - val payloadString = convertToUTF8(MoshiProvider.getCanonicalJson(Map::class.java, content)) + val payloadString = convertToUTF8(MoshiProvider.getCanonicalJson(Map::class.java, payloadJson)) val ciphertext = olmDevice.encryptGroupMessage(session.mSessionId, payloadString!!) val map = HashMap() @@ -437,7 +435,7 @@ internal class MXMegolmEncryption( // m.new_device message if they don't have our session key. map["device_id"] = mCredentials.deviceId!! - CryptoAsyncHelper.getUiHandler().post { queuedEncryption.mApiCallback?.onSuccess(map.toContent()!!) } + CryptoAsyncHelper.getUiHandler().post { queuedEncryption.mApiCallback?.onSuccess(map) } session.mUseCount++ } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt index b7befdd0..9d6f586f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -18,16 +18,20 @@ package im.vector.matrix.android.internal.crypto.algorithms.olm import android.text.TextUtils +import com.squareup.moshi.Json import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE +import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.MXDecryptionException import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult import im.vector.matrix.android.internal.crypto.MXOlmDevice import im.vector.matrix.android.internal.crypto.algorithms.IMXDecrypting import im.vector.matrix.android.internal.crypto.model.event.OlmEventContent import im.vector.matrix.android.internal.crypto.model.event.OlmPayloadContent +import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.util.convertFromUTF8 import timber.log.Timber import java.util.* @@ -58,24 +62,30 @@ internal class MXOlmDecryption( } // The message for myUser - val message = olmEventContent.ciphertext!![mOlmDevice.deviceCurve25519Key] as Map - val payloadString = decryptMessage(message, olmEventContent.senderKey!!) + val message = olmEventContent.ciphertext!![mOlmDevice.deviceCurve25519Key] as JsonDict + val decryptedPayload = decryptMessage(message, olmEventContent.senderKey!!) - if (null == payloadString) { + if (decryptedPayload == null) { Timber.e("## decryptEvent() Failed to decrypt Olm event (id= " + event.eventId + " ) from " + olmEventContent.senderKey) throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)) } + val payloadString = convertFromUTF8(decryptedPayload) + if (payloadString == null) { + Timber.e("## decryptEvent() Failed to decrypt Olm event (id= " + event.eventId + " ) from " + olmEventContent.senderKey) + throw MXDecryptionException(MXCryptoError(MXCryptoError.BAD_ENCRYPTED_MESSAGE_ERROR_CODE, + MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)) + } + val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) + val payload = adapter.fromJson(payloadString) - val payload = convertFromUTF8(payloadString) - - if (null == payload) { + if (payload == null) { Timber.e("## decryptEvent failed : null payload") throw MXDecryptionException(MXCryptoError(MXCryptoError.UNABLE_TO_DECRYPT_ERROR_CODE, MXCryptoError.UNABLE_TO_DECRYPT, MXCryptoError.MISSING_CIPHER_TEXT_REASON)) } - val olmPayloadContent = OlmPayloadContent.fromJsonString(payload) + val olmPayloadContent = OlmPayloadContent.fromJsonString(payloadString) if (TextUtils.isEmpty(olmPayloadContent.recipient)) { val reason = String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient") @@ -134,7 +144,7 @@ internal class MXOlmDecryption( } val result = MXEventDecryptionResult() - // FIXME result.mClearEvent = payload + result.mClearEvent = payload result.mSenderCurve25519Key = olmEventContent.senderKey result.mClaimedEd25519Key = olmPayloadContent.keys!!.get("ed25519") @@ -148,7 +158,7 @@ internal class MXOlmDecryption( * @param message message object, with 'type' and 'body' fields. * @return payload, if decrypted successfully. */ - private fun decryptMessage(message: Map, theirDeviceIdentityKey: String): String? { + private fun decryptMessage(message: JsonDict, theirDeviceIdentityKey: String): String? { val sessionIdsSet = mOlmDevice.getSessionIds(theirDeviceIdentityKey) val sessionIds: List diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/EnableEncryptionWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/EnableEncryptionWorker.kt deleted file mode 100644 index baa81961..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/EnableEncryptionWorker.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.matrix.android.internal.crypto.live - -import android.content.Context -import androidx.work.Worker -import androidx.work.WorkerParameters -import com.squareup.moshi.JsonClass -import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.MatrixCallback -import im.vector.matrix.android.internal.crypto.CryptoManager -import im.vector.matrix.android.internal.database.mapper.asDomain -import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.di.MatrixKoinComponent -import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask -import im.vector.matrix.android.internal.session.room.members.RoomMembers -import im.vector.matrix.android.internal.task.TaskExecutor -import im.vector.matrix.android.internal.task.TaskThread -import im.vector.matrix.android.internal.task.configureWith -import im.vector.matrix.android.internal.util.WorkerParamsFactory -import org.koin.standalone.inject - -internal class EnableEncryptionWorker(context: Context, - workerParameters: WorkerParameters -) : Worker(context, workerParameters), MatrixKoinComponent { - - private val monarchy by inject() - private val cryptoManager by inject() - private val loadRoomMembersTask by inject() - private val taskExecutor by inject() - - @JsonClass(generateAdapter = true) - internal class Params( - val eventIds: List - ) - - - override fun doWork(): Result { - val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.failure() - - - val events = monarchy.fetchAllMappedSync( - { EventEntity.where(it, params.eventIds) }, - { it.asDomain() } - ) - - events.forEach { - val roomId = it.roomId!! - - val callback = object : MatrixCallback { - override fun onSuccess(data: Boolean) { - super.onSuccess(data) - - } - } - - loadRoomMembersTask - .configureWith(LoadRoomMembersTask.Params(roomId)) - .executeOn(TaskThread.ENCRYPTION) - .dispatchTo(callback) - .executeBy(taskExecutor) - - var userIds: List = emptyList() - - monarchy.doWithRealm { realm -> - // Check whether the event content must be encrypted for the invited members. - val encryptForInvitedMembers = cryptoManager.isEncryptionEnabledForInvitedUser() - && cryptoManager.shouldEncryptForInvitedMembers(roomId) - - - userIds = if (encryptForInvitedMembers) { - RoomMembers(realm, roomId).getActiveRoomMemberIds() - } else { - RoomMembers(realm, roomId).getJoinedRoomMemberIds() - } - - } - - cryptoManager.onRoomEncryptionEvent(it, userIds) - } - - return Result.success() - } - - -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/RealmLiveEncryptionObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/RealmLiveEncryptionObserver.kt deleted file mode 100644 index bca038d8..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/live/RealmLiveEncryptionObserver.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.matrix.android.internal.crypto.live - -import androidx.work.ExistingWorkPolicy -import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.WorkManager -import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.internal.database.RealmLiveEntityObserver -import im.vector.matrix.android.internal.database.mapper.asDomain -import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.util.WorkerParamsFactory -import timber.log.Timber - -private const val ENABLE_ENCRYPTION_EVENT_WORKER = "ENABLE_ENCRYPTION_EVENT_WORKER" - -internal class RoomEncryptionEnabler(monarchy: Monarchy) : RealmLiveEntityObserver(monarchy) { - - override val query: Monarchy.Query - get() = Monarchy.Query { EventEntity.where(it, type = EventType.ENCRYPTION) } - - - override fun processChanges(inserted: List, updated: List, deleted: List) { - Timber.v("RoomEncryption received") - - val eventIds = inserted.mapNotNull { it.asDomain().eventId } - - if (eventIds.isEmpty()) { - return - } - - val workParam = EnableEncryptionWorker.Params(eventIds) - val workData = WorkerParamsFactory.toData(workParam) - - val work = OneTimeWorkRequestBuilder() - .setInputData(workData) - .build() - - WorkManager.getInstance() - .beginUniqueWork(ENABLE_ENCRYPTION_EVENT_WORKER, ExistingWorkPolicy.APPEND, work) - .enqueue() - } -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXOlmInboundGroupSession2.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXOlmInboundGroupSession2.kt index ab6f5669..9376b5d4 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXOlmInboundGroupSession2.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/MXOlmInboundGroupSession2.kt @@ -22,13 +22,14 @@ import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import im.vector.matrix.android.internal.crypto.MegolmSessionData import org.matrix.olm.OlmInboundGroupSession import timber.log.Timber +import java.io.Serializable import java.util.* /** * This class adds more context to a OLMInboundGroupSession object. - * This allows additional checks. The class implements NSCoding so that the context can be stored. + * This allows additional checks. The class implements Serializable so that the context can be stored. */ -class MXOlmInboundGroupSession2 { +class MXOlmInboundGroupSession2 : Serializable { // The associated olm inbound group session. var mSession: OlmInboundGroupSession? = null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt index 94d56e1a..2ce00059 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt @@ -65,7 +65,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia fun onToDeviceEvent(event: Event) { CryptoAsyncHelper.getDecryptBackgroundHandler().post { // TODO We are already in a BG thread - when (event.type) { + when (event.getClearType()) { EventType.KEY_VERIFICATION_START -> { onStartRequestReceived(event) } @@ -144,7 +144,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia } private fun onStartRequestReceived(event: Event) { - val startReq = event.content.toModel()!! + val startReq = event.getClearContent().toModel()!! val otherUserId = event.sender if (!startReq.isValid()) { @@ -233,7 +233,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia private fun onCancelReceived(event: Event) { Timber.v("## SAS onCancelReceived") - val cancelReq = event.content.toModel()!! + val cancelReq = event.getClearContent().toModel()!! if (!cancelReq.isValid()) { //ignore @@ -255,7 +255,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia } private fun onAcceptReceived(event: Event) { - val acceptReq = event.content.toModel()!! + val acceptReq = event.getClearContent().toModel()!! if (!acceptReq.isValid()) { //ignore @@ -279,7 +279,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia private fun onKeyReceived(event: Event) { - val keyReq = event.content.toModel()!! + val keyReq = event.getClearContent().toModel()!! if (!keyReq.isValid()) { //ignore @@ -300,7 +300,7 @@ internal class DefaultSasVerificationService(private val mCredentials: Credentia } private fun onMacReceived(event: Event) { - val macReq = event.content.toModel()!! + val macReq = event.getClearContent().toModel()!! if (!macReq.isValid()) { //ignore diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt index 28470455..0db4d14f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt @@ -99,7 +99,7 @@ internal fun ChunkEntity.add(roomId: String, backwardsDisplayIndex = currentDisplayIndex } var currentStateIndex = lastStateIndex(direction, defaultValue = stateIndexOffset) - if (direction == PaginationDirection.FORWARDS && EventType.isStateEvent(event.type)) { + if (direction == PaginationDirection.FORWARDS && EventType.isStateEvent(event.getClearType())) { currentStateIndex += 1 forwardsStateIndex = currentStateIndex } else if (direction == PaginationDirection.BACKWARDS && events.isNotEmpty()) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt index 9f7d2325..801fdf39 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt @@ -17,13 +17,13 @@ package im.vector.matrix.android.internal.database.mapper import im.vector.matrix.android.api.session.events.model.Content -import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE import im.vector.matrix.android.internal.di.MoshiProvider internal object ContentMapper { private val moshi = MoshiProvider.providesMoshi() - private val adapter = moshi.adapter(Event.CONTENT_TYPE) + private val adapter = moshi.adapter(JSON_DICT_PARAMETERIZED_TYPE) fun map(content: String?): Content? { return content?.let { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt index 3d83881a..64139772 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt @@ -32,7 +32,7 @@ internal object EventMapper { val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent eventEntity.prevContent = ContentMapper.map(resolvedPrevContent) eventEntity.stateKey = event.stateKey - eventEntity.type = event.type + eventEntity.type = event.getClearType() eventEntity.sender = event.sender eventEntity.originServerTs = event.originServerTs eventEntity.redacts = event.redacts diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 604053af..d877bd3f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -25,7 +25,6 @@ import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.signout.SignOutService import im.vector.matrix.android.api.session.sync.FilterService import im.vector.matrix.android.api.session.user.UserService -import im.vector.matrix.android.internal.crypto.live.RoomEncryptionEnabler import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.database.model.SessionRealmModule import im.vector.matrix.android.internal.session.cache.ClearCacheTask @@ -152,8 +151,7 @@ internal class SessionModule(private val sessionParams: SessionParams) { val groupSummaryUpdater = GroupSummaryUpdater(get()) val eventsPruner = EventsPruner(get()) val userEntityUpdater = UserEntityUpdater(get(), get(), get()) - val roomEncryptionEnabler = RoomEncryptionEnabler(get()) - listOf(groupSummaryUpdater, eventsPruner, userEntityUpdater, roomEncryptionEnabler) + listOf(groupSummaryUpdater, eventsPruner, userEntityUpdater) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt index ed127845..eb285150 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomFactory.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.room import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.internal.crypto.CryptoManager import im.vector.matrix.android.internal.session.room.invite.InviteTask import im.vector.matrix.android.internal.session.room.members.DefaultRoomMembersService import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTask @@ -48,7 +49,7 @@ internal class RoomFactory(private val loadRoomMembersTask: LoadRoomMembersTask, fun instantiate(roomId: String): Room { val roomMemberExtractor = SenderRoomMemberExtractor(roomId) - val timelineEventFactory = TimelineEventFactory(roomMemberExtractor) + val timelineEventFactory = TimelineEventFactory(roomMemberExtractor, cryptoService) val timelineService = DefaultTimelineService(roomId, monarchy, taskExecutor, contextOfEventTask, timelineEventFactory, paginationTask) val sendService = DefaultSendService(roomId, eventFactory, cryptoService, monarchy) val stateService = DefaultStateService(roomId, sendStateTask, taskExecutor) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt index 36fd74a5..69ddb702 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -131,8 +131,8 @@ internal class DefaultSendService(private val roomId: String, private fun createEncryptEventWork(event: Event): OneTimeWorkRequest { // Same parameter - val sendContentWorkerParams = SendEventWorker.Params(roomId, event) - val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) + val params = EncryptEventWorker.Params(roomId, event) + val sendWorkData = WorkerParamsFactory.toData(params) return OneTimeWorkRequestBuilder() .setConstraints(WORK_CONSTRAINTS) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt index e6619cc4..708e4d33 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt @@ -59,18 +59,22 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) var result: MXEncryptEventContentResult? = null var error: Throwable? = null - crypto.encryptEventContent(localEvent.content!!, localEvent.type, roomService.getRoom(params.roomId)!!, object : MatrixCallback { - override fun onSuccess(data: MXEncryptEventContentResult) { - result = data - latch.countDown() - } - - override fun onFailure(failure: Throwable) { - error = failure - latch.countDown() - } - }) + try { + crypto.encryptEventContent(localEvent.content!!, localEvent.getClearType(), roomService.getRoom(params.roomId)!!, object : MatrixCallback { + override fun onSuccess(data: MXEncryptEventContentResult) { + result = data + latch.countDown() + } + override fun onFailure(failure: Throwable) { + error = failure + latch.countDown() + } + }) + } catch (e: Throwable) { + error = e + latch.countDown() + } latch.await() // TODO Update local echo diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index 864ef13e..ba4dae76 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -53,10 +53,10 @@ internal class SendEventWorker(context: Context, params: WorkerParameters) apiCall = roomAPI.send( localEvent.eventId, params.roomId, - localEvent.type, + localEvent.getClearType(), localEvent.content ) } - return result.fold({ Result.retry() }, { Result.success() }) + return result.fold({ Result.failure() }, { Result.success() }) } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt index 7fe38391..f8aae7ad 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineEventFactory.kt @@ -16,13 +16,17 @@ package im.vector.matrix.android.internal.session.room.timeline +import im.vector.matrix.android.api.session.crypto.CryptoService +import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.session.room.members.SenderRoomMemberExtractor import io.realm.Realm +import timber.log.Timber -internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomMemberExtractor) { +internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomMemberExtractor, + private val cryptoService: CryptoService) { private val cached = mutableMapOf() @@ -30,11 +34,20 @@ internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomM val sender = eventEntity.sender val cacheKey = sender + eventEntity.stateIndex val senderData = cached.getOrPut(cacheKey) { - val senderRoomMember = roomMemberExtractor.extractFrom(eventEntity,realm) + val senderRoomMember = roomMemberExtractor.extractFrom(eventEntity, realm) SenderData(senderRoomMember?.displayName, senderRoomMember?.avatarUrl) } + val event = eventEntity.asDomain() + if (event.getClearType() == EventType.ENCRYPTED) { + try { + val result = cryptoService.decryptEvent(event, "TODO") + event.setClearData(result) + } catch (e: Exception) { + Timber.e(e) + } + } return TimelineEvent( - eventEntity.asDomain(), + event, eventEntity.localId, eventEntity.displayIndex, senderData.senderName, @@ -43,7 +56,7 @@ internal class TimelineEventFactory(private val roomMemberExtractor: SenderRoomM ) } - fun clear(){ + fun clear() { cached.clear() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt index bf03e097..c9f9235b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/CryptoSyncHandler.kt @@ -61,7 +61,7 @@ internal class CryptoSyncHandler(private val cryptoManager: CryptoManager, * @return true if the event has been decrypted */ private fun decryptEvent(event: Event, timelineId: String?): Boolean { - if (event.type == EventType.ENCRYPTED) { + if (event.getClearType() == EventType.ENCRYPTED) { var result: MXEventDecryptionResult? = null try { result = cryptoManager.decryptEvent(event, timelineId ?: "") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index 43ffb758..7963527c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -191,14 +191,14 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, roomId: String, ephemeral: RoomSyncEphemeral) { ephemeral.events - .filter { it.type == EventType.RECEIPT } + .filter { it.getClearType() == EventType.RECEIPT } .map { it.content.toModel() } .forEach { readReceiptHandler.handle(realm, roomId, it) } } private fun handleRoomAccountDataEvents(realm: Realm, roomId: String, accountData: RoomSyncAccountData) { accountData.events - .filter { it.type == EventType.TAG } + .filter { it.getClearType() == EventType.TAG } .map { it.content.toModel() } .forEach { roomTagHandler.handle(realm, roomId, it) } } diff --git a/vector/src/main/java/im/vector/riotredesign/core/services/EventStreamServiceX.kt b/vector/src/main/java/im/vector/riotredesign/core/services/EventStreamServiceX.kt index 8a105139..158a3f8e 100644 --- a/vector/src/main/java/im/vector/riotredesign/core/services/EventStreamServiceX.kt +++ b/vector/src/main/java/im/vector/riotredesign/core/services/EventStreamServiceX.kt @@ -87,7 +87,7 @@ class EventStreamServiceX : VectorService() { return } - if (EventType.CALL_INVITE == event.type) { + if (EventType.CALL_INVITE == event.getClearType()) { handleCallInviteEvent(event) return } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt index bf206623..64a0dbb0 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt @@ -215,7 +215,7 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter, items: List, addDaySeparator: Boolean, currentPosition: Int): MergedHeaderItem? { - return if (!event.canBeMerged() || (nextEvent?.root?.type == event.root.type && !addDaySeparator)) { + return if (!event.canBeMerged() || (nextEvent?.root?.getClearType() == event.root.getClearType() && !addDaySeparator)) { null } else { val prevSameTypeEvents = items.prevSameTypeEvents(currentPosition, 2) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt index ebe02f12..d4c29656 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageMenuViewModel.kt @@ -120,7 +120,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel true - else -> false + else -> false } } private fun canQuote(event: TimelineEvent, messageContent: MessageContent): Boolean { //Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment - if (event.root.type != EventType.MESSAGE) return false + if (event.root.getClearType() != EventType.MESSAGE) return false return when (messageContent.type) { MessageType.MSGTYPE_TEXT, MessageType.MSGTYPE_NOTICE, @@ -144,7 +144,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel { true } - else -> false + else -> false } } @@ -157,7 +157,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel { true } - else -> false + else -> false } } @@ -169,7 +169,7 @@ class MessageMenuViewModel(initialState: MessageMenuState) : VectorViewModel { true } - else -> false + else -> false } } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/CallItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/CallItemFactory.kt index 42f6ba0e..a2905fe2 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/CallItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/CallItemFactory.kt @@ -39,7 +39,7 @@ class CallItemFactory(private val stringProvider: StringProvider) { private fun buildNoticeText(event: Event, senderName: String?): CharSequence? { return when { - EventType.CALL_INVITE == event.type -> { + EventType.CALL_INVITE == event.getClearType() -> { val content = event.content.toModel() ?: return null val isVideoCall = content.offer.sdp == CallInviteContent.Offer.SDP_VIDEO return if (isVideoCall) { @@ -48,8 +48,8 @@ class CallItemFactory(private val stringProvider: StringProvider) { stringProvider.getString(R.string.notice_placed_voice_call, senderName) } } - EventType.CALL_ANSWER == event.type -> stringProvider.getString(R.string.notice_answered_call, senderName) - EventType.CALL_HANGUP == event.type -> stringProvider.getString(R.string.notice_ended_call, senderName) + EventType.CALL_ANSWER == event.getClearType() -> stringProvider.getString(R.string.notice_answered_call, senderName) + EventType.CALL_HANGUP == event.getClearType() -> stringProvider.getString(R.string.notice_ended_call, senderName) else -> null } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/DefaultItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/DefaultItemFactory.kt index 6b7c391e..c44af0ea 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/DefaultItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/DefaultItemFactory.kt @@ -24,7 +24,7 @@ class DefaultItemFactory { fun create(event: TimelineEvent, exception: Exception? = null): DefaultItem? { val text = if (exception == null) { - "${event.root.type} events are not yet handled" + "${event.root.getClearType()} events are not yet handled" } else { "an exception occurred when rendering the event ${event.root.eventId}" } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt index 25bb8d74..eff56072 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt @@ -22,10 +22,12 @@ import android.text.SpannableString import android.text.style.StyleSpan import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.MXCryptoError +import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.internal.crypto.MXDecryptionException import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult +import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.riotredesign.R import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.core.resources.StringProvider @@ -42,7 +44,7 @@ class EncryptedItemFactory( callback: TimelineEventController.Callback?): VectorEpoxyModel<*>? { return when { - EventType.ENCRYPTED == timelineEvent.root.type -> { + EventType.ENCRYPTED == timelineEvent.root.getClearType() -> { val decrypted: MXEventDecryptionResult? try { decrypted = session.decryptEvent(timelineEvent.root, "TODO") @@ -68,12 +70,12 @@ class EncryptedItemFactory( if (decrypted == null) { return null } - if (decrypted.mClearEvent == null) { return null } - - val decryptedTimelineEvent = timelineEvent.copy(root = decrypted.mClearEvent!!) + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val clearEvent = adapter.fromJsonValue(decrypted.mClearEvent) ?: return null + val decryptedTimelineEvent = timelineEvent.copy(root = clearEvent) // Success return messageItemFactory.create(decryptedTimelineEvent, nextEvent, callback) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt index 55ab6527..11a86850 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt @@ -38,7 +38,7 @@ class EncryptionItemFactory(private val stringProvider: StringProvider) { private fun buildNoticeText(event: Event, senderName: String?): CharSequence? { return when { - EventType.ENCRYPTION == event.type -> { + EventType.ENCRYPTION == event.getClearType() -> { val content = event.content.toModel() ?: return null stringProvider.getString(R.string.notice_end_to_end, senderName, content.algorithm) } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt index f8ba03de..de0d9977 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -63,10 +63,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider, val showInformation = addDaySeparator || event.senderAvatar != nextEvent?.senderAvatar || event.senderName != nextEvent?.senderName - || nextEvent?.root?.type != EventType.MESSAGE + || nextEvent?.root?.getClearType() != EventType.MESSAGE || isNextMessageReceivedMoreThanOneHourAgo - val messageContent: MessageContent = event.root.content.toModel() ?: return null + val messageContent: MessageContent = event.root.getClearContent().toModel() ?: return null val time = timelineDateFormatter.formatMessageHour(date) val avatarUrl = event.senderAvatar val memberName = event.senderName ?: event.root.sender ?: "" diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index 937dee53..905feccc 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -38,7 +38,7 @@ class TimelineItemFactory(private val messageItemFactory: MessageItemFactory, callback: TimelineEventController.Callback?): VectorEpoxyModel<*> { val computedModel = try { - when (event.root.type) { + when (event.root.getClearType()) { EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, callback) EventType.STATE_ROOM_NAME -> roomNameItemFactory.create(event) EventType.STATE_ROOM_TOPIC -> roomTopicItemFactory.create(event) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index 53d63f58..f7649bd7 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -40,7 +40,7 @@ object TimelineDisplayableEvents { } fun TimelineEvent.isDisplayable(): Boolean { - return TimelineDisplayableEvents.DISPLAYABLE_TYPES.contains(root.type) && !root.content.isNullOrEmpty() + return TimelineDisplayableEvents.DISPLAYABLE_TYPES.contains(root.getClearType()) && !root.content.isNullOrEmpty() } fun List.filterDisplayableEvents(): List { @@ -50,7 +50,7 @@ fun List.filterDisplayableEvents(): List { } fun TimelineEvent.canBeMerged(): Boolean { - return root.type == EventType.STATE_ROOM_MEMBER + return root.getClearType() == EventType.STATE_ROOM_MEMBER } fun List.nextSameTypeEvents(index: Int, minSize: Int): List { @@ -69,7 +69,7 @@ fun List.nextSameTypeEvents(index: Int, minSize: Int): List { return resolveMessageEvent(event, bingRule, session, store) } @@ -71,7 +71,7 @@ class NotifiableEventResolver(val context: Context) { description = body, soundName = bingRule?.notificationSound, title = context.getString(R.string.notification_unknown_new_event), - type = event.type) + type = event.getClearType()) } //Unsupported event @@ -172,7 +172,7 @@ class NotifiableEventResolver(val context: Context) { title = context.getString(R.string.notification_new_invitation), description = body, soundName = bingRule?.notificationSound, - type = event.type, + type = event.getClearType(), isPushGatewayEvent = false) } else { Timber.e("## unsupported notifiable event for eventId [${event.eventId}]")