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