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