OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.content.browser; |
| 6 |
| 7 import android.util.Log; |
| 8 |
| 9 import org.junit.Assert; |
| 10 |
| 11 import org.chromium.base.annotations.SuppressFBWarnings; |
| 12 import org.chromium.base.test.util.UrlUtils; |
| 13 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; |
| 14 import org.chromium.content_public.browser.LoadUrlParams; |
| 15 import org.chromium.content_shell_apk.ContentShellActivity; |
| 16 import org.chromium.content_shell_apk.ContentShellActivityTestRule; |
| 17 |
| 18 import java.lang.annotation.Annotation; |
| 19 |
| 20 /** |
| 21 * ActivityTestRule with common functionality for testing the Java Bridge. |
| 22 */ |
| 23 public class JavaBridgeActivityTestRule extends ContentShellActivityTestRule { |
| 24 protected TestCallbackHelperContainer mTestCallbackHelperContainer; |
| 25 |
| 26 /** |
| 27 * Sets up the ContentView. Intended to be called from setUp(). |
| 28 */ |
| 29 private void setUpContentView() { |
| 30 // This starts the activity, so must be called on the test thread. |
| 31 final ContentShellActivity activity = launchContentShellWithUrl( |
| 32 UrlUtils.encodeHtmlDataUri("<html><head></head><body>test</body>
</html>")); |
| 33 |
| 34 waitForActiveShellToBeDoneLoading(); |
| 35 |
| 36 try { |
| 37 runOnUiThread(new Runnable() { |
| 38 @Override |
| 39 public void run() { |
| 40 mTestCallbackHelperContainer = |
| 41 new TestCallbackHelperContainer(activity.getActiveCo
ntentViewCore()); |
| 42 } |
| 43 }); |
| 44 } catch (Throwable e) { |
| 45 throw new RuntimeException( |
| 46 "Failed to set up ContentView: " + Log.getStackTraceString(e
)); |
| 47 } |
| 48 } |
| 49 |
| 50 @Override |
| 51 protected void beforeActivityLaunched() { |
| 52 super.beforeActivityLaunched(); |
| 53 setUpContentView(); |
| 54 } |
| 55 |
| 56 @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") |
| 57 protected class Controller { |
| 58 private static final int RESULT_WAIT_TIME = 5000; |
| 59 |
| 60 private boolean mIsResultReady; |
| 61 |
| 62 protected synchronized void notifyResultIsReady() { |
| 63 mIsResultReady = true; |
| 64 notify(); |
| 65 } |
| 66 |
| 67 protected synchronized void waitForResult() { |
| 68 while (!mIsResultReady) { |
| 69 try { |
| 70 wait(RESULT_WAIT_TIME); |
| 71 } catch (Exception e) { |
| 72 continue; |
| 73 } |
| 74 if (!mIsResultReady) { |
| 75 Assert.fail("Wait timed out"); |
| 76 } |
| 77 } |
| 78 mIsResultReady = false; |
| 79 } |
| 80 } |
| 81 |
| 82 public void executeJavaScript(final String script) throws Throwable { |
| 83 runOnUiThread(new Runnable() { |
| 84 @Override |
| 85 public void run() { |
| 86 // When a JavaScript URL is executed, if the value of the last |
| 87 // expression evaluated is not 'undefined', this value is |
| 88 // converted to a string and used as the new document for the |
| 89 // frame. We don't want this behaviour, so wrap the script in |
| 90 // an anonymous function. |
| 91 getWebContents().getNavigationController().loadUrl( |
| 92 new LoadUrlParams("javascript:(function() { " + script +
" })()")); |
| 93 } |
| 94 }); |
| 95 } |
| 96 |
| 97 public void injectObjectAndReload(final Object object, final String name) th
rows Exception { |
| 98 injectObjectAndReload(object, name, null); |
| 99 } |
| 100 |
| 101 public void injectObjectAndReload(final Object object, final String name, |
| 102 final Class<? extends Annotation> requiredAnnotation) throws Excepti
on { |
| 103 injectObjectsAndReload(object, name, null, null, requiredAnnotation); |
| 104 } |
| 105 |
| 106 public void injectObjectsAndReload(final Object object1, final String name1, |
| 107 final Object object2, final String name2, |
| 108 final Class<? extends Annotation> requiredAnnotation) throws Excepti
on { |
| 109 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = |
| 110 mTestCallbackHelperContainer.getOnPageFinishedHelper(); |
| 111 int currentCallCount = onPageFinishedHelper.getCallCount(); |
| 112 try { |
| 113 runOnUiThread(new Runnable() { |
| 114 @Override |
| 115 public void run() { |
| 116 getContentViewCore().addPossiblyUnsafeJavascriptInterface( |
| 117 object1, name1, requiredAnnotation); |
| 118 if (object2 != null && name2 != null) { |
| 119 getContentViewCore().addPossiblyUnsafeJavascriptInterfac
e( |
| 120 object2, name2, requiredAnnotation); |
| 121 } |
| 122 getContentViewCore().getWebContents().getNavigationControlle
r().reload(true); |
| 123 } |
| 124 }); |
| 125 onPageFinishedHelper.waitForCallback(currentCallCount); |
| 126 } catch (Throwable e) { |
| 127 throw new RuntimeException( |
| 128 "Failed to injectObjectsAndReload: " + Log.getStackTraceStri
ng(e)); |
| 129 } |
| 130 } |
| 131 |
| 132 public void synchronousPageReload() throws Throwable { |
| 133 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = |
| 134 mTestCallbackHelperContainer.getOnPageFinishedHelper(); |
| 135 int currentCallCount = onPageFinishedHelper.getCallCount(); |
| 136 runOnUiThread(new Runnable() { |
| 137 @Override |
| 138 public void run() { |
| 139 getContentViewCore().getWebContents().getNavigationController().
reload(true); |
| 140 } |
| 141 }); |
| 142 onPageFinishedHelper.waitForCallback(currentCallCount); |
| 143 } |
| 144 } |
OLD | NEW |