mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-03 23:15:31 +00:00
parent
bca8b74263
commit
279d59897c
@ -60,15 +60,29 @@ fun Fragment.hideToolbar() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the backstack to force users to re-auth if they put the app in the background and return to it
|
||||
* while being inside the saved logins flow
|
||||
*
|
||||
* Does nothing if the user is currently navigating to any of the [destinations] given as a parameter
|
||||
* Pops the backstack to force users to re-auth if they put the app in the background and return to
|
||||
* it while being inside a secured flow (e.g. logins or credit cards).
|
||||
*
|
||||
* Does nothing if the user is currently navigating to any of the [destinations] given as a
|
||||
* parameter.
|
||||
*/
|
||||
fun Fragment.redirectToReAuth(destinations: List<Int>, currentDestination: Int?) {
|
||||
fun Fragment.redirectToReAuth(
|
||||
destinations: List<Int>,
|
||||
currentDestination: Int?,
|
||||
currentLocation: Int
|
||||
) {
|
||||
if (currentDestination !in destinations) {
|
||||
findNavController().popBackStack(R.id.savedLoginsAuthFragment, false)
|
||||
when (currentLocation) {
|
||||
R.id.loginDetailFragment,
|
||||
R.id.editLoginFragment,
|
||||
R.id.savedLoginsFragment -> {
|
||||
findNavController().popBackStack(R.id.savedLoginsAuthFragment, false)
|
||||
}
|
||||
R.id.creditCardEditorFragment,
|
||||
R.id.creditCardsManagementFragment -> {
|
||||
findNavController().popBackStack(R.id.creditCardsSettingFragment, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,120 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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.biometric
|
||||
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.settings.requirePreference
|
||||
|
||||
/**
|
||||
* Helper for creating and implementing the [BiometricPromptFeature]. Currently used
|
||||
* for logins and credit cards.
|
||||
*/
|
||||
abstract class BiometricPromptPreferenceFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private val biometricPromptFeature = ViewBoundFeatureWrapper<BiometricPromptFeature>()
|
||||
|
||||
/**
|
||||
* Gets the string to be used for [BiometricPromptFeature.requestAuthentication] prompting to
|
||||
* unlock the device.
|
||||
*/
|
||||
abstract fun unlockMessage(): String
|
||||
|
||||
/**
|
||||
* Navigate when authentication is successful.
|
||||
*/
|
||||
abstract fun navigateOnSuccess()
|
||||
|
||||
/**
|
||||
* Shows a dialog warning to set up a pin/password when the device is not secured. This is
|
||||
* only used when BiometricPrompt is unavailable on the device.
|
||||
*/
|
||||
abstract fun showPinDialogWarning(context: Context)
|
||||
|
||||
/**
|
||||
* Toggle preferences to enable or disable navigation during authentication flows.
|
||||
*
|
||||
* @param prefList a list of [Preference]s to toggle.
|
||||
* @param enabled whether or not the preferences should be enabled.
|
||||
*/
|
||||
fun togglePrefsEnabled(prefList: List<Int>, enabled: Boolean) {
|
||||
for (preference in prefList) {
|
||||
requirePreference<Preference>(preference).isEnabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a prompt to verify the device's pin/password and start activity based on the result.
|
||||
* This is only used when BiometricPrompt is unavailable on the device.
|
||||
*/
|
||||
@Suppress("Deprecation")
|
||||
abstract fun showPinVerification(manager: KeyguardManager)
|
||||
|
||||
/**
|
||||
* Sets the biometric prompt feature.
|
||||
*
|
||||
* @param view the view that the prompt will be associate with.
|
||||
* @param prefList a list of [Preference]s to toggle.
|
||||
*/
|
||||
fun setBiometricPrompt(view: View, prefList: List<Int>) {
|
||||
biometricPromptFeature.set(
|
||||
feature = BiometricPromptFeature(
|
||||
context = requireContext(),
|
||||
fragment = this,
|
||||
onAuthFailure = {
|
||||
togglePrefsEnabled(prefList, true)
|
||||
},
|
||||
onAuthSuccess = ::navigateOnSuccess
|
||||
),
|
||||
owner = this,
|
||||
view = view
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use [BiometricPromptFeature] or [KeyguardManager] to confirm device security.
|
||||
*
|
||||
* @param prefList a list of [Preference]s to disable while authentication is happening.
|
||||
*/
|
||||
fun verifyCredentialsOrShowSetupWarning(context: Context, prefList: List<Int>) {
|
||||
// Use the BiometricPrompt if available
|
||||
if (BiometricPromptFeature.canUseFeature(context)) {
|
||||
togglePrefsEnabled(prefList, false)
|
||||
biometricPromptFeature.get()?.requestAuthentication(unlockMessage())
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback to prompting for password with the KeyguardManager
|
||||
val manager = context.getSystemService<KeyguardManager>()
|
||||
if (manager?.isKeyguardSecure == true) {
|
||||
showPinVerification(manager)
|
||||
} else {
|
||||
// Warn that the device has not been secured
|
||||
if (context.settings().shouldShowSecurityPinWarning) {
|
||||
showPinDialogWarning(context)
|
||||
} else {
|
||||
navigateOnSuccess()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == PIN_REQUEST && resultCode == RESULT_OK) {
|
||||
navigateOnSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PIN_REQUEST = 303
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ import androidx.navigation.fragment.navArgs
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.SecureFragment
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.redirectToReAuth
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardEditorController
|
||||
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardEditorInteractor
|
||||
@ -28,6 +29,8 @@ class CreditCardEditorFragment : SecureFragment(R.layout.fragment_credit_card_ed
|
||||
|
||||
private lateinit var creditCardEditorState: CreditCardEditorState
|
||||
private lateinit var creditCardEditorView: CreditCardEditorView
|
||||
private lateinit var menu: Menu
|
||||
|
||||
private val args by navArgs<CreditCardEditorFragmentArgs>()
|
||||
|
||||
/**
|
||||
@ -64,8 +67,25 @@ class CreditCardEditorFragment : SecureFragment(R.layout.fragment_credit_card_ed
|
||||
creditCardEditorView.bind(creditCardEditorState)
|
||||
}
|
||||
|
||||
/**
|
||||
* Close any open dialogs or menus and reauthenticate if the fragment is paused and
|
||||
* the user is not navigating to [CreditCardsManagementFragment].
|
||||
*/
|
||||
override fun onPause() {
|
||||
menu.close()
|
||||
|
||||
redirectToReAuth(
|
||||
listOf(R.id.creditCardsManagementFragment),
|
||||
findNavController().currentDestination?.id,
|
||||
R.id.creditCardEditorFragment
|
||||
)
|
||||
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.credit_card_editor, menu)
|
||||
this.menu = menu
|
||||
|
||||
menu.findItem(R.id.delete_credit_card_button).isVisible = isEditing
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.SecureFragment
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.redirectToReAuth
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.settings.creditcards.controller.DefaultCreditCardsManagementController
|
||||
import org.mozilla.fenix.settings.creditcards.interactor.CreditCardsManagementInteractor
|
||||
@ -75,6 +76,20 @@ class CreditCardsManagementFragment : SecureFragment() {
|
||||
showToolbar(getString(R.string.credit_cards_saved_cards))
|
||||
}
|
||||
|
||||
/**
|
||||
* When the fragment is paused, navigate back to the settings page to reauthenticate.
|
||||
*/
|
||||
override fun onPause() {
|
||||
// Don't redirect if the user is navigating to the credit card editor fragment.
|
||||
redirectToReAuth(
|
||||
listOf(R.id.creditCardEditorFragment),
|
||||
findNavController().currentDestination?.id,
|
||||
R.id.creditCardsManagementFragment
|
||||
)
|
||||
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all the credit cards from the autofill storage and updates the
|
||||
* [CreditCardsFragmentStore] with the list of credit cards.
|
||||
|
@ -4,41 +4,76 @@
|
||||
|
||||
package org.mozilla.fenix.settings.creditcards
|
||||
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreference
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.lib.state.ext.consumeFrom
|
||||
import mozilla.components.service.fxa.SyncEngine
|
||||
import org.mozilla.fenix.NavGraphDirections
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
||||
import org.mozilla.fenix.ext.secure
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.settings.SharedPreferenceUpdater
|
||||
import org.mozilla.fenix.settings.SyncPreferenceView
|
||||
import org.mozilla.fenix.settings.biometric.BiometricPromptFeature
|
||||
import org.mozilla.fenix.settings.biometric.BiometricPromptPreferenceFragment
|
||||
import org.mozilla.fenix.settings.requirePreference
|
||||
|
||||
/**
|
||||
* "Credit cards" settings fragment displays a list of settings related to autofilling, adding and
|
||||
* syncing credit cards.
|
||||
* syncing credit cards. Authentication for saved credit cards uses [BiometricPromptFeature]
|
||||
* or [KeyguardManager].
|
||||
*/
|
||||
class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
@SuppressWarnings("TooManyFunctions")
|
||||
class CreditCardsSettingFragment : BiometricPromptPreferenceFragment() {
|
||||
|
||||
private lateinit var creditCardsStore: CreditCardsFragmentStore
|
||||
private var isCreditCardsListLoaded: Boolean = false
|
||||
|
||||
/**
|
||||
* List of preferences to be enabled or disabled during authentication.
|
||||
*/
|
||||
private val creditCardPreferences: List<Int> = listOf(
|
||||
R.string.pref_key_credit_cards_save_and_autofill_cards,
|
||||
R.string.pref_key_credit_cards_sync_cards_across_devices,
|
||||
R.string.pref_key_credit_cards_manage_cards
|
||||
)
|
||||
|
||||
override fun unlockMessage() = getString(R.string.credit_cards_biometric_prompt_message)
|
||||
|
||||
override fun navigateOnSuccess() {
|
||||
runIfFragmentIsAttached {
|
||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
// Workaround for likely biometric library bug
|
||||
// https://github.com/mozilla-mobile/fenix/issues/8438
|
||||
delay(SHORT_DELAY_MS)
|
||||
navigateToCreditCardManagementFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
creditCardsStore = StoreProvider.get(this) {
|
||||
@ -71,6 +106,8 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
consumeFrom(creditCardsStore) { state ->
|
||||
updateCardManagementPreference(state.creditCards.isNotEmpty(), findNavController())
|
||||
}
|
||||
|
||||
setBiometricPrompt(view, creditCardPreferences)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
@ -93,16 +130,18 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
loggedInTitle = requireContext()
|
||||
.getString(R.string.preferences_credit_cards_sync_cards),
|
||||
onSignInToSyncClicked = {
|
||||
val directions =
|
||||
CreditCardsSettingFragmentDirections.actionCreditCardsSettingFragmentToTurnOnSyncFragment()
|
||||
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||
findNavController().navigateBlockingForAsyncNavGraph(
|
||||
NavGraphDirections.actionGlobalTurnOnSync()
|
||||
)
|
||||
},
|
||||
onReconnectClicked = {
|
||||
val directions =
|
||||
findNavController().navigateBlockingForAsyncNavGraph(
|
||||
CreditCardsSettingFragmentDirections.actionGlobalAccountProblemFragment()
|
||||
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
togglePrefsEnabled(creditCardPreferences, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,14 +155,6 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
val manageSavedCardsPreference =
|
||||
requirePreference<Preference>(R.string.pref_key_credit_cards_manage_cards)
|
||||
|
||||
val directions = if (hasCreditCards) {
|
||||
CreditCardsSettingFragmentDirections
|
||||
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
|
||||
} else {
|
||||
CreditCardsSettingFragmentDirections
|
||||
.actionCreditCardsSettingFragmentToCreditCardEditorFragment()
|
||||
}
|
||||
|
||||
if (hasCreditCards) {
|
||||
manageSavedCardsPreference.icon = null
|
||||
manageSavedCardsPreference.title =
|
||||
@ -135,7 +166,14 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
manageSavedCardsPreference.setOnPreferenceClickListener {
|
||||
navController.navigateBlockingForAsyncNavGraph(directions)
|
||||
if (hasCreditCards) {
|
||||
verifyCredentialsOrShowSetupWarning(requireContext(), creditCardPreferences)
|
||||
} else {
|
||||
navController.navigateBlockingForAsyncNavGraph(
|
||||
CreditCardsSettingFragmentDirections
|
||||
.actionCreditCardsSettingFragmentToCreditCardEditorFragment()
|
||||
)
|
||||
}
|
||||
super.onPreferenceTreeClick(it)
|
||||
}
|
||||
}
|
||||
@ -158,4 +196,54 @@ class CreditCardsSettingFragment : PreferenceFragmentCompat() {
|
||||
|
||||
isCreditCardsListLoaded = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a dialog warning to set up a pin/password when the device is not secured. This is
|
||||
* only used when BiometricPrompt is unavailable on the device.
|
||||
*/
|
||||
override fun showPinDialogWarning(context: Context) {
|
||||
AlertDialog.Builder(context).apply {
|
||||
setTitle(getString(R.string.credit_cards_warning_dialog_title))
|
||||
setMessage(getString(R.string.credit_cards_warning_dialog_message))
|
||||
|
||||
setNegativeButton(getString(R.string.credit_cards_warning_dialog_later)) { _: DialogInterface, _ ->
|
||||
navigateToCreditCardManagementFragment()
|
||||
}
|
||||
|
||||
setPositiveButton(getString(R.string.credit_cards_warning_dialog_set_up_now)) { it: DialogInterface, _ ->
|
||||
it.dismiss()
|
||||
val intent = Intent(Settings.ACTION_SECURITY_SETTINGS)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
create()
|
||||
}.show().secure(activity)
|
||||
context.settings().incrementSecureWarningCount()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a prompt to verify the device's pin/password and start activity based on the result.
|
||||
* This is only used when BiometricPrompt is unavailable on the device.
|
||||
*
|
||||
* @param manager The device [KeyguardManager]
|
||||
*/
|
||||
@Suppress("Deprecation")
|
||||
override fun showPinVerification(manager: KeyguardManager) {
|
||||
val intent = manager.createConfirmDeviceCredentialIntent(
|
||||
getString(R.string.credit_cards_biometric_prompt_message_pin),
|
||||
getString(R.string.credit_cards_biometric_prompt_message)
|
||||
)
|
||||
startActivityForResult(intent, BiometricPromptPreferenceFragment.PIN_REQUEST)
|
||||
}
|
||||
|
||||
private fun navigateToCreditCardManagementFragment() {
|
||||
val directions =
|
||||
CreditCardsSettingFragmentDirections
|
||||
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
|
||||
findNavController().navigateBlockingForAsyncNavGraph(directions)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SHORT_DELAY_MS = 100L
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,8 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login) {
|
||||
override fun onPause() {
|
||||
redirectToReAuth(
|
||||
listOf(R.id.loginDetailFragment),
|
||||
findNavController().currentDestination?.id
|
||||
findNavController().currentDestination?.id,
|
||||
R.id.editLoginFragment
|
||||
)
|
||||
super.onPause()
|
||||
}
|
||||
|
@ -131,7 +131,8 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
|
||||
menu.close()
|
||||
redirectToReAuth(
|
||||
listOf(R.id.editLoginFragment, R.id.savedLoginsFragment),
|
||||
findNavController().currentDestination?.id
|
||||
findNavController().currentDestination?.id,
|
||||
R.id.loginDetailFragment
|
||||
)
|
||||
super.onPause()
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
create()
|
||||
}.show().secure(activity)
|
||||
context.settings().incrementShowLoginsSecureWarningCount()
|
||||
context.settings().incrementSecureWarningCount()
|
||||
}
|
||||
|
||||
@Suppress("Deprecation") // This is only used when BiometricPrompt is unavailable
|
||||
|
@ -148,7 +148,11 @@ class SavedLoginsFragment : Fragment() {
|
||||
sortLoginsMenuRoot.setOnClickListener(null)
|
||||
setHasOptionsMenu(false)
|
||||
|
||||
redirectToReAuth(listOf(R.id.loginDetailFragment), findNavController().currentDestination?.id)
|
||||
redirectToReAuth(
|
||||
listOf(R.id.loginDetailFragment),
|
||||
findNavController().currentDestination?.id,
|
||||
R.id.savedLoginsFragment
|
||||
)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
||||
get() = loginsSecureWarningSyncCount.underMaxCount()
|
||||
|
||||
val shouldShowSecurityPinWarning: Boolean
|
||||
get() = loginsSecureWarningCount.underMaxCount()
|
||||
get() = secureWarningCount.underMaxCount()
|
||||
|
||||
var shouldShowPrivacyPopWindow by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_privacy_pop_window),
|
||||
@ -652,12 +652,12 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
||||
)
|
||||
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
internal val loginsSecureWarningCount = counterPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_logins_secure_warning),
|
||||
internal val secureWarningCount = counterPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_secure_warning),
|
||||
maxCount = 1
|
||||
)
|
||||
|
||||
fun incrementShowLoginsSecureWarningCount() = loginsSecureWarningCount.increment()
|
||||
fun incrementSecureWarningCount() = secureWarningCount.increment()
|
||||
|
||||
fun incrementShowLoginsSecureWarningSyncCount() = loginsSecureWarningSyncCount.increment()
|
||||
|
||||
|
@ -1043,13 +1043,6 @@
|
||||
android:id="@+id/creditCardsSettingFragment"
|
||||
android:name="org.mozilla.fenix.settings.creditcards.CreditCardsSettingFragment"
|
||||
android:label="@string/preferences_credit_cards">
|
||||
<action
|
||||
android:id="@+id/action_creditCardsSettingFragment_to_turnOnSyncFragment"
|
||||
app:destination="@id/turnOnSyncFragment"
|
||||
app:enterAnim="@anim/slide_in_right"
|
||||
app:exitAnim="@anim/slide_out_left"
|
||||
app:popEnterAnim="@anim/slide_in_left"
|
||||
app:popExitAnim="@anim/slide_out_right" />
|
||||
<action
|
||||
android:id="@+id/action_creditCardsSettingFragment_to_creditCardEditorFragment"
|
||||
app:destination="@id/creditCardEditorFragment"
|
||||
|
@ -171,7 +171,7 @@
|
||||
<string name="pref_key_saved_logins" translatable="false">pref_key_saved_logins</string>
|
||||
<string name="pref_key_password_sync_logins" translatable="false">pref_key_password_sync_logins</string>
|
||||
<string name="pref_key_logins_secure_warning_sync" translatable="false">pref_key_logins_secure_warning_sync</string>
|
||||
<string name="pref_key_logins_secure_warning" translatable="false">pref_key_logins_secure_warning</string>
|
||||
<string name="pref_key_secure_warning" translatable="false">pref_key_secure_warning</string>
|
||||
|
||||
<!-- Credit Cards Settings -->
|
||||
<!-- Key for the "Credit cards" preference in the "Settings" fragment -->
|
||||
|
@ -1555,6 +1555,18 @@
|
||||
<string name="credit_cards_saved_cards">Saved cards</string>
|
||||
<!-- Error message for credit card number validation -->
|
||||
<string name="credit_cards_number_validation_error_message">Please enter a valid credit card number</string>
|
||||
<!-- Message displayed in biometric prompt displayed for authentication before allowing users to view their saved credit cards -->
|
||||
<string name="credit_cards_biometric_prompt_message">Unlock to view your saved cards</string>
|
||||
<!-- Title of warning dialog if users have no device authentication set up -->
|
||||
<string name="credit_cards_warning_dialog_title">Secure your credit cards</string>
|
||||
<!-- Message of warning dialog if users have no device authentication set up -->
|
||||
<string name="credit_cards_warning_dialog_message">Set up a device lock pattern, PIN, or password to protect your saved credit cards from being accessed if someone else has your device.</string>
|
||||
<!-- Positive button to send users to set up a pin of warning dialog if users have no device authentication set up -->
|
||||
<string name="credit_cards_warning_dialog_set_up_now">Set up now</string>
|
||||
<!-- Negative button to ignore warning dialog if users have no device authentication set up -->
|
||||
<string name="credit_cards_warning_dialog_later">Later</string>
|
||||
<!-- Title of PIN verification dialog to direct users to re-enter their device credentials to access their credit cards -->
|
||||
<string name="credit_cards_biometric_prompt_message_pin">Unlock your device</string>
|
||||
|
||||
<!-- Title of the Add search engine screen -->
|
||||
<string name="search_engine_add_custom_search_engine_title">Add search engine</string>
|
||||
|
@ -53,10 +53,6 @@ class CreditCardsSettingFragmentTest {
|
||||
creditCardsSettingFragment.getPreferenceKey(R.string.pref_key_credit_cards_manage_cards)
|
||||
)
|
||||
|
||||
val directions =
|
||||
CreditCardsSettingFragmentDirections
|
||||
.actionCreditCardsSettingFragmentToCreditCardsManagementFragment()
|
||||
|
||||
val creditCards: List<CreditCard> = listOf(mockk(), mockk())
|
||||
|
||||
val creditCardsState = CreditCardsListState(creditCards = creditCards)
|
||||
@ -69,10 +65,6 @@ class CreditCardsSettingFragmentTest {
|
||||
|
||||
assertNull(manageCardsPreference?.icon)
|
||||
assertEquals(preferenceTitle, manageCardsPreference?.title)
|
||||
|
||||
manageCardsPreference?.performClick()
|
||||
|
||||
verify { navController.navigateBlockingForAsyncNavGraph(directions) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -183,13 +183,13 @@ class SettingsTest {
|
||||
fun showLoginsDialogWarning() {
|
||||
// When just created
|
||||
// Then
|
||||
assertEquals(0, settings.loginsSecureWarningCount.value)
|
||||
assertEquals(0, settings.secureWarningCount.value)
|
||||
|
||||
// When
|
||||
settings.incrementShowLoginsSecureWarningCount()
|
||||
settings.incrementSecureWarningCount()
|
||||
|
||||
// Then
|
||||
assertEquals(1, settings.loginsSecureWarningCount.value)
|
||||
assertEquals(1, settings.secureWarningCount.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -199,7 +199,7 @@ class SettingsTest {
|
||||
assertTrue(settings.shouldShowSecurityPinWarning)
|
||||
|
||||
// When
|
||||
settings.incrementShowLoginsSecureWarningCount()
|
||||
settings.incrementSecureWarningCount()
|
||||
|
||||
// Then
|
||||
assertFalse(settings.shouldShowSecurityPinWarning)
|
||||
|
Loading…
Reference in New Issue
Block a user