Commit 99abf633 authored by Pete Williamson's avatar Pete Williamson Committed by Commit Bot

Add navigateNewTab, navigateIncognitoTab, and downloadLink.

As part of Feed development, add entry points to allow an XSurface
client to open a page in a new tab, open in an incognito tab, or
download the URL as an offline page.

Bug: 1099057
Change-Id: Id6152147c105993d88aa08cee9f16ea42da45b2d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2265497Reviewed-by: default avatarDan H <harringtond@chromium.org>
Reviewed-by: default avatarJustin DeWitt <dewittj@chromium.org>
Reviewed-by: default avatarJian Li <jianli@chromium.org>
Commit-Queue: Peter Williamson <petewil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782741}
parent 350e9c41
...@@ -22,6 +22,8 @@ import org.chromium.base.annotations.NativeMethods; ...@@ -22,6 +22,8 @@ import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate; import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.offlinepages.RequestCoordinatorBridge;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.IdentityServicesProvider;
import org.chromium.chrome.browser.suggestions.SuggestionsConfig; import org.chromium.chrome.browser.suggestions.SuggestionsConfig;
...@@ -393,12 +395,24 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand ...@@ -393,12 +395,24 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand
@Override @Override
public void navigateTab(String url) { public void navigateTab(String url) {
openUrl(url, /*inNewTab=*/false); openUrl(url, WindowOpenDisposition.CURRENT_TAB);
} }
@Override @Override
public void navigateNewTab(String url) { public void navigateNewTab(String url) {
openUrl(url, /*inNewTab=*/true); openUrl(url, WindowOpenDisposition.NEW_FOREGROUND_TAB);
}
@Override
public void navigateIncognitoTab(String url) {
openUrl(url, WindowOpenDisposition.OFF_THE_RECORD);
}
@Override
public void downloadLink(String url) {
RequestCoordinatorBridge.getForProfile(Profile.getLastUsedRegularProfile())
.savePageLater(url, OfflinePageBridge.SUGGESTED_ARTICLES_NAMESPACE,
true /* user requested*/);
} }
@Override @Override
...@@ -502,19 +516,21 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand ...@@ -502,19 +516,21 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand
} }
} }
private void openUrl(String url, boolean inNewTab) { private void openUrl(String url, int disposition) {
LoadUrlParams params = new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK); LoadUrlParams params = new LoadUrlParams(url, PageTransition.AUTO_BOOKMARK);
params.setReferrer( params.setReferrer(
new Referrer(SuggestionsConfig.getReferrerUrl(ChromeFeatureList.INTEREST_FEED_V2), new Referrer(SuggestionsConfig.getReferrerUrl(ChromeFeatureList.INTEREST_FEED_V2),
ReferrerPolicy.ALWAYS)); ReferrerPolicy.ALWAYS));
Tab tab = Tab tab = mPageNavigationDelegate.openUrl(disposition, params);
mPageNavigationDelegate.openUrl(inNewTab ? WindowOpenDisposition.NEW_BACKGROUND_TAB
: WindowOpenDisposition.CURRENT_TAB, boolean inNewTab = (disposition == WindowOpenDisposition.NEW_BACKGROUND_TAB
params); || disposition == WindowOpenDisposition.OFF_THE_RECORD);
FeedStreamSurfaceJni.get().reportNavigationStarted( FeedStreamSurfaceJni.get().reportNavigationStarted(
mNativeFeedStreamSurface, FeedStreamSurface.this, url, inNewTab); mNativeFeedStreamSurface, FeedStreamSurface.this);
tab.addObserver(new FeedTabNavigationObserver(inNewTab)); if (tab != null) {
tab.addObserver(new FeedTabNavigationObserver(inNewTab));
}
} }
@NativeMethods @NativeMethods
...@@ -524,8 +540,7 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand ...@@ -524,8 +540,7 @@ public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHand
// TODO(jianli): Call this function at the appropriate time. // TODO(jianli): Call this function at the appropriate time.
void reportSliceViewed( void reportSliceViewed(
long nativeFeedStreamSurface, FeedStreamSurface caller, String sliceId); long nativeFeedStreamSurface, FeedStreamSurface caller, String sliceId);
void reportNavigationStarted(long nativeFeedStreamSurface, FeedStreamSurface caller, void reportNavigationStarted(long nativeFeedStreamSurface, FeedStreamSurface caller);
String url, boolean inNewTab);
// TODO(jianli): Call this function at the appropriate time. // TODO(jianli): Call this function at the appropriate time.
void reportPageLoaded(long nativeFeedStreamSurface, FeedStreamSurface caller, String url, void reportPageLoaded(long nativeFeedStreamSurface, FeedStreamSurface caller, String url,
boolean inNewTab); boolean inNewTab);
......
...@@ -7,7 +7,9 @@ package org.chromium.chrome.browser.feed.v2; ...@@ -7,7 +7,9 @@ package org.chromium.chrome.browser.feed.v2;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity; import android.app.Activity;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
...@@ -19,7 +21,9 @@ import com.google.protobuf.ByteString; ...@@ -19,7 +21,9 @@ import com.google.protobuf.ByteString;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
...@@ -27,13 +31,17 @@ import org.robolectric.annotation.Config; ...@@ -27,13 +31,17 @@ import org.robolectric.annotation.Config;
import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker; import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
import org.chromium.chrome.browser.tab.MockTab;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.xsurface.FeedActionsHandler; import org.chromium.chrome.browser.xsurface.FeedActionsHandler;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.feed.proto.FeedUiProto.Slice; import org.chromium.components.feed.proto.FeedUiProto.Slice;
import org.chromium.components.feed.proto.FeedUiProto.StreamUpdate; import org.chromium.components.feed.proto.FeedUiProto.StreamUpdate;
import org.chromium.components.feed.proto.FeedUiProto.StreamUpdate.SliceUpdate; import org.chromium.components.feed.proto.FeedUiProto.StreamUpdate.SliceUpdate;
import org.chromium.components.feed.proto.FeedUiProto.XSurfaceSlice; import org.chromium.components.feed.proto.FeedUiProto.XSurfaceSlice;
import org.chromium.ui.mojom.WindowOpenDisposition;
import java.util.Arrays; import java.util.Arrays;
...@@ -42,6 +50,7 @@ import java.util.Arrays; ...@@ -42,6 +50,7 @@ import java.util.Arrays;
@Config(manifest = Config.NONE) @Config(manifest = Config.NONE)
public class FeedStreamSurfaceTest { public class FeedStreamSurfaceTest {
private static final String TEST_DATA = "test"; private static final String TEST_DATA = "test";
private static final String TEST_URL = "https://www.chromium.org";
private FeedStreamSurface mFeedStreamSurface; private FeedStreamSurface mFeedStreamSurface;
private Activity mActivity; private Activity mActivity;
...@@ -51,9 +60,15 @@ public class FeedStreamSurfaceTest { ...@@ -51,9 +60,15 @@ public class FeedStreamSurfaceTest {
private FeedActionsHandler.SnackbarController mSnackbarController; private FeedActionsHandler.SnackbarController mSnackbarController;
@Mock @Mock
private BottomSheetController mBottomSheetController; private BottomSheetController mBottomSheetController;
@Mock
private NativePageNavigationDelegate mPageNavigationDelegate;
@Rule @Rule
public JniMocker mocker = new JniMocker(); public JniMocker mocker = new JniMocker();
// Enable the Features class, so we can call code which checks to see if features are enabled
// without crashing.
@Rule
public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
@Mock @Mock
private FeedStreamSurface.Natives mFeedStreamSurfaceJniMock; private FeedStreamSurface.Natives mFeedStreamSurfaceJniMock;
...@@ -63,8 +78,8 @@ public class FeedStreamSurfaceTest { ...@@ -63,8 +78,8 @@ public class FeedStreamSurfaceTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mActivity = Robolectric.buildActivity(Activity.class).get(); mActivity = Robolectric.buildActivity(Activity.class).get();
mocker.mock(FeedStreamSurfaceJni.TEST_HOOKS, mFeedStreamSurfaceJniMock); mocker.mock(FeedStreamSurfaceJni.TEST_HOOKS, mFeedStreamSurfaceJniMock);
mFeedStreamSurface = new FeedStreamSurface( mFeedStreamSurface = new FeedStreamSurface(mActivity, false, mSnackbarManager,
mActivity, false, mSnackbarManager, null, mBottomSheetController); mPageNavigationDelegate, mBottomSheetController);
} }
@Test @Test
...@@ -358,6 +373,32 @@ public class FeedStreamSurfaceTest { ...@@ -358,6 +373,32 @@ public class FeedStreamSurfaceTest {
assertEquals(headers + 6, contentManager.findContentPositionByKey("i")); assertEquals(headers + 6, contentManager.findContentPositionByKey("i"));
} }
@Test
@SmallTest
public void testNavigateTab() {
when(mPageNavigationDelegate.openUrl(anyInt(), any())).thenReturn(new MockTab(1, false));
mFeedStreamSurface.navigateTab(TEST_URL);
verify(mPageNavigationDelegate)
.openUrl(ArgumentMatchers.eq(WindowOpenDisposition.CURRENT_TAB), any());
}
@Test
@SmallTest
public void testNavigateNewTab() {
when(mPageNavigationDelegate.openUrl(anyInt(), any())).thenReturn(new MockTab(1, false));
mFeedStreamSurface.navigateNewTab(TEST_URL);
verify(mPageNavigationDelegate)
.openUrl(ArgumentMatchers.eq(WindowOpenDisposition.NEW_FOREGROUND_TAB), any());
}
@Test
@SmallTest
public void testNavigateIncognitoTab() {
when(mPageNavigationDelegate.openUrl(anyInt(), any())).thenReturn(new MockTab(1, false));
mFeedStreamSurface.navigateIncognitoTab(TEST_URL);
verify(mPageNavigationDelegate)
.openUrl(ArgumentMatchers.eq(WindowOpenDisposition.OFF_THE_RECORD), any());
}
@Test @Test
@SmallTest @SmallTest
public void testShowSnackbar() { public void testShowSnackbar() {
......
...@@ -175,9 +175,7 @@ void FeedStreamSurface::ReportDownloadAction(JNIEnv* env, ...@@ -175,9 +175,7 @@ void FeedStreamSurface::ReportDownloadAction(JNIEnv* env,
void FeedStreamSurface::ReportNavigationStarted( void FeedStreamSurface::ReportNavigationStarted(
JNIEnv* env, JNIEnv* env,
const JavaParamRef<jobject>& obj, const JavaParamRef<jobject>& obj) {
const JavaParamRef<jstring>& url,
jboolean in_new_tab) {
feed_stream_api_->ReportNavigationStarted(); feed_stream_api_->ReportNavigationStarted();
} }
......
...@@ -80,9 +80,7 @@ class FeedStreamSurface : public FeedStreamApi::SurfaceInterface { ...@@ -80,9 +80,7 @@ class FeedStreamSurface : public FeedStreamApi::SurfaceInterface {
void ReportDownloadAction(JNIEnv* env, void ReportDownloadAction(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj); const base::android::JavaParamRef<jobject>& obj);
void ReportNavigationStarted(JNIEnv* env, void ReportNavigationStarted(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& obj);
const base::android::JavaParamRef<jstring>& url,
jboolean in_new_tab);
void ReportPageLoaded(JNIEnv* env, void ReportPageLoaded(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& url, const base::android::JavaParamRef<jstring>& url,
......
...@@ -22,6 +22,16 @@ public interface SurfaceActionsHandler { ...@@ -22,6 +22,16 @@ public interface SurfaceActionsHandler {
*/ */
default void navigateNewTab(String url) {} default void navigateNewTab(String url) {}
/**
* Navigate a new incognito tab to a URL.
*/
default void navigateIncognitoTab(String url) {}
/**
* Get an offline page for a URL.
*/
default void downloadLink(String url) {}
/** /**
* Open a bottom sheet with the view as contents. * Open a bottom sheet with the view as contents.
*/ */
......
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