[Android] Wait for native initialization when creating bottom strip (#28728)

* [cr137] [Android] Wait for native initialization when creating bottom strip

Chromium change:
https://chromium.googlesource.com/chromium/src/+/ea006a988d2a36db0eb25801e1c02e9c6e9f5b86

[Tab Group UI] Wait for native initialization when creating bottom strip

Wait for native initialization to complete before initializing the
bottom tab strip. Otherwise it will try to initialize pre-native and
crash. This appears to have regressed in M134/M135 likely due to some
lifecycle change for the BottomControlsCoordinator.

Fixed: 407305088

* Suppressed warning around ContextUtils.getAppSharedPreferences()

---------

Co-authored-by: Artem Samoilenko <artem@brave.com>
This commit is contained in:
AlexeyBarabash
2025-04-18 13:50:22 +03:00
committed by GitHub
co-authored by Artem Samoilenko
parent af6a913380
commit 29a7bfd427
5 changed files with 86 additions and 64 deletions
+2
View File
@@ -154,6 +154,8 @@
*** mReadAloudControllerSupplier;
*** mTopUiThemeColorProvider;
*** mCurrentOrientation;
*** mInitializedWithNative;
*** mTabGroupUiOneshotSupplier;
*** onOrientationChange(...);
*** updateBookmarkButtonStatus(...);
*** updateReloadState(...);
@@ -23,7 +23,6 @@ import org.chromium.base.ContextUtils;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneshotSupplier;
import org.chromium.base.supplier.OneshotSupplierImpl;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
@@ -59,8 +58,7 @@ import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
import org.chromium.chrome.browser.tabmodel.TabClosureParams;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tasks.tab_management.TabGroupUi;
import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegateProvider;
import org.chromium.chrome.browser.tasks.tab_management.TabGroupUiOneshotSupplier;
import org.chromium.chrome.browser.theme.BottomUiThemeColorProvider;
import org.chromium.chrome.browser.theme.ThemeColorProvider;
import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
@@ -123,9 +121,10 @@ public class BraveToolbarManager extends ToolbarManager
private ObservableSupplier<ReadAloudController> mReadAloudControllerSupplier;
private TopUiThemeColorProvider mTopUiThemeColorProvider;
private int mCurrentOrientation;
private boolean mInitializedWithNative;
private @Nullable TabGroupUiOneshotSupplier mTabGroupUiOneshotSupplier;
// Own members.
private TabGroupUi mTabGroupUi;
private boolean mIsBraveBottomControlsVisible;
private ObservableSupplier<Boolean> mOmniboxFocusStateSupplier;
private OneshotSupplier<LayoutStateProvider> mLayoutStateProviderSupplier;
@@ -139,11 +138,10 @@ public class BraveToolbarManager extends ToolbarManager
private ObservableSupplier<EdgeToEdgeController> mEdgeToEdgeControllerSupplier;
private ObservableSupplier<Profile> mProfileSupplier;
private final BrowserControlsSizer mBrowserControlsSizer;
private OneshotSupplierImpl<BottomControlsContentDelegate> mContentDelegateSupplier =
new OneshotSupplierImpl<>();
private final DataSharingTabManager mDataSharingTabManager;
private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
private LayoutStateProvider.LayoutStateObserver mLayoutStateObserver;
private Runnable mOpenGridTabSwitcherHandler;
public BraveToolbarManager(
AppCompatActivity activity,
@@ -288,29 +286,31 @@ public class BraveToolbarManager extends ToolbarManager
mIncognitoStateProvider,
mActivity);
mTabGroupUi =
TabManagementDelegateProvider.getDelegate()
.createTabGroupUi(
mActivity,
mBottomControls.findViewById(R.id.bottom_container_slot),
mBrowserControlsSizer,
mScrimManager,
mOmniboxFocusStateSupplier,
mBottomSheetController,
mDataSharingTabManager,
mTabModelSelector,
mTabContentManager,
mTabCreatorManager,
mLayoutStateProviderSupplier,
mModalDialogManagerSupplier.get(),
bottomUiThemeColorProvider);
mContentDelegateSupplier.set(mTabGroupUi);
mTabGroupUiOneshotSupplier =
new TabGroupUiOneshotSupplier(
mActivityTabProvider,
mTabModelSelector,
mActivity,
mBottomControls.findViewById(R.id.bottom_container_slot),
mBrowserControlsSizer,
mScrimManager,
mOmniboxFocusStateSupplier,
mBottomSheetController,
mDataSharingTabManager,
mTabContentManager,
mTabCreatorManager,
mLayoutStateProviderSupplier,
mModalDialogManagerSupplier.get(),
bottomUiThemeColorProvider);
var bottomControlsContentDelegateSupplier =
(OneshotSupplier<BottomControlsContentDelegate>)
((OneshotSupplier<? extends BottomControlsContentDelegate>)
mTabGroupUiOneshotSupplier);
BrowserStateBrowserControlsVisibilityDelegate controlsVisibilityDelegate =
mBrowserControlsSizer.getBrowserVisibilityDelegate();
assert controlsVisibilityDelegate != null;
mBottomControlsCoordinatorSupplier.set(
var bottomControlsCoordinator =
new BraveBottomControlsCoordinator(
mLayoutStateProviderSupplier,
BottomTabSwitcherActionMenuCoordinator.createOnLongClickListener(
@@ -336,14 +336,49 @@ public class BraveToolbarManager extends ToolbarManager
mFullscreenManager,
mEdgeToEdgeControllerSupplier,
mBottomControls,
mContentDelegateSupplier,
bottomControlsContentDelegateSupplier,
mTabObscuringHandler,
mOverlayPanelVisibilitySupplier,
getConstraintsProxy(),
/* readAloudRestoringSupplier= */ () -> {
final var readAloud = mReadAloudControllerSupplier.get();
return readAloud != null && readAloud.isRestoringPlayer();
}));
});
if (mInitializedWithNative) {
Runnable closeAllTabsAction =
() -> {
mTabModelSelector
.getModel(mIncognitoStateProvider.isIncognitoSelected())
.getTabRemover()
.closeTabs(TabClosureParams.closeAllTabs().build(), false);
};
assert (mActivity instanceof ChromeActivity);
OnClickListener wrappedNewTabClickHandler =
v -> {
recordNewTabClick();
((ChromeActivity) mActivity)
.getMenuOrKeyboardActionController()
.onMenuOrKeyboardAction(
mIncognitoStateProvider.isIncognitoSelected()
? R.id.new_incognito_tab_menu_id
: R.id.new_tab_menu_id,
false);
};
bottomControlsCoordinator.initializeWithNative(
mActivity,
mCompositorViewHolder.getResourceManager(),
mCompositorViewHolder.getLayoutManager(),
/*tabSwitcherListener*/ v -> mOpenGridTabSwitcherHandler.run(),
/*newTabClickListener*/ wrappedNewTabClickHandler,
mWindowAndroid,
mTabModelSelector,
mIncognitoStateProvider,
mActivity.findViewById(R.id.control_container),
closeAllTabsAction);
}
mBottomControlsCoordinatorSupplier.set(bottomControlsCoordinator);
mBottomControls.setBottomControlsCoordinatorSupplier(
mBottomControlsCoordinatorSupplier);
updateBraveBottomControlsVisibility();
@@ -360,6 +395,10 @@ public class BraveToolbarManager extends ToolbarManager
// Also ToolbarManager.initializeWithNative calls
// TopToolbarCoordinator.initializeWithNative where 3rd parameter is
// `OnClickListener tabSwitcherClickHandler`. So it is a tabSwitcherClickHandler.
//
// Suppress to observe SharedPreferences, which is discouraged; use another messaging channel
// instead.
@SuppressWarnings("UseSharedPreferencesManagerFromChromeCheck")
@Override
public void initializeWithNative(
@NonNull LayoutManagerImpl layoutManager,
@@ -379,45 +418,10 @@ public class BraveToolbarManager extends ToolbarManager
archivedTabCountSupplier,
tabModelNotificationDotSupplier);
mOpenGridTabSwitcherHandler = openGridTabSwitcherHandler;
if (isToolbarPhone() && BottomToolbarConfiguration.isBraveBottomControlsEnabled()) {
enableBottomControls();
Runnable closeAllTabsAction =
() -> {
mTabModelSelector
.getModel(mIncognitoStateProvider.isIncognitoSelected())
.getTabRemover()
.closeTabs(TabClosureParams.closeAllTabs().build(), false);
};
assert (mActivity instanceof ChromeActivity);
OnClickListener wrappedNewTabClickHandler =
v -> {
recordNewTabClick();
((ChromeActivity) mActivity)
.getMenuOrKeyboardActionController()
.onMenuOrKeyboardAction(
mIncognitoStateProvider.isIncognitoSelected()
? R.id.new_incognito_tab_menu_id
: R.id.new_tab_menu_id,
false);
};
assert (mBottomControlsCoordinatorSupplier.get()
instanceof BraveBottomControlsCoordinator);
((BraveBottomControlsCoordinator) mBottomControlsCoordinatorSupplier.get())
.initializeWithNative(
mActivity,
mCompositorViewHolder.getResourceManager(),
mCompositorViewHolder.getLayoutManager(),
/*tabSwitcherListener*/ v -> openGridTabSwitcherHandler.run(),
/*newTabClickListener*/ wrappedNewTabClickHandler,
mWindowAndroid,
mTabModelSelector,
mIncognitoStateProvider,
mActivity.findViewById(R.id.control_container),
closeAllTabsAction);
mLocationBar.getContainerView().setAccessibilityTraversalBefore(R.id.bottom_toolbar);
ContextUtils.getAppSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
}
@@ -115,6 +115,8 @@ public class BraveBottomControlsCoordinator extends BottomControlsCoordinator {
IncognitoStateProvider incognitoStateProvider,
ViewGroup topToolbarRoot,
Runnable closeAllTabsAction) {
super.initializeWithNative();
if (BottomToolbarConfiguration.isBraveBottomControlsEnabled()) {
mBottomToolbarCoordinator =
new BottomToolbarCoordinator(