Commit 44a512fd authored by Mehran Mahmoudi's avatar Mehran Mahmoudi Committed by Commit Bot

[Paint Preview] Tab integration for startup experiment

This CL implements the integration needed for paint previews to show
on a cold start. This feature is guarded behind an experimental flag
that is only intended for the Canary/Dev channels.

PTAL at the design doc for more context: http://go/fdt-tab-integration

Bug: 1064011
Change-Id: I91bd682f32eccb8e22b27ec026f04079fd6fc250
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2231179Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarCalder Kitagawa <ckitagawa@chromium.org>
Commit-Queue: Mehran Mahmoudi <mahmoudi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776229}
parent 7b61c208
......@@ -1191,7 +1191,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/page_info/SiteSettingsHelper.java",
"java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewDemoManager.java",
"java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewExperiments.java",
"java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewInitializer.java",
"java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewHelper.java",
"java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewTabHelper.java",
"java/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewPlayer.java",
"java/src/org/chromium/chrome/browser/paint_preview/services/PaintPreviewDemoService.java",
......
......@@ -112,7 +112,7 @@ import org.chromium.chrome.browser.omaha.notification.UpdateNotificationControll
import org.chromium.chrome.browser.omaha.notification.UpdateNotificationControllerFactory;
import org.chromium.chrome.browser.page_info.ChromePageInfoControllerDelegate;
import org.chromium.chrome.browser.page_info.ChromePermissionParamsListBuilderDelegate;
import org.chromium.chrome.browser.paint_preview.PaintPreviewInitializer;
import org.chromium.chrome.browser.paint_preview.PaintPreviewHelper;
import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
......@@ -612,7 +612,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mIncognitoTabCreator = tabCreators.second;
OfflinePageUtils.observeTabModelSelector(this, mTabModelSelector);
PaintPreviewInitializer.observeTabModelSelector(this, mTabModelSelector);
PaintPreviewHelper.observeTabModelSelector(this, mTabModelSelector);
if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
......
......@@ -635,7 +635,7 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
boolean itemVisible = canShowRequestDesktopSite
&& (!isChromeScheme || currentTab.isNativePage())
&& !shouldShowReaderModePrefs(currentTab);
&& !shouldShowReaderModePrefs(currentTab) && currentTab.getWebContents() != null;
requestMenuRow.setVisible(itemVisible);
if (!itemVisible) return;
......
......@@ -106,7 +106,7 @@ public class ContextualSearchTabHelper
public void onContentChanged(Tab tab) {
// Native initialization happens after a page loads or content is changed to ensure profile
// is initialized.
if (mNativeHelper == 0) {
if (mNativeHelper == 0 && tab.getWebContents() != null) {
mNativeHelper = ContextualSearchTabHelperJni.get().init(
ContextualSearchTabHelper.this, Profile.fromWebContents(tab.getWebContents()));
}
......
......@@ -202,8 +202,9 @@ public class ReaderModeManager extends EmptyTabObserver implements UserData {
}
// Make sure there is a WebContentsObserver on this tab's WebContents.
if (mWebContentsObserver == null) mWebContentsObserver = createWebContentsObserver();
if (mWebContentsObserver == null && mTab.getWebContents() != null) {
mWebContentsObserver = createWebContentsObserver();
}
tryShowingInfoBar();
}
......
......@@ -8,13 +8,14 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabServiceFactory;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
/**
* Handles initialization of the Paint Preview tab observers.
*/
public class PaintPreviewInitializer {
public class PaintPreviewHelper {
/**
* Observes a {@link TabModelSelector} to monitor for initialization completion.
* @param activity The ChromeActivity that corresponds to the tabModelSelector.
......@@ -39,4 +40,20 @@ public class PaintPreviewInitializer {
}
});
}
/**
* Attemps to display the Paint Preview representation of for the given Tab.
* @param onShown The callback for when the Paint Preview is shown.
* @param onDismissed The callback for when the Paint Preview is dismissed.
* @return Whether the Paint Preview started to initialize or is already initializating.
* Note that if the Paint Preview is already showing, this will return false.
*/
public static boolean showPaintPreviewOnRestore(
Tab tab, Runnable onShown, Runnable onDismissed) {
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP)) {
return false;
}
return TabbedPaintPreviewPlayer.get(tab).maybeShow(onShown, onDismissed);
}
}
......@@ -32,6 +32,7 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
private PlayerManager mPlayerManager;
private Runnable mOnShown;
private Runnable mOnDismissed;
private Boolean mInitializing;
public static TabbedPaintPreviewPlayer get(Tab tab) {
if (tab.getUserDataHost().getUserData(USER_DATA_KEY) == null) {
......@@ -46,24 +47,27 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
}
/**
* Shows a Paint Preview for the provided tab if it exists.
* Shows a Paint Preview for the provided tab if it exists and has not been displayed for this
* Tab before.
* @param onShown The callback for when the Paint Preview is shown.
* @param onDismissed The callback for when the Paint Preview is dismissed.
* @return a boolean indicating whether a Paint Preview exists for the tab.
* @return Whether the Paint Preview started to initialize or is already initializating.
* Note that if the Paint Preview is already showing, this will return false.
*/
public boolean showIfExists(@Nullable Runnable onShown, @Nullable Runnable onDismissed) {
if (isShowing()) return true;
public boolean maybeShow(@Nullable Runnable onShown, @Nullable Runnable onDismissed) {
if (mInitializing != null) return mInitializing;
// Check if a capture exists. This is a quick check using a cache.
boolean hasCapture = mPaintPreviewTabService.hasCaptureForTab(mTab.getId());
mOnShown = onShown;
mOnDismissed = onDismissed;
mInitializing = hasCapture;
if (hasCapture) {
mPlayerManager = new PlayerManager(mTab.getUrl(), mTab.getContext(),
mPaintPreviewTabService, String.valueOf(mTab.getId()), this::onLinkClicked,
this::removePaintPreview,
() -> TabViewManager.get(mTab).addTabViewProvider(this),
TabThemeColorHelper.getBackgroundColor(mTab), this::removePaintPreview);
mOnShown = onShown;
mOnDismissed = onDismissed;
}
return hasCapture;
......@@ -74,13 +78,14 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
* nothing if there is no view showing.
*/
private void removePaintPreview() {
mOnShown = null;
mOnDismissed = null;
mInitializing = false;
if (mTab == null || mPlayerManager == null) return;
TabViewManager.get(mTab).removeTabViewProvider(this);
mPlayerManager.destroy();
mPlayerManager = null;
mOnShown = null;
mOnDismissed = null;
}
public boolean isShowing() {
......@@ -106,6 +111,7 @@ public class TabbedPaintPreviewPlayer implements TabViewProvider, UserData {
@Override
public void onShown() {
mInitializing = false;
if (mOnShown != null) mOnShown.run();
}
......
......@@ -51,6 +51,7 @@ specific_include_rules = {
"+chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePage.java",
"+chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageAssassin.java",
"+chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java",
"+chrome/android/java/src/org/chromium/chrome/browser/paint_preview/PaintPreviewHelper.java",
"+chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java",
"+chrome/android/java/src/org/chromium/chrome/browser/rlz/RevenueStats.java",
"+chrome/android/java/src/org/chromium/chrome/browser/night_mode",
......
......@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
import org.chromium.chrome.browser.native_page.NativePageAssassin;
import org.chromium.chrome.browser.night_mode.NightModeUtils;
import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
import org.chromium.chrome.browser.paint_preview.PaintPreviewHelper;
import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler;
import org.chromium.chrome.browser.rlz.RevenueStats;
import org.chromium.chrome.browser.tab.TabState.WebContentsState;
......@@ -618,7 +619,6 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
updateInteractableState();
loadIfNeeded();
assert !isFrozen();
if (getWebContents() != null) getWebContents().onShow();
......@@ -1395,6 +1395,14 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
* history load are used.
*/
private final void restoreIfNeeded() {
// Attempts to display the Paint Preview representation of this Tab instead of fully
// restoring. Please note that this is behind an experimental flag.
if (isFrozen()
&& PaintPreviewHelper.showPaintPreviewOnRestore(
this, () -> restoreIfNeeded(), () -> restoreIfNeeded())) {
return;
}
try {
TraceEvent.begin("Tab.restoreIfNeeded");
// Restore is needed for a tab that is loaded for the first time. WebContents will
......
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