Chromium Code Reviews| 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 = |
|
Ted C
2017/02/22 23:28:04
I think you can get rid of the weakhashmap (and ma
carlosk
2017/02/23 03:46:47
Looking at the related code it seems that TabWindo
|
| + sTabModelObservers.put(activity, new RecentTabTracker(tabModelSelector)); |
| + if (previousObserver != null) previousObserver.destroy(); |
| + } |
| + |
| @VisibleForTesting |
| static void setInstanceForTesting(OfflinePageUtils instance) { |
| sInstance = instance; |