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