Loading mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/annotation/FlexibleWindowLightDarkPreview.kt +4 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,8 @@ import mozilla.components.compose.base.theme.layout.AcornWindowSize device = Devices.PIXEL_TABLET, uiMode = Configuration.UI_MODE_NIGHT_YES, ) @Preview( name = "Large text", fontScale = 2.5f, ) annotation class FlexibleWindowLightDarkPreview mobile/android/fenix/app/src/beta/res/drawable/tor_browser_app_icon.png 0 → 100644 +7.26 KiB Loading image diff... mobile/android/fenix/app/src/main/java/org/mozilla/fenix/pbmlock/PrivateBrowsingLockFeature.kt +2 −1 Original line number Diff line number Diff line Loading @@ -347,7 +347,8 @@ fun Fragment.verifyUser( onVerified: (() -> Unit)? = null, ) { biometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = R.string.pbm_authentication_unlock_private_tabs, titleRes = R.string.tor_authentication_unlock_private_tabs, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> fallbackVerification.launch(intent) }, onAuthSuccess = { handleVerificationSuccess(requireContext(), onVerified) }, Loading mobile/android/fenix/app/src/main/java/org/mozilla/fenix/pbmlock/UnlockPrivateTabsFragment.kt +4 −4 Original line number Diff line number Diff line Loading @@ -73,8 +73,7 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse UnlockPrivateTabsScreen( onUnlockClicked = { requestPrompt() }, onLeaveClicked = { PrivateBrowsingLocked.seeOtherTabsClicked.record() closeFragment() requireActivity().moveTaskToBack(true) }, showNegativeButton = !isCustomPrivateTab, ) Loading @@ -84,7 +83,7 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse } override fun onBackPressed(): Boolean { closeFragment() requireActivity().moveTaskToBack(true) return true } Loading @@ -108,7 +107,8 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse private fun requestPrompt() { DefaultBiometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = R.string.pbm_authentication_unlock_private_tabs, titleRes = R.string.tor_authentication_unlock_private_tabs, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> startForResult.launch(intent) }, onAuthSuccess = ::onAuthSuccess, Loading mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/TabsSettingsFragment.kt +96 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,16 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.utils.view.addToRadioGroup import android.content.Intent import android.provider.Settings import androidx.activity.result.ActivityResultLauncher import androidx.biometric.BiometricManager import androidx.preference.Preference import org.mozilla.fenix.ext.registerForActivityResult import org.mozilla.fenix.settings.biometric.DefaultBiometricUtils import org.mozilla.fenix.settings.biometric.ext.isAuthenticatorAvailable import org.mozilla.fenix.settings.biometric.ext.isHardwareAvailable /** * Lets the user customize auto closing tabs. */ Loading @@ -43,6 +53,31 @@ class TabsSettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragm findPreference<PreferenceCategory>(getString(R.string.pref_key_inactive_tabs_category))?.apply { isVisible = !context.settings().shouldDisableNormalMode } startForResult = registerForActivityResult( onFailure = { }, onSuccess = { onSuccessfulAuthenticationUsingFallbackPrompt() }, ) } private lateinit var startForResult: ActivityResultLauncher<Intent> private fun onSuccessfulAuthenticationUsingFallbackPrompt() { val newValue = !requireContext().settings().privateBrowsingLockedFeatureEnabled requireContext().settings().privateBrowsingLockedFeatureEnabled = newValue // Update switch state manually requirePreference<SwitchPreferenceCompat>(R.string.pref_key_private_browsing_locked_enabled).apply { isChecked = !isChecked } } private fun onSuccessfulAuthenticationUsingPrimaryPrompt( pbmLockEnabled: Boolean, preference: Preference, ) { requireContext().settings().privateBrowsingLockedFeatureEnabled = pbmLockEnabled // Update switch state manually (preference as? SwitchPreferenceCompat)?.isChecked = pbmLockEnabled } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Loading Loading @@ -92,6 +127,67 @@ class TabsSettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragm radioOneMonth.onClickListener(::enableInactiveTabsSetting) setupRadioGroups() /** * Changes in this file for "tor-browser#44027 Update PBM lockscreen" were copied from * [PrivateBrowsingFragment] and changed to make sense and work for TBA such as removing * any use of nimbus/glean that was being used for business logic which was making the * release build variant not work. We should check [PrivateBrowsingFragment] for updates * when we rebase * */ setUpHideBrowsingSessionPreference() } private fun setUpHideBrowsingSessionPreference() { val biometricManager = BiometricManager.from(requireContext()) val deviceCapable = biometricManager.isHardwareAvailable() val userHasEnabledCapability = biometricManager.isAuthenticatorAvailable() requirePreference<SwitchPreferenceCompat>(R.string.pref_key_private_browsing_locked_enabled).apply { title = getString(R.string.preferences_tor_lock_screen_title, getString(R.string.app_name)) summary = getString(R.string.preferences_tor_lock_screen_summary, getString(R.string.app_name)) isChecked = context.settings().privateBrowsingLockedFeatureEnabled && biometricManager.isAuthenticatorAvailable() isVisible = deviceCapable isEnabled = userHasEnabledCapability setOnPreferenceChangeListener { preference, newValue -> val pbmLockEnabled = newValue as? Boolean ?: return@setOnPreferenceChangeListener false val titleRes = if (pbmLockEnabled) { R.string.tor_authentication_enable_lock } else { R.string.tor_authentication_disable_lock } DefaultBiometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = titleRes, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> startForResult.launch(intent) }, onAuthSuccess = { onSuccessfulAuthenticationUsingPrimaryPrompt( pbmLockEnabled = pbmLockEnabled, preference = preference, ) }, onAuthFailure = { }, ) // Cancel toggle change until biometric is successful false } } requirePreference<Preference>(R.string.pref_key_private_browsing_lock_device_feature_enabled).apply { title = getString(R.string.tor_authentication_lock_device_feature_disabled, getString(R.string.app_name)) isVisible = deviceCapable && !userHasEnabledCapability setOnPreferenceClickListener { context.startActivity(Intent(Settings.ACTION_SECURITY_SETTINGS)) true } } } private fun setupRadioGroups() { Loading Loading
mobile/android/android-components/components/compose/base/src/main/java/mozilla/components/compose/base/annotation/FlexibleWindowLightDarkPreview.kt +4 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,8 @@ import mozilla.components.compose.base.theme.layout.AcornWindowSize device = Devices.PIXEL_TABLET, uiMode = Configuration.UI_MODE_NIGHT_YES, ) @Preview( name = "Large text", fontScale = 2.5f, ) annotation class FlexibleWindowLightDarkPreview
mobile/android/fenix/app/src/beta/res/drawable/tor_browser_app_icon.png 0 → 100644 +7.26 KiB Loading image diff...
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/pbmlock/PrivateBrowsingLockFeature.kt +2 −1 Original line number Diff line number Diff line Loading @@ -347,7 +347,8 @@ fun Fragment.verifyUser( onVerified: (() -> Unit)? = null, ) { biometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = R.string.pbm_authentication_unlock_private_tabs, titleRes = R.string.tor_authentication_unlock_private_tabs, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> fallbackVerification.launch(intent) }, onAuthSuccess = { handleVerificationSuccess(requireContext(), onVerified) }, Loading
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/pbmlock/UnlockPrivateTabsFragment.kt +4 −4 Original line number Diff line number Diff line Loading @@ -73,8 +73,7 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse UnlockPrivateTabsScreen( onUnlockClicked = { requestPrompt() }, onLeaveClicked = { PrivateBrowsingLocked.seeOtherTabsClicked.record() closeFragment() requireActivity().moveTaskToBack(true) }, showNegativeButton = !isCustomPrivateTab, ) Loading @@ -84,7 +83,7 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse } override fun onBackPressed(): Boolean { closeFragment() requireActivity().moveTaskToBack(true) return true } Loading @@ -108,7 +107,8 @@ class UnlockPrivateTabsFragment : Fragment(), UserInteractionHandler, SystemInse private fun requestPrompt() { DefaultBiometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = R.string.pbm_authentication_unlock_private_tabs, titleRes = R.string.tor_authentication_unlock_private_tabs, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> startForResult.launch(intent) }, onAuthSuccess = ::onAuthSuccess, Loading
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/TabsSettingsFragment.kt +96 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,16 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.utils.view.addToRadioGroup import android.content.Intent import android.provider.Settings import androidx.activity.result.ActivityResultLauncher import androidx.biometric.BiometricManager import androidx.preference.Preference import org.mozilla.fenix.ext.registerForActivityResult import org.mozilla.fenix.settings.biometric.DefaultBiometricUtils import org.mozilla.fenix.settings.biometric.ext.isAuthenticatorAvailable import org.mozilla.fenix.settings.biometric.ext.isHardwareAvailable /** * Lets the user customize auto closing tabs. */ Loading @@ -43,6 +53,31 @@ class TabsSettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragm findPreference<PreferenceCategory>(getString(R.string.pref_key_inactive_tabs_category))?.apply { isVisible = !context.settings().shouldDisableNormalMode } startForResult = registerForActivityResult( onFailure = { }, onSuccess = { onSuccessfulAuthenticationUsingFallbackPrompt() }, ) } private lateinit var startForResult: ActivityResultLauncher<Intent> private fun onSuccessfulAuthenticationUsingFallbackPrompt() { val newValue = !requireContext().settings().privateBrowsingLockedFeatureEnabled requireContext().settings().privateBrowsingLockedFeatureEnabled = newValue // Update switch state manually requirePreference<SwitchPreferenceCompat>(R.string.pref_key_private_browsing_locked_enabled).apply { isChecked = !isChecked } } private fun onSuccessfulAuthenticationUsingPrimaryPrompt( pbmLockEnabled: Boolean, preference: Preference, ) { requireContext().settings().privateBrowsingLockedFeatureEnabled = pbmLockEnabled // Update switch state manually (preference as? SwitchPreferenceCompat)?.isChecked = pbmLockEnabled } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { Loading Loading @@ -92,6 +127,67 @@ class TabsSettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragm radioOneMonth.onClickListener(::enableInactiveTabsSetting) setupRadioGroups() /** * Changes in this file for "tor-browser#44027 Update PBM lockscreen" were copied from * [PrivateBrowsingFragment] and changed to make sense and work for TBA such as removing * any use of nimbus/glean that was being used for business logic which was making the * release build variant not work. We should check [PrivateBrowsingFragment] for updates * when we rebase * */ setUpHideBrowsingSessionPreference() } private fun setUpHideBrowsingSessionPreference() { val biometricManager = BiometricManager.from(requireContext()) val deviceCapable = biometricManager.isHardwareAvailable() val userHasEnabledCapability = biometricManager.isAuthenticatorAvailable() requirePreference<SwitchPreferenceCompat>(R.string.pref_key_private_browsing_locked_enabled).apply { title = getString(R.string.preferences_tor_lock_screen_title, getString(R.string.app_name)) summary = getString(R.string.preferences_tor_lock_screen_summary, getString(R.string.app_name)) isChecked = context.settings().privateBrowsingLockedFeatureEnabled && biometricManager.isAuthenticatorAvailable() isVisible = deviceCapable isEnabled = userHasEnabledCapability setOnPreferenceChangeListener { preference, newValue -> val pbmLockEnabled = newValue as? Boolean ?: return@setOnPreferenceChangeListener false val titleRes = if (pbmLockEnabled) { R.string.tor_authentication_enable_lock } else { R.string.tor_authentication_disable_lock } DefaultBiometricUtils.bindBiometricsCredentialsPromptOrShowWarning( titleRes = titleRes, titleRes2 = R.string.app_name, view = requireView(), onShowPinVerification = { intent -> startForResult.launch(intent) }, onAuthSuccess = { onSuccessfulAuthenticationUsingPrimaryPrompt( pbmLockEnabled = pbmLockEnabled, preference = preference, ) }, onAuthFailure = { }, ) // Cancel toggle change until biometric is successful false } } requirePreference<Preference>(R.string.pref_key_private_browsing_lock_device_feature_enabled).apply { title = getString(R.string.tor_authentication_lock_device_feature_disabled, getString(R.string.app_name)) isVisible = deviceCapable && !userHasEnabledCapability setOnPreferenceClickListener { context.startActivity(Intent(Settings.ACTION_SECURITY_SETTINGS)) true } } } private fun setupRadioGroups() { Loading