Commit b17b9e9d authored by Mehran Mahmoudi's avatar Mehran Mahmoudi Committed by Commit Bot

[Paint Preview] Add fake progressbar on upgrading to live tab

As per UX review, this CL disables the progressbar when paint preview
is shown. It also fakes a progress fill animation on upgrading to the
live tab.

Bug: 1131497
Change-Id: I8054f2aacaaea7d76423017b89057f811895e548
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2441188
Commit-Queue: Mehran Mahmoudi <mahmoudi@chromium.org>
Reviewed-by: default avatarCalder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812868}
parent 3e50c687
...@@ -1487,7 +1487,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -1487,7 +1487,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
mInactivityTracker = new ChromeInactivityTracker( mInactivityTracker = new ChromeInactivityTracker(
ChromePreferenceKeys.TABBED_ACTIVITY_LAST_BACKGROUNDED_TIME_MS_PREF); ChromePreferenceKeys.TABBED_ACTIVITY_LAST_BACKGROUNDED_TIME_MS_PREF);
PaintPreviewHelper.initialize(this, getTabModelSelector()); PaintPreviewHelper.initialize(
this, getTabModelSelector(), () -> getToolbarManager().getProgressBarCoordinator());
} }
@Override @Override
......
...@@ -9,6 +9,7 @@ import android.os.SystemClock; ...@@ -9,6 +9,7 @@ import android.os.SystemClock;
import org.chromium.base.ActivityState; import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
...@@ -20,6 +21,7 @@ import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabService ...@@ -20,6 +21,7 @@ import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabService
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.toolbar.load_progress.LoadProgressCoordinator;
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -52,14 +54,15 @@ public class PaintPreviewHelper { ...@@ -52,14 +54,15 @@ public class PaintPreviewHelper {
* @param activity The ChromeActivity that corresponds to the tabModelSelector. * @param activity The ChromeActivity that corresponds to the tabModelSelector.
* @param tabModelSelector The TabModelSelector to observe. * @param tabModelSelector The TabModelSelector to observe.
*/ */
public static void initialize(ChromeActivity<?> activity, TabModelSelector tabModelSelector) { public static void initialize(ChromeActivity<?> activity, TabModelSelector tabModelSelector,
Supplier<LoadProgressCoordinator> progressBarCoordinatorSupplier) {
if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP)) return; if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP)) return;
if (!MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity)) { if (!MultiWindowUtils.getInstance().areMultipleChromeInstancesRunning(activity)) {
sHasAttemptedToShowOnRestore = false; sHasAttemptedToShowOnRestore = false;
} }
sWindowAndroidHelperMap.put( sWindowAndroidHelperMap.put(activity.getWindowAndroid(),
activity.getWindowAndroid(), new PaintPreviewWindowAndroidHelper(activity)); new PaintPreviewWindowAndroidHelper(activity, progressBarCoordinatorSupplier));
// TODO(crbug/1074428): verify this doesn't cause a memory leak if the user exits Chrome // TODO(crbug/1074428): verify this doesn't cause a memory leak if the user exits Chrome
// prior to onTabStateInitialized being called. // prior to onTabStateInitialized being called.
...@@ -95,6 +98,14 @@ public class PaintPreviewHelper { ...@@ -95,6 +98,14 @@ public class PaintPreviewHelper {
TabbedPaintPreviewPlayer player = TabbedPaintPreviewPlayer.get(tab); TabbedPaintPreviewPlayer player = TabbedPaintPreviewPlayer.get(tab);
player.setBrowserVisibilityDelegate( player.setBrowserVisibilityDelegate(
windowAndroidHelper.getBrowserControlsManager().getBrowserVisibilityDelegate()); windowAndroidHelper.getBrowserControlsManager().getBrowserVisibilityDelegate());
player.setProgressSimulatorNeededCallback(
()
-> windowAndroidHelper.getLoadProgressCoordinator()
.simulateLoadProgressCompletion());
player.setProgressbarUpdatePreventionCallback(
(preventProgressbar)
-> windowAndroidHelper.getLoadProgressCoordinator().setPreventUpdates(
preventProgressbar));
PageLoadMetrics.Observer observer = new PageLoadMetrics.Observer() { PageLoadMetrics.Observer observer = new PageLoadMetrics.Observer() {
@Override @Override
public void onFirstMeaningfulPaint(WebContents webContents, long navigationId, public void onFirstMeaningfulPaint(WebContents webContents, long navigationId,
...@@ -124,11 +135,14 @@ public class PaintPreviewHelper { ...@@ -124,11 +135,14 @@ public class PaintPreviewHelper {
private long mActivityCreationTime; private long mActivityCreationTime;
private WindowAndroid mWindowAndroid; private WindowAndroid mWindowAndroid;
private BrowserControlsManager mBrowserControlsManager; private BrowserControlsManager mBrowserControlsManager;
private Supplier<LoadProgressCoordinator> mProgressBarCoordinatorSupplier;
PaintPreviewWindowAndroidHelper(ChromeActivity<?> chromeActivity) { PaintPreviewWindowAndroidHelper(ChromeActivity<?> chromeActivity,
Supplier<LoadProgressCoordinator> progressBarCoordinatorSupplier) {
mWindowAndroid = chromeActivity.getWindowAndroid(); mWindowAndroid = chromeActivity.getWindowAndroid();
mActivityCreationTime = chromeActivity.getOnCreateTimestampMs(); mActivityCreationTime = chromeActivity.getOnCreateTimestampMs();
mBrowserControlsManager = chromeActivity.getBrowserControlsManager(); mBrowserControlsManager = chromeActivity.getBrowserControlsManager();
mProgressBarCoordinatorSupplier = progressBarCoordinatorSupplier;
ApplicationStatus.registerStateListenerForActivity(this, chromeActivity); ApplicationStatus.registerStateListenerForActivity(this, chromeActivity);
} }
...@@ -136,6 +150,10 @@ public class PaintPreviewHelper { ...@@ -136,6 +150,10 @@ public class PaintPreviewHelper {
return mActivityCreationTime; return mActivityCreationTime;
} }
LoadProgressCoordinator getLoadProgressCoordinator() {
return mProgressBarCoordinatorSupplier.get();
}
BrowserControlsManager getBrowserControlsManager() { BrowserControlsManager getBrowserControlsManager() {
return mBrowserControlsManager; return mBrowserControlsManager;
} }
......
...@@ -1186,6 +1186,13 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve ...@@ -1186,6 +1186,13 @@ public class ToolbarManager implements UrlFocusChangeListener, ThemeColorObserve
if (mInitializedWithNative) mToolbar.finishAnimations(); if (mInitializedWithNative) mToolbar.finishAnimations();
} }
/**
* @return The current {@link LoadProgressCoordinator}.
*/
public LoadProgressCoordinator getProgressBarCoordinator() {
return mProgressBarCoordinator;
}
/** /**
* Updates the current button states and calls appropriate abstract visibility methods, giving * Updates the current button states and calls appropriate abstract visibility methods, giving
* inheriting classes the chance to update the button visuals as well. * inheriting classes the chance to update the button visuals as well.
......
...@@ -31,4 +31,20 @@ public class LoadProgressCoordinator { ...@@ -31,4 +31,20 @@ public class LoadProgressCoordinator {
mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create( mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(
mModel, mProgressBarView, mLoadProgressViewBinder::bind); mModel, mProgressBarView, mLoadProgressViewBinder::bind);
} }
/**
* Simulates progressbar being filled over a short time.
*/
public void simulateLoadProgressCompletion() {
mMediator.simulateLoadProgressCompletion();
}
/**
* Whether progressbar should be updated on tab progress changes.
* @param preventUpdates If true, prevents updating progressbar when the tab it's observing
* is being loaded.
*/
public void setPreventUpdates(boolean preventUpdates) {
mMediator.setPreventUpdates(preventUpdates);
}
} }
...@@ -24,6 +24,7 @@ public class LoadProgressMediator { ...@@ -24,6 +24,7 @@ public class LoadProgressMediator {
private final PropertyModel mModel; private final PropertyModel mModel;
private final EmptyTabObserver mTabObserver; private final EmptyTabObserver mTabObserver;
private final LoadProgressSimulator mLoadProgressSimulator; private final LoadProgressSimulator mLoadProgressSimulator;
private boolean mPreventUpdates;
public LoadProgressMediator(ActivityTabProvider activityTabProvider, PropertyModel model) { public LoadProgressMediator(ActivityTabProvider activityTabProvider, PropertyModel model) {
mModel = model; mModel = model;
...@@ -75,7 +76,7 @@ public class LoadProgressMediator { ...@@ -75,7 +76,7 @@ public class LoadProgressMediator {
// If loading both started and finished before we swapped in the WebContents, we // If loading both started and finished before we swapped in the WebContents, we
// won't get any load progress signals. Otherwise, we should receive at least one // won't get any load progress signals. Otherwise, we should receive at least one
// real signal so we don't need to simulate them. // real signal so we don't need to simulate them.
if (didStartLoad && didFinishLoad) { if (didStartLoad && didFinishLoad && !mPreventUpdates) {
mLoadProgressSimulator.start(); mLoadProgressSimulator.start();
} }
} }
...@@ -93,8 +94,25 @@ public class LoadProgressMediator { ...@@ -93,8 +94,25 @@ public class LoadProgressMediator {
onNewTabObserved(activityTabProvider.get()); onNewTabObserved(activityTabProvider.get());
} }
/**
* Simulates progressbar being filled over a short time.
*/
void simulateLoadProgressCompletion() {
mLoadProgressSimulator.start();
}
/**
* Whether progressbar should be updated on tab progress changes.
* @param preventUpdates If true, prevents updating progressbar when the tab it's observing
* is being loaded.
*/
void setPreventUpdates(boolean preventUpdates) {
mPreventUpdates = preventUpdates;
}
private void onNewTabObserved(Tab tab) { private void onNewTabObserved(Tab tab) {
if (tab == null) return; if (tab == null) return;
if (tab.isLoading()) { if (tab.isLoading()) {
if (NativePageFactory.isNativePageUrl(tab.getUrlString(), tab.isIncognito())) { if (NativePageFactory.isNativePageUrl(tab.getUrlString(), tab.isIncognito())) {
finishLoadProgress(false); finishLoadProgress(false);
...@@ -108,10 +126,14 @@ public class LoadProgressMediator { ...@@ -108,10 +126,14 @@ public class LoadProgressMediator {
} }
private void startLoadProgress() { private void startLoadProgress() {
if (mPreventUpdates) return;
mModel.set(LoadProgressProperties.COMPLETION_STATE, CompletionState.UNFINISHED); mModel.set(LoadProgressProperties.COMPLETION_STATE, CompletionState.UNFINISHED);
} }
private void updateLoadProgress(float progress) { private void updateLoadProgress(float progress) {
if (mPreventUpdates) return;
progress = Math.max(progress, MINIMUM_LOAD_PROGRESS); progress = Math.max(progress, MINIMUM_LOAD_PROGRESS);
mModel.set(LoadProgressProperties.PROGRESS, progress); mModel.set(LoadProgressProperties.PROGRESS, progress);
if (MathUtils.areFloatsEqual(progress, 1)) finishLoadProgress(true); if (MathUtils.areFloatsEqual(progress, 1)) finishLoadProgress(true);
......
...@@ -14,6 +14,7 @@ import android.view.View; ...@@ -14,6 +14,7 @@ import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.base.Callback;
import org.chromium.base.UserData; import org.chromium.base.UserData;
import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
...@@ -66,6 +67,8 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -66,6 +67,8 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
private BrowserStateBrowserControlsVisibilityDelegate mBrowserVisibilityDelegate; private BrowserStateBrowserControlsVisibilityDelegate mBrowserVisibilityDelegate;
private int mPersistentToolbarToken = TokenHolder.INVALID_TOKEN; private int mPersistentToolbarToken = TokenHolder.INVALID_TOKEN;
private SnackbarManager.SnackbarController mSnackbarController; private SnackbarManager.SnackbarController mSnackbarController;
private Runnable mProgressSimulatorNeededCallback;
private Callback<Boolean> mProgressPreventionCallback;
public static TabbedPaintPreviewPlayer get(Tab tab) { public static TabbedPaintPreviewPlayer get(Tab tab) {
if (tab.getUserDataHost().getUserData(USER_DATA_KEY) == null) { if (tab.getUserDataHost().getUserData(USER_DATA_KEY) == null) {
...@@ -118,6 +121,9 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -118,6 +121,9 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
public void onHidden(Tab tab, @TabHidingType int hidingType) { public void onHidden(Tab tab, @TabHidingType int hidingType) {
releasePersistentToolbar(); releasePersistentToolbar();
dismissSnackbar(); dismissSnackbar();
if (mProgressSimulatorNeededCallback != null) {
mProgressPreventionCallback.onResult(false);
}
if (mPlayerManager == null || !isShowingAndNeedsBadge()) return; if (mPlayerManager == null || !isShowingAndNeedsBadge()) return;
...@@ -129,7 +135,12 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -129,7 +135,12 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
@Override @Override
public void onShown(Tab tab, int type) { public void onShown(Tab tab, int type) {
if (isShowingAndNeedsBadge()) showToolbarPersistent(); if (!isShowingAndNeedsBadge()) return;
showToolbarPersistent();
if (mProgressSimulatorNeededCallback != null) {
mProgressPreventionCallback.onResult(true);
}
} }
} }
...@@ -146,6 +157,14 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -146,6 +157,14 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
mBrowserVisibilityDelegate = browserVisibilityDelegate; mBrowserVisibilityDelegate = browserVisibilityDelegate;
} }
public void setProgressSimulatorNeededCallback(Runnable callback) {
mProgressSimulatorNeededCallback = callback;
}
public void setProgressbarUpdatePreventionCallback(Callback<Boolean> callback) {
mProgressPreventionCallback = callback;
}
/** /**
* Triggered via {@link PageLoadMetrics.Observer} when First Meaningful Paint happens. * Triggered via {@link PageLoadMetrics.Observer} when First Meaningful Paint happens.
* @param webContents the webContents that triggered the event. * @param webContents the webContents that triggered the event.
...@@ -252,6 +271,7 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -252,6 +271,7 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
} }
}); });
if (exitCause == ExitCause.TAB_FINISHED_LOADING) showUpgradeToast(); if (exitCause == ExitCause.TAB_FINISHED_LOADING) showUpgradeToast();
if (mProgressSimulatorNeededCallback != null) mProgressSimulatorNeededCallback.run();
mMetricsHelper.recordExitMetrics(exitCause, mSnackbarShownCount); mMetricsHelper.recordExitMetrics(exitCause, mSnackbarShownCount);
} }
...@@ -343,12 +363,14 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData { ...@@ -343,12 +363,14 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
@Override @Override
public void onShown() { public void onShown() {
showToolbarPersistent(); showToolbarPersistent();
if (mProgressSimulatorNeededCallback != null) mProgressPreventionCallback.onResult(true);
} }
@Override @Override
public void onHidden() { public void onHidden() {
releasePersistentToolbar(); releasePersistentToolbar();
dismissSnackbar(); dismissSnackbar();
if (mProgressSimulatorNeededCallback != null) mProgressPreventionCallback.onResult(false);
} }
@Override @Override
......
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