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