Aligns brave:// with chrome:// in IntentHandler.intentHasUnsafeInternalScheme.
The upstream guard is unaware of the Brave alias because the brave:// →
chrome:// rewrite happens after the intent layer.
BraveIntentHandlerClassAdapter redirects the upstream call site through
BraveIntentHandler.intentHasUnsafeInternalScheme. The Brave method defers to
upstream first, then additionally rejects brave:// under the same category
guard upstream uses. A new BraveIntentHandlerInternal helper holds the
bytecode stub used to back-call the (private) upstream method.
Resolves: https://github.com/brave/brave-browser/issues/55473
Now it is NullableObservableSupplier, missed old change
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/416a61c418c152a7a7ae568d89302e5ecb6e4a3d
commit 416a61c418c152a7a7ae568d89302e5ecb6e4a3d
Author: Andrew Grieve <agrieve@chromium.org>
Date: Tue Dec 2 14:13:59 2025 -0800
Android: Split ObservableSupplier into Nullable / Monotonic / NonNull variants
The goal is to use proper @Nullable annotations with
ObservableSuppliers.
To achieve this, we use interfaces that define nullness:
* (Settable)NullableObservableSupplier
* (Settable)ObservableSupplier <-- monotonic
* (Settable)NonNullObservableSupplier
And we have ObservableSupplierImpl implement all of them.
In order to make this migration manageable, I've marked the interfaces
as @NullUnmarked, and will fix annotations in batches until they
can be marked @NullMarked.
This CL includes a batch in order to test out the new interfaces (and
because many were necessary to make the change).
Monotonic suppliers are by far the most common afaict, so that's why
the non-prefixed ObservableSupplier is the monotonic one (that, and
because "Monotonic" is a mouthful).
One implication of this approach is that we'll never have:
ObservableSupplier<@Nullable Foo>
We'd have instead:
NullableObservableSupplier<Foo>
Having the nullness in the interface rather than in the generic
allows for defining toNonNull() only on monotonic suppliers, and
simplifies the implementation.
Bug: 455874046
Change-Id: Id48e235b9ff16a5b21a9c1199863150d17c22736
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7206746
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Owners-Override: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1553094}
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/f85df3955cb3bcc7d90cf0af71458e5cad9d45cc
1. NewTabPage.initializeMainView renamed to
initializeFeedSurfaceProvider
2. Some code from NewTabPage.initializeMainView
was moved to c-tor
commit f85df3955cb3bcc7d90cf0af71458e5cad9d45cc
Author: Xi Han <hanxi@google.com>
Date: Mon Mar 30 09:06:59 2026 -0700
[NtpRefactor] Polish NewTabPageCoordinator.
1. Move several parameters passed in NewTabPageCoordinator#initialize()
to the constructor. This allows to set multiple member variables as
final variables.
2. Add missing @Nullable to member variables and add null check in
code for them. This includes: mSearchBoxCoorinator, mUiConfig etc.
3. Re-arange the sequencings in #destroy(): the last created object is
destroyed first.
Bug: 487641528
Change-Id: I935e3aee111a6fd816a228f004f7b1d9663d03d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7709015
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Commit-Queue: Xi Han <hanxi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1607137}
- isOpenInOtherWindowSupported removed;
- isLinkNavigationToNewWindowSupported added;
- isLinkNavigationToIncognitoWindowSupported added.
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/8ebbccb8137c4b44999c92edfb971e821d9365ba
commit 8ebbccb8137c4b44999c92edfb971e821d9365ba
Author: Aishwarya Rajesh <aishwaryarj@google.com>
Date: Mon Mar 30 11:44:27 2026 -0700
Update conditions for "Move to other window" / "Move to new window"
visibility on context menus for link navigation
The CL creates / updates utility methods in MultiWindowUtils to
determine when these options are shown on a link context menu per latest
recommendations:
- Open in new window
- Open in Incognito window
- Open in other window
The updates in this CL ensure that either "Open in new window" or "Open
in other window" (not both) are visible on the menu. Both options will
invoke the same codepath currently, this will be updated in fast-follow
CLs.
Bug: 475571336
Change-Id: I33a597703e634a7d5cd2d6b66c4c2ca9254374ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7680970
Reviewed-by: Jinsuk Kim <jinsukkim@chromium.org>
Reviewed-by: Sirisha Kavuluru <skavuluru@google.com>
Commit-Queue: Aishwarya Rajesh <aishwaryarj@google.com>
Reviewed-by: Shu Yang <shuyng@google.com>
Cr-Commit-Position: refs/heads/main@{#1607263}
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/040e46a7c7697d0eb32e58b30a39e9822d045d81
commit 040e46a7c7697d0eb32e58b30a39e9822d045d81
Author: Xi Han <hanxi@google.com>
Date: Wed Mar 11 18:33:45 2026 -0700
[NtpRefactor] Split NewTabPageLayout into NewTabPageCoordinator and
layout.
This is a refactor CL without any behavior changes. In this CL:
1. Split major logic from NewTabPageLayout to NewTabPageCoordinator,
only Layout implementations remains in the NewTabPageLayout;
2. To preserve the renaming history, temporarily renaming
NewTabPageLayout to NtpLayout. We will rename back in follow up CL
https://crrev.com/c/7658503.
Design doc: go/ntp-mvc-refactor.
Bug: 487641528
Bypass-Check-License: NewTabPageCoordinator is a renamed from NewTabPageLayout.
Change-Id: Ief8fd9b048696a875ccd8167421d88ad2e667f04
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7658403
Commit-Queue: Xi Han <hanxi@chromium.org>
Reviewed-by: Xinyi Ji <xinyiji@chromium.org>
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1598132}
* [Android] Fixed containment at settings
Resolves https://github.com/brave/brave-browser/issues/54164
* Fixed containment for the Homepage settings screen
* Fixed containment for WebRTC policy screen
* Fixed containment at Languages settings; modified SettingsUtils.getVisiblePreferences
* Fixed privacy item
* Fixed containment for NFT discovery learn more preference
Replaced TextMessagePreference (BackgroundStyle.NONE, transparent) with
ChromeBasePreference so the NFT description groups with the Enable NFT
discovery toggle in one card. Follows the same camera OS-warning pattern:
ForegroundColorSpan for the link color, setOnPreferenceClickListener for
the tap action, matching Chromium upstream conventions.
* Moved NFT discovery block before Reset wallet preference
Enable NFT discovery toggle and its description now appear above
"Reset and clear wallet data", matching the intended UX order.
* Fixed containment for Brave Firewall + VPN settings
Set initial visibility of server_change_location in onCreatePreferences
to avoid animated removal artifact. Call notifyPreferencesUpdated() after
dynamic visibility changes in updateSummaries so containment styles stay
in sync with adapter positions.
* Fixed containment for New Tab Page settings learn more
Replaced ClickableSpansTextMessagePreference with ChromeBasePreference
for the sponsored images learn more link so it groups into the
Background Images card with the toggles above it.
* Removed On/Off captions from New Tab Page switch prefs
* [Android] Move tab switcher controls to bottom when address bar is at bottom
When the address bar is configured to show at the bottom, reposition the
entire hub toolbar (new tab, menu, pane switcher, search, shred) from
the top to the bottom of the tab switcher for one-handed accessibility.
- BraveHubManagerImpl: Add maybeRepositionToolbarToBottom() that changes
the toolbar wrapper's FrameLayout gravity to BOTTOM and swaps the pane
host container's top margin to bottom margin. Uses EdgeToEdge pad
adjuster (same pattern as upstream HubBottomToolbarCoordinator) to
handle navigation bar insets. Properly cleans up the adjuster on hub
hide since the coordinator and views are destroyed between show/hide
cycles.
- BraveHubManagerImplClassAdapter: Expose parent's mEdgeToEdgeSupplier
field via deleteField/makeProtectedField bytecode pattern.
- BraveToolbarManager: Remove setLayoutStateProvider() and its
LayoutStateObserver that toggled menu popup direction on tab switcher
transitions. No longer needed since the hub toolbar is now at the
bottom when address bar is at bottom.
- BraveHubToolbarView: Change INVISIBLE to GONE for hidden action/menu
buttons when bottom navigation controls are enabled (address bar on
top). INVISIBLE left the buttons clickable despite being hidden.
Resolves: https://github.com/brave/brave-browser/issues/53326
* [Android] Fix autofill toggle greyed out when Google is the system autofill service
When Google's Autofill with Google (AWG) is set as the preferred autofill
service in Android OS settings, Chromium disables the third-party autofill
toggle in Settings because Chrome has its own built-in Google-synced
autofill. Since Brave does not have built-in Google autofill, AWG should
be treated like any other third-party provider (e.g. 1Password, Bitwarden).
This fix has two parts:
Java side: Override AutofillClientProviderUtils.getAndroidAutofillFramework-
Availability() via bytecode changeMethodOwner to remap the
ANDROID_AUTOFILL_SERVICE_IS_GOOGLE status to AVAILABLE or SETTING_TURNED_OFF
based on the user's existing pref. This makes the toggle interactive in the
Settings UI.
Native side: The C++ code calls the Java method via JNI, bypassing the
bytecode redirect. To handle this, BraveAutofillClientProviderUtils is
annotated with @CalledByNative to generate its own JNI header. A chromium_src
override of autofill_client_provider.cc uses #define to redirect the original
JNI function to the Brave version, ensuring the native code also uses the
remapped availability status and doesn't reset the pref on browser startup.
Resolves: https://github.com/brave/brave-browser/issues/52960
* [Android][cr146] Put url into url bar after QR scan
This commit brings back pre-cr146 behaviour
on scanning QR codes with url - url text now
is at the url bar and selected again.
Resolves https://github.com/brave/brave-browser/issues/53318
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/23c8fddd48102899160ce4d71b1ab1949c88a248
[Theme] Add NtpCustomizationPolicyManager.
In this CL, we add NtpCustomizationPolicyManager which listens to
Pref.NTP_CUSTOM_BACKGROUND_DICT changes.
1) Pref.NTP_CUSTOM_BACKGROUND_DICT being managed means the
policy::key::NTPCustomBackgroundEnabled is disabled.
2) When the policy NTPCustomBackgroundEnabled changes,
NtpCustomizationPolicyManager saves the latest policy value to the
shared preference. It will apply after relaunch chrome. This allows
the UI correct when CTA isn't recreated.
Demo: http://shortn/_nBBqRNFS3N
Bug: 467029432
Change-Id: I04a50d0d814802fbd3ef8be29414a17181adae98
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7500251
BraveNewTabPageLayout.setSearchProviderTopMargin and
BraveNewTabPageLayout.setSearchProviderBottomMargin methods were removed at
https://github.com/brave/brave-core/commit/798973641caa39762bae9dff9d2866c7185ce6c8
but class adapter/bytecode
Chromium commit below is the commit which caused our bytecode test
to fail, because was renamed
setSearchProviderBottomMargin => setLogoViewBottomMargin .
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/9b284825edfb4cea09d686dac7456517c1e8b96e
[Composeplate] Fix composeplate view visibility issue.
There are 3 issues of the existing NTP:
1) When DSE is changed between Google and 3P, the return value of
ComposeplateUtils.isComposeplateEnabled(mIsTablet, profile)
changes, but we didn't recalculate it. It causes the bug that
composeplate view button doesn't show again for Google -> 3p ->
Google.
2) If Chrome starts with 3p DSE, ComposeplateCoornidator won't be
initialized at all. Switching to Google won't make it visible.
3) When switching from Google -> 3p, search box's height doesn't reduce
from 72dp to 64dp.
In this CL, we resolve the above 3 issues:
1) When DSE is changed, initialize ComposeplateCoornidator if hasn't
yet; updates the buttons' visibility.
2) Changes the search box height inside NTP, not in
SaerchBoxContainerView. The height is determined by whether
composeplate is enabled, as well as whether a shadow is added.
3) Polish the initialization process of NTP layout to prevent calling
same function multiple times.
Demo: http://shortn/_vdN9koVnsu
Bug: 474426974
Change-Id: I3a16e56e655465d36184204657626f2bb7c92f24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7487954
Override DownloadLocationDialogCoordinator to force the download
location dialog even on single-directory devices (no SD card).
Upstream skips the dialog when only one storage directory is
available; the Brave override intercepts that skip and re-triggers
the dialog display. Also transitions SHOW_INITIAL to SHOW_PREFERENCE
so the "Don't show again" checkbox starts unchecked, preventing the
feature from silently disabling itself after the first use.
Resolves: https://github.com/brave/brave-browser/issues/52737
Pass a temporary no-op HomeSurfaceTracker when mHomeSurfaceTracker is
null during warm startup to prevent the NPE in upstream's
setInitialOverviewStateOnResumeWithNtp. This can happen on activity
recreate (rotation, process death, foldable transitions) where
onResumeWithNative fires before the tracker is initialized.
Resolves: https://github.com/brave/brave-browser/issues/53071
[Android] Fixes a crash in FaviconUtils.getIconDrawableWithFilter
when an icon is not available for a particular URL by falling back
to the default globe icon.
Resolves: https://github.com/brave/brave-browser/issues/52458
Resets the overflow main menu to the top every time is shown. Modifications are applied using bytecode manipulations as we needed to modify upstream class `AppMenuHandlerImpl`.
[Android] Adds kBraveFreshNtpAfterIdleExpirement experiment flag.
That commit adds the flag with parameters and a functionality
to use cached flags on Android.
Resolves: https://github.com/brave/brave-browser/issues/50567
Chromium changes:
https://chromium.googlesource.com/chromium/src/+/a11ac5d97f40076f5d1502084c6ef8972cff2a22
commit a11ac5d97f40076f5d1502084c6ef8972cff2a22
Author: Samuel Huang <huangs@chromium.org>
Date: Thu Oct 2 12:00:50 2025 -0700
[MVT] Fix MVT container sizing and centering on Tablets.
By "blocks" we include MVT tiles and the "Add now" button.
On Tablets, blocks and its container have special behavior:
1. Depending on **initial** block count, these render in modes:
* Centered: With "few" blocks present: The container is WRAP_CONTENT,
and "edge margins" (outer margin of outer blocks) expanded so blocks
are centered and immobile.
* Overflowed: With "many" blocks present: The container is
MATCH_PARENT, and "edge margins" are assigned a fixed value. The
blocks become scrollable.
2. When changing from "many" blocks to "few" blocks, the Overflowed
state remains. In this case, blocks no longer scroll, and are start-
aligned instead of centered.
(2) was intentional, presumably to reduce tiles "jumping" on repeated
tile removal. NewTabPageLayout (for container) and TilesLinearLayout
(for "edge margins") implemented this by doing the following:
* Store initial tile count and block count.
* Use these counts and width constants to compute "content width".
* If "content width" <= "container" size then Centered (AKA "full
filled", "all filled"); else Overflowed.
Now, MVT on tablets has some longstanding oddities
O1. When Centered, the container might not reach full width.
O2. Container may shrink on repeated tile removal (and centered) --
this is a cross between Centered (re. WRAP_CONTENT) and Overflowed
(re. fixed "edge margin") modes.
O3. When changing from "few" blocks to "many" blocks (by adding Custom
Tiles), Overflow mode does kick in sometimes, leading to blocks
appearing off-screen but cannot be scrolled to.
This CL fixes the oddities and removes behavior (2); now Centered and
Overflowed behavior depends on **current** (instead of the initial)
block count -- this fixes (O3). High level changes:
* Stop storing initial tile and block counts.
* Centralize Centered / Overflowed decision, including "content width"
computation, to MostVisitedTilesLayout.
* Change MVT child addition semantics from {Tile, non-Tile} to
{Tile, Divider, UI View (for the "Add new" button)}.
Bugs that were found and fixed:
* The duplicated Centered / Overflowed decision logic were inconsistent;
the NewTabPageLayout version (for WRAP_CONTENT / MATCH_PARENT) didn't
account for Custom Tile changes, i.e., divider & "Add new" button.
This led to (O2), and is fixed when we dedup the logic.
* When "divider gap" was changed to same as "tile gap" in
crrev.com/c/6780677 , we didn't update "content width" calculation.
This also led to (O2), and is fixed by having dividers not contribute
to "content width".
* Resources.getDimension() returns (float) PX value, and NOT DP. The
misunderstanding led to explicit conversions that made the width of
the "Add new" too large (TileRenderer.renderTileSection()). This led
to (O1). Fixing this also simplified code.
Bug: 447086773, 388782412
Change-Id: Id1400e672f1f0be11b4cc218cd20521988c3455f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7004884
Commit-Queue: Samuel Huang <huangs@chromium.org>
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Xi Han <hanxi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1524365}
Requres to adjust proguard flags for bytecode tests
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/2747c27c571886bc1a646c4ab9eb1fa46c4b29fd
Use event-driven supplier for fulfillment type
Replace the polling-based `isUsingAiMode()` method with an event-driven
`ObservableSupplier` that reports the `NavigationFulfillmentType`.
This refactoring allows consumers like the LocationBar and Autocomplete
systems to react dynamically to changes in the fulfillment mode (e.g.,
switching between DEFAULT and AI_MODE) without needing to continuously
poll for the current state.
As a direct benefit, the LocationBar now observes this supplier to
hide the Lens button when the fulfillment type is AI_MODE, ensuring
the UI accurately reflects the available actions.
Bug: 436888404
Change-Id: Iae4df3f4fc6f5d2e298765a823b3ad61aa9f1512
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6943716
* [Android] Update header image for quick shortcuts and optimization
Optimizations done:
- Initialize leo and wallet controllers regardless if feature enabled or not. This is because at this point native is not guaranteed to be initialized to check the feature. Check for option visibility is done in `BraveRadioButtonGroupAdaptiveToolbarPreference` instead.
- Override `buildUiStateForStats` to avoid asserts on Brave specific options.
* Fix for tests
* Fix for JUnit tests
Chromium changes:
https://chromium.googlesource.com/chromium/src/+/09316976243447de4c0b3979b3c00c747792fa98
commit 09316976243447de4c0b3979b3c00c747792fa98
Author: Hitarth Kothari <hitarthkothari@google.com>
Date: Tue Aug 12 13:48:48 2025 -0700
Consolidate single-tab reparenting into multi-tab methods.
This change renames `ReparentingMultiTabTask` to `ReparentingTabsTask`
and updates its `begin` method to accept additional parameters. All
instances of moving a single tab are now handled by the
`moveTabsToWindow` and `moveTabsToNewWindow` methods by passing a
`Collections.singletonList` containing the single tab. This removes
redundant single-tab reparenting methods from `MultiInstanceManager` and
its implementations.
Bug: 432819744
Change-Id: I03394cbd3ae0f9afb49065d40a4271c2adcbc78e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6841517
Auto-Submit: Hitarth Kothari <hitarthkothari@google.com>
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1500399}
* [Android] Initial integration of Brave adaptive buttons
The Bookmarks button is the first in the list; the rest of the buttons will be added in separate PRs.
Important notes:
- override via `chromium_src` doesn't work for `patches/chrome-browser-ui-android-toolbar-adaptive_toolbar_enums.h.patch` since this file is parsed by `java_cpp_enum.py` to convert it to java enum
- patch to `java_cpp_enum.py` was added to be able to do 1 line patch, since upsteam parses each value as a separate line
- in `patches/chrome-browser-ui-android-toolbar-adaptive_toolbar_enums.h.patch` were added values for all planned Brave buttons to avoid additional patching for each consecutive PR
* Python patch optimisations
* Presubmit fixes
* Remove python patch in favour of multiline header patch