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