Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Omnibox
DescriptionInappropriate implementation in Omnibox
ComponentOmnibox
Bug ClassLogic Error
Tracker452392032
Fix commit316d6696542c (chromium/src) +57/-24
CISA KEVNot listed
CreditedHafiizh
Disclosed2025-11-05

Changed Functions

FunctionChangeNotes
if
chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java
modified
if
chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java
modified

Files Changed

  • chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
  • chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
  • chrome/browser/keyboard_accessory/android/internal/java/res/values/dimens.xml
  • chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java
  • chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java
  • chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionControllerTest.java
From 316d6696542c7cd0307eeb8df3a914a8eda9989f Mon Sep 17 00:00:00 2001
From: Patrick Noland <[email protected]>
Date: Wed, 22 Oct 2025 12:30:26 -0700
Subject: [PATCH] [mobar] Fix keyboard accessory overlap in multiwindow

For reasons as yet unknown to me, multi-window seems to cause
ToolbarControlContainer to not be drawn when its pre-translation
position overlaps with the keyboard accessory. This may be an
optimization of sorts; I was not able to turn it off by fiddling with
clipChildren/clipToBounds.

Instead, we resolve it by removing kb accessory height from the
translation calculation, using it instead to set the bottom margin. This
should be safe since we don't use the bottom margin for another purpose
and performant since the keyboard accessory doesn't change height often.

Two related issues are resolved at the same time:
* The revamped kb accessory reports the wrong height, referencing the
  old dimen. This is changed to be feature aware.
* There is no insets animation in multiwindow, meaning minimization
  progress isn't set properly. We now explicitly call it when skipping
  the animation.

Bug: 452392032, 438136964
Change-Id: I0df6bffdbbb0885e70b5c7ff0614faa5447b93e1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7069866
Reviewed-by: Tomasz Wiszkowski <[email protected]>
Commit-Queue: Patrick Noland <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1533841}
---

diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
index 33eeae5..95eacd57 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
@@ -1064,12 +1064,22 @@
     }
 
     private @Px int getBarHeightWithoutShadow() {
-        return mActivity
-                .getResources()
-                .getDimensionPixelSize(R.dimen.keyboard_accessory_suggestion_height);
+        if (ChromeFeatureList.isEnabled(
+                ChromeFeatureList.AUTOFILL_ENABLE_KEYBOARD_ACCESSORY_CHIP_REDESIGN)) {
+            return mActivity
+                    .getResources()
+                    .getDimensionPixelSize(R.dimen.keyboard_accessory_height_redesign);
+        }
+        return mActivity.getResources().getDimensionPixelSize(R.dimen.keyboard_accessory_height);
     }
 
     private @Px int getHeaderHeight() {
+        if (ChromeFeatureList.isEnabled(
+                ChromeFeatureList.AUTOFILL_ENABLE_KEYBOARD_ACCESSORY_CHIP_REDESIGN)) {
+            return mActivity
+                    .getResources()
+                    .getDimensionPixelSize(R.dimen.keyboard_accessory_height_with_shadow_redesign);
+        }
         return mActivity
                 .getResources()
                 .getDimensionPixelSize(R.dimen.keyboard_accessory_height_with_shadow);
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
index c53e72f1..334a699 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
@@ -123,7 +123,8 @@
 @Config(manifest = Config.NONE)
 @Features.EnableFeatures({
     ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_SUPPRESS_ACCESSORY_ON_EMPTY,
-    ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP
+    ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP,
+    ChromeFeatureList.AUTOFILL_ENABLE_KEYBOARD_ACCESSORY_CHIP_REDESIGN
 })
 public class ManualFillingControllerTest {
     private static final int sKeyboardHeightDp = 100;
@@ -1701,6 +1702,8 @@
         // Return the correct keyboard_accessory_height for the current density:
         when(mMockResources.getDimensionPixelSize(R.dimen.keyboard_accessory_suggestion_height))
                 .thenReturn((int) (density * 48));
+        when(mMockResources.getDimensionPixelSize(R.dimen.keyboard_accessory_height_redesign))
+                .thenReturn((int) (density * 48));
     }
 
     /**
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/res/values/dimens.xml b/chrome/browser/keyboard_accessory/android/internal/java/res/values/dimens.xml
index 270a49f..32e0eb4 100644
--- a/chrome/browser/keyboard_accessory/android/internal/java/res/values/dimens.xml
+++ b/chrome/browser/keyboard_accessory/android/internal/java/res/values/dimens.xml
@@ -11,6 +11,7 @@
     <dimen name="keyboard_accessory_horizontal_padding">6dp</dimen>
     <dimen name="keyboard_accessory_height">48dp</dimen>
     <dimen name="keyboard_accessory_height_redesign">64dp</dimen>
+    <dimen name="keyboard_accessory_height_with_shadow_redesign">72dp</dimen>
     <dimen name="keyboard_accessory_chip_min_height_redesign">64dp</dimen>
     <dimen name="keyboard_accessory_chip_vertical_insets">8dp</dimen>
     <dimen name="keyboard_accessory_chip_vertical_insets_large_font">2dp</dimen>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java
index f8e7527..9394ad06 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/MiniOriginBarController.java
@@ -243,17 +243,19 @@
         boolean finishedShowing = newMiniOriginState == MiniOriginState.SHOWING;
         mMiniOriginBarState = newMiniOriginState;
 
-        if (finishedShowing) {
-            setMinimizationProgress(1.0f);
+        if (!isChangingVisibility) {
+            if (finishedShowing) setMinimizationProgress(1.0f);
+            return;
         }
 
-        if (!isChangingVisibility) return;
-
         if (isMiniOriginBarVisibleForState(newMiniOriginState)) {
             // Cache the location bar's layout params now, since we are about to mutate them.
             mDefaultLocationBarLayoutParams =
                     (FrameLayout.LayoutParams) mLocationBar.getContainerView().getLayoutParams();
             showMiniOriginBar();
+            if (finishedShowing) {
+                setMinimizationProgress(1.0f);
+            }
         } else {
             hideMiniOriginBar();
         }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java
index 553dd369..1f0f955 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionController.java
@@ -54,6 +54,9 @@
 /** Class responsible for managing the position (top, bottom) of the browsing mode toolbar. */
 @NullMarked
 public class ToolbarPositionController implements OnSharedPreferenceChangeListener {
+
+    private final Callback<Integer> mKeyboardAccessoryHeightObserver;
+
     @IntDef({
         ToolbarPositionAndSource.TOP_LONG_PRESS,
         ToolbarPositionAndSource.TOP_SETTINGS,
@@ -332,11 +335,19 @@
                 (focused) -> updateViewOffset(mProgressBarLayer, mToolbarProgressBarContainer);
         mControlContainerTranslationCallback =
                 (offset) -> updateViewOffset(mBottomToolbarLayer, mControlContainer.getView());
+        mKeyboardAccessoryHeightObserver =
+                (height) -> {
+                    if (mCurrentPosition.get() == ControlsPosition.TOP) {
+                        mControlContainer.mutateLayoutParams().bottomMargin = 0;
+                        return;
+                    }
+                    mControlContainer.mutateLayoutParams().bottomMargin = height;
+                };
         mControlContainerHeightCallback = this::updateControlContainerHeight;
         mControlContainerHeightSupplier.addSyncObserverAndCallIfNonNull(
                 mControlContainerHeightCallback);
 
-        mKeyboardAccessoryHeightSupplier.addObserver(mKeyboardHeightToolbarCallback);
+        mKeyboardAccessoryHeightSupplier.addObserver(mKeyboardAccessoryHeightObserver);
         mKeyboardAccessoryHeightSupplier.addObserver(mKeyboardHeightProgressBarCallback);
         mKeyboardVisibilityDelegate.addKeyboardVisibilityListener(
                 mKeyboardVisibilityViewOffsetCallback);
@@ -374,6 +385,7 @@
         mIsFormFieldFocusedSupplier.removeObserver(mFormFieldViewOffsetCallback);
         mControlContainerTranslationSupplier.removeObserver(mControlContainerTranslationCallback);
         mControlContainerHeightSupplier.removeObserver(mControlContainerHeightCallback);
+        mKeyboardAccessoryHeightSupplier.removeObserver(mKeyboardAccessoryHeightObserver);
         if (mTopInsetCoordinatorObserver != null) {
             var topInsetCoordinator = mTopInsetCoordinatorSupplier.get();
             if (topInsetCoordinator != null) {
@@ -636,18 +648,15 @@
     private void updateViewOffset(BottomControlsLayerWithOffset layer, View viewForLayer) {
         if (mLayerVisibility != LayerVisibility.VISIBLE) return;
 
-        int keyboardAccessoryHeight = mKeyboardAccessoryHeightSupplier.get();
-        int layerYOffset =
-                layer.getLayerOffsetPx()
-                        - keyboardAccessoryHeight
-                        + mControlContainerTranslationSupplier.get();
+        int layerYOffset = layer.getLayerOffsetPx() + mControlContainerTranslationSupplier.get();
         int chinHeight =
                 mBottomControlsStacker.isLayerVisible(LayerType.BOTTOM_CHIN)
                         ? mBottomControlsStacker.getHeightFromLayerToBottom(LayerType.BOTTOM_CHIN)
                         : 0;
         // The chin overlaps with the accessory when they're both visible. To avoid double counting,
         // remove the chin's height from the final offset.
-        boolean chinVisibleWithAccessory = keyboardAccessoryHeight > 0 && chinHeight > 0;
+        boolean chinVisibleWithAccessory =
+                mKeyboardAccessoryHeightSupplier.get() > 0 && chinHeight > 0;
         if (chinVisibleWithAccessory) {
             layerYOffset += chinHeight;
         }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionControllerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionControllerTest.java
index 967632d..00876e1e 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionControllerTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarPositionControllerTest.java
@@ -998,7 +998,8 @@
         verify(mControlContainerView).setTranslationY(baseTranslation);
 
         final int chinHeight = 36;
-        int keybpardAccessoryHeight = 100;
+        int keyboardAccessoryHeight = 100;
+        mKeyboardAccessoryHeightSupplier.set(keyboardAccessoryHeight);
Loading diff…

Original Bug Report

reported by [email protected]

When in split-view mode, the mini address bar does not appear above the virtual keyboard, leading to a spoof.

VULNERABILITY DETAILS This vulnerability is similar to https://issues.chromium.org/issues/439262604 (iOS version), but this bug occurs on the Android version. When in split-view mode, the mini address bar does not appear above the virtual keyboard.

VERSION Chrome Version: [143.0.7472.0] + [Canary] Operating System: Android 16 Device: Samsung S25 Edge

REPRODUCTION CASE

  1. Open https://you-can-billowy-nimble-login-secure-docs-google-source-attacker.com/spoofnewxiov.html or open spoofnewxiov.html on a local web server using the https:// protocol and open it in split-view mode.
  2. Click on the “google” link.
View on issue tracker