1 /* 2 * Copyright (C) 2006 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; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.FlaggedApi; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SystemApi; 25 import android.annotation.Widget; 26 import android.compat.annotation.UnsupportedAppUsage; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageInfo; 30 import android.content.res.Configuration; 31 import android.graphics.Bitmap; 32 import android.graphics.Canvas; 33 import android.graphics.Paint; 34 import android.graphics.Picture; 35 import android.graphics.Rect; 36 import android.graphics.drawable.Drawable; 37 import android.net.Uri; 38 import android.net.http.SslCertificate; 39 import android.os.Build; 40 import android.os.Bundle; 41 import android.os.Handler; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.os.RemoteException; 45 import android.os.StrictMode; 46 import android.print.PrintDocumentAdapter; 47 import android.util.AttributeSet; 48 import android.util.Log; 49 import android.util.LongSparseArray; 50 import android.util.SparseArray; 51 import android.view.DragEvent; 52 import android.view.KeyEvent; 53 import android.view.MotionEvent; 54 import android.view.PointerIcon; 55 import android.view.View; 56 import android.view.ViewDebug; 57 import android.view.ViewGroup; 58 import android.view.ViewHierarchyEncoder; 59 import android.view.ViewStructure; 60 import android.view.ViewTreeObserver; 61 import android.view.WindowInsets; 62 import android.view.accessibility.AccessibilityEvent; 63 import android.view.accessibility.AccessibilityNodeInfo; 64 import android.view.accessibility.AccessibilityNodeProvider; 65 import android.view.autofill.AutofillId; 66 import android.view.autofill.AutofillValue; 67 import android.view.inputmethod.EditorInfo; 68 import android.view.inputmethod.InputConnection; 69 import android.view.inspector.InspectableProperty; 70 import android.view.textclassifier.TextClassifier; 71 import android.view.translation.TranslationCapability; 72 import android.view.translation.TranslationSpec.DataFormat; 73 import android.view.translation.ViewTranslationRequest; 74 import android.view.translation.ViewTranslationResponse; 75 import android.widget.AbsoluteLayout; 76 77 import java.io.BufferedWriter; 78 import java.io.File; 79 import java.lang.annotation.Retention; 80 import java.lang.annotation.RetentionPolicy; 81 import java.util.List; 82 import java.util.Map; 83 import java.util.concurrent.Executor; 84 import java.util.function.Consumer; 85 86 /** 87 * A View that displays web pages. 88 * 89 * <h3>Basic usage</h3> 90 * 91 * 92 * <p>In most cases, we recommend using a standard web browser, like Chrome, to deliver 93 * content to the user. To learn more about web browsers, read the guide on 94 * <a href="/guide/components/intents-common#Browser"> 95 * invoking a browser with an intent</a>. 96 * 97 * <p>WebView objects allow you to display web content as part of your activity layout, but 98 * lack some of the features of fully-developed browsers. A WebView is useful when 99 * you need increased control over the UI and advanced configuration options that will allow 100 * you to embed web pages in a specially-designed environment for your app. 101 * 102 * <p>To learn more about WebView and alternatives for serving web content, read the 103 * documentation on 104 * <a href="/guide/webapps/"> 105 * Web-based content</a>. 106 * 107 */ 108 // Implementation notes. 109 // The WebView is a thin API class that delegates its public API to a backend WebViewProvider 110 // class instance. WebView extends {@link AbsoluteLayout} for backward compatibility reasons. 111 // Methods are delegated to the provider implementation: all public API methods introduced in this 112 // file are fully delegated, whereas public and protected methods from the View base classes are 113 // only delegated where a specific need exists for them to do so. 114 @Widget 115 public class WebView extends AbsoluteLayout 116 implements ViewTreeObserver.OnGlobalFocusChangeListener, 117 ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler { 118 119 private static final String LOGTAG = "WebView"; 120 121 // Throwing an exception for incorrect thread usage if the 122 // build target is JB MR2 or newer. Defaults to false, and is 123 // set in the WebView constructor. 124 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 125 private static volatile boolean sEnforceThreadChecking = false; 126 127 /** 128 * Transportation object for returning WebView across thread boundaries. 129 */ 130 public class WebViewTransport { 131 private WebView mWebview; 132 133 /** 134 * Sets the WebView to the transportation object. 135 * 136 * @param webview the WebView to transport 137 */ setWebView(@ullable WebView webview)138 public synchronized void setWebView(@Nullable WebView webview) { 139 mWebview = webview; 140 } 141 142 /** 143 * Gets the WebView object. 144 * 145 * @return the transported WebView object 146 */ 147 @Nullable getWebView()148 public synchronized WebView getWebView() { 149 return mWebview; 150 } 151 } 152 153 /** 154 * URI scheme for telephone number. 155 */ 156 public static final String SCHEME_TEL = "tel:"; 157 /** 158 * URI scheme for email address. 159 */ 160 public static final String SCHEME_MAILTO = "mailto:"; 161 /** 162 * URI scheme for map address. 163 */ 164 public static final String SCHEME_GEO = "geo:0,0?q="; 165 166 /** 167 * Interface to listen for find results. 168 */ 169 public interface FindListener { 170 /** 171 * Notifies the listener about progress made by a find operation. 172 * 173 * @param activeMatchOrdinal the zero-based ordinal of the currently selected match 174 * @param numberOfMatches how many matches have been found 175 * @param isDoneCounting whether the find operation has actually completed. The listener 176 * may be notified multiple times while the 177 * operation is underway, and the numberOfMatches 178 * value should not be considered final unless 179 * isDoneCounting is {@code true}. 180 */ onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting)181 public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, 182 boolean isDoneCounting); 183 } 184 185 /** 186 * Callback interface supplied to {@link #postVisualStateCallback} for receiving 187 * notifications about the visual state. 188 */ 189 public static abstract class VisualStateCallback { 190 /** 191 * Invoked when the visual state is ready to be drawn in the next {@link #onDraw}. 192 * 193 * @param requestId The identifier passed to {@link #postVisualStateCallback} when this 194 * callback was posted. 195 */ onComplete(long requestId)196 public abstract void onComplete(long requestId); 197 } 198 199 /** 200 * Interface to listen for new pictures as they change. 201 * 202 * @deprecated This interface is now obsolete. 203 */ 204 @Deprecated 205 public interface PictureListener { 206 /** 207 * Used to provide notification that the WebView's picture has changed. 208 * See {@link WebView#capturePicture} for details of the picture. 209 * 210 * @param view the WebView that owns the picture 211 * @param picture the new picture. Applications targeting 212 * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} or above 213 * will always receive a {@code null} Picture. 214 * @deprecated Deprecated due to internal changes. 215 */ 216 @Deprecated onNewPicture(WebView view, @Nullable Picture picture)217 void onNewPicture(WebView view, @Nullable Picture picture); 218 } 219 220 public static class HitTestResult { 221 /** 222 * Default HitTestResult, where the target is unknown. 223 */ 224 public static final int UNKNOWN_TYPE = 0; 225 /** 226 * @deprecated This type is no longer used. 227 */ 228 @Deprecated 229 public static final int ANCHOR_TYPE = 1; 230 /** 231 * HitTestResult for hitting a phone number. 232 */ 233 public static final int PHONE_TYPE = 2; 234 /** 235 * HitTestResult for hitting a map address. 236 */ 237 public static final int GEO_TYPE = 3; 238 /** 239 * HitTestResult for hitting an email address. 240 */ 241 public static final int EMAIL_TYPE = 4; 242 /** 243 * HitTestResult for hitting an HTML::img tag. 244 */ 245 public static final int IMAGE_TYPE = 5; 246 /** 247 * @deprecated This type is no longer used. 248 */ 249 @Deprecated 250 public static final int IMAGE_ANCHOR_TYPE = 6; 251 /** 252 * HitTestResult for hitting a HTML::a tag with src=http. 253 */ 254 public static final int SRC_ANCHOR_TYPE = 7; 255 /** 256 * HitTestResult for hitting a HTML::a tag with src=http + HTML::img. 257 */ 258 public static final int SRC_IMAGE_ANCHOR_TYPE = 8; 259 /** 260 * HitTestResult for hitting an edit text area. 261 */ 262 public static final int EDIT_TEXT_TYPE = 9; 263 264 private int mType; 265 private String mExtra; 266 267 /** 268 * @hide Only for use by WebViewProvider implementations 269 */ 270 @SystemApi HitTestResult()271 public HitTestResult() { 272 mType = UNKNOWN_TYPE; 273 } 274 275 /** 276 * @hide Only for use by WebViewProvider implementations 277 */ 278 @SystemApi setType(int type)279 public void setType(int type) { 280 mType = type; 281 } 282 283 /** 284 * @hide Only for use by WebViewProvider implementations 285 */ 286 @SystemApi setExtra(String extra)287 public void setExtra(String extra) { 288 mExtra = extra; 289 } 290 291 /** 292 * Gets the type of the hit test result. See the XXX_TYPE constants 293 * defined in this class. 294 * 295 * @return the type of the hit test result 296 */ getType()297 public int getType() { 298 return mType; 299 } 300 301 /** 302 * Gets additional type-dependant information about the result. See 303 * {@link WebView#getHitTestResult()} for details. May either be {@code null} 304 * or contain extra information about this result. 305 * 306 * @return additional type-dependant information about the result 307 */ 308 @Nullable getExtra()309 public String getExtra() { 310 return mExtra; 311 } 312 } 313 314 /** 315 * Constructs a new WebView with an Activity Context object. 316 * 317 * <p class="note"><b>Note:</b> WebView should always be instantiated with an Activity Context. 318 * If instantiated with an Application Context, WebView will be unable to provide several 319 * features, such as JavaScript dialogs and autofill. 320 * 321 * @param context an Activity Context to access application assets 322 */ WebView(@onNull Context context)323 public WebView(@NonNull Context context) { 324 this(context, null); 325 } 326 327 /** 328 * Constructs a new WebView with layout parameters. 329 * 330 * @param context an Activity Context to access application assets 331 * @param attrs an AttributeSet passed to our parent 332 */ WebView(@onNull Context context, @Nullable AttributeSet attrs)333 public WebView(@NonNull Context context, @Nullable AttributeSet attrs) { 334 this(context, attrs, com.android.internal.R.attr.webViewStyle); 335 } 336 337 /** 338 * Constructs a new WebView with layout parameters and a default style. 339 * 340 * @param context an Activity Context to access application assets 341 * @param attrs an AttributeSet passed to our parent 342 * @param defStyleAttr an attribute in the current theme that contains a 343 * reference to a style resource that supplies default values for 344 * the view. Can be 0 to not look for defaults. 345 */ WebView(@onNull Context context, @Nullable AttributeSet attrs, int defStyleAttr)346 public WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 347 this(context, attrs, defStyleAttr, 0); 348 } 349 350 /** 351 * Constructs a new WebView with layout parameters and a default style. 352 * 353 * @param context an Activity Context to access application assets 354 * @param attrs an AttributeSet passed to our parent 355 * @param defStyleAttr an attribute in the current theme that contains a 356 * reference to a style resource that supplies default values for 357 * the view. Can be 0 to not look for defaults. 358 * @param defStyleRes a resource identifier of a style resource that 359 * supplies default values for the view, used only if 360 * defStyleAttr is 0 or can not be found in the theme. Can be 0 361 * to not look for defaults. 362 */ WebView(@onNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)363 public WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, 364 int defStyleRes) { 365 this(context, attrs, defStyleAttr, defStyleRes, null, false); 366 } 367 368 /** 369 * Constructs a new WebView with layout parameters and a default style. 370 * 371 * @param context an Activity Context to access application assets 372 * @param attrs an AttributeSet passed to our parent 373 * @param defStyleAttr an attribute in the current theme that contains a 374 * reference to a style resource that supplies default values for 375 * the view. Can be 0 to not look for defaults. 376 * @param privateBrowsing whether this WebView will be initialized in 377 * private mode 378 * 379 * @deprecated Private browsing is no longer supported directly via 380 * WebView and will be removed in a future release. Prefer using 381 * {@link WebSettings}, {@link WebViewDatabase}, {@link CookieManager} 382 * and {@link WebStorage} for fine-grained control of privacy data. 383 */ 384 @Deprecated WebView(@onNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, boolean privateBrowsing)385 public WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, 386 boolean privateBrowsing) { 387 this(context, attrs, defStyleAttr, 0, null, privateBrowsing); 388 } 389 390 /** 391 * Constructs a new WebView with layout parameters, a default style and a set 392 * of custom JavaScript interfaces to be added to this WebView at initialization 393 * time. This guarantees that these interfaces will be available when the JS 394 * context is initialized. 395 * 396 * @param context an Activity Context to access application assets 397 * @param attrs an AttributeSet passed to our parent 398 * @param defStyleAttr an attribute in the current theme that contains a 399 * reference to a style resource that supplies default values for 400 * the view. Can be 0 to not look for defaults. 401 * @param javaScriptInterfaces a Map of interface names, as keys, and 402 * object implementing those interfaces, as 403 * values 404 * @param privateBrowsing whether this WebView will be initialized in 405 * private mode 406 * @hide This is used internally by dumprendertree, as it requires the JavaScript interfaces to 407 * be added synchronously, before a subsequent loadUrl call takes effect. 408 */ 409 @UnsupportedAppUsage WebView(@onNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, @Nullable Map<String, Object> javaScriptInterfaces, boolean privateBrowsing)410 protected WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, 411 @Nullable Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) { 412 this(context, attrs, defStyleAttr, 0, javaScriptInterfaces, privateBrowsing); 413 } 414 415 /** 416 * @hide 417 */ 418 @SuppressWarnings("deprecation") // for super() call into deprecated base class constructor. 419 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) WebView(@onNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes, @Nullable Map<String, Object> javaScriptInterfaces, boolean privateBrowsing)420 protected WebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, 421 int defStyleRes, @Nullable Map<String, Object> javaScriptInterfaces, 422 boolean privateBrowsing) { 423 super(context, attrs, defStyleAttr, defStyleRes); 424 425 // WebView is important by default, unless app developer overrode attribute. 426 if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) { 427 setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES); 428 } 429 if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { 430 setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES); 431 } 432 433 if (context == null) { 434 throw new IllegalArgumentException("Invalid context argument"); 435 } 436 if (mWebViewThread == null) { 437 throw new RuntimeException( 438 "WebView cannot be initialized on a thread that has no Looper."); 439 } 440 sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >= 441 Build.VERSION_CODES.JELLY_BEAN_MR2; 442 checkThread(); 443 444 ensureProviderCreated(); 445 mProvider.init(javaScriptInterfaces, privateBrowsing); 446 // Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed. 447 CookieSyncManager.setGetInstanceIsAllowed(); 448 } 449 450 /** 451 * Specifies whether the horizontal scrollbar has overlay style. 452 * 453 * @deprecated This method has no effect. 454 * @param overlay {@code true} if horizontal scrollbar should have overlay style 455 */ 456 @Deprecated setHorizontalScrollbarOverlay(boolean overlay)457 public void setHorizontalScrollbarOverlay(boolean overlay) { 458 } 459 460 /** 461 * Specifies whether the vertical scrollbar has overlay style. 462 * 463 * @deprecated This method has no effect. 464 * @param overlay {@code true} if vertical scrollbar should have overlay style 465 */ 466 @Deprecated setVerticalScrollbarOverlay(boolean overlay)467 public void setVerticalScrollbarOverlay(boolean overlay) { 468 } 469 470 /** 471 * Gets whether horizontal scrollbar has overlay style. 472 * 473 * @deprecated This method is now obsolete. 474 * @return {@code true} 475 */ 476 @Deprecated overlayHorizontalScrollbar()477 public boolean overlayHorizontalScrollbar() { 478 // The old implementation defaulted to true, so return true for consistency 479 return true; 480 } 481 482 /** 483 * Gets whether vertical scrollbar has overlay style. 484 * 485 * @deprecated This method is now obsolete. 486 * @return {@code false} 487 */ 488 @Deprecated overlayVerticalScrollbar()489 public boolean overlayVerticalScrollbar() { 490 // The old implementation defaulted to false, so return false for consistency 491 return false; 492 } 493 494 /** 495 * Gets the visible height (in pixels) of the embedded title bar (if any). 496 * 497 * @deprecated This method is now obsolete. 498 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 499 */ 500 @Deprecated 501 @UnsupportedAppUsage getVisibleTitleHeight()502 public int getVisibleTitleHeight() { 503 checkThread(); 504 return mProvider.getVisibleTitleHeight(); 505 } 506 507 /** 508 * Gets the SSL certificate for the main top-level page or {@code null} if there is 509 * no certificate (the site is not secure). 510 * 511 * @return the SSL certificate for the main top-level page 512 */ 513 @Nullable getCertificate()514 public SslCertificate getCertificate() { 515 checkThread(); 516 return mProvider.getCertificate(); 517 } 518 519 /** 520 * Sets the SSL certificate for the main top-level page. 521 * 522 * @deprecated Calling this function has no useful effect, and will be 523 * ignored in future releases. 524 */ 525 @Deprecated setCertificate(SslCertificate certificate)526 public void setCertificate(SslCertificate certificate) { 527 checkThread(); 528 mProvider.setCertificate(certificate); 529 } 530 531 //------------------------------------------------------------------------- 532 // Methods called by activity 533 //------------------------------------------------------------------------- 534 535 /** 536 * Sets a username and password pair for the specified host. This data is 537 * used by the WebView to autocomplete username and password fields in web 538 * forms. Note that this is unrelated to the credentials used for HTTP 539 * authentication. 540 * 541 * @param host the host that required the credentials 542 * @param username the username for the given host 543 * @param password the password for the given host 544 * @see WebViewDatabase#clearUsernamePassword 545 * @see WebViewDatabase#hasUsernamePassword 546 * @deprecated Saving passwords in WebView will not be supported in future versions. 547 */ 548 @Deprecated savePassword(String host, String username, String password)549 public void savePassword(String host, String username, String password) { 550 checkThread(); 551 mProvider.savePassword(host, username, password); 552 } 553 554 /** 555 * Stores HTTP authentication credentials for a given host and realm to the {@link WebViewDatabase} 556 * instance. 557 * 558 * @param host the host to which the credentials apply 559 * @param realm the realm to which the credentials apply 560 * @param username the username 561 * @param password the password 562 * @deprecated Use {@link WebViewDatabase#setHttpAuthUsernamePassword} instead 563 */ 564 @Deprecated setHttpAuthUsernamePassword(String host, String realm, String username, String password)565 public void setHttpAuthUsernamePassword(String host, String realm, 566 String username, String password) { 567 checkThread(); 568 mProvider.setHttpAuthUsernamePassword(host, realm, username, password); 569 } 570 571 /** 572 * Retrieves HTTP authentication credentials for a given host and realm from the {@link 573 * WebViewDatabase} instance. 574 * @param host the host to which the credentials apply 575 * @param realm the realm to which the credentials apply 576 * @return the credentials as a String array, if found. The first element 577 * is the username and the second element is the password. {@code null} if 578 * no credentials are found. 579 * @deprecated Use {@link WebViewDatabase#getHttpAuthUsernamePassword} instead 580 */ 581 @Deprecated 582 @Nullable getHttpAuthUsernamePassword(String host, String realm)583 public String[] getHttpAuthUsernamePassword(String host, String realm) { 584 checkThread(); 585 return mProvider.getHttpAuthUsernamePassword(host, realm); 586 } 587 588 /** 589 * Destroys the internal state of this WebView. This method should be called 590 * after this WebView has been removed from the view system. No other 591 * methods may be called on this WebView after destroy. 592 */ destroy()593 public void destroy() { 594 checkThread(); 595 mProvider.destroy(); 596 } 597 598 /** 599 * Enables platform notifications of data state and proxy changes. 600 * Notifications are enabled by default. 601 * 602 * @deprecated This method is now obsolete. 603 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 604 */ 605 @Deprecated 606 @UnsupportedAppUsage enablePlatformNotifications()607 public static void enablePlatformNotifications() { 608 // noop 609 } 610 611 /** 612 * Disables platform notifications of data state and proxy changes. 613 * Notifications are enabled by default. 614 * 615 * @deprecated This method is now obsolete. 616 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 617 */ 618 @Deprecated 619 @UnsupportedAppUsage disablePlatformNotifications()620 public static void disablePlatformNotifications() { 621 // noop 622 } 623 624 /** 625 * Used only by internal tests to free up memory. 626 * 627 * @hide 628 */ 629 @UnsupportedAppUsage freeMemoryForTests()630 public static void freeMemoryForTests() { 631 getFactory().getStatics().freeMemoryForTests(); 632 } 633 634 /** 635 * Informs WebView of the network state. This is used to set 636 * the JavaScript property window.navigator.isOnline and 637 * generates the online/offline event as specified in HTML5, sec. 5.7.7 638 * 639 * @param networkUp a boolean indicating if network is available 640 */ setNetworkAvailable(boolean networkUp)641 public void setNetworkAvailable(boolean networkUp) { 642 checkThread(); 643 mProvider.setNetworkAvailable(networkUp); 644 } 645 646 /** 647 * Saves the state of this WebView used in 648 * {@link android.app.Activity#onSaveInstanceState}. Please note that this 649 * method no longer stores the display data for this WebView. The previous 650 * behavior could potentially leak files if {@link #restoreState} was never 651 * called. 652 * 653 * @param outState the Bundle to store this WebView's state 654 * @return the same copy of the back/forward list used to save the state, {@code null} if the 655 * method fails. 656 */ 657 @Nullable saveState(@onNull Bundle outState)658 public WebBackForwardList saveState(@NonNull Bundle outState) { 659 checkThread(); 660 return mProvider.saveState(outState); 661 } 662 663 /** 664 * Saves the current display data to the Bundle given. Used in conjunction 665 * with {@link #saveState}. 666 * @param b a Bundle to store the display data 667 * @param dest the file to store the serialized picture data. Will be 668 * overwritten with this WebView's picture data. 669 * @return {@code true} if the picture was successfully saved 670 * @deprecated This method is now obsolete. 671 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 672 */ 673 @Deprecated 674 @UnsupportedAppUsage savePicture(Bundle b, final File dest)675 public boolean savePicture(Bundle b, final File dest) { 676 checkThread(); 677 return mProvider.savePicture(b, dest); 678 } 679 680 /** 681 * Restores the display data that was saved in {@link #savePicture}. Used in 682 * conjunction with {@link #restoreState}. Note that this will not work if 683 * this WebView is hardware accelerated. 684 * 685 * @param b a Bundle containing the saved display data 686 * @param src the file where the picture data was stored 687 * @return {@code true} if the picture was successfully restored 688 * @deprecated This method is now obsolete. 689 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 690 */ 691 @Deprecated 692 @UnsupportedAppUsage restorePicture(Bundle b, File src)693 public boolean restorePicture(Bundle b, File src) { 694 checkThread(); 695 return mProvider.restorePicture(b, src); 696 } 697 698 /** 699 * Restores the state of this WebView from the given Bundle. This method is 700 * intended for use in {@link android.app.Activity#onRestoreInstanceState} 701 * and should be called to restore the state of this WebView. If 702 * it is called after this WebView has had a chance to build state (load 703 * pages, create a back/forward list, etc.) there may be undesirable 704 * side-effects. Please note that this method no longer restores the 705 * display data for this WebView. 706 * 707 * @param inState the incoming Bundle of state 708 * @return the restored back/forward list or {@code null} if restoreState failed 709 */ 710 @Nullable restoreState(@onNull Bundle inState)711 public WebBackForwardList restoreState(@NonNull Bundle inState) { 712 checkThread(); 713 return mProvider.restoreState(inState); 714 } 715 716 /** 717 * Loads the given URL with additional HTTP headers, specified as a map from 718 * name to value. Note that if this map contains any of the headers that are 719 * set by default by this WebView, such as those controlling caching, accept 720 * types or the User-Agent, their values may be overridden by this WebView's 721 * defaults. 722 * <p> 723 * Some older WebView implementations require {@code additionalHttpHeaders} 724 * to be mutable. 725 * <p> 726 * Also see compatibility note on {@link #evaluateJavascript}. 727 * 728 * @param url the URL of the resource to load 729 * @param additionalHttpHeaders map with additional headers 730 */ loadUrl(@onNull String url, @NonNull Map<String, String> additionalHttpHeaders)731 public void loadUrl(@NonNull String url, @NonNull Map<String, String> additionalHttpHeaders) { 732 checkThread(); 733 mProvider.loadUrl(url, additionalHttpHeaders); 734 } 735 736 /** 737 * Loads the given URL. 738 * <p> 739 * Also see compatibility note on {@link #evaluateJavascript}. 740 * 741 * @param url the URL of the resource to load 742 */ loadUrl(@onNull String url)743 public void loadUrl(@NonNull String url) { 744 checkThread(); 745 mProvider.loadUrl(url); 746 } 747 748 /** 749 * Loads the URL with postData using "POST" method into this WebView. If url 750 * is not a network URL, it will be loaded with {@link #loadUrl(String)} 751 * instead, ignoring the postData param. 752 * 753 * @param url the URL of the resource to load 754 * @param postData the data will be passed to "POST" request, which must be 755 * be "application/x-www-form-urlencoded" encoded. 756 */ postUrl(@onNull String url, @NonNull byte[] postData)757 public void postUrl(@NonNull String url, @NonNull byte[] postData) { 758 checkThread(); 759 if (URLUtil.isNetworkUrl(url)) { 760 mProvider.postUrl(url, postData); 761 } else { 762 mProvider.loadUrl(url); 763 } 764 } 765 766 /** 767 * Loads the given data into this WebView using a 'data' scheme URL. 768 * <p> 769 * Note that JavaScript's same origin policy means that script running in a 770 * page loaded using this method will be unable to access content loaded 771 * using any scheme other than 'data', including 'http(s)'. To avoid this 772 * restriction, use {@link 773 * #loadDataWithBaseURL(String,String,String,String,String) 774 * loadDataWithBaseURL()} with an appropriate base URL. 775 * <p> 776 * The {@code encoding} parameter specifies whether the data is base64 or URL 777 * encoded. If the data is base64 encoded, the value of the encoding 778 * parameter must be {@code "base64"}. HTML can be encoded with {@link 779 * android.util.Base64#encodeToString(byte[],int)} like so: 780 * <pre class="prettyprint"> 781 * String unencodedHtml = 782 * "<html><body>'%28' is the code for '('</body></html>"; 783 * String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); 784 * webView.loadData(encodedHtml, "text/html", "base64"); 785 * </pre> 786 * <p class="note"> 787 * For all other values of {@code encoding} (including {@code null}) it is assumed that the 788 * data uses ASCII encoding for octets inside the range of safe URL characters and use the 789 * standard %xx hex encoding of URLs for octets outside that range. See <a 790 * href="https://tools.ietf.org/html/rfc3986#section-2.2">RFC 3986</a> for more information. 791 * Applications targeting {@link android.os.Build.VERSION_CODES#Q} or later must either use 792 * base64 or encode any {@code #} characters in the content as {@code %23}, otherwise they 793 * will be treated as the end of the content and the remaining text used as a document 794 * fragment identifier. 795 * <p> 796 * The {@code mimeType} parameter specifies the format of the data. 797 * If WebView can't handle the specified MIME type, it will download the data. 798 * If {@code null}, defaults to 'text/html'. 799 * <p> 800 * The 'data' scheme URL formed by this method uses the default US-ASCII 801 * charset. If you need to set a different charset, you should form a 802 * 'data' scheme URL which explicitly specifies a charset parameter in the 803 * mediatype portion of the URL and call {@link #loadUrl(String)} instead. 804 * Note that the charset obtained from the mediatype portion of a data URL 805 * always overrides that specified in the HTML or XML document itself. 806 * <p> 807 * Content loaded using this method will have a {@code window.origin} value 808 * of {@code "null"}. This must not be considered to be a trusted origin 809 * by the application or by any JavaScript code running inside the WebView 810 * (for example, event sources in DOM event handlers or web messages), 811 * because malicious content can also create frames with a null origin. If 812 * you need to identify the main frame's origin in a trustworthy way, you 813 * should use {@link #loadDataWithBaseURL(String,String,String,String,String) 814 * loadDataWithBaseURL()} with a valid HTTP or HTTPS base URL to set the 815 * origin. 816 * 817 * @param data a String of data in the given encoding 818 * @param mimeType the MIME type of the data, e.g. 'text/html'. 819 * @param encoding the encoding of the data 820 */ loadData(@onNull String data, @Nullable String mimeType, @Nullable String encoding)821 public void loadData(@NonNull String data, @Nullable String mimeType, 822 @Nullable String encoding) { 823 checkThread(); 824 mProvider.loadData(data, mimeType, encoding); 825 } 826 827 /** 828 * Loads the given data into this WebView, using baseUrl as the base URL for 829 * the content. The base URL is used both to resolve relative URLs and when 830 * applying JavaScript's same origin policy. The historyUrl is used for the 831 * history entry. 832 * <p> 833 * The {@code mimeType} parameter specifies the format of the data. 834 * If WebView can't handle the specified MIME type, it will download the data. 835 * If {@code null}, defaults to 'text/html'. 836 * <p> 837 * Note that content specified in this way can access local device files 838 * (via 'file' scheme URLs) only if baseUrl specifies a scheme other than 839 * 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'. 840 * <p> 841 * If the base URL uses the data scheme, this method is equivalent to 842 * calling {@link #loadData(String,String,String) loadData()} and the 843 * historyUrl is ignored, and the data will be treated as part of a data: URL, 844 * including the requirement that the content be URL-encoded or base64 encoded. 845 * If the base URL uses any other scheme, then the data will be loaded into 846 * the WebView as a plain string (i.e. not part of a data URL) and any URL-encoded 847 * entities in the string will not be decoded. 848 * <p> 849 * Note that the baseUrl is sent in the 'Referer' HTTP header when 850 * requesting subresources (images, etc.) of the page loaded using this method. 851 * <p> 852 * If a valid HTTP or HTTPS base URL is not specified in {@code baseUrl}, then 853 * content loaded using this method will have a {@code window.origin} value 854 * of {@code "null"}. This must not be considered to be a trusted origin 855 * by the application or by any JavaScript code running inside the WebView 856 * (for example, event sources in DOM event handlers or web messages), 857 * because malicious content can also create frames with a null origin. If 858 * you need to identify the main frame's origin in a trustworthy way, you 859 * should use a valid HTTP or HTTPS base URL to set the origin. 860 * 861 * @param baseUrl the URL to use as the page's base URL. If {@code null} defaults to 862 * 'about:blank'. 863 * @param data a String of data in the given encoding 864 * @param mimeType the MIME type of the data, e.g. 'text/html'. 865 * @param encoding the encoding of the data 866 * @param historyUrl the URL to use as the history entry. If {@code null} defaults 867 * to 'about:blank'. If non-null, this must be a valid URL. 868 */ loadDataWithBaseURL(@ullable String baseUrl, @NonNull String data, @Nullable String mimeType, @Nullable String encoding, @Nullable String historyUrl)869 public void loadDataWithBaseURL(@Nullable String baseUrl, @NonNull String data, 870 @Nullable String mimeType, @Nullable String encoding, @Nullable String historyUrl) { 871 checkThread(); 872 mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl); 873 } 874 875 /** 876 * Asynchronously evaluates JavaScript in the context of the currently displayed page. 877 * If non-null, {@code resultCallback} will be invoked with any result returned from that 878 * execution. This method must be called on the UI thread and the callback will 879 * be made on the UI thread. 880 * <p> 881 * Compatibility note. Applications targeting {@link android.os.Build.VERSION_CODES#N} or 882 * later, JavaScript state from an empty WebView is no longer persisted across navigations like 883 * {@link #loadUrl(String)}. For example, global variables and functions defined before calling 884 * {@link #loadUrl(String)} will not exist in the loaded page. Applications should use 885 * {@link #addJavascriptInterface} instead to persist JavaScript objects across navigations. 886 * 887 * @param script the JavaScript to execute. 888 * @param resultCallback A callback to be invoked when the script execution 889 * completes with the result of the execution (if any). 890 * May be {@code null} if no notification of the result is required. 891 */ evaluateJavascript(@onNull String script, @Nullable ValueCallback<String> resultCallback)892 public void evaluateJavascript(@NonNull String script, @Nullable ValueCallback<String> 893 resultCallback) { 894 checkThread(); 895 mProvider.evaluateJavaScript(script, resultCallback); 896 } 897 898 /** 899 * Saves the current view as a web archive. 900 * 901 * @param filename the filename where the archive should be placed 902 */ saveWebArchive(@onNull String filename)903 public void saveWebArchive(@NonNull String filename) { 904 checkThread(); 905 mProvider.saveWebArchive(filename); 906 } 907 908 /** 909 * Saves the current view as a web archive. 910 * 911 * @param basename the filename where the archive should be placed 912 * @param autoname if {@code false}, takes basename to be a file. If {@code true}, basename 913 * is assumed to be a directory in which a filename will be 914 * chosen according to the URL of the current page. 915 * @param callback called after the web archive has been saved. The 916 * parameter for onReceiveValue will either be the filename 917 * under which the file was saved, or {@code null} if saving the 918 * file failed. 919 */ saveWebArchive(@onNull String basename, boolean autoname, @Nullable ValueCallback<String> callback)920 public void saveWebArchive(@NonNull String basename, boolean autoname, 921 @Nullable ValueCallback<String> callback) { 922 checkThread(); 923 mProvider.saveWebArchive(basename, autoname, callback); 924 } 925 926 /** 927 * Stops the current load. 928 */ stopLoading()929 public void stopLoading() { 930 checkThread(); 931 mProvider.stopLoading(); 932 } 933 934 /** 935 * Reloads the current URL. 936 */ reload()937 public void reload() { 938 checkThread(); 939 mProvider.reload(); 940 } 941 942 /** 943 * Gets whether this WebView has a back history item. 944 * 945 * @return {@code true} if this WebView has a back history item 946 */ canGoBack()947 public boolean canGoBack() { 948 checkThread(); 949 return mProvider.canGoBack(); 950 } 951 952 /** 953 * Goes back in the history of this WebView. 954 */ goBack()955 public void goBack() { 956 checkThread(); 957 mProvider.goBack(); 958 } 959 960 /** 961 * Gets whether this WebView has a forward history item. 962 * 963 * @return {@code true} if this WebView has a forward history item 964 */ canGoForward()965 public boolean canGoForward() { 966 checkThread(); 967 return mProvider.canGoForward(); 968 } 969 970 /** 971 * Goes forward in the history of this WebView. 972 */ goForward()973 public void goForward() { 974 checkThread(); 975 mProvider.goForward(); 976 } 977 978 /** 979 * Gets whether the page can go back or forward the given 980 * number of steps. 981 * 982 * @param steps the negative or positive number of steps to move the 983 * history 984 */ canGoBackOrForward(int steps)985 public boolean canGoBackOrForward(int steps) { 986 checkThread(); 987 return mProvider.canGoBackOrForward(steps); 988 } 989 990 /** 991 * Goes to the history item that is the number of steps away from 992 * the current item. Steps is negative if backward and positive 993 * if forward. 994 * 995 * @param steps the number of steps to take back or forward in the back 996 * forward list 997 */ goBackOrForward(int steps)998 public void goBackOrForward(int steps) { 999 checkThread(); 1000 mProvider.goBackOrForward(steps); 1001 } 1002 1003 /** 1004 * Gets whether private browsing is enabled in this WebView. 1005 */ isPrivateBrowsingEnabled()1006 public boolean isPrivateBrowsingEnabled() { 1007 checkThread(); 1008 return mProvider.isPrivateBrowsingEnabled(); 1009 } 1010 1011 /** 1012 * Scrolls the contents of this WebView up by half the view size. 1013 * 1014 * @param top {@code true} to jump to the top of the page 1015 * @return {@code true} if the page was scrolled 1016 */ pageUp(boolean top)1017 public boolean pageUp(boolean top) { 1018 checkThread(); 1019 return mProvider.pageUp(top); 1020 } 1021 1022 /** 1023 * Scrolls the contents of this WebView down by half the page size. 1024 * 1025 * @param bottom {@code true} to jump to bottom of page 1026 * @return {@code true} if the page was scrolled 1027 */ pageDown(boolean bottom)1028 public boolean pageDown(boolean bottom) { 1029 checkThread(); 1030 return mProvider.pageDown(bottom); 1031 } 1032 1033 /** 1034 * Posts a {@link VisualStateCallback}, which will be called when 1035 * the current state of the WebView is ready to be drawn. 1036 * 1037 * <p>Because updates to the DOM are processed asynchronously, updates to the DOM may not 1038 * immediately be reflected visually by subsequent {@link WebView#onDraw} invocations. The 1039 * {@link VisualStateCallback} provides a mechanism to notify the caller when the contents of 1040 * the DOM at the current time are ready to be drawn the next time the {@link WebView} 1041 * draws. 1042 * 1043 * <p>The next draw after the callback completes is guaranteed to reflect all the updates to the 1044 * DOM up to the point at which the {@link VisualStateCallback} was posted, but it may also 1045 * contain updates applied after the callback was posted. 1046 * 1047 * <p>The state of the DOM covered by this API includes the following: 1048 * <ul> 1049 * <li>primitive HTML elements (div, img, span, etc..)</li> 1050 * <li>images</li> 1051 * <li>CSS animations</li> 1052 * <li>WebGL</li> 1053 * <li>canvas</li> 1054 * </ul> 1055 * It does not include the state of: 1056 * <ul> 1057 * <li>the video tag</li> 1058 * </ul> 1059 * 1060 * <p>To guarantee that the {@link WebView} will successfully render the first frame 1061 * after the {@link VisualStateCallback#onComplete} method has been called a set of conditions 1062 * must be met: 1063 * <ul> 1064 * <li>If the {@link WebView}'s visibility is set to {@link View#VISIBLE VISIBLE} then 1065 * the {@link WebView} must be attached to the view hierarchy.</li> 1066 * <li>If the {@link WebView}'s visibility is set to {@link View#INVISIBLE INVISIBLE} 1067 * then the {@link WebView} must be attached to the view hierarchy and must be made 1068 * {@link View#VISIBLE VISIBLE} from the {@link VisualStateCallback#onComplete} method.</li> 1069 * <li>If the {@link WebView}'s visibility is set to {@link View#GONE GONE} then the 1070 * {@link WebView} must be attached to the view hierarchy and its 1071 * {@link AbsoluteLayout.LayoutParams LayoutParams}'s width and height need to be set to fixed 1072 * values and must be made {@link View#VISIBLE VISIBLE} from the 1073 * {@link VisualStateCallback#onComplete} method.</li> 1074 * </ul> 1075 * 1076 * <p>When using this API it is also recommended to enable pre-rasterization if the {@link 1077 * WebView} is off screen to avoid flickering. See {@link WebSettings#setOffscreenPreRaster} for 1078 * more details and do consider its caveats. 1079 * 1080 * @param requestId An id that will be returned in the callback to allow callers to match 1081 * requests with callbacks. 1082 * @param callback The callback to be invoked. 1083 */ postVisualStateCallback(long requestId, @NonNull VisualStateCallback callback)1084 public void postVisualStateCallback(long requestId, @NonNull VisualStateCallback callback) { 1085 checkThread(); 1086 mProvider.insertVisualStateCallback(requestId, callback); 1087 } 1088 1089 /** 1090 * Clears this WebView so that onDraw() will draw nothing but white background, 1091 * and onMeasure() will return 0 if MeasureSpec is not MeasureSpec.EXACTLY. 1092 * @deprecated Use WebView.loadUrl("about:blank") to reliably reset the view state 1093 * and release page resources (including any running JavaScript). 1094 */ 1095 @Deprecated clearView()1096 public void clearView() { 1097 checkThread(); 1098 mProvider.clearView(); 1099 } 1100 1101 /** 1102 * Gets a new picture that captures the current contents of this WebView. 1103 * The picture is of the entire document being displayed, and is not 1104 * limited to the area currently displayed by this WebView. Also, the 1105 * picture is a static copy and is unaffected by later changes to the 1106 * content being displayed. 1107 * <p> 1108 * Note that due to internal changes, for API levels between 1109 * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and 1110 * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} inclusive, the 1111 * picture does not include fixed position elements or scrollable divs. 1112 * <p> 1113 * Note that from {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} the returned picture 1114 * should only be drawn into bitmap-backed Canvas - using any other type of Canvas will involve 1115 * additional conversion at a cost in memory and performance. 1116 * 1117 * @deprecated Use {@link #onDraw} to obtain a bitmap snapshot of the WebView, or 1118 * {@link #saveWebArchive} to save the content to a file. 1119 * 1120 * @return a picture that captures the current contents of this WebView 1121 */ 1122 @Deprecated capturePicture()1123 public Picture capturePicture() { 1124 checkThread(); 1125 return mProvider.capturePicture(); 1126 } 1127 1128 /** 1129 * @deprecated Use {@link #createPrintDocumentAdapter(String)} which requires user 1130 * to provide a print document name. 1131 */ 1132 @Deprecated createPrintDocumentAdapter()1133 public PrintDocumentAdapter createPrintDocumentAdapter() { 1134 checkThread(); 1135 return mProvider.createPrintDocumentAdapter("default"); 1136 } 1137 1138 /** 1139 * Creates a PrintDocumentAdapter that provides the content of this WebView for printing. 1140 * 1141 * The adapter works by converting the WebView contents to a PDF stream. The WebView cannot 1142 * be drawn during the conversion process - any such draws are undefined. It is recommended 1143 * to use a dedicated off screen WebView for the printing. If necessary, an application may 1144 * temporarily hide a visible WebView by using a custom PrintDocumentAdapter instance 1145 * wrapped around the object returned and observing the onStart and onFinish methods. See 1146 * {@link android.print.PrintDocumentAdapter} for more information. 1147 * 1148 * @param documentName The user-facing name of the printed document. See 1149 * {@link android.print.PrintDocumentInfo} 1150 */ 1151 @NonNull createPrintDocumentAdapter(@onNull String documentName)1152 public PrintDocumentAdapter createPrintDocumentAdapter(@NonNull String documentName) { 1153 checkThread(); 1154 return mProvider.createPrintDocumentAdapter(documentName); 1155 } 1156 1157 /** 1158 * Gets the current scale of this WebView. 1159 * 1160 * @return the current scale 1161 * 1162 * @deprecated This method is prone to inaccuracy due to race conditions 1163 * between the web rendering and UI threads; prefer 1164 * {@link WebViewClient#onScaleChanged}. 1165 */ 1166 @Deprecated 1167 @ViewDebug.ExportedProperty(category = "webview") getScale()1168 public float getScale() { 1169 checkThread(); 1170 return mProvider.getScale(); 1171 } 1172 1173 /** 1174 * Sets the initial scale for this WebView. 0 means default. 1175 * The behavior for the default scale depends on the state of 1176 * {@link WebSettings#getUseWideViewPort()} and 1177 * {@link WebSettings#getLoadWithOverviewMode()}. 1178 * If the content fits into the WebView control by width, then 1179 * the zoom is set to 100%. For wide content, the behavior 1180 * depends on the state of {@link WebSettings#getLoadWithOverviewMode()}. 1181 * If its value is {@code true}, the content will be zoomed out to be fit 1182 * by width into the WebView control, otherwise not. 1183 * 1184 * If initial scale is greater than 0, WebView starts with this value 1185 * as initial scale. 1186 * Please note that unlike the scale properties in the viewport meta tag, 1187 * this method doesn't take the screen density into account. 1188 * 1189 * @param scaleInPercent the initial scale in percent 1190 */ setInitialScale(int scaleInPercent)1191 public void setInitialScale(int scaleInPercent) { 1192 checkThread(); 1193 mProvider.setInitialScale(scaleInPercent); 1194 } 1195 1196 /** 1197 * Invokes the graphical zoom picker widget for this WebView. This will 1198 * result in the zoom widget appearing on the screen to control the zoom 1199 * level of this WebView. 1200 */ invokeZoomPicker()1201 public void invokeZoomPicker() { 1202 checkThread(); 1203 mProvider.invokeZoomPicker(); 1204 } 1205 1206 /** 1207 * Gets a HitTestResult based on the current cursor node. If a HTML::a 1208 * tag is found and the anchor has a non-JavaScript URL, the HitTestResult 1209 * type is set to SRC_ANCHOR_TYPE and the URL is set in the "extra" field. 1210 * If the anchor does not have a URL or if it is a JavaScript URL, the type 1211 * will be UNKNOWN_TYPE and the URL has to be retrieved through 1212 * {@link #requestFocusNodeHref} asynchronously. If a HTML::img tag is 1213 * found, the HitTestResult type is set to IMAGE_TYPE and the URL is set in 1214 * the "extra" field. A type of 1215 * SRC_IMAGE_ANCHOR_TYPE indicates an anchor with a URL that has an image as 1216 * a child node. If a phone number is found, the HitTestResult type is set 1217 * to PHONE_TYPE and the phone number is set in the "extra" field of 1218 * HitTestResult. If a map address is found, the HitTestResult type is set 1219 * to GEO_TYPE and the address is set in the "extra" field of HitTestResult. 1220 * If an email address is found, the HitTestResult type is set to EMAIL_TYPE 1221 * and the email is set in the "extra" field of HitTestResult. Otherwise, 1222 * HitTestResult type is set to UNKNOWN_TYPE. 1223 */ 1224 @NonNull getHitTestResult()1225 public HitTestResult getHitTestResult() { 1226 checkThread(); 1227 return mProvider.getHitTestResult(); 1228 } 1229 1230 /** 1231 * Requests the anchor or image element URL at the last tapped point. 1232 * If hrefMsg is {@code null}, this method returns immediately and does not 1233 * dispatch hrefMsg to its target. If the tapped point hits an image, 1234 * an anchor, or an image in an anchor, the message associates 1235 * strings in named keys in its data. The value paired with the key 1236 * may be an empty string. 1237 * 1238 * @param hrefMsg the message to be dispatched with the result of the 1239 * request. The message data contains three keys. "url" 1240 * returns the anchor's href attribute. "title" returns the 1241 * anchor's text. "src" returns the image's src attribute. 1242 */ requestFocusNodeHref(@ullable Message hrefMsg)1243 public void requestFocusNodeHref(@Nullable Message hrefMsg) { 1244 checkThread(); 1245 mProvider.requestFocusNodeHref(hrefMsg); 1246 } 1247 1248 /** 1249 * Requests the URL of the image last touched by the user. msg will be sent 1250 * to its target with a String representing the URL as its object. 1251 * 1252 * @param msg the message to be dispatched with the result of the request 1253 * as the data member with "url" as key. The result can be {@code null}. 1254 */ requestImageRef(@onNull Message msg)1255 public void requestImageRef(@NonNull Message msg) { 1256 checkThread(); 1257 mProvider.requestImageRef(msg); 1258 } 1259 1260 /** 1261 * Gets the URL for the current page. This is not always the same as the URL 1262 * passed to WebViewClient.onPageStarted because although the load for 1263 * that URL has begun, the current page may not have changed. 1264 * 1265 * @return the URL for the current page or {@code null} if no page has been loaded 1266 */ 1267 @InspectableProperty(hasAttributeId = false) 1268 @ViewDebug.ExportedProperty(category = "webview") 1269 @Nullable getUrl()1270 public String getUrl() { 1271 checkThread(); 1272 return mProvider.getUrl(); 1273 } 1274 1275 /** 1276 * Gets the original URL for the current page. This is not always the same 1277 * as the URL passed to WebViewClient.onPageStarted because although the 1278 * load for that URL has begun, the current page may not have changed. 1279 * Also, there may have been redirects resulting in a different URL to that 1280 * originally requested. 1281 * 1282 * @return the URL that was originally requested for the current page or 1283 * {@code null} if no page has been loaded 1284 */ 1285 @InspectableProperty(hasAttributeId = false) 1286 @ViewDebug.ExportedProperty(category = "webview") 1287 @Nullable getOriginalUrl()1288 public String getOriginalUrl() { 1289 checkThread(); 1290 return mProvider.getOriginalUrl(); 1291 } 1292 1293 /** 1294 * Gets the title for the current page. This is the title of the current page 1295 * until WebViewClient.onReceivedTitle is called. 1296 * 1297 * @return the title for the current page or {@code null} if no page has been loaded 1298 */ 1299 @InspectableProperty(hasAttributeId = false) 1300 @ViewDebug.ExportedProperty(category = "webview") 1301 @Nullable getTitle()1302 public String getTitle() { 1303 checkThread(); 1304 return mProvider.getTitle(); 1305 } 1306 1307 /** 1308 * Gets the favicon for the current page. This is the favicon of the current 1309 * page until WebViewClient.onReceivedIcon is called. 1310 * 1311 * @return the favicon for the current page or {@code null} if the page doesn't 1312 * have one or if no page has been loaded 1313 */ 1314 @InspectableProperty(hasAttributeId = false) 1315 @Nullable getFavicon()1316 public Bitmap getFavicon() { 1317 checkThread(); 1318 return mProvider.getFavicon(); 1319 } 1320 1321 /** 1322 * Gets the touch icon URL for the apple-touch-icon <link> element, or 1323 * a URL on this site's server pointing to the standard location of a 1324 * touch icon. 1325 * 1326 * @hide 1327 */ 1328 @UnsupportedAppUsage getTouchIconUrl()1329 public String getTouchIconUrl() { 1330 return mProvider.getTouchIconUrl(); 1331 } 1332 1333 /** 1334 * Gets the progress for the current page. 1335 * 1336 * @return the progress for the current page between 0 and 100 1337 */ 1338 @InspectableProperty(hasAttributeId = false) getProgress()1339 public int getProgress() { 1340 checkThread(); 1341 return mProvider.getProgress(); 1342 } 1343 1344 /** 1345 * Gets the height of the HTML content. 1346 * 1347 * @return the height of the HTML content 1348 */ 1349 @InspectableProperty(hasAttributeId = false) 1350 @ViewDebug.ExportedProperty(category = "webview") getContentHeight()1351 public int getContentHeight() { 1352 checkThread(); 1353 return mProvider.getContentHeight(); 1354 } 1355 1356 /** 1357 * Gets the width of the HTML content. 1358 * 1359 * @return the width of the HTML content 1360 * @hide 1361 */ 1362 @ViewDebug.ExportedProperty(category = "webview") 1363 @UnsupportedAppUsage getContentWidth()1364 public int getContentWidth() { 1365 return mProvider.getContentWidth(); 1366 } 1367 1368 /** 1369 * Pauses all layout, parsing, and JavaScript timers for all WebViews. This 1370 * is a global requests, not restricted to just this WebView. This can be 1371 * useful if the application has been paused. 1372 */ pauseTimers()1373 public void pauseTimers() { 1374 checkThread(); 1375 mProvider.pauseTimers(); 1376 } 1377 1378 /** 1379 * Resumes all layout, parsing, and JavaScript timers for all WebViews. 1380 * This will resume dispatching all timers. 1381 */ resumeTimers()1382 public void resumeTimers() { 1383 checkThread(); 1384 mProvider.resumeTimers(); 1385 } 1386 1387 /** 1388 * Does a best-effort attempt to pause any processing that can be paused 1389 * safely, such as animations and geolocation. Note that this call 1390 * does not pause JavaScript. To pause JavaScript globally, use 1391 * {@link #pauseTimers}. 1392 * 1393 * To resume WebView, call {@link #onResume}. 1394 */ onPause()1395 public void onPause() { 1396 checkThread(); 1397 mProvider.onPause(); 1398 } 1399 1400 /** 1401 * Resumes a WebView after a previous call to {@link #onPause}. 1402 */ onResume()1403 public void onResume() { 1404 checkThread(); 1405 mProvider.onResume(); 1406 } 1407 1408 /** 1409 * Gets whether this WebView is paused, meaning onPause() was called. 1410 * Calling onResume() sets the paused state back to {@code false}. 1411 * 1412 * @hide 1413 */ 1414 @UnsupportedAppUsage isPaused()1415 public boolean isPaused() { 1416 return mProvider.isPaused(); 1417 } 1418 1419 /** 1420 * Informs this WebView that memory is low so that it can free any available 1421 * memory. 1422 * @deprecated Memory caches are automatically dropped when no longer needed, and in response 1423 * to system memory pressure. 1424 */ 1425 @Deprecated freeMemory()1426 public void freeMemory() { 1427 checkThread(); 1428 mProvider.freeMemory(); 1429 } 1430 1431 /** 1432 * Clears the resource cache. Note that the cache is per-application, so 1433 * this will clear the cache for all WebViews used. 1434 * 1435 * @param includeDiskFiles if {@code false}, only the RAM cache is cleared 1436 */ clearCache(boolean includeDiskFiles)1437 public void clearCache(boolean includeDiskFiles) { 1438 checkThread(); 1439 mProvider.clearCache(includeDiskFiles); 1440 } 1441 1442 /** 1443 * Removes the autocomplete popup from the currently focused form field, if 1444 * present. Note this only affects the display of the autocomplete popup, 1445 * it does not remove any saved form data from this WebView's store. To do 1446 * that, use {@link WebViewDatabase#clearFormData}. 1447 */ clearFormData()1448 public void clearFormData() { 1449 checkThread(); 1450 mProvider.clearFormData(); 1451 } 1452 1453 /** 1454 * Tells this WebView to clear its internal back/forward list. 1455 */ clearHistory()1456 public void clearHistory() { 1457 checkThread(); 1458 mProvider.clearHistory(); 1459 } 1460 1461 /** 1462 * Clears the SSL preferences table stored in response to proceeding with 1463 * SSL certificate errors. 1464 */ clearSslPreferences()1465 public void clearSslPreferences() { 1466 checkThread(); 1467 mProvider.clearSslPreferences(); 1468 } 1469 1470 /** 1471 * Clears the client certificate preferences stored in response 1472 * to proceeding/cancelling client cert requests. Note that WebView 1473 * automatically clears these preferences when the system keychain is updated. 1474 * The preferences are shared by all the WebViews that are created by the embedder application. 1475 * 1476 * @param onCleared A runnable to be invoked when client certs are cleared. 1477 * The runnable will be called in UI thread. 1478 */ clearClientCertPreferences(@ullable Runnable onCleared)1479 public static void clearClientCertPreferences(@Nullable Runnable onCleared) { 1480 getFactory().getStatics().clearClientCertPreferences(onCleared); 1481 } 1482 1483 /** 1484 * Starts Safe Browsing initialization. 1485 * <p> 1486 * URL loads are not guaranteed to be protected by Safe Browsing until after {@code callback} is 1487 * invoked with {@code true}. Safe Browsing is not fully supported on all devices. For those 1488 * devices {@code callback} will receive {@code false}. 1489 * <p> 1490 * This should not be called if Safe Browsing has been disabled by manifest tag or {@link 1491 * WebSettings#setSafeBrowsingEnabled}. This prepares resources used for Safe Browsing. 1492 * <p> 1493 * This should be called with the Application Context (and will always use the Application 1494 * context to do its work regardless). 1495 * 1496 * @param context Application Context. 1497 * @param callback will be called on the UI thread with {@code true} if initialization is 1498 * successful, {@code false} otherwise. 1499 * @deprecated In WebView version 122.0.6174.0 and later, this initialization is done 1500 * automatically, so there is no need to call this API. If called, this API will invoke 1501 * the {@code callback} immediately with {@code true}, given that Safe Browsing 1502 * is enabled and supported on the device. 1503 */ 1504 @Deprecated 1505 @FlaggedApi(android.webkit.Flags.FLAG_DEPRECATE_START_SAFE_BROWSING) startSafeBrowsing(@onNull Context context, @Nullable ValueCallback<Boolean> callback)1506 public static void startSafeBrowsing(@NonNull Context context, 1507 @Nullable ValueCallback<Boolean> callback) { 1508 getFactory().getStatics().initSafeBrowsing(context, callback); 1509 } 1510 1511 /** 1512 * Sets the list of hosts (domain names/IP addresses) that are exempt from SafeBrowsing checks. 1513 * The list is global for all the WebViews. 1514 * <p> 1515 * Each rule should take one of these: 1516 * <table> 1517 * <tr><th> Rule </th> <th> Example </th> <th> Matches Subdomain</th> </tr> 1518 * <tr><td> HOSTNAME </td> <td> example.com </td> <td> Yes </td> </tr> 1519 * <tr><td> .HOSTNAME </td> <td> .example.com </td> <td> No </td> </tr> 1520 * <tr><td> IPV4_LITERAL </td> <td> 192.168.1.1 </td> <td> No </td></tr> 1521 * <tr><td> IPV6_LITERAL_WITH_BRACKETS </td><td>[10:20:30:40:50:60:70:80]</td><td>No</td></tr> 1522 * </table> 1523 * <p> 1524 * All other rules, including wildcards, are invalid. 1525 * <p> 1526 * The correct syntax for hosts is defined by <a 1527 * href="https://tools.ietf.org/html/rfc3986#section-3.2.2">RFC 3986</a>. 1528 * 1529 * @param hosts the list of hosts 1530 * @param callback will be called with {@code true} if hosts are successfully added to the 1531 * allowlist. It will be called with {@code false} if any hosts are malformed. The callback 1532 * will be run on the UI thread 1533 */ setSafeBrowsingWhitelist(@onNull List<String> hosts, @Nullable ValueCallback<Boolean> callback)1534 public static void setSafeBrowsingWhitelist(@NonNull List<String> hosts, 1535 @Nullable ValueCallback<Boolean> callback) { 1536 getFactory().getStatics().setSafeBrowsingWhitelist(hosts, callback); 1537 } 1538 1539 /** 1540 * Returns a URL pointing to the privacy policy for Safe Browsing reporting. 1541 * 1542 * @return the url pointing to a privacy policy document which can be displayed to users. 1543 */ 1544 @NonNull getSafeBrowsingPrivacyPolicyUrl()1545 public static Uri getSafeBrowsingPrivacyPolicyUrl() { 1546 return getFactory().getStatics().getSafeBrowsingPrivacyPolicyUrl(); 1547 } 1548 1549 /** 1550 * Gets the WebBackForwardList for this WebView. This contains the 1551 * back/forward list for use in querying each item in the history stack. 1552 * This is a copy of the private WebBackForwardList so it contains only a 1553 * snapshot of the current state. Multiple calls to this method may return 1554 * different objects. The object returned from this method will not be 1555 * updated to reflect any new state. 1556 */ 1557 @NonNull copyBackForwardList()1558 public WebBackForwardList copyBackForwardList() { 1559 checkThread(); 1560 return mProvider.copyBackForwardList(); 1561 1562 } 1563 1564 /** 1565 * Registers the listener to be notified as find-on-page operations 1566 * progress. This will replace the current listener. 1567 * 1568 * @param listener an implementation of {@link FindListener} 1569 */ setFindListener(@ullable FindListener listener)1570 public void setFindListener(@Nullable FindListener listener) { 1571 checkThread(); 1572 setupFindListenerIfNeeded(); 1573 mFindListener.mUserFindListener = listener; 1574 } 1575 1576 /** 1577 * Highlights and scrolls to the next match found by 1578 * {@link #findAllAsync}, wrapping around page boundaries as necessary. 1579 * Notifies any registered {@link FindListener}. If {@link #findAllAsync(String)} 1580 * has not been called yet, or if {@link #clearMatches} has been called since the 1581 * last find operation, this function does nothing. 1582 * 1583 * @param forward the direction to search 1584 * @see #setFindListener 1585 */ findNext(boolean forward)1586 public void findNext(boolean forward) { 1587 checkThread(); 1588 mProvider.findNext(forward); 1589 } 1590 1591 /** 1592 * Finds all instances of find on the page and highlights them. 1593 * Notifies any registered {@link FindListener}. 1594 * 1595 * @param find the string to find 1596 * @return the number of occurrences of the String "find" that were found 1597 * @deprecated {@link #findAllAsync} is preferred. 1598 * @see #setFindListener 1599 */ 1600 @Deprecated findAll(String find)1601 public int findAll(String find) { 1602 checkThread(); 1603 StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync"); 1604 return mProvider.findAll(find); 1605 } 1606 1607 /** 1608 * Finds all instances of find on the page and highlights them, 1609 * asynchronously. Notifies any registered {@link FindListener}. 1610 * Successive calls to this will cancel any pending searches. 1611 * 1612 * @param find the string to find. 1613 * @see #setFindListener 1614 */ findAllAsync(@onNull String find)1615 public void findAllAsync(@NonNull String find) { 1616 checkThread(); 1617 mProvider.findAllAsync(find); 1618 } 1619 1620 /** 1621 * Starts an ActionMode for finding text in this WebView. Only works if this 1622 * WebView is attached to the view system. 1623 * 1624 * @param text if non-null, will be the initial text to search for. 1625 * Otherwise, the last String searched for in this WebView will 1626 * be used to start. 1627 * @param showIme if {@code true}, show the IME, assuming the user will begin typing. 1628 * If {@code false} and text is non-null, perform a find all. 1629 * @return {@code true} if the find dialog is shown, {@code false} otherwise 1630 * @deprecated This method does not work reliably on all Android versions; 1631 * implementing a custom find dialog using WebView.findAllAsync() 1632 * provides a more robust solution. 1633 */ 1634 @Deprecated showFindDialog(@ullable String text, boolean showIme)1635 public boolean showFindDialog(@Nullable String text, boolean showIme) { 1636 checkThread(); 1637 return mProvider.showFindDialog(text, showIme); 1638 } 1639 1640 /** 1641 * Gets the first substring which appears to be the address of a physical 1642 * location. Only addresses in the United States can be detected, which 1643 * must consist of: 1644 * <ul> 1645 * <li>a house number</li> 1646 * <li>a street name</li> 1647 * <li>a street type (Road, Circle, etc), either spelled out or 1648 * abbreviated</li> 1649 * <li>a city name</li> 1650 * <li>a state or territory, either spelled out or two-letter abbr</li> 1651 * <li>an optional 5 digit or 9 digit zip code</li> 1652 * </ul> 1653 * All names must be correctly capitalized, and the zip code, if present, 1654 * must be valid for the state. The street type must be a standard USPS 1655 * spelling or abbreviation. The state or territory must also be spelled 1656 * or abbreviated using USPS standards. The house number may not exceed 1657 * five digits. 1658 * 1659 * <p class="note"><b>Note:</b> This function is deprecated and should be 1660 * avoided on all API levels, as it cannot detect addresses outside of the 1661 * United States and has a high rate of false positives. On API level 1662 * {@link android.os.Build.VERSION_CODES#O_MR1} and earlier, it also causes 1663 * the entire WebView implementation to be loaded and initialized, which 1664 * can throw {@link android.util.AndroidRuntimeException} or other exceptions 1665 * if the WebView implementation is currently being updated. 1666 * 1667 * @param addr the string to search for addresses 1668 * @return the address, or if no address is found, {@code null} 1669 * @deprecated This method is superseded by {@link TextClassifier#generateLinks( 1670 * android.view.textclassifier.TextLinks.Request)}. Avoid using this method even when targeting 1671 * API levels where no alternative is available. 1672 */ 1673 @Nullable 1674 @Deprecated findAddress(String addr)1675 public static String findAddress(String addr) { 1676 if (addr == null) { 1677 throw new NullPointerException("addr is null"); 1678 } 1679 return FindAddress.findAddress(addr); 1680 } 1681 1682 /** 1683 * For apps targeting the L release, WebView has a new default behavior that reduces 1684 * memory footprint and increases performance by intelligently choosing 1685 * the portion of the HTML document that needs to be drawn. These 1686 * optimizations are transparent to the developers. However, under certain 1687 * circumstances, an App developer may want to disable them: 1688 * <ol> 1689 * <li>When an app uses {@link #onDraw} to do own drawing and accesses portions 1690 * of the page that is way outside the visible portion of the page.</li> 1691 * <li>When an app uses {@link #capturePicture} to capture a very large HTML document. 1692 * Note that capturePicture is a deprecated API.</li> 1693 * </ol> 1694 * Enabling drawing the entire HTML document has a significant performance 1695 * cost. This method should be called before any WebViews are created. 1696 */ enableSlowWholeDocumentDraw()1697 public static void enableSlowWholeDocumentDraw() { 1698 getFactory().getStatics().enableSlowWholeDocumentDraw(); 1699 } 1700 1701 /** 1702 * Clears the highlighting surrounding text matches created by 1703 * {@link #findAllAsync}. 1704 */ clearMatches()1705 public void clearMatches() { 1706 checkThread(); 1707 mProvider.clearMatches(); 1708 } 1709 1710 /** 1711 * Queries the document to see if it contains any image references. The 1712 * message object will be dispatched with arg1 being set to 1 if images 1713 * were found and 0 if the document does not reference any images. 1714 * 1715 * @param response the message that will be dispatched with the result 1716 */ documentHasImages(@onNull Message response)1717 public void documentHasImages(@NonNull Message response) { 1718 checkThread(); 1719 mProvider.documentHasImages(response); 1720 } 1721 1722 /** 1723 * Sets the WebViewClient that will receive various notifications and 1724 * requests. This will replace the current handler. 1725 * 1726 * @param client an implementation of WebViewClient 1727 * @see #getWebViewClient 1728 */ setWebViewClient(@onNull WebViewClient client)1729 public void setWebViewClient(@NonNull WebViewClient client) { 1730 checkThread(); 1731 mProvider.setWebViewClient(client); 1732 } 1733 1734 /** 1735 * Gets the WebViewClient. 1736 * 1737 * @return the WebViewClient, or a default client if not yet set 1738 * @see #setWebViewClient 1739 */ 1740 @NonNull getWebViewClient()1741 public WebViewClient getWebViewClient() { 1742 checkThread(); 1743 return mProvider.getWebViewClient(); 1744 } 1745 1746 1747 /** 1748 * Gets a handle to the WebView renderer process associated with this WebView. 1749 * 1750 * <p>In {@link android.os.Build.VERSION_CODES#O} and above, WebView may 1751 * run in "multiprocess" mode. In multiprocess mode, rendering of web 1752 * content is performed by a sandboxed renderer process separate to the 1753 * application process. This renderer process may be shared with other 1754 * WebViews in the application, but is not shared with other application 1755 * processes. 1756 * 1757 * <p>If WebView is running in multiprocess mode, this method returns a 1758 * handle to the renderer process associated with the WebView, which can 1759 * be used to control the renderer process. 1760 * 1761 * @return the {@link WebViewRenderProcess} renderer handle associated 1762 * with this {@link WebView}, or {@code null} if 1763 * WebView is not runing in multiprocess mode. 1764 */ 1765 @Nullable getWebViewRenderProcess()1766 public WebViewRenderProcess getWebViewRenderProcess() { 1767 checkThread(); 1768 return mProvider.getWebViewRenderProcess(); 1769 } 1770 1771 /** 1772 * Sets the renderer client object associated with this WebView. 1773 * 1774 * <p>The renderer client encapsulates callbacks relevant to WebView renderer 1775 * state. See {@link WebViewRenderProcessClient} for details. 1776 * 1777 * <p>Although many WebView instances may share a single underlying 1778 * renderer, and renderers may live either in the application 1779 * process, or in a sandboxed process that is isolated from the 1780 * application process, instances of {@link WebViewRenderProcessClient} 1781 * are set per-WebView. Callbacks represent renderer events from 1782 * the perspective of this WebView, and may or may not be correlated 1783 * with renderer events affecting other WebViews. 1784 * 1785 * @param executor the Executor on which {@link WebViewRenderProcessClient} 1786 * callbacks will execute. 1787 * @param webViewRenderProcessClient the {@link WebViewRenderProcessClient} 1788 * object. 1789 */ setWebViewRenderProcessClient( @onNull @allbackExecutor Executor executor, @NonNull WebViewRenderProcessClient webViewRenderProcessClient)1790 public void setWebViewRenderProcessClient( 1791 @NonNull @CallbackExecutor Executor executor, 1792 @NonNull WebViewRenderProcessClient webViewRenderProcessClient) { 1793 checkThread(); 1794 mProvider.setWebViewRenderProcessClient( 1795 executor, webViewRenderProcessClient); 1796 } 1797 1798 /** 1799 * Sets the renderer client object associated with this WebView. 1800 * 1801 * See {@link #setWebViewRenderProcessClient(Executor,WebViewRenderProcessClient)} for details. 1802 * 1803 * <p> {@link WebViewRenderProcessClient} callbacks will run on the thread that this WebView was 1804 * initialized on. 1805 * 1806 * @param webViewRenderProcessClient the {@link WebViewRenderProcessClient} object. 1807 */ setWebViewRenderProcessClient( @ullable WebViewRenderProcessClient webViewRenderProcessClient)1808 public void setWebViewRenderProcessClient( 1809 @Nullable WebViewRenderProcessClient webViewRenderProcessClient) { 1810 checkThread(); 1811 mProvider.setWebViewRenderProcessClient(null, webViewRenderProcessClient); 1812 } 1813 1814 /** 1815 * Gets the renderer client object associated with this WebView. 1816 * 1817 * @return the {@link WebViewRenderProcessClient} object associated with this WebView, if one 1818 * has been set via {@link #setWebViewRenderProcessClient(WebViewRenderProcessClient)} 1819 * or {@code null} otherwise. 1820 */ 1821 @Nullable getWebViewRenderProcessClient()1822 public WebViewRenderProcessClient getWebViewRenderProcessClient() { 1823 checkThread(); 1824 return mProvider.getWebViewRenderProcessClient(); 1825 } 1826 1827 /** 1828 * Registers the interface to be used when content can not be handled by 1829 * the rendering engine, and should be downloaded instead. This will replace 1830 * the current handler. 1831 * 1832 * @param listener an implementation of DownloadListener 1833 */ setDownloadListener(@ullable DownloadListener listener)1834 public void setDownloadListener(@Nullable DownloadListener listener) { 1835 checkThread(); 1836 mProvider.setDownloadListener(listener); 1837 } 1838 1839 /** 1840 * Sets the chrome handler. This is an implementation of WebChromeClient for 1841 * use in handling JavaScript dialogs, favicons, titles, and the progress. 1842 * This will replace the current handler. 1843 * 1844 * @param client an implementation of WebChromeClient 1845 * @see #getWebChromeClient 1846 */ setWebChromeClient(@ullable WebChromeClient client)1847 public void setWebChromeClient(@Nullable WebChromeClient client) { 1848 checkThread(); 1849 mProvider.setWebChromeClient(client); 1850 } 1851 1852 /** 1853 * Gets the chrome handler. 1854 * 1855 * @return the WebChromeClient, or {@code null} if not yet set 1856 * @see #setWebChromeClient 1857 */ 1858 @Nullable getWebChromeClient()1859 public WebChromeClient getWebChromeClient() { 1860 checkThread(); 1861 return mProvider.getWebChromeClient(); 1862 } 1863 1864 /** 1865 * Sets the Picture listener. This is an interface used to receive 1866 * notifications of a new Picture. 1867 * 1868 * @param listener an implementation of WebView.PictureListener 1869 * @deprecated This method is now obsolete. 1870 */ 1871 @Deprecated setPictureListener(PictureListener listener)1872 public void setPictureListener(PictureListener listener) { 1873 checkThread(); 1874 mProvider.setPictureListener(listener); 1875 } 1876 1877 /** 1878 * Injects the supplied Java object into this WebView. The object is 1879 * injected into all frames of the web page, including all the iframes, 1880 * using the supplied name. This allows the Java object's methods to be 1881 * accessed from JavaScript. For applications targeted to API 1882 * level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 1883 * and above, only public methods that are annotated with 1884 * {@link android.webkit.JavascriptInterface} can be accessed from JavaScript. 1885 * For applications targeted to API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below, 1886 * all public methods (including the inherited ones) can be accessed, see the 1887 * important security note below for implications. 1888 * <p> Note that injected objects will not appear in JavaScript until the page is next 1889 * (re)loaded. JavaScript should be enabled before injecting the object. For example: 1890 * <pre class="prettyprint"> 1891 * class JsObject { 1892 * {@literal @}JavascriptInterface 1893 * public String toString() { return "injectedObject"; } 1894 * } 1895 * webview.getSettings().setJavaScriptEnabled(true); 1896 * webView.addJavascriptInterface(new JsObject(), "injectedObject"); 1897 * webView.loadData("<!DOCTYPE html><title></title>", "text/html", null); 1898 * webView.loadUrl("javascript:alert(injectedObject.toString())");</pre> 1899 * <p> 1900 * <strong>IMPORTANT:</strong> 1901 * <ul> 1902 * <li> This method can be used to allow JavaScript to control the host 1903 * application. This is a powerful feature, but also presents a security 1904 * risk for apps targeting {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or earlier. 1905 * Apps that target a version later than {@link android.os.Build.VERSION_CODES#JELLY_BEAN} 1906 * are still vulnerable if the app runs on a device running Android earlier than 4.2. 1907 * The most secure way to use this method is to target {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 1908 * and to ensure the method is called only when running on Android 4.2 or later. 1909 * With these older versions, JavaScript could use reflection to access an 1910 * injected object's public fields. Use of this method in a WebView 1911 * containing untrusted content could allow an attacker to manipulate the 1912 * host application in unintended ways, executing Java code with the 1913 * permissions of the host application. Use extreme care when using this 1914 * method in a WebView which could contain untrusted content.</li> 1915 * <li> JavaScript interacts with Java object on a private, background 1916 * thread of this WebView. Care is therefore required to maintain thread 1917 * safety. 1918 * </li> 1919 * <li> Because the object is exposed to all the frames, any frame could 1920 * obtain the object name and call methods on it. There is no way to tell the 1921 * calling frame's origin from the app side, so the app must not assume that 1922 * the caller is trustworthy unless the app can guarantee that no third party 1923 * content is ever loaded into the WebView even inside an iframe.</li> 1924 * <li> The Java object's fields are not accessible.</li> 1925 * <li> For applications targeted to API level {@link android.os.Build.VERSION_CODES#LOLLIPOP} 1926 * and above, methods of injected Java objects are enumerable from 1927 * JavaScript.</li> 1928 * </ul> 1929 * 1930 * @param object the Java object to inject into this WebView's JavaScript 1931 * context. {@code null} values are ignored. 1932 * @param name the name used to expose the object in JavaScript 1933 */ addJavascriptInterface(@onNull Object object, @NonNull String name)1934 public void addJavascriptInterface(@NonNull Object object, @NonNull String name) { 1935 checkThread(); 1936 mProvider.addJavascriptInterface(object, name); 1937 } 1938 1939 /** 1940 * Removes a previously injected Java object from this WebView. Note that 1941 * the removal will not be reflected in JavaScript until the page is next 1942 * (re)loaded. See {@link #addJavascriptInterface}. 1943 * 1944 * @param name the name used to expose the object in JavaScript 1945 */ removeJavascriptInterface(@onNull String name)1946 public void removeJavascriptInterface(@NonNull String name) { 1947 checkThread(); 1948 mProvider.removeJavascriptInterface(name); 1949 } 1950 1951 /** 1952 * Creates a message channel to communicate with JS and returns the message 1953 * ports that represent the endpoints of this message channel. The HTML5 message 1954 * channel functionality is described 1955 * <a href="https://html.spec.whatwg.org/multipage/comms.html#messagechannel">here 1956 * </a> 1957 * 1958 * <p>The returned message channels are entangled and already in started state. 1959 * 1960 * @return the two message ports that form the message channel. 1961 */ 1962 @NonNull createWebMessageChannel()1963 public WebMessagePort[] createWebMessageChannel() { 1964 checkThread(); 1965 return mProvider.createWebMessageChannel(); 1966 } 1967 1968 /** 1969 * Post a message to main frame. The embedded application can restrict the 1970 * messages to a certain target origin. See 1971 * <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages"> 1972 * HTML5 spec</a> for how target origin can be used. 1973 * <p> 1974 * A target origin can be set as a wildcard ("*"). However this is not recommended. 1975 * See the page above for security issues. 1976 * <p> 1977 * Content loaded via {@link #loadData(String,String,String)} will not have a 1978 * valid origin, and thus cannot be sent messages securely. If you need to send 1979 * messages using this function, you should use 1980 * {@link #loadDataWithBaseURL(String,String,String,String,String)} with a valid 1981 * HTTP or HTTPS {@code baseUrl} to define a valid origin that can be used for 1982 * messaging. 1983 * 1984 * @param message the WebMessage 1985 * @param targetOrigin the target origin. 1986 */ postWebMessage(@onNull WebMessage message, @NonNull Uri targetOrigin)1987 public void postWebMessage(@NonNull WebMessage message, @NonNull Uri targetOrigin) { 1988 checkThread(); 1989 mProvider.postMessageToMainFrame(message, targetOrigin); 1990 } 1991 1992 /** 1993 * Gets the WebSettings object used to control the settings for this 1994 * WebView. 1995 * 1996 * @return a WebSettings object that can be used to control this WebView's 1997 * settings 1998 */ 1999 @NonNull getSettings()2000 public WebSettings getSettings() { 2001 checkThread(); 2002 return mProvider.getSettings(); 2003 } 2004 2005 /** 2006 * Enables debugging of web contents (HTML / CSS / JavaScript) 2007 * loaded into any WebViews of this application. This flag can be enabled 2008 * in order to facilitate debugging of web layouts and JavaScript 2009 * code running inside WebViews. Please refer to WebView documentation 2010 * for the debugging guide. 2011 * <p> 2012 * In WebView 113.0.5656.0 and later, this is enabled automatically if the 2013 * app is declared as 2014 * <a href="https://developer.android.com/guide/topics/manifest/application-element#debug"> 2015 * {@code android:debuggable="true"}</a> in its manifest; otherwise, the 2016 * default is {@code false}. 2017 * <p> 2018 * Enabling web contents debugging allows the state of any WebView in the 2019 * app to be inspected and modified by the user via adb. This is a security 2020 * liability and should not be enabled in production builds of apps unless 2021 * this is an explicitly intended use of the app. More info on 2022 * <a href="https://developer.android.com/topic/security/risks/android-debuggable"> 2023 * secure debug settings</a>. 2024 * 2025 * @param enabled whether to enable web contents debugging 2026 */ setWebContentsDebuggingEnabled(boolean enabled)2027 public static void setWebContentsDebuggingEnabled(boolean enabled) { 2028 getFactory().getStatics().setWebContentsDebuggingEnabled(enabled); 2029 } 2030 2031 /** 2032 * Gets the list of currently loaded plugins. 2033 * 2034 * @return the list of currently loaded plugins 2035 * @deprecated This was used for Gears, which has been deprecated. 2036 * @hide 2037 */ 2038 @Deprecated 2039 @UnsupportedAppUsage getPluginList()2040 public static synchronized PluginList getPluginList() { 2041 return new PluginList(); 2042 } 2043 2044 /** 2045 * Define the directory used to store WebView data for the current process. 2046 * The provided suffix will be used when constructing data and cache 2047 * directory paths. If this API is not called, no suffix will be used. 2048 * Each directory can be used by only one process in the application. If more 2049 * than one process in an app wishes to use WebView, only one process can use 2050 * the default directory, and other processes must call this API to define 2051 * a unique suffix. 2052 * <p> 2053 * This means that different processes in the same application cannot directly 2054 * share WebView-related data, since the data directories must be distinct. 2055 * Applications that use this API may have to explicitly pass data between 2056 * processes. For example, login cookies may have to be copied from one 2057 * process's cookie jar to the other using {@link CookieManager} if both 2058 * processes' WebViews are intended to be logged in. 2059 * <p> 2060 * Most applications should simply ensure that all components of the app 2061 * that rely on WebView are in the same process, to avoid needing multiple 2062 * data directories. The {@link #disableWebView} method can be used to ensure 2063 * that the other processes do not use WebView by accident in this case. 2064 * <p> 2065 * This API must be called before any instances of WebView are created in 2066 * this process and before any other methods in the android.webkit package 2067 * are called by this process. 2068 * 2069 * @param suffix The directory name suffix to be used for the current 2070 * process. Must not contain a path separator. 2071 * @throws IllegalStateException if WebView has already been initialized 2072 * in the current process. 2073 * @throws IllegalArgumentException if the suffix contains a path separator. 2074 */ setDataDirectorySuffix(@onNull String suffix)2075 public static void setDataDirectorySuffix(@NonNull String suffix) { 2076 WebViewFactory.setDataDirectorySuffix(suffix); 2077 } 2078 2079 /** 2080 * Indicate that the current process does not intend to use WebView, and 2081 * that an exception should be thrown if a WebView is created or any other 2082 * methods in the android.webkit package are used. 2083 * <p> 2084 * Applications with multiple processes may wish to call this in processes 2085 * that are not intended to use WebView to avoid accidentally incurring 2086 * the memory usage of initializing WebView in long-lived processes that 2087 * have no need for it, and to prevent potential data directory conflicts 2088 * (see {@link #setDataDirectorySuffix}). 2089 * <p> 2090 * For example, an audio player application with one process for its 2091 * activities and another process for its playback service may wish to call 2092 * this method in the playback service's {@link android.app.Service#onCreate}. 2093 * 2094 * @throws IllegalStateException if WebView has already been initialized 2095 * in the current process. 2096 */ disableWebView()2097 public static void disableWebView() { 2098 WebViewFactory.disableWebView(); 2099 } 2100 2101 2102 /** 2103 * @deprecated This was used for Gears, which has been deprecated. 2104 * @hide 2105 */ 2106 @Deprecated 2107 @UnsupportedAppUsage refreshPlugins(boolean reloadOpenPages)2108 public void refreshPlugins(boolean reloadOpenPages) { 2109 checkThread(); 2110 } 2111 2112 /** 2113 * Puts this WebView into text selection mode. Do not rely on this 2114 * functionality; it will be deprecated in the future. 2115 * 2116 * @deprecated This method is now obsolete. 2117 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 2118 */ 2119 @Deprecated 2120 @UnsupportedAppUsage emulateShiftHeld()2121 public void emulateShiftHeld() { 2122 checkThread(); 2123 } 2124 2125 /** 2126 * @deprecated WebView no longer needs to implement 2127 * ViewGroup.OnHierarchyChangeListener. This method does nothing now. 2128 */ 2129 @Override 2130 // Cannot add @hide as this can always be accessed via the interface. 2131 @Deprecated onChildViewAdded(View parent, View child)2132 public void onChildViewAdded(View parent, View child) {} 2133 2134 /** 2135 * @deprecated WebView no longer needs to implement 2136 * ViewGroup.OnHierarchyChangeListener. This method does nothing now. 2137 */ 2138 @Override 2139 // Cannot add @hide as this can always be accessed via the interface. 2140 @Deprecated onChildViewRemoved(View p, View child)2141 public void onChildViewRemoved(View p, View child) {} 2142 2143 /** 2144 * @deprecated WebView should not have implemented 2145 * ViewTreeObserver.OnGlobalFocusChangeListener. This method does nothing now. 2146 */ 2147 @Override 2148 // Cannot add @hide as this can always be accessed via the interface. 2149 @Deprecated onGlobalFocusChanged(View oldFocus, View newFocus)2150 public void onGlobalFocusChanged(View oldFocus, View newFocus) { 2151 } 2152 2153 /** 2154 * @deprecated Only the default case, {@code true}, will be supported in a future version. 2155 */ 2156 @Deprecated setMapTrackballToArrowKeys(boolean setMap)2157 public void setMapTrackballToArrowKeys(boolean setMap) { 2158 checkThread(); 2159 mProvider.setMapTrackballToArrowKeys(setMap); 2160 } 2161 2162 flingScroll(int vx, int vy)2163 public void flingScroll(int vx, int vy) { 2164 checkThread(); 2165 mProvider.flingScroll(vx, vy); 2166 } 2167 2168 /** 2169 * Gets the zoom controls for this WebView, as a separate View. The caller 2170 * is responsible for inserting this View into the layout hierarchy. 2171 * <p/> 2172 * API level {@link android.os.Build.VERSION_CODES#CUPCAKE} introduced 2173 * built-in zoom mechanisms for the WebView, as opposed to these separate 2174 * zoom controls. The built-in mechanisms are preferred and can be enabled 2175 * using {@link WebSettings#setBuiltInZoomControls}. 2176 * 2177 * @deprecated the built-in zoom mechanisms are preferred 2178 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} 2179 */ 2180 @Deprecated 2181 @UnsupportedAppUsage getZoomControls()2182 public View getZoomControls() { 2183 checkThread(); 2184 return mProvider.getZoomControls(); 2185 } 2186 2187 /** 2188 * Gets whether this WebView can be zoomed in. 2189 * 2190 * @return {@code true} if this WebView can be zoomed in 2191 * 2192 * @deprecated This method is prone to inaccuracy due to race conditions 2193 * between the web rendering and UI threads; prefer 2194 * {@link WebViewClient#onScaleChanged}. 2195 */ 2196 @Deprecated canZoomIn()2197 public boolean canZoomIn() { 2198 checkThread(); 2199 return mProvider.canZoomIn(); 2200 } 2201 2202 /** 2203 * Gets whether this WebView can be zoomed out. 2204 * 2205 * @return {@code true} if this WebView can be zoomed out 2206 * 2207 * @deprecated This method is prone to inaccuracy due to race conditions 2208 * between the web rendering and UI threads; prefer 2209 * {@link WebViewClient#onScaleChanged}. 2210 */ 2211 @Deprecated canZoomOut()2212 public boolean canZoomOut() { 2213 checkThread(); 2214 return mProvider.canZoomOut(); 2215 } 2216 2217 /** 2218 * Performs a zoom operation in this WebView. 2219 * 2220 * @param zoomFactor the zoom factor to apply. The zoom factor will be clamped to the WebView's 2221 * zoom limits. This value must be in the range 0.01 to 100.0 inclusive. 2222 */ zoomBy(float zoomFactor)2223 public void zoomBy(float zoomFactor) { 2224 checkThread(); 2225 if (zoomFactor < 0.01) 2226 throw new IllegalArgumentException("zoomFactor must be greater than 0.01."); 2227 if (zoomFactor > 100.0) 2228 throw new IllegalArgumentException("zoomFactor must be less than 100."); 2229 mProvider.zoomBy(zoomFactor); 2230 } 2231 2232 /** 2233 * Performs zoom in in this WebView. 2234 * 2235 * @return {@code true} if zoom in succeeds, {@code false} if no zoom changes 2236 */ zoomIn()2237 public boolean zoomIn() { 2238 checkThread(); 2239 return mProvider.zoomIn(); 2240 } 2241 2242 /** 2243 * Performs zoom out in this WebView. 2244 * 2245 * @return {@code true} if zoom out succeeds, {@code false} if no zoom changes 2246 */ zoomOut()2247 public boolean zoomOut() { 2248 checkThread(); 2249 return mProvider.zoomOut(); 2250 } 2251 2252 /** 2253 * @deprecated This method is now obsolete. 2254 * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 2255 */ 2256 @Deprecated 2257 @UnsupportedAppUsage debugDump()2258 public void debugDump() { 2259 checkThread(); 2260 } 2261 2262 /** 2263 * See {@link ViewDebug.HierarchyHandler#dumpViewHierarchyWithProperties(BufferedWriter, int)} 2264 * @hide 2265 */ 2266 @Override dumpViewHierarchyWithProperties(BufferedWriter out, int level)2267 public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) { 2268 mProvider.dumpViewHierarchyWithProperties(out, level); 2269 } 2270 2271 /** 2272 * See {@link ViewDebug.HierarchyHandler#findHierarchyView(String, int)} 2273 * @hide 2274 */ 2275 @Override findHierarchyView(String className, int hashCode)2276 public View findHierarchyView(String className, int hashCode) { 2277 return mProvider.findHierarchyView(className, hashCode); 2278 } 2279 2280 /** @hide */ 2281 @IntDef(prefix = { "RENDERER_PRIORITY_" }, value = { 2282 RENDERER_PRIORITY_WAIVED, 2283 RENDERER_PRIORITY_BOUND, 2284 RENDERER_PRIORITY_IMPORTANT 2285 }) 2286 @Retention(RetentionPolicy.SOURCE) 2287 public @interface RendererPriority {} 2288 2289 /** 2290 * This is the lowest binding priority for the WebView renderer process. This is equivalent to 2291 * {@link Context#BIND_WAIVE_PRIORITY}. At this priority level {@link WebView} renderers will be 2292 * frequent targets for being killed when the system is running low on memory. 2293 * 2294 * <p>If using this priority, we recommend handling the {@link 2295 * WebViewClient#onRenderProcessGone} callback to recover from low memory kills as well as other 2296 * types of renderer crashes. 2297 * 2298 * @see #setRendererPriorityPolicy 2299 * @see #getRendererPriorityPolicy 2300 * @see RenderProcessGoneDetail#rendererPriorityAtExit 2301 */ 2302 public static final int RENDERER_PRIORITY_WAIVED = 0; 2303 2304 /** 2305 * This is the medium binding priority for the WebView renderer process. This is equivalent to 2306 * the standard priority used by the system for calls to {@link 2307 * Context#bindService(Intent,android.content.ServiceConnection,int)} when no flags are 2308 * provided. At this priority level {@link WebView} renderers will be slightly more likely 2309 * targets for being killed when the system is running low on memory. 2310 * 2311 * <p>If using this priority, we recommend handling the {@link 2312 * WebViewClient#onRenderProcessGone} callback to recover from low memory kills as well as other 2313 * types of renderer crashes. 2314 * 2315 * @see #setRendererPriorityPolicy 2316 * @see #getRendererPriorityPolicy 2317 * @see RenderProcessGoneDetail#rendererPriorityAtExit 2318 */ 2319 public static final int RENDERER_PRIORITY_BOUND = 1; 2320 2321 /** 2322 * This is the highest binding priority for the WebView renderer process, and the default value 2323 * WebView uses to bind to the renderer process. This is equivalent to {@link 2324 * Context#BIND_IMPORTANT}. At this priority level {@link WebView} renderers are less likely to 2325 * be killed when the system is running low on memory and will have the same priority as your 2326 * app's main process. 2327 * 2328 * <p>It's still possible for the renderer process to be killed when the system is running low 2329 * on memory, however specifying this priority makes this situation less likely. It's also still 2330 * possible for the renderer process to crash for other reasons. You may optionally still choose 2331 * to handle {@link WebViewClient#onRenderProcessGone} in order to recover from a killed or 2332 * crashed renderer process. 2333 * 2334 * @see #setRendererPriorityPolicy 2335 * @see #getRendererPriorityPolicy 2336 * @see RenderProcessGoneDetail#rendererPriorityAtExit 2337 */ 2338 public static final int RENDERER_PRIORITY_IMPORTANT = 2; 2339 2340 /** 2341 * Set the renderer priority policy for this {@link WebView}. The 2342 * priority policy will be used to determine whether an out of 2343 * process renderer should be considered to be a target for OOM 2344 * killing. 2345 * 2346 * <p>Because a renderer can be associated with more than one 2347 * WebView, the final priority it is computed as the maximum of 2348 * any attached WebViews. When a WebView is destroyed it will 2349 * cease to be considerered when calculating the renderer 2350 * priority. Once no WebViews remain associated with the renderer, 2351 * the priority of the renderer will be reduced to 2352 * {@link #RENDERER_PRIORITY_WAIVED}. 2353 * 2354 * <p>The default policy is to set the priority to 2355 * {@link #RENDERER_PRIORITY_IMPORTANT} regardless of visibility, 2356 * and this should not be changed unless the caller also handles 2357 * renderer crashes with 2358 * {@link WebViewClient#onRenderProcessGone}. Any other setting 2359 * will result in WebView renderers being killed by the system 2360 * more aggressively than the application. 2361 * 2362 * @param rendererRequestedPriority the minimum priority at which 2363 * this WebView desires the renderer process to be bound. 2364 * @param waivedWhenNotVisible if {@code true}, this flag specifies that 2365 * when this WebView is not visible, it will be treated as 2366 * if it had requested a priority of 2367 * {@link #RENDERER_PRIORITY_WAIVED}. 2368 * @see #getRendererPriorityPolicy 2369 * @see RenderProcessGoneDetail#rendererPriorityAtExit 2370 */ setRendererPriorityPolicy( @endererPriority int rendererRequestedPriority, boolean waivedWhenNotVisible)2371 public void setRendererPriorityPolicy( 2372 @RendererPriority int rendererRequestedPriority, 2373 boolean waivedWhenNotVisible) { 2374 mProvider.setRendererPriorityPolicy(rendererRequestedPriority, waivedWhenNotVisible); 2375 } 2376 2377 /** 2378 * Get the requested renderer priority for this WebView. 2379 * 2380 * @return the requested renderer priority policy. 2381 * @see #setRendererPriorityPolicy 2382 * @see RenderProcessGoneDetail#rendererPriorityAtExit 2383 */ 2384 @InspectableProperty(hasAttributeId = false, enumMapping = { 2385 @InspectableProperty.EnumEntry(name = "waived", value = RENDERER_PRIORITY_WAIVED), 2386 @InspectableProperty.EnumEntry(name = "bound", value = RENDERER_PRIORITY_BOUND), 2387 @InspectableProperty.EnumEntry(name = "important", value = RENDERER_PRIORITY_IMPORTANT) 2388 }) 2389 @RendererPriority getRendererRequestedPriority()2390 public int getRendererRequestedPriority() { 2391 return mProvider.getRendererRequestedPriority(); 2392 } 2393 2394 /** 2395 * Return whether this WebView requests a priority of 2396 * {@link #RENDERER_PRIORITY_WAIVED} when not visible. 2397 * 2398 * @return whether this WebView requests a priority of 2399 * {@link #RENDERER_PRIORITY_WAIVED} when not visible. 2400 */ 2401 @InspectableProperty(hasAttributeId = false) getRendererPriorityWaivedWhenNotVisible()2402 public boolean getRendererPriorityWaivedWhenNotVisible() { 2403 return mProvider.getRendererPriorityWaivedWhenNotVisible(); 2404 } 2405 2406 /** 2407 * Sets the {@link TextClassifier} for this WebView. 2408 */ setTextClassifier(@ullable TextClassifier textClassifier)2409 public void setTextClassifier(@Nullable TextClassifier textClassifier) { 2410 mProvider.setTextClassifier(textClassifier); 2411 } 2412 2413 /** 2414 * Returns the {@link TextClassifier} used by this WebView. 2415 * If no TextClassifier has been set, this WebView uses the default set by the system. 2416 */ 2417 @NonNull getTextClassifier()2418 public TextClassifier getTextClassifier() { 2419 return mProvider.getTextClassifier(); 2420 } 2421 2422 /** 2423 * Returns the {@link ClassLoader} used to load internal WebView classes. 2424 * This method is meant for use by the WebView Support Library, there is no reason to use this 2425 * method otherwise. 2426 */ 2427 @NonNull getWebViewClassLoader()2428 public static ClassLoader getWebViewClassLoader() { 2429 return getFactory().getWebViewClassLoader(); 2430 } 2431 2432 /** 2433 * Returns the {@link Looper} corresponding to the thread on which WebView calls must be made. 2434 */ 2435 @NonNull getWebViewLooper()2436 public Looper getWebViewLooper() { 2437 return mWebViewThread; 2438 } 2439 2440 //------------------------------------------------------------------------- 2441 // Interface for WebView providers 2442 //------------------------------------------------------------------------- 2443 2444 /** 2445 * Gets the WebViewProvider. Used by providers to obtain the underlying 2446 * implementation, e.g. when the application responds to 2447 * WebViewClient.onCreateWindow() request. 2448 * 2449 * @hide WebViewProvider is not public API. 2450 */ 2451 @SystemApi getWebViewProvider()2452 public WebViewProvider getWebViewProvider() { 2453 return mProvider; 2454 } 2455 2456 /** 2457 * Callback interface, allows the provider implementation to access non-public methods 2458 * and fields, and make super-class calls in this WebView instance. 2459 * @hide Only for use by WebViewProvider implementations 2460 */ 2461 @SystemApi 2462 public class PrivateAccess { 2463 // ---- Access to super-class methods ---- super_getScrollBarStyle()2464 public int super_getScrollBarStyle() { 2465 return WebView.super.getScrollBarStyle(); 2466 } 2467 super_scrollTo(int scrollX, int scrollY)2468 public void super_scrollTo(int scrollX, int scrollY) { 2469 WebView.super.scrollTo(scrollX, scrollY); 2470 } 2471 super_computeScroll()2472 public void super_computeScroll() { 2473 WebView.super.computeScroll(); 2474 } 2475 super_onHoverEvent(MotionEvent event)2476 public boolean super_onHoverEvent(MotionEvent event) { 2477 return WebView.super.onHoverEvent(event); 2478 } 2479 super_performAccessibilityAction(int action, Bundle arguments)2480 public boolean super_performAccessibilityAction(int action, Bundle arguments) { 2481 return WebView.super.performAccessibilityActionInternal(action, arguments); 2482 } 2483 super_performLongClick()2484 public boolean super_performLongClick() { 2485 return WebView.super.performLongClick(); 2486 } 2487 super_setFrame(int left, int top, int right, int bottom)2488 public boolean super_setFrame(int left, int top, int right, int bottom) { 2489 return WebView.super.setFrame(left, top, right, bottom); 2490 } 2491 super_dispatchKeyEvent(KeyEvent event)2492 public boolean super_dispatchKeyEvent(KeyEvent event) { 2493 return WebView.super.dispatchKeyEvent(event); 2494 } 2495 super_onGenericMotionEvent(MotionEvent event)2496 public boolean super_onGenericMotionEvent(MotionEvent event) { 2497 return WebView.super.onGenericMotionEvent(event); 2498 } 2499 super_requestFocus(int direction, Rect previouslyFocusedRect)2500 public boolean super_requestFocus(int direction, Rect previouslyFocusedRect) { 2501 return WebView.super.requestFocus(direction, previouslyFocusedRect); 2502 } 2503 super_setLayoutParams(ViewGroup.LayoutParams params)2504 public void super_setLayoutParams(ViewGroup.LayoutParams params) { 2505 WebView.super.setLayoutParams(params); 2506 } 2507 super_startActivityForResult(Intent intent, int requestCode)2508 public void super_startActivityForResult(Intent intent, int requestCode) { 2509 WebView.super.startActivityForResult(intent, requestCode); 2510 } 2511 2512 /** 2513 * @see View#onApplyWindowInsets(WindowInsets) 2514 */ 2515 @Nullable super_onApplyWindowInsets(@ullable WindowInsets insets)2516 public WindowInsets super_onApplyWindowInsets(@Nullable WindowInsets insets) { 2517 return WebView.super.onApplyWindowInsets(insets); 2518 } 2519 2520 // ---- Access to non-public methods ---- overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent)2521 public void overScrollBy(int deltaX, int deltaY, 2522 int scrollX, int scrollY, 2523 int scrollRangeX, int scrollRangeY, 2524 int maxOverScrollX, int maxOverScrollY, 2525 boolean isTouchEvent) { 2526 WebView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, 2527 maxOverScrollX, maxOverScrollY, isTouchEvent); 2528 } 2529 awakenScrollBars(int duration)2530 public void awakenScrollBars(int duration) { 2531 WebView.this.awakenScrollBars(duration); 2532 } 2533 awakenScrollBars(int duration, boolean invalidate)2534 public void awakenScrollBars(int duration, boolean invalidate) { 2535 WebView.this.awakenScrollBars(duration, invalidate); 2536 } 2537 getVerticalScrollFactor()2538 public float getVerticalScrollFactor() { 2539 return WebView.this.getVerticalScrollFactor(); 2540 } 2541 getHorizontalScrollFactor()2542 public float getHorizontalScrollFactor() { 2543 return WebView.this.getHorizontalScrollFactor(); 2544 } 2545 setMeasuredDimension(int measuredWidth, int measuredHeight)2546 public void setMeasuredDimension(int measuredWidth, int measuredHeight) { 2547 WebView.this.setMeasuredDimension(measuredWidth, measuredHeight); 2548 } 2549 onScrollChanged(int l, int t, int oldl, int oldt)2550 public void onScrollChanged(int l, int t, int oldl, int oldt) { 2551 WebView.this.onScrollChanged(l, t, oldl, oldt); 2552 } 2553 getHorizontalScrollbarHeight()2554 public int getHorizontalScrollbarHeight() { 2555 return WebView.this.getHorizontalScrollbarHeight(); 2556 } 2557 super_onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b)2558 public void super_onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, 2559 int l, int t, int r, int b) { 2560 WebView.super.onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b); 2561 } 2562 2563 // ---- Access to (non-public) fields ---- 2564 /** Raw setter for the scroll X value, without invoking onScrollChanged handlers etc. */ setScrollXRaw(int scrollX)2565 public void setScrollXRaw(int scrollX) { 2566 WebView.this.mScrollX = scrollX; 2567 } 2568 2569 /** Raw setter for the scroll Y value, without invoking onScrollChanged handlers etc. */ setScrollYRaw(int scrollY)2570 public void setScrollYRaw(int scrollY) { 2571 WebView.this.mScrollY = scrollY; 2572 } 2573 2574 } 2575 2576 //------------------------------------------------------------------------- 2577 // Package-private internal stuff 2578 //------------------------------------------------------------------------- 2579 2580 // Only used by android.webkit.FindActionModeCallback. setFindDialogFindListener(FindListener listener)2581 void setFindDialogFindListener(FindListener listener) { 2582 checkThread(); 2583 setupFindListenerIfNeeded(); 2584 mFindListener.mFindDialogFindListener = listener; 2585 } 2586 2587 // Only used by android.webkit.FindActionModeCallback. 2588 @UnsupportedAppUsage notifyFindDialogDismissed()2589 void notifyFindDialogDismissed() { 2590 checkThread(); 2591 mProvider.notifyFindDialogDismissed(); 2592 } 2593 2594 //------------------------------------------------------------------------- 2595 // Private internal stuff 2596 //------------------------------------------------------------------------- 2597 2598 @UnsupportedAppUsage 2599 private WebViewProvider mProvider; 2600 2601 /** 2602 * In addition to the FindListener that the user may set via the WebView.setFindListener 2603 * API, FindActionModeCallback will register it's own FindListener. We keep them separate 2604 * via this class so that the two FindListeners can potentially exist at once. 2605 */ 2606 private class FindListenerDistributor implements FindListener { 2607 private FindListener mFindDialogFindListener; 2608 private FindListener mUserFindListener; 2609 2610 @Override onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting)2611 public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, 2612 boolean isDoneCounting) { 2613 if (mFindDialogFindListener != null) { 2614 mFindDialogFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, 2615 isDoneCounting); 2616 } 2617 2618 if (mUserFindListener != null) { 2619 mUserFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, 2620 isDoneCounting); 2621 } 2622 } 2623 } 2624 private FindListenerDistributor mFindListener; 2625 setupFindListenerIfNeeded()2626 private void setupFindListenerIfNeeded() { 2627 if (mFindListener == null) { 2628 mFindListener = new FindListenerDistributor(); 2629 mProvider.setFindListener(mFindListener); 2630 } 2631 } 2632 ensureProviderCreated()2633 private void ensureProviderCreated() { 2634 checkThread(); 2635 if (mProvider == null) { 2636 // As this can get called during the base class constructor chain, pass the minimum 2637 // number of dependencies here; the rest are deferred to init(). 2638 mProvider = getFactory().createWebView(this, new PrivateAccess()); 2639 } 2640 } 2641 2642 @UnsupportedAppUsage getFactory()2643 private static WebViewFactoryProvider getFactory() { 2644 return WebViewFactory.getProvider(); 2645 } 2646 2647 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2648 private final Looper mWebViewThread = Looper.myLooper(); 2649 2650 @UnsupportedAppUsage checkThread()2651 private void checkThread() { 2652 // Ignore mWebViewThread == null because this can be called during in the super class 2653 // constructor, before this class's own constructor has even started. 2654 if (mWebViewThread != null && Looper.myLooper() != mWebViewThread) { 2655 Throwable throwable = new Throwable( 2656 "A WebView method was called on thread '" + 2657 Thread.currentThread().getName() + "'. " + 2658 "All WebView methods must be called on the same thread. " + 2659 "(Expected Looper " + mWebViewThread + " called on " + Looper.myLooper() + 2660 ", FYI main Looper is " + Looper.getMainLooper() + ")"); 2661 Log.w(LOGTAG, Log.getStackTraceString(throwable)); 2662 StrictMode.onWebViewMethodCalledOnWrongThread(throwable); 2663 2664 if (sEnforceThreadChecking) { 2665 throw new RuntimeException(throwable); 2666 } 2667 } 2668 } 2669 2670 //------------------------------------------------------------------------- 2671 // Override View methods 2672 //------------------------------------------------------------------------- 2673 2674 // TODO: Add a test that enumerates all methods in ViewDelegte & ScrollDelegate, and ensures 2675 // there's a corresponding override (or better, caller) for each of them in here. 2676 2677 @Override onAttachedToWindow()2678 protected void onAttachedToWindow() { 2679 super.onAttachedToWindow(); 2680 mProvider.getViewDelegate().onAttachedToWindow(); 2681 } 2682 2683 /** @hide */ 2684 @Override onDetachedFromWindowInternal()2685 protected void onDetachedFromWindowInternal() { 2686 mProvider.getViewDelegate().onDetachedFromWindow(); 2687 super.onDetachedFromWindowInternal(); 2688 } 2689 2690 /** @hide */ 2691 @Override onMovedToDisplay(int displayId, Configuration config)2692 public void onMovedToDisplay(int displayId, Configuration config) { 2693 mProvider.getViewDelegate().onMovedToDisplay(displayId, config); 2694 } 2695 2696 @Override setLayoutParams(ViewGroup.LayoutParams params)2697 public void setLayoutParams(ViewGroup.LayoutParams params) { 2698 mProvider.getViewDelegate().setLayoutParams(params); 2699 } 2700 2701 @Override setOverScrollMode(int mode)2702 public void setOverScrollMode(int mode) { 2703 super.setOverScrollMode(mode); 2704 // This method may be called in the constructor chain, before the WebView provider is 2705 // created. 2706 ensureProviderCreated(); 2707 mProvider.getViewDelegate().setOverScrollMode(mode); 2708 } 2709 2710 @Override setScrollBarStyle(int style)2711 public void setScrollBarStyle(int style) { 2712 mProvider.getViewDelegate().setScrollBarStyle(style); 2713 super.setScrollBarStyle(style); 2714 } 2715 2716 @Override computeHorizontalScrollRange()2717 protected int computeHorizontalScrollRange() { 2718 return mProvider.getScrollDelegate().computeHorizontalScrollRange(); 2719 } 2720 2721 @Override computeHorizontalScrollOffset()2722 protected int computeHorizontalScrollOffset() { 2723 return mProvider.getScrollDelegate().computeHorizontalScrollOffset(); 2724 } 2725 2726 @Override computeVerticalScrollRange()2727 protected int computeVerticalScrollRange() { 2728 return mProvider.getScrollDelegate().computeVerticalScrollRange(); 2729 } 2730 2731 @Override computeVerticalScrollOffset()2732 protected int computeVerticalScrollOffset() { 2733 return mProvider.getScrollDelegate().computeVerticalScrollOffset(); 2734 } 2735 2736 @Override computeVerticalScrollExtent()2737 protected int computeVerticalScrollExtent() { 2738 return mProvider.getScrollDelegate().computeVerticalScrollExtent(); 2739 } 2740 2741 @Override computeScroll()2742 public void computeScroll() { 2743 mProvider.getScrollDelegate().computeScroll(); 2744 } 2745 2746 @Override onHoverEvent(MotionEvent event)2747 public boolean onHoverEvent(MotionEvent event) { 2748 return mProvider.getViewDelegate().onHoverEvent(event); 2749 } 2750 2751 @Override onTouchEvent(MotionEvent event)2752 public boolean onTouchEvent(MotionEvent event) { 2753 return mProvider.getViewDelegate().onTouchEvent(event); 2754 } 2755 2756 @Override onGenericMotionEvent(MotionEvent event)2757 public boolean onGenericMotionEvent(MotionEvent event) { 2758 return mProvider.getViewDelegate().onGenericMotionEvent(event); 2759 } 2760 2761 @Override onTrackballEvent(MotionEvent event)2762 public boolean onTrackballEvent(MotionEvent event) { 2763 return mProvider.getViewDelegate().onTrackballEvent(event); 2764 } 2765 2766 @Override onKeyDown(int keyCode, KeyEvent event)2767 public boolean onKeyDown(int keyCode, KeyEvent event) { 2768 return mProvider.getViewDelegate().onKeyDown(keyCode, event); 2769 } 2770 2771 @Override onKeyUp(int keyCode, KeyEvent event)2772 public boolean onKeyUp(int keyCode, KeyEvent event) { 2773 return mProvider.getViewDelegate().onKeyUp(keyCode, event); 2774 } 2775 2776 @Override onKeyMultiple(int keyCode, int repeatCount, KeyEvent event)2777 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 2778 return mProvider.getViewDelegate().onKeyMultiple(keyCode, repeatCount, event); 2779 } 2780 2781 /* 2782 TODO: These are not currently implemented in WebViewClassic, but it seems inconsistent not 2783 to be delegating them too. 2784 2785 @Override 2786 public boolean onKeyPreIme(int keyCode, KeyEvent event) { 2787 return mProvider.getViewDelegate().onKeyPreIme(keyCode, event); 2788 } 2789 @Override 2790 public boolean onKeyLongPress(int keyCode, KeyEvent event) { 2791 return mProvider.getViewDelegate().onKeyLongPress(keyCode, event); 2792 } 2793 @Override 2794 public boolean onKeyShortcut(int keyCode, KeyEvent event) { 2795 return mProvider.getViewDelegate().onKeyShortcut(keyCode, event); 2796 } 2797 */ 2798 2799 @Override getAccessibilityNodeProvider()2800 public AccessibilityNodeProvider getAccessibilityNodeProvider() { 2801 AccessibilityNodeProvider provider = 2802 mProvider.getViewDelegate().getAccessibilityNodeProvider(); 2803 return provider == null ? super.getAccessibilityNodeProvider() : provider; 2804 } 2805 2806 @Deprecated 2807 @Override shouldDelayChildPressedState()2808 public boolean shouldDelayChildPressedState() { 2809 return mProvider.getViewDelegate().shouldDelayChildPressedState(); 2810 } 2811 2812 @Override getAccessibilityClassName()2813 public CharSequence getAccessibilityClassName() { 2814 return WebView.class.getName(); 2815 } 2816 2817 @Override onProvideVirtualStructure(ViewStructure structure)2818 public void onProvideVirtualStructure(ViewStructure structure) { 2819 mProvider.getViewDelegate().onProvideVirtualStructure(structure); 2820 } 2821 2822 /** 2823 * {@inheritDoc} 2824 * 2825 * <p>The {@link ViewStructure} traditionally represents a {@link View}, while for web pages 2826 * it represent HTML nodes. Hence, it's necessary to "map" the HTML properties in a way that is 2827 * understood by the {@link android.service.autofill.AutofillService} implementations: 2828 * 2829 * <ol> 2830 * <li>Only the HTML nodes inside a {@code FORM} are generated. 2831 * <li>The source of the HTML is set using {@link ViewStructure#setWebDomain(String)} in the 2832 * node representing the WebView. 2833 * <li>If a web page has multiple {@code FORM}s, only the data for the current form is 2834 * represented—if the user taps a field from another form, then the current autofill 2835 * context is canceled (by calling {@link android.view.autofill.AutofillManager#cancel()} and 2836 * a new context is created for that {@code FORM}. 2837 * <li>Similarly, if the page has {@code IFRAME} nodes, they are not initially represented in 2838 * the view structure until the user taps a field from a {@code FORM} inside the 2839 * {@code IFRAME}, in which case it would be treated the same way as multiple forms described 2840 * above, except that the {@link ViewStructure#setWebDomain(String) web domain} of the 2841 * {@code FORM} contains the {@code src} attribute from the {@code IFRAME} node. 2842 * <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to 2843 * {@link ViewStructure#setAutofillHints(String[])}. 2844 * <li>If the view is editable, the {@link ViewStructure#setAutofillType(int)} and 2845 * {@link ViewStructure#setAutofillValue(AutofillValue)} must be set. 2846 * <li>The {@code placeholder} attribute maps to {@link ViewStructure#setHint(CharSequence)}. 2847 * <li>Other HTML attributes can be represented through 2848 * {@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}. 2849 * </ol> 2850 * 2851 * <p>If the WebView implementation can determine that the value of a field was set statically 2852 * (for example, not through Javascript), it should also call 2853 * {@code structure.setDataIsSensitive(false)}. 2854 * 2855 * <p>For example, an HTML form with 2 fields for username and password: 2856 * 2857 * <pre class="prettyprint"> 2858 * <label>Username:</label> 2859 * <input type="text" name="username" id="user" value="Type your username" autocomplete="username" placeholder="Email or username"> 2860 * <label>Password:</label> 2861 * <input type="password" name="password" id="pass" autocomplete="current-password" placeholder="Password"> 2862 * </pre> 2863 * 2864 * <p>Would map to: 2865 * 2866 * <pre class="prettyprint"> 2867 * int index = structure.addChildCount(2); 2868 * ViewStructure username = structure.newChild(index); 2869 * username.setAutofillId(structure.getAutofillId(), 1); // id 1 - first child 2870 * username.setAutofillHints("username"); 2871 * username.setHtmlInfo(username.newHtmlInfoBuilder("input") 2872 * .addAttribute("type", "text") 2873 * .addAttribute("name", "username") 2874 * .addAttribute("label", "Username:") 2875 * .build()); 2876 * username.setHint("Email or username"); 2877 * username.setAutofillType(View.AUTOFILL_TYPE_TEXT); 2878 * username.setAutofillValue(AutofillValue.forText("Type your username")); 2879 * // Value of the field is not sensitive because it was created statically and not changed. 2880 * username.setDataIsSensitive(false); 2881 * 2882 * ViewStructure password = structure.newChild(index + 1); 2883 * username.setAutofillId(structure, 2); // id 2 - second child 2884 * password.setAutofillHints("current-password"); 2885 * password.setHtmlInfo(password.newHtmlInfoBuilder("input") 2886 * .addAttribute("type", "password") 2887 * .addAttribute("name", "password") 2888 * .addAttribute("label", "Password:") 2889 * .build()); 2890 * password.setHint("Password"); 2891 * password.setAutofillType(View.AUTOFILL_TYPE_TEXT); 2892 * </pre> 2893 */ 2894 @Override onProvideAutofillVirtualStructure(ViewStructure structure, int flags)2895 public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) { 2896 mProvider.getViewDelegate().onProvideAutofillVirtualStructure(structure, flags); 2897 } 2898 2899 @Override onProvideContentCaptureStructure(@onNull ViewStructure structure, int flags)2900 public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) { 2901 mProvider.getViewDelegate().onProvideContentCaptureStructure(structure, flags); 2902 } 2903 2904 @Override autofill(SparseArray<AutofillValue>values)2905 public void autofill(SparseArray<AutofillValue>values) { 2906 mProvider.getViewDelegate().autofill(values); 2907 } 2908 2909 @Override isVisibleToUserForAutofill(int virtualId)2910 public boolean isVisibleToUserForAutofill(int virtualId) { 2911 return mProvider.getViewDelegate().isVisibleToUserForAutofill(virtualId); 2912 } 2913 2914 @Override 2915 @Nullable onCreateVirtualViewTranslationRequests(@onNull long[] virtualIds, @NonNull @DataFormat int[] supportedFormats, @NonNull Consumer<ViewTranslationRequest> requestsCollector)2916 public void onCreateVirtualViewTranslationRequests(@NonNull long[] virtualIds, 2917 @NonNull @DataFormat int[] supportedFormats, 2918 @NonNull Consumer<ViewTranslationRequest> requestsCollector) { 2919 mProvider.getViewDelegate().onCreateVirtualViewTranslationRequests(virtualIds, 2920 supportedFormats, requestsCollector); 2921 } 2922 2923 @Override dispatchCreateViewTranslationRequest(@onNull Map<AutofillId, long[]> viewIds, @NonNull @DataFormat int[] supportedFormats, @Nullable TranslationCapability capability, @NonNull List<ViewTranslationRequest> requests)2924 public void dispatchCreateViewTranslationRequest(@NonNull Map<AutofillId, long[]> viewIds, 2925 @NonNull @DataFormat int[] supportedFormats, 2926 @Nullable TranslationCapability capability, 2927 @NonNull List<ViewTranslationRequest> requests) { 2928 super.dispatchCreateViewTranslationRequest(viewIds, supportedFormats, capability, requests); 2929 mProvider.getViewDelegate().dispatchCreateViewTranslationRequest(viewIds, supportedFormats, 2930 capability, requests); 2931 } 2932 2933 @Override onVirtualViewTranslationResponses( @onNull LongSparseArray<ViewTranslationResponse> response)2934 public void onVirtualViewTranslationResponses( 2935 @NonNull LongSparseArray<ViewTranslationResponse> response) { 2936 mProvider.getViewDelegate().onVirtualViewTranslationResponses(response); 2937 } 2938 2939 /** @hide */ 2940 @Override onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info)2941 public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { 2942 super.onInitializeAccessibilityNodeInfoInternal(info); 2943 mProvider.getViewDelegate().onInitializeAccessibilityNodeInfo(info); 2944 } 2945 2946 /** @hide */ 2947 @Override onInitializeAccessibilityEventInternal(AccessibilityEvent event)2948 public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) { 2949 super.onInitializeAccessibilityEventInternal(event); 2950 mProvider.getViewDelegate().onInitializeAccessibilityEvent(event); 2951 } 2952 2953 /** @hide */ 2954 @Override performAccessibilityActionInternal(int action, Bundle arguments)2955 public boolean performAccessibilityActionInternal(int action, Bundle arguments) { 2956 return mProvider.getViewDelegate().performAccessibilityAction(action, arguments); 2957 } 2958 2959 /** @hide */ 2960 @Override 2961 @UnsupportedAppUsage onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b)2962 protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, 2963 int l, int t, int r, int b) { 2964 mProvider.getViewDelegate().onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b); 2965 } 2966 2967 @Override onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY)2968 protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { 2969 mProvider.getViewDelegate().onOverScrolled(scrollX, scrollY, clampedX, clampedY); 2970 } 2971 2972 @Override onWindowVisibilityChanged(int visibility)2973 protected void onWindowVisibilityChanged(int visibility) { 2974 super.onWindowVisibilityChanged(visibility); 2975 mProvider.getViewDelegate().onWindowVisibilityChanged(visibility); 2976 } 2977 2978 @Override onDraw(Canvas canvas)2979 protected void onDraw(Canvas canvas) { 2980 mProvider.getViewDelegate().onDraw(canvas); 2981 } 2982 2983 @Override performLongClick()2984 public boolean performLongClick() { 2985 return mProvider.getViewDelegate().performLongClick(); 2986 } 2987 2988 @Override onConfigurationChanged(Configuration newConfig)2989 protected void onConfigurationChanged(Configuration newConfig) { 2990 mProvider.getViewDelegate().onConfigurationChanged(newConfig); 2991 } 2992 2993 /** 2994 * Creates a new InputConnection for an InputMethod to interact with the WebView. 2995 * This is similar to {@link View#onCreateInputConnection} but note that WebView 2996 * calls InputConnection methods on a thread other than the UI thread. 2997 * If these methods are overridden, then the overriding methods should respect 2998 * thread restrictions when calling View methods or accessing data. 2999 */ 3000 @Override onCreateInputConnection(EditorInfo outAttrs)3001 public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 3002 return mProvider.getViewDelegate().onCreateInputConnection(outAttrs); 3003 } 3004 3005 @Override onDragEvent(DragEvent event)3006 public boolean onDragEvent(DragEvent event) { 3007 return mProvider.getViewDelegate().onDragEvent(event); 3008 } 3009 3010 @Override onVisibilityChanged(View changedView, int visibility)3011 protected void onVisibilityChanged(View changedView, int visibility) { 3012 super.onVisibilityChanged(changedView, visibility); 3013 // This method may be called in the constructor chain, before the WebView provider is 3014 // created. 3015 ensureProviderCreated(); 3016 mProvider.getViewDelegate().onVisibilityChanged(changedView, visibility); 3017 } 3018 3019 @Override onWindowFocusChanged(boolean hasWindowFocus)3020 public void onWindowFocusChanged(boolean hasWindowFocus) { 3021 mProvider.getViewDelegate().onWindowFocusChanged(hasWindowFocus); 3022 super.onWindowFocusChanged(hasWindowFocus); 3023 } 3024 3025 @Override onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)3026 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 3027 mProvider.getViewDelegate().onFocusChanged(focused, direction, previouslyFocusedRect); 3028 super.onFocusChanged(focused, direction, previouslyFocusedRect); 3029 } 3030 3031 /** @hide */ 3032 @Override 3033 @UnsupportedAppUsage setFrame(int left, int top, int right, int bottom)3034 protected boolean setFrame(int left, int top, int right, int bottom) { 3035 return mProvider.getViewDelegate().setFrame(left, top, right, bottom); 3036 } 3037 3038 @Override onSizeChanged(int w, int h, int ow, int oh)3039 protected void onSizeChanged(int w, int h, int ow, int oh) { 3040 super.onSizeChanged(w, h, ow, oh); 3041 mProvider.getViewDelegate().onSizeChanged(w, h, ow, oh); 3042 } 3043 3044 @Override onScrollChanged(int l, int t, int oldl, int oldt)3045 protected void onScrollChanged(int l, int t, int oldl, int oldt) { 3046 super.onScrollChanged(l, t, oldl, oldt); 3047 mProvider.getViewDelegate().onScrollChanged(l, t, oldl, oldt); 3048 } 3049 3050 @Override dispatchKeyEvent(KeyEvent event)3051 public boolean dispatchKeyEvent(KeyEvent event) { 3052 return mProvider.getViewDelegate().dispatchKeyEvent(event); 3053 } 3054 3055 @Override requestFocus(int direction, Rect previouslyFocusedRect)3056 public boolean requestFocus(int direction, Rect previouslyFocusedRect) { 3057 return mProvider.getViewDelegate().requestFocus(direction, previouslyFocusedRect); 3058 } 3059 3060 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)3061 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3062 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 3063 mProvider.getViewDelegate().onMeasure(widthMeasureSpec, heightMeasureSpec); 3064 } 3065 3066 @Override requestChildRectangleOnScreen(View child, Rect rect, boolean immediate)3067 public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) { 3068 return mProvider.getViewDelegate().requestChildRectangleOnScreen(child, rect, immediate); 3069 } 3070 3071 @Override setBackgroundColor(int color)3072 public void setBackgroundColor(int color) { 3073 mProvider.getViewDelegate().setBackgroundColor(color); 3074 } 3075 3076 @Override setLayerType(int layerType, Paint paint)3077 public void setLayerType(int layerType, Paint paint) { 3078 super.setLayerType(layerType, paint); 3079 mProvider.getViewDelegate().setLayerType(layerType, paint); 3080 } 3081 3082 @Override dispatchDraw(Canvas canvas)3083 protected void dispatchDraw(Canvas canvas) { 3084 mProvider.getViewDelegate().preDispatchDraw(canvas); 3085 super.dispatchDraw(canvas); 3086 } 3087 3088 @Override onStartTemporaryDetach()3089 public void onStartTemporaryDetach() { 3090 super.onStartTemporaryDetach(); 3091 mProvider.getViewDelegate().onStartTemporaryDetach(); 3092 } 3093 3094 @Override onFinishTemporaryDetach()3095 public void onFinishTemporaryDetach() { 3096 super.onFinishTemporaryDetach(); 3097 mProvider.getViewDelegate().onFinishTemporaryDetach(); 3098 } 3099 3100 @Override getHandler()3101 public Handler getHandler() { 3102 return mProvider.getViewDelegate().getHandler(super.getHandler()); 3103 } 3104 3105 @Override findFocus()3106 public View findFocus() { 3107 return mProvider.getViewDelegate().findFocus(super.findFocus()); 3108 } 3109 3110 /** 3111 * If WebView has already been loaded into the current process this method will return the 3112 * package that was used to load it. Otherwise, the package that would be used if the WebView 3113 * was loaded right now will be returned; this does not cause WebView to be loaded, so this 3114 * information may become outdated at any time. 3115 * The WebView package changes either when the current WebView package is updated, disabled, or 3116 * uninstalled. It can also be changed through a Developer Setting. 3117 * If the WebView package changes, any app process that has loaded WebView will be killed. The 3118 * next time the app starts and loads WebView it will use the new WebView package instead. 3119 * @return the current WebView package, or {@code null} if there is none. 3120 */ 3121 @Nullable getCurrentWebViewPackage()3122 public static PackageInfo getCurrentWebViewPackage() { 3123 PackageInfo webviewPackage = WebViewFactory.getLoadedPackageInfo(); 3124 if (webviewPackage != null) { 3125 return webviewPackage; 3126 } 3127 3128 if (Flags.updateServiceIpcWrapper()) { 3129 if (WebViewFactory.isWebViewSupported()) { 3130 return WebViewUpdateManager.getInstance().getCurrentWebViewPackage(); 3131 } else { 3132 return null; 3133 } 3134 } else { 3135 IWebViewUpdateService service = WebViewFactory.getUpdateService(); 3136 if (service == null) { 3137 return null; 3138 } 3139 try { 3140 return service.getCurrentWebViewPackage(); 3141 } catch (RemoteException e) { 3142 throw e.rethrowFromSystemServer(); 3143 } 3144 } 3145 } 3146 3147 /** 3148 * Receive the result from a previous call to {@link #startActivityForResult(Intent, int)}. 3149 * 3150 * @param requestCode The integer request code originally supplied to 3151 * startActivityForResult(), allowing you to identify who this 3152 * result came from. 3153 * @param resultCode The integer result code returned by the child activity 3154 * through its setResult(). 3155 * @param data An Intent, which can return result data to the caller 3156 * (various data can be attached to Intent "extras"). 3157 * @hide 3158 */ 3159 @Override onActivityResult(int requestCode, int resultCode, Intent data)3160 public void onActivityResult(int requestCode, int resultCode, Intent data) { 3161 mProvider.getViewDelegate().onActivityResult(requestCode, resultCode, data); 3162 } 3163 3164 @Override onCheckIsTextEditor()3165 public boolean onCheckIsTextEditor() { 3166 return mProvider.getViewDelegate().onCheckIsTextEditor(); 3167 } 3168 3169 /** @hide */ 3170 @Override encodeProperties(@onNull ViewHierarchyEncoder encoder)3171 protected void encodeProperties(@NonNull ViewHierarchyEncoder encoder) { 3172 super.encodeProperties(encoder); 3173 3174 checkThread(); 3175 encoder.addProperty("webview:contentHeight", mProvider.getContentHeight()); 3176 encoder.addProperty("webview:contentWidth", mProvider.getContentWidth()); 3177 encoder.addProperty("webview:scale", mProvider.getScale()); 3178 encoder.addProperty("webview:title", mProvider.getTitle()); 3179 encoder.addProperty("webview:url", mProvider.getUrl()); 3180 encoder.addProperty("webview:originalUrl", mProvider.getOriginalUrl()); 3181 } 3182 3183 @Override onApplyWindowInsets(WindowInsets insets)3184 public WindowInsets onApplyWindowInsets(WindowInsets insets) { 3185 WindowInsets result = mProvider.getViewDelegate().onApplyWindowInsets(insets); 3186 if (result == null) return super.onApplyWindowInsets(insets); 3187 return result; 3188 } 3189 3190 @Override 3191 @Nullable onResolvePointerIcon(@onNull MotionEvent event, int pointerIndex)3192 public PointerIcon onResolvePointerIcon(@NonNull MotionEvent event, int pointerIndex) { 3193 PointerIcon icon = 3194 mProvider.getViewDelegate().onResolvePointerIcon(event, pointerIndex); 3195 if (icon != null) { 3196 return icon; 3197 } 3198 return super.onResolvePointerIcon(event, pointerIndex); 3199 } 3200 } 3201