Index: chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java |
index d1c7dfa4eac9fd9c97007e5d07f09ce1e94d2b61..db6840cbe8ba356be7b13afe0c77aa46e9d4d596 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java |
@@ -4,134 +4,208 @@ |
package org.chromium.chrome.browser.dom_distiller; |
-import android.app.Activity; |
import android.content.Context; |
import android.text.TextUtils; |
import org.chromium.base.ApiCompatibilityUtils; |
import org.chromium.base.CommandLine; |
+import org.chromium.base.SysUtils; |
import org.chromium.base.metrics.RecordHistogram; |
import org.chromium.chrome.R; |
import org.chromium.chrome.browser.ChromeActivity; |
import org.chromium.chrome.browser.ChromeSwitches; |
-import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; |
-import org.chromium.chrome.browser.contextualsearch.ContextualSearchObserver; |
-import org.chromium.chrome.browser.dom_distiller.ReaderModePanel.ReaderModePanelHost; |
-import org.chromium.chrome.browser.gsa.GSAContextDisplaySelection; |
+import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; |
+import org.chromium.chrome.browser.compositor.bottombar.readermode.ReaderModePanel; |
import org.chromium.chrome.browser.infobar.InfoBar; |
import org.chromium.chrome.browser.infobar.InfoBarContainer; |
import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarContainerObserver; |
-import org.chromium.chrome.browser.tab.EmptyTabObserver; |
import org.chromium.chrome.browser.tab.Tab; |
+import org.chromium.chrome.browser.tabmodel.TabCreatorManager; |
+import org.chromium.chrome.browser.tabmodel.TabModel; |
+import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; |
import org.chromium.components.dom_distiller.content.DistillablePageUtils; |
import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
+import org.chromium.content_public.browser.LoadUrlParams; |
import org.chromium.content_public.browser.WebContents; |
import org.chromium.content_public.browser.WebContentsObserver; |
import org.chromium.ui.base.DeviceFormFactor; |
+import org.chromium.ui.base.PageTransition; |
+ |
+import java.util.HashMap; |
+import java.util.Map; |
/** |
* Manages UI effects for reader mode including hiding and showing the |
* reader mode and reader mode preferences toolbar icon and hiding the |
* top controls when a reader mode page has finished loading. |
*/ |
-public class ReaderModeManager extends EmptyTabObserver |
- implements ContextualSearchObserver, InfoBarContainerObserver, ReaderModePanelHost { |
+public class ReaderModeManager extends TabModelSelectorTabObserver |
+ implements InfoBarContainerObserver, ReaderModeManagerDelegate { |
/** |
- * Observer for changes to the current status of reader mode. |
+ * URL scheme for dom-distiller. |
*/ |
- public static interface ReaderModeManagerObserver { |
- /** |
- * Triggered on changes to the reader mode status for the owning tab. |
- * |
- * @param readerModeStatus The current status of reader mode. |
- * @see ReaderModeManager#POSSIBLE |
- * @see ReaderModeManager#NOT_POSSIBLE |
- * @see ReaderModeManager#STARTED |
- */ |
- void onReaderModeStatusChanged(int readerModeStatus); |
- } |
+ public static final String DOM_DISTILLER_SCHEME = "chrome-distiller"; |
/** |
* POSSIBLE means reader mode can be entered. |
*/ |
public static final int POSSIBLE = 0; |
+ |
/** |
* NOT_POSSIBLE means reader mode cannot be entered. |
*/ |
public static final int NOT_POSSIBLE = 1; |
+ |
/** |
* STARTED means reader mode is currently in reader mode. |
*/ |
public static final int STARTED = 2; |
- /** |
- * The url of the last page visited if the last page was reader mode page. Otherwise null. |
- */ |
+ // The url of the last page visited if the last page was reader mode page. Otherwise null. |
private String mReaderModePageUrl; |
- /** |
- * Whether the page is an article or not. |
- */ |
- private int mReaderModeStatus = NOT_POSSIBLE; |
- |
- /** |
- * Whether the fact that the current web page was distillable or not has been recorded. |
- */ |
+ // Whether the fact that the current web page was distillable or not has been recorded. |
private boolean mIsUmaRecorded; |
- private WebContentsObserver mWebContentsObserver; |
+ // The per-tab state of distillation. |
+ private Map<Integer, ReaderModeTabInfo> mTabStatusMap; |
- private final Tab mTab; |
+ // The current tab ID. This will change as the user switches between tabs. |
+ private int mTabId; |
- private final ReaderModePanel mReaderModePanel; |
+ // The ReaderModePanel that this class is managing. |
+ private ReaderModePanel mReaderModePanel; |
- private final int mHeaderBackgroundColor; |
+ // The ChromeActivity that this panel exists in. |
+ private ChromeActivity mChromeActivity; |
+ |
+ // The primary means of getting the currently active tab. |
+ private TabModelSelector mTabModelSelector; |
- public ReaderModeManager(Tab tab, Context context) { |
- mTab = tab; |
- mTab.addObserver(this); |
- mReaderModePanel = isEnabled(context) ? new ReaderModePanel(this, context) : null; |
- mHeaderBackgroundColor = context != null |
+ private final int mHeaderBackgroundColor; |
+ private boolean mIsFullscreenModeEntered; |
+ private boolean mIsInfobarContainerShown; |
+ |
+ public ReaderModeManager(TabModelSelector selector, ChromeActivity activity) { |
+ super(selector); |
+ mTabId = Tab.INVALID_TAB_ID; |
+ mTabModelSelector = selector; |
+ mChromeActivity = activity; |
+ mTabStatusMap = new HashMap<>(); |
+ mHeaderBackgroundColor = activity != null |
? ApiCompatibilityUtils.getColor( |
- context.getResources(), R.color.reader_mode_header_bg) |
+ activity.getResources(), R.color.reader_mode_header_bg) |
: 0; |
} |
- // EmptyTabObserver: |
+ /** |
+ * Clear the status map and references to other objects. |
+ */ |
+ public void destroy() { |
+ for (Map.Entry<Integer, ReaderModeTabInfo> e : mTabStatusMap.entrySet()) { |
+ if (e.getValue().getWebContentsObserver() != null) { |
+ e.getValue().getWebContentsObserver().destroy(); |
+ } |
+ } |
+ mTabStatusMap.clear(); |
+ mChromeActivity = null; |
+ mReaderModePanel = null; |
+ mTabModelSelector = null; |
+ } |
+ |
+ // TabModelSelectorTabObserver: |
+ |
@Override |
- public void onDestroyed(Tab tab) { |
- ContextualSearchManager contextualSearchManager = getContextualSearchManager(tab); |
- if (contextualSearchManager != null) contextualSearchManager.removeObserver(this); |
+ public void onShown(Tab shownTab) { |
+ int shownTabId = shownTab.getId(); |
- if (mTab.getInfoBarContainer() != null) mTab.getInfoBarContainer().removeObserver(this); |
+ Tab previousTab = mTabModelSelector.getTabById(mTabId); |
+ mTabId = shownTabId; |
- if (mReaderModePanel != null) mReaderModePanel.onDestroy(); |
+ // If the reader panel was dismissed, stop here. |
+ if (mTabStatusMap.containsKey(shownTabId) |
+ && mTabStatusMap.get(shownTabId).isDismissed()) { |
+ return; |
+ } |
+ |
+ // Remove the infobar observer from the previous tab and attach it to the current one. |
+ if (previousTab != null && previousTab.getInfoBarContainer() != null) { |
+ previousTab.getInfoBarContainer().removeObserver(this); |
+ } |
+ |
+ if (shownTab.getInfoBarContainer() != null) { |
+ shownTab.getInfoBarContainer().addObserver(this); |
+ } |
+ |
+ // If there is no state info for this tab, create it. |
+ ReaderModeTabInfo tabInfo = mTabStatusMap.get(shownTabId); |
+ if (tabInfo == null) { |
+ tabInfo = new ReaderModeTabInfo(); |
+ tabInfo.setStatus(NOT_POSSIBLE); |
+ tabInfo.setUrl(shownTab.getUrl()); |
+ mTabStatusMap.put(shownTabId, tabInfo); |
+ } |
+ |
+ // Make sure there is a WebContentsObserver on this tab's WebContents. |
+ if (tabInfo.getWebContentsObserver() == null) { |
+ tabInfo.setWebContentsObserver(createWebContentsObserver(shownTab.getWebContents())); |
+ } |
+ |
+ requestReaderPanelShow(StateChangeReason.UNKNOWN); |
+ } |
- if (mWebContentsObserver != null) { |
- mWebContentsObserver.destroy(); |
- mWebContentsObserver = null; |
+ @Override |
+ public void onHidden(Tab tab) { |
+ mReaderModePanel.closePanel(StateChangeReason.UNKNOWN, false); |
+ } |
+ |
+ @Override |
+ public void onDestroyed(Tab tab) { |
+ if (tab.getInfoBarContainer() != null) { |
+ tab.getInfoBarContainer().removeObserver(this); |
} |
+ removeTabState(tab.getId()); |
+ } |
- destroyReaderModeControl(); |
+ /** |
+ * Clean up the state associated with a tab. |
+ * @param tabId The target tab ID. |
+ */ |
+ private void removeTabState(int tabId) { |
+ if (!mTabStatusMap.containsKey(tabId)) return; |
+ ReaderModeTabInfo tabInfo = mTabStatusMap.get(tabId); |
+ if (tabInfo.getWebContentsObserver() != null) { |
+ tabInfo.getWebContentsObserver().destroy(); |
+ } |
+ mTabStatusMap.remove(tabId); |
} |
@Override |
public void onContentChanged(Tab tab) { |
- if (mWebContentsObserver != null) { |
- mWebContentsObserver.destroy(); |
- mWebContentsObserver = null; |
+ // Only listen to events on the currently active tab. |
+ if (tab.getId() != mTabId) return; |
+ |
+ if (mTabStatusMap.containsKey(mTabId)) { |
+ // If the panel was closed using the "x" icon, don't show it again for this tab. |
+ if (mTabStatusMap.get(mTabId).isDismissed()) return; |
+ removeTabState(mTabId); |
} |
+ |
+ ReaderModeTabInfo tabInfo = new ReaderModeTabInfo(); |
+ tabInfo.setStatus(NOT_POSSIBLE); |
+ tabInfo.setUrl(tab.getUrl()); |
+ mTabStatusMap.put(tab.getId(), tabInfo); |
+ |
if (tab.getWebContents() != null) { |
- mWebContentsObserver = createWebContentsObserver(tab.getWebContents()); |
+ tabInfo.setWebContentsObserver(createWebContentsObserver(tab.getWebContents())); |
if (DomDistillerUrlUtils.isDistilledPage(tab.getUrl())) { |
- mReaderModeStatus = STARTED; |
+ tabInfo.setStatus(STARTED); |
mReaderModePageUrl = tab.getUrl(); |
- if (mReaderModePanel != null) mReaderModePanel.updateBottomButtonBar(); |
+ mReaderModePanel.closePanel(StateChangeReason.CONTENT_CHANGED, true); |
} |
} |
- ContextualSearchManager contextualSearchManager = getContextualSearchManager(tab); |
- if (contextualSearchManager != null) contextualSearchManager.addObserver(this); |
if (tab.getInfoBarContainer() != null) tab.getInfoBarContainer().addObserver(this); |
} |
@@ -140,36 +214,37 @@ public class ReaderModeManager extends EmptyTabObserver |
public void onToggleFullscreenMode(Tab tab, boolean enable) { |
if (mReaderModePanel == null) return; |
+ // Temporarily hide the reader mode panel while fullscreen is enabled. |
if (enable) { |
- mReaderModePanel.onEnterFullscreen(); |
+ mIsFullscreenModeEntered = true; |
+ mReaderModePanel.closePanel(StateChangeReason.FULLSCREEN_ENTERED, false); |
} else { |
- mReaderModePanel.onExitFullscreen(); |
+ mIsFullscreenModeEntered = false; |
+ requestReaderPanelShow(StateChangeReason.FULLSCREEN_EXITED); |
} |
} |
- // ContextualSearchObserver: |
- @Override |
- public void onShowContextualSearch(GSAContextDisplaySelection selectionContext) { |
- if (mReaderModePanel != null) mReaderModePanel.hideButtonBar(); |
- } |
- |
- @Override |
- public void onHideContextualSearch() { |
- if (mReaderModePanel != null) mReaderModePanel.unhideButtonBar(); |
- } |
- |
// InfoBarContainerObserver: |
+ |
@Override |
public void onAddInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isFirst) { |
- if (isFirst && mReaderModePanel != null) mReaderModePanel.onShowInfobarContainer(); |
+ // Temporarily hides the reader mode button while the infobars are shown. |
+ if (isFirst && mReaderModePanel != null) { |
+ mIsInfobarContainerShown = true; |
+ mReaderModePanel.closePanel(StateChangeReason.INFOBAR_SHOWN, false); |
+ } |
} |
@Override |
public void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isLast) { |
- if (isLast && mReaderModePanel != null) mReaderModePanel.onHideInfobarContainer(); |
+ // Re-shows the reader mode button if necessary once the infobars are dismissed. |
+ if (isLast && mReaderModePanel != null) { |
+ mIsInfobarContainerShown = false; |
+ requestReaderPanelShow(StateChangeReason.INFOBAR_HIDDEN); |
+ } |
} |
- // ReaderModePanelHost: |
+ // ReaderModeManagerDelegate: |
@Override |
public int getReaderModeHeaderBackgroundColor() { |
@@ -178,50 +253,56 @@ public class ReaderModeManager extends EmptyTabObserver |
@Override |
public int getReaderModeStatus() { |
- return mReaderModeStatus; |
- } |
+ int currentTabId = mTabModelSelector.getCurrentTabId(); |
+ if (currentTabId == Tab.INVALID_TAB_ID) return NOT_POSSIBLE; |
- @Override |
- public Tab getTab() { |
- return mTab; |
+ if (!mTabStatusMap.containsKey(currentTabId)) return NOT_POSSIBLE; |
+ return mTabStatusMap.get(currentTabId).getStatus(); |
} |
@Override |
- public boolean isInsideDismissButton(float x, float y) { |
- ReaderModeActivityDelegate delegate = getReaderModeActivityDelegate(); |
- if (delegate == null) return false; |
- return delegate.getReaderModeControl().isInsideDismissButton(x, y); |
+ public void setReaderModePanel(ReaderModePanel panel) { |
+ mReaderModePanel = panel; |
} |
@Override |
- public void createReaderModeControl() { |
- ReaderModeActivityDelegate delegate = getReaderModeActivityDelegate(); |
- if (delegate != null) delegate.getReaderModeControl(); |
+ public ChromeActivity getChromeActivity() { |
+ return mChromeActivity; |
} |
@Override |
- public void destroyReaderModeControl() { |
- ReaderModeActivityDelegate delegate = getReaderModeActivityDelegate(); |
- if (delegate != null) delegate.destroyReaderModeControl(); |
- } |
- |
- /** |
- * @return The panel associated with the managed tab. |
- */ |
- public ReaderModePanel getReaderModePanel() { |
- return mReaderModePanel; |
+ public void onCloseButtonPressed() { |
+ int currentTabId = mTabModelSelector.getCurrentTabId(); |
+ if (currentTabId == Tab.INVALID_TAB_ID) return; |
+ |
+ if (!mTabStatusMap.containsKey(currentTabId)) return; |
+ ReaderModeTabInfo tabInfo = mTabStatusMap.get(currentTabId); |
+ tabInfo.setIsDismissed(true); |
+ if (tabInfo.getWebContentsObserver() != null) { |
+ tabInfo.getWebContentsObserver().destroy(); |
+ } |
} |
- private ReaderModeActivityDelegate getReaderModeActivityDelegate() { |
- return mTab.getReaderModeActivityDelegate(); |
+ @Override |
+ public void onPanelPeek() { |
+ String distillerUrl = DomDistillerUrlUtils.getDistillerViewUrlFromUrl( |
+ DOM_DISTILLER_SCHEME, mTabModelSelector.getCurrentTab().getUrl()); |
+ // Load the distilled page URL when the visibility of the panel changes. |
+ mReaderModePanel.loadUrlInPanel(distillerUrl, false); |
} |
private WebContentsObserver createWebContentsObserver(WebContents webContents) { |
+ final int readerTabId = mTabModelSelector.getCurrentTabId(); |
+ if (readerTabId == Tab.INVALID_TAB_ID) return null; |
+ |
return new WebContentsObserver(webContents) { |
@Override |
public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) { |
if (!isMainFrame) return; |
- if (DomDistillerUrlUtils.isDistilledPage(mTab.getUrl())) return; |
+ if (DomDistillerUrlUtils.isDistilledPage( |
+ mTabModelSelector.getTabById(readerTabId).getUrl())) { |
+ return; |
+ } |
updateStatusBasedOnReaderModeCriteria(true); |
} |
@@ -229,7 +310,10 @@ public class ReaderModeManager extends EmptyTabObserver |
public void didFailLoad(boolean isProvisionalLoad, boolean isMainFrame, int errorCode, |
String description, String failingUrl, boolean wasIgnoredByHandler) { |
if (!isMainFrame) return; |
- if (DomDistillerUrlUtils.isDistilledPage(mTab.getUrl())) return; |
+ if (DomDistillerUrlUtils.isDistilledPage( |
+ mTabModelSelector.getTabById(readerTabId).getUrl())) { |
+ return; |
+ } |
updateStatusBasedOnReaderModeCriteria(true); |
} |
@@ -238,9 +322,10 @@ public class ReaderModeManager extends EmptyTabObserver |
boolean isMainFrame, String validatedUrl, boolean isErrorPage, |
boolean isIframeSrcdoc) { |
if (!isMainFrame) return; |
+ mTabStatusMap.get(readerTabId).setUrl(validatedUrl); |
if (DomDistillerUrlUtils.isDistilledPage(validatedUrl)) { |
- mReaderModeStatus = STARTED; |
- if (mReaderModePanel != null) mReaderModePanel.updateBottomButtonBar(); |
+ mTabStatusMap.get(readerTabId).setStatus(STARTED); |
+ mReaderModePanel.closePanel(StateChangeReason.UNKNOWN, true); |
mReaderModePageUrl = validatedUrl; |
} |
} |
@@ -254,53 +339,115 @@ public class ReaderModeManager extends EmptyTabObserver |
if (isNavigationInPage) return; |
if (DomDistillerUrlUtils.isDistilledPage(url)) return; |
- mReaderModeStatus = POSSIBLE; |
+ mTabStatusMap.get(readerTabId).setStatus(POSSIBLE); |
if (!TextUtils.equals(url, |
DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl( |
mReaderModePageUrl))) { |
- mReaderModeStatus = NOT_POSSIBLE; |
+ mTabStatusMap.get(readerTabId).setStatus(NOT_POSSIBLE); |
mIsUmaRecorded = false; |
// Do not call updateStatusBasedOnReaderModeCriteria here. |
// For ADABOOST_MODEL, it is unlikely to get valid info at this event. |
} |
mReaderModePageUrl = null; |
- if (mReaderModePanel != null) mReaderModePanel.updateBottomButtonBar(); |
+ if (mTabStatusMap.containsKey(readerTabId) |
+ && mTabStatusMap.get(readerTabId).getStatus() != POSSIBLE) { |
+ mReaderModePanel.closePanel(StateChangeReason.UNKNOWN, false); |
+ } else { |
+ requestReaderPanelShow(StateChangeReason.UNKNOWN); |
+ } |
} |
}; |
} |
+ /** |
+ * This is a wrapper for "requestPanelShow" that checks if reader mode is possible before |
+ * showing. |
+ * @param reason The reason the panel is requesting to be shown. |
+ */ |
+ private void requestReaderPanelShow(StateChangeReason reason) { |
+ int currentTabId = mTabModelSelector.getCurrentTabId(); |
+ if (currentTabId == Tab.INVALID_TAB_ID) return; |
+ |
+ if (mReaderModePanel == null || !mTabStatusMap.containsKey(currentTabId) |
+ || mTabStatusMap.get(currentTabId).getStatus() == NOT_POSSIBLE |
+ || mTabStatusMap.get(currentTabId).isDismissed() |
+ || mIsInfobarContainerShown |
+ || mIsFullscreenModeEntered) { |
+ return; |
+ } |
+ mReaderModePanel.requestPanelShow(reason); |
+ } |
+ |
+ /** |
+ * Orientation change event handler. Simply close the panel. |
+ */ |
+ public void onOrientationChange() { |
+ if (mReaderModePanel == null) return; |
+ // Close to reset the panel then immediately show again. |
+ mReaderModePanel.closePanel(StateChangeReason.UNKNOWN, false); |
+ requestReaderPanelShow(StateChangeReason.UNKNOWN); |
+ } |
+ |
+ /** |
+ * Open a link from the panel in a new tab. |
+ * @param url The URL to load. |
+ */ |
+ public void createNewTab(String url) { |
+ if (mChromeActivity == null) return; |
+ |
+ Tab currentTab = mTabModelSelector.getCurrentTab(); |
+ if (currentTab == null) return; |
+ |
+ TabCreatorManager.TabCreator tabCreator = |
+ mChromeActivity.getTabCreator(currentTab.isIncognito()); |
+ if (tabCreator == null) return; |
+ |
+ tabCreator.createNewTab(new LoadUrlParams(url, PageTransition.LINK), |
+ TabModel.TabLaunchType.FROM_LINK, mChromeActivity.getActivityTab()); |
+ } |
+ |
// Updates reader mode status based on whether or not the page should be viewed in reader mode. |
private void updateStatusBasedOnReaderModeCriteria(final boolean forceRecord) { |
- if (mTab.getWebContents() == null) return; |
- if (mTab.getContentViewCore() == null) return; |
+ Tab currentTab = mTabModelSelector.getCurrentTab(); |
+ if (currentTab == null || currentTab.getWebContents() == null |
+ || currentTab.getContentViewCore() == null) { |
+ return; |
+ } |
- DistillablePageUtils.isPageDistillable(mTab.getWebContents(), |
- mTab.getContentViewCore().getIsMobileOptimizedHint(), |
+ final int readerTabId = currentTab.getId(); |
+ DistillablePageUtils.isPageDistillable(currentTab.getWebContents(), |
+ currentTab.getContentViewCore().getIsMobileOptimizedHint(), |
new DistillablePageUtils.PageDistillableCallback() { |
@Override |
public void onIsPageDistillableResult(boolean isDistillable) { |
+ if (!mTabStatusMap.containsKey(readerTabId)) return; |
+ ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); |
+ |
+ Tab readerTab = mTabModelSelector.getTabById(readerTabId); |
+ // Make sure the page didn't navigate while waiting for a response. |
+ if (!readerTab.getUrl().equals(tabInfo.getUrl())) return; |
+ |
if (isDistillable) { |
- mReaderModeStatus = POSSIBLE; |
+ tabInfo.setStatus(POSSIBLE); |
+ // The user may have changed tabs. |
+ if (readerTabId == mTabModelSelector.getCurrentTabId()) { |
+ // TODO(mdjones): Add reason DISTILLER_STATE_CHANGE. |
+ requestReaderPanelShow(StateChangeReason.UNKNOWN); |
+ } |
} else { |
- mReaderModeStatus = NOT_POSSIBLE; |
+ tabInfo.setStatus(NOT_POSSIBLE); |
} |
- if (!mIsUmaRecorded && (mReaderModeStatus == POSSIBLE || forceRecord)) { |
+ if (!mIsUmaRecorded |
+ && (tabInfo.getStatus() == POSSIBLE || forceRecord)) { |
mIsUmaRecorded = true; |
RecordHistogram.recordBooleanHistogram( |
- "DomDistiller.PageDistillable", mReaderModeStatus == POSSIBLE); |
+ "DomDistiller.PageDistillable", |
+ tabInfo.getStatus() == POSSIBLE); |
} |
- if (mReaderModePanel != null) mReaderModePanel.updateBottomButtonBar(); |
} |
}); |
} |
- private ContextualSearchManager getContextualSearchManager(Tab tab) { |
- if (tab == null || tab.getWindowAndroid() == null) return null; |
- Activity activity = tab.getWindowAndroid().getActivity().get(); |
- if (!(activity instanceof ChromeActivity)) return null; |
- return ((ChromeActivity) activity).getContextualSearchManager(); |
- } |
- |
/** |
* @return Whether Reader mode and its new UI are enabled. |
* @param context A context |
@@ -312,7 +459,8 @@ public class ReaderModeManager extends EmptyTabObserver |
&& !CommandLine.getInstance().hasSwitch( |
ChromeSwitches.DISABLE_READER_MODE_BOTTOM_BAR) |
&& !DeviceFormFactor.isTablet(context) |
- && DomDistillerTabUtils.isDistillerHeuristicsEnabled(); |
+ && DomDistillerTabUtils.isDistillerHeuristicsEnabled() |
+ && !SysUtils.isLowEndDevice(); |
return enabled; |
} |
} |