Repository: brave/brave-core
Pull request #29051: [Android] New Mobile Bookmarks homepage setting
Author: login: samartnik
Labels: name: CI/skip-ios
description: Do not run CI builds for iOS
name: CI/skip-windows-x64
description: Do not run CI builds for Windows x64
name: CI/skip-macos-arm64
description: Do not run CI builds for macOS arm64
Created: 2025-05-14T15:25:00Z | Merged: 2025-05-16T21:05:04Z

<!-- Add brave-browser issue below that this PR will resolve -->
Resolves https://github.com/brave/brave-browser/issues/43657

<!-- CI-related labels that can be applied to this PR:
* CI/run-audit-deps (1) - check for known npm/cargo vulnerabilities (audit_deps)
* CI/run-network-audit (1) - run network-audit
* CI/run-upstream-tests - run Chromium unit and browser tests on Linux and Windows (otherwise only on Linux)
* CI/run-linux-arm64, CI/run-macos-x64, CI/run-windows-arm64, CI/run-windows-x86 - run builds that would otherwise be skipped
* CI/skip - do not run CI builds (except noplatform)
* CI/skip-linux-x64, CI/skip-android, CI/skip-macos-arm64, CI/skip-ios, CI/skip-windows-x64 - skip CI builds for specific platforms
* CI/skip-upstream-tests - do not run Chromium unit, or browser tests (otherwise only on Linux)
* CI/skip-all-linters - do not run presubmit and lint checks
* CI/storybook-url (1) - deploy storybook and provide a unique URL for each build

