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