Commit 1ebf6fa5 authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

WebLayer: add test for auto-reload after bg tab crash.

Bug: 1146058
Change-Id: Id8bbf7e0b964385016d74bf21d94874e5afa9883
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523103Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Evan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825460}
parent b0a112e7
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.content_public.browser.test.util; package org.chromium.content_public.browser.test.util;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.content.browser.input.SelectPopup; import org.chromium.content.browser.input.SelectPopup;
import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.content.browser.selection.SelectionPopupControllerImpl;
import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl;
...@@ -14,8 +15,10 @@ import org.chromium.content_public.browser.RenderFrameHost; ...@@ -14,8 +15,10 @@ import org.chromium.content_public.browser.RenderFrameHost;
import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.SelectionPopupController;
import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.ViewEventSink;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/** /**
* Collection of test-only WebContents utilities. * Collection of test-only WebContents utilities.
...@@ -134,9 +137,27 @@ public class WebContentsUtils { ...@@ -134,9 +137,27 @@ public class WebContentsUtils {
return controller.isActionModeSupported(); return controller.isActionModeSupported();
} }
/** Cause the renderer process for the given WebContents to crash. */
public static void crashTabAndWait(WebContents webContents) throws TimeoutException {
CallbackHelper callbackHelper = new CallbackHelper();
WebContentsObserver observer = new WebContentsObserver() {
@Override
public void renderProcessGone(boolean wasOoomProtected) {
callbackHelper.notifyCalled();
}
};
TestThreadUtils.runOnUiThreadBlocking(() -> {
webContents.addObserver(observer);
nativeCrashTab(webContents);
});
callbackHelper.waitForFirst();
TestThreadUtils.runOnUiThreadBlocking(() -> { webContents.removeObserver(observer); });
}
private static native void nativeReportAllFrameSubmissions( private static native void nativeReportAllFrameSubmissions(
WebContents webContents, boolean enabled); WebContents webContents, boolean enabled);
private static native RenderFrameHost nativeGetFocusedFrame(WebContents webContents); private static native RenderFrameHost nativeGetFocusedFrame(WebContents webContents);
private static native void nativeEvaluateJavaScriptWithUserGesture( private static native void nativeEvaluateJavaScriptWithUserGesture(
WebContents webContents, String script); WebContents webContents, String script);
private static native void nativeCrashTab(WebContents webContents);
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "content/browser/web_contents/web_contents_android.h" #include "content/browser/web_contents/web_contents_android.h"
#include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_frame_metadata_provider.h" #include "content/public/browser/render_frame_metadata_provider.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/test/android/content_test_jni/WebContentsUtils_jni.h" #include "content/public/test/android/content_test_jni/WebContentsUtils_jni.h"
...@@ -57,4 +58,11 @@ void JNI_WebContentsUtils_EvaluateJavaScriptWithUserGesture( ...@@ -57,4 +58,11 @@ void JNI_WebContentsUtils_EvaluateJavaScriptWithUserGesture(
ConvertJavaStringToUTF16(env, script)); ConvertJavaStringToUTF16(env, script));
} }
void JNI_WebContentsUtils_CrashTab(JNIEnv* env,
const JavaParamRef<jobject>& jweb_contents) {
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
WebContents::FromJavaWebContents(jweb_contents));
web_contents->GetMainFrame()->GetProcess()->Shutdown(RESULT_CODE_KILLED);
}
} // namespace content } // namespace content
...@@ -13,7 +13,13 @@ import org.junit.Rule; ...@@ -13,7 +13,13 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.weblayer.Browser;
import org.chromium.weblayer.Navigation;
import org.chromium.weblayer.NavigationCallback;
import org.chromium.weblayer.Tab;
import org.chromium.weblayer.TabCallback;
import org.chromium.weblayer.TestWebLayer; import org.chromium.weblayer.TestWebLayer;
import org.chromium.weblayer.shell.InstrumentationActivity; import org.chromium.weblayer.shell.InstrumentationActivity;
...@@ -43,4 +49,50 @@ public class TabPrivateTest { ...@@ -43,4 +49,50 @@ public class TabPrivateTest {
activity.getBrowser().createTab(); activity.getBrowser().createTab();
}); });
} }
@Test
@SmallTest
@MinWebLayerVersion(88)
public void testAutoReloadOnBackgroundCrash() throws Exception {
InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank");
activity.setIgnoreRendererCrashes();
CallbackHelper renderProcessGoneHelper = new CallbackHelper();
final Tab crashedTab = TestThreadUtils.runOnUiThreadBlocking(() -> {
Browser browser = activity.getBrowser();
Tab originalTab = browser.getActiveTab();
originalTab.registerTabCallback(new TabCallback() {
@Override
public void onRenderProcessGone() {
renderProcessGoneHelper.notifyCalled();
}
});
// Place a different tab in the foreground.
browser.setActiveTab(browser.createTab());
return originalTab;
});
// Crash the background tab.
getTestWebLayer().crashTab(crashedTab);
renderProcessGoneHelper.waitForFirst();
// Expect a navigation to occur when the crashed background tab is brought to the front.
// See logic in content's navigation_controller_impl.cc for why this is not classified as a
// reload.
CallbackHelper navigationCompletedHelper = new CallbackHelper();
TestThreadUtils.runOnUiThreadBlocking(() -> {
crashedTab.getNavigationController().registerNavigationCallback(
new NavigationCallback() {
@Override
public void onNavigationCompleted(Navigation navigation) {
navigationCompletedHelper.notifyCalled();
}
});
activity.getBrowser().setActiveTab(crashedTab);
});
navigationCompletedHelper.waitForFirst();
}
} }
...@@ -22,6 +22,7 @@ import org.chromium.components.media_router.MockMediaRouteProvider; ...@@ -22,6 +22,7 @@ import org.chromium.components.media_router.MockMediaRouteProvider;
import org.chromium.components.media_router.RouterTestUtils; import org.chromium.components.media_router.RouterTestUtils;
import org.chromium.components.permissions.PermissionDialogController; import org.chromium.components.permissions.PermissionDialogController;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.WebContentsUtils;
import org.chromium.device.geolocation.LocationProviderOverrider; import org.chromium.device.geolocation.LocationProviderOverrider;
import org.chromium.device.geolocation.MockLocationProvider; import org.chromium.device.geolocation.MockLocationProvider;
import org.chromium.net.NetworkChangeNotifier; import org.chromium.net.NetworkChangeNotifier;
...@@ -36,6 +37,7 @@ import org.chromium.weblayer_private.media.MediaRouteDialogFragmentImpl; ...@@ -36,6 +37,7 @@ import org.chromium.weblayer_private.media.MediaRouteDialogFragmentImpl;
import org.chromium.weblayer_private.test_interfaces.ITestWebLayer; import org.chromium.weblayer_private.test_interfaces.ITestWebLayer;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/** /**
* Root implementation class for TestWebLayer. * Root implementation class for TestWebLayer.
...@@ -226,4 +228,14 @@ public final class TestWebLayerImpl extends ITestWebLayer.Stub { ...@@ -226,4 +228,14 @@ public final class TestWebLayerImpl extends ITestWebLayer.Stub {
MediaRouteDialogFragmentImpl.getInstanceForTest().getSupportFragmentManager(); MediaRouteDialogFragmentImpl.getInstanceForTest().getSupportFragmentManager();
return ObjectWrapper.wrap(RouterTestUtils.waitForRouteButton(fm, name)); return ObjectWrapper.wrap(RouterTestUtils.waitForRouteButton(fm, name));
} }
@Override
public void crashTab(ITab tab) {
try {
TabImpl tabImpl = (TabImpl) tab;
WebContentsUtils.crashTabAndWait(tabImpl.getWebContents());
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
} }
...@@ -63,4 +63,7 @@ interface ITestWebLayer { ...@@ -63,4 +63,7 @@ interface ITestWebLayer {
// Gets a button from the currently visible media route selection dialog. The button represents a // Gets a button from the currently visible media route selection dialog. The button represents a
// route and contains the text |name|. Returns null if no such dialog or button exists. // route and contains the text |name|. Returns null if no such dialog or button exists.
IObjectWrapper /* View */ getMediaRouteButton(String name) = 19; IObjectWrapper /* View */ getMediaRouteButton(String name) = 19;
// Causes the renderer process in the tab's main frame to crash.
void crashTab(in ITab tab) = 20;
} }
...@@ -149,4 +149,8 @@ public final class TestWebLayer { ...@@ -149,4 +149,8 @@ public final class TestWebLayer {
public View getMediaRouteButton(String name) throws RemoteException { public View getMediaRouteButton(String name) throws RemoteException {
return (View) ObjectWrapper.unwrap(mITestWebLayer.getMediaRouteButton(name), View.class); return (View) ObjectWrapper.unwrap(mITestWebLayer.getMediaRouteButton(name), View.class);
} }
public void crashTab(Tab tab) throws RemoteException {
mITestWebLayer.crashTab(tab.getITab());
}
} }
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