diff --git a/vector/build.gradle b/vector/build.gradle index 3ecdcea524..7b4abeb385 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -137,6 +137,10 @@ android { buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\"" resValue "string", "build_number", "\"${buildNumber}\"" + // The two booleans must not have the same value. We need two values for the manifest + resValue "bool", "useLoginV1", "false" + resValue "bool", "useLoginV2", "true" + buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index b363df397e..82d0fb0b0f 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -106,6 +106,7 @@ @@ -122,6 +123,7 @@ diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 50a86d24ed..054b1bcff1 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -42,6 +42,7 @@ import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.signout.hard.SignedOutActivity import im.vector.app.features.signout.soft.SoftLogoutActivity +import im.vector.app.features.signout.soft.SoftLogoutActivity2 import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.ui.UiStateRepository import kotlinx.parcelize.Parcelize @@ -228,7 +229,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity } args.isSoftLogout -> // The homeserver has invalidated the token, with a soft logout - SoftLogoutActivity.newIntent(this) + getSoftLogoutActivityIntent() args.isUserLoggedOut -> // the homeserver has invalidated the token (password changed, device deleted, other security reasons) SignedOutActivity.newIntent(this) @@ -239,7 +240,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity HomeActivity.newIntent(this) } else { // The token is still invalid - SoftLogoutActivity.newIntent(this) + getSoftLogoutActivityIntent() } else -> { // First start, or no active session @@ -250,4 +251,12 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity intent?.let { startActivity(it) } finish() } + + private fun getSoftLogoutActivityIntent(): Intent { + return if (resources.getBoolean(R.bool.useLoginV2)) { + SoftLogoutActivity2.newIntent(this) + } else { + SoftLogoutActivity.newIntent(this) + } + } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt index d4fdf2e80e..bafe836a8d 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt @@ -24,9 +24,7 @@ import android.view.ViewGroup import androidx.core.view.isVisible import im.vector.app.BuildConfig import im.vector.app.databinding.FragmentLoginSplashBinding -import im.vector.app.features.login2.LoginActivity2 import im.vector.app.features.settings.VectorPreferences - import javax.inject.Inject /** @@ -56,13 +54,6 @@ class LoginSplashFragment @Inject constructor( "Branch: ${BuildConfig.GIT_BRANCH_NAME}\n" + "Build: ${BuildConfig.BUILD_NUMBER}" } - - views.loginSplashNewFlow.setOnClickListener { startNewFlow() } - } - - private fun startNewFlow() { - startActivity(LoginActivity2.newIntent(requireContext(), null)) - requireActivity().finish() } private fun getStarted() { 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 c6df7910ea..b232d1f903 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 @@ -56,6 +56,7 @@ import im.vector.app.features.home.room.filtered.FilteredRoomsActivity import im.vector.app.features.invite.InviteUsersToRoomActivity import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig +import im.vector.app.features.login2.LoginActivity2 import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.BigImageViewerActivity @@ -99,7 +100,11 @@ class DefaultNavigator @Inject constructor( ) : Navigator { override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) { - val intent = LoginActivity.newIntent(context, loginConfig) + val intent = if (context.resources.getBoolean(R.bool.useLoginV2)) { + LoginActivity2.newIntent(context, loginConfig) + } else { + LoginActivity.newIntent(context, loginConfig) + } intent.addFlags(flags) context.startActivity(intent) } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt new file mode 100644 index 0000000000..cfccc6f699 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -0,0 +1,119 @@ +/* + * Copyright 2021 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.signout.soft + +import android.content.Context +import android.content.Intent +import androidx.appcompat.app.AlertDialog +import androidx.core.view.isVisible +import androidx.fragment.app.FragmentManager +import com.airbnb.mvrx.Success +import com.airbnb.mvrx.viewModel +import im.vector.app.R +import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.error.ErrorFormatter +import im.vector.app.core.extensions.replaceFragment +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs +import im.vector.app.features.login2.LoginActivity2 + +import org.matrix.android.sdk.api.failure.GlobalError +import org.matrix.android.sdk.api.session.Session +import timber.log.Timber +import javax.inject.Inject + +/** + * In this screen, the user is viewing a message informing that he has been logged out + * Extends LoginActivity to get the login with SSO and forget password functionality for (nearly) free + * + * This is just a copy of SoftLogoutActivity2, which extends LoginActivity2 + */ +class SoftLogoutActivity2 : LoginActivity2() { + + private val softLogoutViewModel: SoftLogoutViewModel by viewModel() + + @Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory + @Inject lateinit var session: Session + @Inject lateinit var errorFormatter: ErrorFormatter + + override fun injectWith(injector: ScreenComponent) { + super.injectWith(injector) + injector.inject(this) + } + + override fun initUiAndData() { + super.initUiAndData() + + softLogoutViewModel.subscribe(this) { + updateWithState(it) + } + + softLogoutViewModel.observeViewEvents { handleSoftLogoutViewEvents(it) } + } + + private fun handleSoftLogoutViewEvents(softLogoutViewEvents: SoftLogoutViewEvents) { + when (softLogoutViewEvents) { + is SoftLogoutViewEvents.Failure -> + showError(errorFormatter.toHumanReadable(softLogoutViewEvents.throwable)) + is SoftLogoutViewEvents.ErrorNotSameUser -> { + // Pop the backstack + supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) + + // And inform the user + showError(getString( + R.string.soft_logout_sso_not_same_user_error, + softLogoutViewEvents.currentUserId, + softLogoutViewEvents.newUserId) + ) + } + is SoftLogoutViewEvents.ClearData -> { + MainActivity.restartApp(this, MainActivityArgs(clearCredentials = true)) + } + } + } + + private fun showError(message: String) { + AlertDialog.Builder(this) + .setTitle(R.string.dialog_title_error) + .setMessage(message) + .setPositiveButton(R.string.ok, null) + .show() + } + + override fun addFirstFragment() { + replaceFragment(R.id.loginFragmentContainer, SoftLogoutFragment::class.java) + } + + private fun updateWithState(softLogoutViewState: SoftLogoutViewState) { + if (softLogoutViewState.asyncLoginAction is Success) { + MainActivity.restartApp(this, MainActivityArgs()) + } + + views.loginLoading.isVisible = softLogoutViewState.isLoading() + } + + companion object { + fun newIntent(context: Context): Intent { + return Intent(context, SoftLogoutActivity2::class.java) + } + } + + override fun handleInvalidToken(globalError: GlobalError.InvalidToken) { + // No op here + Timber.w("Ignoring invalid token global error") + } +} diff --git a/vector/src/main/res/layout/fragment_login_splash.xml b/vector/src/main/res/layout/fragment_login_splash.xml index 9a39c40a68..92655c87b6 100644 --- a/vector/src/main/res/layout/fragment_login_splash.xml +++ b/vector/src/main/res/layout/fragment_login_splash.xml @@ -204,13 +204,4 @@ tools:text="@string/settings_version" tools:visibility="visible" /> - - diff --git a/vector/src/main/res/values/strings_login_v2.xml b/vector/src/main/res/values/strings_login_v2.xml index 73f5ba03b4..3062929050 100644 --- a/vector/src/main/res/values/strings_login_v2.xml +++ b/vector/src/main/res/values/strings_login_v2.xml @@ -21,7 +21,6 @@ Once your account is created, your identifier cannot be modified. However you will be able to change your display name. If you\'re not sure, select this option Element Matrix Server and others - Try the new flow Create a new account I already have an account