diff --git a/changelog.d/5703.misc b/changelog.d/5703.misc new file mode 100644 index 00000000000..05e50804108 --- /dev/null +++ b/changelog.d/5703.misc @@ -0,0 +1 @@ +Reduce error logs \ No newline at end of file diff --git a/changelog.d/5703.sdk b/changelog.d/5703.sdk new file mode 100644 index 00000000000..ece1fec8e88 --- /dev/null +++ b/changelog.d/5703.sdk @@ -0,0 +1 @@ +KeysBackupService.getCurrentVersion takes a new type `KeysBackupLastVersionResult` in the callback. \ No newline at end of file diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt index 72493325c3f..d21e898c1da 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt index a9f062f3793..42d84ed535a 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 4c945662194..3326eab55d4 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -39,10 +39,11 @@ import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import java.util.Collections import java.util.concurrent.CountDownLatch @@ -403,9 +404,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync { + val keysVersionResult = testHelper.doSync { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -463,9 +464,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync { + val keysVersionResult = testHelper.doSync { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -565,9 +566,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync { + val keysVersionResult = testHelper.doSync { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -835,9 +836,9 @@ class KeysBackupTest : InstrumentedTest { keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) // Get key backup version from the homeserver - val keysVersionResult = testHelper.doSync { + val keysVersionResult = testHelper.doSync { keysBackup.getCurrentVersion(it) - } + }.toKeysVersionResult() // - Check the returned KeyBackupVersion is trusted val keysBackupVersionTrust = testHelper.doSync { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt index 89b4a343dd4..99fc0ba8b7c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt @@ -29,6 +29,11 @@ fun Throwable.is401() = httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED && /* 401 */ error.code == MatrixError.M_UNAUTHORIZED +fun Throwable.is404() = + this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_NOT_FOUND && /* 404 */ + error.code == MatrixError.M_NOT_FOUND + fun Throwable.isTokenError() = this is Failure.ServerError && (error.code == MatrixError.M_UNKNOWN_TOKEN || diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 4464427b903..1d9dbed3e23 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion @@ -31,9 +32,9 @@ interface KeysBackupService { * Retrieve the current version of the backup from the homeserver * * It can be different than keysBackupVersion. - * @param callback onSuccess(null) will be called if there is no backup on the server + * @param callback Asynchronous callback */ - fun getCurrentVersion(callback: MatrixCallback) + fun getCurrentVersion(callback: MatrixCallback) /** * Create a new keys backup version and enable it, using the information return from [prepareKeysBackupVersion]. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index f1304f62163..77661682972 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -202,7 +202,9 @@ data class Event( fun getDecryptedTextSummary(): String? { if (isRedacted()) return "Message Deleted" val text = getDecryptedValue() ?: run { - if (isPoll()) { return getPollQuestion() ?: "created a poll." } + if (isPoll()) { + return getPollQuestion() ?: "created a poll." + } return null } @@ -300,57 +302,67 @@ data class Event( } } +/** + * Return the value of "content.msgtype", if the Event type is "m.room.message" + * and if the content has it, and if it is a String + */ +fun Event.getMsgType(): String? { + if (getClearType() != EventType.MESSAGE) return null + return getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY) as? String +} + fun Event.isTextMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_TEXT, - MessageType.MSGTYPE_EMOTE, - MessageType.MSGTYPE_NOTICE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_TEXT, + MessageType.MSGTYPE_EMOTE, + MessageType.MSGTYPE_NOTICE -> true + else -> false + } } fun Event.isImageMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_IMAGE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_IMAGE -> true + else -> false + } } fun Event.isVideoMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_VIDEO -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_VIDEO -> true + else -> false + } } fun Event.isAudioMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_AUDIO -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_AUDIO -> true + else -> false + } } fun Event.isFileMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_FILE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_FILE -> true + else -> false + } } fun Event.isAttachmentMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_IMAGE, - MessageType.MSGTYPE_AUDIO, - MessageType.MSGTYPE_VIDEO, - MessageType.MSGTYPE_FILE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_IMAGE, + MessageType.MSGTYPE_AUDIO, + MessageType.MSGTYPE_VIDEO, + MessageType.MSGTYPE_FILE -> true + else -> false + } +} + +fun Event.isLocationMessage(): Boolean { + return when (getMsgType()) { + MessageType.MSGTYPE_LOCATION -> true + else -> false + } } fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START || getClearType() in EventType.POLL_END diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 954c2dbe431..f1182340f9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -41,6 +41,7 @@ import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.ObjectSigner import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData @@ -54,6 +55,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionDataTask @@ -586,21 +588,28 @@ internal class DefaultKeysBackupService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { try { - val keysBackupVersion = getKeysBackupLastVersionTask.execute(Unit) - val recoveryKey = computeRecoveryKey(secret.fromBase64()) - if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { - awaitCallback { - trustKeysBackupVersion(keysBackupVersion, true, it) + when (val keysBackupLastVersionResult = getKeysBackupLastVersionTask.execute(Unit)) { + KeysBackupLastVersionResult.NoKeysBackup -> { + Timber.d("No keys backup found") } - val importResult = awaitCallback { - restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) - } - withContext(coroutineDispatchers.crypto) { - cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) + is KeysBackupLastVersionResult.KeysBackup -> { + val keysBackupVersion = keysBackupLastVersionResult.keysVersionResult + val recoveryKey = computeRecoveryKey(secret.fromBase64()) + if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { + awaitCallback { + trustKeysBackupVersion(keysBackupVersion, true, it) + } + val importResult = awaitCallback { + restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) + } + withContext(coroutineDispatchers.crypto) { + cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) + } + Timber.i("onSecretKeyGossip: Recovered keys $importResult") + } else { + Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") + } } - Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") - } else { - Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") } } catch (failure: Throwable) { Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}") @@ -875,63 +884,49 @@ internal class DefaultKeysBackupService @Inject constructor( .executeBy(taskExecutor) } - override fun getCurrentVersion(callback: MatrixCallback) { + override fun getCurrentVersion(callback: MatrixCallback) { getKeysBackupLastVersionTask .configureWith { - this.callback = object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult) { - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError && - failure.error.code == MatrixError.M_NOT_FOUND) { - // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup - callback.onSuccess(null) - } else { - // Transmit the error - callback.onFailure(failure) - } - } - } + this.callback = callback } .executeBy(taskExecutor) } override fun forceUsingLastVersion(callback: MatrixCallback) { - getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { + getCurrentVersion(object : MatrixCallback { + override fun onSuccess(data: KeysBackupLastVersionResult) { val localBackupVersion = keysBackupVersion?.version - val serverBackupVersion = data?.version - - if (serverBackupVersion == null) { - if (localBackupVersion == null) { - // No backup on the server, and backup is not active - callback.onSuccess(true) - } else { - // No backup on the server, and we are currently backing up, so stop backing up - callback.onSuccess(false) - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Disabled - } - } else { - if (localBackupVersion == null) { - // backup on the server, and backup is not active - callback.onSuccess(false) - // Do a check - checkAndStartWithKeysBackupVersion(data) - } else { - // Backup on the server, and we are currently backing up, compare version - if (localBackupVersion == serverBackupVersion) { - // We are already using the last version of the backup + when (data) { + KeysBackupLastVersionResult.NoKeysBackup -> { + if (localBackupVersion == null) { + // No backup on the server, and backup is not active callback.onSuccess(true) } else { - // We are not using the last version, so delete the current version we are using on the server + // No backup on the server, and we are currently backing up, so stop backing up callback.onSuccess(false) + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Disabled + } + } + is KeysBackupLastVersionResult.KeysBackup -> { + if (localBackupVersion == null) { + // backup on the server, and backup is not active + callback.onSuccess(false) + // Do a check + checkAndStartWithKeysBackupVersion(data.keysVersionResult) + } else { + // Backup on the server, and we are currently backing up, compare version + if (localBackupVersion == data.keysVersionResult.version) { + // We are already using the last version of the backup + callback.onSuccess(true) + } else { + // We are not using the last version, so delete the current version we are using on the server + callback.onSuccess(false) - // This will automatically check for the last version then - deleteBackup(localBackupVersion, null) + // This will automatically check for the last version then + deleteBackup(localBackupVersion, null) + } } } } @@ -954,9 +949,9 @@ internal class DefaultKeysBackupService @Inject constructor( keysBackupVersion = null keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver - getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { - checkAndStartWithKeysBackupVersion(data) + getCurrentVersion(object : MatrixCallback { + override fun onSuccess(data: KeysBackupLastVersionResult) { + checkAndStartWithKeysBackupVersion(data.toKeysVersionResult()) } override fun onFailure(failure: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupLastVersionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupLastVersionResult.kt new file mode 100644 index 00000000000..72d6b45bbdc --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupLastVersionResult.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.keysbackup.model + +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult + +sealed interface KeysBackupLastVersionResult { + // No Keys backup found (404 error) + object NoKeysBackup : KeysBackupLastVersionResult + data class KeysBackup(val keysVersionResult: KeysVersionResult) : KeysBackupLastVersionResult +} + +fun KeysBackupLastVersionResult.toKeysVersionResult(): KeysVersionResult? = when (this) { + is KeysBackupLastVersionResult.KeysBackup -> keysVersionResult + KeysBackupLastVersionResult.NoKeysBackup -> null +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt index 54dbf85e302..a17ced11814 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt @@ -16,23 +16,34 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks +import org.matrix.android.sdk.api.failure.is404 import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject -internal interface GetKeysBackupLastVersionTask : Task +internal interface GetKeysBackupLastVersionTask : Task internal class DefaultGetKeysBackupLastVersionTask @Inject constructor( private val roomKeysApi: RoomKeysApi, private val globalErrorReceiver: GlobalErrorReceiver ) : GetKeysBackupLastVersionTask { - override suspend fun execute(params: Unit): KeysVersionResult { - return executeRequest(globalErrorReceiver) { - roomKeysApi.getKeysBackupLastVersion() + override suspend fun execute(params: Unit): KeysBackupLastVersionResult { + return try { + val keysVersionResult = executeRequest(globalErrorReceiver) { + roomKeysApi.getKeysBackupLastVersion() + } + KeysBackupLastVersionResult.KeysBackup(keysVersionResult) + } catch (throwable: Throwable) { + if (throwable.is404()) { + KeysBackupLastVersionResult.NoKeysBackup + } else { + // Propagate other errors + throw throwable + } } } } diff --git a/tools/check/check_code_quality.sh b/tools/check/check_code_quality.sh index 9535ff9efb2..af09dce9d4e 100755 --- a/tools/check/check_code_quality.sh +++ b/tools/check/check_code_quality.sh @@ -66,7 +66,7 @@ echo "Search for forbidden patterns in code..." ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code.txt \ ./matrix-sdk-android/src/main/java \ - ./matrix-sdk-android-rx/src/main/java \ + ./matrix-sdk-android-flow/src/main/java \ ./vector/src/main/java \ ./vector/src/debug/java \ ./vector/src/release/java \ @@ -80,7 +80,7 @@ echo "Search for forbidden patterns specific for SDK code..." ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code_sdk.txt \ ./matrix-sdk-android/src \ - ./matrix-sdk-android-rx/src + ./matrix-sdk-android-flow/src resultForbiddenStringInCodeSdk=$? @@ -131,7 +131,7 @@ echo "Search for kotlin files with more than ${maxLines} lines..." ${checkLongFilesScript} ${maxLines} \ ./matrix-sdk-android/src/main/java \ - ./matrix-sdk-android-rx/src/main/java \ + ./matrix-sdk-android-flow/src/main/java \ ./vector/src/androidTest/java \ ./vector/src/debug/java \ ./vector/src/fdroid/java \ diff --git a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt index 14ba34cc52c..b90956ad9e5 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt @@ -33,7 +33,7 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.glide.GlideApp import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.home.room.detail.timeline.action.LocationUiData import im.vector.app.features.home.room.detail.timeline.item.BindingOptions import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess import im.vector.app.features.media.ImageContentRenderer @@ -71,13 +71,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel GlideApp.with(holder.staticMapImageView) - .load(locationUrl) + .load(safeLocationUiData.locationUrl) .apply(RequestOptions.centerCropTransform()) .into(holder.staticMapImageView) - locationPinProvider?.create(locationOwnerId) { pinDrawable -> + safeLocationUiData.locationPinProvider.create(safeLocationUiData.locationOwnerId) { pinDrawable -> GlideApp.with(holder.staticMapPinImageView) .load(pinDrawable) .into(holder.staticMapPinImageView) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt index 8362a3566e5..3b7b2e91d63 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt @@ -32,7 +32,9 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.util.awaitCallback @@ -117,9 +119,9 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { try { - val version = awaitCallback { + val version = awaitCallback { keysBackup.getCurrentVersion(it) - } + }.toKeysVersionResult() if (version?.version == null) { loadingEvent.postValue(null) _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, ""))) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt index 1141886689a..3c78b72ff7e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt @@ -27,9 +27,10 @@ import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import timber.log.Timber import javax.inject.Inject @@ -150,9 +151,9 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() { creatingBackupError.value = null - keysBackup.getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { - if (data?.version.isNullOrBlank() || forceOverride) { + keysBackup.getCurrentVersion(object : MatrixCallback { + override fun onSuccess(data: KeysBackupLastVersionResult) { + if (data.toKeysVersionResult()?.version.isNullOrBlank() || forceOverride) { processOnCreate() } else { loadingStatus.value = null diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt index cc863346aa6..7c1685d30c5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -33,9 +33,10 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber @@ -221,10 +222,9 @@ class BootstrapCrossSigningTask @Inject constructor( Timber.d("## BootstrapCrossSigningTask: Creating 4S - Checking megolm backup") // First ensure that in sync - var serverVersion = awaitCallback { + var serverVersion = awaitCallback { session.cryptoService().keysBackupService().getCurrentVersion(it) - } - + }.toKeysVersionResult() val knownMegolmSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() val isMegolmBackupSecretKnown = knownMegolmSecret != null && knownMegolmSecret.version == serverVersion?.version val shouldCreateKeyBackup = serverVersion == null || @@ -236,9 +236,9 @@ class BootstrapCrossSigningTask @Inject constructor( awaitCallback { session.cryptoService().keysBackupService().deleteBackup(serverVersion!!.version, it) } - serverVersion = awaitCallback { + serverVersion = awaitCallback { session.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() } Timber.d("## BootstrapCrossSigningTask: Creating 4S - Create megolm backup") diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index 8b8a8faaef1..5fa77214fcc 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -45,7 +45,9 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth import org.matrix.android.sdk.internal.util.awaitCallback @@ -103,9 +105,9 @@ class BootstrapSharedViewModel @AssistedInject constructor( // We need to check if there is an existing backup viewModelScope.launch(Dispatchers.IO) { - val version = awaitCallback { + val version = awaitCallback { session.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() if (version == null) { // we just resume plain bootstrap doesKeyBackupExist = false diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 2495ae4ea5b..e347e4d91bb 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -52,7 +52,8 @@ import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupLastVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.toKeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.util.awaitCallback @@ -426,9 +427,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( Timber.v("## Keybackup secret not restored from SSSS") } - val version = awaitCallback { + val version = awaitCallback { session.cryptoService().keysBackupService().getCurrentVersion(it) - } ?: return@launch + }.toKeysVersionResult() ?: return@launch awaitCallback { session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt new file mode 100644 index 00000000000..c50c6492216 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 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.app.features.home.room.detail.timeline.action + +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider + +/** + * Data used to display Location data in the message bottom sheet + */ +data class LocationUiData( + val locationUrl: String, + val locationOwnerId: String?, + val locationPinProvider: LocationPinProvider, +) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index 307be220d3d..41916c609da 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -46,8 +46,8 @@ import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.session.events.model.isLocationMessage import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageLocationContent import org.matrix.android.sdk.api.session.room.send.SendState @@ -80,12 +80,7 @@ class MessageActionsEpoxyController @Inject constructor( val formattedDate = dateFormatter.format(date, DateFormatKind.MESSAGE_DETAIL) val body = state.messageBody.linkify(host.listener) val bindingOptions = spanUtils.getBindingOptions(body) - - val locationContent = state.timelineEvent()?.root?.getClearContent() - ?.toModel(catchError = true) - val locationUrl = locationContent?.toLocationData() - ?.let { urlMapProvider.buildStaticMapUrl(it, INITIAL_MAP_ZOOM_IN_TIMELINE, 1200, 800) } - val locationOwnerId = if (locationContent?.isSelfLocation().orTrue()) state.informationData.matrixItem.id else null + val locationUiData = buildLocationUiData(state) bottomSheetMessagePreviewItem { id("preview") @@ -99,9 +94,7 @@ class MessageActionsEpoxyController @Inject constructor( body(body.toEpoxyCharSequence()) bodyDetails(host.eventDetailsFormatter.format(state.timelineEvent()?.root)?.toEpoxyCharSequence()) time(formattedDate) - locationUrl(locationUrl) - locationPinProvider(host.locationPinProvider) - locationOwnerId(locationOwnerId) + locationUiData(locationUiData) } // Send state @@ -222,6 +215,23 @@ class MessageActionsEpoxyController @Inject constructor( } } + private fun buildLocationUiData(state: MessageActionState): LocationUiData? { + if (state.timelineEvent()?.root?.isLocationMessage() != true) return null + + val locationContent = state.timelineEvent()?.root?.getClearContent().toModel(catchError = true) + ?: return null + val locationUrl = locationContent.toLocationData() + ?.let { urlMapProvider.buildStaticMapUrl(it, INITIAL_MAP_ZOOM_IN_TIMELINE, 1200, 800) } + ?: return null + val locationOwnerId = if (locationContent.isSelfLocation()) state.informationData.matrixItem.id else null + + return LocationUiData( + locationUrl = locationUrl, + locationOwnerId = locationOwnerId, + locationPinProvider = locationPinProvider, + ) + } + private fun EventSharedAction.shouldShowBetaLabel(): Boolean = this is EventSharedAction.ReplyInThread && !vectorPreferences.areThreadMessagesEnabled()