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