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 276725d068340820805511894a605628187923b9..f7e4408ca003b74eb4a81b741f86025705e4c64c 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 |
@@ -26,7 +26,6 @@ import java.io.DataInputStream; |
import java.io.DataOutputStream; |
import java.io.File; |
import java.io.FileInputStream; |
-import java.io.FileOutputStream; |
import java.io.IOException; |
import java.util.ArrayDeque; |
import java.util.Deque; |
@@ -35,7 +34,7 @@ import java.util.concurrent.ExecutionException; |
/** |
* This class handles saving and loading tab state from the persistent storage. |
*/ |
-public class TabPersistentStore { |
+public class TabPersistentStore extends TabPersister { |
private static final String TAG = "TabPersistentStore"; |
/** The current version of the saved state file. */ |
@@ -51,18 +50,19 @@ public class TabPersistentStore { |
private static final Object MIGRATION_LOCK = new Object(); |
/** |
- * Callback interface to use while reading the saved state file from disk. |
+ * Callback interface to use while reading the persisted TabModelSelector info from disk. |
*/ |
public static interface OnTabStateReadCallback { |
/** |
- * To be called as the state for each tab is read from disk. |
+ * To be called as the details about a persisted Tab are read from the TabModelSelector's |
+ * persisted data. |
* @param index The index out of all tabs for the current tab read. |
* @param id The id for the current tab read. |
* @param url The url for the current tab read. |
* @param isStandardActiveIndex Whether the current tab read is the normal active tab. |
* @param isIncognitoActiveIndex Whether the current tab read is the incognito active tab. |
*/ |
- void onStateRead(int index, int id, String url, |
+ void onDetailsRead(int index, int id, String url, |
boolean isStandardActiveIndex, boolean isIncognitoActiveIndex); |
} |
@@ -141,18 +141,21 @@ public class TabPersistentStore { |
} |
} |
+ @Override |
+ public File getStateDirectory() { |
+ return getStateDirectory(mContext, mSelectorIndex); |
+ } |
+ |
/** |
* The folder where the state should be saved to. |
* @param context A Context instance. |
* @param index The TabModelSelector index. |
* @return A file representing the directory that contains the TabModelSelector state. |
*/ |
- public static File getStateFolder(Context context, int index) { |
+ public static File getStateDirectory(Context context, int index) { |
File file = new File(context.getDir(BASE_STATE_FOLDER, Context.MODE_PRIVATE), |
Integer.toString(index)); |
- if (!file.mkdirs()) { |
- Log.e(TAG, "Failed to create state folder: " + file); |
- } |
+ if (!file.exists() && !file.mkdirs()) Log.e(TAG, "Failed to create state folder: " + file); |
return file; |
} |
@@ -223,7 +226,7 @@ public class TabPersistentStore { |
logSaveException(e); |
} catch (OutOfMemoryError e) { |
Log.w(TAG, "Out of memory error while attempting to save tab state. Erasing."); |
- deleteTabStateFile(id, incognito); |
+ deleteTabState(id, incognito); |
} |
} |
mTabsToSave.clear(); |
@@ -332,7 +335,7 @@ public class TabPersistentStore { |
boolean tabRestored = false; |
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); |
try { |
- TabState state = readTabState(tabToRestore.id); |
+ TabState state = TabState.restoreTabState(getStateDirectory(), tabToRestore.id); |
if (state != null) { |
restoreTab(tabToRestore, state, setAsActive); |
@@ -520,8 +523,7 @@ public class TabPersistentStore { |
private void saveListToFile(byte[] listData) { |
synchronized (mSaveListLock) { |
// Save the index file containing the list of tabs to restore. |
- String fileName = new File(getStateFolder(mContext, mSelectorIndex), |
- SAVED_STATE_FILE).getAbsolutePath(); |
+ String fileName = new File(getStateDirectory(), SAVED_STATE_FILE).getAbsolutePath(); |
ImportantFileWriterAndroid.writeFileAtomically(fileName, listData); |
} |
} |
@@ -538,7 +540,7 @@ public class TabPersistentStore { |
assert mTabModelSelector.getModel(false).getCount() == 0; |
int maxId = 0; |
File[] folders = mContext.getDir(BASE_STATE_FOLDER, Context.MODE_PRIVATE).listFiles(); |
- File stateFolder = getStateFolder(mContext, mSelectorIndex); |
+ File stateFolder = getStateDirectory(); |
for (File folder : folders) { |
assert folder.isDirectory(); |
if (!folder.isDirectory()) continue; |
@@ -548,7 +550,7 @@ public class TabPersistentStore { |
int curId = readSavedStateFile(folder, new OnTabStateReadCallback() { |
@Override |
- public void onStateRead(int index, int id, String url, |
+ public void onDetailsRead(int index, int id, String url, |
boolean isStandardActiveIndex, boolean isIncognitoActiveIndex) { |
// If we're not trying to build the restore list skip the build part. |
// We've already read all the state for this entry from the input stream. |
@@ -610,7 +612,7 @@ public class TabPersistentStore { |
String tabUrl = skipUrlRead ? "" : stream.readUTF(); |
if (id >= nextId) nextId = id + 1; |
- callback.onStateRead( |
+ callback.onDetailsRead( |
i, id, tabUrl, i == standardActiveIndex, i == incognitoActiveIndex); |
} |
return nextId; |
@@ -653,16 +655,7 @@ public class TabPersistentStore { |
@Override |
protected Void doInBackground(Void... voids) { |
- if (mState == null) return null; |
- try { |
- TabState.saveState(openTabStateOutputStream(mId, mEncrypted), mState, mEncrypted); |
- mStateSaved = true; |
- } catch (IOException e) { |
- Log.w(TAG, "IO Exception while attempting to save tab state."); |
- } catch (OutOfMemoryError e) { |
- Log.w(TAG, "Out of memory error while attempting to save tab state. Erasing."); |
- deleteTabStateFile(mId, mEncrypted); |
- } |
+ mStateSaved = saveTabState(mId, mEncrypted, mState); |
return null; |
} |
@@ -726,7 +719,7 @@ public class TabPersistentStore { |
} |
private void cleanupPersistentData() { |
- String[] files = getStateFolder(mContext, mSelectorIndex).list(); |
+ String[] files = getStateDirectory().list(); |
for (String file : files) { |
Pair<Integer, Boolean> data = TabState.parseInfoFromFilename(file); |
if (data != null) { |
@@ -740,7 +733,7 @@ public class TabPersistentStore { |
} |
private void cleanupPersistentDataAtAndAboveId(int minForbiddenId) { |
- String[] files = getStateFolder(mContext, mSelectorIndex).list(); |
+ String[] files = getStateDirectory().list(); |
for (String file : files) { |
Pair<Integer, Boolean> data = TabState.parseInfoFromFilename(file); |
@@ -755,7 +748,7 @@ public class TabPersistentStore { |
} |
private void cleanupAllEncryptedPersistentData() { |
- String[] files = getStateFolder(mContext, mSelectorIndex).list(); |
+ String[] files = getStateDirectory().list(); |
for (String file : files) { |
if (file.startsWith(TabState.SAVED_TAB_STATE_FILE_PREFIX_INCOGNITO)) { |
deleteFileAsync(file); |
@@ -767,7 +760,7 @@ public class TabPersistentStore { |
new AsyncTask<Void, Void, Void>() { |
@Override |
protected Void doInBackground(Void... voids) { |
- File stateFile = new File(getStateFolder(mContext, mSelectorIndex), file); |
+ File stateFile = new File(getStateDirectory(), file); |
if (stateFile.exists()) { |
if (!stateFile.delete()) Log.e(TAG, "Failed to delete file: " + stateFile); |
} |
@@ -789,10 +782,7 @@ public class TabPersistentStore { |
protected TabState doInBackground(Void... voids) { |
if (mDestroyed || isCancelled()) return null; |
try { |
- return readTabState(mTabToRestore.id); |
- } catch (IOException e) { |
- // Bad state file, skipping it. |
- return null; |
+ return TabState.restoreTabState(getStateDirectory(), mTabToRestore.id); |
} catch (Exception e) { |
Log.w(TAG, "Unable to read state: " + e); |
return null; |
@@ -828,7 +818,7 @@ public class TabPersistentStore { |
@Override |
protected Void doInBackground(Void... params) { |
File oldFolder = mContext.getFilesDir(); |
- File newFolder = getStateFolder(mContext, mSelectorIndex); |
+ File newFolder = getStateDirectory(); |
// If we already have files here just return. |
File[] newFiles = newFolder.listFiles(); |
if (newFiles != null && newFiles.length > 0) return null; |
@@ -855,46 +845,6 @@ public class TabPersistentStore { |
} |
} |
- private TabState readTabState(int id) throws IOException { |
- File stateFolder = getStateFolder(mContext, mSelectorIndex); |
- FileInputStream fis = null; |
- try { |
- // First try finding an unencrypted file. |
- boolean encrypted = false; |
- File file = new File(stateFolder, TabState.getTabStateFilename(id, encrypted)); |
- |
- // If that fails, try finding the encrypted version. |
- if (!file.exists()) { |
- encrypted = true; |
- file = new File(stateFolder, TabState.getTabStateFilename(id, encrypted)); |
- } |
- |
- // If they both failed, there's nothing to read. |
- if (!file.exists()) return null; |
- |
- // If one of them passed, open the file input stream and read the state contents. |
- fis = new FileInputStream(file); |
- return TabState.readState(fis, encrypted); |
- } finally { |
- StreamUtil.closeQuietly(fis); |
- } |
- } |
- |
- private FileOutputStream openTabStateOutputStream(int id, boolean encrypted) |
- throws IOException { |
- File stateFolder = getStateFolder(mContext, mSelectorIndex); |
- return new FileOutputStream( |
- new File(stateFolder, TabState.getTabStateFilename(id, encrypted))); |
- } |
- |
- private void deleteTabStateFile(int id, boolean encrypted) { |
- File stateFolder = getStateFolder(mContext, mSelectorIndex); |
- File file = new File(stateFolder, TabState.getTabStateFilename(id, encrypted)); |
- if (file.exists()) { |
- if (!file.delete()) Log.e(TAG, "Failed to delete TabState: " + file); |
- } |
- } |
- |
private boolean isTabUrlContentScheme(Tab tab) { |
String url = tab.getUrl(); |
return url != null && url.startsWith("content"); |