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