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