Commit b79781bc authored by twellington's avatar twellington Committed by Commit bot

Migrate TabPersistentStore to one shared directory for multi-instance

Rather than using a sub-directory per ChromeTabbedActivity instance,
use one shared director for all instances.

BUG=622143

Review-Url: https://codereview.chromium.org/2087893003
Cr-Commit-Position: refs/heads/master@{#403229}
parent 76388ee0
......@@ -321,10 +321,8 @@ public class TabContentManager {
// BUG: We support multiple tab model selectors, and they all share the same thumbnail
// directory. This cleanup code checks only the current model selector to see if the
// thumbnails are no longer used. It should instead:
// a) consult with *all* tab model selectors (which may not even be in memory)
// b) use separate thumbnail directories for each tab model (perhaps using hardlink to
// eliminate disk overhead)
// thumbnails are no longer used. It should instead consult with *all* tab model selectors
// (which may not even be in memory).
new AsyncTask<Void, Void, String[]>() {
@Override
protected String[] doInBackground(Void... voids) {
......
......@@ -34,7 +34,6 @@ import org.chromium.chrome.browser.util.FeatureUtilities;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
......@@ -82,13 +81,10 @@ public class IncognitoNotificationService extends IntentService {
}
});
} else {
List<Integer> processedSelectors = closeIncognitoTabsInRunningTabbedActivities();
closeIncognitoTabsInRunningTabbedActivities();
for (int i = 0; i < TabWindowManager.MAX_SIMULTANEOUS_SELECTORS; i++) {
if (processedSelectors.contains(i)) continue;
clearedIncognito &= deleteIncognitoStateFilesInDirectory(
TabPersistentStore.getOrCreateSelectorStateDirectory(i));
}
clearedIncognito = deleteIncognitoStateFilesInDirectory(
TabPersistentStore.getOrCreateStateDirectory());
}
// If we failed clearing all of the incognito tabs, then do not dismiss the notification.
......@@ -193,36 +189,27 @@ public class IncognitoNotificationService extends IntentService {
* Iterate across the running activities and for any running tabbed mode activities close their
* incognito tabs.
*
* @return The list of window indexes that were processed.
*
* @see TabWindowManager#getIndexForWindow(Activity)
*/
private List<Integer> closeIncognitoTabsInRunningTabbedActivities() {
return ThreadUtils.runOnUiThreadBlockingNoException(
new Callable<List<Integer>>() {
@Override
public List<Integer> call() {
List<Integer> selectorIndexes = new ArrayList<>();
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (!(activity instanceof ChromeTabbedActivity)) continue;
ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity;
if (tabbedActivity.isActivityDestroyed()) continue;
tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs(
false, false);
selectorIndexes.add(TabWindowManager.getInstance().getIndexForWindow(
tabbedActivity));
}
return selectorIndexes;
}
});
private void closeIncognitoTabsInRunningTabbedActivities() {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
List<WeakReference<Activity>> runningActivities =
ApplicationStatus.getRunningActivities();
for (int i = 0; i < runningActivities.size(); i++) {
Activity activity = runningActivities.get(i).get();
if (activity == null) continue;
if (!(activity instanceof ChromeTabbedActivity)) continue;
ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity) activity;
if (tabbedActivity.isActivityDestroyed()) continue;
tabbedActivity.getTabModelSelector().getModel(true).closeAllTabs(
false, false);
}
}
});
}
/**
......
......@@ -342,8 +342,8 @@ public class DocumentModeAssassin {
@Override
protected Boolean doInBackground(Void... params) {
if (mSerializedMetadata != null) {
File tabbedDirectory = getTabbedDataDirectory();
TabPersistentStore.saveListToFile(tabbedDirectory, mSerializedMetadata);
TabPersistentStore.saveListToFile(
getTabbedDataDirectory(), TAB_MODEL_INDEX, mSerializedMetadata);
return true;
} else {
return false;
......@@ -543,9 +543,9 @@ public class DocumentModeAssassin {
return new StorageDelegate().getStateDirectory();
}
/** @return Where tabbed mode data is stored for the main {@link TabModelImpl}. */
/** @return Where tabbed mode data is stored. */
protected File getTabbedDataDirectory() {
return TabPersistentStore.getOrCreateSelectorStateDirectory(TAB_MODEL_INDEX);
return TabPersistentStore.getOrCreateStateDirectory();
}
/** @return True if the user is not in document mode. */
......
......@@ -31,7 +31,6 @@ public class TabWindowManager implements ActivityStateListener {
public static final int INVALID_WINDOW_INDEX = -1;
/** The maximum number of simultaneous TabModelSelector instances in this Application. */
@VisibleForTesting
public static final int MAX_SIMULTANEOUS_SELECTORS = 3;
/**
......
......@@ -1214,6 +1214,7 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreatorTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/ContextMenuLoadUrlParamsTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassinTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/MultiInstanceMigrationTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/OffTheRecordTabModelTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java",
"javatests/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorTabObserverTest.java",
......
......@@ -107,7 +107,7 @@ public class IncognitoNotificationServiceTest extends ChromeTabbedActivityTestBa
public void testNoAliveProcess() throws Exception {
Context context = getInstrumentation().getTargetContext();
final TestTabModelDirectory tabbedModeDirectory = new TestTabModelDirectory(
context, "tabs", String.valueOf(1));
context, "tabs", String.valueOf(0));
// Add a couple non-incognito tabs (their filenames use a different prefix, so we do not
// need to worry about ID space collisions with the generated incognito tabs).
......
......@@ -14,6 +14,7 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.util.AdvancedMockContext;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.TabState;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabIdManager;
......@@ -41,10 +42,10 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
return TabPersistentStore.serializeTabModelSelector(selector, null);
}
});
File f = TabPersistentStore.getOrCreateSelectorStateDirectory(index);
File f = TabPersistentStore.getOrCreateStateDirectory();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(f, TabPersistentStore.SAVED_STATE_FILE));
fos = new FileOutputStream(new File(f, TabPersistentStore.getStateFileName(index)));
fos.write(data);
} finally {
StreamUtil.closeQuietly(fos);
......@@ -78,6 +79,7 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
@SuppressWarnings("unused")
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
@SmallTest
@Feature({"TabPersistentStore"})
public void testMigrateData() throws IOException, InterruptedException, ExecutionException {
ApplicationData.clearAppData(mAppContext);
......@@ -105,8 +107,8 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
TabPersistentStore.PREF_HAS_RUN_FILE_MIGRATION, false));
// Check that the files were moved.
File newDir = TabPersistentStore.getOrCreateSelectorStateDirectory(0);
File newStateFile = new File(newDir, TabPersistentStore.SAVED_STATE_FILE);
File newDir = TabPersistentStore.getOrCreateStateDirectory();
File newStateFile = new File(newDir, TabPersistentStore.getStateFileName(0));
File newTab0 = new File(newDir, TabState.SAVED_TAB_STATE_FILE_PREFIX + "0");
File newTab1 = new File(newDir, TabState.SAVED_TAB_STATE_FILE_PREFIX + "1");
File newTab2 = new File(newDir, TabState.SAVED_TAB_STATE_FILE_PREFIX_INCOGNITO + "2");
......@@ -136,6 +138,7 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
@SuppressWarnings("unused")
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
@SmallTest
@Feature({"TabPersistentStore"})
public void testSkipMigrateData() throws IOException, InterruptedException, ExecutionException {
ApplicationData.clearAppData(mAppContext);
......@@ -154,8 +157,8 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
assertTrue("Could not create tab 3 file", tab3.createNewFile());
// Write new state files
File newDir = TabPersistentStore.getOrCreateSelectorStateDirectory(0);
File newStateFile = new File(newDir, TabPersistentStore.SAVED_STATE_FILE);
File newDir = TabPersistentStore.getOrCreateStateDirectory();
File newStateFile = new File(newDir, TabPersistentStore.getStateFileName(0));
File newTab4 = new File(newDir, TabState.SAVED_TAB_STATE_FILE_PREFIX + "4");
assertTrue("Could not create new tab 4 file", newTab4.createNewFile());
......@@ -192,6 +195,7 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
@SuppressWarnings("unused")
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
@SmallTest
@Feature({"TabPersistentStore"})
public void testMigrationLeavesOtherFilesAlone() throws IOException, InterruptedException,
ExecutionException {
ApplicationData.clearAppData(mAppContext);
......@@ -216,8 +220,8 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
assertTrue("Could not find other file", otherFile.exists());
// Check that the files were moved.
File newDir = TabPersistentStore.getOrCreateSelectorStateDirectory(0);
File newStateFile = new File(newDir, TabPersistentStore.SAVED_STATE_FILE);
File newDir = TabPersistentStore.getOrCreateStateDirectory();
File newStateFile = new File(newDir, TabPersistentStore.getStateFileName(0));
File newTab0 = new File(newDir, TabState.SAVED_TAB_STATE_FILE_PREFIX + "0");
File newOtherFile = new File(newDir, "other.file");
......@@ -233,6 +237,7 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
* @throws IOException
*/
@SmallTest
@Feature({"TabPersistentStore"})
public void testFindsMaxIdProperly() throws IOException {
TabModelSelector selector0 = new MockTabModelSelector(1, 1, null);
TabModelSelector selector1 = new MockTabModelSelector(1, 1, null);
......@@ -258,6 +263,7 @@ public class RestoreMigrateTest extends InstrumentationTestCase {
* @throws IOException
*/
@SmallTest
@Feature({"TabPersistentStore"})
public void testOnlyLoadsSingleModel() throws IOException {
TabModelSelector selector0 = new MockTabModelSelector(3, 3, null);
TabModelSelector selector1 = new MockTabModelSelector(2, 1, null);
......
......@@ -13,6 +13,7 @@ import android.util.SparseArray;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.AdvancedMockContext;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.TabState;
import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper;
import org.chromium.chrome.browser.snackbar.undo.UndoBarController;
......@@ -255,6 +256,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
}
@SmallTest
@Feature({"TabPersistentStore"})
public void testBasic() throws Exception {
TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4;
int numExpectedTabs = info.contents.length;
......@@ -302,6 +304,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
}
@SmallTest
@Feature({"TabPersistentStore"})
public void testInterruptedButStillRestoresAllTabs() throws Exception {
TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4;
int numExpectedTabs = info.contents.length;
......@@ -375,6 +378,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
}
@SmallTest
@Feature({"TabPersistentStore"})
public void testMissingTabStateButStillRestoresTab() throws Exception {
TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5;
int numExpectedTabs = info.contents.length;
......@@ -417,6 +421,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
}
@SmallTest
@Feature({"TabPersistentStore"})
public void testRestoresTabWithMissingTabStateWhileIgnoringIncognitoTab() throws Exception {
TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_WITH_INCOGNITO;
int numExpectedTabs = info.contents.length;
......@@ -452,6 +457,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
}
@SmallTest
@Feature({"TabPersistentStore"})
public void testPrefetchActiveTab() throws Exception {
final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_NO_M18;
mMockDirectory.writeTabModelFiles(info, true);
......@@ -493,6 +499,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
* an updated metadata file when a closure is undone.
*/
@SmallTest
@Feature({"TabPersistentStore"})
public void testUndoSingleTabClosureWritesTabListFile() throws Exception {
TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_NO_M18;
mMockDirectory.writeTabModelFiles(info, true);
......@@ -519,6 +526,7 @@ public class TabPersistentStoreTest extends NativeLibraryTestBase {
* canceling the closure of all the tabs simultaneously.
*/
@SmallTest
@Feature({"TabPersistentStore"})
public void testUndoCloseAllTabsWritesTabListFile() throws Exception {
final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_NO_M18;
mMockDirectory.writeTabModelFiles(info, true);
......
......@@ -344,7 +344,7 @@ public class TestTabModelDirectory {
*/
public void writeTabModelFiles(TabModelMetaDataInfo info, boolean writeTabStates)
throws Exception {
writeFile(mDataDirectory, "tab_state", info.encodedFile);
writeFile(mDataDirectory, "tab_state0", info.encodedFile);
for (TabStateInfo tabStateInfo : info.contents) {
writeTabStateFile(tabStateInfo);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment