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