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