Bug 1804107 - Fix for BaseBrowserFragment toolbar getter null crash and invalidating actions when modifying toolbar

fork
Zac McKenney 2 years ago committed by mergify[bot]
parent f6a52e9216
commit 4cd398a0b5

@ -33,7 +33,6 @@ import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -1400,6 +1399,11 @@ abstract class BaseBrowserFragment :
binding.swipeRefresh.isEnabled = shouldPullToRefreshBeEnabled(inFullScreen) binding.swipeRefresh.isEnabled = shouldPullToRefreshBeEnabled(inFullScreen)
} }
@CallSuper
internal open fun onUpdateToolbarForConfigurationChange(toolbar: BrowserToolbarView) {
toolbar.dismissMenu()
}
/* /*
* Dereference these views when the fragment view is destroyed to prevent memory leaks * Dereference these views when the fragment view is destroyed to prevent memory leaks
*/ */
@ -1472,7 +1476,9 @@ abstract class BaseBrowserFragment :
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
_browserToolbarView?.dismissMenu() _browserToolbarView?.let {
onUpdateToolbarForConfigurationChange(it)
}
} }
// This method is called in response to native web extension messages from // This method is called in response to native web extension messages from

@ -5,7 +5,6 @@
package org.mozilla.fenix.browser package org.mozilla.fenix.browser
import android.content.Context import android.content.Context
import android.content.res.Configuration
import android.os.StrictMode import android.os.StrictMode
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -32,6 +31,7 @@ import org.mozilla.fenix.GleanMetrics.ReaderMode
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.toolbar.BrowserToolbarView
import org.mozilla.fenix.components.toolbar.ToolbarMenu import org.mozilla.fenix.components.toolbar.ToolbarMenu
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
@ -90,7 +90,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
browserToolbarView.view.addNavigationAction(homeAction) browserToolbarView.view.addNavigationAction(homeAction)
setScreenSize(isTablet = resources.getBoolean(R.bool.tablet)) updateToolbarActions(isTablet = resources.getBoolean(R.bool.tablet))
val readerModeAction = val readerModeAction =
BrowserToolbar.ToggleButton( BrowserToolbar.ToggleButton(
@ -170,7 +170,14 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
} }
} }
private fun setScreenSize(isTablet: Boolean) { override fun onUpdateToolbarForConfigurationChange(toolbar: BrowserToolbarView) {
super.onUpdateToolbarForConfigurationChange(toolbar)
updateToolbarActions(isTablet = resources.getBoolean(R.bool.tablet))
}
@VisibleForTesting
internal fun updateToolbarActions(isTablet: Boolean) {
if (isTablet == this.isTablet) return if (isTablet == this.isTablet) return
if (isTablet) { if (isTablet) {
@ -280,6 +287,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
refreshAction?.let { refreshAction?.let {
browserToolbarView.view.addNavigationAction(it) browserToolbarView.view.addNavigationAction(it)
} }
browserToolbarView.view.invalidateActions()
} }
private fun removeTabletActions() { private fun removeTabletActions() {
@ -292,6 +301,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
refreshAction?.let { refreshAction?.let {
browserToolbarView.view.removeNavigationAction(it) browserToolbarView.view.removeNavigationAction(it)
} }
browserToolbarView.view.invalidateActions()
} }
override fun onStart() { override fun onStart() {
@ -447,9 +458,4 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
internal fun updateLastBrowseActivity() { internal fun updateLastBrowseActivity() {
requireContext().settings().lastBrowseActivity = System.currentTimeMillis() requireContext().settings().lastBrowseActivity = System.currentTimeMillis()
} }
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
setScreenSize(isTablet = resources.getBoolean(R.bool.tablet))
}
} }

@ -312,6 +312,21 @@ class BrowserFragmentTest {
verify(exactly = 1) { toolbarIntegration.invalidateMenu() } verify(exactly = 1) { toolbarIntegration.invalidateMenu() }
} }
@Test
fun `WHEN toolbar is initialized THEN onConfigurationChanged sets toolbar actions for size in fragment`() {
val browserToolbarView: BrowserToolbarView = mockk(relaxed = true)
browserFragment._browserToolbarView = null
browserFragment.onConfigurationChanged(mockk(relaxed = true))
verify(exactly = 0) { browserFragment.onUpdateToolbarForConfigurationChange(any()) }
verify(exactly = 0) { browserFragment.updateToolbarActions(any()) }
browserFragment._browserToolbarView = browserToolbarView
browserFragment.onConfigurationChanged(mockk(relaxed = true))
verify(exactly = 1) { browserFragment.onUpdateToolbarForConfigurationChange(any()) }
verify(exactly = 1) { browserFragment.updateToolbarActions(any()) }
}
@Test @Test
fun `WHEN fragment configuration changed THEN menu is dismissed`() { fun `WHEN fragment configuration changed THEN menu is dismissed`() {
val browserToolbarView: BrowserToolbarView = mockk(relaxed = true) val browserToolbarView: BrowserToolbarView = mockk(relaxed = true)
@ -325,7 +340,9 @@ class BrowserFragmentTest {
@Test @Test
fun `WHEN fragment configuration screen size changes between tablet and mobile size THEN tablet action items added and removed`() { fun `WHEN fragment configuration screen size changes between tablet and mobile size THEN tablet action items added and removed`() {
val browserToolbarView: BrowserToolbarView = mockk(relaxed = true)
val browserToolbar: BrowserToolbar = mockk(relaxed = true) val browserToolbar: BrowserToolbar = mockk(relaxed = true)
browserFragment._browserToolbarView = browserToolbarView
every { browserFragment.browserToolbarView.view } returns browserToolbar every { browserFragment.browserToolbarView.view } returns browserToolbar
mockkObject(ThemeManager.Companion) mockkObject(ThemeManager.Companion)
@ -348,7 +365,9 @@ class BrowserFragmentTest {
@Test @Test
fun `WHEN fragment configuration change enables tablet size twice THEN tablet action items are only added once`() { fun `WHEN fragment configuration change enables tablet size twice THEN tablet action items are only added once`() {
val browserToolbarView: BrowserToolbarView = mockk(relaxed = true)
val browserToolbar: BrowserToolbar = mockk(relaxed = true) val browserToolbar: BrowserToolbar = mockk(relaxed = true)
browserFragment._browserToolbarView = browserToolbarView
every { browserFragment.browserToolbarView.view } returns browserToolbar every { browserFragment.browserToolbarView.view } returns browserToolbar
mockkObject(ThemeManager.Companion) mockkObject(ThemeManager.Companion)
@ -370,7 +389,9 @@ class BrowserFragmentTest {
@Test @Test
fun `WHEN fragment configuration change sets mobile size twice THEN tablet action items are not added or removed`() { fun `WHEN fragment configuration change sets mobile size twice THEN tablet action items are not added or removed`() {
val browserToolbarView: BrowserToolbarView = mockk(relaxed = true)
val browserToolbar: BrowserToolbar = mockk(relaxed = true) val browserToolbar: BrowserToolbar = mockk(relaxed = true)
browserFragment._browserToolbarView = browserToolbarView
every { browserFragment.browserToolbarView.view } returns browserToolbar every { browserFragment.browserToolbarView.view } returns browserToolbar
mockkObject(ThemeManager.Companion) mockkObject(ThemeManager.Companion)

Loading…
Cancel
Save