Commit d9773b82 authored by Becky Zhou's avatar Becky Zhou Committed by Commit Bot

[Feed] Save and restore instance state for the Stream

Bug: 851981
Change-Id: I2e97155353f2119661df92cdd023e2e086328d18
Reviewed-on: https://chromium-review.googlesource.com/1157441
Commit-Queue: Theresa <twellington@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585584}
parent 1723281f
......@@ -273,8 +273,8 @@ public class FeedNewTabPage extends NewTabPage {
}
@Override
protected void restoreLastScrollPosition() {
// This behavior is handled by the Feed library.
protected void saveLastScrollPosition() {
// This behavior is handled by the StreamLifecycleManager and the Feed library.
}
@Override
......
......@@ -171,7 +171,7 @@ class FeedNewTabPageMediator
if (!isScrollViewInitialized()) return 0;
int firstChildTop = mCoordinator.getStream().getChildTopAt(0);
return firstChildTop != Stream.POSITION_NOT_KNOWN ? -firstChildTop : 0;
return firstChildTop != Stream.POSITION_NOT_KNOWN ? -firstChildTop : Integer.MIN_VALUE;
}
@Override
......
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.feed;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.IntDef;
import com.google.android.libraries.feed.api.stream.Stream;
......@@ -13,9 +12,12 @@ import com.google.android.libraries.feed.api.stream.Stream;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.content_public.browser.NavigationController;
import org.chromium.content_public.browser.NavigationEntry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -29,6 +31,9 @@ class StreamLifecycleManager implements ApplicationStatus.ActivityStateListener
@Retention(RetentionPolicy.SOURCE)
private @interface StreamState {}
/** Key for the Stream instance state that may be stored in a navigation entry. */
private static final String STREAM_SAVED_INSTANCE_STATE_KEY = "StreamSavedInstanceState";
private static final int NOT_SPECIFIED = -1;
private static final int CREATED = 0;
private static final int SHOWN = 1;
......@@ -86,11 +91,15 @@ class StreamLifecycleManager implements ApplicationStatus.ActivityStateListener
public void onHidden(Tab tab) {
hide();
}
@Override
public void onPageLoadStarted(Tab tab, String url) {
saveInstanceState();
}
};
mStreamState = CREATED;
// TODO(huayinz): Handle saved instance state.
mStream.onCreate((Bundle) null);
mStream.onCreate(restoreInstanceState());
show();
activate();
......@@ -166,6 +175,9 @@ class StreamLifecycleManager implements ApplicationStatus.ActivityStateListener
deactivate();
mStreamState = HIDDEN;
// Save instance state as the Stream begins to hide. This matches the activity lifecycle
// that instance state is saved as the activity begins to stop.
saveInstanceState();
mStream.onHide();
}
......@@ -183,6 +195,37 @@ class StreamLifecycleManager implements ApplicationStatus.ActivityStateListener
mStream.onDestroy();
}
/** Save the Stream instance state to the navigation entry if necessary. */
private void saveInstanceState() {
if (mTab.getWebContents() == null) return;
NavigationController controller = mTab.getWebContents().getNavigationController();
int index = controller.getLastCommittedEntryIndex();
NavigationEntry entry = controller.getEntryAtIndex(index);
if (entry == null) return;
// At least under test conditions this method may be called initially for the load of the
// NTP itself, at which point the last committed entry is not for the NTP yet. This method
// will then be called a second time when the user navigates away, at which point the last
// committed entry is for the NTP. The extra data must only be set in the latter case.
if (!NewTabPage.isNTPUrl(entry.getUrl())) return;
controller.setEntryExtraData(
index, STREAM_SAVED_INSTANCE_STATE_KEY, mStream.getSavedInstanceStateString());
}
/**
* @return The Stream instance state saved in navigation entry, or null if it is not previously
* saved.
*/
private String restoreInstanceState() {
if (mTab.getWebContents() == null) return null;
NavigationController controller = mTab.getWebContents().getNavigationController();
int index = controller.getLastCommittedEntryIndex();
return controller.getEntryExtraData(index, STREAM_SAVED_INSTANCE_STATE_KEY);
}
@VisibleForTesting
TabObserver getTabObserverForTesting() {
return mTabObserver;
......
......@@ -314,7 +314,7 @@ public class NewTabPage
@Override
public void onPageLoadStarted(Tab tab, String url) {
restoreLastScrollPosition();
saveLastScrollPosition();
}
};
mTab.addObserver(mTabObserver);
......@@ -349,9 +349,9 @@ public class NewTabPage
}
/**
* Restore the last scroll position stored in the navigation entry (if set).
* Save the last scroll position stored in the navigation entry if necessary.
*/
protected void restoreLastScrollPosition() {
protected void saveLastScrollPosition() {
int scrollPosition = mNewTabPageView.getScrollPosition();
if (scrollPosition == RecyclerView.NO_POSITION) return;
......
......@@ -12,7 +12,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.os.Bundle;
import android.support.test.filters.SmallTest;
import com.google.android.libraries.feed.api.stream.Stream;
......@@ -51,7 +50,7 @@ public class StreamLifecycleManagerTest {
MockitoAnnotations.initMocks(this);
ApplicationStatus.onStateChangeForTesting(mActivity, ActivityState.CREATED);
mStreamLifecycleManager = new StreamLifecycleManager(mStream, mActivity, mTab);
verify(mStream, times(1)).onCreate(or(any(Bundle.class), isNull()));
verify(mStream, times(1)).onCreate(or(any(String.class), isNull()));
}
@Test
......
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