Android: Factor out TabState API from Tab
Moves TabState-related stuff from Tab to TabState which is a collection
of static utility methods.
|SHOULD_PRESERVE| is not in use any more. Deleted the field from
TabState, and access to/from Bundle.
Bug: 925242
Change-Id: I675275d821cabcccc5e67eef67baa80a103073a0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1501952
Reviewed-by: Theresa <twellington@chromium.org>
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#639704}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 28c03c7..025656d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -86,14 +86,12 @@
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsAccessibility;
import org.chromium.content_public.common.BrowserControlsState;
-import org.chromium.content_public.common.Referrer;
import org.chromium.content_public.common.ResourceRequestBody;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.base.WindowAndroid;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
/**
* The basic Java representation of a tab. Contains and manages a {@link ContentView}.
@@ -226,12 +224,6 @@
private String mAppAssociatedWith;
/**
- * Keeps track of whether the Tab should be kept in the TabModel after the user hits "back".
- * Used by Document mode to keep track of whether we want to remove the tab when user hits back.
- */
- private boolean mShouldPreserve;
-
- /**
* True while a page load is in progress.
*/
private boolean mIsLoading;
@@ -411,7 +403,6 @@
assert state != null;
mAppAssociatedWith = state.openerAppId;
mFrozenContentsState = state.contentsState;
- mShouldPreserve = state.shouldPreserve;
mTimestampMillis = state.timestampMillis;
mUrl = state.getVirtualUrlFromState();
@@ -648,58 +639,11 @@
return getActivity().getTabModelSelector();
}
- /** @return An opaque "state" object that can be persisted to storage. */
- public TabState getState() {
- if (!isInitialized()) return null;
- TabState tabState = new TabState();
- tabState.contentsState = getWebContentsState();
- tabState.openerAppId = mAppAssociatedWith;
- tabState.parentId = mParentId;
- tabState.shouldPreserve = mShouldPreserve;
- tabState.timestampMillis = mTimestampMillis;
- tabState.tabLaunchTypeAtCreation = mLaunchTypeAtCreation;
- // Don't save actual default theme color because it could change on night mode state
- // changed.
- tabState.themeColor = TabThemeColorHelper.isDefaultColorUsed(this)
- ? TabState.UNSPECIFIED_THEME_COLOR
- : TabThemeColorHelper.getColor(this);
- tabState.rootId = mRootId;
- return tabState;
- }
-
/** @return WebContentsState representing the state of the WebContents (navigations, etc.) */
- private WebContentsState getFrozenContentsState() {
+ WebContentsState getFrozenContentsState() {
return mFrozenContentsState;
}
- /** Returns an object representing the state of the Tab's WebContents. */
- private TabState.WebContentsState getWebContentsState() {
- if (mFrozenContentsState != null) return mFrozenContentsState;
-
- // Native call returns null when buffer allocation needed to serialize the state failed.
- ByteBuffer buffer = getWebContentsStateAsByteBuffer();
- if (buffer == null) return null;
-
- TabState.WebContentsState state = new TabState.WebContentsState(buffer);
- state.setVersion(TabState.CONTENTS_STATE_CURRENT_VERSION);
- return state;
- }
-
- /** Returns an ByteBuffer representing the state of the Tab's WebContents. */
- private ByteBuffer getWebContentsStateAsByteBuffer() {
- if (mPendingLoadParams == null) {
- return TabState.getContentsStateAsByteBuffer(this);
- } else {
- Referrer referrer = mPendingLoadParams.getReferrer();
- return TabState.createSingleNavigationStateAsByteBuffer(
- mPendingLoadParams.getUrl(),
- referrer != null ? referrer.getUrl() : null,
- // Policy will be ignored for null referrer url, 0 is just a placeholder.
- referrer != null ? referrer.getPolicy() : 0,
- isIncognito());
- }
- }
-
/**
* Reloads the current page content.
*/
@@ -1950,7 +1894,7 @@
/**
* @return Parameters that should be used for a lazily loaded Tab. May be null.
*/
- private LoadUrlParams getPendingLoadParams() {
+ LoadUrlParams getPendingLoadParams() {
return mPendingLoadParams;
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabState.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabState.java
index 8c50b64b..e0fb454 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabState.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabState.java
@@ -17,7 +17,9 @@
import org.chromium.chrome.browser.crypto.CipherFactory;
import org.chromium.chrome.browser.tabmodel.TabLaunchType;
import org.chromium.chrome.browser.util.ColorUtils;
+import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.common.Referrer;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
@@ -76,7 +78,6 @@
private static final String PARENT_ID = TAB_STATE_BUNDLE_PREFIX + "parentId";
private static final String OPENER_APP_ID = TAB_STATE_BUNDLE_PREFIX + "openerAppId";
private static final String VERSION = TAB_STATE_BUNDLE_PREFIX + "version";
- private static final String SHOULD_PRESERVE = TAB_STATE_BUNDLE_PREFIX + "shouldPreserve";
private static final String THEME_COLOR = TAB_STATE_BUNDLE_PREFIX + "themeColor";
private static final String IS_INCOGNITO = TAB_STATE_BUNDLE_PREFIX + "isIncognito";
@@ -144,7 +145,6 @@
public long timestampMillis = TIMESTAMP_NOT_SET;
public String openerAppId;
- public boolean shouldPreserve;
/**
* The tab's brand theme color. Set this to {@link #UNSPECIFIED_THEME_COLOR} for an unspecified
@@ -224,7 +224,6 @@
tabState.parentId = bundle.getInt(PARENT_ID);
tabState.openerAppId = bundle.getString(OPENER_APP_ID);
tabState.contentsState.setVersion(bundle.getInt(VERSION));
- tabState.shouldPreserve = bundle.getBoolean(SHOULD_PRESERVE);
tabState.themeColor = bundle.getInt(THEME_COLOR);
tabState.mIsIncognito = bundle.getBoolean(IS_INCOGNITO);
@@ -300,10 +299,9 @@
} catch (EOFException eof) {
}
try {
- tabState.shouldPreserve = stream.readBoolean();
+ boolean shouldPreserveNotUsed = stream.readBoolean();
} catch (EOFException eof) {
// Could happen if reading a version of TabState without this flag set.
- tabState.shouldPreserve = false;
Log.w(TAG,
"Failed to read shouldPreserve flag from tab state. "
+ "Assuming shouldPreserve is false");
@@ -355,6 +353,47 @@
return contentsStateBytes;
}
+ /** @return An opaque "state" object that can be persisted to storage. */
+ public static TabState from(Tab tab) {
+ if (!tab.isInitialized()) return null;
+ TabState tabState = new TabState();
+ tabState.contentsState = getWebContentsState(tab);
+ tabState.openerAppId = tab.getAppAssociatedWith();
+ tabState.parentId = tab.getParentId();
+ tabState.timestampMillis = tab.getTimestampMillis();
+ tabState.tabLaunchTypeAtCreation = tab.getLaunchTypeAtInitialTabCreation();
+ tabState.themeColor = TabThemeColorHelper.getColor(tab);
+ tabState.rootId = tab.getRootId();
+ return tabState;
+ }
+
+ /** Returns an object representing the state of the Tab's WebContents. */
+ private static WebContentsState getWebContentsState(Tab tab) {
+ if (tab.getFrozenContentsState() != null) return tab.getFrozenContentsState();
+
+ // Native call returns null when buffer allocation needed to serialize the state failed.
+ ByteBuffer buffer = getWebContentsStateAsByteBuffer(tab);
+ if (buffer == null) return null;
+
+ WebContentsState state = new WebContentsState(buffer);
+ state.setVersion(CONTENTS_STATE_CURRENT_VERSION);
+ return state;
+ }
+
+ /** Returns an ByteBuffer representing the state of the Tab's WebContents. */
+ private static ByteBuffer getWebContentsStateAsByteBuffer(Tab tab) {
+ LoadUrlParams pendingLoadParams = tab.getPendingLoadParams();
+ if (pendingLoadParams == null) {
+ return getContentsStateAsByteBuffer(tab);
+ } else {
+ Referrer referrer = pendingLoadParams.getReferrer();
+ return createSingleNavigationStateAsByteBuffer(pendingLoadParams.getUrl(),
+ referrer != null ? referrer.getUrl() : null,
+ // Policy will be ignored for null referrer url, 0 is just a placeholder.
+ referrer != null ? referrer.getPolicy() : 0, tab.isIncognito());
+ }
+ }
+
/**
* Writes the TabState to disk. This method may be called on either the UI or background thread.
* @param file File to write the tab's state to.
@@ -397,7 +436,7 @@
dataOutputStream.writeUTF(state.openerAppId != null ? state.openerAppId : "");
dataOutputStream.writeInt(state.contentsState.version());
dataOutputStream.writeLong(-1); // Obsolete sync ID.
- dataOutputStream.writeBoolean(state.shouldPreserve);
+ dataOutputStream.writeBoolean(false); // Obsolete attribute |SHOULD_PRESERVE|.
dataOutputStream.writeInt(state.themeColor);
dataOutputStream.writeInt(
state.tabLaunchTypeAtCreation != null ? state.tabLaunchTypeAtCreation : -1);
@@ -434,7 +473,6 @@
bundle.putInt(PARENT_ID, state.parentId);
bundle.putString(OPENER_APP_ID, state.openerAppId);
bundle.putInt(VERSION, state.contentsState.version());
- bundle.putBoolean(SHOULD_PRESERVE, state.shouldPreserve);
bundle.putInt(THEME_COLOR, state.themeColor);
bundle.putBoolean(IS_INCOGNITO, state.isIncognito());
}
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 a7b0ae0..e92175a 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
@@ -317,7 +317,7 @@
int id = tab.getId();
boolean incognito = tab.isIncognito();
try {
- TabState state = tab.getState();
+ TabState state = TabState.from(tab);
if (state != null) {
TabState.saveState(getTabStateFile(id, incognito), state, incognito);
}
@@ -1141,7 +1141,7 @@
@Override
protected void onPreExecute() {
if (mDestroyed || isCancelled()) return;
- mState = mTab.getState();
+ mState = TabState.from(mTab);
}
@Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
index 6e3b34c..11cd4a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -371,7 +371,7 @@
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
long time = SystemClock.elapsedRealtime();
- TabState.saveState(tabFile, getActivityTab().getState(), false);
+ TabState.saveState(tabFile, TabState.from(getActivityTab()), false);
RecordHistogram.recordTimesHistogram(
"Android.StrictMode.WebappSaveState", SystemClock.elapsedRealtime() - time);
} finally {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
index 9bb6462..5acb866 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
@@ -572,11 +572,12 @@
Tab[] frozen = new Tab[1];
WebContents[] restored = new WebContents[1];
ThreadUtils.runOnUiThreadBlocking(() -> {
- TabState state = tab.getState();
+ TabState state = TabState.from(tab);
mActivityTestRule.getActivity().getCurrentTabModel().closeTab(tab);
frozen[0] = mActivityTestRule.getActivity().getCurrentTabCreator().createFrozenTab(
state, tab.getId(), 1);
- restored[0] = frozen[0].getState().contentsState.restoreContentsFromByteBuffer(false);
+ restored[0] =
+ TabState.from(frozen[0]).contentsState.restoreContentsFromByteBuffer(false);
});
// Check content of frozen state.
@@ -594,7 +595,8 @@
// Check that frozen state was cleaned up.
ThreadUtils.runOnUiThreadBlocking(() -> {
- restored[0] = frozen[0].getState().contentsState.restoreContentsFromByteBuffer(false);
+ restored[0] =
+ TabState.from(frozen[0]).contentsState.restoreContentsFromByteBuffer(false);
});
controller = restored[0].getNavigationController();
assertEquals(0, controller.getLastCommittedEntryIndex());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabStateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabStateTest.java
index 254bb0a..93651ce 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabStateTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/TabStateTest.java
@@ -101,7 +101,6 @@
tabState.parentId = 2;
tabState.openerAppId = "app";
tabState.contentsState.setVersion(TabState.CONTENTS_STATE_CURRENT_VERSION);
- tabState.shouldPreserve = true;
tabState.themeColor = Color.BLACK;
tabState.mIsIncognito = true;
@@ -116,7 +115,6 @@
Assert.assertEquals(tabState.timestampMillis, restoredState.timestampMillis);
Assert.assertEquals(
tabState.contentsState.version(), restoredState.contentsState.version());
- Assert.assertEquals(tabState.shouldPreserve, restoredState.shouldPreserve);
Assert.assertEquals(tabState.themeColor, restoredState.themeColor);
Assert.assertEquals(tabState.mIsIncognito, restoredState.mIsIncognito);
}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java
index 44a53cd..0c1fd9a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java
@@ -37,7 +37,6 @@
private static final int PARENT_ID = 1;
private static final int VERSION = 2;
private static final int THEME_COLOR = 4;
- private static final boolean SHOULD_PRESERVE = true;
private static final String OPENER_APP_ID = "test";
private static final @Nullable @TabLaunchType Integer LAUNCH_TYPE_AT_CREATION = null;
private static final int ROOT_ID = 1;
@@ -67,7 +66,6 @@
state.timestampMillis = TIMESTAMP;
state.parentId = PARENT_ID;
state.themeColor = THEME_COLOR;
- state.shouldPreserve = SHOULD_PRESERVE;
state.openerAppId = OPENER_APP_ID;
state.tabLaunchTypeAtCreation = LAUNCH_TYPE_AT_CREATION;
state.rootId = ROOT_ID;
@@ -82,7 +80,6 @@
assertEquals(PARENT_ID, state.parentId);
assertEquals(OPENER_APP_ID, state.openerAppId);
assertEquals(VERSION, state.contentsState.version());
- assertEquals(SHOULD_PRESERVE, state.shouldPreserve);
assertEquals(THEME_COLOR, state.getThemeColor());
assertEquals(LAUNCH_TYPE_AT_CREATION, state.tabLaunchTypeAtCreation);
assertEquals(ROOT_ID, state.rootId);
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java
index 6edd39c..aa326fe 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/NoTouchActivity.java
@@ -153,7 +153,7 @@
if (tab == null || tab.getUrl() == null || tab.getUrl().isEmpty()) return;
long time = SystemClock.elapsedRealtime();
outState.putInt(BUNDLE_TAB_ID, tab.getId());
- TabState.saveState(outState, tab.getState());
+ TabState.saveState(outState, TabState.from(tab));
RecordHistogram.recordTimesHistogram("Android.StrictMode.NoTouchActivitySaveState",
SystemClock.elapsedRealtime() - time);
}