Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3206)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java

Issue 2166123002: Ignore tabs with duplicate IDs when merging tab models on cold start (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
index d1580ebcf596375d8fe2de0b16a49cac98baefa1..26773da290187f0b147c18198efa7e5d14491b42 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -44,7 +44,9 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -191,6 +193,7 @@ public class TabPersistentStore extends TabPersister {
private final Deque<Tab> mTabsToSave;
private final Deque<TabRestoreDetails> mTabsToRestore;
+ private final Set<Integer> mTabIdsToRestore;
private LoadTabTask mLoadTabTask;
private SaveTabTask mSaveTabTask;
@@ -207,9 +210,12 @@ public class TabPersistentStore extends TabPersister {
private SharedPreferences mPreferences;
private AsyncTask<Void, Void, DataInputStream> mPrefetchTabListTask;
private AsyncTask<Void, Void, DataInputStream> mPrefetchTabListToMergeTask;
+ private byte[] mLastSavedMetadata;
+
+ // Tracks whether this TabPersistentStore's tabs are being loaded.
private boolean mLoadInProgress;
+ // Tracks whether another TabPersistentStore's tabs are being merged into this instance.
private boolean mMergeInProgress;
- private byte[] mLastSavedMetadata;
@VisibleForTesting
AsyncTask<Void, Void, TabState> mPrefetchActiveTabTask;
@@ -233,6 +239,7 @@ public class TabPersistentStore extends TabPersister {
mTabCreatorManager = tabCreatorManager;
mTabsToSave = new ArrayDeque<Tab>();
mTabsToRestore = new ArrayDeque<TabRestoreDetails>();
+ mTabIdsToRestore = new HashSet<Integer>();
mSelectorIndex = selectorIndex;
mOtherSelectorIndex = selectorIndex == 0 ? 1 : 0;
mObserver = observer;
@@ -379,6 +386,11 @@ public class TabPersistentStore extends TabPersister {
/**
* Restore saved state. Must be called before any tabs are added to the list.
+ *
+ * This will read the metadata file for the current TabPersistentStore and the metadata file
+ * from another TabPersistentStore if applicable. When restoreTabs() is called, tabs from both
+ * will be restored into this instance.
+ *
* @param ignoreIncognitoFiles Whether to skip loading incognito tabs.
*/
public void loadState(boolean ignoreIncognitoFiles) {
@@ -441,12 +453,13 @@ public class TabPersistentStore extends TabPersister {
/**
* Merge the tabs of the other Chrome instance into this instance by reading its tab metadata
* file and tab state files.
+ *
+ * This method should be called after a change in activity state indicates that a merge is
+ * necessary. #loadState() will take care of merging states on application cold start if needed.
+ *
+ * If there is currently a merge or load in progress then this method will return early.
*/
public void mergeState() {
- // TODO(twellington): Handle cases where merging is interrupted. Currently if a merge is
- // in progress and the activity is destroyed the tab state may continue duplicate tabs
- // on the next cold start.
-
// TODO(twellington): Add UMA metrics to determine merging performance.
if (mLoadInProgress || mMergeInProgress || !mTabsToRestore.isEmpty()) {
@@ -900,6 +913,18 @@ public class TabPersistentStore extends TabPersister {
@Override
public void onDetailsRead(int index, int id, String url, Boolean isIncognito,
boolean isStandardActiveIndex, boolean isIncognitoActiveIndex) {
+ if (mLoadInProgress) {
+ // If a load and merge are both in progress, that means two metadata files
+ // are being read. If a merge was previously started and interrupted due to the
+ // app dying, the two metadata files may contain duplicate IDs. Skip tabs with
+ // duplicate IDs.
+ if (mMergeInProgress && mTabIdsToRestore.contains(id)) {
+ return;
+ }
+
+ mTabIdsToRestore.add(id);
+ }
+
// Note that incognito tab may not load properly so we may need to use
// the current tab from the standard model.
// This logic only works because we store the incognito indices first.
@@ -1103,7 +1128,6 @@ public class TabPersistentStore extends TabPersister {
saveTabListAsynchronously();
deleteFileAsync(getStateFileName(mOtherSelectorIndex));
if (mObserver != null) mObserver.onStateMerged();
- mMergeInProgress = false;
}
// Only clean up persistent data on application cold start.
@@ -1156,6 +1180,12 @@ public class TabPersistentStore extends TabPersister {
File stateFile = new File(getStateDirectory(), file);
if (stateFile.exists()) {
if (!stateFile.delete()) Log.e(TAG, "Failed to delete file: " + stateFile);
+
+ // The merge isn't completely finished until the other TabPersistentStore's
+ // metadata file is deleted.
+ if (file.equals(getStateFileName(mOtherSelectorIndex))) {
+ mMergeInProgress = false;
+ }
}
return null;
}
« no previous file with comments | « no previous file | chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698