Firefox · Core
CVE-2024-8388
Logic Error in Core
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
FullScreenNotificationToastmobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotification.kt |
modified | |
FullScreenNotificationDialogmobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt |
modified | |
ifmobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/GestureNavUtils.kt |
modified | |
FullScreenNotificationTestmobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt |
modified |
Files Changed
mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotification.ktmobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.ktmobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/GestureNavUtils.ktmobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.ktmobile/android/android-components/docs/changelog.mdmobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.ktmobile/android/fenix/app/src/main/res/values/strings.xmlmobile/android/focus-android/app/src/main/java/org/mozilla/focus/browser/integration/FullScreenIntegration.ktmobile/android/focus-android/app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.ktmobile/android/focus-android/app/src/main/res/values/strings.xmlmobile/android/focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
Patch
diff --git a/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotification.kt b/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotification.kt
deleted file mode 100644
index ed20bf5234b..00000000000
--- a/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotification.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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 mozilla.components.feature.prompts.dialog
-
-import android.app.Activity
-import android.widget.Toast
-
-/**
- * UI to show a 'full screen mode' notification.
- */
-interface FullScreenNotification {
- /**
- * Show the notification.
- */
- fun show()
-}
-
-/**
- * A [Toast] to show a full screen notification message
- * @property activity The activity to show the toast on.
- * @property gestureNavString The string to show when in gesture navigation mode.
- * @property backButtonString The string to show when in 3-button navigation mode.
- * @property gestureNavUtils Utility to detect gesture navigation.
- */
-class FullScreenNotificationToast(
- private val activity: Activity,
- private val gestureNavString: String,
- private val backButtonString: String,
- private val gestureNavUtils: GestureNavUtils,
-) : FullScreenNotification {
- override fun show() {
- val toastString =
- if (gestureNavUtils.isInGestureNavigationMode(activity.window)) {
- gestureNavString
- } else {
- backButtonString
- }
- Toast.makeText(activity, toastString, Toast.LENGTH_LONG).show()
- }
-}
diff --git a/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt b/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
new file mode 100644
index 00000000000..3c403f3734e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt
@@ -0,0 +1,70 @@
+/* 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 mozilla.components.feature.prompts.dialog
+
+import android.app.Dialog
+import android.os.Bundle
+import android.view.Gravity
+import android.view.WindowManager
+import androidx.annotation.LayoutRes
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+import androidx.fragment.app.FragmentManager
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+private const val TAG = "mozac_feature_prompts_full_screen_notification_dialog"
+private const val SNACKBAR_DURATION_LONG_MS = 3000L
+
+/**
+ * UI to show a 'full screen mode' notification.
+ */
+interface FullScreenNotification {
+ /**
+ * Show the notification.
+ *
+ * @param fragmentManager the [FragmentManager] to add this notification to.
+ */
+ fun show(fragmentManager: FragmentManager)
+}
+
+/**
+ * [DialogFragment] that is configured to match the style and behaviour of a Snackbar.
+ *
+ * @property layout the layout to use for the dialog.
+ */
+class FullScreenNotificationDialog(@LayoutRes val layout: Int) :
+ DialogFragment(), FullScreenNotification {
+ override fun show(fragmentManager: FragmentManager) = super.show(fragmentManager, TAG)
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = requireActivity().let {
+ val view = layoutInflater.inflate(layout, null)
+ AlertDialog.Builder(it).setView(view).create()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ dialog?.let { dialog ->
+ dialog.window?.let { window ->
+ // Prevent any user input from key or other button events to it.
+ window.setFlags(
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ )
+
+ window.setGravity(Gravity.BOTTOM)
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
+ }
+ }
+
+ // Attempt to automatically dismiss the dialog after the given duration.
+ lifecycleScope.launch {
+ delay(SNACKBAR_DURATION_LONG_MS)
+ dialog?.dismiss()
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/GestureNavUtils.kt b/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/GestureNavUtils.kt
deleted file mode 100644
index 203e0c45dbd..00000000000
--- a/mobile/android/android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/GestureNavUtils.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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 mozilla.components.feature.prompts.dialog
-
-import android.os.Build
-import android.view.Window
-import androidx.core.view.WindowInsetsCompat
-
-/**
- * A place to keep utility functions for gesture navigation.
- */
-object GestureNavUtils {
- /**
- * Find out if the device supports gesture navigation and has gestures enabled.
- *
- * Gesture nav support was added in Android Q, but on recent devices it is possible to
- * switch navigation mode between gesture nav and 3-button navigation.
- * The system gesture inset needs to be greater than 0 at the left edge of the screen
- * for the back gesture to be picked up, so this seems to be the most reliable way of
- * detecting gesture navigation use.
- *
- * * See also: [Gesture Navigation: handling visual overlaps (II)](https://medium.com/androiddevelopers/gesture-navigation-handling-visual-overlaps-4aed565c134c)
- * * See also: [How to detect full screen gesture mode](https://stackoverflow.com/a/70514883)
- *
- * @param window The containing [Window] of the current `Activity`.
- * @return true if the device supports gesture navigation and gestures are enabled.
- */
- fun isInGestureNavigationMode(window: Window): Boolean =
- (
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- WindowInsetsCompat
- .toWindowInsetsCompat(
- window.decorView.rootWindowInsets,
- ).getInsets(WindowInsetsCompat.Type.systemGestures())
- .left
- } else {
- 0
- }
- ) > 0
-}
diff --git a/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt b/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt
deleted file mode 100644
index a388ce24311..00000000000
--- a/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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 mozilla.components.feature.prompts.dialog
-
-import android.app.Activity
-import androidx.test.core.app.ActivityScenario
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import mozilla.components.support.test.any
-import mozilla.components.support.test.whenever
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-import org.robolectric.Robolectric
-import org.robolectric.shadows.ShadowToast
-
-@RunWith(AndroidJUnit4::class)
-class FullScreenNotificationTest {
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt b/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt
deleted file mode 100644
index a388ce24311..00000000000
--- a/mobile/android/android-components/components/feature/prompts/src/test/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationTest.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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 mozilla.components.feature.prompts.dialog
-
-import android.app.Activity
-import androidx.test.core.app.ActivityScenario
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import mozilla.components.support.test.any
-import mozilla.components.support.test.whenever
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-import org.robolectric.Robolectric
-import org.robolectric.shadows.ShadowToast
-
-@RunWith(AndroidJUnit4::class)
-class FullScreenNotificationTest {
-
- @Mock
- lateinit var mockGestureNavUtils: GestureNavUtils
-
- @Before
- fun setup() {
- MockitoAnnotations.openMocks(this)
- val activity = Robolectric.buildActivity(EmptyActivity::class.java)
- activity.create()
- }
-
- @Test
- fun `when in 3 button navigation mode, full screen notification shows exit instructions for back button`() {
- whenever(mockGestureNavUtils.isInGestureNavigationMode(any())).thenReturn(false)
- ActivityScenario.launch(EmptyActivity::class.java).use { scenario ->
- scenario.onActivity { activity: EmptyActivity ->
- FullScreenNotificationToast(
- activity,
- "gesture",
- "button",
- mockGestureNavUtils,
- ).show()
- assertTrue(ShadowToast.showedToast("button"))
- }
- }
- }
-
- @Test
- fun `when in gesture navigation mode, full screen notification shows exit instructions for gesture nav`() {
- whenever(mockGestureNavUtils.isInGestureNavigationMode(any())).thenReturn(true)
- ActivityScenario.launch(EmptyActivity::class.java).use { scenario ->
- scenario.onActivity { activity: EmptyActivity ->
- FullScreenNotificationToast(
- activity,
- "gesture",
- "button",
- mockGestureNavUtils,
- ).show()
- assertTrue(ShadowToast.showedToast("gesture"))
- }
- }
- }
-}
-
-internal class EmptyActivity : Activity()
diff --git a/mobile/android/focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt b/mobile/android/focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
index 64e4a865ad5..69b7a031b4b 100644
--- a/mobile/android/focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
+++ b/mobile/android/focus-android/app/src/test/java/org/mozilla/focus/browser/integration/FullScreenIntegrationTest.kt
@@ -22,7 +22,6 @@ import mozilla.components.support.test.robolectric.testContext
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.runner.RunWith
-import org.mockito.Mockito.anyInt
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
@@ -43,7 +42,17 @@ internal class FullScreenIntegrationTest {
@Test
fun `WHEN the integration is started THEN start FullScreenFeature`() {
val feature: FullScreenFeature = mock()
- val integration = createFullScreenIntegration().apply {
+ val integration = FullScreenIntegration(
+ mock(),
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ ).apply {
this.feature = feature
}
@@ -55,7 +64,17 @@ internal class FullScreenIntegrationTest {
@Test
fun `WHEN the integration is stopped THEN stop FullScreenFeature`() {
val feature: FullScreenFeature = mock()
- val integration = createFullScreenIntegration().apply {
+ val integration = FullScreenIntegration(
+ mock(),
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ ).apply {
this.feature = feature
}
@@ -67,7 +86,17 @@ internal class FullScreenIntegrationTest {
@Test
fun `WHEN back is pressed THEN send this to the feature`() {
val feature: FullScreenFeature = mock()
- val integration = createFullScreenIntegration().apply {
+ val integration = FullScreenIntegration(
+ mock(),
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ ).apply {
this.feature = feature
}
@@ -83,7 +112,17 @@ internal class FullScreenIntegrationTest {
val activity: Activity = mock()
doReturn(activityWindow).`when`(activity).window
doReturn(windowAttributes).`when`(activityWindow).attributes
- val integration = createFullScreenIntegration(activity = activity)
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ )
integration.viewportFitChanged(33)
@@ -102,7 +141,17 @@ internal class FullScreenIntegrationTest {
doReturn(decorView).`when`(activityWindow).decorView
doReturn(layoutParams).`when`(activityWindow).attributes
- val integration = createFullScreenIntegration(activity = activity)
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ )
integration.switchToImmersiveMode()
@@ -126,7 +175,17 @@ internal class FullScreenIntegrationTest {
doReturn(layoutParams).`when`(activityWindow).attributes
doReturn(insetsController).`when`(activityWindow).insetsController
- val integration = createFullScreenIntegration(activity = activity)
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ )
integration.switchToImmersiveMode()
@@ -155,7 +214,17 @@ internal class FullScreenIntegrationTest {
doReturn(activityWindow).`when`(activity).window
doReturn(decorView).`when`(activityWindow).decorView
doReturn(layoutParams).`when`(activityWindow).attributes
- val integration = createFullScreenIntegration(activity = activity)
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ )
integration.exitImmersiveMode()
// Hiding the system bar hides the status and navigation bars.
@@ -178,7 +247,17 @@ internal class FullScreenIntegrationTest {
doReturn(layoutParams).`when`(activityWindow).attributes
doReturn(insetsController).`when`(activityWindow).insetsController
- val integration = createFullScreenIntegration(activity = activity)
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ mock(),
+ )
integration.exitImmersiveMode()
@@ -199,10 +278,16 @@ internal class FullScreenIntegrationTest {
doReturn(mock<View>()).`when`(engineView).asView()
val settings: Settings = mock()
doReturn(true).`when`(settings).isAccessibilityEnabled()
- val integration = createFullScreenIntegration(
- settings = settings,
- toolbar = toolbar,
- engineView = engineView,
+ val integration = FullScreenIntegration(
+ mock(),
+ mock(),
+ null,
+ mock(),
+ settings,
+ toolbar,
+ mock(),
+ engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -219,10 +304,16 @@ internal class FullScreenIntegrationTest {
doReturn(mock<View>()).`when`(engineView).asView()
val settings: Settings = mock()
doReturn(false).`when`(settings).isAccessibilityEnabled()
- val integration = createFullScreenIntegration(
- settings = settings,
- toolbar = toolbar,
- engineView = engineView,
+ val integration = FullScreenIntegration(
+ mock(),
+ mock(),
+ null,
+ mock(),
+ settings,
+ toolbar,
+ mock(),
+ engineView,
+ mock(),
)
integration.enterBrowserFullscreen()
@@ -244,13 +335,17 @@ internal class FullScreenIntegrationTest {
val resources: Resources = mock()
val activity: Activity = mock()
doReturn(resources).`when`(activity).resources
- val integration =
- createFullScreenIntegration(
- activity = activity,
- settings = settings,
- toolbar = toolbar,
- engineView = engineView,
- )
+ val integration = FullScreenIntegration(
+ activity,
+ mock(),
+ null,
+ mock(),
+ settings,
+ toolbar,
+ mock(),
+ engineView,
+ mock(),
... (truncated)
Loading diff…
References
On This Page