For #21611: Show the jump back in Contextual Hints independently of the home onboarding dialog.

This commit is contained in:
Arturo Mejia 2021-10-05 16:47:59 -04:00 committed by mergify[bot]
parent 7e3a2ba89d
commit 0f07703c3e
20 changed files with 144 additions and 98 deletions

View File

@ -52,6 +52,8 @@ class BookmarksTest {
dispatcher = AndroidAssetDispatcher()
start()
}
val settings = activityTestRule.activity.settings()
settings.shouldShowJumpBackInCFR = false
}
@After
@ -346,7 +348,7 @@ class BookmarksTest {
@Test
fun openSelectionInNewTabTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
browserScreen {

View File

@ -40,7 +40,7 @@ class CollectionTest {
@Before
fun setUp() {
activityTestRule.activity.applicationContext.settings().hasShownHomeOnboardingDialog = true
activityTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()

View File

@ -43,7 +43,7 @@ class HistoryTest {
@Before
fun setUp() {
InstrumentationRegistry.getInstrumentation().targetContext.settings()
.hasShownHomeOnboardingDialog = true
.shouldShowJumpBackInCFR = false
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()

View File

@ -119,7 +119,7 @@ class HomeScreenTest {
@Test
fun dismissOnboardingUsingHelpTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
homeScreen {
verifyWelcomeHeader()
}.openThreeDotMenu {

View File

@ -12,6 +12,7 @@ import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.TestAssetHelper
@ -41,6 +42,8 @@ class NavigationToolbarTest {
dispatcher = AndroidAssetDispatcher()
start()
}
val settings = activityTestRule.activity.settings()
settings.shouldShowJumpBackInCFR = false
}
@After

View File

@ -56,7 +56,7 @@ class NoNetworkAccessStartupTests {
fun networkInterruptedFromBrowserToHomeTest() {
val url = "example.com"
val settings = InstrumentationRegistry.getInstrumentation().targetContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
activityTestRule.launchActivity(null)

View File

@ -77,7 +77,7 @@ class SettingsAboutTest {
@Test
fun verifyAboutFirefoxPreview() {
val settings = activityIntentTestRule.activity.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
homeScreen {
}.openThreeDotMenu {
}.openSettings {

View File

@ -43,6 +43,8 @@ class SettingsBasicsTest {
dispatcher = AndroidAssetDispatcher()
start()
}
val settings = activityIntentTestRule.activity.settings()
settings.shouldShowJumpBackInCFR = false
}
@After
@ -157,7 +159,7 @@ class SettingsBasicsTest {
val fenixApp = activityIntentTestRule.activity.applicationContext as FenixApplication
val webpage = getLoremIpsumAsset(mockWebServer).url
val settings = fenixApp.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
// This value will represent the text size percentage the webpage will scale to. The default value is 100%.
val textSizePercentage = 180

View File

@ -47,7 +47,7 @@ class SettingsPrivacyTest {
}
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
}
@After
@ -223,7 +223,7 @@ class SettingsPrivacyTest {
fun neverSaveLoginFromPromptTest() {
val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer)
val settings = activityTestRule.activity.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
navigationToolbar {
}.enterURLAndEnterToBrowser(saveLoginTest.url) {
@ -330,7 +330,7 @@ class SettingsPrivacyTest {
@Test
fun launchLinksInPrivateToggleOffStateDoesntChangeTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
setOpenLinksInPrivateOn()

View File

@ -108,7 +108,7 @@ class SmokeTest {
// So we are initializing this here instead of in all related tests.
browserStore = activityTestRule.activity.components.core.store
activityTestRule.activity.applicationContext.settings().hasShownHomeOnboardingDialog = true
activityTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
@ -312,7 +312,7 @@ class SmokeTest {
// Verifies the Add to top sites option in a tab's 3 dot menu
fun openMainMenuAddTopSiteTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -824,7 +824,7 @@ class SmokeTest {
@Ignore("https://github.com/mozilla-mobile/fenix/issues/21397")
fun createFirstCollectionTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val firstWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val secondWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 2)
@ -858,7 +858,7 @@ class SmokeTest {
@Ignore("https://github.com/mozilla-mobile/fenix/issues/21397")
fun verifyExpandedCollectionItemsTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
@ -912,7 +912,7 @@ class SmokeTest {
@Test
fun shareCollectionTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -938,7 +938,7 @@ class SmokeTest {
// caution when making changes to it, so they don't block the builds
fun deleteCollectionTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val webPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
@ -1357,7 +1357,7 @@ class SmokeTest {
@Test
fun goToHomeScreenBottomToolbarTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {
@ -1371,7 +1371,7 @@ class SmokeTest {
@Test
fun goToHomeScreenTopToolbarTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
@ -1441,7 +1441,7 @@ class SmokeTest {
@Test
fun alwaysStartOnHomeTest() {
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val genericURL = TestAssetHelper.getGenericAsset(mockWebServer, 1)
navigationToolbar {

View File

@ -44,7 +44,9 @@ class StrictEnhancedTrackingProtectionTest {
start()
}
activityTestRule.activity.settings().setStrictETP()
val settings = activityTestRule.activity.settings()
settings.setStrictETP()
settings.shouldShowJumpBackInCFR = false
}
@After

View File

@ -48,14 +48,11 @@ class TabbedBrowsingTest {
@Before
fun setUp() {
activityTestRule.activity.applicationContext.settings().hasShownHomeOnboardingDialog = true
activityTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()
}
val settings = activityTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
}
@After

View File

@ -29,7 +29,7 @@ class ThreeDotMenuMainTest {
@Before
fun setUp() {
activityTestRule.activity.applicationContext.settings().hasShownHomeOnboardingDialog = true
activityTestRule.activity.applicationContext.settings().shouldShowJumpBackInCFR = false
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
start()

View File

@ -50,7 +50,7 @@ class TopSitesTest {
@Test
fun verifyAddToFirefoxHome() {
val settings = activityIntentTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val defaultWebPageTitle = "Test_Page_1"
@ -70,7 +70,7 @@ class TopSitesTest {
@Test
fun verifyOpenTopSiteNormalTab() {
val settings = activityIntentTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val defaultWebPageTitle = "Test_Page_1"
@ -100,7 +100,7 @@ class TopSitesTest {
@Test
fun verifyOpenTopSitePrivateTab() {
val settings = activityIntentTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val defaultWebPageTitle = "Test_Page_1"
@ -124,7 +124,7 @@ class TopSitesTest {
@Test
fun verifyRenameTopSite() {
val settings = activityIntentTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val defaultWebPageTitle = "Test_Page_1"
val defaultWebPageTitleNew = "Test_Page_2"
@ -150,7 +150,7 @@ class TopSitesTest {
@Test
fun verifyRemoveTopSite() {
val settings = activityIntentTestRule.activity.applicationContext.settings()
settings.hasShownHomeOnboardingDialog = true
settings.shouldShowJumpBackInCFR = false
val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1)
val defaultWebPageTitle = "Test_Page_1"

View File

@ -12,7 +12,7 @@
"value": {
"sections-enabled": {
"topSites": true,
"recentExplorations": false,
"recentExplorations": true,
"recentlySaved": false,
"jumpBackIn": false,
"pocket": false

View File

@ -24,6 +24,7 @@ import org.mozilla.fenix.home.HomeScreenViewModel
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.home.recenttabs.RecentTab
import org.mozilla.fenix.onboarding.JumpBackInCFRDialog
import org.mozilla.fenix.utils.Settings
// This method got a little complex with the addition of the tab tray feature flag
@ -197,7 +198,13 @@ class SessionControlView(
init {
view.apply {
adapter = sessionControlAdapter
layoutManager = LinearLayoutManager(containerView.context)
layoutManager = object : LinearLayoutManager(containerView.context) {
override fun onLayoutCompleted(state: RecyclerView.State?) {
super.onLayoutCompleted(state)
JumpBackInCFRDialog(view).showIfNeeded()
}
}
val itemTouchHelper =
ItemTouchHelper(
SwipeToDeleteCallback(

View File

@ -4,22 +4,14 @@
package org.mozilla.fenix.onboarding
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentOnboardingHomeDialogBinding
import org.mozilla.fenix.databinding.OnboardingJumpBackInCfrBinding
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.recenttabs.view.RecentTabsHeaderViewHolder
/**
* Dialog displayed once when one or multiples of these sections are shown in the home screen
@ -45,65 +37,7 @@ class HomeOnboardingDialogFragment : DialogFragment() {
context?.settings()?.let { settings ->
settings.hasShownHomeOnboardingDialog = true
}
showJumpCFR()
dismiss()
}
}
private fun showJumpCFR() {
val jumpBackInView = findJumpBackInView()
jumpBackInView?.let {
val crfDialog = createJumpCRF(anchor = jumpBackInView)
crfDialog?.show()
}
}
private fun findJumpBackInView(): View? {
val list = activity?.findViewById<RecyclerView>(R.id.sessionControlRecyclerView)
val count = list?.adapter?.itemCount ?: return null
for (index in 0..count) {
val viewHolder = list.findViewHolderForAdapterPosition(index)
if (viewHolder is RecentTabsHeaderViewHolder) {
return viewHolder.containerView
}
}
return null
}
private fun createJumpCRF(anchor: View): Dialog? {
val context: Context = requireContext()
val anchorPosition = IntArray(2)
val popupBinding = OnboardingJumpBackInCfrBinding.inflate(LayoutInflater.from(context))
val popup = Dialog(context)
popup.apply {
setContentView(popupBinding.root)
setCancelable(false)
// removing title or setting it as an empty string does not prevent a11y services from assigning one
setTitle(" ")
}
popupBinding.closeInfoBanner.setOnClickListener {
popup.dismiss()
}
anchor.getLocationOnScreen(anchorPosition)
val (x, y) = anchorPosition
if (x == 0 && y == 0) {
return null
}
popupBinding.root.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
popup.window?.apply {
val attr = attributes
setGravity(Gravity.START or Gravity.TOP)
attr.x = x
attr.y = y - popupBinding.root.measuredHeight
attributes = attr
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
return popup
}
}

View File

@ -0,0 +1,89 @@
/* 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.onboarding
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.databinding.OnboardingJumpBackInCfrBinding
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.recenttabs.view.RecentTabsHeaderViewHolder
/**
* Dialog displayed once when the jump back in section is shown in the home screen.
*/
class JumpBackInCFRDialog(val recyclerView: RecyclerView) {
/**
* Try to show the crf dialog if it hasn't been shown before.
*/
fun showIfNeeded() {
val jumpBackInView = findJumpBackInView()
jumpBackInView?.let {
val crfDialog = createJumpCRF(anchor = jumpBackInView)
crfDialog?.let {
val context = jumpBackInView.context
context.settings().shouldShowJumpBackInCFR = false
it.show()
}
}
}
private fun findJumpBackInView(): View? {
val count = recyclerView.adapter?.itemCount ?: return null
for (index in 0..count) {
val viewHolder = recyclerView.findViewHolderForAdapterPosition(index)
if (viewHolder is RecentTabsHeaderViewHolder) {
return viewHolder.containerView
}
}
return null
}
private fun createJumpCRF(anchor: View): Dialog? {
val context: Context = recyclerView.context
if (!context.settings().shouldShowJumpBackInCFR) {
return null
}
val anchorPosition = IntArray(2)
val popupBinding = OnboardingJumpBackInCfrBinding.inflate(LayoutInflater.from(context))
val popup = Dialog(context)
popup.apply {
setContentView(popupBinding.root)
setCancelable(false)
// removing title or setting it as an empty string does not prevent a11y services from assigning one
setTitle(" ")
}
popupBinding.closeInfoBanner.setOnClickListener {
popup.dismiss()
}
anchor.getLocationOnScreen(anchorPosition)
val (x, y) = anchorPosition
if (x == 0 && y == 0) {
return null
}
popupBinding.root.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
popup.window?.apply {
val attr = attributes
setGravity(Gravity.START or Gravity.TOP)
attr.x = x
attr.y = y - popupBinding.root.measuredHeight
attributes = attr
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
return popup
}
}

View File

@ -837,6 +837,14 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = true
)
/**
* Indicates if the jump back in CRF should be shown.
*/
var shouldShowJumpBackInCFR by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_should_show_jump_back_in_tabs_popup),
default = true
)
fun getSitePermissionsPhoneFeatureAction(
feature: PhoneFeature,
default: Action = Action.ASK_TO_ALLOW

View File

@ -227,6 +227,8 @@
<!-- A value of `true` means the Inactive tabs onboarding popup has not been shown yet -->
<string name="pref_key_should_show_inactive_tabs_popup" translatable="false">pref_key_should_show_inactive_tabs_popup</string>
<!-- A value of `true` means the jump back in onboarding popup has not been shown yet -->
<string name="pref_key_should_show_jump_back_in_tabs_popup" translatable="false">pref_key_should_show_jump_back_in_tabs_popup</string>
<string name="pref_key_migrating_from_fenix_nightly_tip" translatable="false">pref_key_migrating_from_fenix_nightly_tip</string>