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