diff --git a/changelog.d/8889.misc b/changelog.d/8889.misc
new file mode 100644
index 0000000000..177cc0e8f4
--- /dev/null
+++ b/changelog.d/8889.misc
@@ -0,0 +1 @@
+Remove legacy QR code login.
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index 2a98069c2e..ef02e525af 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -2228,7 +2228,8 @@
If you don’t know your password, go back to reset it.This is not a valid user identifier. Expected format: \'@user:homeserver.org\'Unable to find a valid homeserver. Please check your identifier
- Scan QR code
+
+ Scan QR codeSeen by
@@ -3475,9 +3476,10 @@
Session nameCustom session names can help you recognize your devices more easily.Please be aware that session names are also visible to people you communicate with.
- Sign in with QR Code
- You can use this device to sign in a mobile or web device with a QR code. There are two ways to do this:
-
+
+ Sign in with QR Code
+
+ You can use this device to sign in a mobile or web device with a QR code. There are two ways to do this:Inactive sessionsInactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.\n\nRemoving inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.Unverified sessions
@@ -3515,45 +3517,82 @@
Tap top right to see the option to feedback.Try it out
- 1
- 2
- 3
+
+ 1
+
+ 2
+
+ 3
- Scan QR code
- Use the camera on this device to scan the QR code shown on your other device:
- Sign in with QR code
- Use your signed in device to scan the QR code below:
- Scan the QR code below with your device that’s signed out.
- Secure connection established
- Check your signed in device, the code below should be displayed. Confirm that the code below matches with that device:
- Unsuccessful connection
- Linking with this device is not supported.
- The linking wasn’t completed in the required time.
- The request was denied on the other device.
- The request failed.
- A security issue was encountered setting up secure messaging. One of the following may be compromised: Your homeserver; Your internet connection(s); Your device(s);
- The other device is already signed in.
- The other device must be signed in.
- That QR code is invalid.
- The sign in was cancelled on the other device.
- The homeserver doesn\'t support sign in with QR code.
- Open the app on your other device
- Go to Settings -> Security & Privacy
- Select \'Show QR code\'
- Start at the sign in screen
- Select \'Sign in with QR code\'
- Start at the sign in screen
- Select \'Scan QR code\'
- Show QR code in this device
- Signing in a mobile device?
- Scan QR code
- Connecting to device
- Signing you in
- No match?
- Try again
- Confirm
- Please ensure that you know the origin of this code. By linking devices, you will provide someone with full access to your account.
+
+ Scan QR code
+
+ Use the camera on this device to scan the QR code shown on your other device:
+
+ Sign in with QR code
+
+ Use your signed in device to scan the QR code below:
+
+ Scan the QR code below with your device that’s signed out.
+
+ Secure connection established
+
+ Check your signed in device, the code below should be displayed. Confirm that the code below matches with that device:
+
+ Unsuccessful connection
+
+ Linking with this device is not supported.
+
+ The linking wasn’t completed in the required time.
+
+ The request was denied on the other device.
+
+ The request failed.
+
+ A security issue was encountered setting up secure messaging. One of the following may be compromised: Your homeserver; Your internet connection(s); Your device(s);
+
+ The other device is already signed in.
+
+ The other device must be signed in.
+
+ That QR code is invalid.
+
+ The sign in was cancelled on the other device.
+
+ The homeserver doesn\'t support sign in with QR code.
+
+ Open the app on your other device
+
+ Go to Settings -> Security & Privacy
+
+ Select \'Show QR code\'
+
+ Start at the sign in screen
+
+ Select \'Sign in with QR code\'
+
+ Start at the sign in screen
+
+ Select \'Scan QR code\'
+
+ Show QR code in this device
+
+ Signing in a mobile device?
+
+ Scan QR code
+
+ Connecting to device
+
+ Signing you in
+
+ No match?
+
+ Try again
+
+ Confirm
+
+ Please ensure that you know the origin of this code. By linking devices, you will provide someone with full access to your account.Apply bold format
diff --git a/library/ui-styles/src/main/res/values/stylable_qr_code_instructions_view.xml b/library/ui-styles/src/main/res/values/stylable_qr_code_instructions_view.xml
deleted file mode 100644
index c9a4bb9d05..0000000000
--- a/library/ui-styles/src/main/res/values/stylable_qr_code_instructions_view.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/library/ui-styles/src/main/res/values/stylable_qr_code_login_header_view.xml b/library/ui-styles/src/main/res/values/stylable_qr_code_login_header_view.xml
deleted file mode 100644
index 99f56084d9..0000000000
--- a/library/ui-styles/src/main/res/values/stylable_qr_code_login_header_view.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/rendezvous/RendezvousTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/rendezvous/RendezvousTest.kt
deleted file mode 100644
index 5b5aad4c51..0000000000
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/api/rendezvous/RendezvousTest.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.api.rendezvous
-
-import org.amshove.kluent.invoking
-import org.amshove.kluent.shouldBeEqualTo
-import org.amshove.kluent.shouldBeInstanceOf
-import org.amshove.kluent.shouldThrow
-import org.amshove.kluent.with
-import org.junit.Test
-import org.matrix.android.sdk.InstrumentedTest
-import org.matrix.android.sdk.api.rendezvous.channels.ECDHRendezvousChannel
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import org.matrix.android.sdk.common.CommonTestHelper
-
-class RendezvousTest : InstrumentedTest {
-
- @Test
- fun shouldSuccessfullyBuildChannels() = CommonTestHelper.runCryptoTest(context()) { _, _ ->
- val cases = listOf(
- // v1:
- "{\"rendezvous\":{\"algorithm\":\"org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256\"," +
- "\"key\":\"aeSGwYTV1IUhikUyCapzC6p2xG5NpJ4Lwj2UgUMlcTk\",\"transport\":" +
- "{\"type\":\"org.matrix.msc3886.http.v1\",\"uri\":\"https://rendezvous.lab.element.dev/bcab62cd-3e34-48b4-bc39-90895da8f6fe\"}}," +
- "\"intent\":\"login.reciprocate\"}",
- // v2:
- "{\"rendezvous\":{\"algorithm\":\"org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256\"," +
- "\"key\":\"aeSGwYTV1IUhikUyCapzC6p2xG5NpJ4Lwj2UgUMlcTk\",\"transport\":" +
- "{\"type\":\"org.matrix.msc3886.http.v1\",\"uri\":\"https://rendezvous.lab.element.dev/bcab62cd-3e34-48b4-bc39-90895da8f6fe\"}}," +
- "\"intent\":\"login.reciprocate\"}",
- )
-
- cases.forEach { input ->
- Rendezvous.buildChannelFromCode(input).channel shouldBeInstanceOf ECDHRendezvousChannel::class
- }
- }
-
- @Test
- fun shouldFailToBuildChannelAsUnsupportedAlgorithm() {
- invoking {
- Rendezvous.buildChannelFromCode(
- "{\"rendezvous\":{\"algorithm\":\"bad algo\"," +
- "\"key\":\"aeSGwYTV1IUhikUyCapzC6p2xG5NpJ4Lwj2UgUMlcTk\",\"transport\":" +
- "{\"type\":\"org.matrix.msc3886.http.v1\",\"uri\":\"https://rendezvous.lab.element.dev/bcab62cd-3e34-48b4-bc39-90895da8f6fe\"}}," +
- "\"intent\":\"login.reciprocate\"}"
- )
- } shouldThrow RendezvousError::class with {
- this.reason shouldBeEqualTo RendezvousFailureReason.UnsupportedAlgorithm
- }
- }
-
- @Test
- fun shouldFailToBuildChannelAsUnsupportedTransport() {
- invoking {
- Rendezvous.buildChannelFromCode(
- "{\"rendezvous\":{\"algorithm\":\"org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256\"," +
- "\"key\":\"aeSGwYTV1IUhikUyCapzC6p2xG5NpJ4Lwj2UgUMlcTk\",\"transport\":" +
- "{\"type\":\"bad transport\",\"uri\":\"https://rendezvous.lab.element.dev/bcab62cd-3e34-48b4-bc39-90895da8f6fe\"}}," +
- "\"intent\":\"login.reciprocate\"}"
- )
- } shouldThrow RendezvousError::class with {
- this.reason shouldBeEqualTo RendezvousFailureReason.UnsupportedTransport
- }
- }
-
- @Test
- fun shouldFailToBuildChannelWithInvalidIntent() {
- invoking {
- Rendezvous.buildChannelFromCode(
- "{\"rendezvous\":{\"algorithm\":\"org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256\"," +
- "\"key\":\"aeSGwYTV1IUhikUyCapzC6p2xG5NpJ4Lwj2UgUMlcTk\",\"transport\":" +
- "{\"type\":\"org.matrix.msc3886.http.v1\",\"uri\":\"https://rendezvous.lab.element.dev/bcab62cd-3e34-48b4-bc39-90895da8f6fe\"}}," +
- "\"intent\":\"foo\"}"
- )
- } shouldThrow RendezvousError::class with {
- this.reason shouldBeEqualTo RendezvousFailureReason.InvalidCode
- }
- }
-
- @Test
- fun shouldFailToBuildChannelAsInvalidCode() {
- val cases = listOf(
- "{}",
- "rubbish",
- ""
- )
-
- cases.forEach { input ->
- invoking {
- Rendezvous.buildChannelFromCode(input)
- } shouldThrow RendezvousError::class with {
- this.reason shouldBeEqualTo RendezvousFailureReason.InvalidCode
- }
- }
- }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/Rendezvous.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/Rendezvous.kt
deleted file mode 100644
index 5bceecf643..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/Rendezvous.kt
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous
-
-import android.net.Uri
-import org.matrix.android.sdk.api.auth.AuthenticationService
-import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
-import org.matrix.android.sdk.api.logger.LoggerTag
-import org.matrix.android.sdk.api.rendezvous.channels.ECDHRendezvousChannel
-import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
-import org.matrix.android.sdk.api.rendezvous.model.Outcome
-import org.matrix.android.sdk.api.rendezvous.model.Payload
-import org.matrix.android.sdk.api.rendezvous.model.PayloadType
-import org.matrix.android.sdk.api.rendezvous.model.Protocol
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousCode
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportType
-import org.matrix.android.sdk.api.rendezvous.model.SecureRendezvousChannelAlgorithm
-import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
-import org.matrix.android.sdk.api.session.Session
-import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
-import org.matrix.android.sdk.api.util.MatrixJsonParser
-import timber.log.Timber
-
-// n.b MSC3886/MSC3903/MSC3906 that this is based on are now closed.
-// However, we want to keep this implementation around for some time.
-// TODO define an end-of-life date for this implementation.
-
-/**
- * Implementation of MSC3906 to sign in + E2EE set up using a QR code.
- */
-class Rendezvous(
- val channel: RendezvousChannel,
- val theirIntent: RendezvousIntent,
-) {
- companion object {
- private val TAG = LoggerTag(Rendezvous::class.java.simpleName, LoggerTag.RENDEZVOUS).value
-
- @Throws(RendezvousError::class)
- fun buildChannelFromCode(code: String): Rendezvous {
- // we first check that the code is valid JSON and has right high-level structure
- val genericParsed = try {
- // we rely on moshi validating the code and throwing exception if invalid JSON or algorithm doesn't match
- MatrixJsonParser.getMoshi().adapter(RendezvousCode::class.java).fromJson(code)
- } catch (a: Throwable) {
- throw RendezvousError("Malformed code", RendezvousFailureReason.InvalidCode)
- } ?: throw RendezvousError("Code is null", RendezvousFailureReason.InvalidCode)
-
- // then we check that algorithm is supported
- if (!SecureRendezvousChannelAlgorithm.values().map { it.value }.contains(genericParsed.rendezvous.algorithm)) {
- throw RendezvousError("Unsupported algorithm", RendezvousFailureReason.UnsupportedAlgorithm)
- }
-
- // and, that the transport is supported
- if (!RendezvousTransportType.values().map { it.value }.contains(genericParsed.rendezvous.transport.type)) {
- throw RendezvousError("Unsupported transport", RendezvousFailureReason.UnsupportedTransport)
- }
-
- // now that we know the overall structure looks sensible, we rely on moshi validating the code and
- // throwing exception if other parts are invalid
- val supportedParsed = try {
- MatrixJsonParser.getMoshi().adapter(ECDHRendezvousCode::class.java).fromJson(code)
- } catch (a: Throwable) {
- throw RendezvousError("Malformed ECDH rendezvous code", RendezvousFailureReason.InvalidCode)
- } ?: throw RendezvousError("ECDH rendezvous code is null", RendezvousFailureReason.InvalidCode)
-
- val transport = SimpleHttpRendezvousTransport(supportedParsed.rendezvous.transport.uri)
-
- return Rendezvous(
- ECDHRendezvousChannel(transport, supportedParsed.rendezvous.algorithm, supportedParsed.rendezvous.key),
- supportedParsed.intent
- )
- }
- }
-
- private val adapter = MatrixJsonParser.getMoshi().adapter(Payload::class.java)
-
- // not yet implemented: RendezvousIntent.RECIPROCATE_LOGIN_ON_EXISTING_DEVICE
- val ourIntent: RendezvousIntent = RendezvousIntent.LOGIN_ON_NEW_DEVICE
-
- @Throws(RendezvousError::class)
- private suspend fun checkCompatibility() {
- val incompatible = theirIntent == ourIntent
-
- Timber.tag(TAG).d("ourIntent: $ourIntent, theirIntent: $theirIntent, incompatible: $incompatible")
-
- if (incompatible) {
- // inform the other side
- send(Payload(PayloadType.FINISH, intent = ourIntent))
- if (ourIntent == RendezvousIntent.LOGIN_ON_NEW_DEVICE) {
- throw RendezvousError("The other device isn't signed in", RendezvousFailureReason.OtherDeviceNotSignedIn)
- } else {
- throw RendezvousError("The other device is already signed in", RendezvousFailureReason.OtherDeviceAlreadySignedIn)
- }
- }
- }
-
- @Throws(RendezvousError::class)
- suspend fun startAfterScanningCode(): String {
- val checksum = channel.connect()
-
- Timber.tag(TAG).i("Connected to secure channel with checksum: $checksum")
-
- checkCompatibility()
-
- // get protocols
- Timber.tag(TAG).i("Waiting for protocols")
- val protocolsResponse = receive()
-
- if (protocolsResponse?.protocols == null || !protocolsResponse.protocols.contains(Protocol.LOGIN_TOKEN)) {
- send(Payload(PayloadType.FINISH, outcome = Outcome.UNSUPPORTED))
- throw RendezvousError("Unsupported protocols", RendezvousFailureReason.UnsupportedHomeserver)
- }
-
- send(Payload(PayloadType.PROGRESS, protocol = Protocol.LOGIN_TOKEN))
-
- return checksum
- }
-
- @Throws(RendezvousError::class)
- suspend fun waitForLoginOnNewDevice(authenticationService: AuthenticationService): Session {
- Timber.tag(TAG).i("Waiting for login_token")
-
- val loginToken = receive()
-
- if (loginToken?.type == PayloadType.FINISH) {
- when (loginToken.outcome) {
- Outcome.DECLINED -> {
- throw RendezvousError("Login declined by other device", RendezvousFailureReason.UserDeclined)
- }
- Outcome.UNSUPPORTED -> {
- throw RendezvousError("Homeserver lacks support", RendezvousFailureReason.UnsupportedHomeserver)
- }
- else -> {
- throw RendezvousError("Unknown error", RendezvousFailureReason.Unknown)
- }
- }
- }
-
- val homeserver = loginToken?.homeserver ?: throw RendezvousError("No homeserver returned", RendezvousFailureReason.ProtocolError)
- val token = loginToken.loginToken ?: throw RendezvousError("No login token returned", RendezvousFailureReason.ProtocolError)
-
- Timber.tag(TAG).i("Got login_token now attempting to sign in with $homeserver")
-
- val hsConfig = HomeServerConnectionConfig(homeServerUri = Uri.parse(homeserver))
- return authenticationService.loginUsingQrLoginToken(hsConfig, token)
- }
-
- @Throws(RendezvousError::class)
- suspend fun completeVerificationOnNewDevice(session: Session) {
- val userId = session.myUserId
- val crypto = session.cryptoService()
- val deviceId = crypto.getMyCryptoDevice().deviceId
- val deviceKey = crypto.getMyCryptoDevice().fingerprint()
- send(Payload(PayloadType.PROGRESS, outcome = Outcome.SUCCESS, deviceId = deviceId, deviceKey = deviceKey))
-
- try {
- // explicitly download keys for ourself rather than racing with initial sync which might not complete in time
- crypto.downloadKeysIfNeeded(listOf(userId), false)
- } catch (e: Throwable) {
- // log as warning and continue as initial sync might still complete
- Timber.tag(TAG).w(e, "Failed to download keys for self")
- }
-
- // await confirmation of verification
- val verificationResponse = receive()
- if (verificationResponse?.outcome == Outcome.VERIFIED) {
- val verifyingDeviceId = verificationResponse.verifyingDeviceId
- ?: throw RendezvousError("No verifying device id returned", RendezvousFailureReason.ProtocolError)
- val verifyingDeviceFromServer = crypto.getCryptoDeviceInfo(userId, verifyingDeviceId)
- if (verifyingDeviceFromServer?.fingerprint() != verificationResponse.verifyingDeviceKey) {
- Timber.tag(TAG).w(
- "Verifying device $verifyingDeviceId key doesn't match: ${
- verifyingDeviceFromServer?.fingerprint()
- } vs ${verificationResponse.verifyingDeviceKey})"
- )
- // inform the other side
- send(Payload(PayloadType.FINISH, outcome = Outcome.E2EE_SECURITY_ERROR))
- throw RendezvousError("Key from verifying device doesn't match", RendezvousFailureReason.E2EESecurityIssue)
- }
-
- verificationResponse.masterKey?.let { masterKeyFromVerifyingDevice ->
- // verifying device provided us with a master key, so use it to check integrity
-
- // see what the homeserver told us
- val localMasterKey = crypto.crossSigningService().getMyCrossSigningKeys()?.masterKey()
-
- // n.b. if no local master key this is a problem, as well as it not matching
- if (localMasterKey?.unpaddedBase64PublicKey != masterKeyFromVerifyingDevice) {
- Timber.tag(TAG).w("Master key from verifying device doesn't match: $masterKeyFromVerifyingDevice vs $localMasterKey")
- // inform the other side
- send(Payload(PayloadType.FINISH, outcome = Outcome.E2EE_SECURITY_ERROR))
- throw RendezvousError("Master key from verifying device doesn't match", RendezvousFailureReason.E2EESecurityIssue)
- }
-
- // set other device as verified
- Timber.tag(TAG).i("Setting device $verifyingDeviceId as verified")
- crypto.setDeviceVerification(DeviceTrustLevel(locallyVerified = true, crossSigningVerified = false), userId, verifyingDeviceId)
-
- Timber.tag(TAG).i("Setting master key as trusted")
- crypto.crossSigningService().markMyMasterKeyAsTrusted()
- } ?: run {
- // set other device as verified anyway
- Timber.tag(TAG).i("Setting device $verifyingDeviceId as verified")
- crypto.setDeviceVerification(DeviceTrustLevel(locallyVerified = true, crossSigningVerified = false), userId, verifyingDeviceId)
-
- Timber.tag(TAG).i("No master key given by verifying device")
- }
-
- // request secrets from other sessions.
- Timber.tag(TAG).i("Requesting secrets from other sessions")
-
- session.sharedSecretStorageService().requestMissingSecrets()
- } else {
- Timber.tag(TAG).i("Not doing verification")
- }
- }
-
- @Throws(RendezvousError::class)
- private suspend fun receive(): Payload? {
- val data = channel.receive() ?: return null
- val payload = try {
- adapter.fromJson(data.toString(Charsets.UTF_8))
- } catch (e: Exception) {
- Timber.tag(TAG).w(e, "Failed to parse payload")
- throw RendezvousError("Invalid payload received", RendezvousFailureReason.Unknown)
- }
-
- return payload
- }
-
- private suspend fun send(payload: Payload) {
- channel.send(adapter.toJson(payload).toByteArray(Charsets.UTF_8))
- }
-
- suspend fun close() {
- channel.close()
- }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousChannel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousChannel.kt
deleted file mode 100644
index 0956a5b0a0..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousChannel.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous
-
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-
-/**
- * Representation of a rendezvous channel such as that described by MSC3903.
- */
-interface RendezvousChannel {
- val transport: RendezvousTransport
-
- /**
- * @returns the checksum/confirmation digits to be shown to the user
- */
- @Throws(RendezvousError::class)
- suspend fun connect(): String
-
- /**
- * Send a payload via the channel.
- * @param data payload to send
- */
- @Throws(RendezvousError::class)
- suspend fun send(data: ByteArray)
-
- /**
- * Receive a payload from the channel.
- * @returns the received payload
- */
- @Throws(RendezvousError::class)
- suspend fun receive(): ByteArray?
-
- /**
- * Closes the channel and cleans up.
- */
- suspend fun close()
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousFailureReason.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousFailureReason.kt
deleted file mode 100644
index 18e625d825..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousFailureReason.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous
-
-enum class RendezvousFailureReason(val canRetry: Boolean = true) {
- UserDeclined,
- OtherDeviceNotSignedIn,
- OtherDeviceAlreadySignedIn,
- Unknown,
- Expired,
- UserCancelled,
- InvalidCode,
- UnsupportedAlgorithm(false),
- UnsupportedTransport(false),
- UnsupportedHomeserver(false),
- ProtocolError,
- E2EESecurityIssue(false)
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousTransport.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousTransport.kt
deleted file mode 100644
index 81632e951a..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/RendezvousTransport.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous
-
-import okhttp3.MediaType
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportDetails
-
-interface RendezvousTransport {
- var ready: Boolean
-
- @Throws(RendezvousError::class)
- suspend fun details(): RendezvousTransportDetails
-
- @Throws(RendezvousError::class)
- suspend fun send(contentType: MediaType, data: ByteArray)
-
- @Throws(RendezvousError::class)
- suspend fun receive(): ByteArray?
-
- suspend fun close()
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/channels/ECDHRendezvousChannel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/channels/ECDHRendezvousChannel.kt
deleted file mode 100644
index bcde4a2a7f..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/channels/ECDHRendezvousChannel.kt
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.channels
-
-import android.util.Base64
-import com.squareup.moshi.JsonClass
-import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-import okhttp3.MediaType.Companion.toMediaType
-import org.matrix.android.sdk.api.logger.LoggerTag
-import org.matrix.android.sdk.api.rendezvous.RendezvousChannel
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-import org.matrix.android.sdk.api.rendezvous.RendezvousTransport
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import org.matrix.android.sdk.api.rendezvous.model.SecureRendezvousChannelAlgorithm
-import org.matrix.android.sdk.api.util.MatrixJsonParser
-import org.matrix.android.sdk.internal.crypto.verification.getDecimalCodeRepresentation
-import org.matrix.olm.OlmSAS
-import timber.log.Timber
-import java.security.SecureRandom
-import java.util.LinkedList
-import javax.crypto.Cipher
-import javax.crypto.spec.IvParameterSpec
-import javax.crypto.spec.SecretKeySpec
-
-/**
- * Implements X25519 ECDH key agreement and AES-256-GCM encryption channel as per MSC3903:
- * https://github.com/matrix-org/matrix-spec-proposals/pull/3903
- */
-class ECDHRendezvousChannel(
- override var transport: RendezvousTransport,
- private val algorithm: SecureRendezvousChannelAlgorithm,
- theirPublicKeyBase64: String?,
-) : RendezvousChannel {
- companion object {
- private const val ALGORITHM_SPEC = "AES/GCM/NoPadding"
- private const val KEY_SPEC = "AES"
- private val TAG = LoggerTag(ECDHRendezvousChannel::class.java.simpleName, LoggerTag.RENDEZVOUS).value
- }
-
- @JsonClass(generateAdapter = true)
- internal data class ECDHPayload(
- val algorithm: SecureRendezvousChannelAlgorithm? = null,
- val key: String? = null,
- val ciphertext: String? = null,
- val iv: String? = null,
- )
-
- private val olmSASMutex = Mutex()
- private var olmSAS: OlmSAS?
- private val ourPublicKey: ByteArray
- private val ecdhAdapter = MatrixJsonParser.getMoshi().adapter(ECDHPayload::class.java)
- private var theirPublicKey: ByteArray? = null
- private var aesKey: ByteArray? = null
-
- init {
- theirPublicKeyBase64?.let {
- theirPublicKey = decodeBase64(it)
- }
- olmSAS = OlmSAS()
- ourPublicKey = decodeBase64(olmSAS!!.publicKey)
- }
-
- fun encodeBase64(input: ByteArray?): String? {
- if (algorithm == SecureRendezvousChannelAlgorithm.ECDH_V2) {
- return Base64.encodeToString(input, Base64.NO_WRAP or Base64.NO_PADDING)
- }
- return Base64.encodeToString(input, Base64.NO_WRAP)
- }
-
- fun decodeBase64(input: String?): ByteArray {
- // for decoding we aren't concerned about padding
- return Base64.decode(input, Base64.NO_WRAP)
- }
-
- @Throws(RendezvousError::class)
- override suspend fun connect(): String {
- val sas = olmSAS ?: throw RendezvousError("Channel closed", RendezvousFailureReason.Unknown)
- val isInitiator = theirPublicKey == null
-
- if (isInitiator) {
- Timber.tag(TAG).i("Waiting for other device to send their public key")
- val res = this.receiveAsPayload() ?: throw RendezvousError("No reply from other device", RendezvousFailureReason.ProtocolError)
-
- if (res.key == null) {
- throw RendezvousError(
- "Unsupported algorithm: ${res.algorithm}",
- RendezvousFailureReason.UnsupportedAlgorithm,
- )
- }
- theirPublicKey = decodeBase64(res.key)
- } else {
- // send our public key unencrypted
- Timber.tag(TAG).i("Sending public key")
- send(
- ECDHPayload(
- algorithm = algorithm,
- key = encodeBase64(ourPublicKey)
- )
- )
- }
-
- olmSASMutex.withLock {
- sas.setTheirPublicKey(encodeBase64(theirPublicKey))
- sas.setTheirPublicKey(encodeBase64(theirPublicKey))
-
- val initiatorKey = encodeBase64(if (isInitiator) ourPublicKey else theirPublicKey)
- val recipientKey = encodeBase64(if (isInitiator) theirPublicKey else ourPublicKey)
- val aesInfo = "${algorithm.value}|$initiatorKey|$recipientKey"
-
- aesKey = sas.generateShortCode(aesInfo, 32)
-
- val rawChecksum = sas.generateShortCode(aesInfo, 5)
- return rawChecksum.getDecimalCodeRepresentation(separator = "-")
- }
- }
-
- private suspend fun send(payload: ECDHPayload) {
- transport.send("application/json".toMediaType(), ecdhAdapter.toJson(payload).toByteArray(Charsets.UTF_8))
- }
-
- override suspend fun send(data: ByteArray) {
- if (aesKey == null) {
- throw IllegalStateException("Shared secret not established")
- }
- send(encrypt(data))
- }
-
- private suspend fun receiveAsPayload(): ECDHPayload? {
- transport.receive()?.toString(Charsets.UTF_8)?.let {
- return ecdhAdapter.fromJson(it)
- } ?: return null
- }
-
- override suspend fun receive(): ByteArray? {
- if (aesKey == null) {
- throw IllegalStateException("Shared secret not established")
- }
- val payload = receiveAsPayload() ?: return null
- return decrypt(payload)
- }
-
- override suspend fun close() {
- val sas = olmSAS ?: throw IllegalStateException("Channel already closed")
- olmSASMutex.withLock {
- // this does a double release check already so we don't re-check ourselves
- sas.releaseSas()
- olmSAS = null
- }
- transport.close()
- }
-
- private fun encrypt(plainText: ByteArray): ECDHPayload {
- val iv = ByteArray(16)
- SecureRandom().nextBytes(iv)
-
- val cipherText = LinkedList()
-
- val encryptCipher = Cipher.getInstance(ALGORITHM_SPEC)
- val secretKeySpec = SecretKeySpec(aesKey, KEY_SPEC)
- val ivParameterSpec = IvParameterSpec(iv)
- encryptCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
- cipherText.addAll(encryptCipher.update(plainText).toList())
- cipherText.addAll(encryptCipher.doFinal().toList())
-
- return ECDHPayload(
- ciphertext = encodeBase64(cipherText.toByteArray()),
- iv = encodeBase64(iv)
- )
- }
-
- private fun decrypt(payload: ECDHPayload): ByteArray {
- val iv = decodeBase64(payload.iv)
- val encryptCipher = Cipher.getInstance(ALGORITHM_SPEC)
- val secretKeySpec = SecretKeySpec(aesKey, KEY_SPEC)
- val ivParameterSpec = IvParameterSpec(iv)
- encryptCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
-
- val plainText = LinkedList()
- plainText.addAll(encryptCipher.update(decodeBase64(payload.ciphertext)).toList())
- plainText.addAll(encryptCipher.doFinal().toList())
-
- return plainText.toByteArray()
- }
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvous.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvous.kt
deleted file mode 100644
index 55bac6397e..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvous.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-data class ECDHRendezvous(
- val transport: SimpleHttpRendezvousTransportDetails,
- val algorithm: SecureRendezvousChannelAlgorithm,
- val key: String
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvousCode.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvousCode.kt
deleted file mode 100644
index 575b5d4bfd..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/ECDHRendezvousCode.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-data class ECDHRendezvousCode(
- val intent: RendezvousIntent,
- val rendezvous: ECDHRendezvous
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Outcome.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Outcome.kt
deleted file mode 100644
index 0ebd1f88b3..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Outcome.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-enum class Outcome(val value: String) {
- @Json(name = "success")
- SUCCESS("success"),
-
- @Json(name = "declined")
- DECLINED("declined"),
-
- @Json(name = "unsupported")
- UNSUPPORTED("unsupported"),
-
- @Json(name = "verified")
- VERIFIED("verified"),
-
- @Json(name = "e2ee_security_error")
- E2EE_SECURITY_ERROR("e2ee_security_error")
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Payload.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Payload.kt
deleted file mode 100644
index 04631ce959..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Payload.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-internal data class Payload(
- val type: PayloadType,
- val intent: RendezvousIntent? = null,
- val outcome: Outcome? = null,
- val protocols: List? = null,
- val protocol: Protocol? = null,
- val homeserver: String? = null,
- @Json(name = "login_token") val loginToken: String? = null,
- @Json(name = "device_id") val deviceId: String? = null,
- @Json(name = "device_key") val deviceKey: String? = null,
- @Json(name = "verifying_device_id") val verifyingDeviceId: String? = null,
- @Json(name = "verifying_device_key") val verifyingDeviceKey: String? = null,
- @Json(name = "master_key") val masterKey: String? = null
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/PayloadType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/PayloadType.kt
deleted file mode 100644
index 33beb1f525..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/PayloadType.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-internal enum class PayloadType(val value: String) {
- @Json(name = "m.login.start")
- START("m.login.start"),
-
- @Json(name = "m.login.finish")
- FINISH("m.login.finish"),
-
- @Json(name = "m.login.progress")
- PROGRESS("m.login.progress")
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Protocol.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Protocol.kt
deleted file mode 100644
index 6fce2fa11c..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Protocol.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-enum class Protocol(val value: String) {
- @Json(name = "org.matrix.msc3906.login_token")
- LOGIN_TOKEN("org.matrix.msc3906.login_token")
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Rendezvous.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Rendezvous.kt
deleted file mode 100644
index f424f8cab0..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/Rendezvous.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-open class Rendezvous(
- val transport: RendezvousTransportDetails,
- val algorithm: String,
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousCode.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousCode.kt
deleted file mode 100644
index ffa8bf6661..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousCode.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-open class RendezvousCode(
- open val intent: RendezvousIntent,
- open val rendezvous: Rendezvous
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousError.kt
deleted file mode 100644
index c52b11a322..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousError.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-
-class RendezvousError(val description: String, val reason: RendezvousFailureReason) : Exception(description)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousIntent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousIntent.kt
deleted file mode 100644
index 65037e1252..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousIntent.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-enum class RendezvousIntent {
- @Json(name = "login.start") LOGIN_ON_NEW_DEVICE,
- @Json(name = "login.reciprocate") RECIPROCATE_LOGIN_ON_EXISTING_DEVICE
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportDetails.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportDetails.kt
deleted file mode 100644
index 34d96ac64a..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportDetails.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-open class RendezvousTransportDetails(
- val type: String
-)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportType.kt
deleted file mode 100644
index 6fca7efa71..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/RendezvousTransportType.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-enum class RendezvousTransportType(val value: String) {
- @Json(name = "org.matrix.msc3886.http.v1")
- MSC3886_SIMPLE_HTTP_V1("org.matrix.msc3886.http.v1")
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SecureRendezvousChannelAlgorithm.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SecureRendezvousChannelAlgorithm.kt
deleted file mode 100644
index 123e41a5d7..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SecureRendezvousChannelAlgorithm.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = false)
-enum class SecureRendezvousChannelAlgorithm(val value: String) {
- @Json(name = "org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256")
- ECDH_V1("org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256"),
- @Json(name = "org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256")
- ECDH_V2("org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256")
-}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SimpleHttpRendezvousTransportDetails.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SimpleHttpRendezvousTransportDetails.kt
deleted file mode 100644
index d2342bb9d5..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/model/SimpleHttpRendezvousTransportDetails.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.model
-
-import com.squareup.moshi.JsonClass
-
-@JsonClass(generateAdapter = true)
-data class SimpleHttpRendezvousTransportDetails(
- val uri: String
-) : RendezvousTransportDetails(type = RendezvousTransportType.MSC3886_SIMPLE_HTTP_V1.name)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/transports/SimpleHttpRendezvousTransport.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/transports/SimpleHttpRendezvousTransport.kt
deleted file mode 100644
index 620b599e3d..0000000000
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/rendezvous/transports/SimpleHttpRendezvousTransport.kt
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2022 The Matrix.org Foundation C.I.C.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.matrix.android.sdk.api.rendezvous.transports
-
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-import org.matrix.android.sdk.api.logger.LoggerTag
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-import org.matrix.android.sdk.api.rendezvous.RendezvousTransport
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportDetails
-import org.matrix.android.sdk.api.rendezvous.model.SimpleHttpRendezvousTransportDetails
-import timber.log.Timber
-import java.text.SimpleDateFormat
-import java.util.Date
-import java.util.Locale
-
-/**
- * Implementation of the Simple HTTP transport MSC3886: https://github.com/matrix-org/matrix-spec-proposals/pull/3886
- */
-class SimpleHttpRendezvousTransport(rendezvousUri: String?) : RendezvousTransport {
- companion object {
- private val TAG = LoggerTag(SimpleHttpRendezvousTransport::class.java.simpleName, LoggerTag.RENDEZVOUS).value
- }
-
- override var ready = false
- private var cancelled = false
- private var uri: String?
- private var etag: String? = null
- private var expiresAt: Date? = null
-
- init {
- uri = rendezvousUri
- }
-
- override suspend fun details(): RendezvousTransportDetails {
- val uri = uri ?: throw IllegalStateException("Rendezvous not set up")
-
- return SimpleHttpRendezvousTransportDetails(uri)
- }
-
- @Throws(RendezvousError::class)
- override suspend fun send(contentType: MediaType, data: ByteArray) {
- if (cancelled) {
- throw IllegalStateException("Rendezvous cancelled")
- }
-
- val method = if (uri != null) "PUT" else "POST"
- val uri = this.uri ?: throw RuntimeException("No rendezvous URI")
-
- val httpClient = okhttp3.OkHttpClient.Builder().build()
-
- val request = Request.Builder()
- .url(uri)
- .method(method, data.toRequestBody())
- .header("content-type", contentType.toString())
-
- etag?.let {
- request.header("if-match", it)
- }
-
- val response = httpClient.newCall(request.build()).execute()
-
- if (response.code == 404) {
- throw get404Error()
- }
- etag = response.header("etag")
-
- Timber.tag(TAG).i("Sent data to $uri new etag $etag")
-
- if (method == "POST") {
- val location = response.header("location") ?: throw RuntimeException("No rendezvous URI found in response")
-
- response.header("expires")?.let {
- val format = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US)
- expiresAt = format.parse(it)
- }
-
- // resolve location header which could be relative or absolute
- this.uri = response.request.url.toUri().resolve(location).toString()
- ready = true
- }
- }
-
- @Throws(RendezvousError::class)
- override suspend fun receive(): ByteArray? {
- if (cancelled) {
- throw IllegalStateException("Rendezvous cancelled")
- }
- val uri = uri ?: throw IllegalStateException("Rendezvous not set up")
- val httpClient = okhttp3.OkHttpClient.Builder().build()
- while (true) {
- Timber.tag(TAG).i("Polling: $uri after etag $etag")
- val request = Request.Builder()
- .url(uri)
- .get()
-
- etag?.let {
- request.header("if-none-match", it)
- }
-
- val response = httpClient.newCall(request.build()).execute()
-
- try {
- // expired
- if (response.code == 404) {
- throw get404Error()
- }
-
- // rely on server expiring the channel rather than checking ourselves
-
- if (response.header("content-type") != "application/json") {
- response.header("etag")?.let {
- etag = it
- }
- } else if (response.code == 200) {
- response.header("etag")?.let {
- etag = it
- }
- return response.body?.bytes()
- }
-
- // sleep for a second before polling again
- // we rely on the server expiring the channel rather than checking it ourselves
- delay(1000)
- } finally {
- response.close()
- }
- }
- }
-
- private fun get404Error(): RendezvousError {
- if (expiresAt != null && Date() > expiresAt) {
- return RendezvousError("Expired", RendezvousFailureReason.Expired)
- }
-
- return RendezvousError("Received unexpected 404", RendezvousFailureReason.Unknown)
- }
-
- override suspend fun close() {
- cancelled = true
- ready = false
-
- uri?.let {
- try {
- val httpClient = okhttp3.OkHttpClient.Builder().build()
- val request = Request.Builder()
- .url(it)
- .delete()
- .build()
- httpClient.newCall(request).execute()
- } catch (e: Throwable) {
- Timber.tag(TAG).w(e, "Failed to delete channel")
- }
- }
- }
-}
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
index 16e26ff3b5..5f34a349d6 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
@@ -85,21 +85,6 @@ class DebugFeaturesStateFactory @Inject constructor(
key = DebugFeatureKeys.newAppLayoutEnabled,
factory = VectorFeatures::isNewAppLayoutFeatureEnabled
),
- createBooleanFeature(
- label = "Enable QR Code Login",
- key = DebugFeatureKeys.qrCodeLoginEnabled,
- factory = VectorFeatures::isQrCodeLoginEnabled
- ),
- createBooleanFeature(
- label = "Allow QR Code Login for all servers",
- key = DebugFeatureKeys.qrCodeLoginForAllServers,
- factory = VectorFeatures::isQrCodeLoginForAllServers
- ),
- createBooleanFeature(
- label = "Show QR Code Login in Device Manager",
- key = DebugFeatureKeys.reciprocateQrCodeLogin,
- factory = VectorFeatures::isReciprocateQrCodeLogin
- ),
createBooleanFeature(
label = "Enable Voice Broadcast",
key = DebugFeatureKeys.voiceBroadcastEnabled,
diff --git a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
index 2134c8cf2c..ffaf462244 100644
--- a/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
@@ -76,15 +76,6 @@ class DebugVectorFeatures(
override fun isNewAppLayoutFeatureEnabled(): Boolean = read(DebugFeatureKeys.newAppLayoutEnabled)
?: vectorFeatures.isNewAppLayoutFeatureEnabled()
- override fun isQrCodeLoginEnabled() = read(DebugFeatureKeys.qrCodeLoginEnabled)
- ?: vectorFeatures.isQrCodeLoginEnabled()
-
- override fun isQrCodeLoginForAllServers() = read(DebugFeatureKeys.qrCodeLoginForAllServers)
- ?: vectorFeatures.isQrCodeLoginForAllServers()
-
- override fun isReciprocateQrCodeLogin() = read(DebugFeatureKeys.reciprocateQrCodeLogin)
- ?: vectorFeatures.isReciprocateQrCodeLogin()
-
override fun isVoiceBroadcastEnabled(): Boolean = read(DebugFeatureKeys.voiceBroadcastEnabled)
?: vectorFeatures.isVoiceBroadcastEnabled()
@@ -150,9 +141,6 @@ object DebugFeatureKeys {
val screenSharing = booleanPreferencesKey("screen-sharing")
val forceUsageOfOpusEncoder = booleanPreferencesKey("force-usage-of-opus-encoder")
val newAppLayoutEnabled = booleanPreferencesKey("new-app-layout-enabled")
- val qrCodeLoginEnabled = booleanPreferencesKey("qr-code-login-enabled")
- val qrCodeLoginForAllServers = booleanPreferencesKey("qr-code-login-for-all-servers")
- val reciprocateQrCodeLogin = booleanPreferencesKey("reciprocate-qr-code-login")
val voiceBroadcastEnabled = booleanPreferencesKey("voice-broadcast-enabled")
val unverifiedSessionsAlertEnabled = booleanPreferencesKey("unverified-sessions-alert-enabled")
}
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index 6fed67e7da..d843f03216 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -349,7 +349,6 @@
-
diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index 8751907f2a..748e672c52 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -61,7 +61,6 @@ import im.vector.app.features.location.LocationSharingViewModel
import im.vector.app.features.location.live.map.LiveLocationMapViewModel
import im.vector.app.features.location.preview.LocationPreviewViewModel
import im.vector.app.features.login.LoginViewModel
-import im.vector.app.features.login.qr.QrCodeLoginViewModel
import im.vector.app.features.matrixto.MatrixToBottomSheetViewModel
import im.vector.app.features.media.VectorAttachmentViewerViewModel
import im.vector.app.features.onboarding.OnboardingViewModel
@@ -668,11 +667,6 @@ interface MavericksViewModelModule {
@MavericksViewModelKey(RenameSessionViewModel::class)
fun renameSessionViewModelFactory(factory: RenameSessionViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
- @Binds
- @IntoMap
- @MavericksViewModelKey(QrCodeLoginViewModel::class)
- fun qrCodeLoginViewModelFactory(factory: QrCodeLoginViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
-
@Binds
@IntoMap
@MavericksViewModelKey(SessionLearnMoreViewModel::class)
diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
index 99abc15f81..65c1d03655 100644
--- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
+++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
@@ -40,9 +40,6 @@ interface VectorFeatures {
* use [VectorPreferences.isNewAppLayoutEnabled] instead.
*/
fun isNewAppLayoutFeatureEnabled(): Boolean
- fun isQrCodeLoginEnabled(): Boolean
- fun isQrCodeLoginForAllServers(): Boolean
- fun isReciprocateQrCodeLogin(): Boolean
fun isVoiceBroadcastEnabled(): Boolean
fun isUnverifiedSessionsAlertEnabled(): Boolean
}
@@ -60,9 +57,6 @@ class DefaultVectorFeatures : VectorFeatures {
override fun isLocationSharingEnabled() = Config.ENABLE_LOCATION_SHARING
override fun forceUsageOfOpusEncoder(): Boolean = false
override fun isNewAppLayoutFeatureEnabled(): Boolean = true
- override fun isQrCodeLoginEnabled(): Boolean = true
- override fun isQrCodeLoginForAllServers(): Boolean = false
- override fun isReciprocateQrCodeLogin(): Boolean = false
override fun isVoiceBroadcastEnabled(): Boolean = true
override fun isUnverifiedSessionsAlertEnabled(): Boolean = true
}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginAction.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginAction.kt
deleted file mode 100644
index 5ea46d3dcd..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginAction.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import im.vector.app.core.platform.VectorViewModelAction
-
-sealed class QrCodeLoginAction : VectorViewModelAction {
- data class OnQrCodeScanned(val qrCode: String) : QrCodeLoginAction()
- object GenerateQrCode : QrCodeLoginAction()
- object ShowQrCode : QrCodeLoginAction()
- object TryAgain : QrCodeLoginAction()
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginActivity.kt
deleted file mode 100644
index 8eb8fd1ddc..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginActivity.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.View
-import com.airbnb.mvrx.Mavericks
-import com.airbnb.mvrx.viewModel
-import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.core.extensions.addFragment
-import im.vector.app.core.extensions.replaceFragment
-import im.vector.app.core.platform.SimpleFragmentActivity
-import im.vector.app.features.home.HomeActivity
-import im.vector.lib.core.utils.compat.getParcelableCompat
-import timber.log.Timber
-
-// n.b MSC3886/MSC3903/MSC3906 that this is based on are now closed.
-// However, we want to keep this implementation around for some time.
-// TODO define an end-of-life date for this implementation.
-
-@AndroidEntryPoint
-class QrCodeLoginActivity : SimpleFragmentActivity() {
-
- private val viewModel: QrCodeLoginViewModel by viewModel()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- views.toolbar.visibility = View.GONE
-
- if (isFirstCreation()) {
- navigateToInitialFragment()
- }
-
- observeViewEvents()
- }
-
- private fun navigateToInitialFragment() {
- val qrCodeLoginArgs: QrCodeLoginArgs? = intent?.extras?.getParcelableCompat(Mavericks.KEY_ARG)
- when (qrCodeLoginArgs?.loginType) {
- QrCodeLoginType.LOGIN -> {
- showInstructionsFragment(qrCodeLoginArgs)
- }
- QrCodeLoginType.LINK_A_DEVICE -> {
- if (qrCodeLoginArgs.showQrCodeImmediately) {
- handleNavigateToShowQrCodeScreen()
- } else {
- showInstructionsFragment(qrCodeLoginArgs)
- }
- }
- null -> {
- Timber.i("QrCodeLoginArgs is null. This is not expected.")
- finish()
- }
- }
- }
-
- private fun showInstructionsFragment(qrCodeLoginArgs: QrCodeLoginArgs) {
- replaceFragment(
- views.container,
- QrCodeLoginInstructionsFragment::class.java,
- qrCodeLoginArgs,
- tag = FRAGMENT_QR_CODE_INSTRUCTIONS_TAG
- )
- }
-
- private fun observeViewEvents() {
- viewModel.observeViewEvents {
- when (it) {
- QrCodeLoginViewEvents.NavigateToStatusScreen -> handleNavigateToStatusScreen()
- QrCodeLoginViewEvents.NavigateToShowQrCodeScreen -> handleNavigateToShowQrCodeScreen()
- QrCodeLoginViewEvents.NavigateToHomeScreen -> handleNavigateToHomeScreen()
- QrCodeLoginViewEvents.NavigateToInitialScreen -> handleNavigateToInitialScreen()
- }
- }
- }
-
- private fun handleNavigateToInitialScreen() {
- navigateToInitialFragment()
- }
-
- private fun handleNavigateToShowQrCodeScreen() {
- addFragment(
- views.container,
- QrCodeLoginShowQrCodeFragment::class.java,
- tag = FRAGMENT_SHOW_QR_CODE_TAG
- )
- }
-
- private fun handleNavigateToStatusScreen() {
- addFragment(
- views.container,
- QrCodeLoginStatusFragment::class.java,
- tag = FRAGMENT_QR_CODE_STATUS_TAG
- )
- }
-
- private fun handleNavigateToHomeScreen() {
- val intent = HomeActivity.newIntent(this, firstStartMainActivity = false, existingSession = true)
- startActivity(intent)
- }
-
- companion object {
-
- private const val FRAGMENT_QR_CODE_INSTRUCTIONS_TAG = "FRAGMENT_QR_CODE_INSTRUCTIONS_TAG"
- private const val FRAGMENT_SHOW_QR_CODE_TAG = "FRAGMENT_SHOW_QR_CODE_TAG"
- private const val FRAGMENT_QR_CODE_STATUS_TAG = "FRAGMENT_QR_CODE_STATUS_TAG"
-
- fun getIntent(context: Context, qrCodeLoginArgs: QrCodeLoginArgs): Intent {
- return Intent(context, QrCodeLoginActivity::class.java).apply {
- putExtra(Mavericks.KEY_ARG, qrCodeLoginArgs)
- }
- }
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginArgs.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginArgs.kt
deleted file mode 100644
index 6c23d07c0f..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginArgs.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.os.Parcelable
-import kotlinx.parcelize.Parcelize
-
-@Parcelize
-data class QrCodeLoginArgs(
- val loginType: QrCodeLoginType,
- val showQrCodeImmediately: Boolean,
-) : Parcelable
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginConnectionStatus.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginConnectionStatus.kt
deleted file mode 100644
index 4bef41b6c1..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginConnectionStatus.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-
-sealed class QrCodeLoginConnectionStatus {
- object ConnectingToDevice : QrCodeLoginConnectionStatus()
- data class Connected(val securityCode: String, val canConfirmSecurityCode: Boolean) : QrCodeLoginConnectionStatus()
- object SigningIn : QrCodeLoginConnectionStatus()
- data class Failed(val errorType: RendezvousFailureReason, val canTryAgain: Boolean) : QrCodeLoginConnectionStatus()
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginHeaderView.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginHeaderView.kt
deleted file mode 100644
index 05c7bdffad..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginHeaderView.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.content.Context
-import android.content.res.ColorStateList
-import android.content.res.TypedArray
-import android.util.AttributeSet
-import android.view.LayoutInflater
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.content.res.use
-import im.vector.app.core.extensions.setTextOrHide
-import im.vector.app.databinding.ViewQrCodeLoginHeaderBinding
-
-class QrCodeLoginHeaderView @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = 0
-) : ConstraintLayout(context, attrs, defStyleAttr) {
-
- private val binding = ViewQrCodeLoginHeaderBinding.inflate(
- LayoutInflater.from(context),
- this
- )
-
- init {
- context.obtainStyledAttributes(
- attrs,
- im.vector.lib.ui.styles.R.styleable.QrCodeLoginHeaderView,
- 0,
- 0
- ).use {
- setTitle(it)
- setDescription(it)
- setImage(it)
- }
- }
-
- private fun setTitle(typedArray: TypedArray) {
- val title = typedArray.getString(im.vector.lib.ui.styles.R.styleable.QrCodeLoginHeaderView_qrCodeLoginHeaderTitle)
- setTitle(title)
- }
-
- private fun setDescription(typedArray: TypedArray) {
- val description = typedArray.getString(im.vector.lib.ui.styles.R.styleable.QrCodeLoginHeaderView_qrCodeLoginHeaderDescription)
- setDescription(description)
- }
-
- private fun setImage(typedArray: TypedArray) {
- val imageResource = typedArray.getResourceId(im.vector.lib.ui.styles.R.styleable.QrCodeLoginHeaderView_qrCodeLoginHeaderImageResource, 0)
- val backgroundTint = typedArray.getColor(im.vector.lib.ui.styles.R.styleable.QrCodeLoginHeaderView_qrCodeLoginHeaderImageBackgroundTint, 0)
- setImage(imageResource, backgroundTint)
- }
-
- fun setTitle(title: String?) {
- binding.qrCodeLoginHeaderTitleTextView.setTextOrHide(title)
- }
-
- fun setDescription(description: String?) {
- binding.qrCodeLoginHeaderDescriptionTextView.setTextOrHide(description)
- }
-
- fun setImage(imageResource: Int, backgroundTintColor: Int) {
- binding.qrCodeLoginHeaderImageView.setImageResource(imageResource)
- binding.qrCodeLoginHeaderImageView.backgroundTintList = ColorStateList.valueOf(backgroundTintColor)
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsFragment.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsFragment.kt
deleted file mode 100644
index f78cae5d22..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsFragment.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.app.Activity
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import com.airbnb.mvrx.activityViewModel
-import com.airbnb.mvrx.withState
-import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.core.extensions.registerStartForActivityResult
-import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentQrCodeLoginInstructionsBinding
-import im.vector.app.features.qrcode.QrCodeScannerActivity
-import im.vector.lib.strings.CommonStrings
-import timber.log.Timber
-
-@AndroidEntryPoint
-class QrCodeLoginInstructionsFragment : VectorBaseFragment() {
-
- private val viewModel: QrCodeLoginViewModel by activityViewModel()
-
- override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeLoginInstructionsBinding {
- return FragmentQrCodeLoginInstructionsBinding.inflate(inflater, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- initScanQrCodeButton()
- initShowQrCodeButton()
- }
-
- private fun initShowQrCodeButton() {
- views.qrCodeLoginInstructionsShowQrCodeButton.debouncedClicks {
- viewModel.handle(QrCodeLoginAction.ShowQrCode)
- }
- }
-
- private fun initScanQrCodeButton() {
- views.qrCodeLoginInstructionsScanQrCodeButton.debouncedClicks {
- QrCodeScannerActivity.startForResult(requireActivity(), scanActivityResultLauncher)
- }
- }
-
- private val scanActivityResultLauncher = registerStartForActivityResult { activityResult ->
- if (activityResult.resultCode == Activity.RESULT_OK) {
- val scannedQrCode = QrCodeScannerActivity.getResultText(activityResult.data)
- val wasQrCode = QrCodeScannerActivity.getResultIsQrCode(activityResult.data)
-
- Timber.d("Scanned QR code: $scannedQrCode, was QR code: $wasQrCode")
- if (wasQrCode && !scannedQrCode.isNullOrBlank()) {
- onQrCodeScanned(scannedQrCode)
- } else {
- onQrCodeScannerFailed()
- }
- }
- }
-
- private fun onQrCodeScanned(scannedQrCode: String) {
- viewModel.handle(QrCodeLoginAction.OnQrCodeScanned(scannedQrCode))
- }
-
- private fun onQrCodeScannerFailed() {
- // The user scanned something unexpected, so we try scanning again.
- // This seems to happen particularly with the large QRs needed for rendezvous
- // especially when the QR is partially off the screen
- Timber.d("QrCodeLoginInstructionsFragment.onQrCodeScannerFailed - showing scanner again")
- QrCodeScannerActivity.startForResult(requireActivity(), scanActivityResultLauncher)
- }
-
- override fun invalidate() = withState(viewModel) { state ->
- if (state.loginType == QrCodeLoginType.LOGIN) {
- views.qrCodeLoginInstructionsView.setInstructions(
- listOf(
- getString(CommonStrings.qr_code_login_new_device_instruction_1),
- getString(CommonStrings.qr_code_login_new_device_instruction_2),
- getString(CommonStrings.qr_code_login_new_device_instruction_3),
- )
- )
- } else {
- views.qrCodeLoginInstructionsView.setInstructions(
- listOf(
- getString(CommonStrings.qr_code_login_link_a_device_scan_qr_code_instruction_1),
- getString(CommonStrings.qr_code_login_link_a_device_scan_qr_code_instruction_2),
- )
- )
- }
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsView.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsView.kt
deleted file mode 100644
index bed4efc952..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginInstructionsView.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.content.Context
-import android.content.res.TypedArray
-import android.util.AttributeSet
-import android.view.LayoutInflater
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.content.res.use
-import androidx.core.view.isVisible
-import im.vector.app.databinding.ViewQrCodeLoginInstructionsBinding
-
-class QrCodeLoginInstructionsView @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = 0
-) : ConstraintLayout(context, attrs, defStyleAttr) {
-
- private val binding = ViewQrCodeLoginInstructionsBinding.inflate(
- LayoutInflater.from(context),
- this
- )
-
- init {
- context.obtainStyledAttributes(
- attrs,
- im.vector.lib.ui.styles.R.styleable.QrCodeLoginInstructionsView,
- 0,
- 0
- ).use {
- setInstructions(it)
- }
- }
-
- private fun setInstructions(typedArray: TypedArray) {
- val instruction1 = typedArray.getString(im.vector.lib.ui.styles.R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction1)
- val instruction2 = typedArray.getString(im.vector.lib.ui.styles.R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction2)
- val instruction3 = typedArray.getString(im.vector.lib.ui.styles.R.styleable.QrCodeLoginInstructionsView_qrCodeLoginInstruction3)
- setInstructions(
- listOf(
- instruction1,
- instruction2,
- instruction3,
- )
- )
- }
-
- fun setInstructions(instructions: List?) {
- setInstruction(binding.instructions1Layout, binding.instruction1TextView, instructions?.getOrNull(0))
- setInstruction(binding.instructions2Layout, binding.instruction2TextView, instructions?.getOrNull(1))
- setInstruction(binding.instructions3Layout, binding.instruction3TextView, instructions?.getOrNull(2))
- }
-
- private fun setInstruction(instructionLayout: LinearLayout, instructionTextView: TextView, instruction: String?) {
- instruction?.let {
- instructionLayout.isVisible = true
- instructionTextView.text = instruction
- } ?: run {
- instructionLayout.isVisible = false
- }
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginShowQrCodeFragment.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginShowQrCodeFragment.kt
deleted file mode 100644
index e84007bd43..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginShowQrCodeFragment.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import com.airbnb.mvrx.activityViewModel
-import com.airbnb.mvrx.withState
-import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentQrCodeLoginShowQrCodeBinding
-import im.vector.lib.strings.CommonStrings
-
-@AndroidEntryPoint
-class QrCodeLoginShowQrCodeFragment : VectorBaseFragment() {
-
- private val viewModel: QrCodeLoginViewModel by activityViewModel()
-
- override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeLoginShowQrCodeBinding {
- return FragmentQrCodeLoginShowQrCodeBinding.inflate(inflater, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- initCancelButton()
- viewModel.handle(QrCodeLoginAction.GenerateQrCode)
- }
-
- private fun initCancelButton() {
- views.qrCodeLoginShowQrCodeCancelButton.debouncedClicks {
- activity?.onBackPressedDispatcher?.onBackPressed()
- }
- }
-
- private fun setInstructions(loginType: QrCodeLoginType) {
- if (loginType == QrCodeLoginType.LOGIN) {
- views.qrCodeLoginShowQrCodeHeaderView.setDescription(getString(CommonStrings.qr_code_login_header_show_qr_code_new_device_description))
- views.qrCodeLoginShowQrCodeInstructionsView.setInstructions(
- listOf(
- getString(CommonStrings.qr_code_login_new_device_instruction_1),
- getString(CommonStrings.qr_code_login_new_device_instruction_2),
- getString(CommonStrings.qr_code_login_new_device_instruction_3),
- )
- )
- } else {
- views.qrCodeLoginShowQrCodeHeaderView.setDescription(getString(CommonStrings.qr_code_login_header_show_qr_code_link_a_device_description))
- views.qrCodeLoginShowQrCodeInstructionsView.setInstructions(
- listOf(
- getString(CommonStrings.qr_code_login_link_a_device_show_qr_code_instruction_1),
- getString(CommonStrings.qr_code_login_link_a_device_show_qr_code_instruction_2),
- )
- )
- }
- }
-
- private fun showQrCode(qrCodeData: String) {
- views.qrCodeLoginSHowQrCodeImageView.setData(qrCodeData)
- }
-
- override fun invalidate() = withState(viewModel) { state ->
- state.generatedQrCodeData?.let { qrCodeData ->
- showQrCode(qrCodeData)
- }
- setInstructions(state.loginType)
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginStatusFragment.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginStatusFragment.kt
deleted file mode 100644
index dcfcd8b06f..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginStatusFragment.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import com.airbnb.mvrx.activityViewModel
-import com.airbnb.mvrx.withState
-import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.R
-import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentQrCodeLoginStatusBinding
-import im.vector.app.features.themes.ThemeUtils
-import im.vector.lib.strings.CommonStrings
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-
-@AndroidEntryPoint
-class QrCodeLoginStatusFragment : VectorBaseFragment() {
-
- private val viewModel: QrCodeLoginViewModel by activityViewModel()
-
- override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeLoginStatusBinding {
- return FragmentQrCodeLoginStatusBinding.inflate(inflater, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- initCancelButton()
- initTryAgainButton()
- }
-
- private fun initTryAgainButton() {
- views.qrCodeLoginStatusTryAgainButton.debouncedClicks {
- viewModel.handle(QrCodeLoginAction.TryAgain)
- }
- }
-
- private fun initCancelButton() {
- views.qrCodeLoginStatusCancelButton.debouncedClicks {
- activity?.onBackPressedDispatcher?.onBackPressed()
- }
- }
-
- private fun handleFailed(connectionStatus: QrCodeLoginConnectionStatus.Failed) {
- views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
- views.qrCodeLoginStatusLoadingLayout.isVisible = false
- views.qrCodeLoginStatusHeaderView.isVisible = true
- views.qrCodeLoginStatusSecurityCode.isVisible = false
- views.qrCodeLoginStatusNoMatchLayout.isVisible = false
- views.qrCodeLoginStatusCancelButton.isVisible = true
- views.qrCodeLoginStatusTryAgainButton.isVisible = connectionStatus.canTryAgain
- views.qrCodeLoginStatusHeaderView.setTitle(getString(CommonStrings.qr_code_login_header_failed_title))
- views.qrCodeLoginStatusHeaderView.setDescription(getErrorDescription(connectionStatus.errorType))
- views.qrCodeLoginStatusHeaderView.setImage(
- imageResource = R.drawable.ic_qr_code_login_failed,
- backgroundTintColor = ThemeUtils.getColor(requireContext(), com.google.android.material.R.attr.colorError)
- )
- }
-
- private fun getErrorDescription(reason: RendezvousFailureReason): String {
- return when (reason) {
- RendezvousFailureReason.UnsupportedAlgorithm,
- RendezvousFailureReason.UnsupportedTransport -> getString(CommonStrings.qr_code_login_header_failed_device_is_not_supported_description)
- RendezvousFailureReason.UnsupportedHomeserver -> getString(CommonStrings.qr_code_login_header_failed_homeserver_is_not_supported_description)
- RendezvousFailureReason.Expired -> getString(CommonStrings.qr_code_login_header_failed_timeout_description)
- RendezvousFailureReason.UserDeclined -> getString(CommonStrings.qr_code_login_header_failed_denied_description)
- RendezvousFailureReason.E2EESecurityIssue -> getString(CommonStrings.qr_code_login_header_failed_e2ee_security_issue_description)
- RendezvousFailureReason.OtherDeviceAlreadySignedIn ->
- getString(CommonStrings.qr_code_login_header_failed_other_device_already_signed_in_description)
- RendezvousFailureReason.OtherDeviceNotSignedIn -> getString(CommonStrings.qr_code_login_header_failed_other_device_not_signed_in_description)
- RendezvousFailureReason.InvalidCode -> getString(CommonStrings.qr_code_login_header_failed_invalid_qr_code_description)
- RendezvousFailureReason.UserCancelled -> getString(CommonStrings.qr_code_login_header_failed_user_cancelled_description)
- else -> getString(CommonStrings.qr_code_login_header_failed_other_description)
- }
- }
-
- private fun handleConnectingToDevice() {
- views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
- views.qrCodeLoginStatusLoadingLayout.isVisible = true
- views.qrCodeLoginStatusHeaderView.isVisible = false
- views.qrCodeLoginStatusSecurityCode.isVisible = false
- views.qrCodeLoginStatusNoMatchLayout.isVisible = false
- views.qrCodeLoginStatusCancelButton.isVisible = true
- views.qrCodeLoginStatusTryAgainButton.isVisible = false
- views.qrCodeLoginStatusLoadingTextView.setText(CommonStrings.qr_code_login_connecting_to_device)
- }
-
- private fun handleSigningIn() {
- views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = false
- views.qrCodeLoginStatusLoadingLayout.isVisible = true
- views.qrCodeLoginStatusHeaderView.apply {
- isVisible = true
- setTitle(getString(CommonStrings.dialog_title_success))
- setDescription("")
- setImage(R.drawable.ic_tick, ThemeUtils.getColor(requireContext(), com.google.android.material.R.attr.colorPrimary))
- }
- views.qrCodeLoginStatusSecurityCode.isVisible = false
- views.qrCodeLoginStatusNoMatchLayout.isVisible = false
- views.qrCodeLoginStatusCancelButton.isVisible = false
- views.qrCodeLoginStatusTryAgainButton.isVisible = false
- views.qrCodeLoginStatusLoadingTextView.setText(CommonStrings.qr_code_login_signing_in)
- }
-
- private fun handleConnectionEstablished(connectionStatus: QrCodeLoginConnectionStatus.Connected, loginType: QrCodeLoginType) {
- views.qrCodeLoginConfirmSecurityCodeLayout.isVisible = loginType == QrCodeLoginType.LINK_A_DEVICE
- views.qrCodeLoginStatusLoadingLayout.isVisible = false
- views.qrCodeLoginStatusHeaderView.isVisible = true
- views.qrCodeLoginStatusSecurityCode.isVisible = true
- views.qrCodeLoginStatusNoMatchLayout.isVisible = loginType == QrCodeLoginType.LOGIN
- views.qrCodeLoginStatusCancelButton.isVisible = true
- views.qrCodeLoginStatusTryAgainButton.isVisible = false
- views.qrCodeLoginStatusSecurityCode.text = connectionStatus.securityCode
- views.qrCodeLoginStatusHeaderView.setTitle(getString(CommonStrings.qr_code_login_header_connected_title))
- views.qrCodeLoginStatusHeaderView.setDescription(getString(CommonStrings.qr_code_login_header_connected_description))
- views.qrCodeLoginStatusHeaderView.setImage(
- imageResource = R.drawable.ic_qr_code_login_connected,
- backgroundTintColor = ThemeUtils.getColor(requireContext(), com.google.android.material.R.attr.colorPrimary)
- )
- }
-
- override fun invalidate() = withState(viewModel) { state ->
- when (state.connectionStatus) {
- is QrCodeLoginConnectionStatus.Connected -> handleConnectionEstablished(state.connectionStatus, state.loginType)
- QrCodeLoginConnectionStatus.ConnectingToDevice -> handleConnectingToDevice()
- QrCodeLoginConnectionStatus.SigningIn -> handleSigningIn()
- is QrCodeLoginConnectionStatus.Failed -> handleFailed(state.connectionStatus)
- null -> { /* NOOP */
- }
- }
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginType.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginType.kt
deleted file mode 100644
index b4bb5b667f..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginType.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-enum class QrCodeLoginType {
- LOGIN,
- LINK_A_DEVICE,
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewEvents.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewEvents.kt
deleted file mode 100644
index e20ea6b2e8..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewEvents.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import im.vector.app.core.platform.VectorViewEvents
-
-sealed class QrCodeLoginViewEvents : VectorViewEvents {
- object NavigateToStatusScreen : QrCodeLoginViewEvents()
- object NavigateToShowQrCodeScreen : QrCodeLoginViewEvents()
- object NavigateToHomeScreen : QrCodeLoginViewEvents()
- object NavigateToInitialScreen : QrCodeLoginViewEvents()
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewModel.kt
deleted file mode 100644
index 97cca9d791..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewModel.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import com.airbnb.mvrx.MavericksViewModelFactory
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-import im.vector.app.core.di.ActiveSessionHolder
-import im.vector.app.core.di.MavericksAssistedViewModelFactory
-import im.vector.app.core.di.hiltMavericksViewModelFactory
-import im.vector.app.core.platform.VectorViewModel
-import im.vector.app.core.session.ConfigureAndStartSessionUseCase
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import org.matrix.android.sdk.api.auth.AuthenticationService
-import org.matrix.android.sdk.api.rendezvous.Rendezvous
-import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
-import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
-import timber.log.Timber
-
-class QrCodeLoginViewModel @AssistedInject constructor(
- @Assisted private val initialState: QrCodeLoginViewState,
- private val authenticationService: AuthenticationService,
- private val activeSessionHolder: ActiveSessionHolder,
- private val configureAndStartSessionUseCase: ConfigureAndStartSessionUseCase,
-) : VectorViewModel(initialState) {
-
- @AssistedFactory
- interface Factory : MavericksAssistedViewModelFactory {
- override fun create(initialState: QrCodeLoginViewState): QrCodeLoginViewModel
- }
-
- companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() {
- val TAG: String = QrCodeLoginViewModel::class.java.simpleName
- }
-
- override fun handle(action: QrCodeLoginAction) {
- when (action) {
- is QrCodeLoginAction.OnQrCodeScanned -> handleOnQrCodeScanned(action)
- QrCodeLoginAction.GenerateQrCode -> handleQrCodeViewStarted()
- QrCodeLoginAction.ShowQrCode -> handleShowQrCode()
- QrCodeLoginAction.TryAgain -> handleTryAgain()
- }
- }
-
- private fun handleTryAgain() {
- setState {
- copy(
- connectionStatus = null
- )
- }
- _viewEvents.post(QrCodeLoginViewEvents.NavigateToInitialScreen)
- }
-
- private fun handleShowQrCode() {
- _viewEvents.post(QrCodeLoginViewEvents.NavigateToShowQrCodeScreen)
- }
-
- private fun handleQrCodeViewStarted() {
- val qrCodeData = generateQrCodeData()
- setState {
- copy(
- generatedQrCodeData = qrCodeData
- )
- }
- }
-
- private fun handleOnQrCodeScanned(action: QrCodeLoginAction.OnQrCodeScanned) {
- Timber.tag(TAG).d("Scanned code of length ${action.qrCode.length}")
-
- val rendezvous = try { Rendezvous.buildChannelFromCode(action.qrCode) } catch (t: Throwable) {
- Timber.tag(TAG).e(t, "Error occurred during sign in")
- if (t is RendezvousError) {
- onFailed(t.reason)
- } else {
- onFailed(RendezvousFailureReason.Unknown)
- }
- return
- }
-
- setState {
- copy(
- connectionStatus = QrCodeLoginConnectionStatus.ConnectingToDevice
- )
- }
-
- _viewEvents.post(QrCodeLoginViewEvents.NavigateToStatusScreen)
-
- viewModelScope.launch(Dispatchers.IO) {
- try {
- val confirmationCode = rendezvous.startAfterScanningCode()
- Timber.tag(TAG).i("Established secure channel with checksum: $confirmationCode")
-
- onConnectionEstablished(confirmationCode)
-
- val session = rendezvous.waitForLoginOnNewDevice(authenticationService)
- onSigningIn()
-
- activeSessionHolder.setActiveSession(session)
- authenticationService.reset()
- configureAndStartSessionUseCase.execute(session)
-
- rendezvous.completeVerificationOnNewDevice(session)
-
- _viewEvents.post(QrCodeLoginViewEvents.NavigateToHomeScreen)
- } catch (t: Throwable) {
- Timber.tag(TAG).e(t, "Error occurred during sign in")
- if (t is RendezvousError) {
- onFailed(t.reason)
- } else {
- onFailed(RendezvousFailureReason.Unknown)
- }
- }
- }
- }
-
- private fun onFailed(reason: RendezvousFailureReason) {
- _viewEvents.post(QrCodeLoginViewEvents.NavigateToStatusScreen)
-
- setState {
- copy(
- connectionStatus = QrCodeLoginConnectionStatus.Failed(reason, reason.canRetry)
- )
- }
- }
-
- private fun onConnectionEstablished(securityCode: String) {
- val canConfirmSecurityCode = initialState.loginType == QrCodeLoginType.LINK_A_DEVICE
- setState {
- copy(
- connectionStatus = QrCodeLoginConnectionStatus.Connected(securityCode, canConfirmSecurityCode)
- )
- }
- }
-
- private fun onSigningIn() {
- setState {
- copy(
- connectionStatus = QrCodeLoginConnectionStatus.SigningIn
- )
- }
- }
-
- /**
- * QR code generation is not currently supported and this is a placeholder for future
- * functionality.
- */
- private fun generateQrCodeData(): String {
- return "NOT SUPPORTED"
- }
-}
diff --git a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewState.kt b/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewState.kt
deleted file mode 100644
index 0c4457c12f..0000000000
--- a/vector/src/main/java/im/vector/app/features/login/qr/QrCodeLoginViewState.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2022 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.login.qr
-
-import com.airbnb.mvrx.MavericksState
-
-data class QrCodeLoginViewState(
- val loginType: QrCodeLoginType,
- val connectionStatus: QrCodeLoginConnectionStatus? = null,
- val generatedQrCodeData: String? = null,
-) : MavericksState {
-
- constructor(args: QrCodeLoginArgs) : this(
- loginType = args.loginType,
- )
-}
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 755b9b3676..dde658ce6d 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
@@ -71,8 +71,6 @@ import im.vector.app.features.location.live.map.LiveLocationMapViewActivity
import im.vector.app.features.location.live.map.LiveLocationMapViewArgs
import im.vector.app.features.login.LoginActivity
import im.vector.app.features.login.LoginConfig
-import im.vector.app.features.login.qr.QrCodeLoginActivity
-import im.vector.app.features.login.qr.QrCodeLoginArgs
import im.vector.app.features.matrixto.MatrixToBottomSheet
import im.vector.app.features.matrixto.OriginOfMatrixTo
import im.vector.app.features.media.AttachmentData
@@ -614,14 +612,6 @@ class DefaultNavigator @Inject constructor(
activityResultLauncher.launch(screenCaptureIntent)
}
- override fun openLoginWithQrCode(context: Context, qrCodeLoginArgs: QrCodeLoginArgs) {
- QrCodeLoginActivity
- .getIntent(context, qrCodeLoginArgs)
- .also {
- context.startActivity(it)
- }
- }
-
private fun Intent.start(context: Context) {
context.startActivity(this)
}
diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
index 5c6a36f797..23fbedf573 100644
--- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
+++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt
@@ -31,7 +31,6 @@ import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
import im.vector.app.features.location.LocationData
import im.vector.app.features.location.LocationSharingMode
import im.vector.app.features.login.LoginConfig
-import im.vector.app.features.login.qr.QrCodeLoginArgs
import im.vector.app.features.matrixto.OriginOfMatrixTo
import im.vector.app.features.media.AttachmentData
import im.vector.app.features.pin.PinMode
@@ -202,9 +201,4 @@ interface Navigator {
screenCaptureIntent: Intent,
activityResultLauncher: ActivityResultLauncher
)
-
- fun openLoginWithQrCode(
- context: Context,
- qrCodeLoginArgs: QrCodeLoginArgs,
- )
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
index 949c728aa2..21b806fda1 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt
@@ -121,29 +121,6 @@ class OnboardingViewModel @AssistedInject constructor(
}
}
- private fun checkQrCodeLoginCapability() {
- if (!vectorFeatures.isQrCodeLoginEnabled()) {
- setState {
- copy(
- canLoginWithQrCode = false
- )
- }
- } else if (vectorFeatures.isQrCodeLoginForAllServers()) {
- // allow for all servers
- setState {
- copy(
- canLoginWithQrCode = true
- )
- }
- } else {
- setState {
- copy(
- canLoginWithQrCode = selectedHomeserver.isLoginWithQrSupported
- )
- }
- }
- }
-
private val matrixOrgUrl = stringProvider.getString(im.vector.app.config.R.string.matrix_org_server_url).ensureTrailingSlash()
private val defaultHomeserverUrl = mdmService.getData(MdmData.DefaultHomeserverUrl, matrixOrgUrl)
@@ -710,7 +687,6 @@ class OnboardingViewModel @AssistedInject constructor(
_viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig")))
} else {
startAuthenticationFlow(action, homeServerConnectionConfig, serverTypeOverride, suspend {
- checkQrCodeLoginCapability()
postAction()
})
}
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
index 58b28ac4e4..defb08aeae 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt
@@ -59,8 +59,6 @@ data class OnboardingViewState(
@PersistState
val personalizationState: PersonalizationState = PersonalizationState(),
-
- val canLoginWithQrCode: Boolean = false,
) : MavericksState
enum class OnboardingFlow {
diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt
index abcfcafc64..cb687f6b00 100644
--- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt
@@ -40,8 +40,6 @@ import im.vector.app.features.VectorFeatures
import im.vector.app.features.login.LoginMode
import im.vector.app.features.login.SSORedirectRouterActivity
import im.vector.app.features.login.SocialLoginButtonsView
-import im.vector.app.features.login.qr.QrCodeLoginArgs
-import im.vector.app.features.login.qr.QrCodeLoginType
import im.vector.app.features.login.render
import im.vector.app.features.onboarding.OnboardingAction
import im.vector.app.features.onboarding.OnboardingViewEvents
@@ -75,26 +73,6 @@ class FtueAuthCombinedLoginFragment :
viewModel.handle(OnboardingAction.UserNameEnteredAction.Login(views.loginInput.content()))
}
views.loginForgotPassword.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnForgetPasswordClicked)) }
-
- viewModel.onEach(OnboardingViewState::canLoginWithQrCode) {
- configureQrCodeLoginButtonVisibility(it)
- }
- }
-
- private fun configureQrCodeLoginButtonVisibility(canLoginWithQrCode: Boolean) {
- views.loginWithQrCode.isVisible = canLoginWithQrCode
- if (canLoginWithQrCode) {
- views.loginWithQrCode.debouncedClicks {
- navigator
- .openLoginWithQrCode(
- requireActivity(),
- QrCodeLoginArgs(
- loginType = QrCodeLoginType.LOGIN,
- showQrCodeImmediately = false,
- )
- )
- }
- }
}
private fun setupSubmitButton() {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
index d680de8aa3..0c49fd07ba 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
@@ -41,8 +41,6 @@ import im.vector.app.databinding.FragmentSettingsDevicesBinding
import im.vector.app.features.VectorFeatures
import im.vector.app.features.auth.ReAuthActivity
import im.vector.app.features.crypto.recover.SetupMode
-import im.vector.app.features.login.qr.QrCodeLoginArgs
-import im.vector.app.features.login.qr.QrCodeLoginType
import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType
import im.vector.app.features.settings.devices.v2.list.NUMBER_OF_OTHER_DEVICES_TO_RENDER
import im.vector.app.features.settings.devices.v2.list.OtherSessionsView
@@ -106,7 +104,6 @@ class VectorSettingsDevicesFragment :
initOtherSessionsHeaderView()
initOtherSessionsView()
initSecurityRecommendationsView()
- initQrLoginView()
observeViewEvents()
}
@@ -240,38 +237,6 @@ class VectorSettingsDevicesFragment :
}
}
- private fun initQrLoginView() {
- if (!vectorFeatures.isReciprocateQrCodeLogin()) {
- views.deviceListHeaderSignInWithQrCode.isVisible = false
- views.deviceListHeaderScanQrCodeButton.isVisible = false
- views.deviceListHeaderShowQrCodeButton.isVisible = false
- return
- }
-
- views.deviceListHeaderSignInWithQrCode.isVisible = true
- views.deviceListHeaderScanQrCodeButton.isVisible = true
- views.deviceListHeaderShowQrCodeButton.isVisible = true
-
- views.deviceListHeaderScanQrCodeButton.debouncedClicks {
- navigateToQrCodeScreen(showQrCodeImmediately = false)
- }
-
- views.deviceListHeaderShowQrCodeButton.debouncedClicks {
- navigateToQrCodeScreen(showQrCodeImmediately = true)
- }
- }
-
- private fun navigateToQrCodeScreen(showQrCodeImmediately: Boolean) {
- navigator
- .openLoginWithQrCode(
- requireActivity(),
- QrCodeLoginArgs(
- loginType = QrCodeLoginType.LINK_A_DEVICE,
- showQrCodeImmediately = showQrCodeImmediately,
- )
- )
- }
-
override fun onDestroyView() {
cleanUpLearnMoreButtonsListeners()
super.onDestroyView()
diff --git a/vector/src/main/res/drawable/circle_qr_code_login_instruction_with_border.xml b/vector/src/main/res/drawable/circle_qr_code_login_instruction_with_border.xml
deleted file mode 100644
index cb99e4467c..0000000000
--- a/vector/src/main/res/drawable/circle_qr_code_login_instruction_with_border.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/res/drawable/ic_qr_code.xml b/vector/src/main/res/drawable/ic_qr_code.xml
deleted file mode 100644
index 1ebdc169c9..0000000000
--- a/vector/src/main/res/drawable/ic_qr_code.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/vector/src/main/res/drawable/ic_qr_code_login_connected.xml b/vector/src/main/res/drawable/ic_qr_code_login_connected.xml
deleted file mode 100644
index 48f5c6a383..0000000000
--- a/vector/src/main/res/drawable/ic_qr_code_login_connected.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/vector/src/main/res/drawable/ic_qr_code_login_failed.xml b/vector/src/main/res/drawable/ic_qr_code_login_failed.xml
deleted file mode 100644
index f49e07c066..0000000000
--- a/vector/src/main/res/drawable/ic_qr_code_login_failed.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/vector/src/main/res/layout/fragment_ftue_combined_login.xml b/vector/src/main/res/layout/fragment_ftue_combined_login.xml
index 7eff92f4f9..a589ec6f5a 100644
--- a/vector/src/main/res/layout/fragment_ftue_combined_login.xml
+++ b/vector/src/main/res/layout/fragment_ftue_combined_login.xml
@@ -244,20 +244,6 @@
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
app:layout_constraintTop_toBottomOf="@id/loginSubmit" />
-
-
diff --git a/vector/src/main/res/layout/fragment_qr_code_login_instructions.xml b/vector/src/main/res/layout/fragment_qr_code_login_instructions.xml
deleted file mode 100644
index a13e460a5a..0000000000
--- a/vector/src/main/res/layout/fragment_qr_code_login_instructions.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/res/layout/fragment_qr_code_login_show_qr_code.xml b/vector/src/main/res/layout/fragment_qr_code_login_show_qr_code.xml
deleted file mode 100644
index 539f019848..0000000000
--- a/vector/src/main/res/layout/fragment_qr_code_login_show_qr_code.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/res/layout/fragment_qr_code_login_status.xml b/vector/src/main/res/layout/fragment_qr_code_login_status.xml
deleted file mode 100644
index 59e1e60cd5..0000000000
--- a/vector/src/main/res/layout/fragment_qr_code_login_status.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/res/layout/fragment_settings_devices.xml b/vector/src/main/res/layout/fragment_settings_devices.xml
index 266f8df46f..3b7d164b99 100644
--- a/vector/src/main/res/layout/fragment_settings_devices.xml
+++ b/vector/src/main/res/layout/fragment_settings_devices.xml
@@ -1,7 +1,6 @@
@@ -111,47 +110,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/deviceListHeaderOtherSessions" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/res/layout/view_qr_code_login_instructions.xml b/vector/src/main/res/layout/view_qr_code_login_instructions.xml
deleted file mode 100644
index fee3e2c5d6..0000000000
--- a/vector/src/main/res/layout/view_qr_code_login_instructions.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
index 5735573862..c2d1cfd342 100644
--- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt
@@ -162,28 +162,6 @@ class OnboardingViewModelTest {
.finish()
}
- @Test
- fun `given combined login enabled, when handling sign in splash action, then emits OpenCombinedLogin with default homeserver qrCode supported`() = runTest {
- val test = viewModel.test()
- fakeVectorFeatures.givenCombinedLoginEnabled()
- givenCanSuccessfullyUpdateHomeserver(A_DEFAULT_HOMESERVER_URL, DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED)
-
- viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(OnboardingFlow.SignIn))
-
- test
- .assertStatesChanges(
- initialState,
- { copy(onboardingFlow = OnboardingFlow.SignIn) },
- { copy(isLoading = true) },
- { copy(selectedHomeserver = DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED) },
- { copy(signMode = SignMode.SignIn) },
- { copy(canLoginWithQrCode = true) },
- { copy(isLoading = false) }
- )
- .assertEvents(OnboardingViewEvents.OpenCombinedLogin)
- .finish()
- }
-
@Test
fun `given can successfully login in with token, when logging in with token, then emits AccountSignedIn`() = runTest {
val test = viewModel.test()