diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceView.kt b/app/src/main/java/org/mozilla/fenix/settings/SyncPreferenceView.kt similarity index 57% rename from app/src/main/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceView.kt rename to app/src/main/java/org/mozilla/fenix/settings/SyncPreferenceView.kt index c8106882b9..578d1eea37 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceView.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SyncPreferenceView.kt @@ -2,10 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mozilla.fenix.settings.logins +package org.mozilla.fenix.settings import androidx.lifecycle.LifecycleOwner -import androidx.navigation.NavController import androidx.preference.Preference import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch @@ -16,16 +15,33 @@ import mozilla.components.service.fxa.SyncEngine import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.manager.SyncEnginesStorage import org.mozilla.fenix.R -import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections /** - * Helper to manage the [R.string.pref_key_password_sync_logins] preference. + * A view to help manage the sync preference in the "Logins and passwords" and "Credit cards" + * settings. The provided [syncPreference] is used to navigate to the different fragments + * that manages the sync account authentication. A summary status will be also added + * depending on the sync account status. + * + * @param syncPreference The sync [Preference] to update and handle navigation. + * @param lifecycleOwner View lifecycle owner used to determine when to cancel UI jobs. + * @param accountManager An instance of [FxaAccountManager]. + * @param syncEngine The sync engine that will be used for the sync status lookup. + * @param onSignInToSyncClicked A callback executed when the [syncPreference] is clicked with a + * preference status of "Sign in to Sync". + * @param onSyncStatusClicked A callback executed when the [syncPreference] is clicked with a + * preference status of "On" or "Off". + * @param onReconnectClicked A callback executed when the [syncPreference] is clicked with a + * preference status of "Reconnect". */ -class SyncLoginsPreferenceView( - private val syncLoginsPreference: Preference, +@Suppress("LongParameterList") +class SyncPreferenceView( + private val syncPreference: Preference, lifecycleOwner: LifecycleOwner, accountManager: FxaAccountManager, - private val navController: NavController + private val syncEngine: SyncEngine, + private val onSignInToSyncClicked: () -> Unit = {}, + private val onSyncStatusClicked: () -> Unit = {}, + private val onReconnectClicked: () -> Unit = {} ) { init { @@ -33,9 +49,11 @@ class SyncLoginsPreferenceView( override fun onAuthenticated(account: OAuthAccount, authType: AuthType) { MainScope().launch { updateSyncPreferenceStatus() } } + override fun onLoggedOut() { MainScope().launch { updateSyncPreferenceNeedsLogin() } } + override fun onAuthenticationProblems() { MainScope().launch { updateSyncPreferenceNeedsReauth() } } @@ -43,6 +61,7 @@ class SyncLoginsPreferenceView( val accountExists = accountManager.authenticatedAccount() != null val needsReauth = accountManager.accountNeedsReauth() + when { needsReauth -> updateSyncPreferenceNeedsReauth() accountExists -> updateSyncPreferenceStatus() @@ -51,62 +70,50 @@ class SyncLoginsPreferenceView( } /** - * Show the current status of the sync preference (on/off) for the logged in user. + * Shows the current status of the sync preference ("On"/"Off") for the logged in user. */ private fun updateSyncPreferenceStatus() { - syncLoginsPreference.apply { + syncPreference.apply { val syncEnginesStatus = SyncEnginesStorage(context).getStatus() - val loginsSyncStatus = syncEnginesStatus.getOrElse(SyncEngine.Passwords) { false } + val loginsSyncStatus = syncEnginesStatus.getOrElse(syncEngine) { false } + summary = context.getString( if (loginsSyncStatus) R.string.preferences_passwords_sync_logins_on else R.string.preferences_passwords_sync_logins_off ) + setOnPreferenceClickListener { - navigateToAccountSettingsFragment() + onSyncStatusClicked() true } } } /** - * Indicate that the user can sign in to turn on sync. + * Display that the user can "Sign in to Sync" when the user is logged off. */ private fun updateSyncPreferenceNeedsLogin() { - syncLoginsPreference.apply { + syncPreference.apply { summary = context.getString(R.string.preferences_passwords_sync_logins_sign_in) + setOnPreferenceClickListener { - navigateToTurnOnSyncFragment() + onSignInToSyncClicked() true } } } /** - * Indicate that the user can fix their account problems to turn on sync. + * Displays that the user needs to "Reconnect" to fix their account problems with sync. */ private fun updateSyncPreferenceNeedsReauth() { - syncLoginsPreference.apply { + syncPreference.apply { summary = context.getString(R.string.preferences_passwords_sync_logins_reconnect) + setOnPreferenceClickListener { - navigateToAccountProblemFragment() + onReconnectClicked() true } } } - - private fun navigateToAccountSettingsFragment() { - val directions = - SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment() - navController.navigate(directions) - } - - private fun navigateToAccountProblemFragment() { - val directions = SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment() - navController.navigate(directions) - } - - private fun navigateToTurnOnSyncFragment() { - val directions = SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment() - navController.navigate(directions) - } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt index 5602571a38..021ef626d8 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsAuthFragment.kt @@ -22,18 +22,19 @@ import androidx.preference.SwitchPreference import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import mozilla.components.service.fxa.SyncEngine import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.ext.secure import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar -import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.settings.SharedPreferenceUpdater +import org.mozilla.fenix.settings.SyncPreferenceView import org.mozilla.fenix.settings.biometric.BiometricPromptFeature -import org.mozilla.fenix.settings.logins.SyncLoginsPreferenceView import org.mozilla.fenix.settings.requirePreference @Suppress("TooManyFunctions") @@ -121,11 +122,26 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() { true } - SyncLoginsPreferenceView( - requirePreference(R.string.pref_key_password_sync_logins), + SyncPreferenceView( + syncPreference = requirePreference(R.string.pref_key_password_sync_logins), lifecycleOwner = viewLifecycleOwner, accountManager = requireComponents.backgroundServices.accountManager, - navController = findNavController() + syncEngine = SyncEngine.Passwords, + onSignInToSyncClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment() + findNavController().navigate(directions) + }, + onSyncStatusClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment() + findNavController().navigate(directions) + }, + onReconnectClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment() + findNavController().navigate(directions) + } ) togglePrefsEnabledWhileAuthenticating(true) diff --git a/app/src/test/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceViewTest.kt b/app/src/test/java/org/mozilla/fenix/settings/logins/LoginsSyncPreferenceViewTest.kt similarity index 84% rename from app/src/test/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceViewTest.kt rename to app/src/test/java/org/mozilla/fenix/settings/logins/LoginsSyncPreferenceViewTest.kt index a6b68ecb45..c985441746 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/logins/SyncLoginsPreferenceViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/logins/LoginsSyncPreferenceViewTest.kt @@ -24,9 +24,10 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.mozilla.fenix.R +import org.mozilla.fenix.settings.SyncPreferenceView import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections -class SyncLoginsPreferenceViewTest { +class LoginsSyncPreferenceViewTest { @MockK private lateinit var syncLoginsPreference: Preference @MockK private lateinit var lifecycleOwner: LifecycleOwner @@ -137,10 +138,25 @@ class SyncLoginsPreferenceViewTest { } } - private fun createView() = SyncLoginsPreferenceView( - syncLoginsPreference, - lifecycleOwner, - accountManager, - navController + private fun createView() = SyncPreferenceView( + syncPreference = syncLoginsPreference, + lifecycleOwner = lifecycleOwner, + accountManager = accountManager, + syncEngine = SyncEngine.Passwords, + onSignInToSyncClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment() + navController.navigate(directions) + }, + onSyncStatusClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment() + navController.navigate(directions) + }, + onReconnectClicked = { + val directions = + SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment() + navController.navigate(directions) + } ) }