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