From dadad3501b1d772367a384ea0bd25fb87e75bec5 Mon Sep 17 00:00:00 2001 From: yostyle Date: Wed, 17 May 2023 11:10:42 +0200 Subject: [PATCH 01/48] Allow stateloss on verification dialogfragment --- .../app/features/navigation/DefaultNavigator.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index d2628fcf0f..b38805f05a 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -38,6 +38,7 @@ import im.vector.app.config.OnboardingVariant import im.vector.app.core.debug.DebugNavigator import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.error.fatalError +import im.vector.app.core.extensions.commitTransaction import im.vector.app.features.VectorFeatures import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsViewRoom @@ -256,8 +257,9 @@ class DefaultNavigator @Inject constructor( otherSessionId ) if (context is AppCompatActivity) { - SelfVerificationBottomSheet.forTransaction(request.transactionId) - .show(context.supportFragmentManager, "VERIF") + context.supportFragmentManager.commitTransaction(allowStateLoss = true) { + add(SelfVerificationBottomSheet.forTransaction(request.transactionId), "VERIF") + } } } } @@ -271,8 +273,9 @@ class DefaultNavigator @Inject constructor( // .filter { it.deviceId != session.sessionParams.deviceId } // .map { it.deviceId } if (context is AppCompatActivity) { - SelfVerificationBottomSheet.verifyOwnUntrustedDevice() - .show(context.supportFragmentManager, "VERIF") + context.supportFragmentManager.commitTransaction(allowStateLoss = true) { + add(SelfVerificationBottomSheet.verifyOwnUntrustedDevice(), "VERIF") + } // if (otherSessions.isNotEmpty()) { // val pr = session.cryptoService().verificationService().requestSelfKeyVerification( // supportedVerificationMethodsProvider.provide()) From d6028b75c9f2aa001df8113c80406a885580878f Mon Sep 17 00:00:00 2001 From: yostyle Date: Wed, 17 May 2023 11:17:54 +0200 Subject: [PATCH 02/48] Add changelog --- changelog.d/8439.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/8439.bugfix diff --git a/changelog.d/8439.bugfix b/changelog.d/8439.bugfix new file mode 100644 index 0000000000..c271f185c9 --- /dev/null +++ b/changelog.d/8439.bugfix @@ -0,0 +1 @@ +Allow stateloss on verification dialogfragment From 134992cf0d18908de6eb874871cefbfd63d204ce Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 12:10:23 +0200 Subject: [PATCH 03/48] Setting version for the release 1.6.0 --- matrix-sdk-android/build.gradle | 2 +- vector-app/build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 9c230bb400..3c1f970bee 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -63,7 +63,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.5.34\"" + buildConfigField "String", "SDK_VERSION", "\"1.6.0\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 2abf6526d2..ebcc9c76ac 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -33,11 +33,11 @@ knit { // Note: 2 digits max for each value ext.versionMajor = 1 -ext.versionMinor = 5 +ext.versionMinor = 6 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 34 +ext.versionPatch = 0 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 120053a018914de87a734bf51a329a07bc0e2df7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 12:22:08 +0200 Subject: [PATCH 04/48] Update the release script to release the flavor `rustCrypto`. --- tools/release/releaseScript.sh | 56 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index cf9671c1dc..e140560e52 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -160,11 +160,11 @@ adb -e uninstall im.vector.app.debug.test printf "\n================================================================================\n" printf "Running the integration test UiAllScreensSanityTest.allScreensTest()...\n" -./gradlew connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest +./gradlew connectedGplayRustCryptoDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest printf "\n================================================================================\n" printf "Building the app...\n" -./gradlew assembleGplayDebug +./gradlew assembleGplayRustCryptoDebug printf "\n================================================================================\n" printf "Uninstalling previous debug app if any...\n" @@ -172,7 +172,7 @@ adb -e uninstall im.vector.app.debug printf "\n================================================================================\n" printf "Installing the app...\n" -adb -e install ./vector-app/build/outputs/apk/gplay/debug/vector-gplay-arm64-v8a-debug.apk +adb -e install ./vector-app/build/outputs/apk/gplayRustCrypto/debug/vector-gplay-rustCrypto-arm64-v8a-debug.apk printf "\n================================================================================\n" printf "Running the app...\n" @@ -267,7 +267,7 @@ fi printf "\n================================================================================\n" printf "Wait for the GitHub action https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%%3Amain to build the 'main' branch.\n" -read -p "After GHA is finished, please enter the artifact URL (for 'vector-gplay-release-unsigned'): " artifactUrl +read -p "After GHA is finished, please enter the artifact URL (for 'vector-gplay-rustCrypto-release-unsigned'): " artifactUrl printf "\n================================================================================\n" printf "Downloading the artifact...\n" @@ -290,70 +290,70 @@ set -e printf "\n================================================================================\n" printf "Unzipping the artifact...\n" -unzip ${targetPath}/vector-gplay-release-unsigned.zip -d ${targetPath} +unzip ${targetPath}/vector-gplay-rustCrypto-release-unsigned.zip -d ${targetPath} # Flatten folder hierarchy -mv ${targetPath}/gplay/release/* ${targetPath} +mv ${targetPath}/gplayRustCrypto/release/* ${targetPath} rm -rf ${targetPath}/gplay printf "\n================================================================================\n" printf "Signing the APKs...\n" -cp ${targetPath}/vector-gplay-arm64-v8a-release-unsigned.apk \ - ${targetPath}/vector-gplay-arm64-v8a-release-signed.apk +cp ${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-unsigned.apk \ + ${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-signed.apk ./tools/release/sign_apk_unsafe.sh \ ${keyStorePath} \ - ${targetPath}/vector-gplay-arm64-v8a-release-signed.apk \ + ${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-signed.apk \ ${keyStorePassword} \ ${keyPassword} -cp ${targetPath}/vector-gplay-armeabi-v7a-release-unsigned.apk \ - ${targetPath}/vector-gplay-armeabi-v7a-release-signed.apk +cp ${targetPath}/vector-gplay-rustCrypto-armeabi-v7a-release-unsigned.apk \ + ${targetPath}/vector-gplay-rustCrypto-armeabi-v7a-release-signed.apk ./tools/release/sign_apk_unsafe.sh \ ${keyStorePath} \ - ${targetPath}/vector-gplay-armeabi-v7a-release-signed.apk \ + ${targetPath}/vector-gplay-rustCrypto-armeabi-v7a-release-signed.apk \ ${keyStorePassword} \ ${keyPassword} -cp ${targetPath}/vector-gplay-x86-release-unsigned.apk \ - ${targetPath}/vector-gplay-x86-release-signed.apk +cp ${targetPath}/vector-gplay-rustCrypto-x86-release-unsigned.apk \ + ${targetPath}/vector-gplay-rustCrypto-x86-release-signed.apk ./tools/release/sign_apk_unsafe.sh \ ${keyStorePath} \ - ${targetPath}/vector-gplay-x86-release-signed.apk \ + ${targetPath}/vector-gplay-rustCrypto-x86-release-signed.apk \ ${keyStorePassword} \ ${keyPassword} -cp ${targetPath}/vector-gplay-x86_64-release-unsigned.apk \ - ${targetPath}/vector-gplay-x86_64-release-signed.apk +cp ${targetPath}/vector-gplay-rustCrypto-x86_64-release-unsigned.apk \ + ${targetPath}/vector-gplay-rustCrypto-x86_64-release-signed.apk ./tools/release/sign_apk_unsafe.sh \ ${keyStorePath} \ - ${targetPath}/vector-gplay-x86_64-release-signed.apk \ + ${targetPath}/vector-gplay-rustCrypto-x86_64-release-signed.apk \ ${keyStorePassword} \ ${keyPassword} # Ref: https://docs.fastlane.tools/getting-started/android/beta-deployment/#uploading-your-app -# set SUPPLY_APK_PATHS="${targetPath}/vector-gplay-arm64-v8a-release-unsigned.apk,${targetPath}/vector-gplay-armeabi-v7a-release-unsigned.apk,${targetPath}/vector-gplay-x86-release-unsigned.apk,${targetPath}/vector-gplay-x86_64-release-unsigned.apk" +# set SUPPLY_APK_PATHS="${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-unsigned.apk,${targetPath}/vector-gplay-rustCrypto-armeabi-v7a-release-unsigned.apk,${targetPath}/vector-gplay-rustCrypto-x86-release-unsigned.apk,${targetPath}/vector-gplay-rustCrypto-x86_64-release-unsigned.apk" # # ./fastlane beta printf "\n================================================================================\n" printf "Please check the information below:\n" -printf "File vector-gplay-arm64-v8a-release-signed.apk:\n" -${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-arm64-v8a-release-signed.apk | grep package -printf "File vector-gplay-armeabi-v7a-release-signed.apk:\n" -${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-armeabi-v7a-release-signed.apk | grep package -printf "File vector-gplay-x86-release-signed.apk:\n" -${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-x86-release-signed.apk | grep package -printf "File vector-gplay-x86_64-release-signed.apk:\n" -${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-x86_64-release-signed.apk | grep package +printf "File vector-gplay-rustCrypto-arm64-v8a-release-signed.apk:\n" +${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-signed.apk | grep package +printf "File vector-gplay-rustCrypto-armeabi-v7a-release-signed.apk:\n" +${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-rustCrypto-armeabi-v7a-release-signed.apk | grep package +printf "File vector-gplay-rustCrypto-x86-release-signed.apk:\n" +${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-rustCrypto-x86-release-signed.apk | grep package +printf "File vector-gplay-rustCrypto-x86_64-release-signed.apk:\n" +${buildToolsPath}/aapt dump badging ${targetPath}/vector-gplay-rustCrypto-x86_64-release-signed.apk | grep package printf "\n" read -p "Does it look correct? Press enter when it's done." printf "\n================================================================================\n" read -p "Installing apk on a real device, press enter when a real device is connected. " -apkPath="${targetPath}/vector-gplay-arm64-v8a-release-signed.apk" +apkPath="${targetPath}/vector-gplay-rustCrypto-arm64-v8a-release-signed.apk" adb -d install ${apkPath} read -p "Please run the APK on your phone to check that the upgrade went well (no init sync, etc.). Press enter when it's done." From 6e27ffc3cff01002b80588b86b13995053d7463c Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 17 May 2023 12:41:11 +0200 Subject: [PATCH 05/48] Add more migration logs --- .../internal/crypto/store/db/migration/rust/ExtractUtils.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt index 608f68fc3d..d99403fe19 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/migration/rust/ExtractUtils.kt @@ -71,6 +71,10 @@ fun RealmToMigrate.getPickledAccount(pickleKey: ByteArray): MigrationData { val userKey = metadataEntity.xSignUserPrivateKey val selfSignedKey = metadataEntity.xSignSelfSignedPrivateKey + Timber.i("## Migration: has private MSK ${masterKey.isNullOrBlank().not()}") + Timber.i("## Migration: has private USK ${userKey.isNullOrBlank().not()}") + Timber.i("## Migration: has private SSK ${selfSignedKey.isNullOrBlank().not()}") + val userId = metadataEntity.userId ?: throw java.lang.IllegalArgumentException("Rust db migration: userId is null") val deviceId = metadataEntity.deviceId @@ -79,6 +83,8 @@ fun RealmToMigrate.getPickledAccount(pickleKey: ByteArray): MigrationData { val backupVersion = metadataEntity.backupVersion val backupRecoveryKey = metadataEntity.keyBackupRecoveryKey + Timber.i("## Migration: has private backup key ${backupRecoveryKey != null} for version $backupVersion") + val isOlmAccountShared = metadataEntity.deviceKeysSentToServer val olmAccount = metadataEntity.getOlmAccount() From ec9b56d19af552ca596506a77adc232c0f094044 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 14:52:43 +0200 Subject: [PATCH 06/48] Changelog for version 1.6.0 --- CHANGES.md | 36 ++++++++++++++++++++++++++++++++++++ changelog.d/748.bugfix | 1 - changelog.d/7619.bugfix | 1 - changelog.d/7628.sdk | 1 - changelog.d/8325.feature | 1 - changelog.d/8327.bugfix | 1 - changelog.d/8339.misc | 1 - changelog.d/8340.misc | 1 - changelog.d/8352.bugfix | 1 - changelog.d/8354.misc | 1 - changelog.d/8364.misc | 1 - changelog.d/8365.misc | 1 - changelog.d/8366.misc | 1 - changelog.d/8376.bugfix | 1 - changelog.d/8390.feature | 1 - changelog.d/8402.misc | 1 - changelog.d/8405.sdk | 1 - changelog.d/8410.bugfix | 1 - changelog.d/8418.bugfix | 1 - changelog.d/8426.misc | 1 - changelog.d/8436.misc | 1 - 21 files changed, 36 insertions(+), 20 deletions(-) delete mode 100644 changelog.d/748.bugfix delete mode 100644 changelog.d/7619.bugfix delete mode 100644 changelog.d/7628.sdk delete mode 100644 changelog.d/8325.feature delete mode 100644 changelog.d/8327.bugfix delete mode 100644 changelog.d/8339.misc delete mode 100644 changelog.d/8340.misc delete mode 100644 changelog.d/8352.bugfix delete mode 100644 changelog.d/8354.misc delete mode 100644 changelog.d/8364.misc delete mode 100644 changelog.d/8365.misc delete mode 100644 changelog.d/8366.misc delete mode 100644 changelog.d/8376.bugfix delete mode 100644 changelog.d/8390.feature delete mode 100644 changelog.d/8402.misc delete mode 100644 changelog.d/8405.sdk delete mode 100644 changelog.d/8410.bugfix delete mode 100644 changelog.d/8418.bugfix delete mode 100644 changelog.d/8426.misc delete mode 100644 changelog.d/8436.misc diff --git a/CHANGES.md b/CHANGES.md index 905f178526..e5ce4dc1ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,39 @@ +Changes in Element v1.6.0 (2023-05-17) +====================================== + +Features ✨ +---------- + - **Element Android is now using the Crypto Rust SDK**. Migration of user's data should be done at first launch after application upgrade. ([#8390](https://github.com/vector-im/element-android/issues/8390)) + - Enable free style cropping for camera and gallery images ([#8325](https://github.com/vector-im/element-android/issues/8325)) + +Bugfixes 🐛 +---------- + - User pills get lost at message editing ([#748](https://github.com/vector-im/element-android/issues/748)) + - Upgrade Jitsi SDK from 6.2.2 to 8.1.1. This fixes video call on some Android devices. ([#7619](https://github.com/vector-im/element-android/issues/7619)) + - Fix duplicate reactions when using full emoji picker. Contributed by @tulir @ Beeper. ([#8327](https://github.com/vector-im/element-android/issues/8327)) + - Fix: RustCrossSigning service API confusion (identity trusted vs own device trusted by identity) ([#8352](https://github.com/vector-im/element-android/issues/8352)) + - Allow custom push gateway to use non-default port ([#8376](https://github.com/vector-im/element-android/issues/8376)) + - Fix crash when opening "Protect access" screen, and various other issue with `repeatOnLifecycle` ([#8410](https://github.com/vector-im/element-android/issues/8410)) + - RustCrypto: Verification UX not refreshed after scanning a QR code ([#8418](https://github.com/vector-im/element-android/issues/8418)) + +SDK API changes ⚠️ +------------------ + - First integration of rust crypto module. See documentation for details `docs/rust_crypto_integration.md` ([#7628](https://github.com/vector-im/element-android/issues/7628)) + - Add crypto database migration 22, that extract account and olm session to the new rust DB format ([#8405](https://github.com/vector-im/element-android/issues/8405)) + +Other changes +------------- + - Add an audio alert when the voice broadcast recording is automatically paused ([#8339](https://github.com/vector-im/element-android/issues/8339)) + - Analytics: add crypto module to E2E events ([#8340](https://github.com/vector-im/element-android/issues/8340)) + - Bump rust crypto crate to 0.3.5 ([#8354](https://github.com/vector-im/element-android/issues/8354)) + - Expose Rust SDK Version in Help & About page and in Bug Reports ([#8364](https://github.com/vector-im/element-android/issues/8364)) + - Matrix-Ids are sometimes shown in notice events instead of display names ([#8365](https://github.com/vector-im/element-android/issues/8365)) + - CI: Add workflow to run test with crypto flavor ([#8366](https://github.com/vector-im/element-android/issues/8366)) + - Remove ability to migrate session from Riot to Element. ([#8402](https://github.com/vector-im/element-android/issues/8402)) + - Improve keyboard navigation and accessibility when using a screen reader. ([#8426](https://github.com/vector-im/element-android/issues/8426)) + - Updated posthog url (cosmetic, target same server) and added a new sentry env. ([#8436](https://github.com/vector-im/element-android/issues/8436)) + + Changes in Element v1.5.32 (2023-04-19) ======================================= diff --git a/changelog.d/748.bugfix b/changelog.d/748.bugfix deleted file mode 100644 index cc33be0033..0000000000 --- a/changelog.d/748.bugfix +++ /dev/null @@ -1 +0,0 @@ -User pills get lost at message editing \ No newline at end of file diff --git a/changelog.d/7619.bugfix b/changelog.d/7619.bugfix deleted file mode 100644 index a41cf5321f..0000000000 --- a/changelog.d/7619.bugfix +++ /dev/null @@ -1 +0,0 @@ -Upgrade Jitsi SDK from 6.2.2 to 8.1.1. This fixes video call on some Android devices. diff --git a/changelog.d/7628.sdk b/changelog.d/7628.sdk deleted file mode 100644 index d9886730fd..0000000000 --- a/changelog.d/7628.sdk +++ /dev/null @@ -1 +0,0 @@ -First integration of rust crypto module. See documentation for details `docs/rust_crypto_integration.md` diff --git a/changelog.d/8325.feature b/changelog.d/8325.feature deleted file mode 100644 index 59e57838f8..0000000000 --- a/changelog.d/8325.feature +++ /dev/null @@ -1 +0,0 @@ -Enable free style cropping for camera and gallery images diff --git a/changelog.d/8327.bugfix b/changelog.d/8327.bugfix deleted file mode 100644 index d1e57f4c16..0000000000 --- a/changelog.d/8327.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix duplicate reactions when using full emoji picker. Contributed by @tulir @ Beeper. diff --git a/changelog.d/8339.misc b/changelog.d/8339.misc deleted file mode 100644 index 2fed9c438b..0000000000 --- a/changelog.d/8339.misc +++ /dev/null @@ -1 +0,0 @@ -Add an audio alert when the voice broadcast recording is automatically paused diff --git a/changelog.d/8340.misc b/changelog.d/8340.misc deleted file mode 100644 index 52556b5b42..0000000000 --- a/changelog.d/8340.misc +++ /dev/null @@ -1 +0,0 @@ -Analytics: add crypto module to E2E events diff --git a/changelog.d/8352.bugfix b/changelog.d/8352.bugfix deleted file mode 100644 index 695c02715e..0000000000 --- a/changelog.d/8352.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix: RustCrossSigning service API confusion (identity trusted vs own device trusted by identity) diff --git a/changelog.d/8354.misc b/changelog.d/8354.misc deleted file mode 100644 index f26be92ed6..0000000000 --- a/changelog.d/8354.misc +++ /dev/null @@ -1 +0,0 @@ -Bump rust crypto crate to 0.3.5 diff --git a/changelog.d/8364.misc b/changelog.d/8364.misc deleted file mode 100644 index 27bf6b975a..0000000000 --- a/changelog.d/8364.misc +++ /dev/null @@ -1 +0,0 @@ -Expose Rust SDK Version in Help & About page and in Bug Reports diff --git a/changelog.d/8365.misc b/changelog.d/8365.misc deleted file mode 100644 index ef9bbdca04..0000000000 --- a/changelog.d/8365.misc +++ /dev/null @@ -1 +0,0 @@ -Matrix-Ids are sometimes shown in notice events instead of display names diff --git a/changelog.d/8366.misc b/changelog.d/8366.misc deleted file mode 100644 index 87c5271688..0000000000 --- a/changelog.d/8366.misc +++ /dev/null @@ -1 +0,0 @@ -CI: Add workflow to run test with crypto flavor diff --git a/changelog.d/8376.bugfix b/changelog.d/8376.bugfix deleted file mode 100644 index 2c30a1e540..0000000000 --- a/changelog.d/8376.bugfix +++ /dev/null @@ -1 +0,0 @@ -Allow custom push gateway to use non-default port \ No newline at end of file diff --git a/changelog.d/8390.feature b/changelog.d/8390.feature deleted file mode 100644 index cc430a5a42..0000000000 --- a/changelog.d/8390.feature +++ /dev/null @@ -1 +0,0 @@ -Element Android is now using the Crypto Rust SDK. Migration of user's data should be done at first launch after application upgrade. diff --git a/changelog.d/8402.misc b/changelog.d/8402.misc deleted file mode 100644 index c493b6bf92..0000000000 --- a/changelog.d/8402.misc +++ /dev/null @@ -1 +0,0 @@ -Remove ability to migrate session from Riot to Element. diff --git a/changelog.d/8405.sdk b/changelog.d/8405.sdk deleted file mode 100644 index c8d165fcdc..0000000000 --- a/changelog.d/8405.sdk +++ /dev/null @@ -1 +0,0 @@ -Add crypto database migration 22, that extract account and olm session to the new rust DB format diff --git a/changelog.d/8410.bugfix b/changelog.d/8410.bugfix deleted file mode 100644 index f72d02e0b4..0000000000 --- a/changelog.d/8410.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash when opening "Protect access" screen, and various other issue with `repeatOnLifecycle` diff --git a/changelog.d/8418.bugfix b/changelog.d/8418.bugfix deleted file mode 100644 index 9b5a2e2fa4..0000000000 --- a/changelog.d/8418.bugfix +++ /dev/null @@ -1 +0,0 @@ -RustCrypto: Verification UX not refreshed after scanning a QR code diff --git a/changelog.d/8426.misc b/changelog.d/8426.misc deleted file mode 100644 index 6e3b5013c8..0000000000 --- a/changelog.d/8426.misc +++ /dev/null @@ -1 +0,0 @@ -Improve keyboard navigation and accessibility when using a screen reader. diff --git a/changelog.d/8436.misc b/changelog.d/8436.misc deleted file mode 100644 index ab174eca5b..0000000000 --- a/changelog.d/8436.misc +++ /dev/null @@ -1 +0,0 @@ -Updated posthog url (cosmetic, target same server) and added a new sentry env. From 8d6d10206bbb6ce24580fba7bdc695ea4ce3234e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 14:53:32 +0200 Subject: [PATCH 07/48] Adding fastlane file for version 1.6.0 --- fastlane/metadata/android/en-US/changelogs/40106000.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40106000.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40106000.txt b/fastlane/metadata/android/en-US/changelogs/40106000.txt new file mode 100644 index 0000000000..badf979955 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40106000.txt @@ -0,0 +1,2 @@ +Main changes in this version: Element Android is now using the Crypto Rust SDK. +Full changelog: https://github.com/vector-im/element-android/releases From 66aa4226b59a9f529e391fc062e24ecc8c9b2f0a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 14:55:30 +0200 Subject: [PATCH 08/48] version++ --- matrix-sdk-android/build.gradle | 2 +- vector-app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 3c1f970bee..6328c1ceac 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -63,7 +63,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.6.0\"" + buildConfigField "String", "SDK_VERSION", "\"1.6.2\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index ebcc9c76ac..9a2506391e 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -37,7 +37,7 @@ ext.versionMinor = 6 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 0 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From aecdd475d8c8f30020633b94311ecf50f4a0080f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 17 May 2023 16:37:08 +0200 Subject: [PATCH 09/48] Update the release script to release the flavor `rustCrypto` - small revert --- tools/release/releaseScript.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index e140560e52..f198670eae 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -267,7 +267,7 @@ fi printf "\n================================================================================\n" printf "Wait for the GitHub action https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%%3Amain to build the 'main' branch.\n" -read -p "After GHA is finished, please enter the artifact URL (for 'vector-gplay-rustCrypto-release-unsigned'): " artifactUrl +read -p "After GHA is finished, please enter the artifact URL (for 'vector-gplay-release-unsigned'): " artifactUrl printf "\n================================================================================\n" printf "Downloading the artifact...\n" @@ -290,7 +290,7 @@ set -e printf "\n================================================================================\n" printf "Unzipping the artifact...\n" -unzip ${targetPath}/vector-gplay-rustCrypto-release-unsigned.zip -d ${targetPath} +unzip ${targetPath}/vector-gplay-release-unsigned.zip -d ${targetPath} # Flatten folder hierarchy mv ${targetPath}/gplayRustCrypto/release/* ${targetPath} From 705b17e7f1014105372eb9344d1d9de5f74126e0 Mon Sep 17 00:00:00 2001 From: valere Date: Mon, 22 May 2023 19:26:05 +0200 Subject: [PATCH 10/48] fix always returning live devices for current user --- .../matrix/android/sdk/internal/crypto/RustCryptoService.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index 4769d57dc9..6d96c2c836 100755 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -360,9 +360,7 @@ internal class RustCryptoService @Inject constructor( } override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { - return olmMachine.getLiveDevices(listOf(myUserId)).map { - it.filter { it.userId == myUserId } - } + return olmMachine.getLiveDevices(userIds) } override fun getLiveCryptoDeviceInfoWithId(deviceId: String): LiveData> { From 517af968e6b923cc8bd9a9a743e1367ca857899f Mon Sep 17 00:00:00 2001 From: valere Date: Mon, 22 May 2023 22:26:26 +0200 Subject: [PATCH 11/48] Remove legacy manually verify specific other device --- .../src/main/res/values/strings.xml | 4 +++- .../devices/DeviceListAction.kt | 2 -- .../devices/DeviceListBottomSheet.kt | 11 +-------- .../DeviceListBottomSheetViewEvents.kt | 4 +--- .../devices/DeviceListBottomSheetViewModel.kt | 21 ++--------------- .../devices/DeviceTrustInfoActionFragment.kt | 5 ---- .../devices/DeviceTrustInfoEpoxyController.kt | 23 +++---------------- .../features/settings/devices/TrustUtils.kt | 2 ++ 8 files changed, 12 insertions(+), 60 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 3d1a36d4c3..bc29627bf9 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2465,7 +2465,9 @@ This session is trusted for secure messaging because %1$s (%2$s) verified it: %1$s (%2$s) signed in using a new session: - Until this user trusts this session, messages sent to and from it are labeled with warnings. Alternatively, you can manually verify it. + + Until this user trusts this session, messages sent to and from it are labeled with warnings. Alternatively, you can manually verify it. + Until this user trusts this session, messages sent to and from it are labeled with warnings. Initialize CrossSigning diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt index c269a4166a..09ae73a55c 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt @@ -22,6 +22,4 @@ import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo sealed class DeviceListAction : VectorViewModelAction { data class SelectDevice(val device: CryptoDeviceInfo) : DeviceListAction() object DeselectDevice : DeviceListAction() - - data class ManuallyVerify(val deviceId: String) : DeviceListAction() } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt index 2a0ca4850e..2dbb03121d 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt @@ -47,16 +47,7 @@ class DeviceListBottomSheet : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.observeViewEvents { - when (it) { - is DeviceListBottomSheetViewEvents.Verify -> { - // TODO selfverif -// VerificationBottomSheet.withArgs( -// // roomId = null, -// otherUserId = it.userId, -// transactionId = it.txID -// ).show(requireActivity().supportFragmentManager, "REQPOP") - } - } + // nop } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewEvents.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewEvents.kt index 8c6cba6cd9..159f505e16 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewEvents.kt @@ -21,6 +21,4 @@ import im.vector.app.core.platform.VectorViewEvents /** * Transient events for device list screen. */ -sealed class DeviceListBottomSheetViewEvents : VectorViewEvents { - data class Verify(val userId: String, val txID: String) : DeviceListBottomSheetViewEvents() -} +sealed class DeviceListBottomSheetViewEvents : VectorViewEvents diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index c3281858f0..435c44aa11 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -34,7 +34,6 @@ import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem @@ -42,7 +41,7 @@ import org.matrix.android.sdk.flow.flow data class DeviceListViewState( val userId: String, - val allowDeviceAction: Boolean, + val myUserId: String, val userItem: MatrixItem? = null, val memberCrossSigningKey: MXCrossSigningInfo? = null, val myDeviceId: String = "", @@ -69,7 +68,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor( val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() return DeviceListViewState( userId = userId, - allowDeviceAction = args.allowDeviceAction, + myUserId = session.myUserId, userItem = session.getUserOrDefault(userId).toMatrixItem(), myDeviceId = session.sessionParams.deviceId, ) @@ -104,7 +103,6 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor( when (action) { is DeviceListAction.SelectDevice -> selectDevice(action) is DeviceListAction.DeselectDevice -> deselectDevice() - is DeviceListAction.ManuallyVerify -> manuallyVerify(action) } } @@ -121,7 +119,6 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor( } private fun selectDevice(action: DeviceListAction.SelectDevice) { - if (!initialState.allowDeviceAction) return setState { copy(selectedDevice = action.device) } @@ -132,18 +129,4 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor( copy(selectedDevice = null) } } - - private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) { - if (!initialState.allowDeviceAction) return - viewModelScope.launch { - session.cryptoService().verificationService().requestDeviceVerification( - methods = listOf(VerificationMethod.SAS), - otherUserId = initialState.userId, - otherDeviceId = action.deviceId, - ).transactionId - .let { txID -> - _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID)) - } - } - } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt index d8abd91091..d3b5a25913 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt @@ -28,7 +28,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.BottomSheetGenericListBinding -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import javax.inject.Inject @AndroidEntryPoint @@ -63,8 +62,4 @@ class DeviceTrustInfoActionFragment : override fun invalidate() = withState(viewModel) { epoxyController.setData(it) } - - override fun onVerifyManually(device: CryptoDeviceInfo) { - viewModel.handle(DeviceListAction.ManuallyVerify(device.deviceId)) - } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt index 20c388dd95..0f39fc889c 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt @@ -25,13 +25,10 @@ import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.core.ui.list.genericItem import im.vector.app.core.ui.list.genericWithValueItem import im.vector.app.core.utils.DimensionConverter -import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem -import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.devices.TrustUtils import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject @@ -39,13 +36,10 @@ class DeviceTrustInfoEpoxyController @Inject constructor( private val stringProvider: StringProvider, private val colorProvider: ColorProvider, private val dimensionConverter: DimensionConverter, - private val vectorPreferences: VectorPreferences ) : TypedEpoxyController() { - interface InteractionListener { - fun onVerifyManually(device: CryptoDeviceInfo) - } + interface InteractionListener var interactionListener: InteractionListener? = null @@ -54,7 +48,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor( data?.selectedDevice?.let { cryptoDeviceInfo -> val trustMSK = data.memberCrossSigningKey?.isTrusted().orFalse() val legacyMode = data.memberCrossSigningKey == null - val isMyDevice = data.myDeviceId == cryptoDeviceInfo.deviceId + val isMyDevice = data.userId == data.myUserId && data.myDeviceId == cryptoDeviceInfo.deviceId val trustLevel = TrustUtils.shieldForTrust( isMyDevice, trustMSK, @@ -126,18 +120,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor( id("warn") centered(false) textColor(host.colorProvider.getColorFromAttribute(R.attr.vctr_content_primary)) - text(host.stringProvider.getString(R.string.verification_profile_device_untrust_info).toEpoxyCharSequence()) - } - - bottomSheetVerificationActionItem { - id("verify") - title(host.stringProvider.getString(R.string.cross_signing_verify_by_emoji)) - titleColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) - iconRes(R.drawable.ic_arrow_right) - iconColor(host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)) - listener { - host.interactionListener?.onVerifyManually(cryptoDeviceInfo) - } + text(host.stringProvider.getString(R.string.verification_profile_other_device_untrust_info).toEpoxyCharSequence()) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt index 7709a63344..983790c80a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt @@ -22,6 +22,8 @@ import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel // TODO Replace usage by the use case GetEncryptionTrustLevelForDeviceUseCase object TrustUtils { + // XXX why is this using the RoomEncryptionTrustLevel? + // should be using a new DeviceTrustShield enum fun shieldForTrust( currentDevice: Boolean, trustMSK: Boolean, From 94956a2ec64b78be79572dfc85218f5ddcf69338 Mon Sep 17 00:00:00 2001 From: valere Date: Mon, 22 May 2023 22:37:37 +0200 Subject: [PATCH 12/48] Add change log --- changelog.d/8458.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/8458.misc diff --git a/changelog.d/8458.misc b/changelog.d/8458.misc new file mode 100644 index 0000000000..ba32317523 --- /dev/null +++ b/changelog.d/8458.misc @@ -0,0 +1 @@ +Remove UI option to manually verify a specific device of another user (deprecated behaviour) From ccf77eb05ab83c57dd6e5d275ba74714cd892897 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 23:59:34 +0000 Subject: [PATCH 13/48] Bump com.likethesalad.android:stem-plugin from 2.4.0 to 2.4.1 Bumps com.likethesalad.android:stem-plugin from 2.4.0 to 2.4.1. --- updated-dependencies: - dependency-name: com.likethesalad.android:stem-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3060747977..a70b54a833 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ buildscript { classpath 'com.google.gms:google-services:4.3.15' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6' - classpath "com.likethesalad.android:stem-plugin:2.4.0" + classpath "com.likethesalad.android:stem-plugin:2.4.1" classpath 'org.owasp:dependency-check-gradle:8.2.1' classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.8.10" classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0" From b98d6ca55b6b7154fa48dacffc33d6848477d546 Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 23 May 2023 08:08:02 +0200 Subject: [PATCH 14/48] Add changelog --- vector-app/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 9a2506391e..71e2c589e2 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -58,11 +58,11 @@ def generateVersionCodeFromVersionName() { } def getVersionCode() { - if (gitBranchName() == "develop") { +// if (gitBranchName() == "develop") { return generateVersionCodeFromTimestamp() - } else { - return generateVersionCodeFromVersionName() - } +// } else { +// return generateVersionCodeFromVersionName() +// } } def getNightlyUniversalApkPath() { From 2ea6cdba6f779b2d474a3dd706c2be2b16fff21c Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 23 May 2023 08:01:32 +0200 Subject: [PATCH 15/48] Fix app non responsive --- changelog.d/8454.bugfix | 1 + .../session/room/read/SetReadMarkersTask.kt | 5 ++- .../DeleteUnusedClientInformationUseCase.kt | 26 ++++++++------- .../home/room/list/RoomListViewModel.kt | 9 +++--- .../NotificationDrawerManager.kt | 32 ++++++++++++------- 5 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 changelog.d/8454.bugfix diff --git a/changelog.d/8454.bugfix b/changelog.d/8454.bugfix new file mode 100644 index 0000000000..01d30cacdd --- /dev/null +++ b/changelog.d/8454.bugfix @@ -0,0 +1 @@ +Fix several performance issues causing app non responsive issues. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt index 8e7592a8b4..5c44931009 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/SetReadMarkersTask.kt @@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.session.room.read import com.zhuinden.monarchy.Monarchy import io.realm.Realm +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity @@ -64,9 +66,10 @@ internal class DefaultSetReadMarkersTask @Inject constructor( private val globalErrorReceiver: GlobalErrorReceiver, private val clock: Clock, private val homeServerCapabilitiesService: HomeServerCapabilitiesService, + private val coroutineDispatchers: MatrixCoroutineDispatchers, ) : SetReadMarkersTask { - override suspend fun execute(params: SetReadMarkersTask.Params) { + override suspend fun execute(params: SetReadMarkersTask.Params) = withContext(coroutineDispatchers.io) { val markers = mutableMapOf() Timber.v("Execute set read marker with params: $params") val latestSyncedEventId = latestSyncedEventId(params.roomId) diff --git a/vector/src/main/java/im/vector/app/core/session/clientinfo/DeleteUnusedClientInformationUseCase.kt b/vector/src/main/java/im/vector/app/core/session/clientinfo/DeleteUnusedClientInformationUseCase.kt index dcd5c58480..cc5dc6725d 100644 --- a/vector/src/main/java/im/vector/app/core/session/clientinfo/DeleteUnusedClientInformationUseCase.kt +++ b/vector/src/main/java/im/vector/app/core/session/clientinfo/DeleteUnusedClientInformationUseCase.kt @@ -17,6 +17,7 @@ package im.vector.app.core.session.clientinfo import im.vector.app.core.di.ActiveSessionHolder +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import javax.inject.Inject @@ -27,16 +28,19 @@ class DeleteUnusedClientInformationUseCase @Inject constructor( suspend fun execute(deviceInfoList: List): Result = runCatching { // A defensive approach against local storage reports an empty device list (although it is not a seen situation). if (deviceInfoList.isEmpty()) return Result.success(Unit) - - val expectedClientInfoKeyList = deviceInfoList.map { MATRIX_CLIENT_INFO_KEY_PREFIX + it.deviceId } - activeSessionHolder - .getSafeActiveSession() - ?.accountDataService() - ?.getUserAccountDataEventsStartWith(MATRIX_CLIENT_INFO_KEY_PREFIX) - ?.map { it.type } - ?.subtract(expectedClientInfoKeyList.toSet()) - ?.forEach { userAccountDataKeyToDelete -> - activeSessionHolder.getSafeActiveSession()?.accountDataService()?.deleteUserAccountData(userAccountDataKeyToDelete) - } + val dispatcher = activeSessionHolder.getSafeActiveSession()?.coroutineDispatchers?.io + ?: return@runCatching + withContext(dispatcher) { + val expectedClientInfoKeyList = deviceInfoList.map { MATRIX_CLIENT_INFO_KEY_PREFIX + it.deviceId } + activeSessionHolder + .getSafeActiveSession() + ?.accountDataService() + ?.getUserAccountDataEventsStartWith(MATRIX_CLIENT_INFO_KEY_PREFIX) + ?.map { it.type } + ?.subtract(expectedClientInfoKeyList.toSet()) + ?.forEach { userAccountDataKeyToDelete -> + activeSessionHolder.getSafeActiveSession()?.accountDataService()?.deleteUserAccountData(userAccountDataKeyToDelete) + } + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 74b55d435d..fad1ad613d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -322,11 +322,10 @@ class RoomListViewModel @AssistedInject constructor( } private fun handleDeleteLocalRooms() { - val localRoomIds = session.roomService() - .getRoomSummaries(roomSummaryQueryParams { roomId = QueryStringValue.Contains(RoomLocalEcho.PREFIX) }) - .map { it.roomId } - - viewModelScope.launch { + viewModelScope.launch(session.coroutineDispatchers.io) { + val localRoomIds = session.roomService() + .getRoomSummaries(roomSummaryQueryParams { roomId = QueryStringValue.Contains(RoomLocalEcho.PREFIX) }) + .map { it.roomId } localRoomIds.forEach { session.roomService().deleteLocalRoom(it) } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 2d799034d9..61cb14a70f 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -24,7 +24,9 @@ import im.vector.app.R import im.vector.app.core.resources.BuildMeta import im.vector.app.core.utils.FirstThrottler import im.vector.app.features.displayname.getBestName +import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorPreferences +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.session.getUserOrDefault @@ -121,11 +123,15 @@ class NotificationDrawerManager @Inject constructor( * Used to ignore events related to that room (no need to display notification) and clean any existing notification on this room. */ fun setCurrentRoom(roomId: String?) { - updateEvents { - val hasChanged = roomId != currentRoomId - currentRoomId = roomId - if (hasChanged && roomId != null) { - it.clearMessagesForRoom(roomId) + val dispatcher = currentSession?.coroutineDispatchers?.io ?: return + val scope = currentSession?.coroutineScope ?: return + scope.launch(dispatcher) { + updateEvents { + val hasChanged = roomId != currentRoomId + currentRoomId = roomId + if (hasChanged && roomId != null) { + it.clearMessagesForRoom(roomId) + } } } } @@ -135,12 +141,16 @@ class NotificationDrawerManager @Inject constructor( * Used to ignore events related to that thread (no need to display notification) and clean any existing notification on this room. */ fun setCurrentThread(threadId: String?) { - updateEvents { - val hasChanged = threadId != currentThreadId - currentThreadId = threadId - currentRoomId?.let { roomId -> - if (hasChanged && threadId != null) { - it.clearMessagesForThread(roomId, threadId) + val dispatcher = currentSession?.coroutineDispatchers?.io ?: return + val scope = currentSession?.coroutineScope ?: return + scope.launch(dispatcher) { + updateEvents { + val hasChanged = threadId != currentThreadId + currentThreadId = threadId + currentRoomId?.let { roomId -> + if (hasChanged && threadId != null) { + it.clearMessagesForThread(roomId, threadId) + } } } } From 19dc812719d0232e8e2e0639fcb0447d0bce13ce Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 23 May 2023 08:32:14 +0200 Subject: [PATCH 16/48] add changelog --- changelog.d/8457.bugfix | 1 + vector-app/build.gradle | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 changelog.d/8457.bugfix diff --git a/changelog.d/8457.bugfix b/changelog.d/8457.bugfix new file mode 100644 index 0000000000..2f50364c1d --- /dev/null +++ b/changelog.d/8457.bugfix @@ -0,0 +1 @@ +Fix: The device list screen from the member profile page was always showing the current user devices (rust crypto). diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 71e2c589e2..9a2506391e 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -58,11 +58,11 @@ def generateVersionCodeFromVersionName() { } def getVersionCode() { -// if (gitBranchName() == "develop") { + if (gitBranchName() == "develop") { return generateVersionCodeFromTimestamp() -// } else { -// return generateVersionCodeFromVersionName() -// } + } else { + return generateVersionCodeFromVersionName() + } } def getNightlyUniversalApkPath() { From 27f9be5eda81ee0c986de535d0f0d2c128a69eb3 Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 23 May 2023 13:08:14 +0200 Subject: [PATCH 17/48] Special text for re-verification after update --- changelog.d/8445.bugfix | 1 + .../src/main/res/values/strings.xml | 2 ++ .../im/vector/app/features/MainActivity.kt | 14 ++++++++++++ .../vector/app/features/home/HomeActivity.kt | 14 ++++++++++-- .../features/home/HomeActivityViewEvents.kt | 2 +- .../features/home/HomeActivityViewModel.kt | 1 + .../features/settings/VectorPreferences.kt | 22 +++++++++++++++++++ 7 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 changelog.d/8445.bugfix diff --git a/changelog.d/8445.bugfix b/changelog.d/8445.bugfix new file mode 100644 index 0000000000..4f5b0f0349 --- /dev/null +++ b/changelog.d/8445.bugfix @@ -0,0 +1 @@ +Fix: Update verification popup text when a re-verification is needed after rust migration (read only sessions) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 3d1a36d4c3..ccdbae634e 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2446,6 +2446,7 @@ Verify this device + App updated Unable to verify this device You won’t be able to access encrypted message history. Reset your Secure Message Backup and verification keys to start fresh. @@ -2707,6 +2708,7 @@ Verify login Interactively Verify by Emoji Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages. + Secure messaging has been improved with the latest update. Please re-verify your device. Confirm your identity by verifying this login, granting it access to encrypted messages. Failed to set up Cross Signing diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index cffb1577cf..ff0e9721e4 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -29,6 +29,7 @@ import com.airbnb.mvrx.viewModel import com.bumptech.glide.Glide import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.extensions.startSyncing import im.vector.app.core.extensions.vectorStore @@ -170,6 +171,19 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } private fun handleAppStarted() { + // On the first run with rust crypto this would be false + if (!vectorPreferences.isOnRustCrypto()) { + if (activeSessionHolder.hasActiveSession()) { + vectorPreferences.setHadExistingLegacyData(activeSessionHolder.getActiveSession().isOpenable) + } else { + vectorPreferences.setHadExistingLegacyData(false) + } + } + + if (BuildConfig.FLAVOR == "rustCrypto") { + vectorPreferences.setIsOnRustCrypto(true) + } + if (intent.hasExtra(EXTRA_NEXT_INTENT)) { // Start the next Activity startSyncing() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 42eb200887..428e62724b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -469,11 +469,21 @@ class HomeActivity : private fun handleOnNewSession(event: HomeActivityViewEvents.CurrentSessionNotVerified) { // We need to ask + val titleRes = if (event.afterMigration) { + R.string.crosssigning_verify_after_update + } else { + R.string.crosssigning_verify_this_session + } + val descRes = if (event.afterMigration) { + R.string.confirm_your_identity_after_update + } else { + R.string.confirm_your_identity + } promptSecurityEvent( uid = PopupAlertManager.VERIFY_SESSION_UID, userItem = event.userItem, - titleRes = R.string.crosssigning_verify_this_session, - descRes = R.string.confirm_your_identity, + titleRes = titleRes, + descRes = descRes, ) { it.navigator.requestSelfSessionVerification(it) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt index 5f8d9cdc51..c57f32694b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt @@ -23,7 +23,7 @@ sealed interface HomeActivityViewEvents : VectorViewEvents { data class AskPasswordToInitCrossSigning(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents data class CurrentSessionNotVerified( val userItem: MatrixItem.UserItem, -// val waitForIncomingRequest: Boolean = true, + val afterMigration: Boolean ) : HomeActivityViewEvents data class CurrentSessionCannotBeVerified( diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 73bbcac070..eb4a796a49 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -453,6 +453,7 @@ class HomeActivityViewModel @AssistedInject constructor( _viewEvents.post( HomeActivityViewEvents.CurrentSessionNotVerified( session.getUserOrDefault(session.myUserId).toMatrixItem(), + vectorPreferences.isOnRustCrypto() && vectorPreferences.hadExistingLegacyData() ) ) } else { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index f915395a42..0dd8d14460 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -254,6 +254,8 @@ class VectorPreferences @Inject constructor( const val TAKE_PHOTO_VIDEO_MODE_PHOTO = 1 const val TAKE_PHOTO_VIDEO_MODE_VIDEO = 2 + const val HAD_EXISTING_LEGACY_DATA = "HAD_EXISTING_LEGACY_DATA" + const val IS_ON_RUST_CRYPTO = "IS_ON_RUST_CRYPTO" // Background sync modes // some preferences keys must be kept after a logout @@ -1278,4 +1280,24 @@ class VectorPreferences @Inject constructor( putBoolean(SETTINGS_NEW_LOGIN_ALERT_SHOWN_FOR_DEVICE + deviceId, true) } } + + fun hadExistingLegacyData(): Boolean { + return defaultPrefs.getBoolean(HAD_EXISTING_LEGACY_DATA, false) + } + + fun setHadExistingLegacyData(had: Boolean) { + defaultPrefs.edit { + putBoolean(HAD_EXISTING_LEGACY_DATA, had) + } + } + + fun isOnRustCrypto(): Boolean { + return defaultPrefs.getBoolean(IS_ON_RUST_CRYPTO, false) + } + + fun setIsOnRustCrypto(boolean: Boolean) { + defaultPrefs.edit { + putBoolean(IS_ON_RUST_CRYPTO, boolean) + } + } } From cee6ec593995f8cab4b27e64f326976dff36bde5 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 23 May 2023 16:51:26 +0100 Subject: [PATCH 18/48] Always allow users sign out - Updates the dialog with a more helpful error message for the user, letting them know what happens if they logout without informing the homeserver. --- changelog.d/4855.bugfix | 1 + .../src/main/res/values/strings.xml | 3 +++ .../im/vector/app/features/MainActivity.kt | 23 ++++++++++++------- 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 changelog.d/4855.bugfix diff --git a/changelog.d/4855.bugfix b/changelog.d/4855.bugfix new file mode 100644 index 0000000000..d85feb42e7 --- /dev/null +++ b/changelog.d/4855.bugfix @@ -0,0 +1 @@ +Fix: Allow users to sign out even if the sign out request fails. diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 3d1a36d4c3..ddd333017e 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -328,6 +328,9 @@ Back up You’ll lose access to your encrypted messages unless you back up your keys before signing out. + Cannot reach the homeserver. If you sign out anyway, this device will not be erased from your device list, you may want to remove it using another client. + Sign out anyway + Loading… diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index cffb1577cf..676986d0df 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -252,13 +252,10 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity try { session.signOutService().signOut(!args.isUserLoggedOut) } catch (failure: Throwable) { - displayError(failure) + displaySignOutFailedDialog(onboardingStore) return@launch } - Timber.w("SIGN_OUT: success, start app") - activeSessionHolder.clearActiveSession() - doLocalCleanup(clearPreferences = true, onboardingStore) - startNextActivityAndFinish() + completeSignout(onboardingStore) } } args.clearCache -> { @@ -272,6 +269,15 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } } + private fun completeSignout(onboardingStore: VectorSessionStore) { + lifecycleScope.launch { + Timber.w("SIGN_OUT: success, start app") + activeSessionHolder.clearActiveSession() + doLocalCleanup(clearPreferences = true, onboardingStore) + startNextActivityAndFinish() + } + } + override fun handleInvalidToken(globalError: GlobalError.InvalidToken) { // No op here Timber.w("Ignoring invalid token global error") @@ -299,12 +305,13 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } } - private fun displayError(failure: Throwable) { + private fun displaySignOutFailedDialog(onboardingStore: VectorSessionStore) { if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { MaterialAlertDialogBuilder(this) .setTitle(R.string.dialog_title_error) - .setMessage(errorFormatter.toHumanReadable(failure)) - .setPositiveButton(R.string.global_retry) { _, _ -> doCleanUp() } + .setMessage(R.string.sign_out_failed_dialog_message) + .setPositiveButton(R.string.sign_out_anyway) { _, _ -> completeSignout(onboardingStore) } + .setNeutralButton(R.string.global_retry) { _, _ -> doCleanUp() } .setNegativeButton(R.string.action_cancel) { _, _ -> startNextActivityAndFinish(ignoreClearCredentials = true) } .setCancelable(false) .show() From bb59a758cf346d44f9391dedf8491770bf789301 Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 23 May 2023 16:38:53 +0200 Subject: [PATCH 19/48] code review --- .../crypto/quads/SharedSecuredStorageResetAllFragment.kt | 2 +- .../roommemberprofile/devices/DeviceListBottomSheet.kt | 5 ++--- .../im/vector/app/features/settings/devices/TrustUtils.kt | 2 -- .../verification/GetEncryptionTrustLevelForDeviceUseCase.kt | 2 ++ 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt index 66344107a4..d060e3996d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt @@ -52,7 +52,7 @@ class SharedSecuredStorageResetAllFragment : views.ssssResetOtherDevices.debouncedClicks { withState(sharedViewModel) { - DeviceListBottomSheet.newInstance(it.userId, false).show(childFragmentManager, "DEV_LIST") + DeviceListBottomSheet.newInstance(it.userId).show(childFragmentManager, "DEV_LIST") } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt index 2dbb03121d..63c44b4000 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt @@ -100,13 +100,12 @@ class DeviceListBottomSheet : @Parcelize data class Args( val userId: String, - val allowDeviceAction: Boolean ) : Parcelable companion object { - fun newInstance(userId: String, allowDeviceAction: Boolean = true): DeviceListBottomSheet { + fun newInstance(userId: String): DeviceListBottomSheet { return DeviceListBottomSheet().apply { - setArguments(Args(userId, allowDeviceAction)) + setArguments(Args(userId)) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt index 983790c80a..7709a63344 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt @@ -22,8 +22,6 @@ import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel // TODO Replace usage by the use case GetEncryptionTrustLevelForDeviceUseCase object TrustUtils { - // XXX why is this using the RoomEncryptionTrustLevel? - // should be using a new DeviceTrustShield enum fun shieldForTrust( currentDevice: Boolean, trustMSK: Boolean, diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt index 268ae86601..762a636494 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/verification/GetEncryptionTrustLevelForDeviceUseCase.kt @@ -25,6 +25,8 @@ class GetEncryptionTrustLevelForDeviceUseCase @Inject constructor( private val getEncryptionTrustLevelForOtherDeviceUseCase: GetEncryptionTrustLevelForOtherDeviceUseCase, ) { + // XXX why is this using the RoomEncryptionTrustLevel? + // should be using a new DeviceTrustShield enum fun execute(currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo, cryptoDeviceInfo: CryptoDeviceInfo?): RoomEncryptionTrustLevel? { if (cryptoDeviceInfo == null) { return null From d5d5c9009b69c8fb6f28472e3b9fce41f51205a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 10:14:22 +0000 Subject: [PATCH 20/48] Bump io.element.android:wysiwyg from 1.2.2 to 2.2.1 (#8464) * Bump io.element.android:wysiwyg from 1.2.2 to 2.2.1 Bumps [io.element.android:wysiwyg](https://github.com/matrix-org/matrix-wysiwyg) from 1.2.2 to 2.2.1. - [Changelog](https://github.com/matrix-org/matrix-rich-text-editor/blob/main/CHANGELOG.md) - [Commits](https://github.com/matrix-org/matrix-wysiwyg/compare/1.2.2...2.2.1) --- updated-dependencies: - dependency-name: io.element.android:wysiwyg dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix compilation --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jonnyandrew --- dependencies.gradle | 2 +- .../androidTest/java/im/vector/app/core/utils/TestSpan.kt | 2 +- .../home/room/detail/composer/RichTextComposerLayout.kt | 6 +++--- .../java/im/vector/app/features/html/EventHtmlRenderer.kt | 2 +- .../java/im/vector/app/features/html/HtmlCodeHandlers.kt | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 5f4df15860..ca5495b04d 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -101,7 +101,7 @@ ext.libs = [ ], element : [ 'opusencoder' : "io.element.android:opusencoder:1.1.0", - 'wysiwyg' : "io.element.android:wysiwyg:1.2.2" + 'wysiwyg' : "io.element.android:wysiwyg:2.2.1" ], squareup : [ 'moshi' : "com.squareup.moshi:moshi:$moshi", diff --git a/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt b/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt index ebbe565642..fe6f6cb987 100644 --- a/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt +++ b/vector/src/androidTest/java/im/vector/app/core/utils/TestSpan.kt @@ -23,7 +23,7 @@ import android.text.Spanned import android.text.style.StrikethroughSpan import androidx.core.text.getSpans import im.vector.app.features.html.HtmlCodeSpan -import io.element.android.wysiwyg.spans.InlineCodeSpan +import io.element.android.wysiwyg.view.spans.InlineCodeSpan import io.mockk.justRun import io.mockk.mockk import io.mockk.slot diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt index a821458939..49e8f0cdc6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt @@ -50,9 +50,9 @@ import im.vector.app.databinding.ComposerRichTextLayoutBinding import im.vector.app.databinding.ViewRichTextMenuButtonBinding import im.vector.app.features.home.room.detail.composer.images.UriContentListener import io.element.android.wysiwyg.EditorEditText -import io.element.android.wysiwyg.inputhandlers.models.InlineFormat -import io.element.android.wysiwyg.inputhandlers.models.LinkAction import io.element.android.wysiwyg.utils.RustErrorCollector +import io.element.android.wysiwyg.view.models.InlineFormat +import io.element.android.wysiwyg.view.models.LinkAction import uniffi.wysiwyg_composer.ActionState import uniffi.wysiwyg_composer.ComposerAction @@ -269,7 +269,7 @@ internal class RichTextComposerLayout @JvmOverloads constructor( views.richTextComposerEditText.getLinkAction()?.let { when (it) { LinkAction.InsertLink -> callback?.onSetLink(isTextSupported = true, initialLink = null) - is LinkAction.SetLink -> callback?.onSetLink(isTextSupported = false, initialLink = it.currentLink) + is LinkAction.SetLink -> callback?.onSetLink(isTextSupported = false, initialLink = it.currentUrl) } } } diff --git a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt index cb3f12d867..5874474965 100644 --- a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt @@ -43,7 +43,7 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.settings.VectorPreferences -import io.element.android.wysiwyg.spans.InlineCodeSpan +import io.element.android.wysiwyg.view.spans.InlineCodeSpan import io.noties.markwon.AbstractMarkwonPlugin import io.noties.markwon.Markwon import io.noties.markwon.MarkwonPlugin diff --git a/vector/src/main/java/im/vector/app/features/html/HtmlCodeHandlers.kt b/vector/src/main/java/im/vector/app/features/html/HtmlCodeHandlers.kt index 3175996ba1..7ffd9ceb84 100644 --- a/vector/src/main/java/im/vector/app/features/html/HtmlCodeHandlers.kt +++ b/vector/src/main/java/im/vector/app/features/html/HtmlCodeHandlers.kt @@ -18,8 +18,8 @@ package im.vector.app.features.html import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.settings.VectorPreferences -import io.element.android.wysiwyg.spans.CodeBlockSpan -import io.element.android.wysiwyg.spans.InlineCodeSpan +import io.element.android.wysiwyg.view.spans.CodeBlockSpan +import io.element.android.wysiwyg.view.spans.InlineCodeSpan import io.noties.markwon.MarkwonVisitor import io.noties.markwon.SpannableBuilder import io.noties.markwon.core.MarkwonTheme From 997c9dd9177fd5470ccb92d0b8de6160e44a88f2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 25 May 2023 10:38:08 +0200 Subject: [PATCH 21/48] Ensure signout service is always use even if users want to ignore sigout error from the server. The SDK is doing more cleanup. --- .../sdk/api/session/signout/SignOutService.kt | 3 +- .../session/signout/DefaultSignOutService.kt | 9 ++++- .../internal/session/signout/SignOutTask.kt | 7 +++- .../im/vector/app/features/MainActivity.kt | 37 ++++++++++++------- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/signout/SignOutService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/signout/SignOutService.kt index d64b2e6e92..fade51600a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/signout/SignOutService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/signout/SignOutService.kt @@ -37,6 +37,7 @@ interface SignOutService { /** * Sign out, and release the session, clear all the session data, including crypto data. * @param signOutFromHomeserver true if the sign out request has to be done + * @param ignoreServerRequestError true to ignore server error if any */ - suspend fun signOut(signOutFromHomeserver: Boolean) + suspend fun signOut(signOutFromHomeserver: Boolean, ignoreServerRequestError: Boolean = false) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/DefaultSignOutService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/DefaultSignOutService.kt index 1bb86ecb4b..2c34f1e2d9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/DefaultSignOutService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/DefaultSignOutService.kt @@ -35,7 +35,12 @@ internal class DefaultSignOutService @Inject constructor( sessionParamsStore.updateCredentials(credentials) } - override suspend fun signOut(signOutFromHomeserver: Boolean) { - return signOutTask.execute(SignOutTask.Params(signOutFromHomeserver)) + override suspend fun signOut(signOutFromHomeserver: Boolean, ignoreServerRequestError: Boolean) { + return signOutTask.execute( + SignOutTask.Params( + signOutFromHomeserver = signOutFromHomeserver, + ignoreServerRequestError = ignoreServerRequestError + ) + ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt index e5213c4696..f8ec23b24d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt @@ -30,7 +30,8 @@ import javax.inject.Inject internal interface SignOutTask : Task { data class Params( - val signOutFromHomeserver: Boolean + val signOutFromHomeserver: Boolean, + val ignoreServerRequestError: Boolean, ) } @@ -59,7 +60,9 @@ internal class DefaultSignOutTask @Inject constructor( // Ignore Timber.w("Ignore error due to https://github.com/matrix-org/synapse/issues/5755") } else { - throw throwable + if (!params.ignoreServerRequestError) { + throw throwable + } } } } diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 676986d0df..5518d1bba2 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -59,6 +59,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.failure.GlobalError +import org.matrix.android.sdk.api.session.Session import timber.log.Timber import javax.inject.Inject @@ -248,15 +249,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } } args.clearCredentials -> { - lifecycleScope.launch { - try { - session.signOutService().signOut(!args.isUserLoggedOut) - } catch (failure: Throwable) { - displaySignOutFailedDialog(onboardingStore) - return@launch - } - completeSignout(onboardingStore) - } + signout(session, onboardingStore, ignoreServerError = false) } args.clearCache -> { lifecycleScope.launch { @@ -269,8 +262,19 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } } - private fun completeSignout(onboardingStore: VectorSessionStore) { + private fun signout( + session: Session, + onboardingStore: VectorSessionStore, + ignoreServerError: Boolean, + ) { lifecycleScope.launch { + try { + session.signOutService().signOut(!args.isUserLoggedOut, ignoreServerError) + } catch (failure: Throwable) { + Timber.e(failure, "SIGN_OUT: error, propose to sign out anyway") + displaySignOutFailedDialog(session, onboardingStore) + return@launch + } Timber.w("SIGN_OUT: success, start app") activeSessionHolder.clearActiveSession() doLocalCleanup(clearPreferences = true, onboardingStore) @@ -305,13 +309,20 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } } - private fun displaySignOutFailedDialog(onboardingStore: VectorSessionStore) { + private fun displaySignOutFailedDialog( + session: Session, + onboardingStore: VectorSessionStore, + ) { if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { MaterialAlertDialogBuilder(this) .setTitle(R.string.dialog_title_error) .setMessage(R.string.sign_out_failed_dialog_message) - .setPositiveButton(R.string.sign_out_anyway) { _, _ -> completeSignout(onboardingStore) } - .setNeutralButton(R.string.global_retry) { _, _ -> doCleanUp() } + .setPositiveButton(R.string.sign_out_anyway) { _, _ -> + signout(session, onboardingStore, ignoreServerError = true) + } + .setNeutralButton(R.string.global_retry) { _, _ -> + signout(session, onboardingStore, ignoreServerError = false) + } .setNegativeButton(R.string.action_cancel) { _, _ -> startNextActivityAndFinish(ignoreClearCredentials = true) } .setCancelable(false) .show() From 82748591f9cf08923bd87088c9ffd7cf76f22e1c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 25 May 2023 11:05:07 +0200 Subject: [PATCH 22/48] Setting version for the release 1.6.1 --- matrix-sdk-android/build.gradle | 2 +- vector-app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 6328c1ceac..230677e8e2 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -63,7 +63,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.6.2\"" + buildConfigField "String", "SDK_VERSION", "\"1.6.1\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 9a2506391e..28ccc03815 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -37,7 +37,7 @@ ext.versionMinor = 6 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 2 +ext.versionPatch = 1 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From f261a903f038fde06c634c155ef9137d6d2cb937 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 25 May 2023 11:18:08 +0200 Subject: [PATCH 23/48] Changelog for version 1.6.1 --- CHANGES.md | 17 +++++++++++++++++ changelog.d/8439.bugfix | 1 - changelog.d/8445.bugfix | 1 - changelog.d/8454.bugfix | 1 - changelog.d/8457.bugfix | 1 - changelog.d/8458.misc | 1 - 6 files changed, 17 insertions(+), 5 deletions(-) delete mode 100644 changelog.d/8439.bugfix delete mode 100644 changelog.d/8445.bugfix delete mode 100644 changelog.d/8454.bugfix delete mode 100644 changelog.d/8457.bugfix delete mode 100644 changelog.d/8458.misc diff --git a/CHANGES.md b/CHANGES.md index e5ce4dc1ab..6d756f2b3f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,20 @@ +Changes in Element v1.6.1 (2023-05-25) +====================================== + +Corrective release for 1.6.0 + +Bugfixes 🐛 +---------- + - Allow stateloss on verification dialogfragment ([#8439](https://github.com/vector-im/element-android/issues/8439)) + - Fix: Update verification popup text when a re-verification is needed after rust migration (read only sessions) ([#8445](https://github.com/vector-im/element-android/issues/8445)) + - Fix several performance issues causing app non responsive issues. ([#8454](https://github.com/vector-im/element-android/issues/8454)) + - Fix: The device list screen from the member profile page was always showing the current user devices (rust crypto). ([#8457](https://github.com/vector-im/element-android/issues/8457)) + +Other changes +------------- + - Remove UI option to manually verify a specific device of another user (deprecated behaviour) ([#8458](https://github.com/vector-im/element-android/issues/8458)) + + Changes in Element v1.6.0 (2023-05-17) ====================================== diff --git a/changelog.d/8439.bugfix b/changelog.d/8439.bugfix deleted file mode 100644 index c271f185c9..0000000000 --- a/changelog.d/8439.bugfix +++ /dev/null @@ -1 +0,0 @@ -Allow stateloss on verification dialogfragment diff --git a/changelog.d/8445.bugfix b/changelog.d/8445.bugfix deleted file mode 100644 index 4f5b0f0349..0000000000 --- a/changelog.d/8445.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix: Update verification popup text when a re-verification is needed after rust migration (read only sessions) diff --git a/changelog.d/8454.bugfix b/changelog.d/8454.bugfix deleted file mode 100644 index 01d30cacdd..0000000000 --- a/changelog.d/8454.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix several performance issues causing app non responsive issues. diff --git a/changelog.d/8457.bugfix b/changelog.d/8457.bugfix deleted file mode 100644 index 2f50364c1d..0000000000 --- a/changelog.d/8457.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix: The device list screen from the member profile page was always showing the current user devices (rust crypto). diff --git a/changelog.d/8458.misc b/changelog.d/8458.misc deleted file mode 100644 index ba32317523..0000000000 --- a/changelog.d/8458.misc +++ /dev/null @@ -1 +0,0 @@ -Remove UI option to manually verify a specific device of another user (deprecated behaviour) From 93e2d7d17648ef821352897f098f4a212fd4c292 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 25 May 2023 11:18:34 +0200 Subject: [PATCH 24/48] Adding fastlane file for version 1.6.1 --- fastlane/metadata/android/en-US/changelogs/40106010.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40106010.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40106010.txt b/fastlane/metadata/android/en-US/changelogs/40106010.txt new file mode 100644 index 0000000000..badf979955 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40106010.txt @@ -0,0 +1,2 @@ +Main changes in this version: Element Android is now using the Crypto Rust SDK. +Full changelog: https://github.com/vector-im/element-android/releases From 8f69e411d71215c67091587d112f769393d05dfd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 25 May 2023 11:22:07 +0200 Subject: [PATCH 25/48] version++ --- matrix-sdk-android/build.gradle | 2 +- vector-app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 230677e8e2..6328c1ceac 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -63,7 +63,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.6.1\"" + buildConfigField "String", "SDK_VERSION", "\"1.6.2\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 28ccc03815..9a2506391e 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -37,7 +37,7 @@ ext.versionMinor = 6 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 1 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 3bf5c0cc1b77a9bda9f5985331960be9597eee72 Mon Sep 17 00:00:00 2001 From: valere Date: Fri, 26 May 2023 09:50:15 +0200 Subject: [PATCH 26/48] Extract common crypto interface for all flavors --- .../sdk/internal/crypto/CryptoModule.kt | 4 + .../internal/crypto/DefaultCryptoService.kt | 5 +- .../crypto/InboundGroupSessionStore.kt | 0 .../sdk/internal/crypto/OlmSessionStore.kt | 0 .../internal/crypto/store/IMXCryptoStore.kt | 116 +----- .../crypto/store/db/RealmCryptoStore.kt | 13 + .../ShouldEncryptForInvitedMembersUseCase.kt | 4 +- .../crypto/store/IMXCommonCryptoStore.kt | 156 ++++++++ .../session/room/EventEditValidator.kt | 26 +- .../session/room/send/DefaultSendService.kt | 4 +- .../queue/EventSenderProcessorCoroutine.kt | 4 +- .../sdk/internal/crypto/CryptoModule.kt | 6 +- .../android/sdk/internal/crypto/OlmMachine.kt | 5 +- .../crypto/PrepareToEncryptUseCase.kt | 4 +- .../sdk/internal/crypto/RustCryptoService.kt | 12 +- .../internal/crypto/network/RequestSender.kt | 9 +- .../internal/crypto/store/RustCryptoStore.kt | 351 ++++++++++++++++++ .../session/room/EventEditValidatorTest.kt | 44 +-- 18 files changed, 582 insertions(+), 181 deletions(-) rename matrix-sdk-android/src/{main => kotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt (100%) rename matrix-sdk-android/src/{main => kotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt (100%) rename matrix-sdk-android/src/{main => kotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt (81%) rename matrix-sdk-android/src/{main => kotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt (99%) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt create mode 100644 matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt diff --git a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index 6ae12aaf3d..719c45a113 100644 --- a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -59,6 +59,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionD import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration @@ -254,6 +255,9 @@ internal abstract class CryptoModule { @Binds abstract fun bindCryptoStore(store: RealmCryptoStore): IMXCryptoStore + @Binds + abstract fun bindCommonCryptoStore(store: RealmCryptoStore): IMXCommonCryptoStore + @Binds abstract fun bindSendEventTask(task: DefaultSendEventTask): SendEventTask diff --git a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 1dd02543cb..f948063c77 100755 --- a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -506,10 +506,7 @@ internal class DefaultCryptoService @Inject constructor( null } else { withContext(coroutineDispatchers.io) { - cryptoStore.deviceWithIdentityKey(senderKey).takeIf { - // check that the claimed user id matches - it?.userId == userId - } + cryptoStore.deviceWithIdentityKey(userId, senderKey) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt similarity index 100% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt rename to matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt similarity index 100% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt rename to matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt similarity index 81% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt rename to matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index a13c15bd1a..fc882e5c1d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -28,20 +28,16 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo import org.matrix.android.sdk.api.session.crypto.model.AuditTrail import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.api.session.crypto.model.CryptoRoomInfo -import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.crypto.model.TrailType import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity import org.matrix.olm.OlmAccount import org.matrix.olm.OlmOutboundGroupSession @@ -49,7 +45,7 @@ import org.matrix.olm.OlmOutboundGroupSession /** * The crypto data store. */ -internal interface IMXCryptoStore { +internal interface IMXCryptoStore : IMXCommonCryptoStore { /** * @return the device id @@ -78,21 +74,6 @@ internal interface IMXCryptoStore { */ fun getInboundGroupSessions(roomId: String): List - /** - * @return true to unilaterally blacklist all unverified devices. - */ - fun getGlobalBlacklistUnverifiedDevices(): Boolean - - /** - * Set the global override for whether the client should ever send encrypted - * messages to unverified devices. - * If false, it can still be overridden per-room. - * If true, it overrides the per-room settings. - * - * @param block true to unilaterally blacklist all - */ - fun setGlobalBlacklistUnverifiedDevices(block: Boolean) - /** * Enable or disable key gossiping. * Default is true. @@ -123,28 +104,6 @@ internal interface IMXCryptoStore { */ fun getRoomsListBlacklistUnverifiedDevices(): List - /** - * A live status regarding sharing keys for unverified devices in this room. - * - * @return Live status - */ - fun getLiveBlockUnverifiedDevices(roomId: String): LiveData - - /** - * Tell if unverified devices should be blacklisted when sending keys. - * - * @return true if should not send keys to unverified devices - */ - fun getBlockUnverifiedDevices(roomId: String): Boolean - - /** - * Define if encryption keys should be sent to unverified devices in this room. - * - * @param roomId the roomId - * @param block if true will not send keys to unverified devices - */ - fun blockUnverifiedDevicesInRoom(roomId: String, block: Boolean) - /** * Get the current keys backup version. */ @@ -186,16 +145,6 @@ internal interface IMXCryptoStore { */ fun deleteStore() - /** - * open any existing crypto store. - */ - fun open() - - /** - * Close the store. - */ - fun close() - /** * Store the device id. * @@ -262,14 +211,6 @@ internal interface IMXCryptoStore { fun getLiveDeviceWithId(deviceId: String): LiveData> - fun getMyDevicesInfo(): List - - fun getLiveMyDevicesInfo(): LiveData> - - fun getLiveMyDevicesInfo(deviceId: String): LiveData> - - fun saveMyDevicesInfo(info: List) - /** * Store the crypto algorithm for a room. * @@ -278,47 +219,8 @@ internal interface IMXCryptoStore { */ fun storeRoomAlgorithm(roomId: String, algorithm: String?) - /** - * Provides the algorithm used in a dedicated room. - * - * @param roomId the room id - * @return the algorithm, null is the room is not encrypted - */ - fun getRoomAlgorithm(roomId: String): String? - - fun getRoomCryptoInfo(roomId: String): CryptoRoomInfo? - fun setAlgorithmInfo(roomId: String, encryption: EncryptionEventContent?) - - /** - * This is a bit different than isRoomEncrypted. - * A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not). - * But the crypto layer has additional guaranty to ensure that encryption would never been reverted. - * It's defensive coding out of precaution (if ever state is reset). - */ - fun roomWasOnceEncrypted(roomId: String): Boolean - - fun shouldEncryptForInvitedMembers(roomId: String): Boolean - - /** - * Sets a boolean flag that will determine whether or not this device should encrypt Events for - * invited members. - * - * @param roomId the room id - * @param shouldEncryptForInvitedMembers The boolean flag - */ - fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) - fun shouldShareHistory(roomId: String): Boolean - /** - * Sets a boolean flag that will determine whether or not room history (existing inbound sessions) - * will be shared to new user invites. - * - * @param roomId the room id - * @param shouldShareHistory The boolean flag - */ - fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) - /** * Store a session between the logged-in user and another device. * @@ -361,15 +263,6 @@ internal interface IMXCryptoStore { */ fun storeInboundGroupSessions(sessions: List) - /** - * Retrieve an inbound group session. - * - * @param sessionId the session identifier. - * @param senderKey the base64-encoded curve25519 key of the sender. - * @return an inbound group session. - */ - fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper? - /** * Retrieve an inbound group session, filtering shared history. * @@ -552,7 +445,6 @@ internal interface IMXCryptoStore { // fun getCrossSigningPrivateKeysFlow(): Flow> fun getGlobalCryptoConfig(): GlobalCryptoConfig - fun getLiveGlobalCryptoConfig(): LiveData fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? @@ -597,14 +489,8 @@ internal interface IMXCryptoStore { fun setDeviceKeysUploaded(uploaded: Boolean) fun areDeviceKeysUploaded(): Boolean - fun tidyUpDataBase() fun getOutgoingRoomKeyRequests(inStates: Set): List - /** - * Store a bunch of data collected during a sync response treatment. @See [CryptoStoreAggregator]. - */ - fun storeData(cryptoStoreAggregator: CryptoStoreAggregator) - /** * Store a bunch of data related to the users. @See [UserDataToStore]. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt similarity index 99% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt rename to matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 2d82f67b9e..e3595f6618 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -280,6 +280,19 @@ internal class RealmCryptoStore @Inject constructor( } } + override fun deviceWithIdentityKey(userId: String, identityKey: String): CryptoDeviceInfo? { + return doWithRealm(realmConfiguration) { realm -> + realm.where() + .equalTo(DeviceInfoEntityFields.USER_ID, userId) + .contains(DeviceInfoEntityFields.KEYS_MAP_JSON, identityKey) + .findAll() + .mapNotNull { CryptoMapper.mapToModel(it) } + .firstOrNull { + it.identityKey() == identityKey + } + } + } + override fun storeUserDevices(userId: String, devices: Map?) { doRealmTransaction("storeUserDevices", realmConfiguration) { realm -> storeUserDevices(realm, userId, devices) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt index 29a550aad3..7c7c8ce901 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt @@ -17,11 +17,11 @@ package org.matrix.android.sdk.internal.crypto import org.matrix.android.sdk.api.crypto.MXCryptoConfig -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import javax.inject.Inject internal class ShouldEncryptForInvitedMembersUseCase @Inject constructor(private val cryptoConfig: MXCryptoConfig, - private val cryptoStore: IMXCryptoStore) { + private val cryptoStore: IMXCommonCryptoStore) { operator fun invoke(roomId: String): Boolean { return cryptoConfig.enableEncryptionForInvitedMembers && cryptoStore.shouldEncryptForInvitedMembers(roomId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt new file mode 100644 index 0000000000..68b002c087 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCommonCryptoStore.kt @@ -0,0 +1,156 @@ +/* + * Copyright 2023 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.store + +import androidx.lifecycle.LiveData +import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoRoomInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator + +/** + * As a temporary measure rust and kotlin flavor are still using realm to store some crypto + * related information. In the near future rust flavor will complitly stop using realm, as soon + * as the missing bits are store in rust side (like room encryption settings, ..) + * This interface defines what's now used by both flavors. + * The actual implementation are moved in each flavors + */ +interface IMXCommonCryptoStore { + + /** + * Provides the algorithm used in a dedicated room. + * + * @param roomId the room id + * @return the algorithm, null is the room is not encrypted + */ + fun getRoomAlgorithm(roomId: String): String? + + fun getRoomCryptoInfo(roomId: String): CryptoRoomInfo? + + fun setAlgorithmInfo(roomId: String, encryption: EncryptionEventContent?) + + fun roomWasOnceEncrypted(roomId: String): Boolean + + fun saveMyDevicesInfo(info: List) + + // questionable that it's stored in crypto store + fun getMyDevicesInfo(): List + + // questionable that it's stored in crypto store + fun getLiveMyDevicesInfo(): LiveData> + + // questionable that it's stored in crypto store + fun getLiveMyDevicesInfo(deviceId: String): LiveData> + + /** + * open any existing crypto store. + */ + fun open() + fun tidyUpDataBase() + + /** + * Close the store. + */ + fun close() + + /* + * Store a bunch of data collected during a sync response treatment. @See [CryptoStoreAggregator]. + */ + fun storeData(cryptoStoreAggregator: CryptoStoreAggregator) + + fun shouldEncryptForInvitedMembers(roomId: String): Boolean + + /** + * Sets a boolean flag that will determine whether or not room history (existing inbound sessions) + * will be shared to new user invites. + * + * @param roomId the room id + * @param shouldShareHistory The boolean flag + */ + fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) + + /** + * Sets a boolean flag that will determine whether or not this device should encrypt Events for + * invited members. + * + * @param roomId the room id + * @param shouldEncryptForInvitedMembers The boolean flag + */ + fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) + + /** + * Define if encryption keys should be sent to unverified devices in this room. + * + * @param roomId the roomId + * @param block if true will not send keys to unverified devices + */ + fun blockUnverifiedDevicesInRoom(roomId: String, block: Boolean) + + /** + * Set the global override for whether the client should ever send encrypted + * messages to unverified devices. + * If false, it can still be overridden per-room. + * If true, it overrides the per-room settings. + * + * @param block true to unilaterally blacklist all + */ + fun setGlobalBlacklistUnverifiedDevices(block: Boolean) + + fun getLiveGlobalCryptoConfig(): LiveData + + /** + * @return true to unilaterally blacklist all unverified devices. + */ + fun getGlobalBlacklistUnverifiedDevices(): Boolean + + /** + * A live status regarding sharing keys for unverified devices in this room. + * + * @return Live status + */ + fun getLiveBlockUnverifiedDevices(roomId: String): LiveData + + /** + * Tell if unverified devices should be blacklisted when sending keys. + * + * @return true if should not send keys to unverified devices + */ + fun getBlockUnverifiedDevices(roomId: String): Boolean + + /** + * Retrieve a device by its identity key. + * + * @param userId the device owner + * @param identityKey the device identity key (`MXDeviceInfo.identityKey`) + * @return the device or null if not found + */ + fun deviceWithIdentityKey(userId: String, identityKey: String): CryptoDeviceInfo? + + /** + * Retrieve an inbound group session. + * Used in rust for lazy migration + * + * @param sessionId the session identifier. + * @param senderKey the base64-encoded curve25519 key of the sender. + * @return an inbound group session. + */ + fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper? +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt index 5a66e7e62d..150f06a18f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt @@ -26,11 +26,11 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.events.model.toValidDecryptedEvent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import timber.log.Timber import javax.inject.Inject -internal class EventEditValidator @Inject constructor(val cryptoStore: IMXCryptoStore) { +internal class EventEditValidator @Inject constructor(val cryptoStore: IMXCommonCryptoStore) { sealed class EditValidity { object Valid : EditValidity() @@ -80,25 +80,21 @@ internal class EventEditValidator @Inject constructor(val cryptoStore: IMXCrypto val replaceDecrypted = replaceEvent.toValidDecryptedEvent() ?: return EditValidity.Unknown // UTD can't decide - val originalCryptoSenderId = cryptoStore.deviceWithIdentityKey(originalDecrypted.cryptoSenderKey)?.userId - val editCryptoSenderId = cryptoStore.deviceWithIdentityKey(replaceDecrypted.cryptoSenderKey)?.userId + if (originalEvent.senderId != replaceEvent.senderId) { + return EditValidity.Invalid("original event and replacement event must have the same sender") + } + + val originalSendingDevice = originalEvent.senderId?.let { cryptoStore.deviceWithIdentityKey(it, originalDecrypted.cryptoSenderKey) } + val editSendingDevice = originalEvent.senderId?.let { cryptoStore.deviceWithIdentityKey(it, replaceDecrypted.cryptoSenderKey) } if (originalDecrypted.getRelationContent()?.type == RelationType.REPLACE) { return EditValidity.Invalid("The original event must not, itself, have a rel_type of m.replace ") } - if (originalCryptoSenderId == null || editCryptoSenderId == null) { + if (originalSendingDevice == null || editSendingDevice == null) { // mm what can we do? we don't know if it's cryptographically from same user? - // let valid and UI should display send by deleted device warning? - val bestEffortOriginal = originalCryptoSenderId ?: originalEvent.senderId - val bestEffortEdit = editCryptoSenderId ?: replaceEvent.senderId - if (bestEffortOriginal != bestEffortEdit) { - return EditValidity.Invalid("original event and replacement event must have the same sender") - } - } else { - if (originalCryptoSenderId != editCryptoSenderId) { - return EditValidity.Invalid("Crypto: original event and replacement event must have the same sender") - } + // maybe it's a deleted device or a not yet downloaded one? + return EditValidity.Unknown } if (originalDecrypted.type != replaceDecrypted.type) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt index d29e7d8f36..7176e36e0c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt @@ -49,7 +49,7 @@ import org.matrix.android.sdk.api.util.CancelableBag import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.NoOpCancellable import org.matrix.android.sdk.api.util.TextContent -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.content.UploadContentWorker @@ -69,7 +69,7 @@ internal class DefaultSendService @AssistedInject constructor( private val workManagerProvider: WorkManagerProvider, @SessionId private val sessionId: String, private val localEchoEventFactory: LocalEchoEventFactory, - private val cryptoStore: IMXCryptoStore, + private val cryptoStore: IMXCommonCryptoStore, private val taskExecutor: TaskExecutor, private val localEchoRepository: LocalEchoRepository, private val eventSenderProcessor: EventSenderProcessor, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt index 929fe7b9a6..9ce29c3c08 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt @@ -28,7 +28,7 @@ import org.matrix.android.sdk.api.failure.isLimitExceededError import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.util.Cancelable -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.task.CoroutineSequencer import org.matrix.android.sdk.internal.task.SemaphoreCoroutineSequencer @@ -54,7 +54,7 @@ private const val MAX_RETRY_COUNT = 3 */ @SessionScope internal class EventSenderProcessorCoroutine @Inject constructor( - private val cryptoStore: IMXCryptoStore, + private val cryptoStore: IMXCommonCryptoStore, private val sessionParams: SessionParams, private val queuedTaskFactory: QueuedTaskFactory, private val taskExecutor: TaskExecutor, diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index 876109a2a3..cdc5973fa1 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -58,8 +58,8 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionD import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore +import org.matrix.android.sdk.internal.crypto.store.RustCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask @@ -246,7 +246,7 @@ internal abstract class CryptoModule { abstract fun bindVerificationService(service: RustVerificationService): VerificationService @Binds - abstract fun bindCryptoStore(store: RealmCryptoStore): IMXCryptoStore + abstract fun bindCryptoStore(store: RustCryptoStore): IMXCommonCryptoStore @Binds abstract fun bindSendEventTask(task: DefaultSendEventTask): SendEventTask diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 2ff4d2d119..3686ab445d 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -54,6 +54,7 @@ import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.coroutines.builder.safeInvokeOnClose import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.DefaultKeysAlgorithmAndData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysAlgorithmAndData +import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.network.RequestSender import org.matrix.android.sdk.internal.crypto.verification.SasVerification import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest @@ -312,10 +313,10 @@ internal class OlmMachine @Inject constructor( /** * Used for lazy migration of inboundGroupSession from EA to ER */ - suspend fun importRoomKey(inbound: InboundGroupSessionHolder): Result { + suspend fun importRoomKey(inbound: MXInboundMegolmSessionWrapper): Result { Timber.v("Migration:: Tentative lazy migration") return withContext(coroutineDispatchers.io) { - val export = inbound.wrapper.exportKeys() + val export = inbound.exportKeys() ?: return@withContext Result.failure(Exception("Failed to export key")) val result = importDecryptedKeys(listOf(export), null).also { Timber.v("Migration:: Tentative lazy migration result: ${it.totalNumberOfKeys}") diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt index cce457f6a7..891e1fe3c0 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt @@ -28,7 +28,7 @@ import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService import org.matrix.android.sdk.internal.crypto.network.RequestSender -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.rustcomponents.sdk.crypto.EncryptionSettings @@ -47,7 +47,7 @@ private val loggerTag = LoggerTag("PrepareToEncryptUseCase", LoggerTag.CRYPTO) internal class PrepareToEncryptUseCase @Inject constructor( private val olmMachine: OlmMachine, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val cryptoStore: IMXCryptoStore, + private val cryptoStore: IMXCommonCryptoStore, private val getRoomUserIds: GetRoomUserIdsUseCase, private val requestSender: RequestSender, private val loadRoomMembersTask: LoadRoomMembersTask, diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index 6d96c2c836..1fa6c2c259 100755 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.crypto import android.content.Context -import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.lifecycle.map import androidx.paging.PagedList @@ -76,7 +75,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService import org.matrix.android.sdk.internal.crypto.model.SessionInfo import org.matrix.android.sdk.internal.crypto.network.OutgoingRequestsProcessor import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask @@ -111,7 +110,7 @@ internal class RustCryptoService @Inject constructor( @UserId private val myUserId: String, @DeviceId private val deviceId: String, // the crypto store - private val cryptoStore: IMXCryptoStore, + private val cryptoStore: IMXCommonCryptoStore, // Set of parameters used to configure/customize the end-to-end crypto. private val mxCryptoConfig: MXCryptoConfig, // Actions @@ -903,13 +902,6 @@ internal class RustCryptoService @Inject constructor( // TODO("Not yet implemented") } - /* ========================================================================================== - * For test only - * ========================================================================================== */ - - @VisibleForTesting - val cryptoStoreForTesting = cryptoStore - companion object { const val CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS = 3_600_000 // one hour } diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt index df041bbf19..b5212ee45a 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult @@ -36,7 +37,6 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.uia.UiaResult import org.matrix.android.sdk.internal.auth.registration.handleUIA -import org.matrix.android.sdk.internal.crypto.InboundGroupSessionStore import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.PerSessionBackupQueryRateLimiter import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult @@ -59,6 +59,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask @@ -102,7 +103,7 @@ internal class RequestSender @Inject constructor( private val moshi: Moshi, cryptoCoroutineScope: CoroutineScope, private val rateLimiter: PerSessionBackupQueryRateLimiter, - private val inboundGroupSessionStore: InboundGroupSessionStore, + private val cryptoStore: IMXCommonCryptoStore, private val localEchoRepository: LocalEchoRepository, private val olmMachine: Lazy, ) { @@ -266,7 +267,9 @@ internal class RequestSender @Inject constructor( val senderKey = requestBody?.get("sender_key") as? String if (roomId != null && sessionId != null) { // try to perform a lazy migration from legacy store - val legacy = inboundGroupSessionStore.getInboundGroupSession(sessionId, senderKey.orEmpty()) + val legacy = tryOrNull("Failed to access legacy crypto store") { + cryptoStore.getInboundGroupSession(sessionId, senderKey.orEmpty()) + } if (legacy == null || olmMachine.get().importRoomKey(legacy).isFailure) { rateLimiter.tryFromBackupIfPossible(sessionId, roomId) } diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt new file mode 100644 index 0000000000..9f3bd8d949 --- /dev/null +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt @@ -0,0 +1,351 @@ +/* + * Copyright 2023 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.store + +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations +import com.zhuinden.monarchy.Monarchy +import io.realm.Realm +import io.realm.RealmConfiguration +import io.realm.kotlin.where +import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.logger.LoggerTag +import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoRoomInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toOptional +import org.matrix.android.sdk.internal.crypto.OlmMachine +import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator +import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransaction +import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransactionAsync +import org.matrix.android.sdk.internal.crypto.store.db.doWithRealm +import org.matrix.android.sdk.internal.crypto.store.db.mapper.CryptoRoomInfoMapper +import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper +import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingKeyRequestEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey +import org.matrix.android.sdk.internal.crypto.store.db.query.getById +import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate +import org.matrix.android.sdk.internal.di.CryptoDatabase +import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.util.time.Clock +import timber.log.Timber +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +private val loggerTag = LoggerTag("RealmCryptoStore", LoggerTag.CRYPTO) + +/** + * In the transition phase, the rust SDK is still using parts to the realm crypto store, + * this should be removed after full migration + */ +@SessionScope +internal class RustCryptoStore @Inject constructor( + @CryptoDatabase private val realmConfiguration: RealmConfiguration, + private val clock: Clock, + private val myDeviceLastSeenInfoEntityMapper: MyDeviceLastSeenInfoEntityMapper, + private val olmMachine: dagger.Lazy, + private val matrixCoroutineDispatchers: MatrixCoroutineDispatchers, +) : IMXCommonCryptoStore { + + /** + * Retrieve a device by its identity key. + * + * @param identityKey the device identity key (`MXDeviceInfo.identityKey`) + * @return the device or null if not found + */ + override fun deviceWithIdentityKey(userId: String, identityKey: String): CryptoDeviceInfo? { + // XXX make this suspendable? + val knownDevices = runBlocking(matrixCoroutineDispatchers.io) { + olmMachine.get().getUserDevices(userId) + } + return knownDevices + .map { it.toCryptoDeviceInfo() } + .firstOrNull { + it.identityKey() == identityKey + } + } + + /** + * Needed for lazy migration of sessions from the legacy store + */ + override fun getInboundGroupSession(sessionId: String, senderKey: String): MXInboundMegolmSessionWrapper? { + val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey) + + return doWithRealm(realmConfiguration) { realm -> + realm.where() + .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) + .findFirst() + ?.toModel() + } + } + + // ================================================ + // Things that should be migrated to another store than realm + // ================================================ + + private val monarchyWriteAsyncExecutor = Executors.newSingleThreadExecutor() + + private val monarchy = Monarchy.Builder() + .setRealmConfiguration(realmConfiguration) + .setWriteAsyncExecutor(monarchyWriteAsyncExecutor) + .build() + + override fun open() { + // nop + } + + override fun tidyUpDataBase() { + // These entities are not used in rust actually, but as they are not yet cleaned up, this will do it with time + val prevWeekTs = clock.epochMillis() - 7 * 24 * 60 * 60 * 1_000 + doRealmTransaction("tidyUpDataBase", realmConfiguration) { realm -> + + // Clean the old ones? + realm.where() + .lessThan(OutgoingKeyRequestEntityFields.CREATION_TIME_STAMP, prevWeekTs) + .findAll() + .also { Timber.i("## Crypto Clean up ${it.size} OutgoingKeyRequestEntity") } + .deleteAllFromRealm() + + // Only keep one month history + + val prevMonthTs = clock.epochMillis() - 4 * 7 * 24 * 60 * 60 * 1_000L + realm.where() + .lessThan(AuditTrailEntityFields.AGE_LOCAL_TS, prevMonthTs) + .findAll() + .also { Timber.i("## Crypto Clean up ${it.size} AuditTrailEntity") } + .deleteAllFromRealm() + + // Can we do something for WithHeldSessionEntity? + } + } + + override fun close() { + val tasks = monarchyWriteAsyncExecutor.shutdownNow() + Timber.w("Closing RealmCryptoStore, ${tasks.size} async task(s) cancelled") + tryOrNull("Interrupted") { + // Wait 1 minute max + monarchyWriteAsyncExecutor.awaitTermination(1, TimeUnit.MINUTES) + } + } + + override fun getRoomAlgorithm(roomId: String): String? { + return doWithRealm(realmConfiguration) { + CryptoRoomEntity.getById(it, roomId)?.algorithm + } + } + + override fun getRoomCryptoInfo(roomId: String): CryptoRoomInfo? { + return doWithRealm(realmConfiguration) { realm -> + CryptoRoomEntity.getById(realm, roomId)?.let { + CryptoRoomInfoMapper.map(it) + } + } + } + + /** + * This is a bit different than isRoomEncrypted. + * A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not). + * But the crypto layer has additional guaranty to ensure that encryption would never been reverted. + * It's defensive coding out of precaution (if ever state is reset). + */ + override fun roomWasOnceEncrypted(roomId: String): Boolean { + return doWithRealm(realmConfiguration) { + CryptoRoomEntity.getById(it, roomId)?.wasEncryptedOnce ?: false + } + } + + override fun setAlgorithmInfo(roomId: String, encryption: EncryptionEventContent?) { + doRealmTransaction("setAlgorithmInfo", realmConfiguration) { + CryptoRoomEntity.getOrCreate(it, roomId).let { entity -> + entity.algorithm = encryption?.algorithm + // store anyway the new algorithm, but mark the room + // as having been encrypted once whatever, this can never + // go back to false + if (encryption?.algorithm == MXCRYPTO_ALGORITHM_MEGOLM) { + entity.wasEncryptedOnce = true + entity.rotationPeriodMs = encryption.rotationPeriodMs + entity.rotationPeriodMsgs = encryption.rotationPeriodMsgs + } + } + } + } + + override fun saveMyDevicesInfo(info: List) { + val entities = info.map { myDeviceLastSeenInfoEntityMapper.map(it) } + doRealmTransactionAsync(realmConfiguration) { realm -> + realm.where().findAll().deleteAllFromRealm() + entities.forEach { + realm.insertOrUpdate(it) + } + } + } + + override fun getMyDevicesInfo(): List { + return monarchy.fetchAllCopiedSync { + it.where() + }.map { + DeviceInfo( + deviceId = it.deviceId, + lastSeenIp = it.lastSeenIp, + lastSeenTs = it.lastSeenTs, + displayName = it.displayName + ) + } + } + + override fun getLiveMyDevicesInfo(): LiveData> { + return monarchy.findAllMappedWithChanges( + { realm: Realm -> + realm.where() + }, + { entity -> myDeviceLastSeenInfoEntityMapper.map(entity) } + ) + } + + override fun getLiveMyDevicesInfo(deviceId: String): LiveData> { + val liveData = monarchy.findAllMappedWithChanges( + { realm: Realm -> + realm.where() + .equalTo(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, deviceId) + }, + { entity -> myDeviceLastSeenInfoEntityMapper.map(entity) } + ) + + return Transformations.map(liveData) { + it.firstOrNull().toOptional() + } + } + + override fun storeData(cryptoStoreAggregator: CryptoStoreAggregator) { + if (cryptoStoreAggregator.isEmpty()) { + return + } + doRealmTransaction("storeData - CryptoStoreAggregator", realmConfiguration) { realm -> + // setShouldShareHistory + cryptoStoreAggregator.setShouldShareHistoryData.forEach { + Timber.tag(loggerTag.value) + .v("setShouldShareHistory for room ${it.key} is ${it.value}") + CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value + } + // setShouldEncryptForInvitedMembers + cryptoStoreAggregator.setShouldEncryptForInvitedMembersData.forEach { + CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value + } + } + } + + override fun shouldEncryptForInvitedMembers(roomId: String): Boolean { + return doWithRealm(realmConfiguration) { + CryptoRoomEntity.getById(it, roomId)?.shouldEncryptForInvitedMembers + } + ?: false + } + + override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) { + Timber.tag(loggerTag.value) + .v("setShouldShareHistory for room $roomId is $shouldShareHistory") + doRealmTransaction("setShouldShareHistory", realmConfiguration) { + CryptoRoomEntity.getOrCreate(it, roomId).shouldShareHistory = shouldShareHistory + } + } + + override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) { + doRealmTransaction("setShouldEncryptForInvitedMembers", realmConfiguration) { + CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers + } + } + + override fun blockUnverifiedDevicesInRoom(roomId: String, block: Boolean) { + doRealmTransaction("blockUnverifiedDevicesInRoom", realmConfiguration) { realm -> + CryptoRoomEntity.getById(realm, roomId) + ?.blacklistUnverifiedDevices = block + } + } + + override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) { + doRealmTransaction("setGlobalBlacklistUnverifiedDevices", realmConfiguration) { + it.where().findFirst()?.globalBlacklistUnverifiedDevices = block + } + } + + override fun getLiveGlobalCryptoConfig(): LiveData { + val liveData = monarchy.findAllMappedWithChanges( + { realm: Realm -> + realm + .where() + }, + { + GlobalCryptoConfig( + globalBlockUnverifiedDevices = it.globalBlacklistUnverifiedDevices, + globalEnableKeyGossiping = it.globalEnableKeyGossiping, + enableKeyForwardingOnInvite = it.enableKeyForwardingOnInvite + ) + } + ) + return Transformations.map(liveData) { + it.firstOrNull() ?: GlobalCryptoConfig(false, false, false) + } + } + + override fun getGlobalBlacklistUnverifiedDevices(): Boolean { + return doWithRealm(realmConfiguration) { + it.where().findFirst()?.globalBlacklistUnverifiedDevices + } ?: false + } + + override fun getLiveBlockUnverifiedDevices(roomId: String): LiveData { + val liveData = monarchy.findAllMappedWithChanges( + { realm: Realm -> + realm.where() + .equalTo(CryptoRoomEntityFields.ROOM_ID, roomId) + }, + { + it.blacklistUnverifiedDevices + } + ) + return Transformations.map(liveData) { + it.firstOrNull() ?: false + } + } + + override fun getBlockUnverifiedDevices(roomId: String): Boolean { + return doWithRealm(realmConfiguration) { realm -> + realm.where() + .equalTo(CryptoRoomEntityFields.ROOM_ID, roomId) + .findFirst() + ?.blacklistUnverifiedDevices ?: false + } + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/EventEditValidatorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/EventEditValidatorTest.kt index 0ae712bff1..113dc4ce83 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/EventEditValidatorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/EventEditValidatorTest.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore class EventEditValidatorTest { @@ -62,7 +62,7 @@ class EventEditValidatorTest { @Test fun `edit should be valid`() { - val mockCryptoStore = mockk() + val mockCryptoStore = mockk() val validator = EventEditValidator(mockCryptoStore) validator @@ -71,7 +71,7 @@ class EventEditValidatorTest { @Test fun `original event and replacement event must have the same sender`() { - val mockCryptoStore = mockk() + val mockCryptoStore = mockk() val validator = EventEditValidator(mockCryptoStore) validator @@ -83,7 +83,7 @@ class EventEditValidatorTest { @Test fun `original event and replacement event must have the same room_id`() { - val mockCryptoStore = mockk() + val mockCryptoStore = mockk() val validator = EventEditValidator(mockCryptoStore) validator @@ -101,7 +101,7 @@ class EventEditValidatorTest { @Test fun `replacement and original events must not have a state_key property`() { - val mockCryptoStore = mockk() + val mockCryptoStore = mockk() val validator = EventEditValidator(mockCryptoStore) validator @@ -119,8 +119,8 @@ class EventEditValidatorTest { @Test fun `replacement event must have an new_content property`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } @@ -157,8 +157,8 @@ class EventEditValidatorTest { @Test fun `The original event must not itself have a rel_type of m_replace`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } @@ -207,8 +207,8 @@ class EventEditValidatorTest { @Test fun `valid e2ee edit`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } @@ -224,8 +224,8 @@ class EventEditValidatorTest { @Test fun `If the original event was encrypted, the replacement should be too`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } @@ -241,12 +241,12 @@ class EventEditValidatorTest { @Test fun `encrypted, original event and replacement event must have the same sender`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } - every { deviceWithIdentityKey("7V5e/2O93mf4GeW7Mtq4YWcRNpYS9NhQbdJMgdnIPUI") } returns + every { deviceWithIdentityKey("@bob:example.com", "7V5e/2O93mf4GeW7Mtq4YWcRNpYS9NhQbdJMgdnIPUI") } returns mockk { every { userId } returns "@bob:example.com" } @@ -256,7 +256,9 @@ class EventEditValidatorTest { validator .validateEdit( encryptedEvent, - encryptedEditEvent.copy().apply { + encryptedEditEvent.copy( + senderId = "@bob:example.com" + ).apply { mxDecryptionResult = encryptedEditEvent.mxDecryptionResult!!.copy( senderKey = "7V5e/2O93mf4GeW7Mtq4YWcRNpYS9NhQbdJMgdnIPUI" ) @@ -269,12 +271,12 @@ class EventEditValidatorTest { @Test fun `encrypted, sent fom a deleted device, original event and replacement event must have the same sender`() { - val mockCryptoStore = mockk { - every { deviceWithIdentityKey("R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns + val mockCryptoStore = mockk { + every { deviceWithIdentityKey("@alice:example.com", "R0s/7Aindgg/RNWqUGJyJOXtCz5H7Gx7fInFuroq1xo") } returns mockk { every { userId } returns "@alice:example.com" } - every { deviceWithIdentityKey("7V5e/2O93mf4GeW7Mtq4YWcRNpYS9NhQbdJMgdnIPUI") } returns + every { deviceWithIdentityKey(any(), "7V5e/2O93mf4GeW7Mtq4YWcRNpYS9NhQbdJMgdnIPUI") } returns null } val validator = EventEditValidator(mockCryptoStore) @@ -288,7 +290,7 @@ class EventEditValidatorTest { ) } - ) shouldBeInstanceOf EventEditValidator.EditValidity.Valid::class + ) shouldBeInstanceOf EventEditValidator.EditValidity.Unknown::class validator .validateEdit( From a2ef95584f090faaf82fb89494c9fc65c6501074 Mon Sep 17 00:00:00 2001 From: valere Date: Fri, 26 May 2023 10:17:48 +0200 Subject: [PATCH 27/48] Add changelog --- changelog.d/8470.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/8470.misc diff --git a/changelog.d/8470.misc b/changelog.d/8470.misc new file mode 100644 index 0000000000..c2a44c430a --- /dev/null +++ b/changelog.d/8470.misc @@ -0,0 +1 @@ +Refactoring: Extract a new interface for common access to crypto store between kotlin and rust crypto From ac916078bc4a3ae1582144911a86a5aa03b00233 Mon Sep 17 00:00:00 2001 From: valere Date: Fri, 26 May 2023 16:04:25 +0200 Subject: [PATCH 28/48] fix test compilation --- .../org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt | 0 .../org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename matrix-sdk-android/src/{androidTest => androidTestKotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt (100%) rename matrix-sdk-android/src/{androidTest => androidTestKotlinCrypto}/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt (100%) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt b/matrix-sdk-android/src/androidTestKotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt similarity index 100% rename from matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt rename to matrix-sdk-android/src/androidTestKotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt b/matrix-sdk-android/src/androidTestKotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt similarity index 100% rename from matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt rename to matrix-sdk-android/src/androidTestKotlinCrypto/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt From 24b18847b560e43093d19b6e073c3ad6623be06c Mon Sep 17 00:00:00 2001 From: Alex Maras Date: Fri, 26 May 2023 23:03:24 +0800 Subject: [PATCH 29/48] Fix animated webp playback (#8120) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: add webp as playable image type * fix: make glide transformations optional to prevent rendering webp throwing exception * fix: stop marking webp as playable by default * fix: play animated Webp in attachment view * feat: autoplay webp if autoplay is enabled --------- Signed-off-by: Alex Maras Co-authored-by: Jorge Martín --- changelog.d/8120.feature | 1 + .../main/java/org/matrix/android/sdk/api/util/MimeTypes.kt | 1 + .../home/room/detail/timeline/factory/MessageItemFactory.kt | 4 +++- .../vector/app/features/media/DataAttachmentRoomProvider.kt | 2 +- .../im/vector/app/features/media/ImageContentRenderer.kt | 6 +++--- .../app/features/media/RoomEventsAttachmentProvider.kt | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 changelog.d/8120.feature diff --git a/changelog.d/8120.feature b/changelog.d/8120.feature new file mode 100644 index 0000000000..906ec2b819 --- /dev/null +++ b/changelog.d/8120.feature @@ -0,0 +1 @@ +Marks WebP files as Animated and allows them to play diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt index 5ec0dedadf..af8ab71a87 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MimeTypes.kt @@ -30,6 +30,7 @@ object MimeTypes { const val BadJpg = "image/jpg" const val Jpeg = "image/jpeg" const val Gif = "image/gif" + const val Webp = "image/webp" const val Ogg = "audio/ogg" diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 09b91cc4f1..5f8883fdfe 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -528,6 +528,8 @@ class MessageItemFactory @Inject constructor( ) val playable = messageContent.mimeType == MimeTypes.Gif + // don't show play button because detecting animated webp isn't possible via mimetype + val playableIfAutoplay = playable || messageContent.mimeType == MimeTypes.Webp return MessageImageVideoItem_() .attributes(attributes) @@ -549,7 +551,7 @@ class MessageItemFactory @Inject constructor( } } }.apply { - if (playable && vectorPreferences.autoplayAnimatedImages()) { + if (playableIfAutoplay && vectorPreferences.autoplayAnimatedImages()) { mode(ImageContentRenderer.Mode.ANIMATED_THUMBNAIL) } } diff --git a/vector/src/main/java/im/vector/app/features/media/DataAttachmentRoomProvider.kt b/vector/src/main/java/im/vector/app/features/media/DataAttachmentRoomProvider.kt index 0924532bc2..a0354f3d60 100644 --- a/vector/src/main/java/im/vector/app/features/media/DataAttachmentRoomProvider.kt +++ b/vector/src/main/java/im/vector/app/features/media/DataAttachmentRoomProvider.kt @@ -49,7 +49,7 @@ class DataAttachmentRoomProvider( return getItem(position).let { when (it) { is ImageContentRenderer.Data -> { - if (it.mimeType == MimeTypes.Gif) { + if (it.mimeType == MimeTypes.Gif || it.mimeType == MimeTypes.Webp) { AttachmentInfo.AnimatedImage( uid = it.eventId, url = it.url ?: "", diff --git a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt index baad815df2..876812cea0 100644 --- a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt @@ -135,7 +135,7 @@ class ImageContentRenderer @Inject constructor( if (mode == Mode.ANIMATED_THUMBNAIL) it else it.dontAnimate() } - .transform(cornerTransformation) + .optionalTransform(cornerTransformation) .into(imageView) } @@ -167,7 +167,7 @@ class ImageContentRenderer @Inject constructor( } req - .fitCenter() + .optionalFitCenter() .into(target) } @@ -211,7 +211,7 @@ class ImageContentRenderer @Inject constructor( return false } }) - .fitCenter() + .optionalFitCenter() .into(imageView) } diff --git a/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt b/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt index e18a13a3e6..f833a33b87 100644 --- a/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt +++ b/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt @@ -71,7 +71,7 @@ class RoomEventsAttachmentProvider( allowNonMxcUrls = it.root.sendState.isSending() ) - if (content.mimeType == MimeTypes.Gif) { + if (content.mimeType == MimeTypes.Gif || content.mimeType == MimeTypes.Webp) { AttachmentInfo.AnimatedImage( uid = it.eventId, url = content.url ?: "", From b37eca45208fba32bf440e21af06e20bb17350f9 Mon Sep 17 00:00:00 2001 From: valere Date: Fri, 26 May 2023 18:22:47 +0200 Subject: [PATCH 30/48] fix rust crypto still need CryptoMetadataEntity for global pref --- .../internal/crypto/store/RustCryptoStore.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt index 9f3bd8d949..b242a3ed34 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/store/RustCryptoStore.kt @@ -57,6 +57,8 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey import org.matrix.android.sdk.internal.crypto.store.db.query.getById import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate import org.matrix.android.sdk.internal.di.CryptoDatabase +import org.matrix.android.sdk.internal.di.DeviceId +import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber @@ -74,11 +76,45 @@ private val loggerTag = LoggerTag("RealmCryptoStore", LoggerTag.CRYPTO) internal class RustCryptoStore @Inject constructor( @CryptoDatabase private val realmConfiguration: RealmConfiguration, private val clock: Clock, + @UserId private val userId: String, + @DeviceId private val deviceId: String, private val myDeviceLastSeenInfoEntityMapper: MyDeviceLastSeenInfoEntityMapper, private val olmMachine: dagger.Lazy, private val matrixCoroutineDispatchers: MatrixCoroutineDispatchers, ) : IMXCommonCryptoStore { + // still needed on rust due to the global crypto settings + init { + // Ensure CryptoMetadataEntity is inserted in DB + doRealmTransaction("init", realmConfiguration) { realm -> + var currentMetadata = realm.where().findFirst() + + var deleteAll = false + + if (currentMetadata != null) { + // Check credentials + // The device id may not have been provided in credentials. + // Check it only if provided, else trust the stored one. + if (currentMetadata.userId != userId || deviceId != currentMetadata.deviceId) { + Timber.w("## open() : Credentials do not match, close this store and delete data") + deleteAll = true + currentMetadata = null + } + } + + if (currentMetadata == null) { + if (deleteAll) { + realm.deleteAll() + } + + // Metadata not found, or database cleaned, create it + realm.createObject(CryptoMetadataEntity::class.java, userId).apply { + deviceId = this@RustCryptoStore.deviceId + } + } + } + } + /** * Retrieve a device by its identity key. * From 7e1659b1f966b56e59021fd46f42ec4d81c15a07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 12:40:02 +0000 Subject: [PATCH 31/48] Bump androidx.activity:activity-ktx from 1.7.1 to 1.7.2 (#8465) --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index ca5495b04d..f4d32c4894 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -47,7 +47,7 @@ ext.libs = [ 'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines" ], androidx : [ - 'activity' : "androidx.activity:activity-ktx:1.7.1", + 'activity' : "androidx.activity:activity-ktx:1.7.2", 'appCompat' : "androidx.appcompat:appcompat:1.6.1", 'biometric' : "androidx.biometric:biometric:1.1.0", 'core' : "androidx.core:core-ktx:1.10.1", From 268cbb83cd0ee4f70e9c9b2f058c7b77e7289392 Mon Sep 17 00:00:00 2001 From: valere Date: Tue, 30 May 2023 23:47:50 +0200 Subject: [PATCH 32/48] Make cryptoDevice calls suspendable --- changelog.d/8482.bugfix | 1 + .../internal/crypto/DefaultCryptoService.kt | 4 ++-- .../sdk/api/session/crypto/CryptoService.kt | 4 ++-- .../session/room/read/DefaultReadService.kt | 7 ++++-- .../sdk/internal/crypto/RustCryptoService.kt | 4 ++-- .../troubleshoot/TestTokenRegistration.kt | 23 +++++++++++-------- .../im/vector/app/push/fcm/GoogleFcmHelper.kt | 12 +++++++++- .../fcm/VectorFirebaseMessagingService.kt | 14 ++++++++++- .../app/core/device/GetDeviceInfoUseCase.kt | 4 ++-- .../vector/app/core/pushers/PushersManager.kt | 6 ++--- .../VectorUnifiedPushMessagingReceiver.kt | 4 +++- .../self/SelfVerificationController.kt | 2 +- .../self/SelfVerificationViewModel.kt | 23 ++++++++++++------- .../UnknownDeviceDetectorSharedViewModel.kt | 11 +++++---- .../TestEndpointAsTokenRegistration.kt | 11 ++++++--- 15 files changed, 88 insertions(+), 42 deletions(-) create mode 100644 changelog.d/8482.bugfix diff --git a/changelog.d/8482.bugfix b/changelog.d/8482.bugfix new file mode 100644 index 0000000000..3e4184b3bf --- /dev/null +++ b/changelog.d/8482.bugfix @@ -0,0 +1 @@ +fix: Make some crypto calls suspendable to avoid reported ANR diff --git a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index f948063c77..b25c04aa9b 100755 --- a/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/kotlinCrypto/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -256,7 +256,7 @@ internal class DefaultCryptoService @Inject constructor( return if (longFormat) olmManager.getDetailedVersion(context) else olmManager.version } - override fun getMyCryptoDevice(): CryptoDeviceInfo { + override suspend fun getMyCryptoDevice(): CryptoDeviceInfo { return myDeviceInfoHolder.get().myDevice } @@ -536,7 +536,7 @@ internal class DefaultCryptoService @Inject constructor( // .executeBy(taskExecutor) // } - override fun getCryptoDeviceInfo(userId: String): List { + override suspend fun getCryptoDeviceInfo(userId: String): List { return cryptoStore.getUserDeviceList(userId).orEmpty() } // diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 043d0a29f5..31d11f6730 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -73,7 +73,7 @@ interface CryptoService { suspend fun getUserDevices(userId: String): List - fun getMyCryptoDevice(): CryptoDeviceInfo + suspend fun getMyCryptoDevice(): CryptoDeviceInfo fun getGlobalBlacklistUnverifiedDevices(): Boolean @@ -130,7 +130,7 @@ interface CryptoService { suspend fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? - fun getCryptoDeviceInfo(userId: String): List + suspend fun getCryptoDeviceInfo(userId: String): List // fun getCryptoDeviceInfoFlow(userId: String): Flow> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/DefaultReadService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/DefaultReadService.kt index 36ec5e8dac..73b7ae05fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/DefaultReadService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/DefaultReadService.kt @@ -22,6 +22,8 @@ import com.zhuinden.monarchy.Monarchy import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.room.model.ReadReceipt import org.matrix.android.sdk.api.session.room.read.ReadService import org.matrix.android.sdk.api.util.Optional @@ -43,7 +45,8 @@ internal class DefaultReadService @AssistedInject constructor( private val setReadMarkersTask: SetReadMarkersTask, private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper, @UserId private val userId: String, - private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource + private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource, + private val matrixCoroutineDispatchers: MatrixCoroutineDispatchers, ) : ReadService { @AssistedFactory @@ -66,7 +69,7 @@ internal class DefaultReadService @AssistedInject constructor( setReadMarkersTask.execute(taskParams) } - override suspend fun setReadReceipt(eventId: String, threadId: String) { + override suspend fun setReadReceipt(eventId: String, threadId: String) = withContext(matrixCoroutineDispatchers.io) { val readReceiptThreadId = if (homeServerCapabilitiesDataSource.getHomeServerCapabilities()?.canUseThreadReadReceiptsAndNotifications == true) { threadId } else { diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index 1fa6c2c259..df435d024b 100755 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -344,8 +344,8 @@ internal class RustCryptoService @Inject constructor( return olmMachine.getCryptoDeviceInfo(userId, deviceId) } - override fun getCryptoDeviceInfo(userId: String): List { - return runBlocking { + override suspend fun getCryptoDeviceInfo(userId: String): List { + return withContext(coroutineDispatchers.io) { olmMachine.getCryptoDeviceInfo(userId) } } diff --git a/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt index cafc2d65e6..313073da4d 100644 --- a/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt +++ b/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt @@ -17,6 +17,7 @@ package im.vector.app.gplay.features.settings.troubleshoot import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope import androidx.work.WorkInfo import androidx.work.WorkManager import im.vector.app.R @@ -25,6 +26,8 @@ import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager import im.vector.app.core.resources.StringProvider import im.vector.app.features.settings.troubleshoot.TroubleshootTest +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.pushers.PusherState import javax.inject.Inject @@ -60,16 +63,18 @@ class TestTokenRegistration @Inject constructor( ) quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_token_registration_quick_fix) { override fun doFix() { - val workId = pushersManager.enqueueRegisterPusherWithFcmKey(fcmToken) - WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context, Observer { workInfo -> - if (workInfo != null) { - if (workInfo.state == WorkInfo.State.SUCCEEDED) { - manager?.retry(testParameters) - } else if (workInfo.state == WorkInfo.State.FAILED) { - manager?.retry(testParameters) + context.lifecycleScope.launch(Dispatchers.IO) { + val workId = pushersManager.enqueueRegisterPusherWithFcmKey(fcmToken) + WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context, Observer { workInfo -> + if (workInfo != null) { + if (workInfo.state == WorkInfo.State.SUCCEEDED) { + manager?.retry(testParameters) + } else if (workInfo.state == WorkInfo.State.FAILED) { + manager?.retry(testParameters) + } } - } - }) + }) + } } } diff --git a/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt b/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt index 53e65f88b4..676cd0258f 100755 --- a/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt +++ b/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt @@ -26,8 +26,11 @@ import dagger.hilt.android.qualifiers.ApplicationContext import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.DefaultPreferences +import im.vector.app.core.dispatchers.CoroutineDispatchers import im.vector.app.core.pushers.FcmHelper import im.vector.app.core.pushers.PushersManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -38,7 +41,12 @@ import javax.inject.Inject class GoogleFcmHelper @Inject constructor( @ApplicationContext private val context: Context, @DefaultPreferences private val sharedPrefs: SharedPreferences, + appScope: CoroutineScope, + private val coroutineDispatchers: CoroutineDispatchers ) : FcmHelper { + + private val scope = CoroutineScope(appScope.coroutineContext + coroutineDispatchers.io) + companion object { private const val PREFS_KEY_FCM_TOKEN = "FCM_TOKEN" } @@ -64,7 +72,9 @@ class GoogleFcmHelper @Inject constructor( .addOnSuccessListener { token -> storeFcmToken(token) if (registerPusher) { - pushersManager.enqueueRegisterPusherWithFcmKey(token) + scope.launch { + pushersManager.enqueueRegisterPusherWithFcmKey(token) + } } } .addOnFailureListener { e -> diff --git a/vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt index 7fd55bd165..6ab9b90a84 100644 --- a/vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt @@ -27,6 +27,10 @@ import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.UnifiedPushHelper import im.vector.app.core.pushers.VectorPushHandler import im.vector.app.features.settings.VectorPreferences +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.logger.LoggerTag import timber.log.Timber import javax.inject.Inject @@ -43,6 +47,12 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { @Inject lateinit var vectorPushHandler: VectorPushHandler @Inject lateinit var unifiedPushHelper: UnifiedPushHelper + private val scope = CoroutineScope(SupervisorJob()) + + override fun onDestroy() { + scope.cancel() + super.onDestroy() + } override fun onNewToken(token: String) { Timber.tag(loggerTag.value).d("New Firebase token") fcmHelper.storeFcmToken(token) @@ -51,7 +61,9 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { activeSessionHolder.hasActiveSession() && unifiedPushHelper.isEmbeddedDistributor() ) { - pushersManager.enqueueRegisterPusher(token, getString(R.string.pusher_http_url)) + scope.launch { + pushersManager.enqueueRegisterPusher(token, getString(R.string.pusher_http_url)) + } } } diff --git a/vector/src/main/java/im/vector/app/core/device/GetDeviceInfoUseCase.kt b/vector/src/main/java/im/vector/app/core/device/GetDeviceInfoUseCase.kt index 4a66988b46..a97fa32a61 100644 --- a/vector/src/main/java/im/vector/app/core/device/GetDeviceInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/core/device/GetDeviceInfoUseCase.kt @@ -22,14 +22,14 @@ import javax.inject.Inject interface GetDeviceInfoUseCase { - fun execute(): CryptoDeviceInfo + suspend fun execute(): CryptoDeviceInfo } class DefaultGetDeviceInfoUseCase @Inject constructor( private val activeSessionHolder: ActiveSessionHolder ) : GetDeviceInfoUseCase { - override fun execute(): CryptoDeviceInfo { + override suspend fun execute(): CryptoDeviceInfo { return activeSessionHolder.getActiveSession().cryptoService().getMyCryptoDevice() } } diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt index fb78feaef1..402471ecef 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt @@ -49,11 +49,11 @@ class PushersManager @Inject constructor( ) } - fun enqueueRegisterPusherWithFcmKey(pushKey: String): UUID { + suspend fun enqueueRegisterPusherWithFcmKey(pushKey: String): UUID { return enqueueRegisterPusher(pushKey, stringProvider.getString(R.string.pusher_http_url)) } - fun enqueueRegisterPusher( + suspend fun enqueueRegisterPusher( pushKey: String, gateway: String ): UUID { @@ -62,7 +62,7 @@ class PushersManager @Inject constructor( return currentSession.pushersService().enqueueAddHttpPusher(pusher) } - private fun createHttpPusher( + private suspend fun createHttpPusher( pushKey: String, gateway: String ) = HttpPusher( diff --git a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt index 838cbd5935..f0e5cd2c2c 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/VectorUnifiedPushMessagingReceiver.kt @@ -76,7 +76,9 @@ class VectorUnifiedPushMessagingReceiver : MessagingReceiver() { coroutineScope.launch { unifiedPushHelper.storeCustomOrDefaultGateway(endpoint) { unifiedPushHelper.getPushGateway()?.let { - pushersManager.enqueueRegisterPusher(endpoint, it) + coroutineScope.launch { + pushersManager.enqueueRegisterPusher(endpoint, it) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt index 4097cf957b..9871d21601 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationController.kt @@ -275,7 +275,7 @@ class SelfVerificationController @Inject constructor( id("notice_div") } // Option to verify with another device - if (state.hasAnyOtherSession) { + if (state.hasAnyOtherSession.invoke() == true) { bottomSheetVerificationActionItem { id("start") title(host.stringProvider.getString(R.string.verification_verify_with_another_device)) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt index e92616f7df..ded10467a9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt @@ -83,7 +83,7 @@ data class SelfVerificationViewState( val transactionId: String? = null, val currentDeviceCanCrossSign: Boolean = false, val userWantsToCancel: Boolean = false, - val hasAnyOtherSession: Boolean = false, + val hasAnyOtherSession: Async = Uninitialized, val quadSContainsSecrets: Boolean = false, val isVerificationRequired: Boolean = false, val isThisSessionVerified: Boolean = false, @@ -146,21 +146,28 @@ class SelfVerificationViewModel @AssistedInject constructor( } } - val hasAnyOtherSession = session.cryptoService() - .getCryptoDeviceInfo(session.myUserId) - .any { - it.deviceId != session.sessionParams.deviceId - } + setState { copy(hasAnyOtherSession = Loading()) } + viewModelScope.launch(Dispatchers.IO) { + val hasAnyOtherSession = session.cryptoService() + .getCryptoDeviceInfo(session.myUserId) + .any { + it.deviceId != session.sessionParams.deviceId + } + setState { + copy( + hasAnyOtherSession = Success(hasAnyOtherSession) + ) + } + } setState { copy( currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(), quadSContainsSecrets = session.sharedSecretStorageService().isRecoverySetup(), - hasAnyOtherSession = hasAnyOtherSession ) } - viewModelScope.launch { + viewModelScope.launch(Dispatchers.IO) { val isThisSessionVerified = session.cryptoService().crossSigningService().isCrossSigningVerified() setState { copy( diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 28016f109f..6ba5976eb8 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -92,11 +92,6 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor( } init { - val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId) - .firstOrNull { it.deviceId == session.sessionParams.deviceId } - ?.firstTimeSeenLocalTs - ?: clock.epochMillis() - Timber.v("## Detector - Current Session first time seen $currentSessionTs") combine( session.flow().liveUserCryptoDevices(session.myUserId), @@ -108,6 +103,12 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor( deleteUnusedClientInformation(infoList) + val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId) + .firstOrNull { it.deviceId == session.sessionParams.deviceId } + ?.firstTimeSeenLocalTs + ?: clock.epochMillis() + Timber.v("## Detector - Current Session first time seen $currentSessionTs") + infoList .asSequence() .filter { diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt index b355b55903..6489fe537d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestEndpointAsTokenRegistration.kt @@ -17,6 +17,7 @@ package im.vector.app.features.settings.troubleshoot import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.lifecycleScope import androidx.work.WorkInfo import androidx.work.WorkManager import im.vector.app.R @@ -72,13 +73,15 @@ class TestEndpointAsTokenRegistration @Inject constructor( } private fun unregisterThenRegister(testParameters: TestParameters, pushKey: String) { - activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch { + val scope = activeSessionHolder.getSafeActiveSession()?.coroutineScope ?: return + val io = activeSessionHolder.getActiveSession().coroutineDispatchers.io + scope.launch(io) { unregisterUnifiedPushUseCase.execute(pushersManager) registerUnifiedPush(distributor = "", testParameters, pushKey) } } - private fun registerUnifiedPush( + private suspend fun registerUnifiedPush( distributor: String, testParameters: TestParameters, pushKey: String, @@ -106,7 +109,9 @@ class TestEndpointAsTokenRegistration @Inject constructor( pushKey: String, ) { unifiedPushHelper.showSelectDistributorDialog(context) { selection -> - registerUnifiedPush(distributor = selection, testParameters, pushKey) + context.lifecycleScope.launch { + registerUnifiedPush(distributor = selection, testParameters, pushKey) + } } } } From b59068b46376c121aeea126ac5b68d6a989807a1 Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 09:52:43 +0200 Subject: [PATCH 33/48] missing suspend --- .../android/sdk/internal/crypto/RustCryptoService.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index df435d024b..33fc13e728 100755 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.MatrixCoroutineDispatchers @@ -188,8 +187,8 @@ internal class RustCryptoService @Inject constructor( return if (longFormat) "Rust SDK $version, Vodozemac $vodozemac" else version } - override fun getMyCryptoDevice(): CryptoDeviceInfo { - return runBlocking { olmMachine.ownDevice() } + override suspend fun getMyCryptoDevice(): CryptoDeviceInfo = withContext(coroutineDispatchers.io) { + olmMachine.ownDevice() } override suspend fun fetchDevicesList(): List { @@ -341,7 +340,7 @@ internal class RustCryptoService @Inject constructor( */ override suspend fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { if (userId.isEmpty() || deviceId.isNullOrEmpty()) return null - return olmMachine.getCryptoDeviceInfo(userId, deviceId) + return withContext(coroutineDispatchers.io) { olmMachine.getCryptoDeviceInfo(userId, deviceId) } } override suspend fun getCryptoDeviceInfo(userId: String): List { From 2d335c13079327e9095d120f66a3b9c77cb34945 Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 10:42:46 +0200 Subject: [PATCH 34/48] fix unit test --- .../app/core/device/DefaultGetDeviceInfoUseCaseTest.kt | 3 ++- .../java/im/vector/app/core/pushers/PushersManagerTest.kt | 5 ++++- .../test/java/im/vector/app/test/fakes/FakeCryptoService.kt | 2 +- .../im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt index 0673fbadb5..5dc0936184 100644 --- a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt @@ -19,6 +19,7 @@ package im.vector.app.core.device import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeCryptoService import im.vector.app.test.fakes.FakeSession +import kotlinx.coroutines.runBlocking import org.amshove.kluent.shouldBeEqualTo import org.junit.Test @@ -32,7 +33,7 @@ class DefaultGetDeviceInfoUseCaseTest { @Test fun `when execute, then get crypto device info`() { - val result = getDeviceInfoUseCase.execute() + val result = runBlocking { getDeviceInfoUseCase.execute() } result shouldBeEqualTo cryptoService.cryptoDeviceInfo } diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt index 1e228353f5..7aa0647a14 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt @@ -29,6 +29,7 @@ import im.vector.app.test.fixtures.CryptoDeviceInfoFixture.aCryptoDeviceInfo import im.vector.app.test.fixtures.PusherFixture import im.vector.app.test.fixtures.SessionParamsFixture import io.mockk.mockk +import kotlinx.coroutines.runBlocking import org.amshove.kluent.shouldBeEqualTo import org.junit.Test import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo @@ -80,7 +81,9 @@ class PushersManagerTest { withEventIdOnly = true, ) - pushersManager.enqueueRegisterPusher(pushKey, gateway) + runBlocking { + pushersManager.enqueueRegisterPusher(pushKey, gateway) + } val httpPusher = pushersService.verifyEnqueueAddHttpPusher() httpPusher shouldBeEqualTo expectedHttpPusher diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt index e8bb15ac58..b5e503dd98 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt @@ -84,5 +84,5 @@ class FakeCryptoService( } } - override fun getMyCryptoDevice() = cryptoDeviceInfo + override suspend fun getMyCryptoDevice() = cryptoDeviceInfo } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt index c284263d28..564cf7a1d5 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt @@ -17,6 +17,7 @@ package im.vector.app.test.fakes import im.vector.app.core.device.GetDeviceInfoUseCase +import io.mockk.coEvery import io.mockk.every import io.mockk.mockk import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo @@ -24,6 +25,6 @@ import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo class FakeGetDeviceInfoUseCase : GetDeviceInfoUseCase by mockk() { fun givenDeviceInfo(cryptoDeviceInfo: CryptoDeviceInfo) { - every { execute() } returns cryptoDeviceInfo + coEvery { execute() } returns cryptoDeviceInfo } } From dc969f502ab46623abb5c8a37d8a35d44030c11f Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 10:55:56 +0200 Subject: [PATCH 35/48] ktlint --- .../java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt index 564cf7a1d5..34853d1776 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeGetDeviceInfoUseCase.kt @@ -18,7 +18,6 @@ package im.vector.app.test.fakes import im.vector.app.core.device.GetDeviceInfoUseCase import io.mockk.coEvery -import io.mockk.every import io.mockk.mockk import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo From 8c1938987ba258fd5605d23bf26ec6348a668dbb Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 12:18:27 +0200 Subject: [PATCH 36/48] Code review --- .../crypto/verification/self/SelfVerificationViewModel.kt | 2 +- .../vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt | 4 ++-- .../java/im/vector/app/core/pushers/PushersManagerTest.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt index ded10467a9..55d84a2446 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/self/SelfVerificationViewModel.kt @@ -147,7 +147,7 @@ class SelfVerificationViewModel @AssistedInject constructor( } setState { copy(hasAnyOtherSession = Loading()) } - viewModelScope.launch(Dispatchers.IO) { + viewModelScope.launch { val hasAnyOtherSession = session.cryptoService() .getCryptoDeviceInfo(session.myUserId) .any { diff --git a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt index 5dc0936184..99bb428d51 100644 --- a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt @@ -19,7 +19,7 @@ package im.vector.app.core.device import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeCryptoService import im.vector.app.test.fakes.FakeSession -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import org.amshove.kluent.shouldBeEqualTo import org.junit.Test @@ -33,7 +33,7 @@ class DefaultGetDeviceInfoUseCaseTest { @Test fun `when execute, then get crypto device info`() { - val result = runBlocking { getDeviceInfoUseCase.execute() } + val result = runTest { getDeviceInfoUseCase.execute() } result shouldBeEqualTo cryptoService.cryptoDeviceInfo } diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt index 7aa0647a14..39ba4691f9 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt @@ -29,7 +29,7 @@ import im.vector.app.test.fixtures.CryptoDeviceInfoFixture.aCryptoDeviceInfo import im.vector.app.test.fixtures.PusherFixture import im.vector.app.test.fixtures.SessionParamsFixture import io.mockk.mockk -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import org.amshove.kluent.shouldBeEqualTo import org.junit.Test import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo @@ -81,7 +81,7 @@ class PushersManagerTest { withEventIdOnly = true, ) - runBlocking { + runTest { pushersManager.enqueueRegisterPusher(pushKey, gateway) } From 7e6376bf90a2962c60ef6263e7794c6778778a7c Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 14:11:39 +0200 Subject: [PATCH 37/48] remove log --- .../android/sdk/internal/session/room/EventEditValidator.kt | 2 -- .../app/core/device/DefaultGetDeviceInfoUseCaseTest.kt | 4 ++-- .../java/im/vector/app/core/pushers/PushersManagerTest.kt | 6 ++---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt index 150f06a18f..fbf1dc532c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventEditValidator.kt @@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.events.model.toValidDecryptedEvent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.internal.crypto.store.IMXCommonCryptoStore -import timber.log.Timber import javax.inject.Inject internal class EventEditValidator @Inject constructor(val cryptoStore: IMXCommonCryptoStore) { @@ -53,7 +52,6 @@ internal class EventEditValidator @Inject constructor(val cryptoStore: IMXCommon * If the original event was encrypted, the replacement should be too. */ fun validateEdit(originalEvent: Event?, replaceEvent: Event): EditValidity { - Timber.v("###REPLACE valide event $originalEvent replaced $replaceEvent") // we might not know the original event at that time. In this case we can't perform the validation // Edits should be revalidated when the original event is received if (originalEvent == null) { diff --git a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt index 99bb428d51..01e5c88809 100644 --- a/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/core/device/DefaultGetDeviceInfoUseCaseTest.kt @@ -32,8 +32,8 @@ class DefaultGetDeviceInfoUseCaseTest { private val getDeviceInfoUseCase = DefaultGetDeviceInfoUseCase(activeSessionHolder.instance) @Test - fun `when execute, then get crypto device info`() { - val result = runTest { getDeviceInfoUseCase.execute() } + fun `when execute, then get crypto device info`() = runTest { + val result = getDeviceInfoUseCase.execute() result shouldBeEqualTo cryptoService.cryptoDeviceInfo } diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt index 39ba4691f9..4b6063fb93 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt @@ -57,7 +57,7 @@ class PushersManagerTest { ) @Test - fun `when enqueueRegisterPusher, then HttpPusher created and enqueued`() { + fun `when enqueueRegisterPusher, then HttpPusher created and enqueued`() = runTest { val pushKey = "abc" val gateway = "123" val pusherAppId = "app-id" @@ -81,9 +81,7 @@ class PushersManagerTest { withEventIdOnly = true, ) - runTest { - pushersManager.enqueueRegisterPusher(pushKey, gateway) - } + pushersManager.enqueueRegisterPusher(pushKey, gateway) val httpPusher = pushersService.verifyEnqueueAddHttpPusher() httpPusher shouldBeEqualTo expectedHttpPusher From cb0fb63fe6d6ba26908ac76a96621526c4a0dffe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:21:27 +0000 Subject: [PATCH 38/48] Bump org.sonarsource.scanner.gradle:sonarqube-gradle-plugin (#8490) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a70b54a833..532e6d8016 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ buildscript { classpath libs.gradle.hiltPlugin classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.0' classpath 'com.google.gms:google-services:4.3.15' - classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' + classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.2.0.3129' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6' classpath "com.likethesalad.android:stem-plugin:2.4.1" classpath 'org.owasp:dependency-check-gradle:8.2.1' From 61d4e468cb2608097a7d1ab0f9f0ce9998093144 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 1 Jun 2023 17:15:01 +0100 Subject: [PATCH 39/48] Support for stable MSC3882 (#8299) --- changelog.d/8299.feature | 1 + .../auth/DefaultAuthenticationService.kt | 5 ++++- .../sdk/internal/auth/data/LoginFlowResponse.kt | 10 +++++++++- .../sdk/internal/auth/version/Versions.kt | 3 +++ .../session/homeserver/GetCapabilitiesResult.kt | 9 ++++++++- .../homeserver/GetHomeServerCapabilitiesTask.kt | 17 +++++++++++++++-- 6 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 changelog.d/8299.feature diff --git a/changelog.d/8299.feature b/changelog.d/8299.feature new file mode 100644 index 0000000000..d4c4dae9c5 --- /dev/null +++ b/changelog.d/8299.feature @@ -0,0 +1 @@ +Updates to protocol used for Sign in with QR code diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index d1dd0238ba..bbef75a21d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -301,6 +301,9 @@ internal class DefaultAuthenticationService @Inject constructor( val oidcCompatibilityFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.sso" && it.delegatedOidcCompatibilty == true } val flows = if (oidcCompatibilityFlow != null) listOf(oidcCompatibilityFlow) else loginFlowResponse.flows + val supportsGetLoginTokenFlow = loginFlowResponse.flows.orEmpty().firstOrNull { it.type == "m.login.token" && it.getLoginToken == true } != null + + @Suppress("DEPRECATION") return LoginFlowResult( supportedLoginTypes = flows.orEmpty().mapNotNull { it.type }, ssoIdentityProviders = flows.orEmpty().firstOrNull { it.type == LoginFlowTypes.SSO }?.ssoIdentityProvider, @@ -309,7 +312,7 @@ internal class DefaultAuthenticationService @Inject constructor( isOutdatedHomeserver = !versions.isSupportedBySdk(), hasOidcCompatibilityFlow = oidcCompatibilityFlow != null, isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices(), - isLoginWithQrSupported = versions.doesServerSupportQrCodeLogin(), + isLoginWithQrSupported = supportsGetLoginTokenFlow || versions.doesServerSupportQrCodeLogin(), ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt index 971407388c..ea749a56b8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/LoginFlowResponse.kt @@ -51,5 +51,13 @@ internal data class LoginFlow( * See [MSC3824](https://github.com/matrix-org/matrix-spec-proposals/pull/3824) */ @Json(name = "org.matrix.msc3824.delegated_oidc_compatibility") - val delegatedOidcCompatibilty: Boolean? = null + val delegatedOidcCompatibilty: Boolean? = null, + + /** + * Whether a login flow of type m.login.token could accept a token issued using /login/get_token. + * + * See https://spec.matrix.org/v1.7/client-server-api/#post_matrixclientv1loginget_token + */ + @Json(name = "get_login_token") + val getLoginToken: Boolean? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt index 4d8e90cf35..3fe5541b68 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt @@ -54,6 +54,7 @@ private const val FEATURE_ID_ACCESS_TOKEN = "m.id_access_token" private const val FEATURE_SEPARATE_ADD_AND_BIND = "m.separate_add_and_bind" private const val FEATURE_THREADS_MSC3440 = "org.matrix.msc3440" private const val FEATURE_THREADS_MSC3440_STABLE = "org.matrix.msc3440.stable" +@Deprecated("The availability of stable get_login_token is now exposed as a capability and part of login flow") private const val FEATURE_QR_CODE_LOGIN = "org.matrix.msc3882" private const val FEATURE_THREADS_MSC3771 = "org.matrix.msc3771" private const val FEATURE_THREADS_MSC3773 = "org.matrix.msc3773" @@ -94,7 +95,9 @@ internal fun Versions.doesServerSupportThreadUnreadNotifications(): Boolean { return getMaxVersion() >= HomeServerVersion.v1_4_0 || (msc3771 && msc3773) } +@Deprecated("The availability of stable get_login_token is now exposed as a capability and part of login flow") internal fun Versions.doesServerSupportQrCodeLogin(): Boolean { + @Suppress("DEPRECATION") return unstableFeatures?.get(FEATURE_QR_CODE_LOGIN) ?: false } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt index 95ff44807c..7c60eab08f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt @@ -71,7 +71,14 @@ internal data class Capabilities( * True if the user can use m.thread relation, false otherwise. */ @Json(name = "m.thread") - val threads: BooleanCapability? = null + val threads: BooleanCapability? = null, + + /** + * Capability to indicate if the server supports login token issuance for signing in another device. + * True if the user can use /login/get_token, false otherwise. + */ + @Json(name = "m.get_login_token") + val getLoginToken: BooleanCapability? = null ) @JsonClass(generateAdapter = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt index ec12695ecd..a368325793 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt @@ -151,8 +151,6 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( getVersionResult.doesServerSupportThreads() homeServerCapabilitiesEntity.canUseThreadReadReceiptsAndNotifications = getVersionResult.doesServerSupportThreadUnreadNotifications() - homeServerCapabilitiesEntity.canLoginWithQrCode = - getVersionResult.doesServerSupportQrCodeLogin() homeServerCapabilitiesEntity.canRemotelyTogglePushNotificationsOfDevices = getVersionResult.doesServerSupportRemoteToggleOfPushNotifications() homeServerCapabilitiesEntity.canRedactEventWithRelations = @@ -169,10 +167,25 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( } homeServerCapabilitiesEntity.externalAccountManagementUrl = getWellknownResult.wellKnown.unstableDelegatedAuthConfig?.accountManagementUrl } + + homeServerCapabilitiesEntity.canLoginWithQrCode = canLoginWithQrCode(getCapabilitiesResult, getVersionResult) + homeServerCapabilitiesEntity.lastUpdatedTimestamp = Date().time } } + private fun canLoginWithQrCode(getCapabilitiesResult: GetCapabilitiesResult?, getVersionResult: Versions?): Boolean { + // in r0 of MSC3882 an unstable feature was exposed. In stable it is done via /capabilities and /login + + // in stable 1.7 a capability is exposed for the authenticated user + if (getCapabilitiesResult?.capabilities?.getLoginToken != null) { + return getCapabilitiesResult.capabilities.getLoginToken.enabled == true + } + + @Suppress("DEPRECATION") + return getVersionResult?.doesServerSupportQrCodeLogin() == true + } + companion object { // 8 hours like on Element Web private const val MIN_DELAY_BETWEEN_TWO_REQUEST_MILLIS = 8 * 60 * 60 * 1000 From 1eda0872330f822cda78b65f32a83002477cd167 Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 15:02:43 +0200 Subject: [PATCH 40/48] bump crypto sdk to 0.3.8 --- matrix-sdk-android/build.gradle | 2 +- .../matrix/android/sdk/internal/crypto/RustCryptoService.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 6328c1ceac..04271e17e2 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -216,7 +216,7 @@ dependencies { implementation libs.google.phonenumber - rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.7") + rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.8") // rustCryptoApi project(":library:rustCrypto") testImplementation libs.tests.junit diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt index 33fc13e728..57f81ef592 100755 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt @@ -183,8 +183,9 @@ internal class RustCryptoService @Inject constructor( override fun getCryptoVersion(context: Context, longFormat: Boolean): String { val version = org.matrix.rustcomponents.sdk.crypto.version() + val gitHash = org.matrix.rustcomponents.sdk.crypto.versionInfo().gitSha val vodozemac = org.matrix.rustcomponents.sdk.crypto.vodozemacVersion() - return if (longFormat) "Rust SDK $version, Vodozemac $vodozemac" else version + return if (longFormat) "Rust SDK $version ($gitHash), Vodozemac $vodozemac" else version } override suspend fun getMyCryptoDevice(): CryptoDeviceInfo = withContext(coroutineDispatchers.io) { From 99b6c887d28f0faeefdc0ffdad335ec5822b6842 Mon Sep 17 00:00:00 2001 From: valere Date: Wed, 31 May 2023 15:04:34 +0200 Subject: [PATCH 41/48] Add change log --- changelog.d/8488.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/8488.feature diff --git a/changelog.d/8488.feature b/changelog.d/8488.feature new file mode 100644 index 0000000000..f95014e80f --- /dev/null +++ b/changelog.d/8488.feature @@ -0,0 +1 @@ +Updated rust crypto SDK to version 0.3.8 From be8f2269489560a9a667e9830df05fd698cb04e8 Mon Sep 17 00:00:00 2001 From: valere Date: Thu, 1 Jun 2023 16:16:56 +0200 Subject: [PATCH 42/48] bump to 0.3.9 --- matrix-sdk-android/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 04271e17e2..420b24ab5a 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -216,8 +216,8 @@ dependencies { implementation libs.google.phonenumber - rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.8") - // rustCryptoApi project(":library:rustCrypto") + rustCryptoImplementation("org.matrix.rustcomponents:crypto-android:0.3.9") +// rustCryptoApi project(":library:rustCrypto") testImplementation libs.tests.junit // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281 From 688ae7d25936c6c9787af9ba4f657e519fae1590 Mon Sep 17 00:00:00 2001 From: valere Date: Thu, 1 Jun 2023 16:45:26 +0200 Subject: [PATCH 43/48] update change log --- changelog.d/8488.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/8488.feature b/changelog.d/8488.feature index f95014e80f..97729b0a89 100644 --- a/changelog.d/8488.feature +++ b/changelog.d/8488.feature @@ -1 +1 @@ -Updated rust crypto SDK to version 0.3.8 +Updated rust crypto SDK to version 0.3.9 From ada85398982ae23ef0e4926604c6b0c2fd1339f0 Mon Sep 17 00:00:00 2001 From: valere Date: Thu, 1 Jun 2023 19:53:36 +0200 Subject: [PATCH 44/48] Fix remove deprecated isReady() call --- .../internal/crypto/verification/RustVerificationService.kt | 5 +++-- .../sdk/internal/crypto/verification/VerificationRequest.kt | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 8cb6618a18..35965d6f2e 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.toValue import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.rustcomponents.sdk.crypto.VerificationRequestState import timber.log.Timber import javax.inject.Inject @@ -165,7 +166,7 @@ internal class RustVerificationService @Inject constructor( // If this is a SAS verification originating from a `m.key.verification.request` // event, we auto-accept here considering that we either initiated the request or // accepted the request. If it's a QR code verification, just dispatch an update. - if (request.isReady() && transaction is SasVerification) { + if (request.innerState() is VerificationRequestState.Ready && transaction is SasVerification) { // accept() will dispatch an update, no need to do it twice. Timber.d("## Verification: Auto accepting SAS verification with $sender") transaction.accept() @@ -308,7 +309,7 @@ internal class RustVerificationService @Inject constructor( return if (request != null) { request.acceptWithMethods(methods) request.startQrCode() - request.isReady() + request.innerState() is VerificationRequestState.Ready } else { false } diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt index 8d1b3392aa..641bf66c12 100644 --- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt +++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt @@ -136,9 +136,9 @@ internal class VerificationRequest @AssistedInject constructor( * concrete verification flow, i.e. we can show/scan a QR code or start emoji * verification. */ - internal fun isReady(): Boolean { - return innerVerificationRequest.isReady() - } +// internal fun isReady(): Boolean { +// return innerVerificationRequest.isReady() +// } /** Did we advertise that we're able to scan QR codes */ internal fun canScanQrCodes(): Boolean { From 7f8a19f19493441ccb24742d78cc1a22f0d2840d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 09:59:16 +0000 Subject: [PATCH 45/48] Bump org.checkerframework:checker from 3.34.0 to 3.35.0 (#8497) --- vector/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/build.gradle b/vector/build.gradle index 05a23bf0df..fb9c63ad2a 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -310,7 +310,7 @@ dependencies { // Fix issue with Jitsi. Inspired from https://github.com/android/android-test/issues/861#issuecomment-872067868 // Error was lots of `Duplicate class org.checkerframework.common.reflection.qual.MethodVal found in modules jetified-checker-3.1 (org.checkerframework:checker:3.1.1) and jetified-checker-qual-3.12.0 (org.checkerframework:checker-qual:3.12.0) //noinspection GradleDependency Cannot use latest 3.15.0 since it required min API 26. - implementation "org.checkerframework:checker:3.34.0" + implementation "org.checkerframework:checker:3.35.0" androidTestImplementation libs.androidx.testCore androidTestImplementation libs.androidx.testRunner From 91f507e6c406103036f2d53c02dc01de702e33c3 Mon Sep 17 00:00:00 2001 From: valere Date: Fri, 2 Jun 2023 14:27:57 +0200 Subject: [PATCH 46/48] revert sonarqube gradle plugin version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 532e6d8016..a70b54a833 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ buildscript { classpath libs.gradle.hiltPlugin classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.0' classpath 'com.google.gms:google-services:4.3.15' - classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.2.0.3129' + classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.0.0.2929' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6' classpath "com.likethesalad.android:stem-plugin:2.4.1" classpath 'org.owasp:dependency-check-gradle:8.2.1' From 1e4f47bc521c9eb1b290c36ffa5075d02ff7b29f Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 2 Jun 2023 17:52:18 +0200 Subject: [PATCH 47/48] Changelog for version 1.6.2 --- CHANGES.md | 20 ++++++++++++++++++++ changelog.d/4855.bugfix | 1 - changelog.d/8120.feature | 1 - changelog.d/8299.feature | 1 - changelog.d/8470.misc | 1 - changelog.d/8482.bugfix | 1 - changelog.d/8488.feature | 1 - 7 files changed, 20 insertions(+), 6 deletions(-) delete mode 100644 changelog.d/4855.bugfix delete mode 100644 changelog.d/8120.feature delete mode 100644 changelog.d/8299.feature delete mode 100644 changelog.d/8470.misc delete mode 100644 changelog.d/8482.bugfix delete mode 100644 changelog.d/8488.feature diff --git a/CHANGES.md b/CHANGES.md index 6d756f2b3f..39ea3f1477 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,23 @@ +Changes in Element v1.6.2 (2023-06-02) +====================================== + +Features ✨ +---------- + - **Element Android is now using the Crypto Rust SDK**. Migration of user's data should be done at first launch after application upgrade. ([#8390](https://github.com/vector-im/element-android/issues/8390)) + - Marks WebP files as Animated and allows them to play ([#8120](https://github.com/vector-im/element-android/issues/8120)) + - Updates to protocol used for Sign in with QR code ([#8299](https://github.com/vector-im/element-android/issues/8299)) + - Updated rust crypto SDK to version 0.3.9 ([#8488](https://github.com/vector-im/element-android/issues/8488)) + +Bugfixes 🐛 +---------- + - Fix: Allow users to sign out even if the sign out request fails. ([#4855](https://github.com/vector-im/element-android/issues/4855)) + - fix: Make some crypto calls suspendable to avoid reported ANR ([#8482](https://github.com/vector-im/element-android/issues/8482)) + +Other changes +------------- + - Refactoring: Extract a new interface for common access to crypto store between kotlin and rust crypto ([#8470](https://github.com/vector-im/element-android/issues/8470)) + + Changes in Element v1.6.1 (2023-05-25) ====================================== diff --git a/changelog.d/4855.bugfix b/changelog.d/4855.bugfix deleted file mode 100644 index d85feb42e7..0000000000 --- a/changelog.d/4855.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix: Allow users to sign out even if the sign out request fails. diff --git a/changelog.d/8120.feature b/changelog.d/8120.feature deleted file mode 100644 index 906ec2b819..0000000000 --- a/changelog.d/8120.feature +++ /dev/null @@ -1 +0,0 @@ -Marks WebP files as Animated and allows them to play diff --git a/changelog.d/8299.feature b/changelog.d/8299.feature deleted file mode 100644 index d4c4dae9c5..0000000000 --- a/changelog.d/8299.feature +++ /dev/null @@ -1 +0,0 @@ -Updates to protocol used for Sign in with QR code diff --git a/changelog.d/8470.misc b/changelog.d/8470.misc deleted file mode 100644 index c2a44c430a..0000000000 --- a/changelog.d/8470.misc +++ /dev/null @@ -1 +0,0 @@ -Refactoring: Extract a new interface for common access to crypto store between kotlin and rust crypto diff --git a/changelog.d/8482.bugfix b/changelog.d/8482.bugfix deleted file mode 100644 index 3e4184b3bf..0000000000 --- a/changelog.d/8482.bugfix +++ /dev/null @@ -1 +0,0 @@ -fix: Make some crypto calls suspendable to avoid reported ANR diff --git a/changelog.d/8488.feature b/changelog.d/8488.feature deleted file mode 100644 index 97729b0a89..0000000000 --- a/changelog.d/8488.feature +++ /dev/null @@ -1 +0,0 @@ -Updated rust crypto SDK to version 0.3.9 From 632f316f8eaaab6ad2111f92a8647e34a77d21c2 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 2 Jun 2023 17:53:52 +0200 Subject: [PATCH 48/48] Adding fastlane file for version 1.6.2 --- fastlane/metadata/android/en-US/changelogs/40106020.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40106020.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40106020.txt b/fastlane/metadata/android/en-US/changelogs/40106020.txt new file mode 100644 index 0000000000..badf979955 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40106020.txt @@ -0,0 +1,2 @@ +Main changes in this version: Element Android is now using the Crypto Rust SDK. +Full changelog: https://github.com/vector-im/element-android/releases