diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 66473d4d0c15..5adf00133059 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -299,9 +299,10 @@ class HomeFragment : Fragment(), SystemInsetsPaddedFragment { registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> with(requireContext()) { maybeNavigateToSystemSetToDefaultAction( - result.resultCode, - settings(), - dateTimeProvider, + resultCode = result.resultCode, + settings = settings(), + dateTimeProvider = dateTimeProvider, + isChecklistTask = true, ) { navigateToDefaultBrowserAppsSettings(BuildManufacturerChecker()) } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/SetToDefaultPromptRequest.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/SetToDefaultPromptRequest.kt index 5206df2679f4..5d6c00a4b493 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/SetToDefaultPromptRequest.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/SetToDefaultPromptRequest.kt @@ -38,6 +38,8 @@ private const val MINIMUM_INTERACTION_DURATION_MS = 300 * @param settings The [Settings] instance used to access and reset the prompt timestamp. * @param dateTimeProvider A provider used to retrieve the current system time, allowing for consistent * time calculations and easier unit testing. + * @param isChecklistTask A boolean flag indicating whether it's triggered from a checklist flow. + * When true and the browser is already set as default, we avoid redirecting the user to device settings. * @param navigationAction A lambda function that executes the navigation to the system's default * app settings screen. */ @@ -45,14 +47,18 @@ fun maybeNavigateToSystemSetToDefaultAction( resultCode: Int, settings: Settings, dateTimeProvider: DateTimeProvider, + isChecklistTask: Boolean = false, navigationAction: () -> Unit, ) { - if (shouldNavigateToAppSettingsLauncher( - resultCode, - settings.setToDefaultPromptRequested, - dateTimeProvider, - ) - ) { + val promptBlockedBySystem = wasPromptBlockedBySystem( + resultCode, + settings.setToDefaultPromptRequested, + dateTimeProvider, + ) + val isEligibleForAppSettingsNavigation = settings.isDefaultBrowser && !isChecklistTask + val shouldNavigateToAppSettingsLauncher = promptBlockedBySystem || isEligibleForAppSettingsNavigation + + if (shouldNavigateToAppSettingsLauncher) { navigationAction() } @@ -110,10 +116,9 @@ fun maybeRequestDefaultBrowserPrompt( * displayed, used to calculate the interaction duration. * @param dateTimeProvider A provider used to retrieve the current system time, allowing for consistent * time calculations and easier unit testing. - * @return True if the prompt was likely blocked by the system (detected by a very short interaction time) - * or if the user explicitly accepted the prompt, indicating a need for further configuration in Settings. + * @return True if the prompt was likely blocked by system. */ -private fun shouldNavigateToAppSettingsLauncher( +private fun wasPromptBlockedBySystem( resultCode: Int, promptRequestTimestamp: Long, dateTimeProvider: DateTimeProvider, diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 6200d8376b82..b9c948180af6 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -6,12 +6,15 @@ package org.mozilla.fenix.settings import android.annotation.SuppressLint import android.content.DialogInterface +import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.view.LayoutInflater import android.view.View import android.widget.Toast +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.VisibleForTesting import androidx.core.app.NotificationManagerCompat import androidx.core.content.edit @@ -41,6 +44,10 @@ import mozilla.components.feature.addons.ui.AddonFilePicker import mozilla.components.service.fxrelay.eligibility.Eligible import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.view.showKeyboard +import mozilla.components.support.utils.BuildManufacturerChecker +import mozilla.components.support.utils.DateTimeProvider +import mozilla.components.support.utils.DefaultDateTimeProvider +import mozilla.components.support.utils.ext.navigateToDefaultBrowserAppsSettings import mozilla.components.ui.widgets.withCenterAlignedButtons import mozilla.telemetry.glean.private.NoExtras import org.mozilla.fenix.Config @@ -51,6 +58,7 @@ import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.SettingsSearch import org.mozilla.fenix.GleanMetrics.TrackingProtection import org.mozilla.fenix.GleanMetrics.Translations +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint @@ -61,11 +69,12 @@ import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.navigateToNotificationsSettings import org.mozilla.fenix.ext.openInNewTab -import org.mozilla.fenix.ext.openSetDefaultBrowserOption import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbarWithIconButton +import org.mozilla.fenix.home.maybeNavigateToSystemSetToDefaultAction +import org.mozilla.fenix.home.maybeRequestDefaultBrowserPrompt import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.perf.ProfilerViewModel import org.mozilla.fenix.perf.ProfilerViewModelFactory @@ -73,6 +82,7 @@ import org.mozilla.fenix.settings.account.AccountUiView import org.mozilla.fenix.snackbar.FenixSnackbarDelegate import org.mozilla.fenix.snackbar.SnackbarBinding import org.mozilla.fenix.utils.Settings +import java.lang.ref.WeakReference import kotlin.system.exitProcess import mozilla.components.ui.icons.R as iconsR import org.mozilla.fenix.GleanMetrics.Settings as SettingsMetrics @@ -91,6 +101,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragment ProfilerViewModelFactory(requireActivity().application) } private val snackbarBinding = ViewBoundFeatureWrapper() + private val dateTimeProvider: DateTimeProvider by lazy { DefaultDateTimeProvider() } @VisibleForTesting internal val accountObserver = object : AccountObserver { @@ -643,6 +654,15 @@ class SettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragment setupEmailMaskPreference(settings, requireComponents) } + private val setToDefaultPromptRequestLauncher: ActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + with(requireContext()) { + maybeNavigateToSystemSetToDefaultAction(result.resultCode, settings(), dateTimeProvider) { + navigateToDefaultBrowserAppsSettings(BuildManufacturerChecker()) + } + } + } + /** * For >=Q -> Use new RoleManager API to show in-app browser switching dialog. * For =N -> Navigate user to Android Default Apps Settings. @@ -650,7 +670,10 @@ class SettingsFragment : PreferenceFragmentCompat(), SystemInsetsPaddedFragment */ private fun getClickListenerForMakeDefaultBrowser(): Preference.OnPreferenceClickListener { return Preference.OnPreferenceClickListener { - activity?.openSetDefaultBrowserOption() + maybeRequestDefaultBrowserPrompt( + WeakReference((requireActivity() as? HomeActivity)), + setToDefaultPromptRequestLauncher, + ) true } }