[VPN 2.0] Split BraveVpnService into interface and implementation
To add a new BraveVpnService implementation based on Architecture 2.0,
which must co-exist with Architecture 1.0 for quite a while, we need
to split service's interface and implementation. All the external
components will keep accessing VPN service via the BraveVpnService
interface, but the implementation mostly goes into BraveVpnServiceImpl.
BraveVpnService is a concrete base that implements bookkeeping shared
by both architectures: mojo remote creation and observer management.
The lion's share of functionality is kept in the implementation; if
it becomes duplicated eventually, we can move it to the base later.
This change is a preparatory step to introduce the second (Arch 2.0)
implementation of BraveVPNServiceImpl, which could be selected at
compile time, or (later) at runtime too.
Other notable changes:
- Revised and moved the public VPN service API to BraveVpnService.
- BraveVpnService base is comprehensively covered by unit tests.
- Removed a BraveVpnMetrics::Delegate method dependency in external
components.
- BraveVPNServiceTest test fixture renamed to
BraveVpnServiceImplV1Test.
Implements part of brave/brave-browser#54597
To add a new BraveVPNService implementation based on Architecture 2.0,
which must co-exist with Architecture 1.0 for quite a while, we need
to split service's interface and implementation. All the external
components will keep accessing VPN service via the BraveVPNService
interface, but the implementation mostly goes into BraveVPNServiceImpl.
This is the first step: renaming the existing service, to minimize
diffs in the next PR, where the concrete base class appears.
No changes in the business logic, pure renaming.
Implements part of https://github.com/brave/brave-browser/issues/54597
* Gate Playlist UI on BravePlaylistEnabled policy
Complements #35732, which hides Playlist via the enable_playlist buildflag
in is_brave_origin_branded=true builds, by also hiding the Playlist UI in
is_brave_origin_branded=false builds when an administrator disables it
via the BravePlaylistEnabled policy (kPlaylistEnabledPref managed=false).
Adds playlist::IsPlaylistEnabled(prefs) / IsDisabledByPolicy(prefs)
helpers alongside existing features.h / pref_names.h, mirroring the iOS
PrefService.isPlaylistAvailable check and the ai_chat::IsAIChatEnabled
pattern. The helper is used to gate the sidebar item, side panel
coordinator and entry, browser action, playlist command, tab helper,
page action icon, and the chrome-untrusted://playlist WebUI.
The SidebarService now observes kPlaylistEnabledPref so the item appears
and disappears when policy changes at runtime.
User-driven pref toggles from settings keep their existing behaviour
(UI stays reachable so the user can flip the pref back); only a managed
pref forced off hides the UI.
Fixesbrave/brave-browser#50156
* Address review: move IsPlaylistAllowed out of common, simplify settings bools
- Relocate playlist::IsPlaylistEnabled from components/playlist/core/common
(which is reachable from any process) to a new components/playlist/core/browser
target, since the helper depends on PrefService (browser-only). Rename the
function to IsPlaylistAllowed to match its semantics (feature flag is enabled
and the pref is not policy-disabled), matching bridiver's suggestion that
"allowed" = managed+feature, "enabled" = user toggle.
- Update all callers and BUILD/DEPS wiring for the new location.
- In brave_settings_ui.cc, stop combining the feature flag and the user pref
into a single isPlaylistAllowed loadTimeData bool. Instead expose
isPlaylistFeatureEnabled and isPlaylistDisabledByPolicy (the Tor pattern),
and let settings page code consult the pref directly via the prefs mixin
when it needs the managed state. page_visibility.ts now computes playlist
visibility from the two building blocks.
Introduces enable_playlist (defaults to !is_brave_origin_branded),
following the same pattern as enable_brave_wallet and enable_ai_chat,
to gate all Playlist code from compilation on origin-branded desktop
builds. enable_playlist_webui now chains through enable_playlist.
Changes are scoped to desktop: iOS and Android don't support
is_brave_origin_branded=true (enforced by asserts in
//brave/components/brave_origin/buildflags/buildflags.gni), so they
have no guards.
This was discovered due to the following upstream tests failing:
* BrowserCommandControllerBrowserTest.DisableFind
* PrintPreviewBrowserTest.PrintCommands
Chromium change:
https://source.chromium.org/chromium/chromium/src/+/73da2407154e4fbb573ae8909dfb639daef2691b
commit 73da2407154e4fbb573ae8909dfb639daef2691b
Author: Steven Luong <stluong@chromium.org>
Date: Thu Feb 12 09:50:10 2026 -0800
[TabRendererData] Remove TabStripModel::OnTabBlockedStateChange()
Consolidate the tab blocked state to be another tab change type. This
is needed to eventually move all tab change related code out of the
TabStripModel.
Fixed: 483478261
Resolvesbrave/brave-browser#53601
Enables macOS immersive fullscreen (auto-hiding toolbar on hover) for the browser
when horizontal tabs are in use. When vertical tabs are active, immersive fullscreen
is disabled and the browser falls back to standard fullscreen behavior. Additionally,
switching to vertical tab mode is blocked while the browser is in fullscreen.
Immersive fullscreen and vertical tab mode both use their own separate widgets for
hosting the tab strip, which means both refer to the same tab strip simultaneously.
This conflict requires more work to resolve properly, so immersive fullscreen is
disabled when vertical tabs are active for now.
IDC_TOGGLE_VERTICAL_TABS command enabled state is used as the single source of truth
for whether the vertical tabs toggle is available. BraveBrowserCommandController
overrides UpdateCommandsForFullscreenMode() to disable this command on macOS when
entering fullscreen. All surfaces — ToggleVerticalTabStrip(), the tab strip context
menu, the system menu, IsVerticalTabToggleEnabled(), and the settings page — derive
their state from this command rather than querying fullscreen state independently.
BraveAppearanceHandler implements CommandObserver to watch IDC_TOGGLE_VERTICAL_TABS
and push state changes to the settings UI via a WebUI event.
TEST=BraveBrowserCommandControllerTest.VerticalTabToggleEnabledState
Co-authored-by: Sangwoo Ko <sangwoo108@gmail.com>
This change in upstream has affected several places where these methods
were being extended. Most changes involve now using `TabInterface`,
rather than `WebContents`.
Chromium changes:
https://chromium.googlesource.com/chromium/src/+/fdb26aae9fcf18a4065d95f88da9677b71ed6512
commit fdb26aae9fcf18a4065d95f88da9677b71ed6512
Author: Eshwar Stalin <estalin@chromium.org>
Date: Tue Dec 30 15:57:18 2025 -0800
Updating TabStripModel observer methods for consistency
Renaming some of the functions for consistency. Also switching some of
the functions from using content::WebContents to tabs::TabInterface to better align with the long term direction.
Change-Id: I3b3cf44f02ed6036282adb132fcfe204853d8a13
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7350719
Commit-Queue: Eshwar Stalin <estalin@chromium.org>
Reviewed-by: David Pennington <dpenning@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1563530}
Implement the Email Aliases menu item in the application menu at
Hamburger menu > Passwords and Autofill > Email Aliases.
This menu item is only visible when the EmailAliases flag is enabled.
When the user clicks on this item, the Email Aliases settings page
opens at brave://settings/email-aliases
Similar to other menu items in the application menu, this menu item
includes an icon for Email Aliases service.
Two browser tests:
- EmailAliasesMenuInsertion
- EmailAliasesOpensSettings
Co-authored-by: boocmp <boocmp@yandex.ru>
* Add enable_brave_wallet GN variable and build flag
This adds a new GN build flag 'enable_brave_wallet' that can be set to
false to exclude Brave Wallet from the build. The flag is true by default
to maintain current behavior.
Changes include:
- Add enable_brave_wallet declare_args in build/config/BUILDCONFIG.gn
- Create brave_wallet/common/buildflags with ENABLE_BRAVE_WALLET flag
- Update all BUILD.gn and sources.gni files to use the new flag
- Add wallet buildflags dependencies via minimal one-line imports
* Add patches for wallet buildflags in Chromium BUILD files
Adds minimal one-line patches to import wallet buildflags dependencies
in Chromium source files. This allows Chromium code to conditionally
depend on wallet headers.
Patches:
- chrome/browser/ui/hid/BUILD.gn
- net/BUILD.gn
- third_party/blink/common/BUILD.gn
- third_party/blink/public/common/BUILD.gn
- third_party/blink/renderer/modules/permissions/BUILD.gn
* Guard wallet code in Chromium source overrides
Updates chromium_src overrides to conditionally compile wallet-related
code based on enable_brave_wallet flag. This includes:
- Adding DEPS files to allow buildflags dependencies
- Guarding wallet permission handling with #if BUILDFLAG(ENABLE_BRAVE_WALLET)
- Keeping wallet permission enum values unconditionally to maintain profile
interchangeability between wallet-enabled and wallet-disabled builds
- Updating component registration and preference handling
Key changes:
- Permission enums remain stable across build configs for UMA and persistence
- Wallet permission handling code only compiled when wallet enabled
- DEPS files updated to allow buildflags includes
* Guard wallet UI code in front-end TypeScript and Mojom
Conditionally compiles wallet-related UI code in TypeScript and Mojom
interfaces based on enable_brave_wallet preprocessor flag.
Changes:
- Settings menu: Use lastInserted pattern for menu item ordering
- Page visibility: Guard wallet page visibility checks
- Browser commands: Guard wallet command handling
- Routes: Conditionally include wallet routes
- Add non-null assertions for DOM insertions in TypeScript
- Update Mojom interfaces to conditionally include wallet enums
Front-end code uses <if expr="enable_brave_wallet"> preprocessor
directives to exclude wallet UI when the feature is disabled.
* Guard wallet usage in non-wallet Brave code
Conditionally compiles wallet-related code in non-wallet Brave files
based on enable_brave_wallet build flag.
Changes include:
- browser/: Guard wallet service factories, preferences, and helpers
- components/: Guard wallet dependencies in rewards, sidebar, and DNS
- renderer/: Conditionally register wallet content settings
- utility/: Guard wallet component registration
- ios/: Add optional chaining for wallet feature flags
- test/: Guard wallet-related test code
Key files:
- brave_stats_updater.cc: Guard wallet pref registration with #if
- brave_profile_prefs.cc: Conditionally register wallet preferences
- sidebar_service.cc: Guard wallet panel items
- iOS WalletConstants.swift: Use optional chaining for feature checks
This allows building Brave without wallet while maintaining profile
compatibility between wallet-enabled and wallet-disabled builds.
* Add static_assert for ENABLE_BRAVE_WALLET in wallet headers
Adds compile-time assertions to wallet headers to ensure they are only
included when wallet is enabled. This prevents accidental usage of wallet
APIs when enable_brave_wallet=false.
Added static_assert(BUILDFLAG(ENABLE_BRAVE_WALLET)) to:
browser/brave_wallet/ (11 files):
- asset_ratio_service_factory.h
- brave_wallet_context_utils.h
- brave_wallet_ipfs_service_factory.h
- brave_wallet_provider_delegate_impl.h
- brave_wallet_service_factory.h
- brave_wallet_tab_helper.h
- meld_integration_service_factory.h
- wallet_notification_service_factory.h
- simulation_service_factory.h
- swap_service_factory.h
- wallet_data_files_installer_delegate_impl.h
components/brave_wallet/browser/ (15 files):
- brave_wallet_p3a_private.h
- brave_wallet_prefs.h
- brave_wallet_service.h
- brave_wallet_utils.h
- ens_resolver_task.h
- json_rpc_service_test_utils.h
- json_rpc_service.h
- keyring_service_observer_base.h
- keyring_service.h
- network_manager.h
- permission_utils.h
- pref_names.h
- test_utils.h
- tx_service.h
- wallet_data_files_installer.h
components/brave_wallet/common/ (6 files):
- brave_wallet_types.h
- common_utils.h
- eth_abi_utils.h
- features.h
- hex_utils.h
- pref_names.h
Also includes minor wallet code updates to use buildflags and
guard zcash-specific test code.
* Follow up fixes after Parts 1-7
* Add AI Chat build flag to components/ai_chat
* Add AI Chat build flag to browser/ui
* Add AI Chat build flag to browser/resources
* Add AI Chat build flag to chromium overrides
* Add AI Chat build flag to other components
* Add AI Chat build flag to core browser files
* Add AI Chat build flag to app and renderer
* Add AI Chat build flag to remaining files
* Set enable_ai_chat to !is_brave_origin_branded
* Review comments
Including gn_check errors in chromium_src
* Exclude ai_chat Jest tests when not enabled
Resolvesbrave/brave-browser#50260
Deleted whole BraveSplitView feature implementation
as our split view feature is based on SideBySide.
No behavioral changes as it's already disabled by default.
- Everything in `browser` moves to `content/browser`
- Everything in `renderer` moves to `content/renderer`
- Everything in `common` moves to `core/common`
- `pref_names.h` moved into `core/common`
- Fixed copyright notice in `playlistSelect.tsx`
Rename pref/features to try to make them more clear. `Enable` means that the site will open in Speedreader automatically. `Allow` means it may open in Speedreader depending on whether it's a site specific override or allow for all readable urls is true and the url looks readable.
This change removes our own verticle toggle constant, as this was
conflicting with the upstream one.
Chromium changes:
https://chromium.googlesource.com/chromium/src/+/4851fb185d0d297ed313bd379fb42d5ef0c3cbca
commit 4851fb185d0d297ed313bd379fb42d5ef0c3cbca
Author: Kunal Daftari <kunaldaftari@google.com>
Date: Wed Aug 27 14:02:37 2025 -0700
Vertical Tabs: Entry Point (Switch Tabs to Side Button + Interactive UI Test)
The following CL includes the addition of a "switch tabs to the side"
button in the tab strip context menu. Currently, the button is able to
switch from the horizontal interface to the vertical one. The goal of
the interactive UI Test is to click the "switch tabs button" and to
check that the UI properly updated.
NO_IFTTT=linter is not applicable
Bug: 439587928
Change-Id: Idee393d910bca74c905a3c31c86b4b3b768d2507
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6871202
Reviewed-by: David Pennington <dpenning@chromium.org>
Commit-Queue: Kunal Daftari <kunaldaftari@google.com>
Reviewed-by: Darryl James <dljames@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1507360}
This class is overriden in Brave, and therefore requires a substitution
during instantiation. This substitution has moved from `Browser` and
into `BrowserWindowFeatures`.
Chromium changes:
https://chromium.googlesource.com/chromium/src/+/58bd9542429a22cf1ce4b8913933a22e69de7284
commit 58bd9542429a22cf1ce4b8913933a22e69de7284
Author: Alex Carutasu <alcaruta@microsoft.com>
Date: Tue Jul 29 16:56:25 2025 -0700
[bedrock] Migrate BrowserCommandController to BrowserWindowFeatures
This CL moves BrowserCommandController ownership from Browser to
BrowserWindowFeatures.
Notes:
- BrowserCommandController is now destroyed during the destruction of
BrowserWindowFeatures, so resetting the BrowserCommandController field
manually in its owner's destructor is no longer necessary since
~Browser()'s body already explicitly resets BrowserWindowFeatures.
- I also removed a couple stale friended test classes from browser.h
that were related to BrowserCommandController.
Bug: 431668289
Change-Id: I08df68363b64e03331708341081cace90aa2a60b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6785957
Reviewed-by: Tom Lukaszewicz <tluk@chromium.org>
Reviewed-by: Keren Zhu <kerenzhu@chromium.org>
Commit-Queue: Alex Carutasu <alcaruta@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1493873}
fixbrave/internal#1337
SplitView observes FullscreenController but it's destroyed before than SplitView destruction.
It's lifecycle is changed in upstream(cr139). BrowserWindowFeatures tears down exclusive acceess manager that owns fullscreen controller at the start of BrowserView dtor.
As SplitView is FullscreenControllerObser, it should be cleaned up before fullscreen controller is gone.
As this PR destroys SplitViewBrowserData at the start of BrowserView dtor, added its null check at all places.
fixbrave/brave-browser#46492
Added SideBySide version of browser commands apis for split tabs.
Also handle our split view related command ids with SideBySide.
TEST=BraveBrowserCommandControllerWithSideBySideTest.SplitViewCommandsTest
* Disable SplitView feature when SideBySide is enabled
fix https://github.com/brave/brave-browser/issues/46089
This PR introduced tab::features::IsBraveSplitViewEnabled() and simply replace base::FeatureList::IsEnabled(tabs::features::kBraveSplitView) with it.
tab::features::IsBraveSplitViewEnabled() always gives false if SideBySide is enabled.
Some upstream tests were failed because both features are enabled.
In that situation, Brave can't run. All filtered upstream tests are added again.
We'll migrate our SplitView UX onto upstream's SideBySide feature.
* Make BrowserWindowFeatures own SplitViewBrowserData
fix https://github.com/brave/brave-browser/issues/44846
To initialize SplitViewBrowserData before starting UI initializaion,
it should be inititialized with Browser object.
Also SplitView is per-window features, BrowserWindowFeatures is
good owner for SplitViewBrowserData.
In `cxx20`, there is a new function in associative containers called
`contains`, which should be used as a replacement to `base::Contains`.
This reland makes use of a `base::flat_set<ContentGroup>` in one test,
as this was causing build failures on x86 builds, as the compiler would
not abide to evaluate `MakeFixedFlatSet` as `constexpr`.
Resolves https://github.com/brave/brave-browser/issues/44063
Introduces full-page UI. Requires the AIChatHistory feature flag to be enabled.
Receives title events for conversations from the conversation API.
---------
Co-authored-by: Taher <8665427+nullhook@users.noreply.github.com>
Co-authored-by: Jay Harris <jay.harris@outlook.co.nz>
All browser tests for this type are incurring in a null deref, as
`browser` was not being passed into the type. This fix corrects these
cases.
Additionally, this change removes the unnecessary checks in
`SplitViewBrowserData` for things like `tab_strip_model`, and
`tab_strip_model_adapter_`, as these should never be nullable in this
class' logic.
https://github.com/brave/brave-browser/issues/41740