1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.webkit.cts; 18 19 import android.cts.util.EvaluateJsResultPollingCheck; 20 import android.cts.util.NullWebViewUtils; 21 import android.cts.util.PollingCheck; 22 import android.graphics.Bitmap; 23 import android.os.Message; 24 import android.test.ActivityInstrumentationTestCase2; 25 import android.view.KeyEvent; 26 import android.view.ViewGroup; 27 import android.webkit.HttpAuthHandler; 28 import android.webkit.ValueCallback; 29 import android.webkit.WebChromeClient; 30 import android.webkit.WebResourceRequest; 31 import android.webkit.WebResourceResponse; 32 import android.webkit.WebSettings; 33 import android.webkit.WebView; 34 import android.webkit.WebViewClient; 35 import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient; 36 37 import java.io.ByteArrayInputStream; 38 import java.nio.charset.StandardCharsets; 39 import java.util.HashMap; 40 import java.util.Map; 41 42 public class WebViewClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> { 43 private static final long TEST_TIMEOUT = 5000; 44 private static final String TEST_URL = "http://foo.com/"; 45 46 private WebViewOnUiThread mOnUiThread; 47 private CtsTestServer mWebServer; 48 WebViewClientTest()49 public WebViewClientTest() { 50 super("com.android.cts.webkit", WebViewCtsActivity.class); 51 } 52 53 @Override setUp()54 protected void setUp() throws Exception { 55 super.setUp(); 56 final WebViewCtsActivity activity = getActivity(); 57 WebView webview = activity.getWebView(); 58 if (webview != null) { 59 new PollingCheck(TEST_TIMEOUT) { 60 @Override 61 protected boolean check() { 62 return activity.hasWindowFocus(); 63 } 64 }.run(); 65 66 mOnUiThread = new WebViewOnUiThread(this, webview); 67 } 68 } 69 70 @Override tearDown()71 protected void tearDown() throws Exception { 72 if (mOnUiThread != null) { 73 mOnUiThread.cleanUp(); 74 } 75 if (mWebServer != null) { 76 mWebServer.shutdown(); 77 } 78 super.tearDown(); 79 } 80 81 // Verify that the shouldoverrideurlloading is false by default testShouldOverrideUrlLoadingDefault()82 public void testShouldOverrideUrlLoadingDefault() { 83 if (!NullWebViewUtils.isWebViewAvailable()) { 84 return; 85 } 86 final WebViewClient webViewClient = new WebViewClient(); 87 assertFalse(webViewClient.shouldOverrideUrlLoading(mOnUiThread.getWebView(), null)); 88 } 89 90 // Verify shouldoverrideurlloading called on top level navigation testShouldOverrideUrlLoading()91 public void testShouldOverrideUrlLoading() { 92 if (!NullWebViewUtils.isWebViewAvailable()) { 93 return; 94 } 95 final MockWebViewClient webViewClient = new MockWebViewClient(); 96 mOnUiThread.setWebViewClient(webViewClient); 97 mOnUiThread.getSettings().setJavaScriptEnabled(true); 98 String data = "<html><body>" + 99 "<a href=\"" + TEST_URL + "\" id=\"link\">new page</a>" + 100 "</body></html>"; 101 mOnUiThread.loadDataAndWaitForCompletion(data, "text/html", null); 102 clickOnLinkUsingJs("link", mOnUiThread); 103 assertEquals(TEST_URL, webViewClient.getLastShouldOverrideUrl()); 104 } 105 106 // Verify shouldoverrideurlloading called on webview called via onCreateWindow 107 // TODO(sgurun) upstream this test to Aw. testShouldOverrideUrlLoadingOnCreateWindow()108 public void testShouldOverrideUrlLoadingOnCreateWindow() throws Exception { 109 if (!NullWebViewUtils.isWebViewAvailable()) { 110 return; 111 } 112 mWebServer = new CtsTestServer(getActivity()); 113 // WebViewClient for main window 114 final MockWebViewClient mainWebViewClient = new MockWebViewClient(); 115 // WebViewClient for child window 116 final MockWebViewClient childWebViewClient = new MockWebViewClient(); 117 mOnUiThread.setWebViewClient(mainWebViewClient); 118 mOnUiThread.getSettings().setJavaScriptEnabled(true); 119 mOnUiThread.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 120 mOnUiThread.getSettings().setSupportMultipleWindows(true); 121 122 final WebView childWebView = mOnUiThread.createWebView(); 123 124 mOnUiThread.setWebChromeClient(new WebChromeClient() { 125 @Override 126 public boolean onCreateWindow( 127 WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { 128 WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; 129 childWebView.setWebViewClient(childWebViewClient); 130 childWebView.getSettings().setJavaScriptEnabled(true); 131 transport.setWebView(childWebView); 132 getActivity().addContentView(childWebView, new ViewGroup.LayoutParams( 133 ViewGroup.LayoutParams.FILL_PARENT, 134 ViewGroup.LayoutParams.WRAP_CONTENT)); 135 resultMsg.sendToTarget(); 136 return true; 137 } 138 }); 139 mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.BLANK_TAG_URL)); 140 141 new PollingCheck(TEST_TIMEOUT) { 142 @Override 143 protected boolean check() { 144 return childWebViewClient.hasOnPageFinishedCalled(); 145 } 146 }.run(); 147 assertEquals(mWebServer.getAssetUrl(TestHtmlConstants.PAGE_WITH_LINK_URL), 148 childWebViewClient.getLastShouldOverrideUrl()); 149 150 // Now test a navigation within the page 151 //TODO(hush) Enable this portion when b/12804986 is fixed. 152 /* 153 WebViewOnUiThread childWebViewOnUiThread = new WebViewOnUiThread(this, childWebView); 154 final int childCallCount = childWebViewClient.getShouldOverrideUrlLoadingCallCount(); 155 final int mainCallCount = mainWebViewClient.getShouldOverrideUrlLoadingCallCount(); 156 clickOnLinkUsingJs("link", childWebViewOnUiThread); 157 new PollingCheck(TEST_TIMEOUT) { 158 @Override 159 protected boolean check() { 160 return childWebViewClient.getShouldOverrideUrlLoadingCallCount() > childCallCount; 161 } 162 }.run(); 163 assertEquals(mainCallCount, mainWebViewClient.getShouldOverrideUrlLoadingCallCount()); 164 assertEquals(TEST_URL, childWebViewClient.getLastShouldOverrideUrl()); 165 */ 166 } 167 clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread)168 private void clickOnLinkUsingJs(final String linkId, WebViewOnUiThread webViewOnUiThread) { 169 EvaluateJsResultPollingCheck jsResult = new EvaluateJsResultPollingCheck("null"); 170 webViewOnUiThread.evaluateJavascript( 171 "document.getElementById('" + linkId + "').click();" + 172 "console.log('element with id [" + linkId + "] clicked');", jsResult); 173 jsResult.run(); 174 } 175 testLoadPage()176 public void testLoadPage() throws Exception { 177 if (!NullWebViewUtils.isWebViewAvailable()) { 178 return; 179 } 180 final MockWebViewClient webViewClient = new MockWebViewClient(); 181 mOnUiThread.setWebViewClient(webViewClient); 182 mWebServer = new CtsTestServer(getActivity()); 183 String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL); 184 185 assertFalse(webViewClient.hasOnPageStartedCalled()); 186 assertFalse(webViewClient.hasOnLoadResourceCalled()); 187 assertFalse(webViewClient.hasOnPageFinishedCalled()); 188 mOnUiThread.loadUrlAndWaitForCompletion(url); 189 190 new PollingCheck(TEST_TIMEOUT) { 191 @Override 192 protected boolean check() { 193 return webViewClient.hasOnPageStartedCalled(); 194 } 195 }.run(); 196 197 new PollingCheck(TEST_TIMEOUT) { 198 @Override 199 protected boolean check() { 200 return webViewClient.hasOnLoadResourceCalled(); 201 } 202 }.run(); 203 204 new PollingCheck(TEST_TIMEOUT) { 205 @Override 206 protected boolean check() { 207 return webViewClient.hasOnPageFinishedCalled(); 208 } 209 }.run(); 210 } 211 testOnReceivedError()212 public void testOnReceivedError() throws Exception { 213 if (!NullWebViewUtils.isWebViewAvailable()) { 214 return; 215 } 216 final MockWebViewClient webViewClient = new MockWebViewClient(); 217 mOnUiThread.setWebViewClient(webViewClient); 218 219 String wrongUri = "invalidscheme://some/resource"; 220 assertEquals(0, webViewClient.hasOnReceivedErrorCode()); 221 mOnUiThread.loadUrlAndWaitForCompletion(wrongUri); 222 assertEquals(WebViewClient.ERROR_UNSUPPORTED_SCHEME, 223 webViewClient.hasOnReceivedErrorCode()); 224 } 225 testOnFormResubmission()226 public void testOnFormResubmission() throws Exception { 227 if (!NullWebViewUtils.isWebViewAvailable()) { 228 return; 229 } 230 final MockWebViewClient webViewClient = new MockWebViewClient(); 231 mOnUiThread.setWebViewClient(webViewClient); 232 final WebSettings settings = mOnUiThread.getSettings(); 233 settings.setJavaScriptEnabled(true); 234 mWebServer = new CtsTestServer(getActivity()); 235 236 assertFalse(webViewClient.hasOnFormResubmissionCalled()); 237 String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_FORM_URL); 238 // this loads a form, which automatically posts itself 239 mOnUiThread.loadUrlAndWaitForCompletion(url); 240 // wait for JavaScript to post the form 241 mOnUiThread.waitForLoadCompletion(); 242 // the URL should have changed when the form was posted 243 assertFalse(url.equals(mOnUiThread.getUrl())); 244 // reloading the current URL should trigger the callback 245 mOnUiThread.reload(); 246 new PollingCheck(TEST_TIMEOUT) { 247 @Override 248 protected boolean check() { 249 return webViewClient.hasOnFormResubmissionCalled(); 250 } 251 }.run(); 252 } 253 testDoUpdateVisitedHistory()254 public void testDoUpdateVisitedHistory() throws Exception { 255 if (!NullWebViewUtils.isWebViewAvailable()) { 256 return; 257 } 258 final MockWebViewClient webViewClient = new MockWebViewClient(); 259 mOnUiThread.setWebViewClient(webViewClient); 260 mWebServer = new CtsTestServer(getActivity()); 261 262 assertFalse(webViewClient.hasDoUpdateVisitedHistoryCalled()); 263 String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL); 264 String url2 = mWebServer.getAssetUrl(TestHtmlConstants.BR_TAG_URL); 265 mOnUiThread.loadUrlAndWaitForCompletion(url1); 266 mOnUiThread.loadUrlAndWaitForCompletion(url2); 267 new PollingCheck(TEST_TIMEOUT) { 268 @Override 269 protected boolean check() { 270 return webViewClient.hasDoUpdateVisitedHistoryCalled(); 271 } 272 }.run(); 273 } 274 testOnReceivedHttpAuthRequest()275 public void testOnReceivedHttpAuthRequest() throws Exception { 276 if (!NullWebViewUtils.isWebViewAvailable()) { 277 return; 278 } 279 final MockWebViewClient webViewClient = new MockWebViewClient(); 280 mOnUiThread.setWebViewClient(webViewClient); 281 mWebServer = new CtsTestServer(getActivity()); 282 283 assertFalse(webViewClient.hasOnReceivedHttpAuthRequestCalled()); 284 String url = mWebServer.getAuthAssetUrl(TestHtmlConstants.EMBEDDED_IMG_URL); 285 mOnUiThread.loadUrlAndWaitForCompletion(url); 286 assertTrue(webViewClient.hasOnReceivedHttpAuthRequestCalled()); 287 } 288 testShouldOverrideKeyEvent()289 public void testShouldOverrideKeyEvent() { 290 if (!NullWebViewUtils.isWebViewAvailable()) { 291 return; 292 } 293 final MockWebViewClient webViewClient = new MockWebViewClient(); 294 mOnUiThread.setWebViewClient(webViewClient); 295 296 assertFalse(webViewClient.shouldOverrideKeyEvent(mOnUiThread.getWebView(), null)); 297 } 298 testOnUnhandledKeyEvent()299 public void testOnUnhandledKeyEvent() throws Throwable { 300 if (!NullWebViewUtils.isWebViewAvailable()) { 301 return; 302 } 303 requireLoadedPage(); 304 final MockWebViewClient webViewClient = new MockWebViewClient(); 305 mOnUiThread.setWebViewClient(webViewClient); 306 307 mOnUiThread.requestFocus(); 308 getInstrumentation().waitForIdleSync(); 309 310 assertFalse(webViewClient.hasOnUnhandledKeyEventCalled()); 311 sendKeys(KeyEvent.KEYCODE_1); 312 313 new PollingCheck(TEST_TIMEOUT) { 314 @Override 315 protected boolean check() { 316 return webViewClient.hasOnUnhandledKeyEventCalled(); 317 } 318 }.run(); 319 } 320 testOnScaleChanged()321 public void testOnScaleChanged() throws Throwable { 322 if (!NullWebViewUtils.isWebViewAvailable()) { 323 return; 324 } 325 final MockWebViewClient webViewClient = new MockWebViewClient(); 326 mOnUiThread.setWebViewClient(webViewClient); 327 mWebServer = new CtsTestServer(getActivity()); 328 329 assertFalse(webViewClient.hasOnScaleChangedCalled()); 330 String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL); 331 mOnUiThread.loadUrlAndWaitForCompletion(url1); 332 333 new PollingCheck(TEST_TIMEOUT) { 334 @Override 335 protected boolean check() { 336 return mOnUiThread.canZoomIn(); 337 } 338 }.run(); 339 340 assertTrue(mOnUiThread.zoomIn()); 341 new PollingCheck(TEST_TIMEOUT) { 342 @Override 343 protected boolean check() { 344 return webViewClient.hasOnScaleChangedCalled(); 345 } 346 }.run(); 347 } 348 349 // Test that shouldInterceptRequest is called with the correct parameters testShouldInterceptRequestParams()350 public void testShouldInterceptRequestParams() throws Throwable { 351 if (!NullWebViewUtils.isWebViewAvailable()) { 352 return; 353 } 354 355 final String mainPath = "/main"; 356 final String mainPage = "<head></head><body>test page</body>"; 357 final String headerName = "x-test-header-name"; 358 final String headerValue = "testheadervalue"; 359 HashMap<String, String> headers = new HashMap<String, String>(1); 360 headers.put(headerName, headerValue); 361 362 // A client which saves the WebResourceRequest as interceptRequest 363 final class TestClient extends WaitForLoadedClient { 364 public TestClient() { 365 super(mOnUiThread); 366 } 367 368 @Override 369 public WebResourceResponse shouldInterceptRequest(WebView view, 370 WebResourceRequest request) { 371 assertNotNull(view); 372 assertNotNull(request); 373 374 assertEquals(view, mOnUiThread.getWebView()); 375 376 // Save the main page request; discard any other requests (e.g. for favicon.ico) 377 if (request.getUrl().getPath().equals(mainPath)) { 378 assertNull(interceptRequest); 379 interceptRequest = request; 380 } 381 382 return null; 383 } 384 385 public volatile WebResourceRequest interceptRequest; 386 } 387 388 TestClient client = new TestClient(); 389 mOnUiThread.setWebViewClient(client); 390 391 TestWebServer server = new TestWebServer(false); 392 try { 393 String mainUrl = server.setResponse(mainPath, mainPage, null); 394 395 mOnUiThread.loadUrlAndWaitForCompletion(mainUrl, headers); 396 397 // Inspect the fields of the saved WebResourceRequest 398 assertNotNull(client.interceptRequest); 399 assertEquals(mainUrl, client.interceptRequest.getUrl().toString()); 400 assertTrue(client.interceptRequest.isForMainFrame()); 401 assertEquals(server.getLastRequest(mainPath).getRequestLine().getMethod(), 402 client.interceptRequest.getMethod()); 403 404 // Web request headers are case-insensitive. We provided lower-case headerName and 405 // headerValue. This will pass implementations which either do not mangle case, 406 // convert to lowercase, or convert to uppercase but return a case-insensitive map. 407 Map<String, String> interceptHeaders = client.interceptRequest.getRequestHeaders(); 408 assertTrue(interceptHeaders.containsKey(headerName)); 409 assertEquals(headerValue, interceptHeaders.get(headerName)); 410 } finally { 411 server.shutdown(); 412 } 413 } 414 415 // Test that the WebResourceResponse returned by shouldInterceptRequest is handled correctly testShouldInterceptRequestResponse()416 public void testShouldInterceptRequestResponse() throws Throwable { 417 if (!NullWebViewUtils.isWebViewAvailable()) { 418 return; 419 } 420 421 final String mainPath = "/main"; 422 final String mainPage = "<head></head><body>test page</body>"; 423 final String interceptPath = "/intercept_me"; 424 425 // A client which responds to requests for interceptPath with a saved interceptResponse 426 final class TestClient extends WaitForLoadedClient { 427 public TestClient() { 428 super(mOnUiThread); 429 } 430 431 @Override 432 public WebResourceResponse shouldInterceptRequest(WebView view, 433 WebResourceRequest request) { 434 if (request.getUrl().toString().contains(interceptPath)) { 435 assertNotNull(interceptResponse); 436 return interceptResponse; 437 } 438 439 return null; 440 } 441 442 volatile public WebResourceResponse interceptResponse; 443 } 444 445 mOnUiThread.getSettings().setJavaScriptEnabled(true); 446 447 TestClient client = new TestClient(); 448 mOnUiThread.setWebViewClient(client); 449 450 TestWebServer server = new TestWebServer(false); 451 try { 452 String interceptUrl = server.getResponseUrl(interceptPath); 453 454 // JavaScript which makes a synchronous AJAX request and logs and returns the status 455 String js = 456 "(function() {" + 457 " var xhr = new XMLHttpRequest();" + 458 " xhr.open('GET', '" + interceptUrl + "', false);" + 459 " xhr.send(null);" + 460 " console.info('xhr.status = ' + xhr.status);" + 461 " console.info('xhr.statusText = ' + xhr.statusText);" + 462 " return '[' + xhr.status + '][' + xhr.statusText + ']';" + 463 "})();"; 464 465 String mainUrl = server.setResponse(mainPath, mainPage, null); 466 mOnUiThread.loadUrlAndWaitForCompletion(mainUrl, null); 467 468 EvaluateJsResultPollingCheck jsResult; 469 470 // Test a nonexistent page 471 client.interceptResponse = new WebResourceResponse("text/html", "UTF-8", null); 472 jsResult = new EvaluateJsResultPollingCheck("\"[404][Not Found]\""); 473 mOnUiThread.evaluateJavascript(js, jsResult); 474 jsResult.run(); 475 476 // Test an empty page 477 client.interceptResponse = new WebResourceResponse("text/html", "UTF-8", 478 new ByteArrayInputStream(new byte[0])); 479 jsResult = new EvaluateJsResultPollingCheck("\"[200][OK]\""); 480 mOnUiThread.evaluateJavascript(js, jsResult); 481 jsResult.run(); 482 483 // Test a nonempty page with unusual response code/text 484 client.interceptResponse = 485 new WebResourceResponse("text/html", "UTF-8", 123, "unusual", null, 486 new ByteArrayInputStream("nonempty page".getBytes(StandardCharsets.UTF_8))); 487 jsResult = new EvaluateJsResultPollingCheck("\"[123][unusual]\""); 488 mOnUiThread.evaluateJavascript(js, jsResult); 489 jsResult.run(); 490 } finally { 491 server.shutdown(); 492 } 493 } 494 requireLoadedPage()495 private void requireLoadedPage() throws Throwable { 496 if (!NullWebViewUtils.isWebViewAvailable()) { 497 return; 498 } 499 mOnUiThread.loadUrlAndWaitForCompletion("about:blank"); 500 } 501 502 private class MockWebViewClient extends WaitForLoadedClient { 503 private boolean mOnPageStartedCalled; 504 private boolean mOnPageFinishedCalled; 505 private boolean mOnLoadResourceCalled; 506 private int mOnReceivedErrorCode; 507 private boolean mOnFormResubmissionCalled; 508 private boolean mDoUpdateVisitedHistoryCalled; 509 private boolean mOnReceivedHttpAuthRequestCalled; 510 private boolean mOnUnhandledKeyEventCalled; 511 private boolean mOnScaleChangedCalled; 512 private int mShouldOverrideUrlLoadingCallCount; 513 private String mLastShouldOverrideUrl; 514 MockWebViewClient()515 public MockWebViewClient() { 516 super(mOnUiThread); 517 } 518 hasOnPageStartedCalled()519 public boolean hasOnPageStartedCalled() { 520 return mOnPageStartedCalled; 521 } 522 hasOnPageFinishedCalled()523 public boolean hasOnPageFinishedCalled() { 524 return mOnPageFinishedCalled; 525 } 526 hasOnLoadResourceCalled()527 public boolean hasOnLoadResourceCalled() { 528 return mOnLoadResourceCalled; 529 } 530 hasOnReceivedErrorCode()531 public int hasOnReceivedErrorCode() { 532 return mOnReceivedErrorCode; 533 } 534 hasOnFormResubmissionCalled()535 public boolean hasOnFormResubmissionCalled() { 536 return mOnFormResubmissionCalled; 537 } 538 hasDoUpdateVisitedHistoryCalled()539 public boolean hasDoUpdateVisitedHistoryCalled() { 540 return mDoUpdateVisitedHistoryCalled; 541 } 542 hasOnReceivedHttpAuthRequestCalled()543 public boolean hasOnReceivedHttpAuthRequestCalled() { 544 return mOnReceivedHttpAuthRequestCalled; 545 } 546 hasOnUnhandledKeyEventCalled()547 public boolean hasOnUnhandledKeyEventCalled() { 548 return mOnUnhandledKeyEventCalled; 549 } 550 hasOnScaleChangedCalled()551 public boolean hasOnScaleChangedCalled() { 552 return mOnScaleChangedCalled; 553 } 554 getShouldOverrideUrlLoadingCallCount()555 public int getShouldOverrideUrlLoadingCallCount() { 556 return mShouldOverrideUrlLoadingCallCount; 557 } 558 getLastShouldOverrideUrl()559 public String getLastShouldOverrideUrl() { 560 return mLastShouldOverrideUrl; 561 } 562 563 @Override onPageStarted(WebView view, String url, Bitmap favicon)564 public void onPageStarted(WebView view, String url, Bitmap favicon) { 565 super.onPageStarted(view, url, favicon); 566 mOnPageStartedCalled = true; 567 } 568 569 @Override onPageFinished(WebView view, String url)570 public void onPageFinished(WebView view, String url) { 571 super.onPageFinished(view, url); 572 assertTrue(mOnPageStartedCalled); 573 assertTrue(mOnLoadResourceCalled); 574 mOnPageFinishedCalled = true; 575 } 576 577 @Override onLoadResource(WebView view, String url)578 public void onLoadResource(WebView view, String url) { 579 super.onLoadResource(view, url); 580 assertTrue(mOnPageStartedCalled); 581 mOnLoadResourceCalled = true; 582 } 583 584 @Override onReceivedError(WebView view, int errorCode, String description, String failingUrl)585 public void onReceivedError(WebView view, int errorCode, 586 String description, String failingUrl) { 587 super.onReceivedError(view, errorCode, description, failingUrl); 588 mOnReceivedErrorCode = errorCode; 589 } 590 591 @Override onFormResubmission(WebView view, Message dontResend, Message resend)592 public void onFormResubmission(WebView view, Message dontResend, Message resend) { 593 mOnFormResubmissionCalled = true; 594 dontResend.sendToTarget(); 595 } 596 597 @Override doUpdateVisitedHistory(WebView view, String url, boolean isReload)598 public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { 599 super.doUpdateVisitedHistory(view, url, isReload); 600 mDoUpdateVisitedHistoryCalled = true; 601 } 602 603 @Override onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)604 public void onReceivedHttpAuthRequest(WebView view, 605 HttpAuthHandler handler, String host, String realm) { 606 super.onReceivedHttpAuthRequest(view, handler, host, realm); 607 mOnReceivedHttpAuthRequestCalled = true; 608 } 609 610 @Override onUnhandledKeyEvent(WebView view, KeyEvent event)611 public void onUnhandledKeyEvent(WebView view, KeyEvent event) { 612 super.onUnhandledKeyEvent(view, event); 613 mOnUnhandledKeyEventCalled = true; 614 } 615 616 @Override onScaleChanged(WebView view, float oldScale, float newScale)617 public void onScaleChanged(WebView view, float oldScale, float newScale) { 618 super.onScaleChanged(view, oldScale, newScale); 619 mOnScaleChangedCalled = true; 620 } 621 622 @Override shouldOverrideUrlLoading(WebView view, String url)623 public boolean shouldOverrideUrlLoading(WebView view, String url) { 624 mLastShouldOverrideUrl = url; 625 mShouldOverrideUrlLoadingCallCount++; 626 return false; 627 } 628 } 629 } 630