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