From `MonotonicObservableSupplier` to `OneshotSupplier`
Chromim change:
https://source.chromium.org/chromium/chromium/src/+/1886db4b40ccf9dfad5270be7861fefbb44c5ed3
commit 1886db4b40ccf9dfad5270be7861fefbb44c5ed3
Author: Anton Goncharenko <agonch@google.com>
Date: Tue Mar 10 17:49:16 2026 -0700
[Signin][Android] SafetyHub: Wait for UI dependencies before initializing sign-in coordinator.
For consistency with other fragments' provided dependencies, pass
Suppliers to SafetyHubModuleDelegateImpl rather than assuming the
Suppliers have already been initialized. Able to repro a
NullPointerException (WindowAndroid not being initialized) during
Activity recreation when killing Chrome during the "add new account"
sign-in flow (see repro steps in crbug.com/479179162).
Bug: 479179162
Change-Id: I8a37a6a532cf5d4650849ec86151e1ee9c9ee0f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7642808
Reviewed-by: Menghan Yang <myuu@google.com>
Commit-Queue: Anton Goncharenko <agonch@google.com>
Reviewed-by: Zaina Al-Mashni <zalmashni@google.com>
Reviewed-by: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1597438}
* [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
The Survey Panelist toggle and its "Learn more" row remained visible
under Settings -> Brave Shields & privacy for users with an active
Brave Origin subscription.
Extend the existing BRAVE_NTP_BRANDED_WALLPAPER_SURVEY_PANELIST
feature-flag gate in BravePrivacySettings to also require
!BraveOriginSubscriptionPrefs.getIsCredentialSummaryActiveCached() for
both the preference visibility and the settings-search index entry.
Resolves: https://github.com/brave/brave-browser/issues/54853
ShortcutsBackend initializes asynchronously. When clearBrowsingData() was
called during startup, the backend was still in the INITIALIZING state and
its OnHistoryDeletions handler silently returned early, leaving shortcut
suggestions (clock-icon entries) intact after exit.
Fix by adding a JNI bridge (BraveShortcutsUtils.initThenRun) that waits for
ShortcutsBackend to finish its async DB init via OnShortcutsLoaded() before
invoking clearBrowsingData(). Also move the clear-on-exit call from
initializeState() to finishNativeInitialization() where the profile is
available, and add FORM_DATA (autofill) to the cleared data types.
Brave Origin subscribers on Android currently receive general-engagement
notifications and unbidden promo dialogs that are not tied to any
Origin-disabled feature. Suppress them under the product stance that
Origin users get a cleaner, promo-free experience.
Surfaces gated:
- RetentionNotificationPublisher: HOUR_3, HOUR_24, DAY_6, EVERY_SUNDAY,
and DORMANT_USERS_DAY_14/25/40 notification fire-time.
- BraveActivity: showDormantUsersEngagementDialog (cold-start and
in-foreground tap paths), India ad-free callout, YouTube-in-Brave
dialog.
The existing getIsSubscriptionActive() pref only reflects Play Store
purchases, so it misses desktop-linked subscribers. Introduce a new
Java-side cached boolean BRAVE_ORIGIN_CREDENTIAL_SUMMARY_CACHED, written
from two authoritative any-source signals:
- fetchOrderCredentials success (primes the cache immediately on a
successful Play Store purchase).
- requestCredentialSummary callback (covers Play Store and
desktop-linked paths; the Skus service resolves both internally).
BraveActivity.finishNativeInitialization now calls
requestCredentialSummary on every app start to keep the cache fresh.
Resolves: https://github.com/brave/brave-browser/issues/54791
BraveActivity shows LinkVpnSubscriptionDialogFragment when a VPN
subscription is detected on the device and the link dialog has not yet
been shown. The guard did not consult the VPN policy pref, so the dialog
was presented even to users whose VPN has been disabled by policy (e.g.
Brave Origin users with VPN turned off at the policy layer).
Add !BraveVpnPolicy.isDisabledByPolicy(mTabModelProfileSupplier.get()) to
the guard.
Resolves: https://github.com/brave/brave-browser/issues/54786
String changes in android_brave_strings.grd:
- IDS_MENU_ORIGIN: "Origin" -> "Brave Origin" (Settings menu row).
- IDS_BRAVE_ORIGIN_PREMIUM: "Origin" -> "Brave Origin" (paywall title).
- IDS_ORIGIN_LEO_AI_TOGGLE: "AI" -> "Leo AI" (toggle label
consistency with other Leo surfaces).
- IDS_ORIGIN_DESCRIPTION_BODY: drop the trailing sentence
"Origin will remove most other features from the browser."
- IDS_ORIGIN_CHANGING_BRAVE_FEATURES_MESSAGE_POST_PURCHASE:
"once Origin has finished updating." ->
"once Brave Origin has finished updating."
- IDS_ORIGIN_PAYWALL_TEXT_4: rewritten to
"One-time purchase can be activated multiple times across all
your devices".
- IDS_ORIGIN_DESCRIPTION_NOTE: removed entirely (Search Premium
note no longer shown).
Layout changes:
- brave_origin_description_preference.xml: remove the
origin_description_note TextView from the preference-screen
description block.
- activity_brave_origin_plans.xml (portrait paywall) and
layout-land/activity_brave_origin_plans.xml (landscape
paywall): remove the note TextView; body description's bottom
margin bumped from 16dp to 24dp to preserve spacing with the
next section.
Resolves: https://github.com/brave/brave-browser/issues/54761
BraveSearchEnginesPreferences.removePreferenceIfPresent was calling
getPreferenceScreen().removePreference(pref) unconditionally. That
only removes direct children of PreferenceScreen — when the target
preference is nested inside a PreferenceCategory (as send_web_discovery
is, inside currently_used_search_engines_category), the remove call
silently returns false and the toggle stays visible.
Users whose WebDiscoveryEnabled pref is managed by policy (e.g. Brave
Origin subscribers, enterprise admins) saw the toggle rendered and
greyed-out instead of being hidden entirely.
Fix: remove from the preference's actual parent group.
preference.getParent() returns the containing PreferenceGroup — the
PreferenceCategory for nested prefs, the PreferenceScreen itself for
top-level prefs. Works for both cases.
Other PREF_CUSTOM_SEARCH_ENGINES_CATEGORY caller is a top-level
PreferenceCategory; new behavior is equivalent for that case.
Resolves: https://github.com/brave/brave-browser/issues/54751
brave_rewards::IsDisabledByPolicy() was hardcoded to return false on
Android regardless of the managed kDisabledByPolicy pref, so every
native call site that gates on brave_rewards::IsSupported() failed to
suppress for Brave Origin subscribers (and enterprise admins setting
the BraveRewardsDisabled policy).
Symptoms fixed:
- Ads service kept initializing on Android for Origin profiles
(AdsServiceFactory::GetForProfile gates on IsSupported).
- NTP sponsored background images and sponsored rich-media takeover
rendered (downstream of the ads service via ViewCounterService).
- DAY_10 / DAY_30 / DAY_35 Rewards retention notifications fired
(RetentionNotificationPublisher gates on rewardsNativeWorker
.isSupported).
Java-side Rewards UI surfaces were already correctly gated via
BraveRewardsPolicy.isDisabledByPolicy(profile) and are unaffected.
Also decouples BraveVpnUtils.isRegionSupported() from
BraveRewardsNativeWorker.isSupported() — otherwise the guard flip would
cause VPN UI to hide for any profile where Rewards is policy-disabled
as a side effect. Added BraveVpnNativeWorker.isSupportedRegion that
does the OFAC region check directly via brave_l10n.
Resolves: https://github.com/brave/brave-browser/issues/54703
When a user who previously purchased Brave Origin switches devices,
verifyPurchase() at startup finds the Play Store purchase and kicks off
the SKUs createOrderFromReceipt / fetchOrderCredentials chain to obtain
an order ID. Until that chain completes, requestCredentialSummary
returns inactive, so Settings -> Brave Origin launches the paywall even
though a purchase exists and is mid-restore.
Gate handleOriginPreferenceClick on isFetchingCredentials() and route
directly to BraveOriginPreferences (which renders the fetching spinner
via its existing setCredentialsFetchedCallback path) when a restore is
in flight.
Also harden setCredentialsFetchedCallback against a lost-notification
race: after registering the callback, re-check isFetchingCredentials()
and synthesize a success notification if the fetch already completed.
Order-ID-set is the only path that flips the state to false, so
synthesizing success is safe.
Resolves: https://github.com/brave/brave-browser/issues/54637
* [Android] Register Brave as Android AutofillService for address autofill
Re-enables the Android AutofillService that was removed in
https://github.com/brave/brave-core/pull/25759 due to crashes on
split-APK installs. Uses the SplitCompat pattern
(SplitCompatAutofillService base class) so the service works correctly
when installed from the Play Store.
When the user selects Brave as their autofill provider in Android Settings,
Brave can fill saved address profiles into third-party apps and save new
addresses from manually filled forms.
Resolves: https://github.com/brave/brave-browser/issues/41334
The deferred PostTask introduced to avoid ANR was causing the bottom
controls to be initialized after the progress bar, breaking it.
Revert to synchronous initialization.
Resolves: https://github.com/brave/brave-browser/issues/54458
The maybeHideRewardsLayout() method controls rewards icon visibility on
tablets based on width but didn't check BraveRewardsPolicy, causing it
to override the main visibility logic that correctly hides the icon when
rewards are disabled.
Resolves: https://github.com/brave/brave-browser/issues/54358
* Android: Implement favicons for Password Manager entries
We now display favicons for Password Manager as happens for our desktop
edition.
In order to do this, the C++ side now passes in the full origin so that
we have the clean, proper URI in order to fetch the favicon.
Resolvesbrave/brave-browser#52775
Always check credentials via SKUs SDK (requestCredentialSummary) in
handleOriginPreferenceClick() instead of gating on the Play Store
purchase pref. This mirrors how Leo uses getPremiumStatus() to handle
both Play Store and desktop purchases.
Only show "Link Purchase" when there is an actual Play Store purchase
that hasn't been linked yet. Desktop purchases have no Play Store
receipt to link.
Resolves: https://github.com/brave/brave-browser/issues/54312
Custom push notifications rendered notification ads as popup windows as a
fallback when native OS notifications were unavailable. Native notifications
are now the only delivery path so the entire custom rendering path, its
feature flags, platform bridge, Views UI, Android dialog UI, P3A position
metric, and three migrated prefs are removed.
Co-authored-by: Aleksei Seren <aseren@brave.com>
Upstream Chromium cr147 (https://chromium-review.googlesource.com/c/chromium/src/+/7559078)
made FOREGROUND_SERVICE_CAMERA unconditional for all Android builds by
removing the is_desktop_android guard. However, the feature that
actually uses it (kAndroidEnableBackgroundMediaCapturing) is disabled
by default and not enabled by Brave, so the permission is declared but
never used.
This blocks Play Store publishing because Google requires a declaration
with a demo video for any app using FOREGROUND_SERVICE_CAMERA.
This PR:
- Re-gates FOREGROUND_SERVICE_CAMERA behind is_desktop_android so it's
excluded from Brave builds
- Removes AndroidManifest_user_permissions.xml since upstream now
declares FOREGROUND_SERVICE_MICROPHONE unconditionally, making
Brave's duplicate unnecessary
Resolves: https://github.com/brave/brave-browser/issues/54143
Move the bottom controls setup (ViewStub inflation, coordinator
creation, native initialization) from synchronous execution during
finishNativeInitialization to a deferred UI task via PostTask. The
synchronous inflation was triggering HardwareRenderer.nNotifyExpensiveFrame
which blocked the main thread waiting for the GPU, causing ANR on
devices under GPU pressure during startup.
This is safe because all consumers of mBottomControlsCoordinatorSupplier
and mTabGroupUiOneshotSupplier already null-check before use, and the
bottom toolbar starts with visibility="gone" making the one-frame delay
imperceptible. The task is wrapped with mCallbackController.makeCancelable()
to auto-cancel during Activity teardown.
Resolves: https://github.com/brave/brave-browser/issues/54077
[Ads] Serve new-tab takeover ads on demand instead of prefetching
Removing prefetching reduces unnecessary complexity.
Ads will instead be served on demand, ensuring they are
only delivered within the campaign’s configured start and
end dates.
Co-authored-by: Aleksei Seren <aseren@brave.com>
* [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