diff --git a/changelog.d/7737.bugfix b/changelog.d/7737.bugfix new file mode 100644 index 0000000000..1477834674 --- /dev/null +++ b/changelog.d/7737.bugfix @@ -0,0 +1 @@ +Fix issue of Scan QR code button sometimes not showing when it should be available diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt index 252c33a8c4..e490311b91 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt @@ -125,12 +125,6 @@ interface AuthenticationService { deviceId: String? = null ): Session - /** - * @param homeServerConnectionConfig the information about the homeserver and other configuration - * Return true if qr code login is supported by the server, false otherwise. - */ - suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean - /** * Authenticate using m.login.token method during sign in with QR code. * @param homeServerConnectionConfig the information about the homeserver and other configuration diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt index 5b6c1897bf..5de83033e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LoginFlowResult.kt @@ -22,5 +22,6 @@ data class LoginFlowResult( val isLoginAndRegistrationSupported: Boolean, val homeServerUrl: String, val isOutdatedHomeserver: Boolean, - val isLogoutDevicesSupported: Boolean + val isLogoutDevicesSupported: Boolean, + val isLoginWithQrSupported: Boolean, ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 5449c0a735..d9c2afcb40 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.auth.wellknown.WellknownResult -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixIdFailure import org.matrix.android.sdk.api.session.Session @@ -299,7 +298,8 @@ internal class DefaultAuthenticationService @Inject constructor( isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(), homeServerUrl = homeServerUrl, isOutdatedHomeserver = !versions.isSupportedBySdk(), - isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices() + isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices(), + isLoginWithQrSupported = versions.doesServerSupportQrCodeLogin(), ) } @@ -408,20 +408,6 @@ internal class DefaultAuthenticationService @Inject constructor( ) } - override suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean { - val authAPI = buildAuthAPI(homeServerConnectionConfig) - val versions = runCatching { - executeRequest(null) { - authAPI.versions() - } - } - return if (versions.isSuccess) { - versions.getOrNull()?.doesServerSupportQrCodeLogin().orFalse() - } else { - false - } - } - override suspend fun loginUsingQrLoginToken( homeServerConnectionConfig: HomeServerConnectionConfig, loginToken: String, 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 7fe73f8087..04487c6198 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 @@ -118,7 +118,7 @@ class OnboardingViewModel @AssistedInject constructor( } } - private suspend fun checkQrCodeLoginCapability(config: HomeServerConnectionConfig) { + private fun checkQrCodeLoginCapability() { if (!vectorFeatures.isQrCodeLoginEnabled()) { setState { copy( @@ -133,11 +133,9 @@ class OnboardingViewModel @AssistedInject constructor( ) } } else { - // check if selected server supports MSC3882 first - val canLoginWithQrCode = authenticationService.isQrLoginSupported(config) setState { copy( - canLoginWithQrCode = canLoginWithQrCode + canLoginWithQrCode = selectedHomeserver.isLoginWithQrSupported ) } } @@ -705,7 +703,10 @@ class OnboardingViewModel @AssistedInject constructor( // This is invalid _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig"))) } else { - startAuthenticationFlow(action, homeServerConnectionConfig, serverTypeOverride, postAction) + startAuthenticationFlow(action, homeServerConnectionConfig, serverTypeOverride, suspend { + checkQrCodeLoginCapability() + postAction() + }) } } @@ -764,8 +765,6 @@ class OnboardingViewModel @AssistedInject constructor( _viewEvents.post(OnboardingViewEvents.OutdatedHomeserver) } - checkQrCodeLoginCapability(config) - when (trigger) { is OnboardingAction.HomeServerChange.SelectHomeServer -> { onHomeServerSelected(config, serverTypeOverride, authResult) 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 6e7d58338e..ea0d940952 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 @@ -76,6 +76,7 @@ data class SelectedHomeserverState( val preferredLoginMode: LoginMode = LoginMode.Unknown, val supportedLoginTypes: List = emptyList(), val isLogoutDevicesSupported: Boolean = false, + val isLoginWithQrSupported: Boolean = false, ) : Parcelable @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt index db21a53854..9b8f0a1cc4 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt @@ -47,7 +47,8 @@ class StartAuthenticationFlowUseCase @Inject constructor( upstreamUrl = authFlow.homeServerUrl, preferredLoginMode = preferredLoginMode, supportedLoginTypes = authFlow.supportedLoginTypes, - isLogoutDevicesSupported = authFlow.isLogoutDevicesSupported + isLogoutDevicesSupported = authFlow.isLogoutDevicesSupported, + isLoginWithQrSupported = authFlow.isLoginWithQrSupported, ) private fun LoginFlowResult.findPreferredLoginMode() = when { 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 92083eb50b..c570a75d99 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 @@ -83,6 +83,7 @@ private val A_HOMESERVER_CONFIG = HomeServerConnectionConfig(FakeUri().instance) private val SELECTED_HOMESERVER_STATE = SelectedHomeserverState(preferredLoginMode = LoginMode.Password, userFacingUrl = A_HOMESERVER_URL) private val SELECTED_HOMESERVER_STATE_SUPPORTED_LOGOUT_DEVICES = SelectedHomeserverState(isLogoutDevicesSupported = true) private val DEFAULT_SELECTED_HOMESERVER_STATE = SELECTED_HOMESERVER_STATE.copy(userFacingUrl = A_DEFAULT_HOMESERVER_URL) +private val DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED = DEFAULT_SELECTED_HOMESERVER_STATE.copy(isLoginWithQrSupported = true) private const val AN_EMAIL = "hello@example.com" private const val A_PASSWORD = "a-password" private const val A_USERNAME = "hello-world" @@ -164,7 +165,7 @@ class OnboardingViewModelTest { 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, canLoginWithQrCode = true) + givenCanSuccessfullyUpdateHomeserver(A_DEFAULT_HOMESERVER_URL, DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED) viewModel.handle(OnboardingAction.SplashAction.OnIAlreadyHaveAnAccount(OnboardingFlow.SignIn)) @@ -173,9 +174,9 @@ class OnboardingViewModelTest { initialState, { copy(onboardingFlow = OnboardingFlow.SignIn) }, { copy(isLoading = true) }, - { copy(canLoginWithQrCode = true) }, - { copy(selectedHomeserver = DEFAULT_SELECTED_HOMESERVER_STATE) }, + { copy(selectedHomeserver = DEFAULT_SELECTED_HOMESERVER_STATE_WITH_QR_SUPPORTED) }, { copy(signMode = SignMode.SignIn) }, + { copy(canLoginWithQrCode = true) }, { copy(isLoading = false) } ) .assertEvents(OnboardingViewEvents.OpenCombinedLogin) @@ -1174,13 +1175,11 @@ class OnboardingViewModelTest { resultingState: SelectedHomeserverState, config: HomeServerConnectionConfig = A_HOMESERVER_CONFIG, fingerprint: Fingerprint? = null, - canLoginWithQrCode: Boolean = false, ) { fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprint, config) fakeStartAuthenticationFlowUseCase.givenResult(config, StartAuthenticationResult(isHomeserverOutdated = false, resultingState)) givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.StartRegistration) fakeHomeServerHistoryService.expectUrlToBeAdded(config.homeServerUri.toString()) - fakeAuthenticationService.givenIsQrLoginSupported(config, canLoginWithQrCode) } private fun givenUpdatingHomeserverErrors(homeserverUrl: String, resultingState: SelectedHomeserverState, error: Throwable) { @@ -1188,7 +1187,6 @@ class OnboardingViewModelTest { fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, resultingState)) givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.Error(error)) fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString()) - fakeAuthenticationService.givenIsQrLoginSupported(A_HOMESERVER_CONFIG, false) } private fun givenUserNameIsAvailable(userName: String) { diff --git a/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt index d15a6cf042..9be22d7ea9 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt @@ -140,7 +140,8 @@ class StartAuthenticationFlowUseCaseTest { isLoginAndRegistrationSupported = true, homeServerUrl = A_DECLARED_HOMESERVER_URL, isOutdatedHomeserver = false, - isLogoutDevicesSupported = false + isLogoutDevicesSupported = false, + isLoginWithQrSupported = false ) private fun expectedResult( diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt index 5d0e317c57..af53913169 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt @@ -58,10 +58,6 @@ class FakeAuthenticationService : AuthenticationService by mockk() { coEvery { getWellKnownData(matrixId, config) } returns result } - fun givenIsQrLoginSupported(config: HomeServerConnectionConfig, result: Boolean) { - coEvery { isQrLoginSupported(config) } returns result - } - fun givenWellKnownThrows(matrixId: String, config: HomeServerConnectionConfig?, cause: Throwable) { coEvery { getWellKnownData(matrixId, config) } throws cause }