Index: chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java |
index 89936ef92c474a4c2dc7034bfa1a1e3357aaa8f5..bc7e0ba87ae07ecacd6b4bc71c6484a21e50d01f 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java |
@@ -12,6 +12,7 @@ import android.os.Build; |
import android.util.Pair; |
import org.chromium.base.ApplicationStatus; |
+import org.chromium.base.CommandLine; |
import org.chromium.base.FileUtils; |
import org.chromium.base.Log; |
import org.chromium.base.ObserverList; |
@@ -19,6 +20,7 @@ import org.chromium.base.StreamUtil; |
import org.chromium.base.ThreadUtils; |
import org.chromium.base.VisibleForTesting; |
import org.chromium.chrome.browser.ChromeApplication; |
+import org.chromium.chrome.browser.ChromeSwitches; |
import org.chromium.chrome.browser.TabState; |
import org.chromium.chrome.browser.document.DocumentActivity; |
import org.chromium.chrome.browser.document.DocumentUtils; |
@@ -42,6 +44,8 @@ import java.nio.channels.FileChannel; |
import java.util.HashSet; |
import java.util.Set; |
+import javax.annotation.Nullable; |
+ |
/** |
* Divorces Chrome's tabs from Android's Overview menu. Assumes native libraries are unavailable. |
* |
@@ -52,7 +56,6 @@ import java.util.Set; |
* into the tabbed mode directory. Incognito tabs are silently dropped, as with the previous |
* migration pathway. |
* |
- * TODO(dfalcantara): Check what happens if a user last viewed an Incognito tab. |
* TODO(dfalcantara): Check what happens on other launchers. |
* |
* Once all TabState files are copied, a TabModel metadata file is written out for the tabbed |
@@ -64,7 +67,6 @@ import java.util.Set; |
* DocumentActivity tasks in Android's Recents are removed, TabState files in the document mode |
* directory are deleted, and document mode preferences are cleared. |
* |
- * TODO(dfalcantara): Clean up the incognito notification, if possible. |
* TODO(dfalcantara): Add histograms for tracking migration progress. |
* |
* TODO(dfalcantara): Potential pitfalls that need to be accounted for: |
@@ -105,7 +107,7 @@ public class DocumentModeAssassin { |
static final int STAGE_CHANGE_SETTINGS_STARTED = 6; |
static final int STAGE_CHANGE_SETTINGS_DONE = 7; |
static final int STAGE_DELETION_STARTED = 8; |
- static final int STAGE_DONE = 9; |
+ public static final int STAGE_DONE = 9; |
private static final String TAG = "DocumentModeAssassin"; |
@@ -137,7 +139,8 @@ public class DocumentModeAssassin { |
/** Returns whether or not a migration to tabbed mode from document mode is necessary. */ |
public static boolean isMigrationNecessary() { |
- return FeatureUtilities.isDocumentMode(ApplicationStatus.getApplicationContext()); |
+ return CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_FORCED_MIGRATION) |
+ && FeatureUtilities.isDocumentMode(ApplicationStatus.getApplicationContext()); |
} |
/** Migrates the user from document mode to tabbed mode if necessary. */ |
@@ -165,18 +168,39 @@ public class DocumentModeAssassin { |
* |
* TODO(dfalcantara): Prevent migrating chrome:// pages? |
* |
- * @param selectedTabId ID of the last viewed non-Incognito tab. |
- * @param documentDirectory File pointing at the DocumentTabModel TabState file directory. |
- * @param tabbedDirectory File pointing at tabbed mode TabState file directory. |
+ * @param selectedTabId ID of the last viewed non-Incognito tab. |
+ * @param context Context to use when accessing directories. |
+ * @param documentDirectoryOverride Overrides the default location for where document mode's |
+ * TabState files are expected to be. |
+ * @param tabbedDirectoryOverride Overrides the default location for where tabbed mode's |
+ * TabState files are expected to be. |
*/ |
- void copyTabStateFiles( |
- final int selectedTabId, final File documentDirectory, final File tabbedDirectory) { |
+ void copyTabStateFiles(final int selectedTabId, final Context context, |
+ @Nullable final File documentDirectoryOverride, |
+ @Nullable final File tabbedDirectoryOverride) { |
ThreadUtils.assertOnUiThread(); |
if (!setStage(STAGE_INITIALIZED, STAGE_COPY_TAB_STATES_STARTED)) return; |
new AsyncTask<Void, Void, Void>() { |
+ private DocumentTabModelImpl mNormalTabModel; |
+ |
+ @Override |
+ protected void onPreExecute() { |
+ if (documentDirectoryOverride == null) { |
+ mNormalTabModel = (DocumentTabModelImpl) |
+ ChromeApplication.getDocumentTabModelSelector().getModel(false); |
+ } |
+ } |
+ |
@Override |
protected Void doInBackground(Void... params) { |
+ File documentDirectory = documentDirectoryOverride == null |
+ ? mNormalTabModel.getStorageDelegate().getStateDirectory() |
+ : documentDirectoryOverride; |
+ File tabbedDirectory = tabbedDirectoryOverride == null |
+ ? TabPersistentStore.getStateDirectory(context, TAB_MODEL_INDEX) |
+ : tabbedDirectoryOverride; |
+ |
Log.d(TAG, "Copying TabState files from document to tabbed mode directory."); |
assert mMigratedTabIds.size() == 0; |
@@ -186,11 +210,12 @@ public class DocumentModeAssassin { |
// before all the other ones to mitigate storage issues for devices with limited |
// available storage. |
if (selectedTabId != Tab.INVALID_TAB_ID) { |
- copyTabStateFilesInternal(allTabStates, selectedTabId, true); |
+ copyTabStateFilesInternal( |
+ allTabStates, tabbedDirectory, selectedTabId, true); |
} |
// Copy over everything else. |
- copyTabStateFilesInternal(allTabStates, selectedTabId, false); |
+ copyTabStateFilesInternal(allTabStates, tabbedDirectory, selectedTabId, false); |
} |
return null; |
} |
@@ -205,12 +230,13 @@ public class DocumentModeAssassin { |
* Copies the files from the document mode directory to the tabbed mode directory. |
* |
* @param allTabStates Listing of all files in the document mode directory. |
+ * @param tabbedDirectory Directory for the tabbed mode files. |
* @param selectedTabId ID of the non-Incognito tab the user last viewed. May be |
* {@link Tab#INVALID_TAB_ID} if the ID is unknown. |
* @param copyOnlySelectedTab Copy only the TabState file for the selectedTabId. |
*/ |
- private void copyTabStateFilesInternal( |
- File[] allTabStates, int selectedTabId, boolean copyOnlySelectedTab) { |
+ private void copyTabStateFilesInternal(File[] allTabStates, File tabbedDirectory, |
+ int selectedTabId, boolean copyOnlySelectedTab) { |
assert !ThreadUtils.runningOnUiThread(); |
for (int i = 0; i < allTabStates.length; i++) { |
// Trawl the directory for non-Incognito TabState files. |
@@ -281,12 +307,15 @@ public class DocumentModeAssassin { |
* means that the user loses some navigation history, but it's not a case document mode would |
* have been able to recover from anyway because the TabState stores the URL data. |
* |
- * @param tabbedDirectory Directory containing all of the main TabModel's files. |
- * @param normalTabModel DocumentTabModel containing information about non-Incognito tabs. |
- * @param migratedTabIds IDs of Tabs whose TabState files were copied successfully. |
+ * @param normalTabModel DocumentTabModel containing info about non-Incognito tabs. |
+ * @param migratedTabIds IDs of Tabs whose TabState files were copied successfully. |
+ * @param context Context to access Files from. |
+ * @param tabbedDirectoryOverride Overrides the default location for where tabbed mode's |
+ * TabState files are expected to be. |
*/ |
- void writeTabModelMetadata(final File tabbedDirectory, final DocumentTabModel normalTabModel, |
- final Set<Integer> migratedTabIds) { |
+ void writeTabModelMetadata(final DocumentTabModel normalTabModel, |
+ final Set<Integer> migratedTabIds, final Context context, |
+ @Nullable final File tabbedDirectoryOverride) { |
ThreadUtils.assertOnUiThread(); |
if (!setStage(STAGE_COPY_TAB_STATES_DONE, STAGE_WRITE_TABMODEL_METADATA_STARTED)) return; |
@@ -329,6 +358,9 @@ public class DocumentModeAssassin { |
@Override |
protected Boolean doInBackground(Void... params) { |
if (mSerializedMetadata != null) { |
+ File tabbedDirectory = tabbedDirectoryOverride == null |
+ ? TabPersistentStore.getStateDirectory(context, TAB_MODEL_INDEX) |
+ : tabbedDirectoryOverride; |
TabPersistentStore.saveListToFile(tabbedDirectory, mSerializedMetadata); |
return true; |
} else { |
@@ -440,22 +472,14 @@ public class DocumentModeAssassin { |
Context context = ApplicationStatus.getApplicationContext(); |
if (newStage == STAGE_INITIALIZED) { |
Log.d(TAG, "Migrating user into tabbed mode."); |
- DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); |
- DocumentTabModelImpl normalTabModel = |
- (DocumentTabModelImpl) selector.getModel(false); |
int selectedTabId = DocumentUtils.getLastShownTabIdFromPrefs(context, false); |
- |
- File documentDirectory = normalTabModel.getStorageDelegate().getStateDirectory(); |
- File tabbedDirectory = TabPersistentStore.getStateDirectory(context, TAB_MODEL_INDEX); |
- copyTabStateFiles(selectedTabId, documentDirectory, tabbedDirectory); |
+ copyTabStateFiles(selectedTabId, context, null, null); |
} else if (newStage == STAGE_COPY_TAB_STATES_DONE) { |
Log.d(TAG, "Writing tabbed mode metadata file."); |
DocumentTabModelSelector selector = ChromeApplication.getDocumentTabModelSelector(); |
DocumentTabModelImpl normalTabModel = |
(DocumentTabModelImpl) selector.getModel(false); |
- File tabbedDirectory = |
- TabPersistentStore.getStateDirectory(context, TAB_MODEL_INDEX); |
- writeTabModelMetadata(tabbedDirectory, normalTabModel, mMigratedTabIds); |
+ writeTabModelMetadata(normalTabModel, mMigratedTabIds, context, null); |
} else if (newStage == STAGE_WRITE_TABMODEL_METADATA_DONE) { |
Log.d(TAG, "Changing user preference."); |
changePreferences(context); |
@@ -471,6 +495,7 @@ public class DocumentModeAssassin { |
*/ |
@VisibleForTesting |
public int getStage() { |
+ ThreadUtils.assertOnUiThread(); |
return mStage; |
} |