diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni index 444fc9a076f..b7812da3341 100644 --- a/android/brave_java_sources.gni +++ b/android/brave_java_sources.gni @@ -367,6 +367,7 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/sync/BraveSyncDevices.java", "../../brave/android/java/org/chromium/chrome/browser/sync/settings/BraveManageSyncSettings.java", "../../brave/android/java/org/chromium/chrome/browser/tab/BraveTabHelpers.java", + "../../brave/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator.java", "../../brave/android/java/org/chromium/chrome/browser/tabmodel/BraveTabCreator.java", "../../brave/android/java/org/chromium/chrome/browser/tasks/BraveReturnToChromeUtil.java", "../../brave/android/java/org/chromium/chrome/browser/toolbar/BraveHomeButton.java", diff --git a/android/java/apk_for_test.flags b/android/java/apk_for_test.flags index 59cea06d387..0aa75c24d56 100644 --- a/android/java/apk_for_test.flags +++ b/android/java/apk_for_test.flags @@ -678,3 +678,11 @@ -keep class org.chromium.chrome.browser.notifications.BraveNotificationBuilder { public (...); } + +-keep class org.chromium.chrome.browser.tabbed_mode.TabbedRootUiCoordinator { + public (...); +} + +-keep class org.chromium.chrome.browser.tabbed_mode.BraveTabbedRootUiCoordinator { + public (...); +} diff --git a/android/java/org/chromium/chrome/browser/app/BraveActivity.java b/android/java/org/chromium/chrome/browser/app/BraveActivity.java index d99558afa28..aced6f977bb 100644 --- a/android/java/org/chromium/chrome/browser/app/BraveActivity.java +++ b/android/java/org/chromium/chrome/browser/app/BraveActivity.java @@ -18,6 +18,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -29,6 +30,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; @@ -166,6 +168,7 @@ import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tasks.tab_management.BraveTabUiFeatureUtilities; +import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarConfiguration; import org.chromium.chrome.browser.toolbar.top.BraveToolbarLayoutImpl; import org.chromium.chrome.browser.util.BraveConstants; import org.chromium.chrome.browser.util.BraveDbUtil; @@ -1991,4 +1994,21 @@ public abstract class BraveActivity extends C executeInitSafeBrowsing(BraveSafeBrowsingApiHandler.SAFE_BROWSING_INIT_INTERVAL_MS); }, delay); } + + public void updateBottomSheetPosition(int orientation) { + if (BottomToolbarConfiguration.isBottomToolbarEnabled()) { + // Ensure the bottom sheet's container is adjusted to the height of the bottom toolbar. + ViewGroup sheetContainer = findViewById(R.id.sheet_container); + assert sheetContainer != null; + + if (sheetContainer != null) { + CoordinatorLayout.LayoutParams params = + (CoordinatorLayout.LayoutParams) sheetContainer.getLayoutParams(); + params.bottomMargin = orientation == Configuration.ORIENTATION_LANDSCAPE + ? 0 + : getResources().getDimensionPixelSize(R.dimen.bottom_controls_height); + sheetContainer.setLayoutParams(params); + } + } + } } diff --git a/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator.java b/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator.java new file mode 100644 index 00000000000..4d688c345eb --- /dev/null +++ b/android/java/org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator.java @@ -0,0 +1,135 @@ +/* Copyright (c) 2023 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.tabbed_mode; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import org.chromium.base.Callback; +import org.chromium.base.jank_tracker.JankTracker; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.supplier.OneshotSupplier; +import org.chromium.base.supplier.Supplier; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.ActivityTabProvider; +import org.chromium.chrome.browser.app.BraveActivity; +import org.chromium.chrome.browser.app.tab_activity_glue.TabReparentingController; +import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.bookmarks.BookmarkModel; +import org.chromium.chrome.browser.bookmarks.TabBookmarker; +import org.chromium.chrome.browser.compositor.CompositorViewHolder; +import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; +import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; +import org.chromium.chrome.browser.flags.ActivityType; +import org.chromium.chrome.browser.fullscreen.BrowserControlsManager; +import org.chromium.chrome.browser.fullscreen.FullscreenManager; +import org.chromium.chrome.browser.layouts.LayoutStateProvider; +import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; +import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.share.ShareDelegate; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabCreatorManager; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; +import org.chromium.chrome.browser.toolbar.ToolbarIntentMetadata; +import org.chromium.chrome.browser.ui.appmenu.AppMenuBlocker; +import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; +import org.chromium.chrome.browser.ui.system.StatusBarColorController; +import org.chromium.chrome.browser.ui.system.StatusBarColorController.StatusBarColorProvider; +import org.chromium.chrome.features.start_surface.StartSurface; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.widget.InsetObserverView; +import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; +import org.chromium.ui.base.ActivityWindowAndroid; +import org.chromium.ui.base.IntentRequestTracker; +import org.chromium.ui.modaldialog.ModalDialogManager; + +import java.util.function.BooleanSupplier; +import java.util.function.Function; + +public class BraveTabbedRootUiCoordinator extends TabbedRootUiCoordinator { + protected AppCompatActivity mActivity; + + public BraveTabbedRootUiCoordinator(@NonNull AppCompatActivity activity, + @Nullable Callback onOmniboxFocusChangedListener, + @NonNull ObservableSupplier shareDelegateSupplier, + @NonNull ActivityTabProvider tabProvider, + @NonNull ObservableSupplier profileSupplier, + @NonNull ObservableSupplier bookmarkModelSupplier, + @NonNull ObservableSupplier tabBookmarkerSupplier, + @NonNull Supplier contextualSearchManagerSupplier, + @NonNull ObservableSupplier tabModelSelectorSupplier, + @NonNull OneshotSupplier startSurfaceSupplier, + @NonNull OneshotSupplier tabSwitcherSupplier, + @NonNull OneshotSupplier intentMetadataOneshotSupplier, + @NonNull OneshotSupplier layoutStateProviderOneshotSupplier, + @NonNull Supplier startSurfaceParentTabSupplier, + @NonNull BrowserControlsManager browserControlsManager, + @NonNull ActivityWindowAndroid windowAndroid, @NonNull JankTracker jankTracker, + @NonNull ActivityLifecycleDispatcher activityLifecycleDispatcher, + @NonNull ObservableSupplier layoutManagerSupplier, + @NonNull MenuOrKeyboardActionController menuOrKeyboardActionController, + @NonNull Supplier activityThemeColorSupplier, + @NonNull ObservableSupplier modalDialogManagerSupplier, + @NonNull AppMenuBlocker appMenuBlocker, + @NonNull BooleanSupplier supportsAppMenuSupplier, + @NonNull BooleanSupplier supportsFindInPage, + @NonNull Supplier tabCreatorManagerSupplier, + @NonNull FullscreenManager fullscreenManager, + @NonNull Supplier compositorViewHolderSupplier, + @NonNull Supplier tabContentManagerSupplier, + @NonNull Supplier snackbarManagerSupplier, + @ActivityType int activityType, @NonNull Supplier isInOverviewModeSupplier, + @NonNull Supplier isWarmOnResumeSupplier, + @NonNull AppMenuDelegate appMenuDelegate, + @NonNull StatusBarColorProvider statusBarColorProvider, + @NonNull ObservableSupplierImpl + ephemeralTabCoordinatorSupplier, + @NonNull IntentRequestTracker intentRequestTracker, int controlContainerHeightResource, + @NonNull Supplier insetObserverViewSupplier, + @NonNull Function backButtonShouldCloseTabFn, + OneshotSupplier tabReparentingControllerSupplier, + boolean initializeUiWithIncognitoColors, @NonNull BackPressManager backPressManager) { + super(activity, onOmniboxFocusChangedListener, shareDelegateSupplier, tabProvider, + profileSupplier, bookmarkModelSupplier, tabBookmarkerSupplier, + contextualSearchManagerSupplier, tabModelSelectorSupplier, startSurfaceSupplier, + tabSwitcherSupplier, intentMetadataOneshotSupplier, + layoutStateProviderOneshotSupplier, startSurfaceParentTabSupplier, + browserControlsManager, windowAndroid, jankTracker, activityLifecycleDispatcher, + layoutManagerSupplier, menuOrKeyboardActionController, activityThemeColorSupplier, + modalDialogManagerSupplier, appMenuBlocker, supportsAppMenuSupplier, + supportsFindInPage, tabCreatorManagerSupplier, fullscreenManager, + compositorViewHolderSupplier, tabContentManagerSupplier, snackbarManagerSupplier, + activityType, isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate, + statusBarColorProvider, ephemeralTabCoordinatorSupplier, intentRequestTracker, + controlContainerHeightResource, insetObserverViewSupplier, + backButtonShouldCloseTabFn, tabReparentingControllerSupplier, + initializeUiWithIncognitoColors, backPressManager); + + mActivity = activity; + } + + @Override + public void onPostInflationStartup() { + super.onPostInflationStartup(); + + assert mActivity instanceof BraveActivity; + + if (mActivity instanceof BraveActivity) { + ((BraveActivity) mActivity) + .updateBottomSheetPosition( + mActivity.getResources().getConfiguration().orientation); + } + } +} diff --git a/android/java/org/chromium/chrome/browser/toolbar/BraveToolbarManager.java b/android/java/org/chromium/chrome/browser/toolbar/BraveToolbarManager.java index 2a9cdbfd1a5..dde689db9dc 100644 --- a/android/java/org/chromium/chrome/browser/toolbar/BraveToolbarManager.java +++ b/android/java/org/chromium/chrome/browser/toolbar/BraveToolbarManager.java @@ -327,6 +327,12 @@ public class BraveToolbarManager extends ToolbarManager { boolean isBottomToolbarVisible = newOrientation != Configuration.ORIENTATION_LANDSCAPE; setBottomToolbarVisible(isBottomToolbarVisible); } + + assert mActivity instanceof BraveActivity; + + if (mActivity instanceof BraveActivity) { + ((BraveActivity) mActivity).updateBottomSheetPosition(newOrientation); + } } protected void updateBookmarkButtonStatus() { diff --git a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java index 9fa27b485ec..b9640423dc8 100644 --- a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java +++ b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java @@ -46,6 +46,7 @@ import org.chromium.chrome.browser.feed.sort_ui.FeedOptionsCoordinator; import org.chromium.chrome.browser.feed.webfeed.WebFeedBridge; import org.chromium.chrome.browser.feed.webfeed.WebFeedSnackbarController; 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.identity_disc.IdentityDiscController; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -96,10 +97,12 @@ import org.chromium.chrome.browser.toolbar.top.ToolbarActionModeCallback; import org.chromium.chrome.browser.toolbar.top.ToolbarControlContainer; import org.chromium.chrome.browser.toolbar.top.ToolbarLayout; import org.chromium.chrome.browser.toolbar.top.ToolbarTablet.OfflineDownloader; +import org.chromium.chrome.browser.ui.appmenu.AppMenuBlocker; import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.native_page.NativePageHost; import org.chromium.chrome.browser.ui.system.StatusBarColorController; +import org.chromium.chrome.browser.ui.system.StatusBarColorController.StatusBarColorProvider; import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; @@ -110,6 +113,7 @@ import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; import org.chromium.components.browser_ui.site_settings.SiteSettingsDelegate; import org.chromium.components.browser_ui.site_settings.Website; import org.chromium.components.browser_ui.site_settings.WebsiteAddress; +import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.displaystyle.UiConfig; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.components.omnibox.AutocompleteMatch; @@ -118,6 +122,8 @@ import org.chromium.components.permissions.PermissionDialogController; import org.chromium.components.search_engines.TemplateUrlService; import org.chromium.content_public.browser.BrowserContextHandle; import org.chromium.ui.ViewProvider; +import org.chromium.ui.base.ActivityWindowAndroid; +import org.chromium.ui.base.IntentRequestTracker; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowDelegate; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -130,6 +136,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; import java.util.function.BooleanSupplier; +import java.util.function.Function; /** * Tests to check whether classes, methods and fields exist for bytecode manipulation. @@ -308,6 +315,10 @@ public class BytecodeTest { classExists("org/chromium/chrome/browser/settings/BravePreferenceFragment")); Assert.assertTrue( classExists("org/chromium/chrome/browser/preferences/ChromePreferenceKeyChecker")); + Assert.assertTrue( + classExists("org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator")); + Assert.assertTrue(classExists( + "org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator")); } @Test @@ -733,6 +744,22 @@ public class BytecodeTest { "org/chromium/chrome/browser/notifications/StandardNotificationBuilder", "org/chromium/chrome/browser/notifications/BraveNotificationBuilder", Context.class)); + Assert.assertTrue(constructorsMatch( + "org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator", + "org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator", + AppCompatActivity.class, Callback.class, ObservableSupplier.class, + ActivityTabProvider.class, ObservableSupplier.class, ObservableSupplier.class, + ObservableSupplier.class, Supplier.class, ObservableSupplier.class, + OneshotSupplier.class, OneshotSupplier.class, OneshotSupplier.class, + OneshotSupplier.class, Supplier.class, BrowserControlsManager.class, + ActivityWindowAndroid.class, JankTracker.class, ActivityLifecycleDispatcher.class, + ObservableSupplier.class, MenuOrKeyboardActionController.class, Supplier.class, + ObservableSupplier.class, AppMenuBlocker.class, BooleanSupplier.class, + BooleanSupplier.class, Supplier.class, FullscreenManager.class, Supplier.class, + Supplier.class, Supplier.class, int.class, Supplier.class, Supplier.class, + AppMenuDelegate.class, StatusBarColorProvider.class, ObservableSupplierImpl.class, + IntentRequestTracker.class, int.class, Supplier.class, Function.class, + OneshotSupplier.class, boolean.class, BackPressManager.class)); } @Test diff --git a/build/android/bytecode/BUILD.gn b/build/android/bytecode/BUILD.gn index b6cdceea6f8..b511941be78 100644 --- a/build/android/bytecode/BUILD.gn +++ b/build/android/bytecode/BUILD.gn @@ -80,6 +80,7 @@ java_binary("java_bytecode_rewriter") { "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTabSwitcherModeTopToolbarClassAdapter.java", "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTabUiThemeProviderClassAdapter.java", "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTabbedActivityClassAdapter.java", + "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTabbedRootUiCoordinatorClassAdapter.java", "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTemplateUrlServiceFactoryClassAdapter.java", "//brave/build/android/bytecode/java/org/brave/bytecode/BraveThemeUtilsClassAdapter.java", "//brave/build/android/bytecode/java/org/brave/bytecode/BraveTileViewClassAdapter.java", diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java index aec238879f5..2ec8d4ce5a8 100644 --- a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java +++ b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java @@ -79,6 +79,7 @@ public class BraveClassAdapter { chain = new BraveTabSwitcherModeTopToolbarClassAdapter(chain); chain = new BraveTabUiThemeProviderClassAdapter(chain); chain = new BraveTabbedActivityClassAdapter(chain); + chain = new BraveTabbedRootUiCoordinatorClassAdapter(chain); chain = new BraveTemplateUrlServiceFactoryClassAdapter(chain); chain = new BraveThemeUtilsClassAdapter(chain); chain = new BraveTileViewClassAdapter(chain); diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveTabbedRootUiCoordinatorClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveTabbedRootUiCoordinatorClassAdapter.java new file mode 100644 index 00000000000..fe89db9809c --- /dev/null +++ b/build/android/bytecode/java/org/brave/bytecode/BraveTabbedRootUiCoordinatorClassAdapter.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2023 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 BraveTabbedRootUiCoordinatorClassAdapter extends BraveClassVisitor { + static String sTabbedRootUiCoordinatorClassName = + "org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator"; + static String sBraveTabbedRootUiCoordinatorClassName = + "org/chromium/chrome/browser/tabbed_mode/BraveTabbedRootUiCoordinator"; + + public BraveTabbedRootUiCoordinatorClassAdapter(ClassVisitor visitor) { + super(visitor); + + redirectConstructor( + sTabbedRootUiCoordinatorClassName, sBraveTabbedRootUiCoordinatorClassName); + } +}