| Index: chrome/android/java/src/org/chromium/chrome/browser/TabState.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabState.java b/chrome/android/java/src/org/chromium/chrome/browser/TabState.java
|
| index 8852253a418481bca0de83e18fde32d619d7b403..16150938f243e033b1017ec47b3131ae61148f4e 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/TabState.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/TabState.java
|
| @@ -286,54 +286,61 @@ public class TabState {
|
|
|
| /**
|
| * Writes the TabState to disk. This method may be called on either the UI or background thread.
|
| - * @param output Stream to write the tab's state to.
|
| + * @param file File to write the tab's state to.
|
| * @param state State object obtained from from {@link Tab#getState()}.
|
| * @param encrypted Whether or not the TabState should be encrypted.
|
| */
|
| - public static void saveState(FileOutputStream output, TabState state, boolean encrypted)
|
| - throws IOException {
|
| + public static void saveState(File file, TabState state, boolean encrypted) {
|
| if (state == null || state.contentsState == null) {
|
| return;
|
| }
|
|
|
| - DataOutputStream stream;
|
| - if (encrypted) {
|
| - Cipher cipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
|
| - if (cipher != null) {
|
| - stream = new DataOutputStream(new CipherOutputStream(output, cipher));
|
| - } else {
|
| - // If cipher is null, getRandomBytes failed, which means encryption is meaningless.
|
| - // Therefore, do not save anything. This will cause users to lose Incognito state in
|
| - // certain cases. That is annoying, but is better than failing to provide the
|
| - // guarantee of Incognito Mode.
|
| - return;
|
| - }
|
| - } else {
|
| - stream = new DataOutputStream(output);
|
| - }
|
| + // Create the byte array from contentsState before opening the FileOutputStream, in case
|
| + // contentsState.buffer is an instance of MappedByteBuffer that is mapped to
|
| + // the tab state file.
|
| + state.contentsState.buffer().rewind();
|
| + byte[] contentsStateBytes = new byte[state.contentsState.buffer().remaining()];
|
| + state.contentsState.buffer().get(contentsStateBytes);
|
|
|
| + DataOutputStream dataOutputStream = null;
|
| + FileOutputStream fileOutputStream = null;
|
| try {
|
| + fileOutputStream = new FileOutputStream(file);
|
| +
|
| if (encrypted) {
|
| - stream.writeLong(KEY_CHECKER);
|
| + Cipher cipher = CipherFactory.getInstance().getCipher(Cipher.ENCRYPT_MODE);
|
| + if (cipher != null) {
|
| + dataOutputStream = new DataOutputStream(new CipherOutputStream(
|
| + fileOutputStream, cipher));
|
| + } else {
|
| + // If cipher is null, getRandomBytes failed, which means encryption is
|
| + // meaningless. Therefore, do not save anything. This will cause users
|
| + // to lose Incognito state in certain cases. That is annoying, but is
|
| + // better than failing to provide the guarantee of Incognito Mode.
|
| + return;
|
| + }
|
| + } else {
|
| + dataOutputStream = new DataOutputStream(fileOutputStream);
|
| }
|
| - stream.writeLong(state.timestampMillis);
|
| - state.contentsState.buffer().rewind();
|
| - stream.writeInt(state.contentsState.buffer().remaining());
|
| if (encrypted) {
|
| - byte[] bytes = new byte[state.contentsState.buffer().remaining()];
|
| - state.contentsState.buffer().get(bytes);
|
| - stream.write(bytes);
|
| - } else {
|
| - output.getChannel().write(state.contentsState.buffer());
|
| + dataOutputStream.writeLong(KEY_CHECKER);
|
| }
|
| - stream.writeInt(state.parentId);
|
| - stream.writeUTF(state.openerAppId != null ? state.openerAppId : "");
|
| - stream.writeInt(state.contentsState.version());
|
| - stream.writeLong(state.syncId);
|
| - stream.writeBoolean(state.shouldPreserve);
|
| - stream.writeInt(state.themeColor);
|
| + dataOutputStream.writeLong(state.timestampMillis);
|
| + dataOutputStream.writeInt(contentsStateBytes.length);
|
| + dataOutputStream.write(contentsStateBytes);
|
| + dataOutputStream.writeInt(state.parentId);
|
| + dataOutputStream.writeUTF(state.openerAppId != null ? state.openerAppId : "");
|
| + dataOutputStream.writeInt(state.contentsState.version());
|
| + dataOutputStream.writeLong(state.syncId);
|
| + dataOutputStream.writeBoolean(state.shouldPreserve);
|
| + dataOutputStream.writeInt(state.themeColor);
|
| + } catch (FileNotFoundException e) {
|
| + Log.w(TAG, "FileNotFoundException while attempting to save TabState.");
|
| + } catch (IOException e) {
|
| + Log.w(TAG, "IOException while attempting to save TabState.");
|
| } finally {
|
| - StreamUtil.closeQuietly(stream);
|
| + StreamUtil.closeQuietly(dataOutputStream);
|
| + StreamUtil.closeQuietly(fileOutputStream);
|
| }
|
| }
|
|
|
| @@ -467,4 +474,4 @@ public class TabState {
|
| private static native void nativeFreeWebContentsStateBuffer(ByteBuffer buffer);
|
|
|
| private static native void nativeCreateHistoricalTab(ByteBuffer state, int savedStateVersion);
|
| -}
|
| +}
|
|
|