| Index: chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
|
| index dc67d57487982bb5856f7b4c23bea943bf651931..4be92b3e1f54925b7d4151d9148c88ccb1a945fa 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
|
| @@ -31,7 +31,9 @@ import org.chromium.chrome.browser.snackbar.Snackbar;
|
| import org.chromium.chrome.browser.snackbar.SnackbarManager;
|
| import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
|
| import org.chromium.chrome.browser.tab.Tab;
|
| +import org.chromium.chrome.browser.tabmodel.TabModel;
|
| import org.chromium.chrome.browser.tabmodel.TabModelSelector;
|
| +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
|
| import org.chromium.components.bookmarks.BookmarkId;
|
| import org.chromium.components.offlinepages.SavePageResult;
|
| import org.chromium.content_public.browser.LoadUrlParams;
|
| @@ -45,8 +47,11 @@ import java.io.FileInputStream;
|
| import java.io.FileOutputStream;
|
| import java.io.IOException;
|
| import java.nio.channels.FileChannel;
|
| +import java.util.ArrayList;
|
| import java.util.HashMap;
|
| +import java.util.List;
|
| import java.util.Map;
|
| +import java.util.WeakHashMap;
|
| import java.util.concurrent.TimeUnit;
|
|
|
| /**
|
| @@ -703,6 +708,73 @@ public class OfflinePageUtils {
|
| return ConnectionType.CONNECTION_UNKNOWN;
|
| }
|
|
|
| + /**
|
| + * Tracks tab creation and closure for the Recent Tabs feature. UI needs to stop showing
|
| + * recent offline pages as soon as the tab is closed. The TabModel is used to get profile
|
| + * information because Tab's profile is tied to the native WebContents, which may not exist at
|
| + * tab adding or tab closing time.
|
| + */
|
| + private static class RecentTabTracker extends TabModelSelectorTabModelObserver {
|
| + private TabModelSelector mTabModelSelector;
|
| +
|
| + public RecentTabTracker(TabModelSelector selector) {
|
| + super(selector);
|
| + mTabModelSelector = selector;
|
| + }
|
| +
|
| + @Override
|
| + public void didAddTab(Tab tab, TabModel.TabLaunchType type) {
|
| + Profile profile = mTabModelSelector.getModel(tab.isIncognito()).getProfile();
|
| + OfflinePageBridge bridge = OfflinePageBridge.getForProfile(profile);
|
| + if (bridge == null) return;
|
| + bridge.registerRecentTab(tab.getId());
|
| + }
|
| +
|
| + @Override
|
| + public void didCloseTab(int tabId, boolean incognito) {
|
| + Profile profile = mTabModelSelector.getModel(incognito).getProfile();
|
| + OfflinePageBridge bridge = OfflinePageBridge.getForProfile(profile);
|
| + if (bridge == null) return;
|
| +
|
| + // First, unregister the tab with the UI.
|
| + bridge.unregisterRecentTab(tabId);
|
| +
|
| + // Then, delete any "Last N" offline pages as well. This is an optimization because
|
| + // the UI will no longer show the page, and the page would also be cleaned up by GC
|
| + // given enough time.
|
| + ClientId clientId =
|
| + new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tabId));
|
| + List<ClientId> clientIds = new ArrayList<>();
|
| + clientIds.add(clientId);
|
| +
|
| + bridge.deletePagesByClientId(clientIds, new Callback<Integer>() {
|
| + @Override
|
| + public void onResult(Integer result) {
|
| + // Result is ignored.
|
| + }
|
| + });
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Tracks the observers of ChromeActivity's TabModelSelectors. This is weak so the activity can
|
| + * be garbage collected without worrying about this map. The RecentTabTracker is held here so
|
| + * that it can be destroyed when the ChromeActivity gets a new TabModelSelector.
|
| + */
|
| + private static WeakHashMap<ChromeActivity, RecentTabTracker> sTabModelObservers =
|
| + new WeakHashMap<>();
|
| +
|
| + /**
|
| + * Starts tracking the tab models in the given selector for tab addition and closure,
|
| + * destroying obsolete observers as necessary.
|
| + */
|
| + public static void observeTabModelSelector(
|
| + ChromeActivity activity, TabModelSelector tabModelSelector) {
|
| + RecentTabTracker previousObserver =
|
| + sTabModelObservers.put(activity, new RecentTabTracker(tabModelSelector));
|
| + if (previousObserver != null) previousObserver.destroy();
|
| + }
|
| +
|
| @VisibleForTesting
|
| static void setInstanceForTesting(OfflinePageUtils instance) {
|
| sInstance = instance;
|
|
|