Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.dom_distiller; | 5 package org.chromium.chrome.browser.dom_distiller; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.text.TextUtils; | 8 import android.text.TextUtils; |
| 9 | 9 |
| 10 import org.chromium.base.CommandLine; | 10 import org.chromium.base.CommandLine; |
| 11 import org.chromium.base.SysUtils; | |
| 12 import org.chromium.base.VisibleForTesting; | |
| 13 import org.chromium.base.library_loader.LibraryLoader; | 11 import org.chromium.base.library_loader.LibraryLoader; |
| 14 import org.chromium.base.metrics.RecordHistogram; | 12 import org.chromium.base.metrics.RecordHistogram; |
| 15 import org.chromium.chrome.browser.ChromeActivity; | 13 import org.chromium.chrome.browser.ChromeActivity; |
| 16 import org.chromium.chrome.browser.ChromeSwitches; | 14 import org.chromium.chrome.browser.ChromeSwitches; |
| 17 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.PanelState; | |
| 18 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange Reason; | 15 import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChange Reason; |
| 19 import org.chromium.chrome.browser.compositor.bottombar.readermode.ReaderModePan el; | 16 import org.chromium.chrome.browser.infobar.ReaderModeInfoBar; |
| 20 import org.chromium.chrome.browser.infobar.InfoBar; | |
| 21 import org.chromium.chrome.browser.infobar.InfoBarContainer; | |
| 22 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarContainerObse rver; | |
| 23 import org.chromium.chrome.browser.rappor.RapporServiceBridge; | 17 import org.chromium.chrome.browser.rappor.RapporServiceBridge; |
| 24 import org.chromium.chrome.browser.tab.Tab; | 18 import org.chromium.chrome.browser.tab.Tab; |
| 25 import org.chromium.chrome.browser.tabmodel.TabCreatorManager; | 19 import org.chromium.chrome.browser.tabmodel.TabCreatorManager; |
| 26 import org.chromium.chrome.browser.tabmodel.TabModel; | 20 import org.chromium.chrome.browser.tabmodel.TabModel; |
| 27 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 21 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
| 28 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; | 22 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; |
| 29 import org.chromium.chrome.browser.util.AccessibilityUtil; | 23 import org.chromium.chrome.browser.util.AccessibilityUtil; |
| 30 import org.chromium.chrome.browser.widget.findinpage.FindToolbarObserver; | |
| 31 import org.chromium.components.dom_distiller.content.DistillablePageUtils; | 24 import org.chromium.components.dom_distiller.content.DistillablePageUtils; |
| 32 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; | 25 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; |
| 33 import org.chromium.content_public.browser.LoadUrlParams; | 26 import org.chromium.content_public.browser.LoadUrlParams; |
| 27 import org.chromium.content_public.browser.NavigationController; | |
| 28 import org.chromium.content_public.browser.NavigationEntry; | |
| 34 import org.chromium.content_public.browser.WebContents; | 29 import org.chromium.content_public.browser.WebContents; |
| 35 import org.chromium.content_public.browser.WebContentsObserver; | 30 import org.chromium.content_public.browser.WebContentsObserver; |
| 36 import org.chromium.ui.UiUtils; | 31 import org.chromium.ui.UiUtils; |
| 37 import org.chromium.ui.base.DeviceFormFactor; | |
| 38 import org.chromium.ui.base.PageTransition; | 32 import org.chromium.ui.base.PageTransition; |
| 39 | 33 |
| 40 import java.util.HashMap; | 34 import java.util.HashMap; |
| 41 import java.util.Map; | 35 import java.util.Map; |
| 42 import java.util.concurrent.TimeUnit; | 36 import java.util.concurrent.TimeUnit; |
| 43 | 37 |
| 44 /** | 38 /** |
| 45 * Manages UI effects for reader mode including hiding and showing the | 39 * Manages UI effects for reader mode including hiding and showing the |
| 46 * reader mode and reader mode preferences toolbar icon and hiding the | 40 * reader mode and reader mode preferences toolbar icon and hiding the |
| 47 * browser controls when a reader mode page has finished loading. | 41 * browser controls when a reader mode page has finished loading. |
| 48 */ | 42 */ |
| 49 public class ReaderModeManager extends TabModelSelectorTabObserver | 43 public class ReaderModeManager |
| 50 implements InfoBarContainerObserver, ReaderModeManagerDelegate { | 44 extends TabModelSelectorTabObserver implements ReaderModeManagerDelegate { |
| 51 | 45 /** POSSIBLE means reader mode can be entered. */ |
| 52 /** | |
| 53 * POSSIBLE means reader mode can be entered. | |
| 54 */ | |
| 55 public static final int POSSIBLE = 0; | 46 public static final int POSSIBLE = 0; |
| 56 | 47 |
| 57 /** | 48 /** NOT_POSSIBLE means reader mode cannot be entered. */ |
| 58 * NOT_POSSIBLE means reader mode cannot be entered. | |
| 59 */ | |
| 60 public static final int NOT_POSSIBLE = 1; | 49 public static final int NOT_POSSIBLE = 1; |
| 61 | 50 |
| 62 /** | 51 /** STARTED means reader mode is currently in reader mode. */ |
| 63 * STARTED means reader mode is currently in reader mode. | |
| 64 */ | |
| 65 public static final int STARTED = 2; | 52 public static final int STARTED = 2; |
| 66 | 53 |
| 67 // The url of the last page visited if the last page was reader mode page. Otherwise null. | 54 /** The url of the last page visited if the last page was reader mode page. Otherwise null. */ |
| 68 private String mReaderModePageUrl; | 55 private String mReaderModePageUrl; |
| 69 | 56 |
| 70 // Whether the fact that the current web page was distillable or not has bee n recorded. | 57 /** Whether the fact that the current web page was distillable or not has be en recorded. */ |
| 71 private boolean mIsUmaRecorded; | 58 private boolean mIsUmaRecorded; |
| 72 | 59 |
| 73 // The per-tab state of distillation. | 60 /** The per-tab state of distillation. */ |
| 74 protected Map<Integer, ReaderModeTabInfo> mTabStatusMap; | 61 protected Map<Integer, ReaderModeTabInfo> mTabStatusMap; |
| 75 | 62 |
| 76 // The current tab ID. This will change as the user switches between tabs. | 63 /** The ChromeActivity that this panel exists in. */ |
|
wychen
2017/05/18 15:26:22
Do we still call it panel?
mdjones
2017/05/18 16:45:55
I renamed panel to infobar in places that will exi
| |
| 77 private int mTabId; | |
| 78 | |
| 79 // The ReaderModePanel that this class is managing. | |
| 80 protected ReaderModePanel mReaderModePanel; | |
| 81 | |
| 82 // The ChromeActivity that this panel exists in. | |
| 83 private ChromeActivity mChromeActivity; | 64 private ChromeActivity mChromeActivity; |
| 84 | 65 |
| 85 // The primary means of getting the currently active tab. | 66 /** The primary means of getting the currently active tab. */ |
| 86 private TabModelSelector mTabModelSelector; | 67 private TabModelSelector mTabModelSelector; |
| 87 | 68 |
| 88 private boolean mIsFullscreenModeEntered; | 69 /** If Reader Mode is detecting all pages as distillable. */ |
| 89 private boolean mIsFindToolbarShowing; | |
| 90 private boolean mIsKeyboardShowing; | |
| 91 | |
| 92 // InfoBar tracking. | |
| 93 private boolean mIsInfoBarContainerShown; | |
| 94 | |
| 95 // If Reader Mode is detecting all pages as distillable. | |
| 96 private boolean mIsReaderHeuristicAlwaysTrue; | 70 private boolean mIsReaderHeuristicAlwaysTrue; |
| 97 | 71 |
| 98 | |
| 99 public ReaderModeManager(TabModelSelector selector, ChromeActivity activity) { | 72 public ReaderModeManager(TabModelSelector selector, ChromeActivity activity) { |
| 100 super(selector); | 73 super(selector); |
| 101 mTabId = Tab.INVALID_TAB_ID; | |
| 102 mTabModelSelector = selector; | 74 mTabModelSelector = selector; |
| 103 mChromeActivity = activity; | 75 mChromeActivity = activity; |
| 104 mTabStatusMap = new HashMap<>(); | 76 mTabStatusMap = new HashMap<>(); |
| 105 mIsReaderHeuristicAlwaysTrue = isDistillerHeuristicAlwaysTrue(); | 77 mIsReaderHeuristicAlwaysTrue = isDistillerHeuristicAlwaysTrue(); |
| 106 } | 78 } |
| 107 | 79 |
| 108 /** | 80 /** |
| 109 * This function wraps a method that calls native code and is overridden by tests. | 81 * This function wraps a method that calls native code and is overridden by tests. |
| 110 * @return True if the heuristic is ALWAYS_TRUE. | 82 * @return True if the heuristic is ALWAYS_TRUE. |
| 111 */ | 83 */ |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 122 for (Map.Entry<Integer, ReaderModeTabInfo> e : mTabStatusMap.entrySet()) { | 94 for (Map.Entry<Integer, ReaderModeTabInfo> e : mTabStatusMap.entrySet()) { |
| 123 if (e.getValue().getWebContentsObserver() != null) { | 95 if (e.getValue().getWebContentsObserver() != null) { |
| 124 e.getValue().getWebContentsObserver().destroy(); | 96 e.getValue().getWebContentsObserver().destroy(); |
| 125 } | 97 } |
| 126 } | 98 } |
| 127 mTabStatusMap.clear(); | 99 mTabStatusMap.clear(); |
| 128 | 100 |
| 129 DomDistillerUIUtils.destroy(this); | 101 DomDistillerUIUtils.destroy(this); |
| 130 | 102 |
| 131 mChromeActivity = null; | 103 mChromeActivity = null; |
| 132 mReaderModePanel = null; | |
| 133 mTabModelSelector = null; | 104 mTabModelSelector = null; |
| 134 } | 105 } |
| 135 | 106 |
| 136 /** | |
| 137 * @return A FindToolbarObserver capable of hiding the Reader Mode panel. | |
| 138 */ | |
| 139 public FindToolbarObserver getFindToolbarObserver() { | |
| 140 return new FindToolbarObserver() { | |
| 141 @Override | |
| 142 public void onFindToolbarShown() { | |
| 143 mIsFindToolbarShowing = true; | |
| 144 closeReaderPanel(StateChangeReason.UNKNOWN, true); | |
| 145 } | |
| 146 | |
| 147 @Override | |
| 148 public void onFindToolbarHidden() { | |
| 149 mIsFindToolbarShowing = false; | |
| 150 requestReaderPanelShow(StateChangeReason.UNKNOWN); | |
| 151 } | |
| 152 }; | |
| 153 } | |
| 154 | |
| 155 // TabModelSelectorTabObserver: | 107 // TabModelSelectorTabObserver: |
| 156 | 108 |
| 157 @Override | 109 @Override |
| 158 public void onShown(Tab shownTab) { | 110 public void onShown(Tab shownTab) { |
| 159 if (mTabModelSelector == null) return; | 111 if (mTabModelSelector == null) return; |
| 160 | 112 |
| 161 int shownTabId = shownTab.getId(); | 113 int shownTabId = shownTab.getId(); |
| 162 Tab previousTab = mTabModelSelector.getTabById(mTabId); | |
| 163 mTabId = shownTabId; | |
| 164 | 114 |
| 165 // If the reader panel was dismissed, stop here. | 115 // If the reader panel was dismissed, stop here. |
|
wychen
2017/05/18 15:26:21
s/panel/infobar/?
mdjones
2017/05/18 16:45:55
Done.
| |
| 166 if (mTabStatusMap.containsKey(shownTabId) | 116 if (mTabStatusMap.containsKey(shownTabId) |
| 167 && mTabStatusMap.get(shownTabId).isDismissed()) { | 117 && mTabStatusMap.get(shownTabId).isDismissed()) { |
| 168 return; | 118 return; |
| 169 } | 119 } |
| 170 | 120 |
| 171 // Set this manager as the active one for the UI utils. | 121 // Set this manager as the active one for the UI utils. |
| 172 DomDistillerUIUtils.setReaderModeManagerDelegate(this); | 122 DomDistillerUIUtils.setReaderModeManagerDelegate(this); |
| 173 | 123 |
| 174 // Update infobar state based on current tab. | |
| 175 if (shownTab.getInfoBarContainer() != null) { | |
| 176 mIsInfoBarContainerShown = shownTab.getInfoBarContainer().hasInfoBar s(); | |
| 177 } | |
| 178 | |
| 179 // Remove the infobar observer from the previous tab and attach it to th e current one. | |
| 180 if (previousTab != null && previousTab.getInfoBarContainer() != null) { | |
| 181 previousTab.getInfoBarContainer().removeObserver(this); | |
| 182 } | |
| 183 | |
| 184 if (shownTab.getInfoBarContainer() != null) { | |
| 185 shownTab.getInfoBarContainer().addObserver(this); | |
| 186 } | |
| 187 | |
| 188 // If there is no state info for this tab, create it. | 124 // If there is no state info for this tab, create it. |
| 189 ReaderModeTabInfo tabInfo = mTabStatusMap.get(shownTabId); | 125 ReaderModeTabInfo tabInfo = mTabStatusMap.get(shownTabId); |
| 190 if (tabInfo == null) { | 126 if (tabInfo == null) { |
| 191 tabInfo = new ReaderModeTabInfo(); | 127 tabInfo = new ReaderModeTabInfo(); |
| 192 tabInfo.setStatus(NOT_POSSIBLE); | 128 tabInfo.setStatus(NOT_POSSIBLE); |
| 193 tabInfo.setUrl(shownTab.getUrl()); | 129 tabInfo.setUrl(shownTab.getUrl()); |
| 194 mTabStatusMap.put(shownTabId, tabInfo); | 130 mTabStatusMap.put(shownTabId, tabInfo); |
| 195 } | 131 } |
| 196 | 132 |
| 133 if (DomDistillerUrlUtils.isDistilledPage(shownTab.getUrl()) | |
| 134 && !tabInfo.isViewingReaderModePage()) { | |
| 135 tabInfo.onStartedReaderMode(); | |
| 136 } | |
| 137 | |
| 197 // Make sure there is a WebContentsObserver on this tab's WebContents. | 138 // Make sure there is a WebContentsObserver on this tab's WebContents. |
| 198 if (tabInfo.getWebContentsObserver() == null) { | 139 if (tabInfo.getWebContentsObserver() == null) { |
| 199 tabInfo.setWebContentsObserver(createWebContentsObserver(shownTab.ge tWebContents())); | 140 tabInfo.setWebContentsObserver(createWebContentsObserver(shownTab.ge tWebContents())); |
| 200 } | 141 } |
| 201 | 142 |
| 202 // Make sure there is a distillability delegate set on the WebContents. | 143 // Make sure there is a distillability delegate set on the WebContents. |
| 203 setDistillabilityCallback(shownTabId); | 144 setDistillabilityCallback(shownTabId); |
| 204 | 145 |
| 205 requestReaderPanelShow(StateChangeReason.UNKNOWN); | 146 tryShowingInfoBar(); |
| 206 } | 147 } |
| 207 | 148 |
| 208 @Override | 149 @Override |
| 209 public void onHidden(Tab tab) { | 150 public void onHidden(Tab tab) { |
| 210 closeReaderPanel(StateChangeReason.UNKNOWN, false); | 151 closeReaderPanel(StateChangeReason.UNKNOWN, false); |
| 152 ReaderModeTabInfo info = mTabStatusMap.get(tab.getId()); | |
| 153 if (info != null && info.isViewingReaderModePage()) { | |
| 154 long timeMs = info.onExitReaderMode(); | |
| 155 recordReaderModeViewDuration(timeMs); | |
| 156 } | |
| 211 } | 157 } |
| 212 | 158 |
| 213 @Override | 159 @Override |
| 214 public void onDestroyed(Tab tab) { | 160 public void onDestroyed(Tab tab) { |
| 215 if (tab == null) return; | 161 if (tab == null) return; |
| 216 if (tab.getInfoBarContainer() != null) { | 162 |
| 217 tab.getInfoBarContainer().removeObserver(this); | |
| 218 } | |
| 219 // If the panel was not shown for the previous navigation, record it now . | 163 // If the panel was not shown for the previous navigation, record it now . |
| 220 ReaderModeTabInfo info = mTabStatusMap.get(tab.getId()); | 164 ReaderModeTabInfo info = mTabStatusMap.get(tab.getId()); |
| 221 if (info != null && !info.isPanelShowRecorded()) { | 165 if (info != null) { |
| 222 recordPanelVisibilityForNavigation(false); | 166 if (!info.isPanelShowRecorded()) { |
| 167 recordPanelVisibilityForNavigation(false); | |
| 168 } | |
| 169 if (info.isViewingReaderModePage()) { | |
| 170 long timeMs = info.onExitReaderMode(); | |
| 171 recordReaderModeViewDuration(timeMs); | |
| 172 } | |
| 223 } | 173 } |
| 224 removeTabState(tab.getId()); | 174 removeTabState(tab.getId()); |
| 225 } | 175 } |
| 226 | 176 |
| 227 /** | 177 /** |
| 228 * Clean up the state associated with a tab. | 178 * Clean up the state associated with a tab. |
| 229 * @param tabId The target tab ID. | 179 * @param tabId The target tab ID. |
| 230 */ | 180 */ |
| 231 private void removeTabState(int tabId) { | 181 private void removeTabState(int tabId) { |
| 232 if (!mTabStatusMap.containsKey(tabId)) return; | 182 if (!mTabStatusMap.containsKey(tabId)) return; |
| 233 ReaderModeTabInfo tabInfo = mTabStatusMap.get(tabId); | 183 ReaderModeTabInfo tabInfo = mTabStatusMap.get(tabId); |
| 234 if (tabInfo.getWebContentsObserver() != null) { | 184 if (tabInfo.getWebContentsObserver() != null) { |
| 235 tabInfo.getWebContentsObserver().destroy(); | 185 tabInfo.getWebContentsObserver().destroy(); |
| 236 } | 186 } |
| 237 mTabStatusMap.remove(tabId); | 187 mTabStatusMap.remove(tabId); |
| 238 } | 188 } |
| 239 | 189 |
| 240 @Override | 190 @Override |
| 241 public void onContentChanged(Tab tab) { | 191 public void onContentChanged(Tab tab) { |
| 242 // Only listen to events on the currently active tab. | 192 // If the content change was because of distiller switching web contents or Reader Mode has |
| 243 if (tab.getId() != mTabId) return; | 193 // already been dismissed for this tab do nothing. |
| 244 closeReaderPanel(StateChangeReason.UNKNOWN, false); | 194 if (mTabStatusMap.containsKey(tab.getId()) && mTabStatusMap.get(tab.getI d()).isDismissed() |
| 245 | 195 && !DomDistillerUrlUtils.isDistilledPage(tab.getUrl())) { |
| 246 if (mTabStatusMap.containsKey(mTabId)) { | 196 return; |
| 247 // If the panel was closed using the "x" icon, don't show it again f or this tab. | |
| 248 if (mTabStatusMap.get(mTabId).isDismissed()) return; | |
| 249 removeTabState(mTabId); | |
| 250 } | 197 } |
| 251 | 198 |
| 252 ReaderModeTabInfo tabInfo = new ReaderModeTabInfo(); | 199 ReaderModeTabInfo tabInfo = mTabStatusMap.get(tab.getId()); |
| 200 if (!mTabStatusMap.containsKey(tab.getId())) { | |
| 201 tabInfo = new ReaderModeTabInfo(); | |
| 202 mTabStatusMap.put(tab.getId(), tabInfo); | |
| 203 } | |
| 204 // If the tab state already existed, only reset the relevant data. Thing s like view duration | |
| 205 // need to be preserved. | |
| 253 tabInfo.setStatus(NOT_POSSIBLE); | 206 tabInfo.setStatus(NOT_POSSIBLE); |
| 254 tabInfo.setUrl(tab.getUrl()); | 207 tabInfo.setUrl(tab.getUrl()); |
| 255 mTabStatusMap.put(tab.getId(), tabInfo); | 208 tabInfo.setIsCallbackSet(false); |
| 256 | 209 |
| 257 if (tab.getWebContents() != null) { | 210 if (tab.getWebContents() != null) { |
| 258 tabInfo.setWebContentsObserver(createWebContentsObserver(tab.getWebC ontents())); | 211 tabInfo.setWebContentsObserver(createWebContentsObserver(tab.getWebC ontents())); |
| 259 if (DomDistillerUrlUtils.isDistilledPage(tab.getUrl())) { | 212 if (DomDistillerUrlUtils.isDistilledPage(tab.getUrl())) { |
| 260 tabInfo.setStatus(STARTED); | 213 tabInfo.setStatus(STARTED); |
| 261 mReaderModePageUrl = tab.getUrl(); | 214 mReaderModePageUrl = tab.getUrl(); |
| 262 closeReaderPanel(StateChangeReason.CONTENT_CHANGED, true); | 215 closeReaderPanel(StateChangeReason.CONTENT_CHANGED, true); |
| 263 } | 216 } |
| 264 // Make sure there is a distillability delegate set on the WebConten ts. | 217 // Make sure there is a distillability delegate set on the WebConten ts. |
| 265 setDistillabilityCallback(tab.getId()); | 218 setDistillabilityCallback(tab.getId()); |
| 266 } | 219 } |
| 267 | |
| 268 if (tab.getInfoBarContainer() != null) tab.getInfoBarContainer().addObse rver(this); | |
| 269 } | |
| 270 | |
| 271 @Override | |
| 272 public void onToggleFullscreenMode(Tab tab, boolean enable) { | |
| 273 // Temporarily hide the reader mode panel while fullscreen is enabled. | |
| 274 if (enable) { | |
| 275 mIsFullscreenModeEntered = true; | |
| 276 closeReaderPanel(StateChangeReason.FULLSCREEN_ENTERED, false); | |
| 277 } else { | |
| 278 mIsFullscreenModeEntered = false; | |
| 279 requestReaderPanelShow(StateChangeReason.FULLSCREEN_EXITED); | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 // InfoBarContainerObserver: | |
| 284 | |
| 285 @Override | |
| 286 public void onAddInfoBar(InfoBarContainer container, InfoBar infoBar, boolea n isFirst) { | |
| 287 mIsInfoBarContainerShown = true; | |
| 288 // If the panel is opened past the peeking state, obscure the infobar. | |
| 289 if (mReaderModePanel != null && mReaderModePanel.isPanelOpened() && cont ainer != null) { | |
| 290 container.setIsObscuredByOtherView(true); | |
| 291 } else if (isFirst) { | |
| 292 // Temporarily hides the reader mode button while the infobars are s hown. | |
| 293 closeReaderPanel(StateChangeReason.INFOBAR_SHOWN, false); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 @Override | |
| 298 public void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boo lean isLast) { | |
| 299 // Re-shows the reader mode button if necessary once the infobars are di smissed. | |
| 300 if (isLast) { | |
| 301 mIsInfoBarContainerShown = false; | |
| 302 requestReaderPanelShow(StateChangeReason.INFOBAR_HIDDEN); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 @Override | |
| 307 public void onInfoBarContainerAttachedToWindow(boolean hasInfoBars) { | |
| 308 mIsInfoBarContainerShown = hasInfoBars; | |
| 309 if (mIsInfoBarContainerShown) { | |
| 310 closeReaderPanel(StateChangeReason.INFOBAR_SHOWN, false); | |
| 311 } else { | |
| 312 requestReaderPanelShow(StateChangeReason.INFOBAR_HIDDEN); | |
| 313 } | |
| 314 } | 220 } |
| 315 | 221 |
| 316 // ReaderModeManagerDelegate: | 222 // ReaderModeManagerDelegate: |
| 317 | 223 |
| 318 @Override | 224 @Override |
| 319 public void setReaderModePanel(ReaderModePanel panel) { | |
| 320 mReaderModePanel = panel; | |
| 321 } | |
| 322 | |
| 323 @Override | |
| 324 public ChromeActivity getChromeActivity() { | 225 public ChromeActivity getChromeActivity() { |
| 325 return mChromeActivity; | 226 return mChromeActivity; |
| 326 } | 227 } |
| 327 | 228 |
| 328 @Override | 229 @Override |
| 329 public void onPanelShown() { | 230 public void onPanelShown() { |
| 330 if (mTabModelSelector == null) return; | 231 if (mTabModelSelector == null) return; |
| 331 int tabId = mTabModelSelector.getCurrentTabId(); | 232 int tabId = mTabModelSelector.getCurrentTabId(); |
| 332 | 233 |
| 333 ReaderModeTabInfo info = mTabStatusMap.get(tabId); | 234 ReaderModeTabInfo info = mTabStatusMap.get(tabId); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 344 /** | 245 /** |
| 345 * Record if the panel became visible on the current page. This can be overr idden for testing. | 246 * Record if the panel became visible on the current page. This can be overr idden for testing. |
| 346 * @param visible If the panel was visible at any time. | 247 * @param visible If the panel was visible at any time. |
| 347 */ | 248 */ |
| 348 protected void recordPanelVisibilityForNavigation(boolean visible) { | 249 protected void recordPanelVisibilityForNavigation(boolean visible) { |
| 349 RecordHistogram.recordBooleanHistogram("DomDistiller.ReaderShownForPageL oad", visible); | 250 RecordHistogram.recordBooleanHistogram("DomDistiller.ReaderShownForPageL oad", visible); |
| 350 } | 251 } |
| 351 | 252 |
| 352 @Override | 253 @Override |
| 353 public void onClosed(StateChangeReason reason) { | 254 public void onClosed(StateChangeReason reason) { |
| 354 if (mReaderModePanel == null || mTabModelSelector == null) return; | 255 if (mTabModelSelector == null) return; |
| 355 | 256 |
| 356 restoreInfobars(); | 257 RecordHistogram.recordBooleanHistogram("DomDistiller.InfoBarUsage", fals e); |
| 357 | |
| 358 // Only dismiss the panel if the close was a result of user interaction. | |
| 359 if (reason != StateChangeReason.FLING && reason != StateChangeReason.SWI PE | |
| 360 && reason != StateChangeReason.CLOSE_BUTTON) { | |
| 361 return; | |
| 362 } | |
| 363 | |
| 364 // Record close button usage. | |
| 365 if (reason == StateChangeReason.CLOSE_BUTTON) { | |
| 366 RecordHistogram.recordBooleanHistogram("DomDistiller.BarCloseButtonU sage", | |
| 367 mReaderModePanel.getPanelState() == PanelState.EXPANDED | |
| 368 || mReaderModePanel.getPanelState() == PanelState.MAXIMIZED) ; | |
| 369 } | |
| 370 | 258 |
| 371 int currentTabId = mTabModelSelector.getCurrentTabId(); | 259 int currentTabId = mTabModelSelector.getCurrentTabId(); |
| 372 if (!mTabStatusMap.containsKey(currentTabId)) return; | 260 if (!mTabStatusMap.containsKey(currentTabId)) return; |
| 373 mTabStatusMap.get(currentTabId).setIsDismissed(true); | 261 mTabStatusMap.get(currentTabId).setIsDismissed(true); |
| 374 } | 262 } |
| 375 | 263 |
| 376 @Override | 264 @Override |
| 377 public void onPeek() { | |
| 378 restoreInfobars(); | |
| 379 } | |
| 380 | |
| 381 /** | |
| 382 * Restore any infobars that may have been hidden by Reader Mode. | |
| 383 */ | |
| 384 private void restoreInfobars() { | |
| 385 if (!mIsInfoBarContainerShown) return; | |
| 386 | |
| 387 Tab curTab = mTabModelSelector.getCurrentTab(); | |
| 388 if (curTab == null) return; | |
| 389 | |
| 390 InfoBarContainer container = curTab.getInfoBarContainer(); | |
| 391 if (container == null) return; | |
| 392 | |
| 393 container.setIsObscuredByOtherView(false); | |
| 394 | |
| 395 // Temporarily hides the reader mode button while the infobars are shown . | |
| 396 closeReaderPanel(StateChangeReason.INFOBAR_SHOWN, false); | |
| 397 } | |
| 398 | |
| 399 @Override | |
| 400 public WebContents getBasePageWebContents() { | 265 public WebContents getBasePageWebContents() { |
| 401 Tab tab = mTabModelSelector.getCurrentTab(); | 266 Tab tab = mTabModelSelector.getCurrentTab(); |
| 402 if (tab == null) return null; | 267 if (tab == null) return null; |
| 403 | 268 |
| 404 return tab.getWebContents(); | 269 return tab.getWebContents(); |
| 405 } | 270 } |
| 406 | 271 |
| 407 @Override | 272 @Override |
| 408 public void closeReaderPanel(StateChangeReason reason, boolean animate) { | 273 public void closeReaderPanel(StateChangeReason reason, boolean animate) { |
| 409 if (mReaderModePanel == null) return; | 274 // TODO(mdjones): Remove this method and dependencies. |
| 410 mReaderModePanel.closePanel(reason, animate); | |
| 411 } | 275 } |
| 412 | 276 |
| 413 @Override | 277 @Override |
| 414 public void recordTimeSpentInReader(long timeMs) { | 278 public void recordTimeSpentInReader(long timeMs) { |
| 415 RecordHistogram.recordLongTimesHistogram("DomDistiller.Time.ViewingReade rModePanel", | 279 RecordHistogram.recordLongTimesHistogram("DomDistiller.Time.ViewingReade rModePanel", |
| 416 timeMs, TimeUnit.MILLISECONDS); | 280 timeMs, TimeUnit.MILLISECONDS); |
| 417 } | 281 } |
| 418 | 282 |
| 419 @Override | |
| 420 public void onLayoutChanged() { | |
| 421 if (isKeyboardShowing()) { | |
| 422 mIsKeyboardShowing = true; | |
| 423 closeReaderPanel(StateChangeReason.KEYBOARD_SHOWN, false); | |
| 424 } else if (mIsKeyboardShowing) { | |
| 425 mIsKeyboardShowing = false; | |
| 426 requestReaderPanelShow(StateChangeReason.KEYBOARD_HIDDEN); | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 /** | 283 /** |
| 431 * @return True if the keyboard might be showing. This is not 100% accurate; see | 284 * @return True if the keyboard might be showing. This is not 100% accurate; see |
| 432 * UiUtils.isKeyboardShowing(...). | 285 * UiUtils.isKeyboardShowing(...). |
| 433 */ | 286 */ |
| 434 protected boolean isKeyboardShowing() { | 287 protected boolean isKeyboardShowing() { |
| 435 return mChromeActivity != null && UiUtils.isKeyboardShowing(mChromeActiv ity, | 288 return mChromeActivity != null && UiUtils.isKeyboardShowing(mChromeActiv ity, |
| 436 mChromeActivity.findViewById(android.R.id.content)); | 289 mChromeActivity.findViewById(android.R.id.content)); |
| 437 } | 290 } |
| 438 | 291 |
| 439 protected WebContentsObserver createWebContentsObserver(WebContents webConte nts) { | 292 protected WebContentsObserver createWebContentsObserver(final WebContents we bContents) { |
| 440 final int readerTabId = mTabModelSelector.getCurrentTabId(); | 293 final int readerTabId = mTabModelSelector.getCurrentTabId(); |
| 441 if (readerTabId == Tab.INVALID_TAB_ID) return null; | 294 if (readerTabId == Tab.INVALID_TAB_ID) return null; |
| 442 | 295 |
| 443 return new WebContentsObserver(webContents) { | 296 return new WebContentsObserver(webContents) { |
| 297 /** Whether or not the previous navigation should be removed. */ | |
| 298 private boolean mShouldRemovePreviousNavigation; | |
| 299 | |
| 300 /** The index of the last committed distiller page in history. */ | |
| 301 private int mLastDistillerPageIndex; | |
| 302 | |
| 444 @Override | 303 @Override |
| 445 public void didStartNavigation(String url, boolean isInMainFrame, | 304 public void didStartNavigation(String url, boolean isInMainFrame, |
| 446 boolean isSameDocument, boolean isErrorPage) { | 305 boolean isSameDocument, boolean isErrorPage) { |
| 447 if (!isInMainFrame || isSameDocument) return; | 306 if (!isInMainFrame || isSameDocument) return; |
| 307 | |
| 308 // Reader Mode should not pollute the navigation stack. To avoid this, watch for | |
| 309 // navigations and prepare to remove any that are "chrome-distil ler" urls. | |
| 310 NavigationController controller = webContents.getNavigationContr oller(); | |
| 311 int index = controller.getLastCommittedEntryIndex(); | |
| 312 NavigationEntry entry = controller.getEntryAtIndex(index); | |
| 313 | |
| 314 if (entry != null && DomDistillerUrlUtils.isDistilledPage(entry. getUrl())) { | |
| 315 mShouldRemovePreviousNavigation = true; | |
| 316 mLastDistillerPageIndex = index; | |
| 317 } | |
| 318 | |
| 448 // If there is a navigation in the current tab, hide the bar. It will show again | 319 // If there is a navigation in the current tab, hide the bar. It will show again |
| 449 // once the distillability test is successful. | 320 // once the distillability test is successful. |
| 450 if (readerTabId == mTabModelSelector.getCurrentTabId()) { | 321 if (readerTabId == mTabModelSelector.getCurrentTabId()) { |
| 451 closeReaderPanel(StateChangeReason.TAB_NAVIGATION, false); | 322 closeReaderPanel(StateChangeReason.TAB_NAVIGATION, false); |
| 452 } | 323 } |
| 453 | 324 |
| 454 // Make sure the tab was not destroyed. | 325 // Make sure the tab was not destroyed. |
| 455 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); | 326 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); |
| 456 if (tabInfo == null) return; | 327 if (tabInfo == null) return; |
| 457 | 328 |
| 458 tabInfo.setUrl(url); | 329 tabInfo.setUrl(url); |
| 459 if (DomDistillerUrlUtils.isDistilledPage(url)) { | 330 if (DomDistillerUrlUtils.isDistilledPage(url)) { |
| 460 tabInfo.setStatus(STARTED); | 331 tabInfo.setStatus(STARTED); |
| 461 mReaderModePageUrl = url; | 332 mReaderModePageUrl = url; |
| 462 } | 333 } |
| 463 } | 334 } |
| 464 | 335 |
| 465 @Override | 336 @Override |
| 466 public void didFinishNavigation(String url, boolean isInMainFrame, b oolean isErrorPage, | 337 public void didFinishNavigation(String url, boolean isInMainFrame, b oolean isErrorPage, |
| 467 boolean hasCommitted, boolean isSameDocument, boolean isFrag mentNavigation, | 338 boolean hasCommitted, boolean isSameDocument, boolean isFrag mentNavigation, |
| 468 Integer pageTransition, int errorCode, String errorDescripti on, | 339 Integer pageTransition, int errorCode, String errorDescripti on, |
| 469 int httpStatusCode) { | 340 int httpStatusCode) { |
| 470 // TODO(cjhopman): This should possibly ignore navigations that replace the entry | 341 // TODO(cjhopman): This should possibly ignore navigations that replace the entry |
| 471 // (like those from history.replaceState()). | 342 // (like those from history.replaceState()). |
| 472 if (!hasCommitted || !isInMainFrame || isSameDocument) return; | 343 if (!hasCommitted || !isInMainFrame || isSameDocument) return; |
| 473 if (DomDistillerUrlUtils.isDistilledPage(url)) return; | 344 |
| 345 if (mShouldRemovePreviousNavigation) { | |
| 346 mShouldRemovePreviousNavigation = false; | |
| 347 NavigationController controller = webContents.getNavigationC ontroller(); | |
| 348 controller.removeEntryAtIndex(mLastDistillerPageIndex); | |
| 349 } | |
| 474 | 350 |
| 475 // Make sure the tab was not destroyed. | 351 // Make sure the tab was not destroyed. |
| 476 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); | 352 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); |
| 477 if (tabInfo == null) return; | 353 if (tabInfo == null) return; |
| 478 | 354 |
| 479 tabInfo.setStatus(POSSIBLE); | 355 tabInfo.setStatus(POSSIBLE); |
| 480 if (!TextUtils.equals(url, | 356 if (!TextUtils.equals(url, |
| 481 DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl( | 357 DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl( |
| 482 mReaderModePageUrl))) { | 358 mReaderModePageUrl))) { |
| 483 tabInfo.setStatus(NOT_POSSIBLE); | 359 tabInfo.setStatus(NOT_POSSIBLE); |
| 484 mIsUmaRecorded = false; | 360 mIsUmaRecorded = false; |
| 485 } | 361 } |
| 486 mReaderModePageUrl = null; | 362 mReaderModePageUrl = null; |
| 487 | 363 |
| 488 if (tabInfo.getStatus() != POSSIBLE) { | 364 if (tabInfo.getStatus() != POSSIBLE) { |
| 489 closeReaderPanel(StateChangeReason.UNKNOWN, false); | 365 closeReaderPanel(StateChangeReason.UNKNOWN, false); |
| 490 } else { | 366 } else { |
| 491 requestReaderPanelShow(StateChangeReason.UNKNOWN); | 367 tryShowingInfoBar(); |
| 492 } | 368 } |
| 493 } | 369 } |
| 494 | 370 |
| 495 @Override | 371 @Override |
| 496 public void navigationEntryCommitted() { | 372 public void navigationEntryCommitted() { |
| 497 // Make sure the tab was not destroyed. | 373 // Make sure the tab was not destroyed. |
| 498 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); | 374 ReaderModeTabInfo tabInfo = mTabStatusMap.get(readerTabId); |
| 499 if (tabInfo == null) return; | 375 if (tabInfo == null) return; |
| 500 // Reset closed state of reader mode in this tab once we know a navigation is | 376 // Reset closed state of reader mode in this tab once we know a navigation is |
| 501 // happening. | 377 // happening. |
| 502 tabInfo.setIsDismissed(false); | 378 tabInfo.setIsDismissed(false); |
| 503 | 379 |
| 504 // If the panel was not shown for the previous navigation, recor d it now. | 380 // If the panel was not shown for the previous navigation, recor d it now. |
| 505 Tab curTab = mTabModelSelector.getTabById(readerTabId); | 381 Tab curTab = mTabModelSelector.getTabById(readerTabId); |
| 506 if (curTab != null && !curTab.isNativePage() && !curTab.isBeingR estored()) { | 382 if (curTab != null && !curTab.isNativePage() && !curTab.isBeingR estored()) { |
| 507 recordPanelVisibilityForNavigation(false); | 383 recordPanelVisibilityForNavigation(false); |
| 508 } | 384 } |
| 509 tabInfo.setIsPanelShowRecorded(false); | 385 tabInfo.setIsPanelShowRecorded(false); |
| 386 | |
| 387 if (!DomDistillerUrlUtils.isDistilledPage(curTab.getUrl()) | |
| 388 && tabInfo.isViewingReaderModePage()) { | |
| 389 long timeMs = tabInfo.onExitReaderMode(); | |
| 390 recordReaderModeViewDuration(timeMs); | |
| 391 } | |
| 510 } | 392 } |
| 511 }; | 393 }; |
| 512 } | 394 } |
| 513 | 395 |
| 514 /** | 396 /** |
| 515 * This is a wrapper for "requestPanelShow" that checks if reader mode is po ssible before | 397 * Record the amount of time the user spent in Reader Mode. |
| 516 * showing. | 398 * @param timeMs The amount of time in ms that the user spent in Reader Mode . |
| 517 * @param reason The reason the panel is requesting to be shown. | |
| 518 */ | 399 */ |
| 519 protected void requestReaderPanelShow(StateChangeReason reason) { | 400 private void recordReaderModeViewDuration(long timeMs) { |
| 401 RecordHistogram.recordLongTimesHistogram( | |
| 402 "DomDistiller.Time.ViewingReaderModePage", timeMs, TimeUnit.MILL ISECONDS); | |
| 403 } | |
| 404 | |
| 405 /** | |
| 406 * Try showing the reader mode infobar. | |
| 407 */ | |
| 408 protected void tryShowingInfoBar() { | |
| 520 if (mTabModelSelector == null) return; | 409 if (mTabModelSelector == null) return; |
| 521 | 410 |
| 522 int currentTabId = mTabModelSelector.getCurrentTabId(); | 411 int currentTabId = mTabModelSelector.getCurrentTabId(); |
| 523 if (currentTabId == Tab.INVALID_TAB_ID) return; | 412 if (currentTabId == Tab.INVALID_TAB_ID) return; |
| 524 | 413 |
| 525 // Test if the user is requesting the desktop site. Ignore this if disti ller is set to | 414 // Test if the user is requesting the desktop site. Ignore this if disti ller is set to |
| 526 // ALWAYS_TRUE. | 415 // ALWAYS_TRUE. |
| 527 boolean usingRequestDesktopSite = getBasePageWebContents() != null | 416 boolean usingRequestDesktopSite = getBasePageWebContents() != null |
| 528 && getBasePageWebContents().getNavigationController().getUseDesk topUserAgent() | 417 && getBasePageWebContents().getNavigationController().getUseDesk topUserAgent() |
| 529 && !mIsReaderHeuristicAlwaysTrue; | 418 && !mIsReaderHeuristicAlwaysTrue; |
| 530 | 419 |
| 531 if (mReaderModePanel == null || !mTabStatusMap.containsKey(currentTabId) | 420 if (!mTabStatusMap.containsKey(currentTabId) || usingRequestDesktopSite |
| 532 || usingRequestDesktopSite | |
| 533 || mTabStatusMap.get(currentTabId).getStatus() != POSSIBLE | 421 || mTabStatusMap.get(currentTabId).getStatus() != POSSIBLE |
| 534 || mTabStatusMap.get(currentTabId).isDismissed() | 422 || mTabStatusMap.get(currentTabId).isDismissed() |
| 535 || mIsInfoBarContainerShown | |
| 536 || mIsFindToolbarShowing | |
| 537 || mIsFullscreenModeEntered | |
| 538 || mIsKeyboardShowing | |
| 539 || AccessibilityUtil.isAccessibilityEnabled()) { | 423 || AccessibilityUtil.isAccessibilityEnabled()) { |
| 540 return; | 424 return; |
| 541 } | 425 } |
| 542 | 426 |
| 543 mReaderModePanel.requestPanelShow(reason); | 427 ReaderModeInfoBar.showReaderModeInfoBar(mTabModelSelector.getCurrentTab( ), this); |
| 544 } | 428 } |
| 545 | 429 |
| 546 /** | 430 /** |
| 431 * Navigate the current tab to a Reader Mode URL. | |
| 432 */ | |
| 433 public void navigateToReaderMode() { | |
| 434 RecordHistogram.recordBooleanHistogram("DomDistiller.InfoBarUsage", true ); | |
| 435 | |
| 436 WebContents baseWebContents = getBasePageWebContents(); | |
| 437 if (baseWebContents == null || mChromeActivity == null || mTabModelSelec tor == null) return; | |
| 438 | |
| 439 String url = baseWebContents.getUrl(); | |
| 440 if (url == null) return; | |
| 441 | |
| 442 ReaderModeTabInfo info = mTabStatusMap.get(mTabModelSelector.getCurrentT abId()); | |
| 443 if (info != null) info.onStartedReaderMode(); | |
| 444 | |
| 445 DomDistillerTabUtils.distillCurrentPageAndView(getBasePageWebContents()) ; | |
| 446 } | |
| 447 | |
| 448 /** | |
| 547 * Open a link from the panel in a new tab. | 449 * Open a link from the panel in a new tab. |
| 548 * @param url The URL to load. | 450 * @param url The URL to load. |
| 549 */ | 451 */ |
| 550 @Override | 452 @Override |
| 551 public void createNewTab(String url) { | 453 public void createNewTab(String url) { |
| 552 if (mChromeActivity == null) return; | 454 if (mChromeActivity == null) return; |
| 553 | 455 |
| 554 Tab currentTab = mTabModelSelector.getCurrentTab(); | 456 Tab currentTab = mTabModelSelector.getCurrentTab(); |
| 555 if (currentTab == null) return; | 457 if (currentTab == null) return; |
| 556 | 458 |
| 557 TabCreatorManager.TabCreator tabCreator = | 459 TabCreatorManager.TabCreator tabCreator = |
| 558 mChromeActivity.getTabCreator(currentTab.isIncognito()); | 460 mChromeActivity.getTabCreator(currentTab.isIncognito()); |
| 559 if (tabCreator == null) return; | 461 if (tabCreator == null) return; |
| 560 | 462 |
| 561 tabCreator.createNewTab(new LoadUrlParams(url, PageTransition.LINK), | 463 tabCreator.createNewTab(new LoadUrlParams(url, PageTransition.LINK), |
| 562 TabModel.TabLaunchType.FROM_LINK, mChromeActivity.getActivityTab ()); | 464 TabModel.TabLaunchType.FROM_LINK, mChromeActivity.getActivityTab ()); |
| 563 } | 465 } |
| 564 | 466 |
| 565 /** | 467 /** |
| 566 * @return Whether the Reader Mode panel is opened (state is EXPANDED or MAX IMIZED). | |
| 567 */ | |
| 568 public boolean isPanelOpened() { | |
| 569 if (mReaderModePanel == null) return false; | |
| 570 return mReaderModePanel.isPanelOpened(); | |
| 571 } | |
| 572 | |
| 573 /** | |
| 574 * @return The ReaderModePanel for testing. | |
| 575 */ | |
| 576 @VisibleForTesting | |
| 577 public ReaderModePanel getPanelForTesting() { | |
| 578 return mReaderModePanel; | |
| 579 } | |
| 580 | |
| 581 /** | |
| 582 * Set the callback for updating reader mode status based on whether or not the page should | 468 * Set the callback for updating reader mode status based on whether or not the page should |
| 583 * be viewed in reader mode. | 469 * be viewed in reader mode. |
| 584 * @param tabId The ID of the tab having its callback set. | 470 * @param tabId The ID of the tab having its callback set. |
| 585 */ | 471 */ |
| 586 private void setDistillabilityCallback(final int tabId) { | 472 private void setDistillabilityCallback(final int tabId) { |
| 587 if (tabId == Tab.INVALID_TAB_ID || mTabStatusMap.get(tabId).isCallbackSe t()) { | 473 if (tabId == Tab.INVALID_TAB_ID || mTabStatusMap.get(tabId).isCallbackSe t()) { |
| 588 return; | 474 return; |
| 589 } | 475 } |
| 590 | 476 |
| 591 if (mTabModelSelector == null) return; | 477 if (mTabModelSelector == null) return; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 610 // destroyed so that this never happens. | 496 // destroyed so that this never happens. |
| 611 if (readerTab == null || tabInfo == null) return; | 497 if (readerTab == null || tabInfo == null) return; |
| 612 | 498 |
| 613 // Make sure the page didn't navigate while waiting for a response. | 499 // Make sure the page didn't navigate while waiting for a response. |
| 614 if (!readerTab.getUrl().equals(tabInfo.getUrl())) return ; | 500 if (!readerTab.getUrl().equals(tabInfo.getUrl())) return ; |
| 615 | 501 |
| 616 if (isDistillable) { | 502 if (isDistillable) { |
| 617 tabInfo.setStatus(POSSIBLE); | 503 tabInfo.setStatus(POSSIBLE); |
| 618 // The user may have changed tabs. | 504 // The user may have changed tabs. |
| 619 if (tabId == mTabModelSelector.getCurrentTabId()) { | 505 if (tabId == mTabModelSelector.getCurrentTabId()) { |
| 620 // TODO(mdjones): Add reason DISTILLER_STATE_CHA NGE. | 506 tryShowingInfoBar(); |
| 621 requestReaderPanelShow(StateChangeReason.UNKNOWN ); | |
| 622 } | 507 } |
| 623 } else { | 508 } else { |
| 624 tabInfo.setStatus(NOT_POSSIBLE); | 509 tabInfo.setStatus(NOT_POSSIBLE); |
| 625 } | 510 } |
| 626 if (!mIsUmaRecorded && (tabInfo.getStatus() == POSSIBLE || isLast)) { | 511 if (!mIsUmaRecorded && (tabInfo.getStatus() == POSSIBLE || isLast)) { |
| 627 mIsUmaRecorded = true; | 512 mIsUmaRecorded = true; |
| 628 RecordHistogram.recordBooleanHistogram( | 513 RecordHistogram.recordBooleanHistogram( |
| 629 "DomDistiller.PageDistillable", | 514 "DomDistiller.PageDistillable", |
| 630 tabInfo.getStatus() == POSSIBLE); | 515 tabInfo.getStatus() == POSSIBLE); |
| 631 } | 516 } |
| 632 } | 517 } |
| 633 }); | 518 }); |
| 634 mTabStatusMap.get(tabId).setIsCallbackSet(true); | 519 mTabStatusMap.get(tabId).setIsCallbackSet(true); |
| 635 } | 520 } |
| 636 | 521 |
| 637 /** | 522 /** |
| 638 * @return Whether Reader mode and its new UI are enabled. | 523 * @return Whether Reader mode and its new UI are enabled. |
| 639 * @param context A context | 524 * @param context A context |
| 640 */ | 525 */ |
| 641 public static boolean isEnabled(Context context) { | 526 public static boolean isEnabled(Context context) { |
| 642 if (context == null) return false; | 527 if (context == null) return false; |
| 643 | 528 |
| 644 boolean enabled = CommandLine.getInstance().hasSwitch(ChromeSwitches.ENA BLE_DOM_DISTILLER) | 529 boolean enabled = CommandLine.getInstance().hasSwitch(ChromeSwitches.ENA BLE_DOM_DISTILLER) |
| 645 && !CommandLine.getInstance().hasSwitch( | 530 && !CommandLine.getInstance().hasSwitch( |
| 646 ChromeSwitches.DISABLE_READER_MODE_BOTTOM_BAR) | 531 ChromeSwitches.DISABLE_READER_MODE_BOTTOM_BAR) |
| 647 && !DeviceFormFactor.isTablet(context) | 532 && DomDistillerTabUtils.isDistillerHeuristicsEnabled(); |
| 648 && DomDistillerTabUtils.isDistillerHeuristicsEnabled() | |
| 649 && !SysUtils.isLowEndDevice(); | |
| 650 return enabled; | 533 return enabled; |
| 651 } | 534 } |
| 652 } | 535 } |
| OLD | NEW |