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