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