(1) applied automatically when some files are changed (see: https://github.com/brave/brave-core/blob/master/.github/labeler.yml)
-->

<!--
## Checklist:

- Review design docs
  [Browser design principles](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/chrome_browser_design_principles.md)
  [Style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md)
  [Core principles](https://www.chromium.org/developers/core-principles/)
- Ensure there are (tests)[https://www.chromium.org/developers/testing/]. Unit test as much as possible (including edge cases), but also include browser tests covering high level functionality.
- Ensure that there are comments explaining what classes/methods are/do. The "why" is often more important than the "what" in comments. Also update any relevant docs (moving docs from wiki to brave-core if necessary).
- Request security or other review (third-party libraries, rust code, etc...) if applicable [security/privacy review is needed](https://github.com/brave/brave-browser/wiki/Security-reviews) [other review](https://github.com/brave/reviews/issues/new/choose)
  Also see [adding third-party libraries](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/adding_to_third_party.md) for general guidelines on using third party code
- Maks sure there is a [ticket](https://github.com/brave/brave-browser/issues) for your issue
- Use Github [auto-closing keywords](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue) in the PR description above
- Write a good [PR/commit description](https://google.github.io/eng-practices/review/developer/cl-descriptions.html)
- Squash any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
- Add appropriate labels (`QA/Yes` or `QA/No`; `release-notes/include` or `release-notes/exclude`; `OS/...`) to the associated issue
- Checked the PR locally:
  * `npm run test -- brave_browser_tests`, `npm run test -- brave_unit_tests` [wiki](https://github.com/brave/brave-browser/wiki/Tests)
  * `npm run presubmit` [wiki](https://github.com/brave/brave-browser/wiki/Presubmit-checks), `npm run gn_check`, `npm run tslint`
- Run `git rebase master` (if needed)
-->



Diff:
diff --git a/android/brave_java_resources.gni b/android/brave_java_resources.gni
index a2f69dc6a8e6..fb6f9cf00fa5 100644
--- a/android/brave_java_resources.gni
+++ b/android/brave_java_resources.gni
@@ -741,6 +741,7 @@ brave_java_resources = [
   "java/res/layout/brave_custom_tabs_toolbar.xml",
   "java/res/layout/brave_dialog_preference.xml",
   "java/res/layout/brave_exit_confirmation.xml",
+  "java/res/layout/brave_homepage_mobile_bookmarks_button.xml",
   "java/res/layout/brave_leo_clear_history_dialog.xml",
   "java/res/layout/brave_leo_reset_dialog.xml",
   "java/res/layout/brave_news_card_menu.xml",
diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni
index a94e22bacc88..275f707e49e9 100644
--- a/android/brave_java_sources.gni
+++ b/android/brave_java_sources.gni
@@ -224,6 +224,8 @@ brave_java_sources = [
   "../../brave/android/java/org/chromium/chrome/browser/firstrun/WelcomeOnboardingActivity.java",
   "../../brave/android/java/org/chromium/chrome/browser/homepage/BraveHomepageManager.java",
   "../../brave/android/java/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettings.java",
+  "../../brave/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java",
+  "../../brave/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreferenceDummySuper.java",
   "../../brave/android/java/org/chromium/chrome/browser/identity_disc/BraveIdentityDiscController.java",
   "../../brave/android/java/org/chromium/chrome/browser/infobar/BraveInfoBarIdentifier.java",
   "../../brave/android/java/org/chromium/chrome/browser/informers/BraveSyncAccountDeletedInformer.java",
diff --git a/android/java/apk_for_test.flags b/android/java/apk_for_test.flags
index c66ab2e593ec..6768316b031d 100644
--- a/android/java/apk_for_test.flags
+++ b/android/java/apk_for_test.flags
@@ -966,3 +966,14 @@
 }
 
 -keep class org.chromium.chrome.browser.suggestions.tile.TilesLinearLayout { *; }
+
+-keep class org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference {
+    *** onCheckedChanged(...);
+    *** getPreferenceValue(...);
+    *** setupPreferenceValues(...);
+    *** onTextChanged(...);
+    *** getCustomUriRadioButton(...);
+    *** getChromeNtpRadioButton(...);
+}
+
+-keep class org.chromium.chrome.browser.homepage.settings.BraveRadioButtonGroupHomepagePreference
diff --git a/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java b/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
new file mode 100644
index 000000000000..eb4b878edab1
--- /dev/null
+++ b/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
@@ -0,0 +1,119 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference.HomepageOption;
+import org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference.PreferenceValues;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+@NullMarked
+public final class BraveRadioButtonGroupHomepagePreference
+        extends BraveRadioButtonGroupHomepagePreferenceDummySuper {
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
+
+    @Nullable private RadioButtonWithDescription mMobileBookmarks;
+    @Nullable private RadioButtonWithEditText mCustomUri;
+    private boolean mSelectMobileBookmarks;
+
+    public BraveRadioButtonGroupHomepagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Called when the checked radio button has changed. When the selection is cleared, checkedId is
+     * -1.
+     *
+     * @param group The group in which the checked radio button has changed
+     * @param checkedId The unique identifier of the newly checked radio button
+     */
+    @Override
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        PreferenceValues preferenceValues = super.getPreferenceValue();
+        if (preferenceValues == null) return;
+
+        if (checkedId == R.id.brave_homepage_mobile_bookmarks) {
+            maybeSelectMobileBookmarks(true);
+        } else {
+            super.onCheckedChanged(group, checkedId);
+        }
+        maybeClearCustomUri();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        mMobileBookmarks =
+                (RadioButtonWithDescription)
+                        holder.findViewById(R.id.brave_homepage_mobile_bookmarks);
+        assert mMobileBookmarks != null : "Mobile bookmarks button is missing in the layout";
+
+        mCustomUri = (RadioButtonWithEditText) holder.findViewById(R.id.radio_button_uri_edit);
+        assert mCustomUri != null : "Custom URI button missing in the layout";
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    @Override
+    void setupPreferenceValues(@NonNull PreferenceValues value) {
+        super.setupPreferenceValues(value);
+
+        // If it is custom uri with mobile bookmarks path, set the mobile bookmarks radio button
+        // selected.
+        mSelectMobileBookmarks =
+                value.getCheckedOption() == HomepageOption.ENTRY_CUSTOM_URI
+                        && value.getCustomURI().equals(MOBILE_BOOKMARKS_PATH);
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    void maybeSelectMobileBookmarks(boolean forceSelect) {
+        if ((mSelectMobileBookmarks || forceSelect) && mMobileBookmarks != null) {
+            // Make sure it is selected.
+            mMobileBookmarks.setChecked(true);
+            // Set proper URL (mobile bookmarks is the same as custom uri just with mobile
+            // bookmarks path).
+            super.onTextChanged(MOBILE_BOOKMARKS_PATH);
+        }
+    }
+
+    private void maybeClearCustomUri() {
+        // If the custom uri is not selected and the text is the mobile bookmarks path then clear
+        // the text.
+        if (mCustomUri != null
+                && !mCustomUri.isChecked()
+                && mCustomUri.getPrimaryText().toString().equals(MOBILE_BOOKMARKS_PATH)) {
+            mCustomUri.setPrimaryText("");
+        }
+    }
+
+    @VisibleForTesting
+    @Nullable
+    RadioButtonWithDescription getMobileBookmarksRadioButton() {
+        return mMobileBookmarks;
+    }
+
+    @VisibleForTesting
+    public static Class getPreferenceValuesClass() {
+        return PreferenceValues.class;
+    }
+}
diff --git a/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreferenceDummySuper.java b/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreferenceDummySuper.java
new file mode 100644
index 000000000000..24e5830bf282
--- /dev/null
+++ b/android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreferenceDummySuper.java
@@ -0,0 +1,65 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference.PreferenceValues;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/**
+ * This is dummy super class for {@link BraveRadioButtonGroupHomepagePreference}. Used to make code
+ * compilable before bytecode manipulations.
+ */
+@NullMarked
+public class BraveRadioButtonGroupHomepagePreferenceDummySuper extends Preference {
+    public BraveRadioButtonGroupHomepagePreferenceDummySuper(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        assert false : "This dummy class should be replaced in bytecode!";
+    }
+
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        assert false : "This dummy class should be replaced in bytecode!";
+    }
+
+    @Nullable
+    PreferenceValues getPreferenceValue() {
+        assert false : "This dummy class should be replaced in bytecode!";
+        return null;
+    }
+
+    void setupPreferenceValues(@NonNull PreferenceValues value) {
+        assert false : "This dummy class should be replaced in bytecode!";
+    }
+
+    public void onTextChanged(CharSequence newText) {
+        assert false : "This dummy class should be replaced in bytecode!";
+    }
+
+    @VisibleForTesting
+    @Nullable
+    RadioButtonWithEditText getCustomUriRadioButton() {
+        assert false : "This dummy class should be replaced in bytecode!";
+        return null;
+    }
+
+    @VisibleForTesting
+    @Nullable
+    RadioButtonWithDescription getChromeNtpRadioButton() {
+        assert false : "This dummy class should be replaced in bytecode!";
+        return null;
+    }
+}
diff --git a/android/java/res/layout/brave_homepage_mobile_bookmarks_button.xml b/android/java/res/layout/brave_homepage_mobile_bookmarks_button.xml
new file mode 100644
index 000000000000..c95414a163f8
--- /dev/null
+++ b/android/java/res/layout/brave_homepage_mobile_bookmarks_button.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/brave_homepage_mobile_bookmarks"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
diff --git a/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java b/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java
index 1f8d83fd525a..306154ac0d7b 100644
--- a/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java
+++ b/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java
@@ -11,8 +11,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.safe_browsing.BraveSafeBrowsingUtils;
 import org.chromium.components.safe_browsing.BraveSafeBrowsingUtils.SafetyNetJavaThreatType;
 
@@ -20,7 +20,7 @@
 import java.util.Arrays;
 
 @Batch(Batch.PER_CLASS)
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BraveSafetyNetThreatsPrioritiesTest {
 
     @Test
diff --git a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
index 9825e461d3eb..82b2f8c86073 100644
--- a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
+++ b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
@@ -27,6 +27,7 @@
 import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.view.Window;
+import android.widget.RadioGroup;
 
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.lifecycle.LifecycleOwner;
@@ -49,7 +50,6 @@
 import org.chromium.base.supplier.OneshotSupplier;
 import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.supplier.Supplier;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.back_press.BackPressManager;
 import org.chromium.chrome.browser.bookmarks.BookmarkImageFetcher;
@@ -77,6 +77,7 @@
 import org.chromium.chrome.browser.findinpage.FindToolbarManager;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
+import org.chromium.chrome.browser.homepage.settings.BraveRadioButtonGroupHomepagePreference;
 import org.chromium.chrome.browser.hub.ResourceButtonData;
 import org.chromium.chrome.browser.keyboard_accessory.ManualFillingComponentSupplier;
 import org.chromium.chrome.browser.layouts.LayoutManager;
@@ -145,6 +146,7 @@
 import org.chromium.chrome.browser.ui.system.StatusBarColorController.StatusBarColorProvider;
 import org.chromium.chrome.browser.undo_tab_close_snackbar.UndoBarThrottle;
 import org.chromium.chrome.browser.user_education.UserEducationHelper;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateManager;
@@ -158,6 +160,8 @@
 import org.chromium.components.browser_ui.site_settings.WebsiteAddress;
 import org.chromium.components.browser_ui.site_settings.WebsitePermissionsFetcher.WebsitePermissionsType;
 import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
 import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
 import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableRecyclerViewAdapter;
 import org.chromium.components.browser_ui.widget.scrim.ScrimManager;
@@ -210,7 +214,7 @@
  * should be whitelisted in 'brave/android/java/apk_for_test.flags'.
  */
 @Batch(Batch.PER_CLASS)
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BytecodeTest {
     enum MethodModifier {
         REGULAR,
@@ -915,6 +919,46 @@ public void testMethodsExist() throws Exception {
                         "getAppHeaderCoordinator",
                         MethodModifier.REGULAR,
                         AppHeaderCoordinator.class));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "onCheckedChanged",
+                        MethodModifier.REGULAR,
+                        void.class,
+                        RadioGroup.class,
+                        int.class));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "getPreferenceValue",
+                        MethodModifier.REGULAR,
+                        BraveRadioButtonGroupHomepagePreference.getPreferenceValuesClass()));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "setupPreferenceValues",
+                        MethodModifier.REGULAR,
+                        void.class,
+                        BraveRadioButtonGroupHomepagePreference.getPreferenceValuesClass()));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "onTextChanged",
+                        MethodModifier.REGULAR,
+                        void.class,
+                        CharSequence.class));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "getCustomUriRadioButton",
+                        MethodModifier.REGULAR,
+                        RadioButtonWithEditText.class));
+        Assert.assertTrue(
+                methodExists(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "getChromeNtpRadioButton",
+                        MethodModifier.REGULAR,
+                        RadioButtonWithDescription.class));
     }
 
     @Test
