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