| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.chrome.browser.externalnav; |
| |
| import android.app.Activity; |
| import android.app.Instrumentation; |
| import android.app.Instrumentation.ActivityMonitor; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.net.Uri; |
| import android.os.SystemClock; |
| import android.support.test.InstrumentationRegistry; |
| import android.support.test.runner.lifecycle.Stage; |
| import android.text.TextUtils; |
| import android.util.Base64; |
| |
| import androidx.test.filters.LargeTest; |
| import androidx.test.filters.SmallTest; |
| |
| import org.hamcrest.Matchers; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import org.chromium.base.ApiCompatibilityUtils; |
| import org.chromium.base.ContextUtils; |
| import org.chromium.base.test.util.ApplicationTestUtils; |
| import org.chromium.base.test.util.CallbackHelper; |
| import org.chromium.base.test.util.CommandLineFlags; |
| import org.chromium.base.test.util.Criteria; |
| import org.chromium.base.test.util.CriteriaHelper; |
| import org.chromium.base.test.util.ScalableTimeout; |
| import org.chromium.chrome.browser.ChromeTabbedActivity; |
| import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
| import org.chromium.chrome.browser.flags.ChromeSwitches; |
| import org.chromium.chrome.browser.tab.EmptyTabObserver; |
| import org.chromium.chrome.browser.tab.InterceptNavigationDelegateTabHelper; |
| import org.chromium.chrome.browser.tab.Tab; |
| import org.chromium.chrome.browser.tab.TabCreationState; |
| import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; |
| import org.chromium.chrome.test.ChromeJUnit4ClassRunner; |
| import org.chromium.chrome.test.ChromeTabbedActivityTestRule; |
| import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResultType; |
| import org.chromium.components.external_intents.InterceptNavigationDelegateImpl; |
| import org.chromium.content_public.browser.LoadUrlParams; |
| import org.chromium.content_public.browser.NavigationHandle; |
| import org.chromium.content_public.browser.test.util.DOMUtils; |
| import org.chromium.content_public.browser.test.util.TestThreadUtils; |
| import org.chromium.content_public.browser.test.util.TouchCommon; |
| import org.chromium.net.test.EmbeddedTestServer; |
| import org.chromium.ui.base.PageTransition; |
| |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.TimeoutException; |
| |
| /** |
| * Test suite for verifying the behavior of various URL overriding actions. |
| */ |
| @RunWith(ChromeJUnit4ClassRunner.class) |
| @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) |
| public class UrlOverridingTest { |
| @Rule |
| public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); |
| |
| private static final String BASE_PATH = "/chrome/test/data/android/url_overriding/"; |
| private static final String NAVIGATION_FROM_TIMEOUT_PAGE = |
| BASE_PATH + "navigation_from_timer.html"; |
| private static final String NAVIGATION_FROM_TIMEOUT_PARENT_FRAME_PAGE = |
| BASE_PATH + "navigation_from_timer_parent_frame.html"; |
| private static final String NAVIGATION_FROM_USER_GESTURE_PAGE = |
| BASE_PATH + "navigation_from_user_gesture.html"; |
| private static final String NAVIGATION_FROM_USER_GESTURE_PARENT_FRAME_PAGE = |
| BASE_PATH + "navigation_from_user_gesture_parent_frame.html"; |
| private static final String NAVIGATION_FROM_XHR_CALLBACK_PAGE = |
| BASE_PATH + "navigation_from_xhr_callback.html"; |
| private static final String NAVIGATION_FROM_XHR_CALLBACK_PARENT_FRAME_PAGE = |
| BASE_PATH + "navigation_from_xhr_callback_parent_frame.html"; |
| private static final String NAVIGATION_FROM_XHR_CALLBACK_AND_SHORT_TIMEOUT_PAGE = |
| BASE_PATH + "navigation_from_xhr_callback_and_short_timeout.html"; |
| private static final String NAVIGATION_FROM_XHR_CALLBACK_AND_LONG_TIMEOUT_PAGE = |
| BASE_PATH + "navigation_from_xhr_callback_and_long_timeout.html"; |
| private static final String NAVIGATION_WITH_FALLBACK_URL_PAGE = |
| BASE_PATH + "navigation_with_fallback_url.html"; |
| private static final String NAVIGATION_WITH_FALLBACK_URL_PARENT_FRAME_PAGE = |
| BASE_PATH + "navigation_with_fallback_url_parent_frame.html"; |
| private static final String FALLBACK_LANDING_PATH = BASE_PATH + "hello.html"; |
| private static final String OPEN_WINDOW_FROM_USER_GESTURE_PAGE = |
| BASE_PATH + "open_window_from_user_gesture.html"; |
| private static final String OPEN_WINDOW_FROM_LINK_USER_GESTURE_PAGE = |
| BASE_PATH + "open_window_from_link_user_gesture.html"; |
| private static final String OPEN_WINDOW_FROM_SVG_USER_GESTURE_PAGE = |
| BASE_PATH + "open_window_from_svg_user_gesture.html"; |
| private static final String NAVIGATION_FROM_JAVA_REDIRECTION_PAGE = |
| BASE_PATH + "navigation_from_java_redirection.html"; |
| private static final String NAVIGATION_TO_CCT_FROM_INTENT_URI = |
| BASE_PATH + "navigation_to_cct_via_intent_uri.html"; |
| private static final String NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI = |
| BASE_PATH + "navigation_to_file_scheme_via_intent_uri.html"; |
| private static final String SUBFRAME_REDIRECT_WITH_PLAY_FALLBACK = |
| BASE_PATH + "subframe_navigation_with_play_fallback.html"; |
| |
| private static class TestTabObserver extends EmptyTabObserver { |
| private final CallbackHelper mFinishCallback; |
| private final CallbackHelper mFailCallback; |
| private final CallbackHelper mDestroyedCallback; |
| |
| TestTabObserver(final CallbackHelper finishCallback, final CallbackHelper failCallback, |
| final CallbackHelper destroyedCallback) { |
| mFinishCallback = finishCallback; |
| mFailCallback = failCallback; |
| mDestroyedCallback = destroyedCallback; |
| } |
| |
| @Override |
| public void onDidFinishNavigation(Tab tab, NavigationHandle navigation) { |
| if (navigation.errorCode() == 0) return; |
| mFailCallback.notifyCalled(); |
| } |
| |
| @Override |
| public void onPageLoadFinished(Tab tab, String url) { |
| mFinishCallback.notifyCalled(); |
| } |
| |
| @Override |
| public void onDestroyed(Tab tab) { |
| // A new tab is destroyed when loading is overridden while opening it. |
| mDestroyedCallback.notifyCalled(); |
| } |
| } |
| |
| private ActivityMonitor mActivityMonitor; |
| private EmbeddedTestServer mTestServer; |
| |
| @Before |
| public void setUp() throws Exception { |
| IntentFilter filter = new IntentFilter(Intent.ACTION_VIEW); |
| filter.addCategory(Intent.CATEGORY_BROWSABLE); |
| filter.addDataScheme("market"); |
| mActivityMonitor = InstrumentationRegistry.getInstrumentation().addMonitor( |
| filter, new Instrumentation.ActivityResult(Activity.RESULT_OK, null), true); |
| mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); |
| } |
| |
| @After |
| public void tearDown() { |
| mTestServer.stopAndDestroyServer(); |
| } |
| |
| private void loadUrlAndWaitForIntentUrl( |
| final String url, boolean needClick, boolean shouldLaunchExternalIntent) { |
| loadUrlAndWaitForIntentUrl(url, needClick, false, shouldLaunchExternalIntent, url, true); |
| } |
| |
| private void loadUrlAndWaitForIntentUrl(final String url, boolean needClick, |
| boolean createsNewTab, final boolean shouldLaunchExternalIntent, |
| final String expectedFinalUrl, final boolean shouldFailNavigation) { |
| loadUrlAndWaitForIntentUrl(url, needClick, createsNewTab, shouldLaunchExternalIntent, |
| expectedFinalUrl, shouldFailNavigation, null); |
| } |
| |
| private void loadUrlAndWaitForIntentUrl(final String url, boolean needClick, |
| boolean createsNewTab, final boolean shouldLaunchExternalIntent, |
| final String expectedFinalUrl, final boolean shouldFailNavigation, |
| String clickTargetId) { |
| final CallbackHelper finishCallback = new CallbackHelper(); |
| final CallbackHelper failCallback = new CallbackHelper(); |
| final CallbackHelper destroyedCallback = new CallbackHelper(); |
| final CallbackHelper newTabCallback = new CallbackHelper(); |
| |
| final Tab tab = mActivityTestRule.getActivity().getActivityTab(); |
| final Tab[] latestTabHolder = new Tab[1]; |
| final InterceptNavigationDelegateImpl[] latestDelegateHolder = |
| new InterceptNavigationDelegateImpl[1]; |
| latestTabHolder[0] = tab; |
| latestDelegateHolder[0] = getInterceptNavigationDelegate(tab); |
| tab.addObserver(new TestTabObserver(finishCallback, failCallback, destroyedCallback)); |
| if (createsNewTab) { |
| mActivityTestRule.getActivity().getTabModelSelector().addObserver( |
| new EmptyTabModelSelectorObserver() { |
| @Override |
| public void onNewTabCreated( |
| Tab newTab, @TabCreationState int creationState) { |
| newTabCallback.notifyCalled(); |
| newTab.addObserver(new TestTabObserver( |
| finishCallback, failCallback, destroyedCallback)); |
| latestTabHolder[0] = newTab; |
| latestDelegateHolder[0] = getInterceptNavigationDelegate(newTab); |
| } |
| }); |
| } |
| |
| mActivityTestRule.getActivity().onUserInteraction(); |
| InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { |
| @Override |
| public void run() { |
| tab.loadUrl(new LoadUrlParams(url, PageTransition.LINK)); |
| } |
| }); |
| |
| if (finishCallback.getCallCount() == 0) { |
| try { |
| finishCallback.waitForCallback(0, 1, 20, TimeUnit.SECONDS); |
| } catch (TimeoutException ex) { |
| Assert.fail(); |
| return; |
| } |
| } |
| |
| SystemClock.sleep(1); |
| mActivityTestRule.getActivity().onUserInteraction(); |
| if (needClick) { |
| if (clickTargetId == null) { |
| TouchCommon.singleClickView(tab.getView()); |
| } else { |
| try { |
| DOMUtils.clickNode(mActivityTestRule.getWebContents(), clickTargetId); |
| } catch (TimeoutException e) { |
| Assert.fail("Failed to click on the target node."); |
| return; |
| } |
| } |
| } |
| |
| if (shouldFailNavigation) { |
| try { |
| failCallback.waitForCallback(0, 1, 20, TimeUnit.SECONDS); |
| } catch (TimeoutException ex) { |
| Assert.fail("Haven't received navigation failure of intents."); |
| return; |
| } |
| } |
| |
| if (createsNewTab) { |
| try { |
| destroyedCallback.waitForCallback(0, 1, 20, TimeUnit.SECONDS); |
| } catch (TimeoutException ex) { |
| Assert.fail("Intercepted new tab wasn't destroyed."); |
| return; |
| } |
| } |
| |
| boolean hasFallbackUrl = |
| expectedFinalUrl != null && !TextUtils.equals(url, expectedFinalUrl); |
| |
| if (hasFallbackUrl) { |
| if (finishCallback.getCallCount() == 1) { |
| try { |
| finishCallback.waitForCallback(1, 1, 20, TimeUnit.SECONDS); |
| } catch (TimeoutException ex) { |
| Assert.fail("Fallback URL is not loaded"); |
| return; |
| } |
| } |
| } |
| |
| Assert.assertEquals(createsNewTab ? 1 : 0, newTabCallback.getCallCount()); |
| // For sub frames, the |loadFailCallback| run through different threads |
| // from the ExternalNavigationHandler. As a result, there is no guarantee |
| // when url override result would come. |
| CriteriaHelper.pollUiThread(() -> { |
| // Note that we do not distinguish between OVERRIDE_WITH_CLOBBERING_TAB |
| // and NO_OVERRIDE since tab clobbering will eventually lead to NO_OVERRIDE. |
| // in the tab. Rather, we check the final URL to distinguish between |
| // fallback and normal navigation. See crbug.com/487364 for more. |
| Tab latestTab = latestTabHolder[0]; |
| InterceptNavigationDelegateImpl delegate = latestDelegateHolder[0]; |
| if (shouldLaunchExternalIntent) { |
| Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultTypeForTests(), |
| Matchers.is(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT)); |
| } else { |
| Criteria.checkThat(delegate.getLastOverrideUrlLoadingResultTypeForTests(), |
| Matchers.not(OverrideUrlLoadingResultType.OVERRIDE_WITH_EXTERNAL_INTENT)); |
| } |
| if (expectedFinalUrl == null) return; |
| Criteria.checkThat(latestTab.getUrlString(), Matchers.is(expectedFinalUrl)); |
| }); |
| |
| CriteriaHelper.pollUiThread(() -> { |
| Criteria.checkThat( |
| mActivityMonitor.getHits(), Matchers.is(shouldLaunchExternalIntent ? 1 : 0)); |
| }); |
| Assert.assertEquals(1 + (hasFallbackUrl ? 1 : 0), finishCallback.getCallCount()); |
| |
| Assert.assertEquals(failCallback.getCallCount(), shouldFailNavigation ? 1 : 0); |
| } |
| |
| private static InterceptNavigationDelegateImpl getInterceptNavigationDelegate(Tab tab) { |
| return TestThreadUtils.runOnUiThreadBlockingNoException( |
| () -> InterceptNavigationDelegateTabHelper.get(tab)); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromTimer() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl(mTestServer.getURL(NAVIGATION_FROM_TIMEOUT_PAGE), false, false); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromTimerInSubFrame() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_TIMEOUT_PARENT_FRAME_PAGE), false, false); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromUserGesture() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PAGE), true, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromUserGestureInSubFrame() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_USER_GESTURE_PARENT_FRAME_PAGE), true, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromXHRCallback() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PAGE), true, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromXHRCallbackInSubFrame() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_PARENT_FRAME_PAGE), true, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromXHRCallbackAndShortTimeout() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_SHORT_TIMEOUT_PAGE), true, |
| true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationFromXHRCallbackAndLongTimeout() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(NAVIGATION_FROM_XHR_CALLBACK_AND_LONG_TIMEOUT_PAGE), true, |
| false); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationWithFallbackURL() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| String fallbackUrl = mTestServer.getURL(FALLBACK_LANDING_PATH); |
| String originalUrl = mTestServer.getURL(NAVIGATION_WITH_FALLBACK_URL_PAGE + "?replace_text=" |
| + Base64.encodeToString( |
| ApiCompatibilityUtils.getBytesUtf8("PARAM_FALLBACK_URL"), Base64.URL_SAFE) |
| + ":" |
| + Base64.encodeToString( |
| ApiCompatibilityUtils.getBytesUtf8(fallbackUrl), Base64.URL_SAFE)); |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, fallbackUrl, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testNavigationWithFallbackURLInSubFrame() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| // The replace_text parameters for NAVIGATION_WITH_FALLBACK_URL_PAGE, which is loaded in |
| // the iframe in NAVIGATION_WITH_FALLBACK_URL_PARENT_FRAME_PAGE, have to go through the |
| // embedded test server twice and, as such, have to be base64-encoded twice. |
| String fallbackUrl = mTestServer.getURL(FALLBACK_LANDING_PATH); |
| byte[] paramBase64Name = ApiCompatibilityUtils.getBytesUtf8("PARAM_BASE64_NAME"); |
| byte[] base64ParamFallbackUrl = Base64.encode( |
| ApiCompatibilityUtils.getBytesUtf8("PARAM_FALLBACK_URL"), Base64.URL_SAFE); |
| byte[] paramBase64Value = ApiCompatibilityUtils.getBytesUtf8("PARAM_BASE64_VALUE"); |
| byte[] base64FallbackUrl = |
| Base64.encode(ApiCompatibilityUtils.getBytesUtf8(fallbackUrl), Base64.URL_SAFE); |
| |
| String originalUrl = mTestServer.getURL( |
| NAVIGATION_WITH_FALLBACK_URL_PARENT_FRAME_PAGE |
| + "?replace_text=" |
| + Base64.encodeToString(paramBase64Name, Base64.URL_SAFE) + ":" |
| + Base64.encodeToString(base64ParamFallbackUrl, Base64.URL_SAFE) |
| + "&replace_text=" |
| + Base64.encodeToString(paramBase64Value, Base64.URL_SAFE) + ":" |
| + Base64.encodeToString(base64FallbackUrl, Base64.URL_SAFE)); |
| |
| // Fallback URL from a subframe will not trigger main or sub frame navigation. |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false); |
| } |
| |
| @Test |
| @SmallTest |
| public void testOpenWindowFromUserGesture() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl(mTestServer.getURL(OPEN_WINDOW_FROM_USER_GESTURE_PAGE), true, |
| true, true, null, true); |
| } |
| |
| @Test |
| @SmallTest |
| public void testOpenWindowFromLinkUserGesture() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl(mTestServer.getURL(OPEN_WINDOW_FROM_LINK_USER_GESTURE_PAGE), |
| true, true, true, null, true, "link"); |
| } |
| |
| @Test |
| @SmallTest |
| public void testOpenWindowFromSvgUserGesture() { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl(mTestServer.getURL(OPEN_WINDOW_FROM_SVG_USER_GESTURE_PAGE), true, |
| true, true, null, true, "link"); |
| } |
| |
| @Test |
| @SmallTest |
| public void testRedirectionFromIntentCold() throws Exception { |
| Context context = ContextUtils.getApplicationContext(); |
| Intent intent = new Intent(Intent.ACTION_VIEW, |
| Uri.parse(mTestServer.getURL(NAVIGATION_FROM_JAVA_REDIRECTION_PAGE))); |
| intent.setClassName(context, ChromeLauncherActivity.class.getName()); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| |
| ChromeTabbedActivity activity = ApplicationTestUtils.waitForActivityWithClass( |
| ChromeTabbedActivity.class, Stage.CREATED, () -> context.startActivity(intent)); |
| mActivityTestRule.setActivity(activity); |
| |
| CriteriaHelper.pollUiThread(() -> { |
| Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(1)); |
| }, ScalableTimeout.scaleTimeout(10000L), CriteriaHelper.DEFAULT_POLLING_INTERVAL); |
| ApplicationTestUtils.waitForActivityState(activity, Stage.STOPPED); |
| } |
| |
| @Test |
| @SmallTest |
| public void testRedirectionFromIntentWarm() throws Exception { |
| Context context = ContextUtils.getApplicationContext(); |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| Intent intent = new Intent(Intent.ACTION_VIEW, |
| Uri.parse(mTestServer.getURL(NAVIGATION_FROM_JAVA_REDIRECTION_PAGE))); |
| intent.setClassName(context, ChromeLauncherActivity.class.getName()); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| context.startActivity(intent); |
| |
| CriteriaHelper.pollUiThread( |
| () -> Criteria.checkThat(mActivityMonitor.getHits(), Matchers.is(1))); |
| } |
| |
| @Test |
| @LargeTest |
| public void testCCTRedirectFromIntentUriStaysInChrome_InIncognito() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| // This will make the mActivityTestRule.getActivity().getActivityTab() used in the method |
| // loadUrlAndWaitForIntentUrl to return an incognito tab instead. |
| mActivityTestRule.loadUrlInNewTab("chrome://about/", /**incognito**/ true); |
| |
| String fallbackUrl = mTestServer.getURL(FALLBACK_LANDING_PATH); |
| String fallbackUrlWithoutScheme = fallbackUrl.replace("http://", ""); |
| String originalUrl = mTestServer.getURL(NAVIGATION_TO_CCT_FROM_INTENT_URI + "?replace_text=" |
| + Base64.encodeToString( |
| ApiCompatibilityUtils.getBytesUtf8("PARAM_FALLBACK_URL"), Base64.URL_SAFE) |
| + ":" |
| + Base64.encodeToString( |
| ApiCompatibilityUtils.getBytesUtf8(fallbackUrlWithoutScheme), |
| Base64.URL_SAFE)); |
| |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, fallbackUrl, true); |
| } |
| |
| @Test |
| @LargeTest |
| public void testIntentURIWithFileSchemeDoesNothing() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| String originalUrl = mTestServer.getURL(NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI); |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, null, false, "scheme_file"); |
| } |
| |
| @Test |
| @LargeTest |
| public void testIntentURIWithMixedCaseFileSchemeDoesNothing() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| String originalUrl = mTestServer.getURL(NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI); |
| loadUrlAndWaitForIntentUrl( |
| originalUrl, true, false, false, null, false, "scheme_mixed_case_file"); |
| } |
| |
| @Test |
| @LargeTest |
| public void testIntentURIWithNoSchemeDoesNothing() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| String originalUrl = mTestServer.getURL(NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI); |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, null, false, "null_scheme"); |
| } |
| @Test |
| @LargeTest |
| public void testIntentURIWithEmptySchemeDoesNothing() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| String originalUrl = mTestServer.getURL(NAVIGATION_TO_FILE_SCHEME_FROM_INTENT_URI); |
| loadUrlAndWaitForIntentUrl(originalUrl, true, false, false, null, false, "empty_scheme"); |
| } |
| |
| @Test |
| @LargeTest |
| public void testSubframeLoadCannotLaunchPlayApp() throws TimeoutException { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| loadUrlAndWaitForIntentUrl( |
| mTestServer.getURL(SUBFRAME_REDIRECT_WITH_PLAY_FALLBACK), false, false); |
| } |
| } |