Commit d8533d8d authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Commit Bot

Toolbar: No ActivityTabProvider in toolbar/

This CL removes the dependency on ActivityTab{Provider/TabObserver} in
toolbar/ package. They are replaced with a new CurrentTabObserver that
works as a stop-gap solution.

Bug: 1127732
Change-Id: I69e4272d38e26e70e62c31a6400859832dd70a2f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2505297
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826541}
parent dde41776
......@@ -18,6 +18,7 @@ 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.ActivityTabProvider.ActivityTabTabObserver;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl;
import org.chromium.chrome.browser.banners.AppBannerInProductHelpController;
......@@ -87,6 +88,8 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
private NavigationSheet mNavigationSheet;
private ComposedBrowserControlsVisibilityDelegate mAppBrowserControlsVisibilityDelegate;
private LayoutManagerImpl mLayoutManager;
private ObservableSupplierImpl<Tab> mToolbarButtonIphTabSupplier;
private ActivityTabTabObserver mToolbarButtonIphTabObserver;
/**
* Construct a new TabbedRootUiCoordinator.
......@@ -155,6 +158,7 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
if (mToolbarButtonInProductHelpController != null) {
mToolbarButtonInProductHelpController.destroy();
mToolbarButtonIphTabObserver.destroy();
}
if (mAppBannerInProductHelpController != null) {
......@@ -309,9 +313,19 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
private void initializeIPH(boolean intentWithEffect) {
if (mActivity == null) return;
mToolbarButtonIphTabSupplier = new ObservableSupplierImpl<>();
mToolbarButtonInProductHelpController =
new ToolbarButtonInProductHelpController(mActivity, mAppMenuCoordinator,
mActivity.getLifecycleDispatcher(), mActivity.getActivityTabProvider());
mActivity.getLifecycleDispatcher(), mToolbarButtonIphTabSupplier);
ActivityTabProvider activityTabProvider = mActivity.getActivityTabProvider();
mToolbarButtonIphTabObserver = new ActivityTabTabObserver(activityTabProvider) {
@Override
public void onObservingDifferentTab(Tab tab, boolean hint) {
mToolbarButtonIphTabSupplier.set(tab);
}
};
mToolbarButtonIphTabSupplier.set(activityTabProvider.get());
boolean didTriggerPromo = triggerPromo(intentWithEffect);
if (!didTriggerPromo) {
mToolbarButtonInProductHelpController.showColdStartIPH();
......
......@@ -5,10 +5,11 @@ package org.chromium.chrome.browser.toolbar;
import android.os.Handler;
import androidx.annotation.NonNull;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.task.PostTask;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl;
......@@ -24,6 +25,8 @@ import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.previews.Previews;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.CurrentTabObserver;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.translate.TranslateBridge;
import org.chromium.chrome.browser.translate.TranslateUtils;
......@@ -46,7 +49,7 @@ import org.chromium.content_public.browser.UiThreadTaskTraits;
*/
public class ToolbarButtonInProductHelpController
implements ScreenshotMonitorDelegate, PauseResumeWithNativeObserver {
private final ActivityTabTabObserver mPageLoadObserver;
private final CurrentTabObserver mPageLoadObserver;
private final ChromeActivity mActivity;
private final AppMenuPropertiesDelegate mAppMenuPropertiesDelegate;
private final ScreenshotMonitor mScreenshotMonitor;
......@@ -54,15 +57,23 @@ public class ToolbarButtonInProductHelpController
private UserEducationHelper mUserEducationHelper;
private final Handler mHandler = new Handler();
public ToolbarButtonInProductHelpController(final ChromeActivity activity,
AppMenuCoordinator appMenuCoordinator, ActivityLifecycleDispatcher lifecycleDispatcher,
ActivityTabProvider tabProvider) {
/**
* @param activity {@link ChromeActivity} on which this class runs.
* @param appMenuCoordinator {@link AppMenuCoordinator} whose visual state is to be updated
* accordingly.
* @param lifecycleDispatcher {@link LifecycleDispatcher} that helps observe activity lifecycle.
* @param tabSupplier An observable supplier of the current {@link Tab}.
*/
public ToolbarButtonInProductHelpController(@NonNull final ChromeActivity activity,
@NonNull AppMenuCoordinator appMenuCoordinator,
@NonNull ActivityLifecycleDispatcher lifecycleDispatcher,
@NonNull ObservableSupplier<Tab> tabSupplier) {
mActivity = activity;
mUserEducationHelper =
new UserEducationHelper(mActivity, mHandler, TrackerFactory::getTrackerForProfile);
mScreenshotMonitor = new ScreenshotMonitor(this);
lifecycleDispatcher.register(this);
mPageLoadObserver = new ActivityTabTabObserver(tabProvider) {
mPageLoadObserver = new CurrentTabObserver(tabSupplier, new EmptyTabObserver() {
/**
* Stores total data saved at the start of a page load. Used to calculate delta at the
* end of page load, which is just an estimate of the data saved for the current page
......@@ -125,16 +136,14 @@ public class ToolbarButtonInProductHelpController
Profile.fromWebContents(tab.getWebContents()));
tracker.notifyEvent(EventConstants.USER_HAS_SEEN_DINO);
}
};
});
mAppMenuHandler = appMenuCoordinator.getAppMenuHandler();
mAppMenuPropertiesDelegate = appMenuCoordinator.getAppMenuPropertiesDelegate();
}
public void destroy() {
if (mPageLoadObserver != null) {
mPageLoadObserver.destroy();
}
mPageLoadObserver.destroy();
}
/**
......
......@@ -46,7 +46,9 @@ import org.chromium.chrome.browser.compositor.Invalidator;
import org.chromium.chrome.browser.compositor.layouts.Layout;
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl;
import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver;
import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator;
import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbar;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.findinpage.FindToolbarManager;
import org.chromium.chrome.browser.findinpage.FindToolbarObserver;
......@@ -160,6 +162,8 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
private ObservableSupplierImpl<BottomControlsCoordinator> mBottomControlsCoordinatorSupplier =
new ObservableSupplierImpl<>();
private final ObservableSupplierImpl<Tab> mActivityTabSupplier = new ObservableSupplierImpl<>();
private TopToolbarOverlayCoordinator mOverlayCoordinator;
private TabModelSelector mTabModelSelector;
private TabModelSelectorObserver mTabModelSelectorObserver;
private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
......@@ -436,14 +440,15 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
}
mProgressBarCoordinator =
new LoadProgressCoordinator(mActivityTabProvider, mToolbar.getProgressBar());
new LoadProgressCoordinator(mActivityTabSupplier, mToolbar.getProgressBar());
mToolbar.addUrlExpansionObserver(statusBarColorController);
mActivityTabTabObserver = new ActivityTabProvider.ActivityTabTabObserver(
mActivityTabProvider) {
@Override
public void onObservingDifferentTab(Tab tab, boolean hint) {
mActivityTabSupplier.set(tab);
// ActivityTabProvider will null out the tab passed to onObservingDifferentTab when
// the tab is non-interactive (e.g. when entering the TabSwitcher), but in those
// cases we actually still want to use the most recently selected tab.
......@@ -927,9 +932,10 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
// clang-format off
mBottomControlsCoordinatorSupplier.set(new BottomControlsCoordinator(mBrowserControlsSizer,
mFullscreenManager, mActivity.findViewById(R.id.bottom_controls_stub),
mActivityTabProvider, mAppThemeColorProvider, mShareDelegateSupplier,
mAppThemeColorProvider, mShareDelegateSupplier,
mMenuButtonCoordinator.getMenuButtonHelperSupplier(),
mToolbarTabController::openHomepage, (reason) -> setUrlBarFocus(true, reason),
mToolbarTabController::openHomepage,
mCallbackController.makeCancelable((reason) -> setUrlBarFocus(true, reason)),
mScrimCoordinator, mOmniboxFocusStateSupplier));
// clang-format on
}
......@@ -972,8 +978,18 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
mToolbar.initializeWithNative(layoutManager::requestUpdate, tabSwitcherClickHandler,
tabSwitcherLongClickHandler, newTabClickHandler, bookmarkClickHandler,
customTabsBackClickHandler, layoutManager, mActivityTabProvider,
mBrowserControlsSizer);
customTabsBackClickHandler, mBrowserControlsSizer);
// If fullscreen is disabled, don't bother creating this overlay; only the android view will
// ever be shown.
if (DeviceClassManager.enableFullscreen()) {
mOverlayCoordinator = new TopToolbarOverlayCoordinator(mActivity, layoutManager,
mControlContainer::getProgressBarDrawingInfo, mActivityTabProvider,
mBrowserControlsSizer, layoutManager::getResourceManager);
layoutManager.addSceneOverlay(mOverlayCoordinator);
ToolbarLayout toolbarLayout = mActivity.findViewById(R.id.toolbar);
toolbarLayout.setOverlayVisibilityCallback(mCallbackController.makeCancelable(
mOverlayCoordinator::setIsAndroidViewVisible));
}
mToolbar.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
......@@ -1038,18 +1054,18 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
mActivity, mHandler, TrackerFactory::getTrackerForProfile);
View homeButton = mControlContainer.findViewById(R.id.home_button);
mHomeButtonCoordinator = new HomeButtonCoordinator(mActivity, homeButton,
mActivityTabProvider, userEducationHelper,
mIncognitoStateProvider::isIncognitoSelected, mIntentMetadataOneshotSupplier,
mPromoShownOneshotSupplier, HomepageManager::isHomepageNonNtp);
userEducationHelper, mIncognitoStateProvider::isIncognitoSelected,
mIntentMetadataOneshotSupplier, mPromoShownOneshotSupplier,
HomepageManager::isHomepageNonNtp, mActivityTabSupplier);
ToggleTabStackButton toggleTabStackButton =
mControlContainer.findViewById(R.id.tab_switcher_button);
mToggleTabStackButtonCoordinator = new ToggleTabStackButtonCoordinator(mActivity,
toggleTabStackButton, mActivityTabProvider, userEducationHelper,
toggleTabStackButton, userEducationHelper,
mIncognitoStateProvider::isIncognitoSelected, mIntentMetadataOneshotSupplier,
mPromoShownOneshotSupplier, mLayoutStateProviderSupplier,
mToolbar::setNewTabButtonHighlight);
mToolbar::setNewTabButtonHighlight, mActivityTabSupplier);
}
mActivityTabSupplier.set(mActivityTabProvider.get());
TraceEvent.end("ToolbarManager.initializeWithNative");
}
......@@ -1144,6 +1160,11 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
mBottomControlsCoordinatorSupplier = null;
}
if (mOverlayCoordinator != null) {
mOverlayCoordinator.destroy();
mOverlayCoordinator = null;
}
mToolbar.removeUrlExpansionObserver(mStatusBarColorController);
mToolbar.destroy();
......@@ -1173,6 +1194,8 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
mActivityTabTabObserver = null;
}
if (mProgressBarCoordinator != null) mProgressBarCoordinator.destroy();
if (mFindToolbarManager != null) {
mFindToolbarManager.removeObserver(mFindToolbarObserver);
mFindToolbarManager = null;
......
......@@ -17,7 +17,6 @@ import org.chromium.base.Callback;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer;
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl;
import org.chromium.chrome.browser.fullscreen.FullscreenManager;
......@@ -64,7 +63,6 @@ public class BottomControlsCoordinator {
* height for the renderer.
* @param fullscreenManager A {@link FullscreenManager} to listen for fullscreen changes.
* @param stub The bottom controls {@link ViewStub} to inflate.
* @param tabProvider
* @param themeColorProvider The {@link ThemeColorProvider} for the bottom toolbar.
* @param shareDelegateSupplier The supplier for the {@link ShareDelegate} the bottom controls
* should use to share content.
......@@ -76,7 +74,7 @@ public class BottomControlsCoordinator {
*/
@SuppressLint("CutPasteId") // Not actually cut and paste since it's View vs ViewGroup.
public BottomControlsCoordinator(BrowserControlsSizer controlsSizer,
FullscreenManager fullscreenManager, ViewStub stub, ActivityTabProvider tabProvider,
FullscreenManager fullscreenManager, ViewStub stub,
ThemeColorProvider themeColorProvider,
ObservableSupplier<ShareDelegate> shareDelegateSupplier,
ObservableSupplier<AppMenuButtonHelper> menuButtonHelperSupplier,
......
......@@ -4,7 +4,10 @@
package org.chromium.chrome.browser.toolbar.load_progress;
import org.chromium.chrome.browser.ActivityTabProvider;
import androidx.annotation.NonNull;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.ToolbarProgressBar;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -21,11 +24,15 @@ public class LoadProgressCoordinator {
private final PropertyModelChangeProcessor<PropertyModel, ToolbarProgressBar, PropertyKey>
mPropertyModelChangeProcessor;
public LoadProgressCoordinator(
ActivityTabProvider activityTabProvider, ToolbarProgressBar progressBarView) {
/**
* @param tabSupplier An observable supplier of the current {@link Tab}.
* @param progressBarView Toolbar progress bar view.
*/
public LoadProgressCoordinator(@NonNull ObservableSupplier<Tab> tabSupplier,
@NonNull ToolbarProgressBar progressBarView) {
mProgressBarView = progressBarView;
mModel = new PropertyModel(LoadProgressProperties.ALL_KEYS);
mMediator = new LoadProgressMediator(activityTabProvider, mModel);
mMediator = new LoadProgressMediator(tabSupplier, mModel);
mLoadProgressViewBinder = new LoadProgressViewBinder();
mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(
......@@ -47,4 +54,9 @@ public class LoadProgressCoordinator {
public void setPreventUpdates(boolean preventUpdates) {
mMediator.setPreventUpdates(preventUpdates);
}
/** Destroy load progress bar object. */
public void destroy() {
mMediator.destroy();
}
}
......@@ -4,8 +4,11 @@
package org.chromium.chrome.browser.toolbar.load_progress;
import androidx.annotation.NonNull;
import org.chromium.base.MathUtils;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.chrome.browser.tab.CurrentTabObserver;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.load_progress.LoadProgressProperties.CompletionState;
......@@ -23,15 +26,20 @@ public class LoadProgressMediator {
static final float MINIMUM_LOAD_PROGRESS = 0.05f;
private final PropertyModel mModel;
private final EmptyTabObserver mTabObserver;
private final CurrentTabObserver mTabObserver;
private final LoadProgressSimulator mLoadProgressSimulator;
private boolean mPreventUpdates;
public LoadProgressMediator(ActivityTabProvider activityTabProvider, PropertyModel model) {
/**
* @param tabSupplier An observable supplier of the current {@link Tab}.
* @param model MVC property model instance used for load progress bar.
*/
public LoadProgressMediator(
@NonNull ObservableSupplier<Tab> tabSupplier, @NonNull PropertyModel model) {
mModel = model;
mLoadProgressSimulator = new LoadProgressSimulator(model);
mTabObserver = new ActivityTabProvider.ActivityTabTabObserver(activityTabProvider) {
mTabObserver = new CurrentTabObserver(tabSupplier, new EmptyTabObserver() {
@Override
public void onDidStartNavigation(Tab tab, NavigationHandle navigation) {
if (navigation.isSameDocument() || !navigation.isInMainFrame()) {
......@@ -84,13 +92,10 @@ public class LoadProgressMediator {
public void onCrash(Tab tab) {
finishLoadProgress(false);
}
});
@Override
protected void onObservingDifferentTab(Tab tab, boolean hint) {
onNewTabObserved(tab);
}
};
onNewTabObserved(activityTabProvider.get());
tabSupplier.addObserver(this::onNewTabObserved);
onNewTabObserved(tabSupplier.get());
}
/**
......@@ -152,4 +157,9 @@ public class LoadProgressMediator {
: CompletionState.FINISHED_DONT_ANIMATE;
mModel.set(LoadProgressProperties.COMPLETION_STATE, completionState);
}
/** Destroy load progress bar object. */
public void destroy() {
mTabObserver.destroy();
}
}
......@@ -7,16 +7,20 @@ package org.chromium.chrome.browser.toolbar.top;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.supplier.BooleanSupplier;
import org.chromium.base.supplier.ObservableSupplier;
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.feed.shared.FeedFeatures;
import org.chromium.chrome.browser.flags.FeatureParamUtils;
import org.chromium.chrome.browser.intent.IntentMetadata;
import org.chromium.chrome.browser.tab.CurrentTabObserver;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.HomeButton;
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
......@@ -40,7 +44,7 @@ public class HomeButtonCoordinator {
private final View mHomeButton;
private final UserEducationHelper mUserEducationHelper;
private final BooleanSupplier mIsIncognitoSupplier;
private final ActivityTabProvider.ActivityTabTabObserver mPageLoadObserver;
private final CurrentTabObserver mPageLoadObserver;
private final OneshotSupplier<IntentMetadata> mIntentMetadataOneshotSupplier;
private final OneshotSupplier<Boolean> mPromoShownOneshotSupplier;
private final Supplier<Boolean> mIsHomepageNonNtpSupplier;
......@@ -48,19 +52,20 @@ public class HomeButtonCoordinator {
/**
* @param context The Android context used for various view operations.
* @param homeButton The concrete {@link View} class for this MVC component.
* @param activityTabProvider Provides the current active tab.
* @param userEducationHelper Helper class for showing in-product help text bubbles.
* @param isIncognitoSupplier Supplier for whether the current tab is incognito.
* @param intentMetadataOneshotSupplier Potentially delayed information about launching intent.
* @param promoShownOneshotSupplier Potentially delayed information about if a promo was shown.
* @param isHomepageNonNtpSupplier Supplier for whether the current homepage is not NTP.
* @param tabSupplier Supplier of the activity tab.
*/
public HomeButtonCoordinator(Context context, View homeButton,
ActivityTabProvider activityTabProvider, UserEducationHelper userEducationHelper,
BooleanSupplier isIncognitoSupplier,
OneshotSupplier<IntentMetadata> intentMetadataOneshotSupplier,
OneshotSupplier<Boolean> promoShownOneshotSupplier,
Supplier<Boolean> isHomepageNonNtpSupplier) {
public HomeButtonCoordinator(@NonNull Context context, @Nullable View homeButton,
@NonNull UserEducationHelper userEducationHelper,
@NonNull BooleanSupplier isIncognitoSupplier,
@NonNull OneshotSupplier<IntentMetadata> intentMetadataOneshotSupplier,
@NonNull OneshotSupplier<Boolean> promoShownOneshotSupplier,
@NonNull Supplier<Boolean> isHomepageNonNtpSupplier,
@NonNull ObservableSupplier<Tab> tabSupplier) {
mContext = context;
mHomeButton = homeButton;
mUserEducationHelper = userEducationHelper;
......@@ -68,17 +73,16 @@ public class HomeButtonCoordinator {
mIntentMetadataOneshotSupplier = intentMetadataOneshotSupplier;
mPromoShownOneshotSupplier = promoShownOneshotSupplier;
mIsHomepageNonNtpSupplier = isHomepageNonNtpSupplier;
mPageLoadObserver = new ActivityTabProvider.ActivityTabTabObserver(activityTabProvider) {
mPageLoadObserver = new CurrentTabObserver(tabSupplier, new EmptyTabObserver() {
@Override
public void onPageLoadFinished(Tab tab, String url) {
handlePageLoadFinished(url);
}
};
});
}
/** Cleans up observers. */
public void destroy() {
// This will unsubscribe the observer.
mPageLoadObserver.destroy();
}
......
......@@ -11,13 +11,15 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.base.Callback;
import org.chromium.base.CallbackController;
import org.chromium.base.supplier.BooleanSupplier;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.OneshotSupplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.flags.FeatureParamUtils;
import org.chromium.chrome.browser.intent.IntentMetadata;
import org.chromium.chrome.browser.layouts.LayoutStateProvider;
import org.chromium.chrome.browser.layouts.LayoutType;
import org.chromium.chrome.browser.tab.CurrentTabObserver;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
......@@ -44,11 +46,10 @@ public class ToggleTabStackButtonCoordinator {
private final OneshotSupplier<IntentMetadata> mIntentMetadataOneshotSupplier;
private final OneshotSupplier<Boolean> mPromoShownOneshotSupplier;
private final Callback<Boolean> mSetNewTabButtonHighlightCallback;
private final CurrentTabObserver mPageLoadObserver;
private LayoutStateProvider mLayoutStateProvider;
private LayoutStateProvider.LayoutStateObserver mLayoutStateObserver;
private ActivityTabProvider.ActivityTabTabObserver mPageLoadObserver;
private boolean mIphBeingShown;
/**
......@@ -62,15 +63,16 @@ public class ToggleTabStackButtonCoordinator {
* @param promoShownOneshotSupplier Potentially delayed information about if a promo was shown.
* @param layoutStateProviderSupplier Allows observing layout state.
* @param setNewTabButtonHighlightCallback Delegate to highlight the new tab button.
*
* @param activityTabSupplier Supplier of the activity tab.
*/
public ToggleTabStackButtonCoordinator(Context context,
ToggleTabStackButton toggleTabStackButton, ActivityTabProvider activityTabProvider,
UserEducationHelper userEducationHelper, BooleanSupplier isIncognitoSupplier,
ToggleTabStackButton toggleTabStackButton, UserEducationHelper userEducationHelper,
BooleanSupplier isIncognitoSupplier,
OneshotSupplier<IntentMetadata> intentMetadataOneshotSupplier,
OneshotSupplier<Boolean> promoShownOneshotSupplier,
OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier,
Callback<Boolean> setNewTabButtonHighlightCallback) {
Callback<Boolean> setNewTabButtonHighlightCallback,
ObservableSupplier<Tab> activityTabSupplier) {
mContext = context;
mToggleTabStackButton = toggleTabStackButton;
mUserEducationHelper = userEducationHelper;
......@@ -81,22 +83,19 @@ public class ToggleTabStackButtonCoordinator {
layoutStateProviderSupplier.onAvailable(
mCallbackController.makeCancelable(this::setLayoutStateProvider));
mPageLoadObserver = new ActivityTabProvider.ActivityTabTabObserver(activityTabProvider) {
mPageLoadObserver = new CurrentTabObserver(activityTabSupplier, new EmptyTabObserver() {
@Override
public void onPageLoadFinished(Tab tab, String url) {
handlePageLoadFinished();
}
};
});
}
/** Cleans up callbacks and observers. */
public void destroy() {
mCallbackController.destroy();
if (mPageLoadObserver != null) {
mPageLoadObserver.destroy();
mPageLoadObserver = null;
}
mPageLoadObserver.destroy();
if (mLayoutStateProvider != null) {
mLayoutStateProvider.removeObserver(mLayoutStateObserver);
......@@ -133,7 +132,6 @@ public class ToggleTabStackButtonCoordinator {
mLayoutStateProvider.addObserver(mLayoutStateObserver);
}
// TODO(https://crbug.com/1133355): Reduce visibility once ActivityTabTabObserver is mockable.
@VisibleForTesting
void handlePageLoadFinished() {
if (mToggleTabStackButton == null || !mToggleTabStackButton.isShown()) return;
......@@ -175,4 +173,4 @@ public class ToggleTabStackButtonCoordinator {
mIphBeingShown = false;
mToggleTabStackButton.setHighlightDrawable(false);
}
}
\ No newline at end of file
}
......@@ -26,7 +26,6 @@ import org.chromium.base.Callback;
import org.chromium.base.ObserverList;
import org.chromium.base.TraceEvent;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator;
import org.chromium.chrome.browser.findinpage.FindToolbar;
import org.chromium.chrome.browser.omnibox.LocationBar;
import org.chromium.chrome.browser.omnibox.LocationBarCoordinator;
......@@ -84,7 +83,7 @@ public abstract class ToolbarLayout
private MenuButtonCoordinator mMenuButtonCoordinator;
private AppMenuButtonHelper mAppMenuButtonHelper;
private TopToolbarOverlayCoordinator mOverlayCoordinator;
private Callback<Boolean> mOverlayVisibilityCallback;
private Runnable mTabOrModelChangeRunnable;
/**
......@@ -125,17 +124,20 @@ public abstract class ToolbarLayout
mTabOrModelChangeRunnable = tabOrModelChangeRunnable;
}
/** @param overlay The coordinator for the texture version of the top toolbar. */
void setOverlayCoordinator(TopToolbarOverlayCoordinator overlay) {
mOverlayCoordinator = overlay;
mOverlayCoordinator.setIsAndroidViewVisible(getVisibility() == View.VISIBLE);
/**
* @param callback Callback to invoke on visibility change of the texture version
* of the top toolbar.
*/
public void setOverlayVisibilityCallback(Callback<Boolean> callback) {
mOverlayVisibilityCallback = callback;
mOverlayVisibilityCallback.onResult(getVisibility() == View.VISIBLE);
}
@Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
if (mOverlayCoordinator != null) {
mOverlayCoordinator.setIsAndroidViewVisible(visibility == View.VISIBLE);
if (mOverlayVisibilityCallback != null) {
mOverlayVisibilityCallback.onResult(visibility == View.VISIBLE);
}
}
......
......@@ -19,13 +19,7 @@ import org.chromium.base.supplier.OneShotCallback;
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.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.Invalidator;
import org.chromium.chrome.browser.compositor.overlays.toolbar.TopToolbarOverlayCoordinator;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.findinpage.FindToolbar;
import org.chromium.chrome.browser.layouts.LayoutManager;
import org.chromium.chrome.browser.layouts.LayoutStateProvider;
import org.chromium.chrome.browser.omnibox.LocationBar;
import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
......@@ -88,7 +82,6 @@ public class TopToolbarCoordinator implements Toolbar {
private MenuButtonCoordinator mMenuButtonCoordinator;
private ObservableSupplier<AppMenuButtonHelper> mAppMenuButtonHelperSupplier;
private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
private TopToolbarOverlayCoordinator mOverlayCoordinator;
private Callback<ClipDrawableProgressBar.DrawingInfo> mProgressDrawInfoCallback;
private ToolbarControlContainer mControlContainer;
......@@ -185,15 +178,12 @@ public class TopToolbarCoordinator implements Toolbar {
* @param newTabClickHandler The click handler for the new tab button.
* @param bookmarkClickHandler The click handler for the bookmarks button.
* @param customTabsBackClickHandler The click handler for the custom tabs back button.
* @param layoutManager A means of adding SceneOverlays.
* @param tabProvider A means of accessing the currently active tab.
* @param browserControlsStateProvider Access to the state of the browser controls.
*/
public void initializeWithNative(Runnable layoutUpdater,
OnClickListener tabSwitcherClickHandler,
OnLongClickListener tabSwitcherLongClickHandler, OnClickListener newTabClickHandler,
OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler,
LayoutManager layoutManager, ActivityTabProvider tabProvider,
BrowserControlsStateProvider browserControlsStateProvider) {
assert mTabModelSelectorSupplier.get() != null;
if (mTabSwitcherModeCoordinatorPhone != null) {
......@@ -218,16 +208,6 @@ public class TopToolbarCoordinator implements Toolbar {
mToolbarLayout.setLayoutUpdater(layoutUpdater);
mToolbarLayout.onNativeLibraryReady();
// If fullscreen is disabled, don't bother creating this overlay; only the android view will
// ever be shown.
if (DeviceClassManager.enableFullscreen()) {
mOverlayCoordinator = new TopToolbarOverlayCoordinator(mToolbarLayout.getContext(),
layoutManager, mProgressDrawInfoCallback, tabProvider,
browserControlsStateProvider, mResourceManagerSupplier);
layoutManager.addSceneOverlay(mOverlayCoordinator);
mToolbarLayout.setOverlayCoordinator(mOverlayCoordinator);
}
}
/**
......@@ -255,11 +235,6 @@ public class TopToolbarCoordinator implements Toolbar {
* Cleans up any code as necessary.
*/
public void destroy() {
if (mOverlayCoordinator != null) {
mOverlayCoordinator.destroy();
mOverlayCoordinator = null;
}
mToolbarLayout.destroy();
if (mTabSwitcherModeCoordinatorPhone != null) {
mTabSwitcherModeCoordinatorPhone.destroy();
......
......@@ -23,13 +23,13 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.MathUtils;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.UiThreadTest;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.chrome.browser.toolbar.load_progress.LoadProgressProperties.CompletionState;
......@@ -44,8 +44,6 @@ public class LoadProgressMediatorTest {
private static final String URL_1 = "http://starting.url";
private static final String NATIVE_PAGE_URL = "chrome-native://newtab";
@Mock
public ActivityTabProvider mActivityTabProvider;
@Mock
private TabImpl mTab;
@Mock
......@@ -53,28 +51,32 @@ public class LoadProgressMediatorTest {
@Captor
public ArgumentCaptor<TabObserver> mTabObserverCaptor;
@Captor
public ArgumentCaptor<ActivityTabObserver> mActivityTabObserverCaptor;
private PropertyModel mModel;
private LoadProgressMediator mMediator;
private TabObserver mTabObserver;
private ObservableSupplierImpl<Tab> mTabSupplier;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mActivityTabProvider.get()).thenReturn(mTab);
mModel = new PropertyModel(LoadProgressProperties.ALL_KEYS);
mMediator = new LoadProgressMediator(mActivityTabProvider, mModel);
verify(mActivityTabProvider).addObserver(mActivityTabObserverCaptor.capture());
}
private void initMediator() {
// ObservableSupplierImpl needs initialization in UI thread.
mTabSupplier = new ObservableSupplierImpl<>();
mMediator = new LoadProgressMediator(mTabSupplier, mModel);
mTabSupplier.set(mTab);
verify(mTab).addObserver(mTabObserverCaptor.capture());
mTabObserver = mTabObserverCaptor.getValue();
}
@Test
@SmallTest
@UiThreadTest
public void loadRegularPage() {
initMediator();
assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
CompletionState.FINISHED_DONT_ANIMATE);
......@@ -96,10 +98,12 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void switchToLoadingTab() {
initMediator();
doReturn(true).when(mTab2).isLoading();
doReturn(0.1f).when(mTab2).getProgress();
mActivityTabObserverCaptor.getValue().onActivityTabChanged(mTab2, false);
mTabSupplier.set(mTab2);
verify(mTab2, times(1)).addObserver(any());
assertEquals(
......@@ -109,7 +113,9 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void switchToLoadedTab() {
initMediator();
NavigationHandle navigation = new NavigationHandle(0, new GURL(URL_1), true, false, false);
mTabObserver.onDidStartNavigation(mTab, navigation);
assertEquals(
......@@ -117,7 +123,7 @@ public class LoadProgressMediatorTest {
assertEquals(mModel.get(LoadProgressProperties.PROGRESS),
LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
mActivityTabObserverCaptor.getValue().onActivityTabChanged(mTab2, false);
mTabSupplier.set(mTab2);
verify(mTab2, times(1)).addObserver(any());
assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
CompletionState.FINISHED_DONT_ANIMATE);
......@@ -125,7 +131,9 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void loadNativePage() {
initMediator();
doReturn(0.1f).when(mTab).getProgress();
NavigationHandle navigation = new NavigationHandle(0, new GURL(URL_1), true, false, false);
mTabObserver.onDidStartNavigation(mTab, navigation);
......@@ -141,7 +149,9 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void switchToTabWithNativePage() {
initMediator();
NavigationHandle navigation = new NavigationHandle(0, new GURL(URL_1), true, false, false);
mTabObserver.onDidStartNavigation(mTab, navigation);
assertEquals(
......@@ -150,7 +160,7 @@ public class LoadProgressMediatorTest {
LoadProgressMediator.MINIMUM_LOAD_PROGRESS, MathUtils.EPSILON);
when(mTab2.getUrlString()).thenReturn(NATIVE_PAGE_URL);
mActivityTabObserverCaptor.getValue().onActivityTabChanged(mTab2, false);
mTabSupplier.set(mTab2);
verify(mTab2, times(1)).addObserver(any());
assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
CompletionState.FINISHED_DONT_ANIMATE);
......@@ -160,7 +170,9 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void pageCrashes() {
initMediator();
NavigationHandle navigation = new NavigationHandle(0, new GURL(URL_1), true, false, false);
mTabObserver.onDidStartNavigation(mTab, navigation);
assertEquals(
......@@ -179,6 +191,7 @@ public class LoadProgressMediatorTest {
@SmallTest
@UiThreadTest
public void testSwapWebContents() {
initMediator();
assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
CompletionState.FINISHED_DONT_ANIMATE);
mTabObserver.onWebContentsSwapped(mTab, true, true);
......@@ -201,7 +214,9 @@ public class LoadProgressMediatorTest {
@Test
@SmallTest
@UiThreadTest
public void testSameDocumentLoad_afterFinishedLoading() {
initMediator();
GURL gurl = new GURL(URL_1);
assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
CompletionState.FINISHED_DONT_ANIMATE);
......
......@@ -27,14 +27,15 @@ import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneshotSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.feed.shared.FeedFeatures;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.homepage.HomepageManager;
import org.chromium.chrome.browser.intent.IntentMetadata;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.toolbar.HomeButton;
import org.chromium.chrome.browser.user_education.IPHCommand;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
......@@ -106,8 +107,6 @@ public class HomeButtonCoordinatorTest {
@Mock
private Context mContext;
@Mock
private ActivityTabProvider mActivityTabProvider;
@Mock
private HomeButton mHomeButton;
@Mock
private android.content.res.Resources mResources;
......@@ -140,9 +139,9 @@ public class HomeButtonCoordinatorTest {
private HomeButtonCoordinator newHomeButtonCoordinator(View view) {
// clang-format off
return new HomeButtonCoordinator(mContext, view, mActivityTabProvider, mUserEducationHelper,
() -> mIsIncognito, mIntentMetadataOneshotSupplier, mPromoShownOneshotSupplier,
HomepageManager::isHomepageNonNtp);
return new HomeButtonCoordinator(mContext, view, mUserEducationHelper, () -> mIsIncognito,
mIntentMetadataOneshotSupplier, mPromoShownOneshotSupplier,
HomepageManager::isHomepageNonNtp, new ObservableSupplierImpl<Tab>());
// clang-format on
}
......
......@@ -27,13 +27,14 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.chromium.base.Callback;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.base.supplier.OneshotSupplierImpl;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.intent.IntentMetadata;
import org.chromium.chrome.browser.layouts.LayoutStateProvider;
import org.chromium.chrome.browser.layouts.LayoutType;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.user_education.IPHCommand;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
import org.chromium.components.feature_engagement.FeatureConstants;
......@@ -67,8 +68,6 @@ public class ToggleTabStackButtonCoordinatorTest {
@Mock
private Context mContext;
@Mock
private ActivityTabProvider mActivityTabProvider;
@Mock
private LayoutStateProvider mLayoutStateProvider;
@Mock
private ToggleTabStackButton mToggleTabStackButton;
......@@ -124,12 +123,12 @@ public class ToggleTabStackButtonCoordinatorTest {
private ToggleTabStackButtonCoordinator newToggleTabStackButtonCoordinator(
ToggleTabStackButton toggleTabStackButton) {
// clang-format off
return new ToggleTabStackButtonCoordinator(mContext, toggleTabStackButton,
mActivityTabProvider, mUserEducationHelper,
()
-> mIsIncognito,
mIntentMetadataOneshotSupplier, mPromoShownOneshotSupplier,
mLayoutSateProviderOneshotSupplier, mSetNewTabButtonHighlightCallback);
mUserEducationHelper, () -> mIsIncognito, mIntentMetadataOneshotSupplier,
mPromoShownOneshotSupplier, mLayoutSateProviderOneshotSupplier,
mSetNewTabButtonHighlightCallback, new ObservableSupplierImpl<Tab>());
// clang-format on
}
private void showOverviewMode() {
......
......@@ -8,6 +8,7 @@ import("//chrome/browser/buildflags.gni")
android_library("java") {
sources = [
"java/src/org/chromium/chrome/browser/tab/CurrentTabObserver.java",
"java/src/org/chromium/chrome/browser/tab/EmptyTabObserver.java",
"java/src/org/chromium/chrome/browser/tab/Tab.java",
"java/src/org/chromium/chrome/browser/tab/TabAttributeKeys.java",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.tab;
import androidx.annotation.NonNull;
import org.chromium.base.Callback;
import org.chromium.base.CallbackController;
import org.chromium.base.supplier.ObservableSupplier;
/**
* TabObserver that keeps switching to always observe the current tab. A stop-gap solution
* to ActivityTabTabObserver for classes that cannot reference it directly.
* TODO(crbug.com/1146871): Just switch to ActivityTabTabObserver once ActivityTabProvider
* gets modularized.
*/
public class CurrentTabObserver {
private final ObservableSupplier<Tab> mTabSupplier;
private final TabObserver mTabObserver;
private final Callback<Tab> mTabSupplierCallback;
private CallbackController mCallbackController;
private Tab mTab;
/**
* @param tabSupplier An observable supplier of the current {@link Tab}. NOT to be owned
* by this class, and should be destroyed by callsite later.
* @param tabObserver {@link TabObserver} that we want to observe the current tab with.
* Owned by this class.
*/
public CurrentTabObserver(
@NonNull ObservableSupplier<Tab> tabSupplier, @NonNull TabObserver tabObserver) {
mTabSupplier = tabSupplier;
mTabObserver = tabObserver;
mCallbackController = new CallbackController();
mTabSupplierCallback = mCallbackController.makeCancelable((tab) -> {
if (mTab != null) mTab.removeObserver(mTabObserver);
mTab = tab;
if (mTab != null) mTab.addObserver(mTabObserver);
});
mTabSupplier.addObserver(mTabSupplierCallback);
}
/** Destroy the current tab observer. This should be called after use. */
public void destroy() {
if (mTab != null) mTab.removeObserver(mTabObserver);
mTabSupplier.removeObserver(mTabSupplierCallback);
mCallbackController.destroy();
mCallbackController = null;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment