Commit 17b517f8 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

[WebLayer] Set type of navigations from embedder appropriately

In WebLayer, navigations coming from the embedder currently get the
type TYPED | FROM_ADDRESS_BAR. This type has implications on how intent
launching is handled for these navigations: for user-typed navigations,

(1) Intents are blocked from launching without a redirect
(2) Intents to URLs that the app can handle stay within the app even
    if (a) there was a redirect and (b) an external app has registered
    as a default handler for such URLs

Fact 2 in particular is problematic for intended production use cases
of WebLayer. This CL changes the navigation type for navigations coming
from the embedder to be reflective of these use cases: LINK with a user
gesture. Setting the navigation params this way ensures that intents
will be launched in the cases (1) and (2) described above.

Bug: 1087434
Change-Id: Ib43d2ea2cbbfd0352dcde3f5895ac82292b3415f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2219892
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773161}
parent aaa2b01c
...@@ -143,26 +143,29 @@ public class ExternalNavigationTest { ...@@ -143,26 +143,29 @@ public class ExternalNavigationTest {
} }
/** /**
* Tests that a direct navigation to an external intent is blocked, resulting in a failed * Tests that a direct navigation to an external intent is launched due to the navigation type
* browser navigation. * being set as from a link with a user gesture.
*/ */
@Test @Test
@SmallTest @SmallTest
public void testExternalIntentWithNoRedirectBlocked() throws Throwable { public void testExternalIntentWithNoRedirectLaunched() throws Throwable {
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(ABOUT_BLANK_URL); InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(ABOUT_BLANK_URL);
IntentInterceptor intentInterceptor = new IntentInterceptor(); IntentInterceptor intentInterceptor = new IntentInterceptor();
activity.setIntentInterceptor(intentInterceptor); activity.setIntentInterceptor(intentInterceptor);
Tab tab = mActivityTestRule.getActivity().getTab(); Tab tab = mActivityTestRule.getActivity().getTab();
TestThreadUtils.runOnUiThreadBlocking(
() -> { tab.getNavigationController().navigate(Uri.parse(INTENT_TO_CHROME_URL)); });
// Note that this navigation will not result in a paint. intentInterceptor.waitForIntent();
mActivityTestRule.navigateAndWaitForFailure(
tab, INTENT_TO_CHROME_URL, /*waitForPaint=*/false);
Assert.assertNull(intentInterceptor.mLastIntent);
// The current URL should not have changed. // The current URL should not have changed, and the intent should have been launched.
Assert.assertEquals(ABOUT_BLANK_URL, mActivityTestRule.getCurrentDisplayUrl()); Assert.assertEquals(ABOUT_BLANK_URL, mActivityTestRule.getCurrentDisplayUrl());
Intent intent = intentInterceptor.mLastIntent;
Assert.assertNotNull(intent);
Assert.assertEquals(INTENT_TO_CHROME_PACKAGE, intent.getPackage());
Assert.assertEquals(INTENT_TO_CHROME_ACTION, intent.getAction());
Assert.assertEquals(INTENT_TO_CHROME_DATA_STRING, intent.getDataString());
} }
/** /**
...@@ -448,12 +451,14 @@ public class ExternalNavigationTest { ...@@ -448,12 +451,14 @@ public class ExternalNavigationTest {
/** /**
* Tests that going to a page that loads an intent that can be handled in onload() results in * Tests that going to a page that loads an intent that can be handled in onload() results in
* the external intent being blocked by policy on intents without user gestures loading in the * the external intent being launched due to the navigation being specified as being from a link
* midst of a user-typed navigation. * with a user gesture (if the navigation were specified as being from user typing the intent
* would be blocked due to Chrome's policy on not launching intents from user-typed navigations
* without a redirect).
*/ */
@Test @Test
@SmallTest @SmallTest
public void testExternalIntentViaOnLoadBlocked() throws Throwable { public void testExternalIntentViaOnLoadLaunched() throws Throwable {
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(ABOUT_BLANK_URL); InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl(ABOUT_BLANK_URL);
IntentInterceptor intentInterceptor = new IntentInterceptor(); IntentInterceptor intentInterceptor = new IntentInterceptor();
activity.setIntentInterceptor(intentInterceptor); activity.setIntentInterceptor(intentInterceptor);
...@@ -465,14 +470,15 @@ public class ExternalNavigationTest { ...@@ -465,14 +470,15 @@ public class ExternalNavigationTest {
TestThreadUtils.runOnUiThreadBlocking( TestThreadUtils.runOnUiThreadBlocking(
() -> { tab.getNavigationController().navigate(Uri.parse(url)); }); () -> { tab.getNavigationController().navigate(Uri.parse(url)); });
NavigationWaiter waiter = new NavigationWaiter( intentInterceptor.waitForIntent();
INTENT_TO_CHROME_URL, tab, /*expectFailure=*/true, /*waitForPaint=*/false);
waiter.waitForNavigation();
Assert.assertNull(intentInterceptor.mLastIntent);
// The current URL should not have changed. // The current URL should not have changed, and the intent should have been launched.
Assert.assertEquals(url, mActivityTestRule.getCurrentDisplayUrl()); Assert.assertEquals(url, mActivityTestRule.getCurrentDisplayUrl());
Intent intent = intentInterceptor.mLastIntent;
Assert.assertNotNull(intent);
Assert.assertEquals(INTENT_TO_CHROME_PACKAGE, intent.getPackage());
Assert.assertEquals(INTENT_TO_CHROME_ACTION, intent.getAction());
Assert.assertEquals(INTENT_TO_CHROME_DATA_STRING, intent.getDataString());
} }
/** /**
......
...@@ -435,8 +435,12 @@ void NavigationControllerImpl::DoNavigate( ...@@ -435,8 +435,12 @@ void NavigationControllerImpl::DoNavigate(
return; return;
} }
params->transition_type = ui::PageTransitionFromInt( // For WebLayer's production use cases, navigations from the embedder are most
ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); // appropriately viewed as being from links with user gestures. In particular,
// this ensures that intents resulting from these navigations get launched as
// the embedder expects.
params->transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);
params->has_user_gesture = true;
web_contents()->GetController().LoadURLWithParams(*params); web_contents()->GetController().LoadURLWithParams(*params);
// So that if the user had entered the UI in a bar it stops flashing the // So that if the user had entered the UI in a bar it stops flashing the
// caret. // caret.
......
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