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