Chromium Code Reviews| Index: android_webview/test/shell/src/org/chromium/android_webview/test/ShouldOverrideUrlLoadingJniCrashTestRunner.java |
| diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/ShouldOverrideUrlLoadingJniCrashTestRunner.java b/android_webview/test/shell/src/org/chromium/android_webview/test/ShouldOverrideUrlLoadingJniCrashTestRunner.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3e625cf7756e2a82629c6d4275450dcd8e6f6643 |
| --- /dev/null |
| +++ b/android_webview/test/shell/src/org/chromium/android_webview/test/ShouldOverrideUrlLoadingJniCrashTestRunner.java |
| @@ -0,0 +1,92 @@ |
| +// Copyright 2016 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.android_webview.test; |
| + |
| +import android.app.Service; |
| +import android.os.Message; |
| +import android.os.Messenger; |
| +import android.os.RemoteException; |
| + |
| +import org.chromium.android_webview.AwBrowserContext; |
| +import org.chromium.android_webview.AwContents; |
| +import org.chromium.android_webview.test.AwTestBaseUtility.TestDependencyFactory; |
| +import org.chromium.base.Log; |
| +import org.chromium.base.test.util.InMemorySharedPreferences; |
| + |
| +/** |
| + * Class containing code to be run in a service in a separate process to ensure a Java crash in |
| + * ShouldOverrideUrlLoading is propagated to the uncaughtExceptionHandler of the Service. |
| + */ |
| +public class ShouldOverrideUrlLoadingJniCrashTestRunner extends ServiceTestRunner { |
|
boliu
2016/09/15 04:57:53
ditto, can this live in JniCrashTest?
|
| + private static final String TAG = "SOULJniCrashTest"; |
| + public static final int RETURN_JNI_CRASH_TEST_SUCCESS = 1; |
| + public static final int RETURN_JNI_CRASH_TEST_FAILED = 2; |
| + |
| + /** |
| + * Ensure that when we navigate a WebView using a shouldOverrideUrlLoading callback that |
| + * throws a java exception, and ensure the exception is properly thrown (as opposed to |
| + * causing a native crash). |
| + */ |
| + @Override |
| + public void runTestOnMainThread(final Messenger testMessenger, Service service) { |
| + final Message successMessage = Message.obtain(null, RETURN_JNI_CRASH_TEST_SUCCESS); |
| + final Message failureMessage = Message.obtain(null, RETURN_JNI_CRASH_TEST_FAILED); |
| + Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { |
| + @Override |
| + public void uncaughtException(Thread t, Throwable e) { |
| + try { |
| + if (e instanceof MySpecialException) { |
| + testMessenger.send(successMessage); |
| + } else { |
| + Log.e(TAG, "Wrong exception thrown from shouldOverrideUrlLoading", e); |
| + testMessenger.send(failureMessage); |
| + } |
| + } catch (RemoteException re) { |
| + Log.e(TAG, "RemoteException in uncaughtExceptionHandler", re); |
| + } |
| + // We don't call the original uncaughtExceptionHandler here - instead we kill the |
|
Torne
2016/09/15 10:26:44
This will mean that the current thread dies, but t
boliu
2016/09/15 16:47:51
That was the original code. Then I assumed killing
gsennton
2016/09/15 17:08:35
Yeah, if the thread + process don't die while this
boliu
2016/09/15 17:13:12
You are talking about nested looper. And I have no
gsennton
2016/09/15 17:17:21
I don't see the connection between this case and a
boliu
2016/09/15 17:22:46
You can't block the thread and then wait for a eve
|
| + // service from the test when done (to ensure any messages sent from the service to |
| + // the test are received before the service is killed). |
| + } |
| + }); |
| + try { |
| + // Set up WebView and navigate on it to cause shouldOverrideUrlLoading to be called. |
| + AwTestBaseUtility.startBrowserProcess(service); |
| + } catch (Exception e) { |
| + try { |
| + testMessenger.send(failureMessage); |
| + } catch (RemoteException re) { |
| + Log.e(TAG, "RemoteException when trying to send fail message to test process", re); |
| + } |
| + return; |
| + } |
| + |
| + TestAwContentsClient contentsClient = new TestAwContentsClient() { |
| + @Override |
| + public boolean shouldOverrideUrlLoading(AwWebResourceRequest request) { |
| + throw new MySpecialException(); |
| + } |
| + }; |
| + |
| + // Create a WebView with a failing shouldOverrideUrlLoading callback |
| + AwBrowserContext browserContext = new AwBrowserContext( |
| + new InMemorySharedPreferences(), service.getApplicationContext()); |
| + AwTestContainerView testContainerView = AwTestBaseUtility.createDetachedAwTestContainerView( |
| + service, browserContext, new TestDependencyFactory(), contentsClient, |
| + false /* supportsLegacyQuirks */, true /* allowHardwareAcceleration */); |
| + AwContents awContents = testContainerView.getAwContents(); |
| + |
| + // Navigate -> causes shouldOverrideUrlLoading to be called |
| + awContents.getSettings().setJavaScriptEnabled(true); |
| + contentsClient.getOnEvaluateJavaScriptResultHelper().evaluateJavaScriptForTests( |
| + awContents.getWebContents(), "window.location.href = 'about:blank'"); |
| + } |
| + |
| + private static class MySpecialException extends RuntimeException { |
| + MySpecialException() { |
| + super(); |
| + } |
| + } |
| +} |