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
Removed noMvPlaceholderStub arg from MostVisitedTilesMediator.ctor
Removed MostVisitedTilesMediator.updateTilePlaceholderVisibility
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/d67f572a5aa967e71a3fa5cbe8fd434be9933eb5
Delete Most Visited Tiles placeholder from NTP
This CL removes the "mv_tiles_placeholder_stub" view as it never
actually appears in the New Tab Page (NTP) UI.
The placeholder's visibility is set to View.VISIBLE when no tiles are
present. However, its parent, mv_tiles_container, is only visible if and
only if there are tiles to display. Consequently, if no tiles are
present, "mv_tiles_container"'s visibility is View.GONE, preventing its
child, "mv_tiles_placeholder_stub", from ever being rendered on the NTP.
This CL deletes all related placeholder logic from the view binder, view
properties, mediator, XML, PNG files, and tests.
Bug: 421436204
Change-Id: Iab3a2288a97dcfa2e7c137d5b1d6e7521a07176e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6771167
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/7211ad73ee02dd19c83cb64c27fca687a7ed8344
Add RedirectTabCreator
- Add int enum SupportedProfileType to ChromeTabbedActivity to determine
the type of tab/profile the activity supports.
- Add RedirectTabCreator to create new tabs in another window.
- Add method in MultiWindowUtils to get foreground CTA with matching
profile.
This change affects the "Open in incognito tab" option, which is
accessible from the web content context menu, the New Tab Page (NTP)
most visited tiles, and the NTP news feed.
When selected, content will open in an incognito tab as follows:
1. New Window: If there is no adjacent window, or if the adjacent
window is a regular (non-incognito) window.
2. Adjacent Window: If the adjacent window is already incognito.
Bug: 429518553
Change-Id: Ic3f1744dcfaf34cc87dc74c0ba5d72de7d2e5ced
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6720784
* [Android] Initial integration of quick shortcut button
- Adds flag for quick shortcut (disabled until all Brave items are available)
- Makes parity with options available with the upstream
- Visual and UI fixes
* Moves flag under Android guards
With Brave asm patching classes inheritence is
```
ChromeTabbedActivity extends BraveActivity
BraveActivity extends ChromeActivity
```
With a new argument at `ChromeTabbedActivity.onMenuOrKeyboardAction` line
`return super.onMenuOrKeyboardAction(id, fromMenu, triggeringMotion);` invoked
not BraveActivity's method but ChromeActivity's one.
This broke app menu and pull to refresh gesture.
Compiler didn't give any warnings, so I added a testcase.
Chromium changes:
https://source.chromium.org/chromium/chromium/src/+/34d6b8ab128e787fdbf4c8bcf93e23ece93c0aa0
Pass triggeringMotionEvent from AppMenu to onMenuOrKeyboardAction()
This CL is a no-op. It only changes method signatures.
Context:
* Tab closure will have different behavior depending on whether a click
came from a peripheral. For example, when using a peripheral to close
all tabs via the app menu, we don't want to show the "undo" snackbar.
* With http://crrev.com/c/6555582, we are able to obtain the
MotionEvent that triggered a click on an AppMenu item, so we can use
it to differentiate between peripheral clicks and other clicks.
* This CL passes the click-triggering MotionEvent from
AppMenuItemViewBinder to
MenuOrKeyboardActionController.onMenuOrKeyboardAction() where the
actual click-handling logic lives.
Similar work was done for the grid tab switcher:
http://crrev.com/c/6521282.
* The change involves a few interfaces. The code path is:
AppMenuItemViewBinder ->
[interface] AppMenuClickHandler.onItemClick() ->
[impl] AppMenu.onItemClick()
AppMenuHandlerImpl.onOptionsItemSelected() ->
[interface] AppMenuDelegate.onOptionsItemSelected ->
[impl] ChromeActivity.onOptionsItemSelected()
[impl] CustomTabActivity.onOptionsItemSelected()
[interface] MenuOrKeyboardActionController.onMenuOrKeyboardAction()
[impl] ChromeTabbedActivity.onMenuOrKeyboardAction()
[impl] ChromeActivity.onMenuOrKeyboardAction()
[impl] BaseCustomTabActivity.onMenuOrKeyboardAction()
[impl] CustomTabActivity.onMenuOrKeyboardAction()
[impl] WebappActivity.onMenuOrKeyboardAction()
This CL adds the click-triggering motion event as a parameter of the
methods above.
* To limit the scope of the CL, current interface methods are kept as
default implementation. For example:
```
public interface AppMenuClickHandler {
// Generally there's no need to override this method.
default void onItemClick(/* current params */) {
onItemClick(
/* current params */, /* triggeringMotionEvent= */ null);
}
// Implementations should always implement this method.
void onItemClick(
/* currentParams */, MotionEvent triggeringMotionEvent);
}
```
Bug: 375468032
Change-Id: I90019b2c02f54af6123280e4099c1b1dbcede585
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6557444
and
https://source.chromium.org/chromium/chromium/src/+/01b2bf1ec0c43a1924269c22c07ff7a2cbccb6d7
Consolidate how MotionEvent info is passed for tab closure
TL;DR:
* This CL is a no-op; it only changes method signatures.
* Reviewers: please follow the "Changes" section below to get a clearer
view of the changes.
Context:
We needed info from the MotionEvent that triggered a click to
differentiate between a peripheral click and other clicks so that tab
closure behavior can be customized. For example, we don't want to show
the undo snackbar when a tab is closed by a peripheral.
Multiple UI surfaces have been updated so far, and we used two ways to
pass MotionEvent info.
(1) For a View that has OnClickListener:
We attach an OnPeripheralClickListener to intercept MotionEvents
from peripherals, then pass the raw MotionEvent to the
click-handling logic.
(2) For a ListView that relies on OnItemClickListener instead of adding
OnClickListener to its individual child Views:
We use TouchTrackingListView to watch (but not intercept) touch
events and store the last relevant event as a state. Then, when
OnItemClickListener is triggered, a child View can query that state
to get motion info.
Since MotionEvent will be recycled by Android framework, the state
is in the form of a plain old data class containing motion info
(ListViewTouchInfo).
So far the UI surfaces are either (1) or (2) at compile time. However,
there is at least one place that are both (1) and (2) at compile time.
They become either (1) or (2) at runtime depending on the
usage/configuration. TabListEditorMenu is one example.
To better support such places, we need to consolidate how motion info is
passed for (1) and (2) so that the click-handling methods can have a
single signature:
* Instead of:
* handleClick(MotionEvent) // for (1)
* handleClick(ListViewTouchInfo) // for (2)
* It would be better to have:
* handleClick(MotionEventInfo) // for both (1) and (2)
Changes:
* Move ListViewTouchInfo out of ListViewTouchTracker, to
//browser_ui/util/motion/MotionEventInfo.
We will use this class to pass motion info around for both (1) and
(2).
* Update OnPeripheralClickListener to pass the new MotionEventInfo
object instead of a raw MotionEvent.
* The rest of the CL is to fix method signatures for the two changes
above.
Note:
Generally it's also safer to pass motion info as a data object instead
of using a raw MotionEvent since the correctness of the latter requires
the MotionEvent not to be recycled by the Android framework before it's
read.
Bug: 375468032
Change-Id: I19c0a468761403a7fa29d072e9b51ff73013dc5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6565526
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/55bc1473c10ac7470c2c2133d26d69c936bdc502
[Minimal UI] Add ThemeColorProvider for browser services
Adding a new ThemeColorProvider that targets browser services
primary color calculations based on the web app manifest and
Chrome default theme. It doesn't add anything new in color calculations
themselves, but rather extracts existing logic from
CustomTabColorController to share with other UI controls like web app
header.
Focused/unfocused primary color will be implemented in scope of
another task.
Bug: 396101424
Change-Id: I2ee3712725e9e1069a1e30c9dccbd33a4af8ce1b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6487756