diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index ed9b83c58..5c6bc0492 100644
--- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -40,7 +40,7 @@ import org.mozilla.fenix.ext.navigateSafe
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.resetPoliciesAfter
import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.shortcut.FirstTimePwaObserver
+import org.mozilla.fenix.shortcut.PwaOnboardingObserver
import org.mozilla.fenix.trackingprotection.TrackingProtectionOverlay
/**
@@ -156,9 +156,9 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
session?.register(toolbarSessionObserver, viewLifecycleOwner, autoPause = true)
- if (settings.shouldShowFirstTimePwaFragment) {
+ if (!settings.userKnowsAboutPwas) {
session?.register(
- FirstTimePwaObserver(
+ PwaOnboardingObserver(
navController = findNavController(),
settings = settings,
webAppUseCases = context.components.useCases.webAppUseCases
diff --git a/app/src/main/java/org/mozilla/fenix/perf/Performance.kt b/app/src/main/java/org/mozilla/fenix/perf/Performance.kt
index 4b0a73b22..f1eb26ffb 100644
--- a/app/src/main/java/org/mozilla/fenix/perf/Performance.kt
+++ b/app/src/main/java/org/mozilla/fenix/perf/Performance.kt
@@ -74,6 +74,6 @@ object Performance {
* Disables the first time PWA popup.
*/
private fun disableFirstTimePWAPopup(context: Context) {
- Settings.getInstance(context).userKnowsAboutPWAs = true
+ Settings.getInstance(context).userKnowsAboutPwas = true
}
}
diff --git a/app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaFragment.kt b/app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingDialogFragment.kt
similarity index 88%
rename from app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaFragment.kt
rename to app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingDialogFragment.kt
index c42c2842f..43b9099fc 100644
--- a/app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingDialogFragment.kt
@@ -16,9 +16,9 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.ext.requireComponents
/**
- * Dialog displayed the first time the user navigates to an installable web app.
+ * Dialog displayed the third time the user navigates to an installable web app.
*/
-class FirstTimePwaFragment : DialogFragment() {
+class PwaOnboardingDialogFragment : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.CreateShortcutDialogStyle)
@@ -28,7 +28,7 @@ class FirstTimePwaFragment : DialogFragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? = inflater.inflate(R.layout.fragment_pwa_first_time, container, false)
+ ): View? = inflater.inflate(R.layout.fragment_pwa_onboarding, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
diff --git a/app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaObserver.kt b/app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingObserver.kt
similarity index 59%
rename from app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaObserver.kt
rename to app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingObserver.kt
index 2c19810d7..5e312df86 100644
--- a/app/src/main/java/org/mozilla/fenix/shortcut/FirstTimePwaObserver.kt
+++ b/app/src/main/java/org/mozilla/fenix/shortcut/PwaOnboardingObserver.kt
@@ -14,20 +14,23 @@ import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.utils.Settings
/**
- * Displays the [FirstTimePwaFragment] info dialog when a PWA is first opened in the browser.
+ * Displays the [PwaOnboardingDialogFragment] info dialog when a PWA is opened in the browser for the third time.
*/
-class FirstTimePwaObserver(
+class PwaOnboardingObserver(
private val navController: NavController,
private val settings: Settings,
private val webAppUseCases: WebAppUseCases
) : Session.Observer {
override fun onWebAppManifestChanged(session: Session, manifest: WebAppManifest?) {
- if (webAppUseCases.isInstallable() && settings.shouldShowFirstTimePwaFragment) {
- val directions = BrowserFragmentDirections.actionBrowserFragmentToFirstTimePwaFragment()
- navController.nav(R.id.browserFragment, directions)
-
- settings.userKnowsAboutPWAs = true
+ if (webAppUseCases.isInstallable() && !settings.userKnowsAboutPwas) {
+ settings.incrementVisitedInstallableCount()
+ if (settings.shouldShowPwaOnboarding) {
+ val directions =
+ BrowserFragmentDirections.actionBrowserFragmentToPwaOnboardingDialogFragment()
+ navController.nav(R.id.browserFragment, directions)
+ settings.userKnowsAboutPwas = true
+ }
}
}
}
diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
index b6d4530c6..a76825bef 100644
--- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
+++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
@@ -53,6 +53,7 @@ class Settings private constructor(
const val showLoginsSecureWarningSyncMaxCount = 1
const val showLoginsSecureWarningMaxCount = 1
const val trackingProtectionOnboardingMaximumCount = 1
+ const val pwaVisitsToShowPromptMaxCount = 3
const val FENIX_PREFERENCES = "fenix_preferences"
private const val showSearchWidgetCFRMaxCount = 3
@@ -146,9 +147,18 @@ class Settings private constructor(
// If any of the prefs have been modified, quit displaying the fenix moved tip
fun shouldDisplayFenixMovingTip(): Boolean =
- preferences.getBoolean(appContext.getString(R.string.pref_key_migrating_from_fenix_nightly_tip), true) &&
- preferences.getBoolean(appContext.getString(R.string.pref_key_migrating_from_firefox_nightly_tip), true) &&
- preferences.getBoolean(appContext.getString(R.string.pref_key_migrating_from_fenix_tip), true)
+ preferences.getBoolean(
+ appContext.getString(R.string.pref_key_migrating_from_fenix_nightly_tip),
+ true
+ ) &&
+ preferences.getBoolean(
+ appContext.getString(R.string.pref_key_migrating_from_firefox_nightly_tip),
+ true
+ ) &&
+ preferences.getBoolean(
+ appContext.getString(R.string.pref_key_migrating_from_fenix_tip),
+ true
+ )
private val activeSearchCount by intPreference(
appContext.getPreferenceKey(R.string.pref_key_search_count),
@@ -167,9 +177,9 @@ class Settings private constructor(
fun shouldDisplaySearchWidgetCFR(): Boolean =
isActiveSearcher &&
- searchWidgetCFRDismissCount < showSearchWidgetCFRMaxCount &&
- !searchWidgetInstalled &&
- !searchWidgetCFRManuallyDismissed
+ searchWidgetCFRDismissCount < showSearchWidgetCFRMaxCount &&
+ !searchWidgetInstalled &&
+ !searchWidgetCFRManuallyDismissed
private val searchWidgetCFRDisplayCount by intPreference(
appContext.getPreferenceKey(R.string.pref_key_search_widget_cfr_display_count),
@@ -236,10 +246,10 @@ class Settings private constructor(
val isCrashReportingEnabled: Boolean
get() = isCrashReportEnabledInBuild &&
- preferences.getBoolean(
- appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
- true
- )
+ preferences.getBoolean(
+ appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
+ true
+ )
val isRemoteDebuggingEnabled by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_remote_debugging),
@@ -267,7 +277,7 @@ class Settings private constructor(
val shouldShowTrackingProtectionOnboarding: Boolean
get() = !isOverrideTPPopupsForPerformanceTest &&
(trackingProtectionOnboardingCount < trackingProtectionOnboardingMaximumCount &&
- !trackingProtectionOnboardingShownThisSession)
+ !trackingProtectionOnboardingShownThisSession)
var showSecretDebugMenuThisSession = false
@@ -418,14 +428,14 @@ class Settings private constructor(
BrowsingMode.Normal
}
}
-
set(value) {
val lastKnownModeWasPrivate = (value == BrowsingMode.Private)
preferences.edit()
.putBoolean(
- appContext.getPreferenceKey(R.string.pref_key_last_known_mode_private),
- lastKnownModeWasPrivate)
+ appContext.getPreferenceKey(R.string.pref_key_last_known_mode_private),
+ lastKnownModeWasPrivate
+ )
.apply()
field = value
@@ -495,7 +505,9 @@ class Settings private constructor(
}
val accessibilityServicesEnabled: Boolean
- get() { return touchExplorationIsEnabled || switchServiceIsEnabled }
+ get() {
+ return touchExplorationIsEnabled || switchServiceIsEnabled
+ }
val toolbarSettingString: String
get() = when {
@@ -569,22 +581,41 @@ class Settings private constructor(
default = false
)
- val shouldShowFirstTimePwaFragment: Boolean
+ fun incrementVisitedInstallableCount() {
+ preferences.edit().putInt(
+ appContext.getPreferenceKey(R.string.pref_key_install_pwa_visits),
+ pwaInstallableVisitCount + 1
+ ).apply()
+ }
+
+ @VisibleForTesting(otherwise = PRIVATE)
+ internal val pwaInstallableVisitCount by intPreference(
+ appContext.getPreferenceKey(R.string.pref_key_install_pwa_visits),
+ default = 0
+ )
+
+ private val userNeedsToVisitInstallableSites: Boolean
+ get() = pwaInstallableVisitCount < pwaVisitsToShowPromptMaxCount
+
+ val shouldShowPwaOnboarding: Boolean
get() {
+ // We only want to show this on the 3rd time a user visits a site
+ if (userNeedsToVisitInstallableSites) return false
+
// ShortcutManager::pinnedShortcuts is only available on Oreo+
- if (!userKnowsAboutPWAs && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val alreadyHavePWaInstalled =
+ if (!userKnowsAboutPwas && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val alreadyHavePwaInstalled =
appContext.getSystemService(ShortcutManager::class.java)
.pinnedShortcuts.size > 0
// Users know about PWAs onboarding if they already have PWAs installed.
- userKnowsAboutPWAs = alreadyHavePWaInstalled
+ userKnowsAboutPwas = alreadyHavePwaInstalled
}
// Show dialog only if user does not know abut PWAs
- return !userKnowsAboutPWAs
+ return !userKnowsAboutPwas
}
- var userKnowsAboutPWAs by booleanPreference(
+ var userKnowsAboutPwas by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_user_knows_about_pwa),
default = false
)
@@ -809,8 +840,12 @@ class Settings private constructor(
var savedLoginsSortingStrategy: SortingStrategy
get() {
return when (savedLoginsSortingStrategyString) {
- SavedLoginsFragment.SORTING_STRATEGY_ALPHABETICALLY -> SortingStrategy.Alphabetically(appContext)
- SavedLoginsFragment.SORTING_STRATEGY_LAST_USED -> SortingStrategy.LastUsed(appContext)
+ SavedLoginsFragment.SORTING_STRATEGY_ALPHABETICALLY -> SortingStrategy.Alphabetically(
+ appContext
+ )
+ SavedLoginsFragment.SORTING_STRATEGY_LAST_USED -> SortingStrategy.LastUsed(
+ appContext
+ )
else -> SortingStrategy.Alphabetically(appContext)
}
}
diff --git a/app/src/main/res/layout/fragment_pwa_first_time.xml b/app/src/main/res/layout/fragment_pwa_onboarding.xml
similarity index 98%
rename from app/src/main/res/layout/fragment_pwa_first_time.xml
rename to app/src/main/res/layout/fragment_pwa_onboarding.xml
index 395a933a3..1c188eb89 100644
--- a/app/src/main/res/layout/fragment_pwa_first_time.xml
+++ b/app/src/main/res/layout/fragment_pwa_onboarding.xml
@@ -10,7 +10,7 @@
android:layout_height="match_parent"
android:background="@drawable/scrim_background"
android:fitsSystemWindows="true"
- tools:context="org.mozilla.fenix.shortcut.FirstTimePwaFragment">
+ tools:context="org.mozilla.fenix.shortcut.PwaOnboardingDialogFragment">
+ android:id="@+id/action_browserFragment_to_pwaOnboardingDialogFragment"
+ app:destination="@id/pwaOnboardingDialogFragment" />
@@ -680,10 +680,9 @@
android:name="org.mozilla.fenix.shortcut.CreateShortcutFragment"
tools:layout="@layout/fragment_create_shortcut" />
+ android:id="@+id/pwaOnboardingDialogFragment"
+ android:name="org.mozilla.fenix.shortcut.PwaOnboardingDialogFragment"
+ tools:layout="@layout/fragment_pwa_onboarding" />