[Origin] Gate BraveProfilePolicyProvider on BraveOriginPolicyManager init
`BraveProvider`'s first `RefreshPolicies` is triggered by
`AdBlockOnlyModePolicyManager` (initialised at process start), well before
`BraveOriginPolicyManager` (lazily initialised by `BraveOriginServiceFactory`)
is ready. The resulting bundle lacks `BraveRewardsDisabled`, but the
default `IsInitializationComplete` lets `PolicyService` report ready
anyway. `AdsServiceImpl::MaybeStartBatAdsService` then evaluates a stale
managed pref store and bat-ads starts despite the policy.
Override `IsInitializationComplete` to additionally gate on
`BraveOriginPolicyManager::IsInitialized()`. Upstream unit tests
(`ProfilePolicyConnectorTest`) bypass our factory bootstrap, so add a
`SetExpectedToBeInitialized` flag set from `BraveOriginServiceFactory`'s
ctor; the override short-circuits when unset (desktop/Android only --
iOS doesn't run those tests).
Resolves: https://github.com/brave/brave-browser/issues/54962
Caption button container on Windows was shifted upward (and had wrong height) in both default
and compact horizontal tab modes.
### Root cause
1. Wrong value in `GetLayoutConstantForBraveWindowControls. The TU-local `GetLayoutConstant`
wrapper returned `tabs::GetHorizontalTabControlsDelta()` for `kTabstripToolbarOverlap`. That value is negative
(−4 default, −5 compact) because it is intended to *center tab-strip control buttons* inside the tab strip.
For the caption button container, `kTabstripToolbarOverlap` is used to compute the **container height**, where
only a positive geometry value (1 default, 8 compact) is correct. Using the negative delta caused the container
to be too tall.
2. Extra negative Y-offset in `BraveBrowserFrameViewWin::LayoutCaptionButtons()`. After calling
`BrowserFrameViewWin::LayoutCaptionButtons()` (which already positions the container correctly),
we applied `SetY(y() + GetHorizontalTabControlsDelta())` — another negative nudge that shifted the
container upward, misaligning both its bottom (should touch the tab-strip top) and its top (should sit at
`WindowTopY()` below the window edge).
### Fix
- Remove `ScopedWinCaptionLayoutUsesGeometryTabstripOverlap`
- Simplify `GetLayoutConstantForBraveWindowControls` to always return
`::GetLayoutConstant(kTabstripToolbarOverlap)` — the correct geometry value in every window type
(normal, popup, PWA)
- Remove the `SetY` delta nudge** from `BraveBrowserFrameViewWin::LayoutCaptionButtons()`
- Update comments in the wrapper and in `brave_compact_horizontal_tabs_layout.h` to document the
distinction between the geometry value (this wrapper) and the controls centering delta
(`horizontal_tab_strip_region_view.cc`'s analogous wrapper).
### Test
Added `brave_browser_frame_view_win_browsertest.cc` (Windows only, parameterized over compact / default
horizontal tab mode) that asserts the two layout invariants for a normal browser window:
1. `container.bottom() == top_container.y()` — container bottom touches the tab/toolbar row top.
2. `container.y() == window.y() + frame->WindowTopY()` — container top sits at the non-client border below the window edge.
Resolves https://github.com/brave/brave-browser/issues/55406
* [Polkadot] Add parachains support
Add supportedKeyrings field to persist for NetworkInfo.
This is required since each polkadot keyring can have multiple
parachains.
Updated Deposit modal so showed address uses patachain ss58 prefix.
Resolves https://github.com/brave/brave-browser/issues/44750
When browser widget is inactive while application is active,
browser widget's WindowEventMonitor couldn't get event.
This can happen when overlay widget is focused in fullscreen mode on macOS.
Fixed by using application monitor.
Resolvesbrave/brave-browser#54300
Not added test code as it's difficult to simulate this scenario.
Constrain the dialog's minimum size to its initial dimensions
(540x500, 540x600 on Linux) so users cannot resize the window below
the designed layout.
Fixes https://github.com/brave/brave-browser/issues/55554
[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
* Added Gap between action buttons.
* Multi card subpage.
* Removed top delemiter in aliases list.
* Aliases presented within a boxed area.
* Fixed paddings.
Sidebar v2 attaches a Brave-styled panel header at the SidePanel level
instead of embedding it inside the content view.
## Changes
- New BraveSidePanelHeader (view) + BraveSidePanelHeaderController (delegate) under
brave/browser/ui/views/side_panel/. Visual spec (title, optional launch button + separator,
close button, 60px height, Nala colors, Leo icons) mirrors V1's inline headers in
BraveReadLaterSidePanelView/BraveBookmarksSidePanelView.
- BraveSidePanelCoordinator::PopulateSidePanel attaches the header via upstream
SidePanel::AddHeaderView only for entries ShouldShowBraveHeader allows (today: kReadingList, kBookmarks).
- SidePanel chromium_src override now wraps upstream AddHeaderView / RemoveHeaderView so each call also
re-runs Brave's UpdateBorder(). UpdateBorder() reserves a top inset equal to the header's preferred height
when a header is attached, in both the rounded-border and no-border states.
- brave_side_panel_header_controller is split into its own :side_panel_impl source_set
(depending on :side_panel) to keep dep chains clean.
## Test plan
- New SidebarBrowserTest.SidebarV2BraveHeaderTest test case
- Manual: run with enable_sidebar_v2=true, open reading list and bookmarks — header should be visible
Replaces site-favicon component - which only retrieves favicons from the
history service, which means the user would first have to visit the site
for the favicon to be available - with settings-search-engine-icon which
retrieves the favicon right away.
In order to make it easier to register draggable areas, we move the non-client
hit test helper to the browser window features. The new BraveNonClientHitTestHelper
will manage the registration of draggable areas and provide a non-client hit test
helper for the frame views.
* [AI Chat] Disable chromium Actor UI Task Button
When an actor framework task is invoked, the button shows due to kGlicActorUiTaskIcon being true. Interacting with this button causes a crash.
First we will disable the button entirely, via this PR.
Then we will bring the functionality either in a custom Brave button and menu, or fix the upstream one.
Tests
Guards the kGlicActorUiTaskIcon=false override in chromium_src/chrome/
common/chrome_features.cc against regressions: while the agent profile
window is executing a task, neither the toolbar nor the tab strip
action container should construct the upstream
GlicAndActorButtonsContainer (which has been the source of crashes).
* Decouple PolicyService::Observer from AdsServiceImpl
Move the "defer ads service start until policy is initialized" pattern out
of `AdsServiceImpl` into a reusable `brave_policy::PolicyInitializationWaiter`
helper. `AdsServiceImpl` no longer inherits from `policy::PolicyService::Observer`
or takes a `policy::PolicyService*` in its constructor; `AdsServiceFactory`
builds the waiter from the profile policy connector and injects it.
Also drops the temporary `[AdsGate]` verbose logging that was added with the
original race fix; behaviour is now covered by unit tests.
The new helper lives at `brave/components/brave_policy/policy_initialization_waiter.{h,cc}`
and is reusable by any service that needs to defer initialization until
`PolicyService` has merged its policy bundle into the managed pref store.
Resolves: https://github.com/brave/brave-browser/issues/55266
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
* Move factory/init orchestration into BraveBatchPassageEmbedder
BravePassageEmbeddingsService held the full embedder lifecycle — the
renderer-side factory remote, a queue of pending loads, and a
state machine that drove factory_->Init in addition to file loading —
which made the set of reachable states hard to reason about and left
room for the factory remote and the batch embedder to drift out of
sync.
Align with upstream's PassageEmbeddingsService: the service now just
reads model files from disk and hands the factory remote, model files,
receiver, and load callback to BraveBatchPassageEmbedder at the right
moment. The BatchEmbedder drives factory->Init, binds the renderer
pipe on success, and reports disconnect back to the service. With Init
moved out, the service's load phases reduce to {kWaiting, kLoading,
kReady}; kInitializing is no longer needed because BatchEmbedder owns
that step internally.
Collapse the pending-load queue to a single std::optional<PendingLoad>
and reject concurrent BindPassageEmbedder calls. An in-flight file
load is cancelled by a dedicated WeakPtrFactory on
ResetEmbedderState. Use base::ScopedClosureRunner in
OnLocalModelFilesLoaded to keep its three early-return failure paths
from duplicating the reset call.
Adds an !pending_load_ orphan-renderer guard in
OnBackgroundContentsCreated: if CloseBackgroundContents fires while
the BackgroundWebContents factory is in flight, the late
create-callback would otherwise install an orphan renderer that
nothing drives or tears down.
* Move BackgroundWebContents and LocalAIService into BraveBatchPassageEmbedder
Shrinks BravePassageEmbeddingsService to its essential responsibility
(reading EmbeddingGemma model files from disk in response to
LocalModelsUpdaterState notifications) and gives the BatchEmbedder
ownership of the renderer-side lifecycle it actually drives:
* the background WebContents that hosts the WASM worker,
* the local_ai::mojom::LocalAIService receiver set used by the WASM
page to register its PassageEmbedderFactory, and
* the factory remote, including the duplicate-registration guard.
BravePassageEmbeddingsService now constructs a BatchEmbedder eagerly on
BindPassageEmbedder and hands over loaded files via SetModelFiles.
The BatchEmbedder waits until both the renderer factory and the model
files are present before driving factory->Init.
The static WebContents -> BindCallback registry stays on
BravePassageEmbeddingsService since UntrustedLocalAIUI uses it as a
public API; the registered callback now points at
BraveBatchPassageEmbedder::BindLocalAIReceiver. The controller's
CreateBackgroundWebContents closure is updated to operate on a
WeakPtr<BraveBatchPassageEmbedder> instead of the service.
BUILD.gn: batch_passage_embedder gains a public_deps entry on
//brave/components/local_ai/core because its header now includes
background_web_contents.h.
* Move model-file loading into BravePassageEmbeddingsServiceController
Mirror upstream's PassageEmbeddingsServiceController: the controller owns
the model lifecycle, the service is a thin factory.
- Controller observes LocalModelsUpdaterState and posts the disk read
for the five EmbeddingGemma files. EmbedderReady() returns true iff
the component is installed; OnLocalModelsReady fires
EmbedderMetadataUpdated so SchedulingEmbedder retries. GetEmbeddings
short-circuits with kModelUnavailable when not ready.
- Service::BindPassageEmbedder now takes ModelFilesPtr and constructs
BraveBatchPassageEmbedder around it. Drops the observer plumbing,
file_load_in_flight_, OnLocalModelsReady, MaybeLoadLocalModelFiles,
OnLocalModelFilesLoaded.
- BraveBatchPassageEmbedder takes ModelFilesPtr in its ctor. Drops
SetModelFiles / pending_model_files_ and the kAwaitingPrereqs phase;
state machine collapses to
kCreatingContents -> kAwaitingFactory -> kInitializing -> kReady.
* Defer receiver_.Bind in BraveBatchPassageEmbedder until kReady
Hold the PendingReceiver<PassageEmbedder> in the ctor instead of binding
receiver_ immediately. Bind it only from OnInitDone(true), after the
renderer-side PassageEmbedder pipe is up.
Callers issue GenerateEmbeddings on embedder_remote_ right after
BindPassageEmbedder; mojo queues those messages on the pipe until the
receiver actually binds, mirroring upstream's utility-process embedder
behavior. By the time GenerateEmbeddings is delivered to this object,
renderer_embedder_ is guaranteed bound, so ProcessNext's
"renderer not bound" branch becomes unreachable and is replaced with a
CHECK.
BraveSyncAccountDeletedInfoBar layout is broken with InfobarRefresh.
As it's not compatible with ConfirmInfoBar, changed to subclass BraveConfirmInfoBar.
sync-account-deleted infobar: No regression w or w/o InfobarRefresh flag
Resolves - subtask of brave/brave-browser#48822
* Add error details struct
* Parse streaming error body in APIRequestHelper, extract status/error codes, display to user
* Add tests, v2 client fixups
* Add comment
* Rename error_code to error_type, use string as type
* Only parse error body if content type is application/json
* Address PR feedback
* Address PR feedback
* [AI Chat] Progress indicator with text and expansion button
Introduce ProgressBubble UI component.
Replaces spinner during generation and tool use, adding text description of the operation currently in progress.
Replaces AssistantTask tabs ("Steps"/"Progress") with a button to control expansion and collapse of details.
Replaces SearchSummary special handling with status inside the ProgressBubble and a regular search Tool Use event rendering when detail is expanded.
The use of `bool` for `DeviceInfo` fields has led to bugs in the past.
This has been correct with plaster, however we should also convert the
field to an enum to make sure we follow the upstream practice of using
enums in this type.
Resolves https://github.com/brave/brave-browser/issues/55018
BraveConfirmInfoBar used to inherit from InfoBarView, so its layout
changed with upstream's features::kInfobarRefresh — vertical centering,
label/link gaps, icon offset and multi-line height all shifted between
the flag-off and flag-on states.
As we're using BraveConfirmInfoBar for our specific info bar only,
we don't need to get suffer from upstream's view change over time.
We can go with our own custom view based on infobars::InfoBar interface.
Replace the base class with direct multi-inheritance from
infobars::InfoBar, views::View and views::ExternalFocusTracker, and
implement Layout / CalculatePreferredSize / OnThemeChanged /
PlatformSpecific* ourselves. The visual is now identical regardless of
the upstream flag and we no longer depend on InfoBarView's internal
structure.
Resolves - subtask of brave/brave-browser#48822
No regressions on existing infobars that uses BraveConfirmInfoBar.
* Make container icon bigger
Previously, the icon used for PageActionView was too small, because the
size includes the background size. Introduces a new generator function
that generates the icon without the background.
Centers the CTA button on New Tab Takeover sponsored image pages in the
NTP refresh when the `brave://flags/#center-ntt-cta-button` flag is enabled.
The flag is disabled by default.
Preparation to BraveConfirmInfoBar refactor
Deleted unused code to make refactoring more easier.
No production delegate ever used BUTTON_EXTRA.
Remove it together with the GetButtons override, GetButtonsOrder, IsProminent, and
ExtraButtonPressed virtuals that only existed to support it.
Delete the chromium_src patch that injected BUTTON_EXTRA into upstream's enum.
Cleaned up dead code from confirm_infobar.h overriding
Resolves - subtask of brave/brave-browser#48822
On a clean profile, engine keys are absent from the profile attributes
dict, causing virtual pref path traversal to fail with "Unknown pref
path". Initialize an empty list for each engine key on first
construction of ProfileAttributesTimePeriodStore so the paths always
resolve to 0.
* Remove max-width and set left flex
Remove the hard max-width from the settings menu and left pane, and set #left to `flex: 0 !important` so the left column no longer relies on a fixed width. Adjusts layout behavior to use flex sizing and addresses overflow/scroll issues. Changes in browser/resources/settings/br/settings_menu.ts and settings_ui.ts (plus minor formatting tweaks).
* remove empty space
Fix race in AdBlockServiceTest.PreRunTestOnMainThread
The RunUntil condition checked a histogram recorded on a background
thread. Due to the incoming-queue/work-queue split in Chromium's
SequenceManager, RunUntil could return after seeing the histogram
sample but before OnEngineLoaded dispatched OnFilterListLoaded on the
UI thread. The observer created in InstallComponent then caught this
stale notification, leaving the histogram count at 1 instead of 2.
Switch to IsFilterListLoadedForTesting(true), a UI-thread flag set
in OnEngineLoaded, which guarantees the reply callback has been fully
processed before RunUntil returns.
Resolvesbrave/brave-browser#55007
Adds a TabStripPlacementCoordinator that owns the parenting of the
horizontal tab strip region view and selects an appropriate parent based
on browser state (vertical tabs, focus mode, default). Callers register
parents per PlacementKind and trigger reassignment via UpdatePlacement.
Migrates BraveVerticalTabStripRegionView off its ad-hoc reparenting
onto the coordinator.
The kTopContainer placement is wired up but left unused; Focus Mode
will register a parent for it in a follow-up.
First step of the BraveConfirmInfoBar refactor.
Before refactoring BraveConfirmInfoBar, removed unused BraveConfirmInfoBar subclass.
Dev channel deprecation infobar: not used anymore. Remove.
Resolves - subtask of brave/brave-browser#48822
The test intermittently fails with "deepQuery is not defined" because
InjectHelpers injects the helper function into the bubble's WebContents
before the WebUI navigation has committed. WaitForLoadStop returns
immediately when no navigation is pending (e.g., the WebContents is
still at about:blank), so deepQuery is injected into the pre-navigation
context, then lost when chrome://email-aliases.panel/ loads.
Wait for the WebContents to commit a non-empty, non-about:blank URL
before calling WaitForLoadStop and injecting JavaScript.
Fixbrave/brave-browser#55000