@@ -2433,6 +2477,22 @@ public void testSuperNames() throws Exception {
                 checkSuperName(
                         "org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerBase",
                         "org/chromium/chrome/browser/fullscreen/BraveFullscreenHtmlApiHandlerBase")); // presubmit: ignore-long-line
+        Assert.assertTrue(
+                checkSuperName(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "androidx/preference/Preference")); // presubmit: ignore-long-line
+        Assert.assertTrue(
+                checkSuperName(
+                        "org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference", // presubmit: ignore-long-line
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference")); // presubmit: ignore-long-line
+    }
+
+    @Test
+    @SmallTest
+    public void testClassIsNotFinal() throws Exception {
+        Assert.assertTrue(
+                checkClassIsNotFinal(
+                        "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference")); // presubmit: ignore-long-line
     }
 
     @Test
@@ -2628,4 +2688,12 @@ private boolean checkSuperName(String className, String superName) {
         }
         return c.getSuperclass().equals(s);
     }
+
+    private boolean checkClassIsNotFinal(String className) {
+        Class c = getClassForPath(className);
+        if (c == null) {
+            return false;
+        }
+        return !Modifier.isFinal(c.getModifiers());
+    }
 }
diff --git a/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java b/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java
index b462fc151456..b3b9905870eb 100644
--- a/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java
+++ b/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java
@@ -15,7 +15,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.brave_wallet.mojom.AccountId;
 import org.chromium.brave_wallet.mojom.BlockchainToken;
@@ -28,6 +27,7 @@
 import org.chromium.brave_wallet.mojom.TxData1559;
 import org.chromium.chrome.browser.crypto_wallet.util.Utils;
 import org.chromium.chrome.browser.crypto_wallet.util.Validations;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.url.mojom.Url;
 
 import java.util.Arrays;
@@ -35,7 +35,7 @@
 import java.util.Locale;
 
 @Batch(Batch.PER_CLASS)
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BraveWalletUtilsTest {
     @Test
     @SmallTest
diff --git a/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java b/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java
new file mode 100644
index 000000000000..848516c83cbc
--- /dev/null
+++ b/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java
@@ -0,0 +1,81 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.preference.Preference;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Batch;
+import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+
+/** Test for {@link BraveHomepageSettings} to check Brave related UI changes. */
+@Batch(Batch.PER_CLASS)
+@RunWith(ChromeJUnit4ClassRunner.class)
+public class BraveHomepageSettingsTest {
+    private static final String PREF_HOMEPAGE_RADIO_GROUP = "homepage_radio_group";
+
+    @Rule
+    public SettingsActivityTestRule<BraveHomepageSettings> mSettingsActivityTestRule =
+            new SettingsActivityTestRule<>(BraveHomepageSettings.class);
+
+    private BraveHomepageSettings mFragment;
+
+    @Before
+    public void setUp() {
+        mSettingsActivityTestRule.startSettingsActivity();
+        mFragment = (BraveHomepageSettings) mSettingsActivityTestRule.getFragment();
+    }
+
+    @Test
+    @SmallTest
+    public void testHomepageRadioGroupType() {
+        Preference homepageRadioGroup = mFragment.findPreference(PREF_HOMEPAGE_RADIO_GROUP);
+        assertNotEquals(null, homepageRadioGroup);
+        assertTrue(homepageRadioGroup instanceof BraveRadioButtonGroupHomepagePreference);
+    }
+
+    @Test
+    @SmallTest
+    public void testMobileBookmarksOption() {
+        ThreadUtils.runOnUiThreadBlocking(
+                () -> {
+                    BraveRadioButtonGroupHomepagePreference homepageRadioGroup =
+                            mFragment.findPreference(PREF_HOMEPAGE_RADIO_GROUP);
+                    // Check initial state.
+                    assertTrue(homepageRadioGroup.getChromeNtpRadioButton().isChecked());
+                    assertFalse(homepageRadioGroup.getMobileBookmarksRadioButton().isChecked());
+                    assertFalse(homepageRadioGroup.getCustomUriRadioButton().isChecked());
+
+                    // Check the click action on the mobile bookmarks radio button.
+                    homepageRadioGroup.getMobileBookmarksRadioButton().performClick();
+                    assertFalse(homepageRadioGroup.getChromeNtpRadioButton().isChecked());
+                    assertTrue(homepageRadioGroup.getMobileBookmarksRadioButton().isChecked());
+                    assertFalse(homepageRadioGroup.getCustomUriRadioButton().isChecked());
+                    assertTrue(
+                            homepageRadioGroup.getPreferenceValue().getCheckedOption()
+                                    == RadioButtonGroupHomepagePreference.HomepageOption
+                                            .ENTRY_CUSTOM_URI);
+                    assertTrue(
+                            homepageRadioGroup
+                                    .getPreferenceValue()
+                                    .getCustomURI()
+                                    .equals(
+                                            BraveRadioButtonGroupHomepagePreference
+                                                    .MOBILE_BOOKMARKS_PATH));
+                });
+    }
+}
diff --git a/android/javatests/org/chromium/chrome/browser/language/settings/BraveLanguageSettingsTest.java b/android/javatests/org/chromium/chrome/browser/language/settings/BraveLanguageSettingsTest.java
index 8fbfa1c1eeb4..3e687e36ce4d 100644
--- a/android/javatests/org/chromium/chrome/browser/language/settings/BraveLanguageSettingsTest.java
+++ b/android/javatests/org/chromium/chrome/browser/language/settings/BraveLanguageSettingsTest.java
@@ -15,10 +15,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
-@RunWith(BaseJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BraveLanguageSettingsTest {
     static final String TRANSLATION_SETTINGS_SECTION = "translation_settings_section";
 
diff --git a/android/javatests/org/chromium/chrome/browser/password_manager/settings/BravePasswordSettingsTest.java b/android/javatests/org/chromium/chrome/browser/password_manager/settings/BravePasswordSettingsTest.java
index d20e322b9e34..572ed1069a04 100644
--- a/android/javatests/org/chromium/chrome/browser/password_manager/settings/BravePasswordSettingsTest.java
+++ b/android/javatests/org/chromium/chrome/browser/password_manager/settings/BravePasswordSettingsTest.java
@@ -16,13 +16,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
 import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 /** Tests for the "Passwords" settings screen. */
-@RunWith(BaseJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BravePasswordSettingsTest {
     private static final String PREF_CHECK_PASSWORDS = "check_passwords";
 
diff --git a/android/javatests/org/chromium/chrome/browser/privacy/settings/BravePrivacySettingsTest.java b/android/javatests/org/chromium/chrome/browser/privacy/settings/BravePrivacySettingsTest.java
index 07aa8e844897..14aa4b2b0745 100644
--- a/android/javatests/org/chromium/chrome/browser/privacy/settings/BravePrivacySettingsTest.java
+++ b/android/javatests/org/chromium/chrome/browser/privacy/settings/BravePrivacySettingsTest.java
@@ -17,17 +17,17 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsBridge;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesState;
 import org.chromium.chrome.browser.profiles.ProfileManager;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 
 /** Checks if changes have been made to the Chromium privacy settings */
 @Batch(Batch.PER_CLASS)
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BravePrivacySettingsTest {
     // Chromium Prefs that are being checked
     private static final String PREF_CAN_MAKE_PAYMENT = "can_make_payment";
diff --git a/android/javatests/org/chromium/chrome/browser/safe_browsing/settings/BraveSafeBrowsingSettingsFragmentTest.java b/android/javatests/org/chromium/chrome/browser/safe_browsing/settings/BraveSafeBrowsingSettingsFragmentTest.java
index c5e3575c7053..5a28c02945c9 100644
--- a/android/javatests/org/chromium/chrome/browser/safe_browsing/settings/BraveSafeBrowsingSettingsFragmentTest.java
+++ b/android/javatests/org/chromium/chrome/browser/safe_browsing/settings/BraveSafeBrowsingSettingsFragmentTest.java
@@ -16,11 +16,11 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
-@RunWith(BaseJUnit4ClassRunner.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 @DoNotBatch(reason = "This test launches a Settings activity")
 public class BraveSafeBrowsingSettingsFragmentTest {
     @Rule
diff --git a/android/javatests/org/chromium/chrome/browser/safety_check/BraveSafetyCheckSettingsFragmentTest.java b/android/javatests/org/chromium/chrome/browser/safety_check/BraveSafetyCheckSettingsFragmentTest.java
index 0f2047307080..e250ec13040f 100644
--- a/android/javatests/org/chromium/chrome/browser/safety_check/BraveSafetyCheckSettingsFragmentTest.java
+++ b/android/javatests/org/chromium/chrome/browser/safety_check/BraveSafetyCheckSettingsFragmentTest.java
@@ -15,13 +15,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 
 // Currently safety check setion is not used in Brave.
 // Main purpose of these tests id to detect that something new, that we may consider valuable, is
 // appeared in this section .
-@RunWith(BaseJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
+@RunWith(ChromeJUnit4ClassRunner.class)
 public class BraveSafetyCheckSettingsFragmentTest {
     private static final String PASSWORDS_LOCAL = "passwords_local";
     private static final String PASSWORDS_ACCOUNT = "passwords_account";
diff --git a/browser/ui/android/strings/android_brave_strings.grd b/browser/ui/android/strings/android_brave_strings.grd
index 4e2889fcc01d..9f7d7d1fb1ee 100644
--- a/browser/ui/android/strings/android_brave_strings.grd
+++ b/browser/ui/android/strings/android_brave_strings.grd
@@ -4052,6 +4052,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne
     <message name="IDS_PRIVATE_TAB_SCREENSHOT_SUMMARY" desc="A summary to show private tab screenshot">
       If allowed, private tabs will also be visible when multiple apps are open.
     </message>
+    <message name="IDS_BRAVE_HOMEPAGE_MOBILE_BOOKMARKS_TEXT" desc="Text for `Mobile bookmarks` setting in `Homepage` settings">
+      Mobile bookmarks
+    </message>
   </messages>
   </release>
 </grit>
diff --git a/build/android/bytecode/BUILD.gn b/build/android/bytecode/BUILD.gn
index 78a5cf48b815..4614f0f1a129 100644
--- a/build/android/bytecode/BUILD.gn
+++ b/build/android/bytecode/BUILD.gn
@@ -97,6 +97,7 @@ java_binary("java_bytecode_rewriter") {
     "//brave/build/android/bytecode/java/org/brave/bytecode/BravePreferenceFragmentClassAdapter.java",
     "//brave/build/android/bytecode/java/org/brave/bytecode/BravePureJavaExceptionReporterClassAdapter.java",
     "//brave/build/android/bytecode/java/org/brave/bytecode/BraveQuickActionSearchWidgetProviderClassAdapter.java",
+    "//brave/build/android/bytecode/java/org/brave/bytecode/BraveRadioButtonGroupHomepagePreferenceClassAdapter.java",
     "//brave/build/android/bytecode/java/org/brave/bytecode/BraveReaderModeManagerClassAdapter.java",
     "//brave/build/android/bytecode/java/org/brave/bytecode/BraveReturnToChromeUtilClassAdapter.java",
     "//brave/build/android/bytecode/java/org/brave/bytecode/BraveSearchEngineAdapterClassAdapter.java",
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
index acfe5eb86f46..e9bb5a627478 100644
--- a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
@@ -36,6 +36,7 @@ public static ClassVisitor createAdapter(ClassVisitor chain) {
         chain = new BraveCachedFlagClassAdapter(chain);
         chain = new BraveChromeContextMenuPopulatorAdapter(chain);
         chain = new BraveQuickActionSearchWidgetProviderClassAdapter(chain);
+        chain = new BraveRadioButtonGroupHomepagePreferenceClassAdapter(chain);
         chain = new BraveClearBrowsingDataFragmentAdapter(chain);
         chain = new BraveCommandLineInitUtilClassAdapter(chain);
         chain = new BraveContentSettingsResourcesClassAdapter(chain);
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveRadioButtonGroupHomepagePreferenceClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveRadioButtonGroupHomepagePreferenceClassAdapter.java
new file mode 100644
index 000000000000..6dde1f122d7e
--- /dev/null
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveRadioButtonGroupHomepagePreferenceClassAdapter.java
@@ -0,0 +1,25 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.brave.bytecode;
+
+import org.objectweb.asm.ClassVisitor;
+
+public class BraveRadioButtonGroupHomepagePreferenceClassAdapter extends BraveClassVisitor {
+    static String sRadioButtonGroupHomepagePreferenceClassName =
+            "org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference";
+    static String sBraveRadioButtonGroupHomepagePreferenceClassName =
+            "org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference";
+
+    public BraveRadioButtonGroupHomepagePreferenceClassAdapter(ClassVisitor visitor) {
+        super(visitor);
+
+        makeNonFinalClass(sRadioButtonGroupHomepagePreferenceClassName);
+
+        changeSuperName(
+                sBraveRadioButtonGroupHomepagePreferenceClassName,
+                sRadioButtonGroupHomepagePreferenceClassName);
+    }
+}
diff --git a/patches/chrome-android-java-res-layout-radio_button_group_homepage_preference.xml.patch b/patches/chrome-android-java-res-layout-radio_button_group_homepage_preference.xml.patch
new file mode 100644
index 000000000000..75d07d1aea73
--- /dev/null
+++ b/patches/chrome-android-java-res-layout-radio_button_group_homepage_preference.xml.patch
@@ -0,0 +1,12 @@
+diff --git a/chrome/android/java/res/layout/radio_button_group_homepage_preference.xml b/chrome/android/java/res/layout/radio_button_group_homepage_preference.xml
+index 9f50c3de56b882ec146ab4c904171c51aac75299..5b29fa0d65e172c686aa800364e5b139bcda5909 100644
+--- a/chrome/android/java/res/layout/radio_button_group_homepage_preference.xml
++++ b/chrome/android/java/res/layout/radio_button_group_homepage_preference.xml
+@@ -36,6 +36,7 @@ found in the LICENSE file.
+         android:layout_width="match_parent"
+         android:layout_height="wrap_content"
+         app:primaryText="@string/options_homepage_chrome_homepage" />
++    <include layout="@layout/brave_homepage_mobile_bookmarks_button" />
+ 
+     <org.chromium.components.browser_ui.widget.RadioButtonWithEditText
+         android:id="@+id/radio_button_uri_edit"
diff --git a/patches/chrome-android-java-res-xml-homepage_preferences.xml.patch b/patches/chrome-android-java-res-xml-homepage_preferences.xml.patch
new file mode 100644
index 000000000000..9e7b3dcae8a5
--- /dev/null
+++ b/patches/chrome-android-java-res-xml-homepage_preferences.xml.patch
@@ -0,0 +1,13 @@
+diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/android/java/res/xml/homepage_preferences.xml
+index 3796a71e3382637681eca8611a761a466d81a307..4b9f1a5a75c49cfc77726ccafbb7a52ebe528044 100644
+--- a/chrome/android/java/res/xml/homepage_preferences.xml
++++ b/chrome/android/java/res/xml/homepage_preferences.xml
+@@ -14,7 +14,7 @@ found in the LICENSE file.
+         android:summaryOn="@string/text_on"
+         android:summaryOff="@string/text_off" />
+ 
+-    <org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference
++    <org.chromium.chrome.browser.homepage.settings.BraveRadioButtonGroupHomepagePreference
+         android:key="homepage_radio_group"
+         android:selectable="false"
+         app:allowDividerAbove="true"
diff --git a/test/BUILD.gn b/test/BUILD.gn
index bbed627be2b1..d2361f78c70d 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -1281,6 +1281,7 @@ if (is_android) {
       "//brave/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/BytecodeTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java",
+      "//brave/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/language/settings/BraveLanguageSettingsTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/password_manager/settings/BravePasswordSettingsTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/privacy/settings/BravePrivacySettingsTest.java",


Reviews:
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T15:25:22Z
user: login: mkarolin
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T15:45:54Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:14:56Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:26:39Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:29:42Z
user: login: simoarpe
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T16:48:53Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:54:39Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:54:53Z
user: login: simoarpe
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T16:57:29Z
user: login: SergeyZhukovsky
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T17:17:49Z
user: login: mkarolin
body: `strings`++
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-14T17:23:03Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T18:58:23Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T18:58:28Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T18:58:34Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T19:08:14Z
user: login: SergeyZhukovsky
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T19:20:11Z
user: login: SergeyZhukovsky
body: ++
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-14T19:20:25Z
user: login: simoarpe
body: 👍 Changes look good to me!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-14T20:29:48Z
user: login: bridiver
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T23:56:52Z
user: login: bridiver
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T23:57:21Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T13:38:52Z
user: login: samartnik
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T13:39:23Z
user: login: bridiver
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-15T21:45:11Z
user: login: bridiver
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T16:49:15Z
user: login: bridiver
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T17:06:16Z
user: login: bridiver
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T17:21:12Z
user: login: bridiver
body: would be great to follow-up to convert this to a robolectric test as that's what upstream has for HomepageSettings
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-16T17:26:36Z

Review comments:
diff_hunk: @@ -0,0 +1,13 @@
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+index 40cfaac31d778a0035a51c84d588ecf56eb19ca6..18dde71d347d41515546943c03a4bf12b14d3482 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+@@ -30,7 +30,7 @@ import java.lang.annotation.RetentionPolicy;
+  * a {@link RadioButtonWithDescription} that represent Chrome NTP, and a
+  * {@link RadioButtonWithEditText} that represents customized URL set by partner or user.
+  */
+-public final class RadioButtonGroupHomepagePreference extends Preference
path: patches/chrome-android-java-src-org-chromium-chrome-browser-homepage-settings-RadioButtonGroupHomepagePreference.java.patch
user: login: samartnik
body: We cannot inherit from the final class
created_at: 2025-05-14T15:25:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -4052,6 +4052,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne
     <message name="IDS_PRIVATE_TAB_SCREENSHOT_SUMMARY" desc="A summary to show private tab screenshot">
       If allowed, private tabs will also be visible when multiple apps are open.
     </message>
+    <message name="IDS_BRAVE_HOMEPAGE_MOBILE_BOOKMARKS_TEXT" desc="Text for Mobile Bookmarks setting in Home Page settings">
+      Mobile Bookmarks
path: browser/ui/android/strings/android_brave_strings.grd
user: login: mkarolin
body: @samartnik can you add a screenshot with the new string, please. Thanks!
created_at: 2025-05-14T15:45:54Z
author_association: COLLABORATOR
diff_hunk: @@ -4052,6 +4052,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne
     <message name="IDS_PRIVATE_TAB_SCREENSHOT_SUMMARY" desc="A summary to show private tab screenshot">
       If allowed, private tabs will also be visible when multiple apps are open.
     </message>
+    <message name="IDS_BRAVE_HOMEPAGE_MOBILE_BOOKMARKS_TEXT" desc="Text for Mobile Bookmarks setting in Home Page settings">
+      Mobile Bookmarks
path: browser/ui/android/strings/android_brave_strings.grd
user: login: samartnik
body: Sure, here it is

![Screenshot_20250514_121346](https://github.com/user-attachments/assets/670a5d98-3bf3-41aa-b416-07d88011e22c)

created_at: 2025-05-14T16:14:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -4052,6 +4052,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne
     <message name="IDS_PRIVATE_TAB_SCREENSHOT_SUMMARY" desc="A summary to show private tab screenshot">
       If allowed, private tabs will also be visible when multiple apps are open.
     </message>
+    <message name="IDS_BRAVE_HOMEPAGE_MOBILE_BOOKMARKS_TEXT" desc="Text for Mobile Bookmarks setting in Home Page settings">
+      Mobile Bookmarks
path: browser/ui/android/strings/android_brave_strings.grd
user: login: samartnik
body: Looks like it should be `Mobile bookmarks`, I'll fix this one
created_at: 2025-05-14T16:26:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -4052,6 +4052,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne
     <message name="IDS_PRIVATE_TAB_SCREENSHOT_SUMMARY" desc="A summary to show private tab screenshot">
       If allowed, private tabs will also be visible when multiple apps are open.
     </message>
+    <message name="IDS_BRAVE_HOMEPAGE_MOBILE_BOOKMARKS_TEXT" desc="Text for Mobile Bookmarks setting in Home Page settings">
+      Mobile Bookmarks
path: browser/ui/android/strings/android_brave_strings.grd
user: login: samartnik
body: That's how it looks now

![Screenshot_20250514_122850](https://github.com/user-attachments/assets/9a73b181-8518-46fd-b2b4-4d63463c25a5)

created_at: 2025-05-14T16:29:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: simoarpe
body: Shouldn't we appy the `@NullMarked` annotation to the class, because of the transition to NullAway configuration? https://chromium.googlesource.com/chromium/src/+/main/styleguide/java/nullaway.md
created_at: 2025-05-14T16:42:22Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: simoarpe
body: Is `MOBILE_BOOKMARKS_PATH` package private and not private because of the test?
created_at: 2025-05-14T16:45:18Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
+
+    private RadioButtonWithDescription mMobileBookmarks;
+    private RadioButtonWithEditText mCustomUri;
+    private boolean mSelectMobileBookmarks;
+
+    public BraveRadioButtonGroupHomepagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Called when the checked radio button has changed. When the selection is cleared, checkedId is
+     * -1.
+     *
+     * @param group The group in which the checked radio button has changed
+     * @param checkedId The unique identifier of the newly checked radio button
+     */
+    @Override
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        PreferenceValues preferenceValues = getPreferenceValue();
+        if (preferenceValues == null) return;
+
+        if (checkedId == R.id.brave_homepage_mobile_bookmarks) {
+            maybeSelectMobileBookmarks(true);
+        } else {
+            super.onCheckedChanged(group, checkedId);
+        }
+        maybeClearCustomUri();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        mMobileBookmarks =
+                (RadioButtonWithDescription)
+                        holder.findViewById(R.id.brave_homepage_mobile_bookmarks);
+        assert mMobileBookmarks != null : "Mobile bookmarks button is missing in the layout";
+
+        mCustomUri = (RadioButtonWithEditText) holder.findViewById(R.id.radio_button_uri_edit);
+        assert mCustomUri != null : "Custom URI button missing in the layout";
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    @Override
+    void setupPreferenceValues(@NonNull PreferenceValues value) {
+        super.setupPreferenceValues(value);
+
+        // If it is custom uri with mobile bookmarks path, set the mobile bookmarks radio button
+        // selected.
+        mSelectMobileBookmarks =
+                value.getCheckedOption() == HomepageOption.ENTRY_CUSTOM_URI
+                        && value.getCustomURI().equals(MOBILE_BOOKMARKS_PATH);
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    void maybeSelectMobileBookmarks(boolean forceSelect) {
+        if (mSelectMobileBookmarks || forceSelect) {
+            if (mMobileBookmarks != null) {
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: simoarpe
body: Double `if`s  can be inlined merging the logic into a single statement:

```java

if ((mSelectMobileBookmarks || forceSelect) && mMobileBookmarks != null) {
    // ...
```
created_at: 2025-05-14T16:48:41Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: samartnik
body: It should be, I'll address it
created_at: 2025-05-14T16:54:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: samartnik
body: Exactly
created_at: 2025-05-14T16:54:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: simoarpe
body: If that's the case I would annotate that with something like this: `@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)`

`(otherwise = VisibleForTesting.PRIVATE)` is probably not required/redundant.
<img width="658" alt="Cursor_and_java_-_How_do_I_test_a_class_that_has_private_methods__fields_or_inner_classes__-_Stack_Overflow" src="https://github.com/user-attachments/assets/5c3adfea-07a5-4e52-a65b-36424b44905b" />

Doing so, the IDE will give us a warning if not called properly.
created_at: 2025-05-14T16:57:29Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+  <!-- TODO(crbug.com/40672235): Change to the exact style TextMessagePreference is using. -->
+  <TextView
+      android:id="@+id/title"
+      style="@style/PreferenceTitle"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingTop="@dimen/homepage_preference_title_vertical_padding"
+      android:paddingEnd="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingBottom="@dimen/homepage_preference_title_vertical_padding"
+      android:text="@string/options_homepage_edit_label" />
+
+  <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+      android:id="@+id/radio_button_group"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusableInTouchMode="true">
+
+    <!-- TODO(crbug.com/40117411): Remove android:background for radio buttons here and below after enhancement. -->
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/radio_button_chrome_ntp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/options_homepage_chrome_homepage" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/brave_homepage_mobile_bookmarks"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
path: android/java/res/layout/radio_button_group_homepage_preference.xml
user: login: SergeyZhukovsky
body: I would try to `addView` into existing `RadioGroup` from upstream in Java code. That way we avoid replacing `android/java/res/layout/radio_button_group_homepage_preference.xml` entirely.
created_at: 2025-05-14T17:17:49Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: samartnik
body: Addressed here 067c9b454b850a75252f156f812d3bef4c54eb97
created_at: 2025-05-14T18:58:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: samartnik
body: Addressed here 067c9b454b850a75252f156f812d3bef4c54eb97
created_at: 2025-05-14T18:58:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,109 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.RadioGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceViewHolder;
+
+import org.chromium.chrome.R;
+import org.chromium.components.browser_ui.widget.RadioButtonWithDescription;
+import org.chromium.components.browser_ui.widget.RadioButtonWithEditText;
+
+/** Brave's version of a radio button group Preference used for Homepage Preference. */
+public final class BraveRadioButtonGroupHomepagePreference
+        extends RadioButtonGroupHomepagePreference {
+    static final String MOBILE_BOOKMARKS_PATH = "chrome-native://bookmarks/folder/1";
+
+    private RadioButtonWithDescription mMobileBookmarks;
+    private RadioButtonWithEditText mCustomUri;
+    private boolean mSelectMobileBookmarks;
+
+    public BraveRadioButtonGroupHomepagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Called when the checked radio button has changed. When the selection is cleared, checkedId is
+     * -1.
+     *
+     * @param group The group in which the checked radio button has changed
+     * @param checkedId The unique identifier of the newly checked radio button
+     */
+    @Override
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        PreferenceValues preferenceValues = getPreferenceValue();
+        if (preferenceValues == null) return;
+
+        if (checkedId == R.id.brave_homepage_mobile_bookmarks) {
+            maybeSelectMobileBookmarks(true);
+        } else {
+            super.onCheckedChanged(group, checkedId);
+        }
+        maybeClearCustomUri();
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        mMobileBookmarks =
+                (RadioButtonWithDescription)
+                        holder.findViewById(R.id.brave_homepage_mobile_bookmarks);
+        assert mMobileBookmarks != null : "Mobile bookmarks button is missing in the layout";
+
+        mCustomUri = (RadioButtonWithEditText) holder.findViewById(R.id.radio_button_uri_edit);
+        assert mCustomUri != null : "Custom URI button missing in the layout";
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    @Override
+    void setupPreferenceValues(@NonNull PreferenceValues value) {
+        super.setupPreferenceValues(value);
+
+        // If it is custom uri with mobile bookmarks path, set the mobile bookmarks radio button
+        // selected.
+        mSelectMobileBookmarks =
+                value.getCheckedOption() == HomepageOption.ENTRY_CUSTOM_URI
+                        && value.getCustomURI().equals(MOBILE_BOOKMARKS_PATH);
+
+        maybeSelectMobileBookmarks(false);
+        maybeClearCustomUri();
+    }
+
+    void maybeSelectMobileBookmarks(boolean forceSelect) {
+        if (mSelectMobileBookmarks || forceSelect) {
+            if (mMobileBookmarks != null) {
path: android/java/org/chromium/chrome/browser/homepage/settings/BraveRadioButtonGroupHomepagePreference.java
user: login: samartnik
body: Addressed here 067c9b454b850a75252f156f812d3bef4c54eb97
created_at: 2025-05-14T18:58:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+  <!-- TODO(crbug.com/40672235): Change to the exact style TextMessagePreference is using. -->
+  <TextView
+      android:id="@+id/title"
+      style="@style/PreferenceTitle"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingTop="@dimen/homepage_preference_title_vertical_padding"
+      android:paddingEnd="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingBottom="@dimen/homepage_preference_title_vertical_padding"
+      android:text="@string/options_homepage_edit_label" />
+
+  <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+      android:id="@+id/radio_button_group"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusableInTouchMode="true">
+
+    <!-- TODO(crbug.com/40117411): Remove android:background for radio buttons here and below after enhancement. -->
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/radio_button_chrome_ntp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/options_homepage_chrome_homepage" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/brave_homepage_mobile_bookmarks"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
path: android/java/res/layout/radio_button_group_homepage_preference.xml
user: login: samartnik
body: We would need to extend `RadioButtonWithDescriptionLayout` because they add additional button preparation in `onFinishInflate` (otherwise it doesn't properly act as a `RadioGroup`). But this will require replacing `RadioButtonWithDescriptionLayout` with `BraveRadioButtonWithDescriptionLayout` in the same `android/java/res/layout/radio_button_group_homepage_preference.xml` and the whole approach will be pointless.
created_at: 2025-05-14T19:08:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+  <!-- TODO(crbug.com/40672235): Change to the exact style TextMessagePreference is using. -->
+  <TextView
+      android:id="@+id/title"
+      style="@style/PreferenceTitle"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingTop="@dimen/homepage_preference_title_vertical_padding"
+      android:paddingEnd="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingBottom="@dimen/homepage_preference_title_vertical_padding"
+      android:text="@string/options_homepage_edit_label" />
+
+  <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+      android:id="@+id/radio_button_group"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusableInTouchMode="true">
+
+    <!-- TODO(crbug.com/40117411): Remove android:background for radio buttons here and below after enhancement. -->
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/radio_button_chrome_ntp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/options_homepage_chrome_homepage" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/brave_homepage_mobile_bookmarks"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
path: android/java/res/layout/radio_button_group_homepage_preference.xml
user: login: SergeyZhukovsky
body: ok, it looks like it would bring more patches in that case.
created_at: 2025-05-14T19:20:10Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,13 @@
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+index 40cfaac31d778a0035a51c84d588ecf56eb19ca6..18dde71d347d41515546943c03a4bf12b14d3482 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+@@ -30,7 +30,7 @@ import java.lang.annotation.RetentionPolicy;
+  * a {@link RadioButtonWithDescription} that represent Chrome NTP, and a
+  * {@link RadioButtonWithEditText} that represents customized URL set by partner or user.
+  */
+-public final class RadioButtonGroupHomepagePreference extends Preference
path: patches/chrome-android-java-src-org-chromium-chrome-browser-homepage-settings-RadioButtonGroupHomepagePreference.java.patch
user: login: bridiver
body: we can't remove final with asm?
created_at: 2025-05-14T23:56:52Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+  <!-- TODO(crbug.com/40672235): Change to the exact style TextMessagePreference is using. -->
+  <TextView
+      android:id="@+id/title"
+      style="@style/PreferenceTitle"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingTop="@dimen/homepage_preference_title_vertical_padding"
+      android:paddingEnd="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingBottom="@dimen/homepage_preference_title_vertical_padding"
+      android:text="@string/options_homepage_edit_label" />
+
+  <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+      android:id="@+id/radio_button_group"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusableInTouchMode="true">
+
+    <!-- TODO(crbug.com/40117411): Remove android:background for radio buttons here and below after enhancement. -->
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/radio_button_chrome_ntp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/options_homepage_chrome_homepage" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/brave_homepage_mobile_bookmarks"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithEditText
+        android:id="@+id/radio_button_uri_edit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/options_homepage_edit_hint"
+        android:inputType="textUri" />
+
+  </org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout>
+</LinearLayout>
path: android/java/res/layout/radio_button_group_homepage_preference.xml
user: login: bridiver
body: I would suggest adding `fix,-indent-with-non-tab,trailing-space,cr-at-eol` to `core.whitespace` in your gitconfig
created_at: 2025-05-14T23:57:21Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,13 @@
+diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+index 40cfaac31d778a0035a51c84d588ecf56eb19ca6..18dde71d347d41515546943c03a4bf12b14d3482 100644
+--- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
++++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java
+@@ -30,7 +30,7 @@ import java.lang.annotation.RetentionPolicy;
+  * a {@link RadioButtonWithDescription} that represent Chrome NTP, and a
+  * {@link RadioButtonWithEditText} that represents customized URL set by partner or user.
+  */
+-public final class RadioButtonGroupHomepagePreference extends Preference
path: patches/chrome-android-java-src-org-chromium-chrome-browser-homepage-settings-RadioButtonGroupHomepagePreference.java.patch
user: login: samartnik
body: Addressed here fa4e1e7cec354525750a0db9aea4d922884dca56
created_at: 2025-05-15T13:38:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2025 The Brave Authors. All rights reserved.
+     This Source Code Form is subject to the terms of the Mozilla Public
+     License, v. 2.0. If a copy of the MPL was not distributed with this file,
+     You can obtain one at https://mozilla.org/MPL/2.0/. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+  <!-- TODO(crbug.com/40672235): Change to the exact style TextMessagePreference is using. -->
+  <TextView
+      android:id="@+id/title"
+      style="@style/PreferenceTitle"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingStart="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingTop="@dimen/homepage_preference_title_vertical_padding"
+      android:paddingEnd="@dimen/homepage_preference_title_lateral_padding"
+      android:paddingBottom="@dimen/homepage_preference_title_vertical_padding"
+      android:text="@string/options_homepage_edit_label" />
+
+  <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout
+      android:id="@+id/radio_button_group"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:focusableInTouchMode="true">
+
+    <!-- TODO(crbug.com/40117411): Remove android:background for radio buttons here and below after enhancement. -->
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/radio_button_chrome_ntp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/options_homepage_chrome_homepage" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithDescription
+        android:id="@+id/brave_homepage_mobile_bookmarks"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:primaryText="@string/brave_homepage_mobile_bookmarks_text" />
+
+    <org.chromium.components.browser_ui.widget.RadioButtonWithEditText
+        android:id="@+id/radio_button_uri_edit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/options_homepage_edit_hint"
+        android:inputType="textUri" />
+
+  </org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout>
+</LinearLayout>
path: android/java/res/layout/radio_button_group_homepage_preference.xml
user: login: samartnik
body: Addressed here fa4e1e7cec354525750a0db9aea4d922884dca56
created_at: 2025-05-15T13:39:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,81 @@
+/* Copyright (c) 2025 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.homepage.settings;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.preference.Preference;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseJUnit4ClassRunner;
+import org.chromium.base.test.util.Batch;
+import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+
+/** Test for {@link BraveHomepageSettings} to check Brave related UI changes. */
+@Batch(Batch.PER_CLASS)
+@RunWith(BaseJUnit4ClassRunner.class)
path: android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java
user: login: bridiver
body: I think this should be using `ChromeJUnit4ClassRunner` since this is chromium code?
created_at: 2025-05-16T16:49:14Z
author_association: COLLABORATOR
diff_hunk: @@ -1281,6 +1281,7 @@ if (is_android) {
       "//brave/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/BytecodeTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java",
+      "//brave/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java",
path: test/BUILD.gn
user: login: bridiver
body: This should be in a BUILD.gn in brave/android/javatests similar to `chrome_test_java_org.chromium.chrome.browser.appearance` and then add a dep here for it. Generally speaking we shouldn't be adding test sources in `brave/android/javatests` and they should instead go in a `javatests` subdir for the relevant feature, but in this case it makes sense because the upstream code is here. 
created_at: 2025-05-16T17:06:16Z
author_association: COLLABORATOR
diff_hunk: @@ -1281,6 +1281,7 @@ if (is_android) {
       "//brave/android/javatests/org/chromium/chrome/browser/BraveSafetyNetThreatsPrioritiesTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/BytecodeTest.java",
       "//brave/android/javatests/org/chromium/chrome/browser/brave_wallet/BraveWalletUtilsTest.java",
+      "//brave/android/javatests/org/chromium/chrome/browser/homepage/settings/BraveHomepageSettingsTest.java",
path: test/BUILD.gn
user: login: bridiver
body: you can ignore this if we're going to follow-up to convert it to a robolectric test
created_at: 2025-05-16T17:21:12Z
author_association: COLLABORATOR

PR comments:
user: login: samartnik
created_at: 2025-05-16T19:10:00Z
body: Added here https://github.com/brave/brave-browser/issues/46134 to start intergration from converting `BraveHomepageSettingsTest`
author_association: CONTRIBUTOR
user: login: brave-builds
created_at: 2025-05-19T00:05:32Z
body: Released in [v1.80.76](https://github.com/brave/brave-browser/releases/tag/v1.80.76)
author_association: COLLABORATOR